Implement get_string_width function (#509)

* Implement get_string_width function

  uint16_t get_string_width(const char* buffer);

* Use readCodePoint to parse the string

* Fix formatting issue

* reverting back changes with readCodePoint

* Remove unicode.h

* Addressed review comments

* Added const definition

Co-authored-by: Duncan <duncans_pumpkin@hotmail.co.uk>
This commit is contained in:
Peter Gaal 2020-06-22 22:20:24 +02:00 committed by GitHub
parent 82b073cd57
commit b20e73c986
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 97 additions and 10 deletions

View File

@ -182,12 +182,87 @@ namespace openloco::gfx
* @param buffer @<esi>
* @return width @<cx>
*/
uint16_t get_string_width(const char* buffer)
uint16_t getStringWidth(const char* buffer)
{
registers regs;
regs.esi = (uintptr_t)buffer;
call(0x495685, regs);
return regs.cx;
uint16_t width = 0;
const uint8_t* str = reinterpret_cast<const uint8_t*>(buffer);
int16_t fontSpriteBase = _currentFontSpriteBase;
while (*str != (uint8_t)0)
{
const uint8_t chr = *str;
str++;
if (chr >= 32)
{
width += _characterWidths[chr - 32 + fontSpriteBase];
continue;
}
switch (chr)
{
case control_codes::move_x:
width = *str;
str++;
break;
case control_codes::adjust_palette:
case 3:
case 4:
str++;
break;
case control_codes::newline:
case control_codes::newline_smaller:
continue;
case control_codes::font_small:
fontSpriteBase = font::small;
break;
case control_codes::font_large:
fontSpriteBase = font::large;
break;
case control_codes::font_bold:
fontSpriteBase = font::medium_bold;
break;
case control_codes::font_regular:
fontSpriteBase = font::medium_normal;
break;
case control_codes::outline:
case control_codes::outline_off:
case control_codes::window_colour_1:
case control_codes::window_colour_2:
case control_codes::window_colour_3:
case 0x10:
break;
case control_codes::inline_sprite_str:
{
const uint32_t image = reinterpret_cast<const uint32_t*>(str)[0];
const uint32_t imageId = image & 0x7FFFF;
str += 4;
width += _g1Elements[imageId].width;
break;
}
default:
if (chr <= 0x16)
{
str += 2;
}
else
{
str += 4;
}
break;
}
}
return width;
}
static void setTextColours(palette_index_t pal1, palette_index_t pal2, palette_index_t pal3)

View File

@ -74,7 +74,7 @@ namespace openloco::gfx
void clear_single(drawpixelinfo_t& dpi, uint8_t paletteId);
int16_t clip_string(int16_t width, char* string);
uint16_t get_string_width(const char* buffer);
uint16_t getStringWidth(const char* buffer);
gfx::point_t draw_string(drawpixelinfo_t* context, int16_t x, int16_t y, uint8_t colour, void* str);

View File

@ -200,6 +200,18 @@ namespace openloco::ui::WindowManager
return 0;
});
register_hook(
0x00495685,
[](registers& regs) FORCE_ALIGN_ARG_POINTER -> uint8_t {
registers backup = regs;
const char* buffer = (const char*)regs.esi;
uint16_t width = gfx::getStringWidth(buffer);
regs = backup;
regs.cx = width;
return 0;
});
register_hook(
0x00499B7E,
[](registers& regs) FORCE_ALIGN_ARG_POINTER -> uint8_t {

View File

@ -413,8 +413,8 @@ namespace openloco::ui::textinput
std::string cursorStr = _buffer.substr(0, cursor_position);
_currentFontSpriteBase = font::medium_bold;
auto stringWidth = gfx::get_string_width(_buffer.data());
auto cursorX = gfx::get_string_width(cursorStr.data());
auto stringWidth = gfx::getStringWidth(_buffer.data());
auto cursorX = gfx::getStringWidth(cursorStr.data());
int x = _xOffset + cursorX;
@ -440,8 +440,8 @@ namespace openloco::ui::textinput
std::string cursorStr = _buffer.substr(0, cursor_position);
_currentFontSpriteBase = font::medium_bold;
auto stringWidth = gfx::get_string_width(_buffer.data());
auto cursorX = gfx::get_string_width(cursorStr.data());
auto stringWidth = gfx::getStringWidth(_buffer.data());
auto cursorX = gfx::getStringWidth(cursorStr.data());
auto midX = containerWidth / 2;