summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-07-02 08:07:55 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-07-02 08:07:55 +0300
commitcc3e6add4dff47306ad877ad59cb8f93feb14d0d (patch)
tree4102f2dad90b2b177aaec977086cc4f2c68b2004 /src
parent93eb4851d708cd152d848ed05b8f2134b0db1a2d (diff)
Text: Nunito kerning adjustment
Diffstat (limited to 'src')
-rw-r--r--src/ui/text.c72
1 files changed, 66 insertions, 6 deletions
diff --git a/src/ui/text.c b/src/ui/text.c
index c8177096..7d141217 100644
--- a/src/ui/text.c
+++ b/src/ui/text.c
@@ -131,18 +131,25 @@ struct Impl_Font {
131 int baseline; 131 int baseline;
132 iHash glyphs; /* key is glyph index in the font */ /* TODO: does not need to be a Hash */ 132 iHash glyphs; /* key is glyph index in the font */ /* TODO: does not need to be a Hash */
133 iBool isMonospaced; 133 iBool isMonospaced;
134 iBool manualKernOnly; 134// iBool manualKernOnly;
135 enum iFontSize sizeId; /* used to look up different fonts of matching size */ 135 enum iFontSize sizeId; /* used to look up different fonts of matching size */
136 uint32_t indexTable[128 - 32]; /* quick ASCII lookup */ 136 uint32_t indexTable[128 - 32]; /* quick ASCII lookup */
137#if defined (LAGRANGE_ENABLE_HARFBUZZ) 137#if defined (LAGRANGE_ENABLE_HARFBUZZ)
138 hb_blob_t * hbBlob; /* raw TrueType data */ 138 hb_blob_t * hbBlob; /* raw TrueType data */
139 hb_face_t * hbFace; 139 hb_face_t * hbFace;
140 hb_font_t * hbFont; 140 hb_font_t * hbMainFont;
141 hb_font_t * hbFont; /* may be a sub-font with customized font metrics */
141#endif 142#endif
142}; 143};
143 144
144static iFont *font_Text_(enum iFontId id); 145static iFont *font_Text_(enum iFontId id);
145 146
147static hb_position_t hbGlyphHKernForNunito_(hb_font_t *font, void *fontData,
148 hb_codepoint_t firstGlyph, hb_codepoint_t secondGlyph,
149 void *userData) {
150 return 100;
151}
152
146static void init_Font(iFont *d, const iBlock *data, int height, float scale, 153static void init_Font(iFont *d, const iBlock *data, int height, float scale,
147 enum iFontSize sizeId, iBool isMonospaced) { 154 enum iFontSize sizeId, iBool isMonospaced) {
148 init_Hash(&d->glyphs); 155 init_Hash(&d->glyphs);
@@ -191,7 +198,23 @@ static void init_Font(iFont *d, const iBlock *data, int height, float scale,
191 d->hbBlob = hb_blob_create(constData_Block(data), size_Block(data), 198 d->hbBlob = hb_blob_create(constData_Block(data), size_Block(data),
192 HB_MEMORY_MODE_READONLY, NULL, NULL); 199 HB_MEMORY_MODE_READONLY, NULL, NULL);
193 d->hbFace = hb_face_create(d->hbBlob, 0); 200 d->hbFace = hb_face_create(d->hbBlob, 0);
194 d->hbFont = hb_font_create(d->hbFace); 201 d->hbMainFont = hb_font_create(d->hbFace);
202#if 0
203 /* TODO: The custom kerning function doesn't get called?
204 Maybe HarfBuzz needs FreeType to do kerning? */
205 if (d->family == nunito_TextFont) {
206 /* Customize the kerning of Nunito. */
207 d->hbFont = hb_font_create_sub_font(d->hbMainFont);
208 hb_font_funcs_t *ffs = hb_font_funcs_create();
209 hb_font_funcs_set_glyph_h_kerning_func(ffs, hbGlyphHKernForNunito_, d, NULL);
210 hb_font_set_funcs(d->hbFont, ffs, NULL, NULL);
211 hb_font_funcs_destroy(ffs);
212 }
213 else
214#endif
215 {
216 d->hbFont = hb_font_reference(d->hbMainFont);
217 }
195 } 218 }
196#endif 219#endif
197} 220}
@@ -207,6 +230,7 @@ static void deinit_Font(iFont *d) {
207#if defined(LAGRANGE_ENABLE_HARFBUZZ) 230#if defined(LAGRANGE_ENABLE_HARFBUZZ)
208 /* HarfBuzz objects. */ { 231 /* HarfBuzz objects. */ {
209 hb_font_destroy(d->hbFont); 232 hb_font_destroy(d->hbFont);
233 hb_font_destroy(d->hbMainFont);
210 hb_face_destroy(d->hbFace); 234 hb_face_destroy(d->hbFace);
211 hb_blob_destroy(d->hbBlob); 235 hb_blob_destroy(d->hbBlob);
212 } 236 }
@@ -395,9 +419,9 @@ static void initFonts_Text_(iText *d) {
395 fontData[i].scaling, 419 fontData[i].scaling,
396 fontData[i].sizeId, 420 fontData[i].sizeId,
397 fontData[i].ttf == &fontIosevkaTermExtended_Embedded); 421 fontData[i].ttf == &fontIosevkaTermExtended_Embedded);
398 if (i == default_FontId || i == defaultMedium_FontId) { 422// if (i == default_FontId || i == defaultMedium_FontId) {
399 font->manualKernOnly = iTrue; 423// font->manualKernOnly = iTrue;
400 } 424// }
401 } 425 }
402 gap_Text = iRound(gap_UI * d->contentFontSize); 426 gap_Text = iRound(gap_UI * d->contentFontSize);
403} 427}
@@ -1065,6 +1089,32 @@ static iBool notify_WrapText_(iWrapText *d, const char *ending, int advance) {
1065 return iTrue; 1089 return iTrue;
1066} 1090}
1067 1091
1092float horizKern_Font_(iFont *d, uint32_t glyph1, uint32_t glyph2) {
1093#if defined (LAGRANGE_ENABLE_KERNING)
1094 if (!enableKerning_Text || d->family != nunito_TextFont) {
1095 return 0.0f;
1096 }
1097 if (glyph1 && glyph2) {
1098 /* These indices will be quickly found from the lookup table. */
1099 const uint32_t gi_h = glyphIndex_Font_(d, 'h');
1100 const uint32_t gi_i = glyphIndex_Font_(d, 'i');
1101 int kern = 0;
1102 /* Nunito needs some kerning fixes. */
1103 if (glyph1 == glyphIndex_Font_(d, 'W') && (glyph2 == gi_h || glyph2 == gi_i)) {
1104 kern = -60;
1105 }
1106 else if (glyph1 == glyphIndex_Font_(d, 'T') && glyph2 == gi_h) {
1107 kern = -25;
1108 }
1109 else if (glyph1 == glyphIndex_Font_(d, 'V') && glyph2 == gi_i) {
1110 kern = -40;
1111 }
1112 return d->xScale * kern;
1113 }
1114#endif
1115 return 0.0f;
1116}
1117
1068#if defined (LAGRANGE_ENABLE_HARFBUZZ) 1118#if defined (LAGRANGE_ENABLE_HARFBUZZ)
1069static iRect run_Font_(iFont *d, const iRunArgs *args) { 1119static iRect run_Font_(iFont *d, const iRunArgs *args) {
1070 const int mode = args->mode; 1120 const int mode = args->mode;
@@ -1168,6 +1218,11 @@ static iRect run_Font_(iFont *d, const iRunArgs *args) {
1168 break; 1218 break;
1169 } 1219 }
1170 x += xAdvance; 1220 x += xAdvance;
1221 /* Additional kerning tweak. It would be better to use HarfBuzz font callbacks,
1222 but they don't seem to get called? */
1223 if (i + 1 < glyphCount) {
1224 x += horizKern_Font_(run->font, glyphId, glyphInfo[i + 1].codepoint);
1225 }
1171 } 1226 }
1172 /* Make a callback for each wrapped line. */ 1227 /* Make a callback for each wrapped line. */
1173 if (breakPos) { 1228 if (breakPos) {
@@ -1244,6 +1299,11 @@ static iRect run_Font_(iFont *d, const iRunArgs *args) {
1244 } 1299 }
1245 xCursor += xAdvance; 1300 xCursor += xAdvance;
1246 yCursor += yAdvance; 1301 yCursor += yAdvance;
1302 /* Additional kerning tweak. It would be better to use HarfBuzz font callbacks,
1303 but they don't seem to get called? */
1304 if (i + 1 < glyphCount) {
1305 xCursor += horizKern_Font_(run->font, glyphId, glyphInfo[i + 1].codepoint);
1306 }
1247 xCursorMax = iMax(xCursorMax, xCursor); 1307 xCursorMax = iMax(xCursorMax, xCursor);
1248 } 1308 }
1249 if (willAbortDueToWrap) { 1309 if (willAbortDueToWrap) {