diff options
-rw-r--r-- | res/about/help.gmi | 2 | ||||
-rw-r--r-- | src/ui/text.c | 93 |
2 files changed, 51 insertions, 44 deletions
diff --git a/res/about/help.gmi b/res/about/help.gmi index 540ca8aa..92cffa08 100644 --- a/res/about/help.gmi +++ b/res/about/help.gmi | |||
@@ -177,7 +177,7 @@ You can find a number of settings in Preferences to customize what the user inte | |||
177 | 177 | ||
178 | ### Page style | 178 | ### Page style |
179 | 179 | ||
180 | * Font: At the moment, two font options are provided. "Nunito" is a friendly rounded font with generous leading. "Fira Sans" is more angular and narrow, and has a tighter leading. | 180 | * Font: At the moment, two font options are provided. "Nunito" is a friendly rounded font. "Fira Sans" is bolder and more angular. |
181 | * Line width: This setting determines the maximum width for text lines. "Window" disables the maximum limit and fits text lines to the full width of the window. Shorter lines are generally easier to read. | 181 | * Line width: This setting determines the maximum width for text lines. "Window" disables the maximum limit and fits text lines to the full width of the window. Shorter lines are generally easier to read. |
182 | * Big 1st paragraph: When enabled, the leading paragraph on the page is shown in a slightly larger font. | 182 | * Big 1st paragraph: When enabled, the leading paragraph on the page is shown in a slightly larger font. |
183 | 183 | ||
diff --git a/src/ui/text.c b/src/ui/text.c index 23524808..12a72836 100644 --- a/src/ui/text.c +++ b/src/ui/text.c | |||
@@ -86,6 +86,7 @@ struct Impl_Font { | |||
86 | iBlock * data; | 86 | iBlock * data; |
87 | stbtt_fontinfo font; | 87 | stbtt_fontinfo font; |
88 | float scale; | 88 | float scale; |
89 | int vertOffset; /* offset due to scaling */ | ||
89 | int height; | 90 | int height; |
90 | int baseline; | 91 | int baseline; |
91 | iHash glyphs; | 92 | iHash glyphs; |
@@ -98,13 +99,14 @@ struct Impl_Font { | |||
98 | 99 | ||
99 | static iFont *font_Text_(enum iFontId id); | 100 | static iFont *font_Text_(enum iFontId id); |
100 | 101 | ||
101 | static void init_Font(iFont *d, const iBlock *data, int height, enum iFontId symbolsFont) { | 102 | static void init_Font(iFont *d, const iBlock *data, int height, float scale, enum iFontId symbolsFont) { |
102 | init_Hash(&d->glyphs); | 103 | init_Hash(&d->glyphs); |
103 | d->data = NULL; | 104 | d->data = NULL; |
104 | d->height = height; | 105 | d->height = height; |
105 | iZap(d->font); | 106 | iZap(d->font); |
106 | stbtt_InitFont(&d->font, constData_Block(data), 0); | 107 | stbtt_InitFont(&d->font, constData_Block(data), 0); |
107 | d->scale = stbtt_ScaleForPixelHeight(&d->font, height); | 108 | d->scale = stbtt_ScaleForPixelHeight(&d->font, height) * scale; |
109 | d->vertOffset = height * (1.0f - scale) / 2; | ||
108 | int ascent; | 110 | int ascent; |
109 | stbtt_GetFontVMetrics(&d->font, &ascent, NULL, NULL); | 111 | stbtt_GetFontVMetrics(&d->font, &ascent, NULL, NULL); |
110 | d->baseline = (int) ascent * d->scale; | 112 | d->baseline = (int) ascent * d->scale; |
@@ -164,65 +166,69 @@ static void initFonts_Text_(iText *d) { | |||
164 | const iBlock *italicFont = &fontNunitoLightItalic_Embedded; | 166 | const iBlock *italicFont = &fontNunitoLightItalic_Embedded; |
165 | const iBlock *boldFont = &fontNunitoExtraBold_Embedded; | 167 | const iBlock *boldFont = &fontNunitoExtraBold_Embedded; |
166 | const iBlock *lightFont = &fontNunitoExtraLight_Embedded; | 168 | const iBlock *lightFont = &fontNunitoExtraLight_Embedded; |
169 | float scaling = 1.0f; | ||
167 | if (d->contentFont == firaSans_TextFont) { | 170 | if (d->contentFont == firaSans_TextFont) { |
168 | regularFont = &fontFiraSansRegular_Embedded; | 171 | regularFont = &fontFiraSansRegular_Embedded; |
169 | italicFont = &fontFiraSansItalic_Embedded; | 172 | italicFont = &fontFiraSansItalic_Embedded; |
170 | boldFont = &fontFiraSansBold_Embedded; | 173 | boldFont = &fontFiraSansBold_Embedded; |
171 | lightFont = &fontFiraSansLight_Embedded; | 174 | lightFont = &fontFiraSansLight_Embedded; |
175 | scaling = 0.85f; | ||
172 | } | 176 | } |
173 | const struct { | 177 | const struct { |
174 | const iBlock *ttf; | 178 | const iBlock *ttf; |
175 | int size; | 179 | int size; |
180 | float scaling; | ||
176 | int symbolsFont; | 181 | int symbolsFont; |
177 | } fontData[max_FontId] = { | 182 | } fontData[max_FontId] = { |
178 | { &fontSourceSansProRegular_Embedded, fontSize_UI, defaultSymbols_FontId }, | 183 | { &fontSourceSansProRegular_Embedded, fontSize_UI, 1.0f, defaultSymbols_FontId }, |
179 | { &fontSourceSansProRegular_Embedded, fontSize_UI * 1.125f, defaultMediumSymbols_FontId }, | 184 | { &fontSourceSansProRegular_Embedded, fontSize_UI * 1.125f, 1.0f, defaultMediumSymbols_FontId }, |
180 | { &fontFiraMonoRegular_Embedded, fontSize_UI * 0.866f, defaultSymbols_FontId }, | 185 | { &fontFiraMonoRegular_Embedded, fontSize_UI * 0.866f, 1.0f, defaultSymbols_FontId }, |
181 | /* content fonts */ | 186 | /* content fonts */ |
182 | { regularFont, textSize, symbols_FontId }, | 187 | { regularFont, textSize, scaling, symbols_FontId }, |
183 | { &fontFiraMonoRegular_Embedded, monoSize, monospaceSymbols_FontId }, | 188 | { &fontFiraMonoRegular_Embedded, monoSize, 1.0f, monospaceSymbols_FontId }, |
184 | { &fontFiraMonoRegular_Embedded, monoSize * 0.750f, monospaceSmallSymbols_FontId }, | 189 | { &fontFiraMonoRegular_Embedded, monoSize * 0.750f, 1.0f, monospaceSmallSymbols_FontId }, |
185 | { regularFont, textSize * 1.200f, mediumSymbols_FontId }, | 190 | { regularFont, textSize * 1.200f, scaling, mediumSymbols_FontId }, |
186 | { regularFont, textSize * 1.333f, bigSymbols_FontId }, | 191 | { regularFont, textSize * 1.333f, scaling, bigSymbols_FontId }, |
187 | { italicFont, textSize, symbols_FontId }, | 192 | { italicFont, textSize, scaling, symbols_FontId }, |
188 | { boldFont, textSize, symbols_FontId }, | 193 | { boldFont, textSize, scaling, symbols_FontId }, |
189 | { boldFont, textSize * 1.333f, mediumSymbols_FontId }, | 194 | { boldFont, textSize * 1.333f, scaling, mediumSymbols_FontId }, |
190 | { boldFont, textSize * 1.666f, largeSymbols_FontId }, | 195 | { boldFont, textSize * 1.666f, scaling, largeSymbols_FontId }, |
191 | { boldFont, textSize * 2.000f, hugeSymbols_FontId }, | 196 | { boldFont, textSize * 2.000f, scaling, hugeSymbols_FontId }, |
192 | { lightFont, textSize * 1.666f, largeSymbols_FontId }, | 197 | { lightFont, textSize * 1.666f, scaling, largeSymbols_FontId }, |
193 | /* symbol fonts */ | 198 | /* symbol fonts */ |
194 | { &fontSymbola_Embedded, fontSize_UI, defaultSymbols_FontId }, | 199 | { &fontSymbola_Embedded, fontSize_UI, 1.0f, defaultSymbols_FontId }, |
195 | { &fontSymbola_Embedded, fontSize_UI * 1.125f, defaultMediumSymbols_FontId }, | 200 | { &fontSymbola_Embedded, fontSize_UI * 1.125f, 1.0f, defaultMediumSymbols_FontId }, |
196 | { &fontSymbola_Embedded, textSize, symbols_FontId }, | 201 | { &fontSymbola_Embedded, textSize, 1.0f, symbols_FontId }, |
197 | { &fontSymbola_Embedded, textSize * 1.200f, mediumSymbols_FontId }, | 202 | { &fontSymbola_Embedded, textSize * 1.200f, 1.0f, mediumSymbols_FontId }, |
198 | { &fontSymbola_Embedded, textSize * 1.333f, bigSymbols_FontId }, | 203 | { &fontSymbola_Embedded, textSize * 1.333f, 1.0f, bigSymbols_FontId }, |
199 | { &fontSymbola_Embedded, textSize * 1.666f, largeSymbols_FontId }, | 204 | { &fontSymbola_Embedded, textSize * 1.666f, 1.0f, largeSymbols_FontId }, |
200 | { &fontSymbola_Embedded, textSize * 2.000f, hugeSymbols_FontId }, | 205 | { &fontSymbola_Embedded, textSize * 2.000f, 1.0f, hugeSymbols_FontId }, |
201 | { &fontSymbola_Embedded, monoSize, monospaceSymbols_FontId }, | 206 | { &fontSymbola_Embedded, monoSize, 1.0f, monospaceSymbols_FontId }, |
202 | { &fontSymbola_Embedded, monoSize * 0.750f, monospaceSmallSymbols_FontId }, | 207 | { &fontSymbola_Embedded, monoSize * 0.750f, 1.0f, monospaceSmallSymbols_FontId }, |
203 | /* emoji fonts */ | 208 | /* emoji fonts */ |
204 | { &fontNotoEmojiRegular_Embedded, fontSize_UI, defaultSymbols_FontId }, | 209 | { &fontNotoEmojiRegular_Embedded, fontSize_UI, 1.0f, defaultSymbols_FontId }, |
205 | { &fontNotoEmojiRegular_Embedded, fontSize_UI * 1.125f, defaultMediumSymbols_FontId }, | 210 | { &fontNotoEmojiRegular_Embedded, fontSize_UI * 1.125f, 1.0f, defaultMediumSymbols_FontId }, |
206 | { &fontNotoEmojiRegular_Embedded, textSize, symbols_FontId }, | 211 | { &fontNotoEmojiRegular_Embedded, textSize, 1.0f, symbols_FontId }, |
207 | { &fontNotoEmojiRegular_Embedded, textSize * 1.200f, mediumSymbols_FontId }, | 212 | { &fontNotoEmojiRegular_Embedded, textSize * 1.200f, 1.0f, mediumSymbols_FontId }, |
208 | { &fontNotoEmojiRegular_Embedded, textSize * 1.333f, bigSymbols_FontId }, | 213 | { &fontNotoEmojiRegular_Embedded, textSize * 1.333f, 1.0f, bigSymbols_FontId }, |
209 | { &fontNotoEmojiRegular_Embedded, textSize * 1.666f, largeSymbols_FontId }, | 214 | { &fontNotoEmojiRegular_Embedded, textSize * 1.666f, 1.0f, largeSymbols_FontId }, |
210 | { &fontNotoEmojiRegular_Embedded, textSize * 2.000f, hugeSymbols_FontId }, | 215 | { &fontNotoEmojiRegular_Embedded, textSize * 2.000f, 1.0f, hugeSymbols_FontId }, |
211 | { &fontNotoEmojiRegular_Embedded, monoSize, monospaceSymbols_FontId }, | 216 | { &fontNotoEmojiRegular_Embedded, monoSize, 1.0f, monospaceSymbols_FontId }, |
212 | { &fontNotoEmojiRegular_Embedded, monoSize * 0.750f, monospaceSmallSymbols_FontId }, | 217 | { &fontNotoEmojiRegular_Embedded, monoSize * 0.750f, 1.0f, monospaceSmallSymbols_FontId }, |
213 | /* japanese fonts */ | 218 | /* japanese fonts */ |
214 | { &fontKosugiMaruRegular_Embedded, fontSize_UI, defaultSymbols_FontId }, | 219 | { &fontKosugiMaruRegular_Embedded, fontSize_UI, 1.0f, defaultSymbols_FontId }, |
215 | { &fontKosugiMaruRegular_Embedded, monoSize * 0.750, monospaceSmallSymbols_FontId }, | 220 | { &fontKosugiMaruRegular_Embedded, monoSize * 0.750, 1.0f, monospaceSmallSymbols_FontId }, |
216 | { &fontKosugiMaruRegular_Embedded, monoSize, monospaceSymbols_FontId }, | 221 | { &fontKosugiMaruRegular_Embedded, monoSize, 1.0f, monospaceSymbols_FontId }, |
217 | { &fontKosugiMaruRegular_Embedded, textSize, symbols_FontId }, | 222 | { &fontKosugiMaruRegular_Embedded, textSize, 1.0f, symbols_FontId }, |
218 | { &fontKosugiMaruRegular_Embedded, textSize * 1.200f, mediumSymbols_FontId }, | 223 | { &fontKosugiMaruRegular_Embedded, textSize * 1.200f, 1.0f, mediumSymbols_FontId }, |
219 | { &fontKosugiMaruRegular_Embedded, textSize * 1.333f, bigSymbols_FontId }, | 224 | { &fontKosugiMaruRegular_Embedded, textSize * 1.333f, 1.0f, bigSymbols_FontId }, |
220 | { &fontKosugiMaruRegular_Embedded, textSize * 1.666f, largeSymbols_FontId }, | 225 | { &fontKosugiMaruRegular_Embedded, textSize * 1.666f, 1.0f, largeSymbols_FontId }, |
221 | { &fontKosugiMaruRegular_Embedded, textSize * 2.000f, hugeSymbols_FontId }, | 226 | { &fontKosugiMaruRegular_Embedded, textSize * 2.000f, 1.0f, hugeSymbols_FontId }, |
222 | }; | 227 | }; |
223 | iForIndices(i, fontData) { | 228 | iForIndices(i, fontData) { |
224 | iFont *font = &d->fonts[i]; | 229 | iFont *font = &d->fonts[i]; |
225 | init_Font(font, fontData[i].ttf, fontData[i].size, fontData[i].symbolsFont); | 230 | init_Font( |
231 | font, fontData[i].ttf, fontData[i].size, fontData[i].scaling, fontData[i].symbolsFont); | ||
226 | if (fontData[i].ttf == &fontFiraMonoRegular_Embedded) { | 232 | if (fontData[i].ttf == &fontFiraMonoRegular_Embedded) { |
227 | font->isMonospaced = iTrue; | 233 | font->isMonospaced = iTrue; |
228 | } | 234 | } |
@@ -427,6 +433,7 @@ static void cache_Font_(iFont *d, iGlyph *glyph, int hoff) { | |||
427 | &glyph->d[hoff].y, | 433 | &glyph->d[hoff].y, |
428 | NULL, | 434 | NULL, |
429 | NULL); | 435 | NULL); |
436 | glyph->d[hoff].y += d->vertOffset; | ||
430 | tex = SDL_CreateTextureFromSurface(render, surface); | 437 | tex = SDL_CreateTextureFromSurface(render, surface); |
431 | SDL_SetTextureBlendMode(tex, SDL_BLENDMODE_NONE); | 438 | SDL_SetTextureBlendMode(tex, SDL_BLENDMODE_NONE); |
432 | glRect->size = init_I2(surface->w, surface->h); | 439 | glRect->size = init_I2(surface->w, surface->h); |