diff --git a/src/drawing/font.c b/src/drawing/font.c index 39c19f1a5d..cde247dc04 100644 --- a/src/drawing/font.c +++ b/src/drawing/font.c @@ -4,8 +4,12 @@ #include "drawing.h" #include "font.h" +static const int SpriteFontLineHeight[] = { 6, 10, 10, 18 }; + static uint8 *_spriteFontCharacterWidths = (uint8*)RCT2_ADDRESS_FONT_CHAR_WIDTH; +TTFFontSetDescriptor *gCurrentTTFFontSet; + /** * * rct2: 0x006C19AC @@ -92,3 +96,33 @@ int font_sprite_get_codepoint_sprite(int fontSpriteBase, int codepoint) { return SPR_CHAR_START + ((IMAGE_TYPE_USE_PALETTE << 28) | (fontSpriteBase + font_sprite_get_codepoint_offset(codepoint))); } + +int font_get_size_from_sprite_base(uint16 spriteBase) +{ + switch (spriteBase) { + case FONT_SPRITE_BASE_TINY: + return 0; + case FONT_SPRITE_BASE_SMALL: + return 1; + default: + case FONT_SPRITE_BASE_MEDIUM: + return 2; + case FONT_SPRITE_BASE_BIG: + return 3; + } +} + +int font_get_line_height(int fontSpriteBase) +{ + int fontSize = font_get_size_from_sprite_base(fontSpriteBase); + if (gUseTrueTypeFont) { + return gCurrentTTFFontSet->size[fontSize].line_height; + } else { + return SpriteFontLineHeight[fontSize]; + } +} + +int font_get_line_height_small(int fontSpriteBase) +{ + return font_get_line_height(fontSpriteBase) / 2; +} diff --git a/src/drawing/font.h b/src/drawing/font.h index 33fd8345e8..48a9f33540 100644 --- a/src/drawing/font.h +++ b/src/drawing/font.h @@ -1,6 +1,7 @@ #ifndef _DRAWING_FONT_H_ #define _DRAWING_FONT_H_ +#include #include "../common.h" enum { @@ -20,9 +21,27 @@ enum { FONT_SPRITE_BASE_BIG = 672 }; +typedef struct { + utf8 *filename; + int ptSize; + int offset_x; + int offset_y; + int line_height; + TTF_Font *font; +} TTFFontDescriptor; + +typedef struct { + TTFFontDescriptor size[FONT_SIZE_COUNT]; +} TTFFontSetDescriptor; + +extern TTFFontSetDescriptor *gCurrentTTFFontSet; + void font_sprite_initialise_characters(); int font_sprite_get_codepoint_offset(int codepoint); int font_sprite_get_codepoint_width(int fontSpriteBase, int codepoint); int font_sprite_get_codepoint_sprite(int fontSpriteBase, int codepoint); +int font_get_size_from_sprite_base(uint16 spriteBase); +int font_get_line_height(int fontSpriteBase); +int font_get_line_height_small(int fontSpriteBase); #endif \ No newline at end of file diff --git a/src/drawing/scrolling_text.c b/src/drawing/scrolling_text.c index e04d40fca4..1958cc1f8a 100644 --- a/src/drawing/scrolling_text.c +++ b/src/drawing/scrolling_text.c @@ -197,7 +197,7 @@ void scrolling_text_set_bitmap_for_sprite(utf8 *text, int scroll, uint8 *bitmap, } } -TTF_Font *ttf_get_font_from_sprite_base(uint16 spriteBase); +TTFFontDescriptor *ttf_get_font_from_sprite_base(uint16 spriteBase); SDL_Surface *_ttf_surface_cache_get_or_add(TTF_Font *font, const utf8 *text); void scrolling_text_set_bitmap_for_ttf(utf8 *text, int scroll, uint8 *bitmap, sint16 *scrollPositionOffsets) @@ -225,8 +225,8 @@ void scrolling_text_set_bitmap_for_ttf(utf8 *text, int scroll, uint8 *bitmap, si colour = RCT2_GLOBAL(0x009FF048, uint8*)[(colour - FORMAT_COLOUR_CODE_START) * 4]; } - TTF_Font *font = ttf_get_font_from_sprite_base(FONT_SPRITE_BASE_TINY); - SDL_Surface *surface = _ttf_surface_cache_get_or_add(font, text); + TTFFontDescriptor *fontDesc = ttf_get_font_from_sprite_base(FONT_SPRITE_BASE_TINY); + SDL_Surface *surface = _ttf_surface_cache_get_or_add(fontDesc->font, text); if (surface == NULL) { return; } diff --git a/src/drawing/string.c b/src/drawing/string.c index b4459939b5..3f5625f39c 100644 --- a/src/drawing/string.c +++ b/src/drawing/string.c @@ -29,10 +29,6 @@ static int ttf_get_string_width(const utf8 *text); static void ttf_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, int y); static bool _ttfInitialised = false; -static TTF_Font *_ttfFont[4] = { NULL }; - -static const int TTFFontSizes[] = { 9, 11, 12, 13 }; -static const rct_xy16 TTFFontOffsets[] = { { -1, -2 }, { -1, -2 }, { -1, -3 }, { -1, -3 } }; #define TTF_SURFACE_CACHE_SIZE 256 #define TTF_GETWIDTH_CACHE_SIZE 1024 @@ -379,17 +375,9 @@ int gfx_draw_string_centred_wrapped(rct_drawpixelinfo *dpi, void *args, int x, i // line_width unused here line_width = gfx_wrap_string(buffer, width, &num_lines, &font_height); + line_height = font_get_line_height(font_height); - line_height = 0x0A; - - if (font_height > 0xE0) { - line_height = 6; - if (font_height != 0x1C0) { - line_height = 0x12; - } - } - - if (*buffer == 0x0B) { + if (*buffer == FORMAT_OUTLINE) { line_height = line_height + 1; } @@ -436,19 +424,7 @@ int gfx_draw_string_left_wrapped(rct_drawpixelinfo *dpi, void *args, int x, int *current_font_sprite_base = FONT_SPRITE_BASE_MEDIUM; gfx_wrap_string(buffer, width, &numLines, &fontSpriteBase); - switch (fontSpriteBase) { - case FONT_SPRITE_BASE_TINY: - lineHeight = 6; - break; - default: - case FONT_SPRITE_BASE_SMALL: - case FONT_SPRITE_BASE_MEDIUM: - lineHeight = 10; - break; - case FONT_SPRITE_BASE_BIG: - lineHeight = 18; - break; - } + lineHeight = font_get_line_height(fontSpriteBase); RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_FLAGS, uint16) = 0; lineY = y; @@ -726,25 +702,13 @@ void gfx_draw_string_centred_wrapped_partial(rct_drawpixelinfo *dpi, int x, int RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = FONT_SPRITE_BASE_MEDIUM; gfx_wrap_string(buffer, width, &numLines, &fontSpriteBase); - switch (fontSpriteBase) { - case FONT_SPRITE_BASE_TINY: - lineHeight = 6; - break; - default: - case FONT_SPRITE_BASE_SMALL: - case FONT_SPRITE_BASE_MEDIUM: - lineHeight = 10; - break; - case FONT_SPRITE_BASE_BIG: - lineHeight = 18; - break; - } + lineHeight = font_get_line_height(fontSpriteBase); int numCharactersDrawn = 0; int numCharactersToDraw = ticks; RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_FLAGS, uint16) = 0; - lineY = y; + lineY = y - ((numLines * lineHeight) / 2); for (int line = 0; line <= numLines; line++) { int halfWidth = gfx_get_string_width(buffer) / 2; @@ -917,11 +881,14 @@ bool ttf_initialise() if (TTF_Init() != 0) return false; - utf8 fontPath[MAX_PATH] = "C:\\Windows\\Fonts\\"; - strcat(fontPath, gTrueTypeFontPath); for (int i = 0; i < 4; i++) { - _ttfFont[i] = TTF_OpenFont(fontPath, TTFFontSizes[i]); - if (_ttfFont[i] == NULL) { + TTFFontDescriptor *fontDesc = &(gCurrentTTFFontSet->size[i]); + + utf8 fontPath[MAX_PATH] = "C:\\Windows\\Fonts\\"; + strcat(fontPath, fontDesc->filename); + + fontDesc->font = TTF_OpenFont(fontPath, fontDesc->ptSize); + if (fontDesc->font == NULL) { TTF_Quit(); return false; } @@ -940,10 +907,11 @@ void ttf_dispose() _ttf_surface_cache_dispose_all(); _ttf_getwidth_cache_dispose_all(); - if (_ttfFont != NULL) { - for (int i = 0; i < 4; i++) { - TTF_CloseFont(_ttfFont[i]); - _ttfFont[i] = NULL; + for (int i = 0; i < 4; i++) { + TTFFontDescriptor *fontDesc = &(gCurrentTTFFontSet->size[i]); + if (fontDesc->font != NULL) { + TTF_CloseFont(fontDesc->font); + fontDesc->font = NULL; } } @@ -951,24 +919,9 @@ void ttf_dispose() _ttfInitialised = false; } -int ttf_get_font_size_from_sprite_base(uint16 spriteBase) +TTFFontDescriptor *ttf_get_font_from_sprite_base(uint16 spriteBase) { - switch (spriteBase) { - case FONT_SPRITE_BASE_TINY: - return 0; - case FONT_SPRITE_BASE_SMALL: - return 1; - default: - case FONT_SPRITE_BASE_MEDIUM: - return 2; - case FONT_SPRITE_BASE_BIG: - return 3; - } -} - -TTF_Font *ttf_get_font_from_sprite_base(uint16 spriteBase) -{ - return _ttfFont[ttf_get_font_size_from_sprite_base(spriteBase)]; + return &gCurrentTTFFontSet->size[font_get_size_from_sprite_base(spriteBase)]; } enum { @@ -1017,13 +970,13 @@ static void ttf_draw_string_raw_ttf(rct_drawpixelinfo *dpi, const utf8 *text, te if (!_ttfInitialised && !ttf_initialise()) return; - TTF_Font *font = ttf_get_font_from_sprite_base(info->font_sprite_base); + TTFFontDescriptor *fontDesc = ttf_get_font_from_sprite_base(info->font_sprite_base); if (info->flags & TEXT_DRAW_FLAG_NO_DRAW) { - info->x += _ttf_getwidth_cache_get_or_add(font, text); + info->x += _ttf_getwidth_cache_get_or_add(fontDesc->font, text); return; } else { uint8 colour = info->palette[1]; - SDL_Surface *surface = _ttf_surface_cache_get_or_add(font, text); + SDL_Surface *surface = _ttf_surface_cache_get_or_add(fontDesc->font, text); if (surface == NULL) return; @@ -1033,9 +986,9 @@ static void ttf_draw_string_raw_ttf(rct_drawpixelinfo *dpi, const utf8 *text, te } } - int fontSize = ttf_get_font_size_from_sprite_base(info->font_sprite_base); - int drawX = info->x + TTFFontOffsets[fontSize].x; - int drawY = info->y + TTFFontOffsets[fontSize].y; + int fontSize = font_get_size_from_sprite_base(info->font_sprite_base); + int drawX = info->x + fontDesc->offset_x; + int drawY = info->y + fontDesc->offset_y; int width = surface->w; int height = surface->h; @@ -1132,11 +1085,12 @@ static const utf8 *ttf_process_format_code(rct_drawpixelinfo *dpi, const utf8 *t nextCh++; break; case FORMAT_NEWLINE: - if (info->font_sprite_base <= 224) { info->y += 28; } - else if (info->font_sprite_base <= 448) { info->y += 24; } - else { info->y += 18; } + info->x = info->startX; + info->y += font_get_line_height(info->font_sprite_base); break; case FORMAT_NEWLINE_SMALLER: + info->x = info->startX; + info->y += font_get_line_height_small(info->font_sprite_base); break; case FORMAT_TINYFONT: info->font_sprite_base = 448; diff --git a/src/localisation/language.c b/src/localisation/language.c index f933eef302..fd0deb5070 100644 --- a/src/localisation/language.c +++ b/src/localisation/language.c @@ -51,6 +51,13 @@ enum { RCT2_LANGUAGE_ID_END = 255 }; +static TTFFontSetDescriptor TTFFontMingliu = {{ + { "msjh.ttc", 9, -1, -3, 6, NULL }, + { "mingliu.ttc", 11, 1, 0, 12, NULL }, + { "mingliu.ttc", 12, 1, 0, 12, NULL }, + { "mingliu.ttc", 13, 1, 0, 20, NULL }, +}}; + const language_descriptor LanguagesDescriptors[LANGUAGE_COUNT] = { { "", "", "", "", FONT_OPENRCT2_SPRITE, RCT2_LANGUAGE_ID_ENGLISH_UK }, // LANGUAGE_UNDEFINED { "en-GB", "English (UK)", "English (UK)", "english_uk", FONT_OPENRCT2_SPRITE, RCT2_LANGUAGE_ID_ENGLISH_UK }, // LANGUAGE_ENGLISH_UK @@ -64,13 +71,12 @@ const language_descriptor LanguagesDescriptors[LANGUAGE_COUNT] = { { "sv-SE", "Swedish", "Svenska", "swedish", FONT_OPENRCT2_SPRITE, RCT2_LANGUAGE_ID_SWEDISH }, // LANGUAGE_SWEDISH { "it-IT", "Italian", "Italiano", "italian", FONT_OPENRCT2_SPRITE, RCT2_LANGUAGE_ID_ITALIAN }, // LANGUAGE_ITALIAN { "pt-BR", "Portuguese (BR)", "Portug\xC3\xAAs (BR)", "portuguese_br", FONT_OPENRCT2_SPRITE, RCT2_LANGUAGE_ID_PORTUGESE }, // LANGUAGE_PORTUGUESE_BR - { "zh-Hant", "Chinese (Traditional)", "Chinese (Traditional)", "chinese_traditional", "msjh.ttc", RCT2_LANGUAGE_ID_CHINESE_TRADITIONAL }, // LANGUAGE_CHINESE_TRADITIONAL + { "zh-Hant", "Chinese (Traditional)", "Chinese (Traditional)", "chinese_traditional", &TTFFontMingliu, RCT2_LANGUAGE_ID_CHINESE_TRADITIONAL }, // LANGUAGE_CHINESE_TRADITIONAL // { "kr-KR", "Korean", "Korean", "english_uk", "malgun.ttf", RCT2_LANGUAGE_ID_KOREAN }, // LANGUAGE_KOREAN }; int gCurrentLanguage = LANGUAGE_UNDEFINED; bool gUseTrueTypeFont = false; -const utf8 *gTrueTypeFontPath; language_data _languageFallback = { 0 }; language_data _languageCurrent = { 0 }; @@ -142,12 +148,13 @@ int language_open(int id) gCurrentLanguage = id; if (LanguagesDescriptors[id].font == FONT_OPENRCT2_SPRITE) { - gUseTrueTypeFont = false; - gTrueTypeFontPath = NULL; ttf_dispose(); + gUseTrueTypeFont = false; + gCurrentTTFFontSet = NULL; } else { + ttf_dispose(); gUseTrueTypeFont = true; - gTrueTypeFontPath = LanguagesDescriptors[id].font; + gCurrentTTFFontSet = LanguagesDescriptors[id].font; if (!ttf_initialise()) { log_warning("Unable to initialise TrueType fonts."); } diff --git a/src/localisation/language.h b/src/localisation/language.h index 6f84cf6471..03dc6d5524 100644 --- a/src/localisation/language.h +++ b/src/localisation/language.h @@ -22,6 +22,7 @@ #define _LANGUAGE_H_ #include "../common.h" +#include "../drawing/font.h" enum { LANGUAGE_UNDEFINED, @@ -48,7 +49,7 @@ typedef struct { const utf8 *english_name; const utf8 *native_name; const utf8 *path; - const utf8 *font; + TTFFontSetDescriptor *font; uint8 rct2_original_id; } language_descriptor; @@ -56,7 +57,6 @@ extern const language_descriptor LanguagesDescriptors[LANGUAGE_COUNT]; extern int gCurrentLanguage; extern bool gUseTrueTypeFont; -extern const utf8 *gTrueTypeFontPath; extern const utf8 BlackUpArrowString[]; extern const utf8 BlackDownArrowString[]; diff --git a/src/windows/loadsave.c b/src/windows/loadsave.c index 286caeca65..f5f3bcb00a 100644 --- a/src/windows/loadsave.c +++ b/src/windows/loadsave.c @@ -462,9 +462,14 @@ static void window_loadsave_paint(rct_window *w, rct_drawpixelinfo *dpi) if (_shortenedDirectory[0] == '\0') shorten_path(_directory, _shortenedDirectory, w->width - 8); - char buffer[256]; + utf8 buffer[256]; + // Format text - sprintf(buffer, "%c%c%s", FORMAT_MEDIUMFONT, FORMAT_BLACK, _shortenedDirectory); + utf8 *ch = buffer; + ch = utf8_write_codepoint(ch, FORMAT_MEDIUMFONT); + ch = utf8_write_codepoint(ch, FORMAT_BLACK); + strcpy(ch, _shortenedDirectory); + // Draw shadow gfx_draw_string(dpi, buffer, 0, w->x + 4, w->y + 20); rct_string_id id = STR_NONE;