diff options
-rw-r--r-- | src/ui/text.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/src/ui/text.c b/src/ui/text.c index 686927b1..1761a87c 100644 --- a/src/ui/text.c +++ b/src/ui/text.c | |||
@@ -110,7 +110,7 @@ static void init_Font(iFont *d, const iBlock *data, int height, float scale, enu | |||
110 | d->vertOffset = height * (1.0f - scale) / 2; | 110 | d->vertOffset = height * (1.0f - scale) / 2; |
111 | int ascent; | 111 | int ascent; |
112 | stbtt_GetFontVMetrics(&d->font, &ascent, NULL, NULL); | 112 | stbtt_GetFontVMetrics(&d->font, &ascent, NULL, NULL); |
113 | d->baseline = (int) ascent * d->scale; | 113 | d->baseline = ceil(ascent * d->scale); |
114 | d->symbolsFont = symbolsFont; | 114 | d->symbolsFont = symbolsFont; |
115 | d->japaneseFont = regularJapanese_FontId; | 115 | d->japaneseFont = regularJapanese_FontId; |
116 | d->koreanFont = regularKorean_FontId; | 116 | d->koreanFont = regularKorean_FontId; |
@@ -714,6 +714,7 @@ static iRect run_Font_(iFont *d, enum iRunMode mode, iRangecc text, size_t maxLe | |||
714 | } | 714 | } |
715 | break; | 715 | break; |
716 | } | 716 | } |
717 | const int yLineMax = pos.y + d->height; | ||
717 | SDL_Rect dst = { x1 + glyph->d[hoff].x, | 718 | SDL_Rect dst = { x1 + glyph->d[hoff].x, |
718 | pos.y + glyph->font->baseline + glyph->d[hoff].y, | 719 | pos.y + glyph->font->baseline + glyph->d[hoff].y, |
719 | glyph->rect[hoff].size.x, | 720 | glyph->rect[hoff].size.x, |
@@ -733,13 +734,26 @@ static iRect run_Font_(iFont *d, enum iRunMode mode, iRangecc text, size_t maxLe | |||
733 | } | 734 | } |
734 | const iBool useMonoAdvance = | 735 | const iBool useMonoAdvance = |
735 | monoAdvance > 0 && !isJapanese_FontId(fontId_Text_(glyph->font)); | 736 | monoAdvance > 0 && !isJapanese_FontId(fontId_Text_(glyph->font)); |
736 | const float advance = (useMonoAdvance ? monoAdvance : glyph->advance); | 737 | /* The -0.25f is to mitigate issues with box-drawing characters sometimes rounding |
738 | up to leave a hairline gap with the previous character. The purpose is to overlap | ||
739 | the glyphs slightly, since they are rendered antialiased and unhinted, which means | ||
740 | the right edge pixels may end up partially non-opaque. */ | ||
741 | const float advance = (useMonoAdvance ? monoAdvance - 0.25f : glyph->advance); | ||
737 | if (!isMeasuring_(mode)) { | 742 | if (!isMeasuring_(mode)) { |
738 | if (useMonoAdvance && dst.w > advance && glyph->font != d) { | 743 | if (useMonoAdvance && dst.w > advance && glyph->font != d) { |
739 | /* Glyphs from a different font may need recentering to look better. */ | 744 | /* Glyphs from a different font may need recentering to look better. */ |
740 | dst.x -= (dst.w - advance) / 2; | 745 | dst.x -= (dst.w - advance) / 2; |
741 | } | 746 | } |
742 | SDL_RenderCopy(text_.render, text_.cache, (const SDL_Rect *) &glyph->rect[hoff], &dst); | 747 | SDL_Rect src; |
748 | memcpy(&src, &glyph->rect[hoff], sizeof(SDL_Rect)); | ||
749 | /* Clip the glyphs to the font's height. This is useful when the font's line spacing | ||
750 | has been reduced or when the glyph is from a different font. */ | ||
751 | if (dst.y + dst.h > yLineMax) { | ||
752 | const int over = dst.y + dst.h - yLineMax; | ||
753 | src.h -= over; | ||
754 | dst.h -= over; | ||
755 | } | ||
756 | SDL_RenderCopy(text_.render, text_.cache, &src, &dst); | ||
743 | } | 757 | } |
744 | /* Symbols and emojis are NOT monospaced, so must conform when the primary font | 758 | /* Symbols and emojis are NOT monospaced, so must conform when the primary font |
745 | is monospaced. Except with Japanese script, that's larger than the normal monospace. */ | 759 | is monospaced. Except with Japanese script, that's larger than the normal monospace. */ |