diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-07-22 09:02:32 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-07-22 09:02:32 +0300 |
commit | de5bed516c43c882766b97133bbd5234026c4d4d (patch) | |
tree | e91208c83f6cb6d48ca319fd821746eccb7c05dd /src/gmdocument.c | |
parent | 2c514c6842c612814fbbf5eef591eb591c1345c3 (diff) |
GmDocument: Basic indents; bullets; bold font
Diffstat (limited to 'src/gmdocument.c')
-rw-r--r-- | src/gmdocument.c | 53 |
1 files changed, 47 insertions, 6 deletions
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 | ||
6 | struct Impl_GmDocument { | 7 | struct 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 | ||
52 | static 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 | |||
51 | static void doLayout_GmDocument_(iGmDocument *d) { | 58 | static 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 | } |