diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-09-21 07:00:19 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-09-21 07:00:19 +0300 |
commit | 7741365e5455c328a0d6525131827f47de36fc4b (patch) | |
tree | 5dd51cd95e446fb1ceef75a6ca8013d5904ee3ac | |
parent | 7eae4386c6e82ff7f7aed322bd5e3b0ebf382813 (diff) |
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.
-rw-r--r-- | src/ui/text.c | 39 | ||||
-rw-r--r-- | 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) { | |||
169 | { &fontFiraMonoRegular_Embedded, fontSize_UI * 0.866f, defaultSymbols_FontId }, | 169 | { &fontFiraMonoRegular_Embedded, fontSize_UI * 0.866f, defaultSymbols_FontId }, |
170 | /* content fonts */ | 170 | /* content fonts */ |
171 | { &fontNunitoRegular_Embedded, textSize, symbols_FontId }, | 171 | { &fontNunitoRegular_Embedded, textSize, symbols_FontId }, |
172 | { &fontFiraMonoRegular_Embedded, monoSize, smallSymbols_FontId }, | 172 | { &fontFiraMonoRegular_Embedded, monoSize, monospaceSymbols_FontId }, |
173 | { &fontFiraMonoRegular_Embedded, monoSize * 0.750f, smallSymbols_FontId }, | 173 | { &fontFiraMonoRegular_Embedded, monoSize * 0.750f, monospaceSmallSymbols_FontId }, |
174 | { &fontNunitoRegular_Embedded, textSize * 1.200f, mediumSymbols_FontId }, | 174 | { &fontNunitoRegular_Embedded, textSize * 1.200f, mediumSymbols_FontId }, |
175 | { &fontNunitoRegular_Embedded, textSize * 1.333f, bigSymbols_FontId }, | 175 | { &fontNunitoRegular_Embedded, textSize * 1.333f, bigSymbols_FontId }, |
176 | { &fontNunitoLightItalic_Embedded, textSize, symbols_FontId }, | 176 | { &fontNunitoLightItalic_Embedded, textSize, symbols_FontId }, |
@@ -187,7 +187,8 @@ static void initFonts_Text_(iText *d) { | |||
187 | { &fontSymbola_Embedded, textSize * 1.333f, bigSymbols_FontId }, | 187 | { &fontSymbola_Embedded, textSize * 1.333f, bigSymbols_FontId }, |
188 | { &fontSymbola_Embedded, textSize * 1.666f, largeSymbols_FontId }, | 188 | { &fontSymbola_Embedded, textSize * 1.666f, largeSymbols_FontId }, |
189 | { &fontSymbola_Embedded, textSize * 2.000f, hugeSymbols_FontId }, | 189 | { &fontSymbola_Embedded, textSize * 2.000f, hugeSymbols_FontId }, |
190 | { &fontSymbola_Embedded, textSize * 0.866f, smallSymbols_FontId }, | 190 | { &fontSymbola_Embedded, monoSize, monospaceSymbols_FontId }, |
191 | { &fontSymbola_Embedded, monoSize * 0.750f, monospaceSmallSymbols_FontId }, | ||
191 | /* emoji fonts */ | 192 | /* emoji fonts */ |
192 | { &fontNotoEmojiRegular_Embedded, fontSize_UI, defaultSymbols_FontId }, | 193 | { &fontNotoEmojiRegular_Embedded, fontSize_UI, defaultSymbols_FontId }, |
193 | { &fontNotoEmojiRegular_Embedded, fontSize_UI * 1.125f, defaultMediumSymbols_FontId }, | 194 | { &fontNotoEmojiRegular_Embedded, fontSize_UI * 1.125f, defaultMediumSymbols_FontId }, |
@@ -196,10 +197,12 @@ static void initFonts_Text_(iText *d) { | |||
196 | { &fontNotoEmojiRegular_Embedded, textSize * 1.333f, bigSymbols_FontId }, | 197 | { &fontNotoEmojiRegular_Embedded, textSize * 1.333f, bigSymbols_FontId }, |
197 | { &fontNotoEmojiRegular_Embedded, textSize * 1.666f, largeSymbols_FontId }, | 198 | { &fontNotoEmojiRegular_Embedded, textSize * 1.666f, largeSymbols_FontId }, |
198 | { &fontNotoEmojiRegular_Embedded, textSize * 2.000f, hugeSymbols_FontId }, | 199 | { &fontNotoEmojiRegular_Embedded, textSize * 2.000f, hugeSymbols_FontId }, |
199 | { &fontNotoEmojiRegular_Embedded, textSize * 0.866f, smallSymbols_FontId }, | 200 | { &fontNotoEmojiRegular_Embedded, monoSize, monospaceSymbols_FontId }, |
201 | { &fontNotoEmojiRegular_Embedded, monoSize * 0.750f, monospaceSmallSymbols_FontId }, | ||
200 | /* japanese fonts */ | 202 | /* japanese fonts */ |
201 | { &fontKosugiMaruRegular_Embedded, fontSize_UI, defaultSymbols_FontId }, | 203 | { &fontKosugiMaruRegular_Embedded, fontSize_UI, defaultSymbols_FontId }, |
202 | { &fontKosugiMaruRegular_Embedded, textSize * 0.666f, smallSymbols_FontId }, | 204 | { &fontKosugiMaruRegular_Embedded, monoSize * 0.750, monospaceSmallSymbols_FontId }, |
205 | { &fontKosugiMaruRegular_Embedded, monoSize, monospaceSymbols_FontId }, | ||
203 | { &fontKosugiMaruRegular_Embedded, textSize, symbols_FontId }, | 206 | { &fontKosugiMaruRegular_Embedded, textSize, symbols_FontId }, |
204 | { &fontKosugiMaruRegular_Embedded, textSize * 1.200f, mediumSymbols_FontId }, | 207 | { &fontKosugiMaruRegular_Embedded, textSize * 1.200f, mediumSymbols_FontId }, |
205 | { &fontKosugiMaruRegular_Embedded, textSize * 1.333f, bigSymbols_FontId }, | 208 | { &fontKosugiMaruRegular_Embedded, textSize * 1.333f, bigSymbols_FontId }, |
@@ -223,8 +226,8 @@ static void initFonts_Text_(iText *d) { | |||
223 | font_Text_(default_FontId)->japaneseFont = defaultJapanese_FontId; | 226 | font_Text_(default_FontId)->japaneseFont = defaultJapanese_FontId; |
224 | font_Text_(defaultMedium_FontId)->japaneseFont = defaultJapanese_FontId; | 227 | font_Text_(defaultMedium_FontId)->japaneseFont = defaultJapanese_FontId; |
225 | font_Text_(defaultMonospace_FontId)->japaneseFont = defaultJapanese_FontId; | 228 | font_Text_(defaultMonospace_FontId)->japaneseFont = defaultJapanese_FontId; |
226 | font_Text_(monospace_FontId)->japaneseFont = smallJapanese_FontId; | 229 | font_Text_(monospaceSmall_FontId)->japaneseFont = monospaceSmallJapanese_FontId; |
227 | font_Text_(monospaceSmall_FontId)->japaneseFont = smallJapanese_FontId; | 230 | font_Text_(monospace_FontId)->japaneseFont = monospaceJapanese_FontId; |
228 | font_Text_(medium_FontId)->japaneseFont = mediumJapanese_FontId; | 231 | font_Text_(medium_FontId)->japaneseFont = mediumJapanese_FontId; |
229 | font_Text_(big_FontId)->japaneseFont = bigJapanese_FontId; | 232 | font_Text_(big_FontId)->japaneseFont = bigJapanese_FontId; |
230 | font_Text_(bigBold_FontId)->japaneseFont = bigJapanese_FontId; | 233 | 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 | |||
533 | } | 536 | } |
534 | } | 537 | } |
535 | iChar ch = nextChar_(&chPos, text.end); | 538 | iChar ch = nextChar_(&chPos, text.end); |
536 | if (ch == variationSelectorEmoji_Char) { | 539 | if (isVariationSelector_Char(ch)) { |
537 | /* TODO: Should peek ahead for this and prefer the Emoji font. */ | 540 | /* TODO: VS15: Should peek ahead for this and prefer the Emoji font. */ |
538 | ch = nextChar_(&chPos, text.end); /* just ignore */ | 541 | ch = nextChar_(&chPos, text.end); /* just ignore */ |
539 | } | 542 | } |
540 | /* Special instructions. */ { | 543 | /* Special instructions. */ { |
@@ -568,10 +571,10 @@ static iRect run_Font_(iFont *d, enum iRunMode mode, iRangecc text, size_t maxLe | |||
568 | } | 571 | } |
569 | break; | 572 | break; |
570 | } | 573 | } |
571 | const SDL_Rect dst = { x1 + glyph->d[hoff].x, | 574 | SDL_Rect dst = { x1 + glyph->d[hoff].x, |
572 | pos.y + glyph->font->baseline + glyph->d[hoff].y, | 575 | pos.y + glyph->font->baseline + glyph->d[hoff].y, |
573 | glyph->rect[hoff].size.x, | 576 | glyph->rect[hoff].size.x, |
574 | glyph->rect[hoff].size.y }; | 577 | glyph->rect[hoff].size.y }; |
575 | /* Update the bounding box. */ | 578 | /* Update the bounding box. */ |
576 | if (mode == measureVisual_RunMode) { | 579 | if (mode == measureVisual_RunMode) { |
577 | if (isEmpty_Rect(bounds)) { | 580 | if (isEmpty_Rect(bounds)) { |
@@ -585,13 +588,19 @@ static iRect run_Font_(iFont *d, enum iRunMode mode, iRangecc text, size_t maxLe | |||
585 | bounds.size.x = iMax(bounds.size.x, x2 - orig.x); | 588 | bounds.size.x = iMax(bounds.size.x, x2 - orig.x); |
586 | bounds.size.y = iMax(bounds.size.y, pos.y + glyph->font->height - orig.y); | 589 | bounds.size.y = iMax(bounds.size.y, pos.y + glyph->font->height - orig.y); |
587 | } | 590 | } |
591 | const iBool useMonoAdvance = | ||
592 | monoAdvance > 0 && !isJapanese_FontId(fontId_Text_(glyph->font)); | ||
593 | const float advance = (useMonoAdvance ? monoAdvance : glyph->advance); | ||
588 | if (!isMeasuring_(mode)) { | 594 | if (!isMeasuring_(mode)) { |
595 | if (useMonoAdvance && dst.w > advance) { | ||
596 | dst.x -= (dst.w - advance) / 2; | ||
597 | |||
598 | } | ||
589 | SDL_RenderCopy(text_.render, text_.cache, (const SDL_Rect *) &glyph->rect[hoff], &dst); | 599 | SDL_RenderCopy(text_.render, text_.cache, (const SDL_Rect *) &glyph->rect[hoff], &dst); |
590 | } | 600 | } |
591 | /* Symbols and emojis are NOT monospaced, so must conform when the primary font | 601 | /* Symbols and emojis are NOT monospaced, so must conform when the primary font |
592 | is monospaced. Except with Japanese script, that's larger than the normal monospace. */ | 602 | is monospaced. Except with Japanese script, that's larger than the normal monospace. */ |
593 | xpos += (monoAdvance > 0 && !isJapanese_FontId(fontId_Text_(glyph->font)) ? monoAdvance | 603 | xpos += advance; |
594 | : glyph->advance); | ||
595 | xposMax = iMax(xposMax, xpos); | 604 | xposMax = iMax(xposMax, xpos); |
596 | if (continueFrom_out && (mode == measureNoWrap_RunMode || isWrapBoundary_(prevCh, ch))) { | 605 | if (continueFrom_out && (mode == measureNoWrap_RunMode || isWrapBoundary_(prevCh, ch))) { |
597 | lastWordEnd = chPos; | 606 | 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 { | |||
53 | bigSymbols_FontId, | 53 | bigSymbols_FontId, |
54 | largeSymbols_FontId, | 54 | largeSymbols_FontId, |
55 | hugeSymbols_FontId, | 55 | hugeSymbols_FontId, |
56 | smallSymbols_FontId, | 56 | monospaceSymbols_FontId, |
57 | monospaceSmallSymbols_FontId, | ||
57 | /* emoji fonts */ | 58 | /* emoji fonts */ |
58 | defaultEmoji_FontId, | 59 | defaultEmoji_FontId, |
59 | defaultMediumEmoji_FontId, | 60 | defaultMediumEmoji_FontId, |
@@ -62,10 +63,12 @@ enum iFontId { | |||
62 | bigEmoji_FontId, | 63 | bigEmoji_FontId, |
63 | largeEmoji_FontId, | 64 | largeEmoji_FontId, |
64 | hugeEmoji_FontId, | 65 | hugeEmoji_FontId, |
65 | smallEmoji_FontId, | 66 | monospaceEmoji_FontId, |
67 | monospaceSmallEmoji_FontId, | ||
66 | /* japanese script */ | 68 | /* japanese script */ |
67 | defaultJapanese_FontId, | 69 | defaultJapanese_FontId, |
68 | smallJapanese_FontId, | 70 | monospaceSmallJapanese_FontId, |
71 | monospaceJapanese_FontId, | ||
69 | regularJapanese_FontId, | 72 | regularJapanese_FontId, |
70 | mediumJapanese_FontId, | 73 | mediumJapanese_FontId, |
71 | bigJapanese_FontId, | 74 | bigJapanese_FontId, |
@@ -74,7 +77,7 @@ enum iFontId { | |||
74 | max_FontId, | 77 | max_FontId, |
75 | 78 | ||
76 | /* Meta: */ | 79 | /* Meta: */ |
77 | fromSymbolsToEmojiOffset_FontId = 8, | 80 | fromSymbolsToEmojiOffset_FontId = 9, |
78 | 81 | ||
79 | /* UI fonts: */ | 82 | /* UI fonts: */ |
80 | uiLabel_FontId = default_FontId, | 83 | uiLabel_FontId = default_FontId, |
@@ -94,7 +97,10 @@ enum iFontId { | |||
94 | }; | 97 | }; |
95 | 98 | ||
96 | iLocalDef iBool isJapanese_FontId(enum iFontId id) { | 99 | iLocalDef iBool isJapanese_FontId(enum iFontId id) { |
97 | return id >= smallJapanese_FontId && id <= hugeJapanese_FontId; | 100 | return id >= defaultJapanese_FontId && id <= hugeJapanese_FontId; |
101 | } | ||
102 | iLocalDef iBool isVariationSelector_Char(iChar ch) { | ||
103 | return ch >= 0xfe00 && ch <= 0xfe0f; | ||
98 | } | 104 | } |
99 | 105 | ||
100 | #define variationSelectorEmoji_Char ((iChar) 0xfe0f) | 106 | #define variationSelectorEmoji_Char ((iChar) 0xfe0f) |