mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-19 13:03:11 +01:00
implement utf8, part 21 (more font specific customisation and bug fixes)
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef _DRAWING_FONT_H_
|
||||
#define _DRAWING_FONT_H_
|
||||
|
||||
#include <SDL_ttf.h>
|
||||
#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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.");
|
||||
}
|
||||
|
||||
@@ -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[];
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user