summaryrefslogtreecommitdiff
path: root/src/ui
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-10-08 15:27:14 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-10-08 15:27:14 +0300
commit52b6013cc01e17f4b500ea79fb786ccc14b1f7ec (patch)
treed3f1a91a282cbb225d8578fabf18a2690205738d /src/ui
parentdeea4951aa8e4068daccb15b7960aa84ebfe906f (diff)
Font configuration; Prefs has a string value array
Added a second version of Iosevka with more line spacing, to be used as the default monospace document font.
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/documentwidget.c4
-rw-r--r--src/ui/labelwidget.c4
-rw-r--r--src/ui/root.c3
-rw-r--r--src/ui/text.c77
-rw-r--r--src/ui/text.h116
-rw-r--r--src/ui/util.c73
6 files changed, 137 insertions, 140 deletions
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index 2ba2fa12..45a8cf2d 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -496,7 +496,7 @@ static int documentWidth_DocumentWidget_(const iDocumentWidget *d) {
496 -1.0f, 10.0f); /* adapt to width */ 496 -1.0f, 10.0f); /* adapt to width */
497 //printf("%f\n", adjust); fflush(stdout); 497 //printf("%f\n", adjust); fflush(stdout);
498 return iMini(iMax(minWidth, bounds.size.x - gap_UI * (d->pageMargin + adjust) * 2), 498 return iMini(iMax(minWidth, bounds.size.x - gap_UI * (d->pageMargin + adjust) * 2),
499 fontSize_UI * emRatio_Text(paragraph_FontId) * /* dependent on avg. glyph width */ 499 fontSize_UI * //emRatio_Text(paragraph_FontId) * /* dependent on avg. glyph width */
500 prefs->lineWidth * prefs->zoomPercent / 100); 500 prefs->lineWidth * prefs->zoomPercent / 100);
501} 501}
502 502
@@ -3441,7 +3441,7 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e
3441 return iTrue; 3441 return iTrue;
3442 } 3442 }
3443 break; 3443 break;
3444#if 1 3444#if !defined (NDEBUG)
3445 case SDLK_KP_1: 3445 case SDLK_KP_1:
3446 case '`': { 3446 case '`': {
3447 iBlock *seed = new_Block(64); 3447 iBlock *seed = new_Block(64);
diff --git a/src/ui/labelwidget.c b/src/ui/labelwidget.c
index cfc81863..9713e1f2 100644
--- a/src/ui/labelwidget.c
+++ b/src/ui/labelwidget.c
@@ -384,7 +384,7 @@ static void draw_LabelWidget_(const iLabelWidget *d) {
384 } 384 }
385 else if (flags & alignLeft_WidgetFlag) { 385 else if (flags & alignLeft_WidgetFlag) {
386 draw_Text(d->font, add_I2(bounds.pos, addX_I2(padding_LabelWidget_(d, 0), iconPad)), 386 draw_Text(d->font, add_I2(bounds.pos, addX_I2(padding_LabelWidget_(d, 0), iconPad)),
387 fg, cstr_String(&d->label)); 387 fg, "%s", cstr_String(&d->label));
388 if ((flags & drawKey_WidgetFlag) && d->key) { 388 if ((flags & drawKey_WidgetFlag) && d->key) {
389 iString str; 389 iString str;
390 init_String(&str); 390 init_String(&str);
@@ -399,6 +399,7 @@ static void draw_LabelWidget_(const iLabelWidget *d) {
399 : colorEscape != none_ColorId ? colorEscape 399 : colorEscape != none_ColorId ? colorEscape
400 : uiTextShortcut_ColorId,*/ 400 : uiTextShortcut_ColorId,*/
401 right_Alignment, 401 right_Alignment,
402 "%s",
402 cstr_String(&str)); 403 cstr_String(&str));
403 deinit_String(&str); 404 deinit_String(&str);
404 } 405 }
@@ -409,6 +410,7 @@ static void draw_LabelWidget_(const iLabelWidget *d) {
409 add_I2(topRight_Rect(bounds), negX_I2(padding_LabelWidget_(d, 1))), 410 add_I2(topRight_Rect(bounds), negX_I2(padding_LabelWidget_(d, 1))),
410 fg, 411 fg,
411 right_Alignment, 412 right_Alignment,
413 "%s",
412 cstr_String(&d->label)); 414 cstr_String(&d->label));
413 } 415 }
414 else { 416 else {
diff --git a/src/ui/root.c b/src/ui/root.c
index a2e6062f..f6d6f11d 100644
--- a/src/ui/root.c
+++ b/src/ui/root.c
@@ -566,7 +566,8 @@ static iBool willPerformSearchQuery_(const iString *userInput) {
566 if (isEmpty_String(clean)) { 566 if (isEmpty_String(clean)) {
567 return iFalse; 567 return iFalse;
568 } 568 }
569 return !isEmpty_String(&prefs_App()->searchUrl) && !isLikelyUrl_String(userInput); 569 return !isEmpty_String(&prefs_App()->strings[searchUrl_PrefsString]) &&
570 !isLikelyUrl_String(userInput);
570} 571}
571 572
572static void updateUrlInputContentPadding_(iWidget *navBar) { 573static void updateUrlInputContentPadding_(iWidget *navBar) {
diff --git a/src/ui/text.c b/src/ui/text.c
index 8adfa019..14b4e305 100644
--- a/src/ui/text.c
+++ b/src/ui/text.c
@@ -171,7 +171,8 @@ iLocalDef iBool isMonospaced_Font(const iFont *d) {
171static iFont *font_Text_(enum iFontId id); 171static iFont *font_Text_(enum iFontId id);
172 172
173static void init_Font(iFont *d, const iFontSpec *fontSpec, const iFontFile *fontFile, 173static void init_Font(iFont *d, const iFontSpec *fontSpec, const iFontFile *fontFile,
174 enum iFontSize sizeId, int height) { 174 enum iFontSize sizeId, float height) {
175 const int scaleType = scaleType_FontSpec(sizeId);
175 d->fontSpec = fontSpec; 176 d->fontSpec = fontSpec;
176 d->fontFile = fontFile; 177 d->fontFile = fontFile;
177 /* TODO: Nunito kerning fixes need to be a font parameter of its own. */ 178 /* TODO: Nunito kerning fixes need to be a font parameter of its own. */
@@ -197,15 +198,9 @@ static void init_Font(iFont *d, const iFontSpec *fontSpec, const iFontFile *font
197 d->family = emojiAndSymbols_TextFont; 198 d->family = emojiAndSymbols_TextFont;
198 } 199 }
199#endif 200#endif
200// d->isMonospaced = (fontSpec->flags & monospace_FontSpecFlag) != 0; 201 d->height = (int) (height * fontSpec->heightScale[scaleType]);
201 d->height = height; 202 const float glyphScale = fontSpec->glyphScale[scaleType];
202 //iZap(d->font); 203 d->xScale = d->yScale = scaleForPixelHeight_FontFile(fontFile, d->height) * glyphScale;
203// stbtt_InitFont(&d->font, constData_Block(data), 0);
204// int ascent, descent, emAdv;
205// stbtt_GetFontVMetrics(&d->font, &ascent, &descent, NULL);
206// stbtt_GetCodepointHMetrics(&d->font, 'M', &emAdv, NULL);
207 const float scale = fontSpec->scaling;
208 d->xScale = d->yScale = scaleForPixelHeight_FontFile(fontFile, height) * scale;
209 if (isMonospaced_Font(d)) { 204 if (isMonospaced_Font(d)) {
210 /* It is important that monospaced fonts align 1:1 with the pixel grid so that 205 /* It is important that monospaced fonts align 1:1 with the pixel grid so that
211 box-drawing characters don't have partially occupied edge pixels, leading to seams 206 box-drawing characters don't have partially occupied edge pixels, leading to seams
@@ -217,8 +212,9 @@ static void init_Font(iFont *d, const iFontSpec *fontSpec, const iFontFile *font
217 } 212 }
218 d->emAdvance = fontFile->emAdvance * d->xScale; 213 d->emAdvance = fontFile->emAdvance * d->xScale;
219 d->baseline = fontFile->ascent * d->yScale; 214 d->baseline = fontFile->ascent * d->yScale;
220 d->vertOffset = height * (1.0f - scale) / 2 * fontSpec->vertOffset; 215 d->vertOffset = d->height * (1.0f - glyphScale) / 2 * fontSpec->vertOffsetScale[scaleType];
221 d->table = NULL; 216 d->table = NULL;
217 // printf("{%s} height:%d baseline:%d\n", cstr_String(&d->fontSpec->id), d->height, d->baseline);
222} 218}
223 219
224static void deinit_Font(iFont *d) { 220static void deinit_Font(iFont *d) {
@@ -252,8 +248,8 @@ struct Impl_CacheRow {
252}; 248};
253 249
254struct Impl_Text { 250struct Impl_Text {
255 enum iTextFont contentFont; 251// enum iTextFont contentFont;
256 enum iTextFont headingFont; 252// enum iTextFont headingFont;
257 float contentFontSize; 253 float contentFontSize;
258 iArray fonts; /* fonts currently selected for use (incl. all styles/sizes) */ 254 iArray fonts; /* fonts currently selected for use (incl. all styles/sizes) */
259 int overrideFontId; /* always checked for glyphs first, regardless of which font is used */ 255 int overrideFontId; /* always checked for glyphs first, regardless of which font is used */
@@ -290,7 +286,8 @@ static void setupFontVariants_Text_(iText *d, const iFontSpec *spec, int baseId)
290 spec, 286 spec,
291 spec->styles[style], 287 spec->styles[style],
292 sizeId, 288 sizeId,
293 (sizeId < contentRegular_FontSize ? uiSize : textSize) * scale_FontSize(sizeId)); 289 (sizeId < contentRegular_FontSize ? uiSize : textSize) *
290 scale_FontSize(sizeId));
294 } 291 }
295 } 292 }
296} 293}
@@ -311,6 +308,11 @@ iLocalDef enum iFontStyle styleId_Text_(const iFont *d) {
311 return (fontId_Text_(d) / max_FontSize) % max_FontStyle; 308 return (fontId_Text_(d) / max_FontSize) % max_FontStyle;
312} 309}
313 310
311static const iFontSpec *tryFindSpec_(enum iPrefsString ps, const char *fallback) {
312 const iFontSpec *spec = findSpec_Fonts(cstr_String(&prefs_App()->strings[ps]));
313 return spec ? spec : findSpec_Fonts(fallback);
314}
315
314static void initFonts_Text_(iText *d) { 316static void initFonts_Text_(iText *d) {
315#if 0 317#if 0
316 const iBlock *regularFont = &fontNunitoRegular_Embedded; 318 const iBlock *regularFont = &fontNunitoRegular_Embedded;
@@ -445,11 +447,11 @@ static void initFonts_Text_(iText *d) {
445 /* First the mandatory fonts. */ 447 /* First the mandatory fonts. */
446 d->overrideFontId = -1; 448 d->overrideFontId = -1;
447 resize_Array(&d->fonts, auxiliary_FontId); /* room for the built-ins */ 449 resize_Array(&d->fonts, auxiliary_FontId); /* room for the built-ins */
448 iAssert(auxiliary_FontId == documentHeading_FontId + maxVariants_Fonts); 450 setupFontVariants_Text_(d, tryFindSpec_(uiFont_PrefsString, "default"), default_FontId);
449 setupFontVariants_Text_(d, findSpec_Fonts("default"), default_FontId); 451 setupFontVariants_Text_(d, tryFindSpec_(monospaceFont_PrefsString, "iosevka"), monospace_FontId);
450 setupFontVariants_Text_(d, findSpec_Fonts("iosevka"), monospace_FontId); 452 setupFontVariants_Text_(d, tryFindSpec_(headingFont_PrefsString, "default"), documentHeading_FontId);
451 setupFontVariants_Text_(d, findSpec_Fonts("default"), documentBody_FontId); 453 setupFontVariants_Text_(d, tryFindSpec_(bodyFont_PrefsString, "default"), documentBody_FontId);
452 setupFontVariants_Text_(d, findSpec_Fonts("default"), documentHeading_FontId); 454 setupFontVariants_Text_(d, tryFindSpec_(monospaceDocumentFont_PrefsString, "iosevka-body"), documentMonospace_FontId);
453 /* Check if there are auxiliary fonts available and set those up, too. */ 455 /* Check if there are auxiliary fonts available and set those up, too. */
454 iConstForEach(PtrArray, s, listSpecsByPriority_Fonts()) { 456 iConstForEach(PtrArray, s, listSpecsByPriority_Fonts()) {
455 const iFontSpec *spec = s.ptr; 457 const iFontSpec *spec = s.ptr;
@@ -459,17 +461,6 @@ static void initFonts_Text_(iText *d) {
459 setupFontVariants_Text_(d, spec, fontId); 461 setupFontVariants_Text_(d, spec, fontId);
460 } 462 }
461 } 463 }
462#if 0
463 iForIndices(i, fontData) {
464 iFont *font = font_Text_(i);
465 init_Font(font,
466 fontData[i].ttf,
467 fontData[i].size,
468 fontData[i].scaling,
469 fontData[i].sizeId,
470 fontData[i].ttf == &fontIosevkaTermExtended_Embedded);
471 }
472#endif
473 gap_Text = iRound(gap_UI * d->contentFontSize); 464 gap_Text = iRound(gap_UI * d->contentFontSize);
474} 465}
475 466
@@ -544,8 +535,8 @@ void init_Text(iText *d, SDL_Renderer *render) {
544 iText *oldActive = activeText_; 535 iText *oldActive = activeText_;
545 activeText_ = d; 536 activeText_ = d;
546 init_Array(&d->fonts, sizeof(iFont)); 537 init_Array(&d->fonts, sizeof(iFont));
547 d->contentFont = nunito_TextFont; 538// d->contentFont = nunito_TextFont;
548 d->headingFont = nunito_TextFont; 539// d->headingFont = nunito_TextFont;
549 d->contentFontSize = contentScale_Text_; 540 d->contentFontSize = contentScale_Text_;
550 d->ansiEscape = new_RegExp("[[()]([0-9;AB]*)m", 0); 541 d->ansiEscape = new_RegExp("[[()]([0-9;AB]*)m", 0);
551 d->render = render; 542 d->render = render;
@@ -579,21 +570,15 @@ void setOpacity_Text(float opacity) {
579 SDL_SetTextureAlphaMod(activeText_->cache, iClamp(opacity, 0.0f, 1.0f) * 255 + 0.5f); 570 SDL_SetTextureAlphaMod(activeText_->cache, iClamp(opacity, 0.0f, 1.0f) * 255 + 0.5f);
580} 571}
581 572
582void setContentFont_Text(iText *d, enum iTextFont font) { 573//void setFont_Text(iText *d, int fontId, const char *fontSpecId) {
583 if (d->contentFont != font) { 574// setupFontVariants_Text_(d, findSpec_Fonts(fontSpecId), fontId);
584 d->contentFont = font; 575// if (d->contentFont != font) {
585 resetFonts_Text(d); 576// d->contentFont = font;
586 } 577// resetFonts_Text(d);
587} 578// }
588 579//}
589void setHeadingFont_Text(iText *d, enum iTextFont font) {
590 if (d->headingFont != font) {
591 d->headingFont = font;
592 resetFonts_Text(d);
593 }
594}
595 580
596void setContentFontSize_Text(iText *d, float fontSizeFactor) { 581void setDocumentFontSize_Text(iText *d, float fontSizeFactor) {
597 fontSizeFactor *= contentScale_Text_; 582 fontSizeFactor *= contentScale_Text_;
598 iAssert(fontSizeFactor > 0); 583 iAssert(fontSizeFactor > 0);
599 if (iAbs(d->contentFontSize - fontSizeFactor) > 0.001f) { 584 if (iAbs(d->contentFontSize - fontSizeFactor) > 0.001f) {
diff --git a/src/ui/text.h b/src/ui/text.h
index af69795a..ac59e7c8 100644
--- a/src/ui/text.h
+++ b/src/ui/text.h
@@ -34,80 +34,49 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
34#define FONT_ID(name, style, size) ((name) + ((style) * max_FontSize) + (size)) 34#define FONT_ID(name, style, size) ((name) + ((style) * max_FontSize) + (size))
35 35
36enum iFontId { 36enum iFontId {
37 default_FontId = 0, /* default is always the first font */ 37 default_FontId = 0, /* default is always the first font */
38 monospace_FontId = maxVariants_Fonts, /* 2nd font is always the monospace font */ 38 monospace_FontId = maxVariants_Fonts, /* 2nd font is always the monospace font */
39 documentBody_FontId = maxVariants_Fonts * 2, /* 3rd font is the body font */ 39 documentHeading_FontId = maxVariants_Fonts * 2, /* heading font */
40 documentHeading_FontId = maxVariants_Fonts * 3, /* heading font */ 40 documentBody_FontId = maxVariants_Fonts * 3, /* body font */
41 auxiliary_FontId = maxVariants_Fonts * 4, /* the first auxiliary font (e.g., symbols) */ 41 documentMonospace_FontId = maxVariants_Fonts * 4,
42 42 auxiliary_FontId = maxVariants_Fonts * 5, /* the first auxiliary font (e.g., symbols) */
43 // defaultMedium_FontId,
44// defaultBig_FontId,
45// defaultLarge_FontId,
46// defaultTiny_FontId,
47// defaultSmall_FontId,
48 /* UI fonts: bold weight */
49// defaultBold_FontId,
50// defaultMediumBold_FontId,
51// defaultBigBold_FontId,
52// defaultLargeBold_FontId,
53 /* content fonts */
54// bold_FontId,
55// italic_FontId,
56// medium_FontId,
57// big_FontId,
58// largeBold_FontId,
59// largeLight_FontId,
60// hugeBold_FontId,
61// monospaceSmall_FontId,
62 /* extra content fonts */
63// defaultContentRegular_FontId, /* UI font but sized to regular_FontId */
64// defaultContentSmall_FontId, /* UI font but sized smaller */
65 /* symbols and scripts */
66// userSymbols_FontId,
67// iosevka_FontId = userSymbols_FontId + max_FontSize,
68// symbols_FontId = iosevka_FontId + max_FontSize,
69// symbols2_FontId = symbols_FontId + max_FontSize,
70// smolEmoji_FontId = symbols2_FontId + max_FontSize,
71// notoEmoji_FontId = smolEmoji_FontId + max_FontSize,
72// japanese_FontId = notoEmoji_FontId + max_FontSize,
73// chineseSimplified_FontId = japanese_FontId + max_FontSize,
74// korean_FontId = chineseSimplified_FontId + max_FontSize,
75// arabic_FontId = korean_FontId + max_FontSize,
76// max_FontId = arabic_FontId + max_FontSize,
77 43
78 /* Meta: */ 44 /* Meta: */
79 mask_FontId = 0x0000ffff, /* font IDs are 16-bit; see GmRun's packing */ 45 mask_FontId = 0x0000ffff, /* font IDs are 16-bit; see GmRun's packing */
80 alwaysVariableFlag_FontId = 0x00010000, 46 alwaysVariableFlag_FontId = 0x00010000,
81 47
82 /* UI fonts: */ 48 /* UI fonts: */
83 uiLabelTiny_FontId = FONT_ID(default_FontId, semiBold_FontStyle, uiTiny_FontSize), 49 uiLabelTiny_FontId = FONT_ID(default_FontId, semiBold_FontStyle, uiTiny_FontSize),
84 uiLabelSmall_FontId = FONT_ID(default_FontId, regular_FontStyle, uiSmall_FontSize), 50 uiLabelSmall_FontId = FONT_ID(default_FontId, regular_FontStyle, uiSmall_FontSize),
85 uiLabel_FontId = FONT_ID(default_FontId, regular_FontStyle, uiNormal_FontSize), 51 uiLabel_FontId = FONT_ID(default_FontId, regular_FontStyle, uiNormal_FontSize),
86 uiLabelMedium_FontId = FONT_ID(default_FontId, regular_FontStyle, uiMedium_FontSize), 52 uiLabelMedium_FontId = FONT_ID(default_FontId, regular_FontStyle, uiMedium_FontSize),
87 uiLabelMediumBold_FontId = FONT_ID(default_FontId, bold_FontStyle, uiMedium_FontSize), 53 uiLabelMediumBold_FontId = FONT_ID(default_FontId, bold_FontStyle, uiMedium_FontSize),
88 uiLabelBig_FontId = FONT_ID(default_FontId, regular_FontStyle, uiBig_FontSize), 54 uiLabelBig_FontId = FONT_ID(default_FontId, regular_FontStyle, uiBig_FontSize),
89 uiLabelBold_FontId = FONT_ID(default_FontId, bold_FontStyle, uiNormal_FontSize), 55 uiLabelBold_FontId = FONT_ID(default_FontId, bold_FontStyle, uiNormal_FontSize),
90 uiLabelBigBold_FontId = FONT_ID(default_FontId, bold_FontStyle, uiBig_FontSize), 56 uiLabelBigBold_FontId = FONT_ID(default_FontId, bold_FontStyle, uiBig_FontSize),
91 uiLabelLarge_FontId = FONT_ID(default_FontId, regular_FontStyle, uiLarge_FontSize), 57 uiLabelLarge_FontId = FONT_ID(default_FontId, regular_FontStyle, uiLarge_FontSize),
92 uiLabelLargeBold_FontId = FONT_ID(default_FontId, bold_FontStyle, uiLarge_FontSize), 58 uiLabelLargeBold_FontId = FONT_ID(default_FontId, bold_FontStyle, uiLarge_FontSize),
93 uiLabelSymbols_FontId = FONT_ID(auxiliary_FontId, regular_FontStyle, uiNormal_FontSize), 59 uiLabelSymbols_FontId = FONT_ID(auxiliary_FontId, regular_FontStyle, uiNormal_FontSize),
94 uiShortcuts_FontId = FONT_ID(default_FontId, regular_FontStyle, uiNormal_FontSize), 60 uiShortcuts_FontId = FONT_ID(default_FontId, regular_FontStyle, uiNormal_FontSize),
95 uiInput_FontId = FONT_ID(default_FontId, regular_FontStyle, uiMedium_FontSize), 61 uiInput_FontId = FONT_ID(default_FontId, regular_FontStyle, uiMedium_FontSize),
96 uiContent_FontId = FONT_ID(default_FontId, regular_FontStyle, uiMedium_FontSize), 62 uiContent_FontId = FONT_ID(default_FontId, regular_FontStyle, uiMedium_FontSize),
97 uiContentBold_FontId = FONT_ID(default_FontId, bold_FontStyle, uiMedium_FontSize), 63 uiContentBold_FontId = FONT_ID(default_FontId, bold_FontStyle, uiMedium_FontSize),
98 uiContentSymbols_FontId = FONT_ID(auxiliary_FontId, regular_FontStyle, uiMedium_FontSize), 64 uiContentSymbols_FontId = FONT_ID(auxiliary_FontId, regular_FontStyle, uiMedium_FontSize),
99 /* Document fonts: */ 65
100 paragraph_FontId = FONT_ID(documentBody_FontId, regular_FontStyle, contentRegular_FontSize), 66 /* Document fonts: */
101 bold_FontId = FONT_ID(documentBody_FontId, semiBold_FontStyle, contentRegular_FontSize), 67 paragraph_FontId = FONT_ID(documentBody_FontId, regular_FontStyle, contentRegular_FontSize),
102 firstParagraph_FontId = FONT_ID(documentBody_FontId, regular_FontStyle, contentMedium_FontSize), 68 bold_FontId = FONT_ID(documentBody_FontId, semiBold_FontStyle, contentRegular_FontSize),
103 preformatted_FontId = FONT_ID(monospace_FontId, regular_FontStyle, contentMono_FontSize), 69 firstParagraph_FontId = FONT_ID(documentBody_FontId, regular_FontStyle, contentMedium_FontSize),
104 preformattedSmall_FontId = FONT_ID(monospace_FontId, regular_FontStyle, contentMonoSmall_FontSize), 70 preformatted_FontId = FONT_ID(monospace_FontId, regular_FontStyle, contentSmall_FontSize),
105 quote_FontId = FONT_ID(documentBody_FontId, italic_FontStyle, contentRegular_FontSize), 71 preformattedSmall_FontId = FONT_ID(monospace_FontId, regular_FontStyle, contentTiny_FontSize),
106 heading1_FontId = FONT_ID(documentHeading_FontId, bold_FontStyle, contentHuge_FontSize), 72 quote_FontId = FONT_ID(documentBody_FontId, italic_FontStyle, contentRegular_FontSize),
107 heading2_FontId = FONT_ID(documentHeading_FontId, bold_FontStyle, contentLarge_FontSize), 73 heading1_FontId = FONT_ID(documentHeading_FontId, bold_FontStyle, contentHuge_FontSize),
108 heading3_FontId = FONT_ID(documentHeading_FontId, regular_FontStyle, contentBig_FontSize), 74 heading2_FontId = FONT_ID(documentHeading_FontId, bold_FontStyle, contentLarge_FontSize),
109 banner_FontId = FONT_ID(documentHeading_FontId, light_FontStyle, contentLarge_FontSize), 75 heading3_FontId = FONT_ID(documentHeading_FontId, regular_FontStyle, contentBig_FontSize),
110 regularMonospace_FontId = FONT_ID(monospace_FontId, regular_FontStyle, contentRegular_FontSize), 76 banner_FontId = FONT_ID(documentHeading_FontId, light_FontStyle, contentLarge_FontSize),
77 monospaceParagraph_FontId = FONT_ID(documentMonospace_FontId, regular_FontStyle, contentRegular_FontSize),
78 monospaceBold_FontId = FONT_ID(documentMonospace_FontId, semiBold_FontStyle, contentRegular_FontSize),
79 plainText_FontId = FONT_ID(documentMonospace_FontId, regular_FontStyle, contentRegular_FontSize),
111}; 80};
112 81
113//iLocalDef iBool isJapanese_FontId(enum iFontId id) { 82//iLocalDef iBool isJapanese_FontId(enum iFontId id) {
@@ -116,6 +85,7 @@ enum iFontId {
116 85
117#define emojiVariationSelector_Char ((iChar) 0xfe0f) 86#define emojiVariationSelector_Char ((iChar) 0xfe0f)
118 87
88#if 0
119/* TODO: get rid of this; configure using font ID strings, check RTL from FontFile flags */ 89/* TODO: get rid of this; configure using font ID strings, check RTL from FontFile flags */
120enum iTextFont { 90enum iTextFont {
121 undefined_TextFont = -1, 91 undefined_TextFont = -1,
@@ -129,6 +99,7 @@ enum iTextFont {
129 arabic_TextFont, 99 arabic_TextFont,
130 emojiAndSymbols_TextFont, 100 emojiAndSymbols_TextFont,
131}; 101};
102#endif
132 103
133extern int gap_Text; /* affected by content font size */ 104extern int gap_Text; /* affected by content font size */
134 105
@@ -140,11 +111,10 @@ void deinit_Text (iText *);
140 111
141void setCurrent_Text (iText *); 112void setCurrent_Text (iText *);
142 113
143//void loadUserFonts_Text (void); /* based on Prefs */ 114//void setContentFont_Text (iText *, enum iTextFont font);
144 115//void setHeadingFont_Text (iText *, enum iTextFont font);
145void setContentFont_Text (iText *, enum iTextFont font); 116//void setFont_Text (iText *, int fontId, const char *fontSpecId);
146void setHeadingFont_Text (iText *, enum iTextFont font); 117void setDocumentFontSize_Text(iText *, float fontSizeFactor); /* affects all except `default*` fonts */
147void setContentFontSize_Text (iText *, float fontSizeFactor); /* affects all except `default*` fonts */
148void resetFonts_Text (iText *); 118void resetFonts_Text (iText *);
149 119
150int lineHeight_Text (int fontId); 120int lineHeight_Text (int fontId);
diff --git a/src/ui/util.c b/src/ui/util.c
index ae72dbee..73193c7a 100644
--- a/src/ui/util.c
+++ b/src/ui/util.c
@@ -1931,7 +1931,38 @@ static void addRadioButton_(iWidget *parent, const char *id, const char *label,
1931 id); 1931 id);
1932} 1932}
1933 1933
1934static iBool proportionalFonts_(const iFontSpec *spec) {
1935 return (spec->flags & monospace_FontSpecFlag) == 0 && ~spec->flags & auxiliary_FontSpecFlag;
1936}
1937
1938static iBool monospaceFonts_(const iFontSpec *spec) {
1939 return (spec->flags & monospace_FontSpecFlag) != 0 && ~spec->flags & auxiliary_FontSpecFlag;
1940}
1941
1934static const iArray *makeFontItems_(const char *id) { 1942static const iArray *makeFontItems_(const char *id) {
1943 iArray *items = collectNew_Array(sizeof(iMenuItem));
1944 if (!startsWith_CStr(id, "mono")) {
1945 iConstForEach(PtrArray, i, listSpecs_Fonts(proportionalFonts_)) {
1946 const iFontSpec *spec = i.ptr;
1947 pushBack_Array(
1948 items,
1949 &(iMenuItem){ cstr_String(&spec->name),
1950 0,
1951 0,
1952 format_CStr("!font.set %s:%s", id, cstr_String(&spec->id)) });
1953 }
1954 pushBack_Array(items, &(iMenuItem){ "---" });
1955 }
1956 iConstForEach(PtrArray, j, listSpecs_Fonts(monospaceFonts_)) {
1957 const iFontSpec *spec = j.ptr;
1958 pushBack_Array(
1959 items,
1960 &(iMenuItem){ cstr_String(&spec->name),
1961 0,
1962 0,
1963 format_CStr("!font.set %s:%s", id, cstr_String(&spec->id)) });
1964 }
1965#if 0
1935 const struct { 1966 const struct {
1936 const char * name; 1967 const char * name;
1937 enum iTextFont cfgId; 1968 enum iTextFont cfgId;
@@ -1943,7 +1974,6 @@ static const iArray *makeFontItems_(const char *id) {
1943 { "Tinos", tinos_TextFont }, 1974 { "Tinos", tinos_TextFont },
1944 { "---", -1 }, 1975 { "---", -1 },
1945 { "Iosevka", iosevka_TextFont } }; 1976 { "Iosevka", iosevka_TextFont } };
1946 iArray *items = collectNew_Array(sizeof(iMenuItem));
1947 iForIndices(i, fonts) { 1977 iForIndices(i, fonts) {
1948 pushBack_Array(items, 1978 pushBack_Array(items,
1949 &(iMenuItem){ fonts[i].name, 1979 &(iMenuItem){ fonts[i].name,
@@ -1953,17 +1983,19 @@ static const iArray *makeFontItems_(const char *id) {
1953 ? format_CStr("!%s.set arg:%d", id, fonts[i].cfgId) 1983 ? format_CStr("!%s.set arg:%d", id, fonts[i].cfgId)
1954 : NULL }); 1984 : NULL });
1955 } 1985 }
1986#endif
1956 pushBack_Array(items, &(iMenuItem){ NULL }); /* terminator */ 1987 pushBack_Array(items, &(iMenuItem){ NULL }); /* terminator */
1957 return items; 1988 return items;
1958} 1989}
1959 1990
1960static void addFontButtons_(iWidget *parent, const char *id) { 1991static void addFontButtons_(iWidget *parent, const char *id) {
1961 const iArray *items = makeFontItems_(id); 1992 const iArray *items = makeFontItems_(id);
1962 iLabelWidget *button = makeMenuButton_LabelWidget("Source Sans 3", 1993 size_t widestIndex = findWidestLabel_MenuItem(constData_Array(items), size_Array(items));
1994 iLabelWidget *button = makeMenuButton_LabelWidget(constValue_Array(items, widestIndex, iMenuItem).label,
1963 constData_Array(items), size_Array(items)); 1995 constData_Array(items), size_Array(items));
1964 setBackgroundColor_Widget(findChild_Widget(as_Widget(button), "menu"), 1996 setBackgroundColor_Widget(findChild_Widget(as_Widget(button), "menu"),
1965 uiBackgroundMenu_ColorId); 1997 uiBackgroundMenu_ColorId);
1966 setId_Widget(as_Widget(button), format_CStr("prefs.%s", id)); 1998 setId_Widget(as_Widget(button), format_CStr("prefs.font.%s", id));
1967 addChildFlags_Widget(parent, iClob(button), alignLeft_WidgetFlag); 1999 addChildFlags_Widget(parent, iClob(button), alignLeft_WidgetFlag);
1968} 2000}
1969 2001
@@ -2170,11 +2202,11 @@ iWidget *makePreferences_Widget(void) {
2170 { NULL } 2202 { NULL }
2171 }; 2203 };
2172 const iMenuItem lineWidthItems[] = { 2204 const iMenuItem lineWidthItems[] = {
2173 { "button id:prefs.linewidth.50 text:\u20132", 0, 0, "linewidth.set arg:50" }, 2205 { "button id:prefs.linewidth.30 text:\u20132", 0, 0, "linewidth.set arg:30" },
2174 { "button id:prefs.linewidth.58 text:\u20131", 0, 0, "linewidth.set arg:58" }, 2206 { "button id:prefs.linewidth.34 text:\u20131", 0, 0, "linewidth.set arg:34" },
2175 { "button id:prefs.linewidth.66 label:prefs.linewidth.normal", 0, 0, "linewidth.set arg:66" }, 2207 { "button id:prefs.linewidth.38 label:prefs.linewidth.normal", 0, 0, "linewidth.set arg:38" },
2176 { "button id:prefs.linewidth.76 text:+1", 0, 0, "linewidth.set arg:76" }, 2208 { "button id:prefs.linewidth.43 text:+1", 0, 0, "linewidth.set arg:43" },
2177 { "button id:prefs.linewidth.86 text:+2", 0, 0, "linewidth.set arg:86" }, 2209 { "button id:prefs.linewidth.48 text:+2", 0, 0, "linewidth.set arg:48" },
2178 { "button id:prefs.linewidth.1000 label:prefs.linewidth.fill", 0, 0, "linewidth.set arg:1000" }, 2210 { "button id:prefs.linewidth.1000 label:prefs.linewidth.fill", 0, 0, "linewidth.set arg:1000" },
2179 { NULL } 2211 { NULL }
2180 }; 2212 };
@@ -2491,10 +2523,14 @@ iWidget *makePreferences_Widget(void) {
2491 /* Fonts. */ { 2523 /* Fonts. */ {
2492 setId_Widget(appendTwoColumnTabPage_Widget(tabs, "${heading.prefs.fonts}", '4', &headings, &values), "prefs.page.fonts"); 2524 setId_Widget(appendTwoColumnTabPage_Widget(tabs, "${heading.prefs.fonts}", '4', &headings, &values), "prefs.page.fonts");
2493 /* Fonts. */ { 2525 /* Fonts. */ {
2494 addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.headingfont}"))); 2526 addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.font.ui}")));
2495 addFontButtons_(values, "headingfont"); 2527 addFontButtons_(values, "ui");
2496 addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.font}"))); 2528 addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.font.heading}")));
2497 addFontButtons_(values, "font"); 2529 addFontButtons_(values, "heading");
2530 addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.font.body}")));
2531 addFontButtons_(values, "body");
2532 addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.font.mono}")));
2533 addFontButtons_(values, "mono");
2498 addDialogPadding_(headings, values); 2534 addDialogPadding_(headings, values);
2499 addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.mono}"))); 2535 addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.mono}")));
2500 iWidget *mono = new_Widget(); { 2536 iWidget *mono = new_Widget(); {
@@ -2511,6 +2547,9 @@ iWidget *makePreferences_Widget(void) {
2511 updateSize_LabelWidget((iLabelWidget *) tog); 2547 updateSize_LabelWidget((iLabelWidget *) tog);
2512 } 2548 }
2513 addChildFlags_Widget(values, iClob(mono), arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag); 2549 addChildFlags_Widget(values, iClob(mono), arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag);
2550 addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.font.monodoc}")));
2551 addFontButtons_(values, "monodoc");
2552 addDialogPadding_(headings, values);
2514 addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.boldlink}"))); 2553 addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.boldlink}")));
2515 iWidget *boldLink = new_Widget(); { 2554 iWidget *boldLink = new_Widget(); {
2516 /* TODO: Add a utility function for this type of toggles? (also for above) */ 2555 /* TODO: Add a utility function for this type of toggles? (also for above) */
@@ -2528,11 +2567,11 @@ iWidget *makePreferences_Widget(void) {
2528 } 2567 }
2529 addChildFlags_Widget(values, iClob(boldLink), arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag); 2568 addChildFlags_Widget(values, iClob(boldLink), arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag);
2530 addDialogPadding_(headings, values); 2569 addDialogPadding_(headings, values);
2531 /* Custom font. */ { 2570// /* Custom font. */ {
2532 iInputWidget *customFont = new_InputWidget(0); 2571// iInputWidget *customFont = new_InputWidget(0);
2533 setHint_InputWidget(customFont, "${hint.prefs.userfont}"); 2572// setHint_InputWidget(customFont, "${hint.prefs.userfont}");
2534 addPrefsInputWithHeading_(headings, values, "prefs.userfont", iClob(customFont)); 2573// addPrefsInputWithHeading_(headings, values, "prefs.userfont", iClob(customFont));
2535 } 2574// }
2536 } 2575 }
2537 } 2576 }
2538 /* Style. */ { 2577 /* Style. */ {