summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt1
-rw-r--r--res/FiraSans-Bold.ttfbin0 -> 208592 bytes
-rw-r--r--src/gmdocument.c53
-rw-r--r--src/ui/documentwidget.c12
-rw-r--r--src/ui/text.c21
-rw-r--r--src/ui/text.h43
6 files changed, 100 insertions, 30 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8498cd6e..c9b342d5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -16,6 +16,7 @@ pkg_check_modules (SDL2 REQUIRED sdl2)
16message (STATUS "Preparing embedded resources...") 16message (STATUS "Preparing embedded resources...")
17set (EMBED_RESOURCES 17set (EMBED_RESOURCES
18 res/FiraSans-Regular.ttf 18 res/FiraSans-Regular.ttf
19 res/FiraSans-Bold.ttf
19 res/FiraSans-LightItalic.ttf 20 res/FiraSans-LightItalic.ttf
20 res/FiraMono-Regular.ttf 21 res/FiraMono-Regular.ttf
21) 22)
diff --git a/res/FiraSans-Bold.ttf b/res/FiraSans-Bold.ttf
new file mode 100644
index 00000000..04830e7e
--- /dev/null
+++ b/res/FiraSans-Bold.ttf
Binary files differ
diff --git a/src/gmdocument.c b/src/gmdocument.c
index 67dcf555..0a47c924 100644
--- a/src/gmdocument.c
+++ b/src/gmdocument.c
@@ -1,6 +1,7 @@
1#include "gmdocument.h" 1#include "gmdocument.h"
2#include "ui/color.h" 2#include "ui/color.h"
3#include "ui/text.h" 3#include "ui/text.h"
4#include "ui/metrics.h"
4#include <the_Foundation/array.h> 5#include <the_Foundation/array.h>
5 6
6struct Impl_GmDocument { 7struct Impl_GmDocument {
@@ -48,6 +49,12 @@ static enum iGmLineType lineType_Rangecc_(const iRangecc *line) {
48 return text_GmLineType; 49 return text_GmLineType;
49} 50}
50 51
52static void trimLine_Rangecc_(iRangecc *line, enum iGmLineType type) {
53 static const unsigned int skip[max_GmLineType] = { 0, 2, 3, 1, 1, 2, 3 };
54 line->start += skip[type];
55 trim_Rangecc(line);
56}
57
51static void doLayout_GmDocument_(iGmDocument *d) { 58static void doLayout_GmDocument_(iGmDocument *d) {
52 if (d->size.x <= 0 || isEmpty_String(&d->source)) { 59 if (d->size.x <= 0 || isEmpty_String(&d->source)) {
53 return; 60 return;
@@ -57,7 +64,7 @@ static void doLayout_GmDocument_(iGmDocument *d) {
57 iInt2 pos = zero_I2(); 64 iInt2 pos = zero_I2();
58 const iRangecc content = range_String(&d->source); 65 const iRangecc content = range_String(&d->source);
59 iRangecc line = iNullRange; 66 iRangecc line = iNullRange;
60 const int fonts[max_GmLineType] = { 67 static const int fonts[max_GmLineType] = {
61 paragraph_FontId, 68 paragraph_FontId,
62 paragraph_FontId, 69 paragraph_FontId,
63 preformatted_FontId, 70 preformatted_FontId,
@@ -66,15 +73,49 @@ static void doLayout_GmDocument_(iGmDocument *d) {
66 header2_FontId, 73 header2_FontId,
67 header3_FontId 74 header3_FontId
68 }; 75 };
76 static const int indents[max_GmLineType] = {
77 4, 10, 4, 10, 0, 0, 0
78 };
79 static const char *bullet = "\u2022";
80 iRangecc preAltText = iNullRange;
69 while (nextSplit_Rangecc(&content, "\n", &line)) { 81 while (nextSplit_Rangecc(&content, "\n", &line)) {
70 enum iGmLineType type = lineType_Rangecc_(&line); 82 int indent = 0;
71 iGmRun run; 83 iGmRun run;
72 run.text = line;
73 run.font = fonts[type];
74 run.color = white_ColorId; 84 run.color = white_ColorId;
75 run.bounds.pos = pos;
76 run.bounds.size = advanceN_Text(run.font, line.start, size_Range(&line));
77 run.linkId = 0; 85 run.linkId = 0;
86 if (!isPreformat) {
87 enum iGmLineType type = lineType_Rangecc_(&line);
88 if (type == preformatted_GmLineType) {
89 isPreformat = iTrue;
90 trimLine_Rangecc_(&line, type);
91 preAltText = line;
92 /* TODO: store and link the alt text to this run */
93 continue;
94 }
95 trimLine_Rangecc_(&line, type);
96 run.font = fonts[type];
97 indent = indents[type];
98 if (type == bullet_GmLineType) {
99 run.bounds.pos = addX_I2(pos, indent * gap_UI);
100 run.bounds.size = advance_Text(run.font, bullet);
101 run.bounds.pos.x -= 4 * gap_UI - run.bounds.size.x / 2;
102 run.text = (iRangecc){ bullet, bullet + strlen(bullet) };
103 pushBack_Array(&d->layout, &run);
104 }
105 }
106 else {
107 if (startsWithSc_Rangecc(&line, "```", &iCaseSensitive)) {
108 isPreformat = iFalse;
109 preAltText = iNullRange;
110 continue;
111 }
112 run.font = preformatted_FontId;
113 indent = indents[preformatted_GmLineType];
114 }
115 run.text = line;
116 run.bounds.pos = pos;
117 run.bounds.size = advanceRange_Text(run.font, line);
118 adjustEdges_Rect(&run.bounds, 0, 0, 0, indent * gap_UI);
78 pushBack_Array(&d->layout, &run); 119 pushBack_Array(&d->layout, &run);
79 pos.y += run.bounds.size.y; 120 pos.y += run.bounds.size.y;
80 } 121 }
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index 7318e4cb..a2cf0a8f 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -1,6 +1,7 @@
1#include "documentwidget.h" 1#include "documentwidget.h"
2#include "paint.h" 2#include "paint.h"
3#include "util.h" 3#include "util.h"
4#include "app.h"
4#include "../gemini.h" 5#include "../gemini.h"
5#include "../gmdocument.h" 6#include "../gmdocument.h"
6 7
@@ -116,6 +117,7 @@ static void requestFinished_DocumentWidget_(iAnyObject *obj) {
116 iReleaseLater(d->request); 117 iReleaseLater(d->request);
117 d->request = NULL; 118 d->request = NULL;
118 fflush(stdout); 119 fflush(stdout);
120 postRefresh_App();
119} 121}
120 122
121static void fetch_DocumentWidget_(iDocumentWidget *d) { 123static void fetch_DocumentWidget_(iDocumentWidget *d) {
@@ -128,9 +130,9 @@ static void fetch_DocumentWidget_(iDocumentWidget *d) {
128 iFile *f = new_File(collect_String(newRange_String(url.path))); 130 iFile *f = new_File(collect_String(newRange_String(url.path)));
129 if (open_File(f, readOnly_FileMode)) { 131 if (open_File(f, readOnly_FileMode)) {
130 setBlock_String(d->newSource, collect_Block(readAll_File(f))); 132 setBlock_String(d->newSource, collect_Block(readAll_File(f)));
133 postRefresh_App();
131 } 134 }
132 iRelease(f); 135 iRelease(f);
133 d->state = ready_DocumentState;
134 return; 136 return;
135 } 137 }
136 d->request = new_TlsRequest(); 138 d->request = new_TlsRequest();
@@ -163,6 +165,14 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e
163 if (isResize_UserEvent(ev)) { 165 if (isResize_UserEvent(ev)) {
164 setWidth_GmDocument(d->doc, documentWidth_DocumentWidget_(d)); 166 setWidth_GmDocument(d->doc, documentWidth_DocumentWidget_(d));
165 } 167 }
168 if (ev->type == SDL_KEYDOWN) {
169 const int mods = keyMods_Sym(ev->key.keysym.mod);
170 const int key = ev->key.keysym.sym;
171 if (mods == KMOD_PRIMARY && key == 'r') {
172 fetch_DocumentWidget_(d);
173 return iTrue;
174 }
175 }
166 return processEvent_Widget(w, ev); 176 return processEvent_Widget(w, ev);
167} 177}
168 178
diff --git a/src/ui/text.c b/src/ui/text.c
index 59ea00dd..a01de2ce 100644
--- a/src/ui/text.c
+++ b/src/ui/text.c
@@ -115,15 +115,13 @@ void init_Text(SDL_Renderer *render) {
115 /* Load the fonts. */ { 115 /* Load the fonts. */ {
116 const struct { const iBlock *ttf; int size; } fontData[max_FontId] = { 116 const struct { const iBlock *ttf; int size; } fontData[max_FontId] = {
117 { &fontFiraSansRegular_Embedded, fontSize_UI }, 117 { &fontFiraSansRegular_Embedded, fontSize_UI },
118 { &fontFiraSansRegular_Embedded, fontSize_UI },
119 { &fontFiraMonoRegular_Embedded, fontSize_UI }, 118 { &fontFiraMonoRegular_Embedded, fontSize_UI },
120 { &fontFiraSansRegular_Embedded, fontSize_UI },
121 { &fontFiraSansRegular_Embedded, fontSize_UI * 1.5f }, 119 { &fontFiraSansRegular_Embedded, fontSize_UI * 1.5f },
122 { &fontFiraMonoRegular_Embedded, fontSize_UI },
123 { &fontFiraSansLightItalic_Embedded, fontSize_UI }, 120 { &fontFiraSansLightItalic_Embedded, fontSize_UI },
124 { &fontFiraSansRegular_Embedded, fontSize_UI * 2.0f }, 121 { &fontFiraSansBold_Embedded, fontSize_UI },
125 { &fontFiraSansRegular_Embedded, fontSize_UI * 1.75f }, 122 { &fontFiraSansBold_Embedded, fontSize_UI * 1.5f },
126 { &fontFiraSansRegular_Embedded, fontSize_UI * 1.5f }, 123 { &fontFiraSansBold_Embedded, fontSize_UI * 1.75f },
124 { &fontFiraSansBold_Embedded, fontSize_UI * 2.0f },
127 }; 125 };
128 iForIndices(i, fontData) { 126 iForIndices(i, fontData) {
129 init_Font(&d->fonts[i], fontData[i].ttf, fontData[i].size); 127 init_Font(&d->fonts[i], fontData[i].ttf, fontData[i].size);
@@ -171,6 +169,7 @@ iLocalDef SDL_Rect sdlRect_(const iRect rect) {
171 return (SDL_Rect){ rect.pos.x, rect.pos.y, rect.size.x, rect.size.y }; 169 return (SDL_Rect){ rect.pos.x, rect.pos.y, rect.size.x, rect.size.y };
172} 170}
173 171
172#if 0
174static void fillTriangle_(SDL_Surface *surface, const SDL_Rect *rect, int dir) { 173static void fillTriangle_(SDL_Surface *surface, const SDL_Rect *rect, int dir) {
175 const uint32_t color = 0xffffffff; 174 const uint32_t color = 0xffffffff;
176 SDL_LockSurface(surface); 175 SDL_LockSurface(surface);
@@ -201,6 +200,7 @@ static void fillTriangle_(SDL_Surface *surface, const SDL_Rect *rect, int dir) {
201 } 200 }
202 SDL_UnlockSurface(surface); 201 SDL_UnlockSurface(surface);
203} 202}
203#endif
204 204
205static void cache_Font_(iFont *d, iGlyph *glyph) { 205static void cache_Font_(iFont *d, iGlyph *glyph) {
206 iText *txt = &text_; 206 iText *txt = &text_;
@@ -452,6 +452,15 @@ iInt2 advanceN_Text(int fontId, const char *text, size_t n) {
452 return init_I2(advance, lineHeight_Text(fontId)); 452 return init_I2(advance, lineHeight_Text(fontId));
453} 453}
454 454
455iInt2 advanceRange_Text(int fontId, iRangecc text) {
456 /* TODO: Rangecc should be the default for runs; no need to copy here */
457 iString str;
458 initRange_String(&str, text);
459 const iInt2 metrics = advance_Text(fontId, cstr_String(&str));
460 deinit_String(&str);
461 return metrics;
462}
463
455static void draw_Text_(int fontId, iInt2 pos, int color, const char *text) { 464static void draw_Text_(int fontId, iInt2 pos, int color, const char *text) {
456 iText *d = &text_; 465 iText *d = &text_;
457 const iColor clr = get_Color(color & mask_ColorId); 466 const iColor clr = get_Color(color & mask_ColorId);
diff --git a/src/ui/text.h b/src/ui/text.h
index 85cd39cf..9bf69c80 100644
--- a/src/ui/text.h
+++ b/src/ui/text.h
@@ -7,17 +7,25 @@
7 7
8enum iFontId { 8enum iFontId {
9 default_FontId, 9 default_FontId,
10 uiShortcuts_FontId, 10 monospace_FontId,
11 uiInput_FontId, 11 medium_FontId,
12 italic_FontId,
13 bold_FontId,
14 mediumBold_FontId,
15 largeBold_FontId,
16 hugeBold_FontId,
17 max_FontId,
18 /* UI fonts: */
19 uiInput_FontId = monospace_FontId,
12 /* Document fonts: */ 20 /* Document fonts: */
13 paragraph_FontId, 21 paragraph_FontId = default_FontId,
14 firstParagraph_FontId, 22 firstParagraph_FontId = medium_FontId,
15 preformatted_FontId, 23 preformatted_FontId = monospace_FontId,
16 quote_FontId, 24 quote_FontId = italic_FontId,
17 header1_FontId, 25 header1_FontId = hugeBold_FontId,
18 header2_FontId, 26 header2_FontId = largeBold_FontId,
19 header3_FontId, 27 header3_FontId = mediumBold_FontId,
20 max_FontId 28 uiShortcuts_FontId = default_FontId,
21}; 29};
22 30
23#define specialSymbol_Text 0x10 31#define specialSymbol_Text 0x10
@@ -29,14 +37,15 @@ enum iSpecialSymbol {
29void init_Text (SDL_Renderer *); 37void init_Text (SDL_Renderer *);
30void deinit_Text (void); 38void deinit_Text (void);
31 39
32int lineHeight_Text (int font); 40int lineHeight_Text (int fontId);
33iInt2 measure_Text (int font, const char *text); 41iInt2 measure_Text (int fontId, const char *text);
34iInt2 advance_Text (int font, const char *text); 42iInt2 advance_Text (int fontId, const char *text);
35iInt2 advanceN_Text (int font, const char *text, size_t n); /* `n` in characters */ 43iInt2 advanceN_Text (int fontId, const char *text, size_t n); /* `n` in characters */
44iInt2 advanceRange_Text (int fontId, iRangecc text);
36 45
37void draw_Text (int font, iInt2 pos, int color, const char *text, ...); /* negative pos to switch alignment */ 46void draw_Text (int fontId, iInt2 pos, int color, const char *text, ...); /* negative pos to switch alignment */
38void drawString_Text (int font, iInt2 pos, int color, const iString *text); 47void drawString_Text (int fontId, iInt2 pos, int color, const iString *text);
39void drawCentered_Text (int font, iRect rect, int color, const char *text, ...); 48void drawCentered_Text (int fontId, iRect rect, int color, const char *text, ...);
40 49
41SDL_Texture * glyphCache_Text (void); 50SDL_Texture * glyphCache_Text (void);
42 51