From 7741365e5455c328a0d6525131827f47de36fc4b Mon Sep 17 00:00:00 2001 From: Jaakko Keränen Date: Mon, 21 Sep 2020 07:00:19 +0300 Subject: Text: Using Unicode symbols in monospace If the regular monospace font is missing a Unicode character, one is used from Symbola. However, these replacements were taken from the wrong sized font. Also, since the replacements are not monospace (Symbola isn't) they are now centered in their location for a better alignment. --- src/ui/text.c | 39 ++++++++++++++++++++++++--------------- src/ui/text.h | 16 +++++++++++----- 2 files changed, 35 insertions(+), 20 deletions(-) diff --git a/src/ui/text.c b/src/ui/text.c index 63b15572..8d4661ac 100644 --- a/src/ui/text.c +++ b/src/ui/text.c @@ -169,8 +169,8 @@ static void initFonts_Text_(iText *d) { { &fontFiraMonoRegular_Embedded, fontSize_UI * 0.866f, defaultSymbols_FontId }, /* content fonts */ { &fontNunitoRegular_Embedded, textSize, symbols_FontId }, - { &fontFiraMonoRegular_Embedded, monoSize, smallSymbols_FontId }, - { &fontFiraMonoRegular_Embedded, monoSize * 0.750f, smallSymbols_FontId }, + { &fontFiraMonoRegular_Embedded, monoSize, monospaceSymbols_FontId }, + { &fontFiraMonoRegular_Embedded, monoSize * 0.750f, monospaceSmallSymbols_FontId }, { &fontNunitoRegular_Embedded, textSize * 1.200f, mediumSymbols_FontId }, { &fontNunitoRegular_Embedded, textSize * 1.333f, bigSymbols_FontId }, { &fontNunitoLightItalic_Embedded, textSize, symbols_FontId }, @@ -187,7 +187,8 @@ static void initFonts_Text_(iText *d) { { &fontSymbola_Embedded, textSize * 1.333f, bigSymbols_FontId }, { &fontSymbola_Embedded, textSize * 1.666f, largeSymbols_FontId }, { &fontSymbola_Embedded, textSize * 2.000f, hugeSymbols_FontId }, - { &fontSymbola_Embedded, textSize * 0.866f, smallSymbols_FontId }, + { &fontSymbola_Embedded, monoSize, monospaceSymbols_FontId }, + { &fontSymbola_Embedded, monoSize * 0.750f, monospaceSmallSymbols_FontId }, /* emoji fonts */ { &fontNotoEmojiRegular_Embedded, fontSize_UI, defaultSymbols_FontId }, { &fontNotoEmojiRegular_Embedded, fontSize_UI * 1.125f, defaultMediumSymbols_FontId }, @@ -196,10 +197,12 @@ static void initFonts_Text_(iText *d) { { &fontNotoEmojiRegular_Embedded, textSize * 1.333f, bigSymbols_FontId }, { &fontNotoEmojiRegular_Embedded, textSize * 1.666f, largeSymbols_FontId }, { &fontNotoEmojiRegular_Embedded, textSize * 2.000f, hugeSymbols_FontId }, - { &fontNotoEmojiRegular_Embedded, textSize * 0.866f, smallSymbols_FontId }, + { &fontNotoEmojiRegular_Embedded, monoSize, monospaceSymbols_FontId }, + { &fontNotoEmojiRegular_Embedded, monoSize * 0.750f, monospaceSmallSymbols_FontId }, /* japanese fonts */ { &fontKosugiMaruRegular_Embedded, fontSize_UI, defaultSymbols_FontId }, - { &fontKosugiMaruRegular_Embedded, textSize * 0.666f, smallSymbols_FontId }, + { &fontKosugiMaruRegular_Embedded, monoSize * 0.750, monospaceSmallSymbols_FontId }, + { &fontKosugiMaruRegular_Embedded, monoSize, monospaceSymbols_FontId }, { &fontKosugiMaruRegular_Embedded, textSize, symbols_FontId }, { &fontKosugiMaruRegular_Embedded, textSize * 1.200f, mediumSymbols_FontId }, { &fontKosugiMaruRegular_Embedded, textSize * 1.333f, bigSymbols_FontId }, @@ -223,8 +226,8 @@ static void initFonts_Text_(iText *d) { font_Text_(default_FontId)->japaneseFont = defaultJapanese_FontId; font_Text_(defaultMedium_FontId)->japaneseFont = defaultJapanese_FontId; font_Text_(defaultMonospace_FontId)->japaneseFont = defaultJapanese_FontId; - font_Text_(monospace_FontId)->japaneseFont = smallJapanese_FontId; - font_Text_(monospaceSmall_FontId)->japaneseFont = smallJapanese_FontId; + font_Text_(monospaceSmall_FontId)->japaneseFont = monospaceSmallJapanese_FontId; + font_Text_(monospace_FontId)->japaneseFont = monospaceJapanese_FontId; font_Text_(medium_FontId)->japaneseFont = mediumJapanese_FontId; font_Text_(big_FontId)->japaneseFont = bigJapanese_FontId; font_Text_(bigBold_FontId)->japaneseFont = bigJapanese_FontId; @@ -533,8 +536,8 @@ static iRect run_Font_(iFont *d, enum iRunMode mode, iRangecc text, size_t maxLe } } iChar ch = nextChar_(&chPos, text.end); - if (ch == variationSelectorEmoji_Char) { - /* TODO: Should peek ahead for this and prefer the Emoji font. */ + if (isVariationSelector_Char(ch)) { + /* TODO: VS15: Should peek ahead for this and prefer the Emoji font. */ ch = nextChar_(&chPos, text.end); /* just ignore */ } /* Special instructions. */ { @@ -568,10 +571,10 @@ static iRect run_Font_(iFont *d, enum iRunMode mode, iRangecc text, size_t maxLe } break; } - const SDL_Rect dst = { x1 + glyph->d[hoff].x, - pos.y + glyph->font->baseline + glyph->d[hoff].y, - glyph->rect[hoff].size.x, - glyph->rect[hoff].size.y }; + SDL_Rect dst = { x1 + glyph->d[hoff].x, + pos.y + glyph->font->baseline + glyph->d[hoff].y, + glyph->rect[hoff].size.x, + glyph->rect[hoff].size.y }; /* Update the bounding box. */ if (mode == measureVisual_RunMode) { if (isEmpty_Rect(bounds)) { @@ -585,13 +588,19 @@ static iRect run_Font_(iFont *d, enum iRunMode mode, iRangecc text, size_t maxLe bounds.size.x = iMax(bounds.size.x, x2 - orig.x); bounds.size.y = iMax(bounds.size.y, pos.y + glyph->font->height - orig.y); } + const iBool useMonoAdvance = + monoAdvance > 0 && !isJapanese_FontId(fontId_Text_(glyph->font)); + const float advance = (useMonoAdvance ? monoAdvance : glyph->advance); if (!isMeasuring_(mode)) { + if (useMonoAdvance && dst.w > advance) { + dst.x -= (dst.w - advance) / 2; + + } SDL_RenderCopy(text_.render, text_.cache, (const SDL_Rect *) &glyph->rect[hoff], &dst); } /* Symbols and emojis are NOT monospaced, so must conform when the primary font is monospaced. Except with Japanese script, that's larger than the normal monospace. */ - xpos += (monoAdvance > 0 && !isJapanese_FontId(fontId_Text_(glyph->font)) ? monoAdvance - : glyph->advance); + xpos += advance; xposMax = iMax(xposMax, xpos); if (continueFrom_out && (mode == measureNoWrap_RunMode || isWrapBoundary_(prevCh, ch))) { lastWordEnd = chPos; diff --git a/src/ui/text.h b/src/ui/text.h index dfdd6b7e..7dc4aa38 100644 --- a/src/ui/text.h +++ b/src/ui/text.h @@ -53,7 +53,8 @@ enum iFontId { bigSymbols_FontId, largeSymbols_FontId, hugeSymbols_FontId, - smallSymbols_FontId, + monospaceSymbols_FontId, + monospaceSmallSymbols_FontId, /* emoji fonts */ defaultEmoji_FontId, defaultMediumEmoji_FontId, @@ -62,10 +63,12 @@ enum iFontId { bigEmoji_FontId, largeEmoji_FontId, hugeEmoji_FontId, - smallEmoji_FontId, + monospaceEmoji_FontId, + monospaceSmallEmoji_FontId, /* japanese script */ defaultJapanese_FontId, - smallJapanese_FontId, + monospaceSmallJapanese_FontId, + monospaceJapanese_FontId, regularJapanese_FontId, mediumJapanese_FontId, bigJapanese_FontId, @@ -74,7 +77,7 @@ enum iFontId { max_FontId, /* Meta: */ - fromSymbolsToEmojiOffset_FontId = 8, + fromSymbolsToEmojiOffset_FontId = 9, /* UI fonts: */ uiLabel_FontId = default_FontId, @@ -94,7 +97,10 @@ enum iFontId { }; iLocalDef iBool isJapanese_FontId(enum iFontId id) { - return id >= smallJapanese_FontId && id <= hugeJapanese_FontId; + return id >= defaultJapanese_FontId && id <= hugeJapanese_FontId; +} +iLocalDef iBool isVariationSelector_Char(iChar ch) { + return ch >= 0xfe00 && ch <= 0xfe0f; } #define variationSelectorEmoji_Char ((iChar) 0xfe0f) -- cgit v1.2.3