summaryrefslogtreecommitdiff
path: root/src/gmdocument.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2020-07-22 15:34:08 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2020-07-22 15:34:08 +0300
commite0e53e4a51afcbd22345d12416645d3fc5483a18 (patch)
tree37c7ca552d60b6ccb179a807d9dbcfee8b097cfd /src/gmdocument.c
parente16f37f75399ef4dd2f267efbc720768489f96a1 (diff)
Text wrapping; basic scrolling in DocumentWidget
Diffstat (limited to 'src/gmdocument.c')
-rw-r--r--src/gmdocument.c46
1 files changed, 36 insertions, 10 deletions
diff --git a/src/gmdocument.c b/src/gmdocument.c
index feff44e6..3f3f8358 100644
--- a/src/gmdocument.c
+++ b/src/gmdocument.c
@@ -150,11 +150,18 @@ static void doLayout_GmDocument_(iGmDocument *d) {
150 run.text = (iRangecc){ bullet, bullet + strlen(bullet) }; 150 run.text = (iRangecc){ bullet, bullet + strlen(bullet) };
151 pushBack_Array(&d->layout, &run); 151 pushBack_Array(&d->layout, &run);
152 } 152 }
153 run.text = line; 153 iRangecc runLine = line;
154 run.bounds.pos = addX_I2(pos, indent * gap_UI); 154 while (!isEmpty_Range(&runLine)) {
155 run.bounds.size = advanceRange_Text(run.font, line); 155 run.bounds.pos = addX_I2(pos, indent * gap_UI);
156 pushBack_Array(&d->layout, &run); 156 const char *contPos;
157 pos.y += run.bounds.size.y; 157 run.bounds.size = tryAdvanceRange_Text(
158 run.font, runLine, isPreformat ? 0 : (d->size.x - run.bounds.pos.x), &contPos);
159 run.text = (iRangecc){ runLine.start, contPos };
160 pushBack_Array(&d->layout, &run);
161 runLine.start = contPos;
162 trimStart_Rangecc(&runLine);
163 pos.y += lineHeight_Text(run.font);
164 }
158 prevType = type; 165 prevType = type;
159 } 166 }
160 d->size.y = pos.y; 167 d->size.y = pos.y;
@@ -185,9 +192,22 @@ static void normalize_GmDocument(iGmDocument *d) {
185 iRangecc src = range_String(&d->source); 192 iRangecc src = range_String(&d->source);
186 iRangecc line = iNullRange; 193 iRangecc line = iNullRange;
187 iBool isPreformat = iFalse; 194 iBool isPreformat = iFalse;
195 const int preTabWidth = 4; /* TODO: user-configurable parameter */
188 while (nextSplit_Rangecc(&src, "\n", &line)) { 196 while (nextSplit_Rangecc(&src, "\n", &line)) {
189 if (isPreformat) { 197 if (isPreformat) {
190 appendRange_String(normalized, line); 198 /* Replace any tab characters with spaces for visualization. */
199 for (const char *ch = line.start; ch != line.end; ch++) {
200 if (*ch == '\t') {
201 int column = ch - line.start;
202 int numSpaces = (column / preTabWidth + 1) * preTabWidth - column;
203 while (numSpaces-- > 0) {
204 appendCStrN_String(normalized, " ", 1);
205 }
206 }
207 else {
208 appendCStrN_String(normalized, ch, 1);
209 }
210 }
191 appendCStr_String(normalized, "\n"); 211 appendCStr_String(normalized, "\n");
192 if (lineType_Rangecc_(&line) == preformatted_GmLineType) { 212 if (lineType_Rangecc_(&line) == preformatted_GmLineType) {
193 isPreformat = iFalse; 213 isPreformat = iFalse;
@@ -202,21 +222,23 @@ static void normalize_GmDocument(iGmDocument *d) {
202 } 222 }
203 iBool isPrevSpace = iFalse; 223 iBool isPrevSpace = iFalse;
204 for (const char *ch = line.start; ch != line.end; ch++) { 224 for (const char *ch = line.start; ch != line.end; ch++) {
205 if (isNormalizableSpace_(*ch)) { 225 char c = *ch;
226 if (isNormalizableSpace_(c)) {
206 if (isPrevSpace) { 227 if (isPrevSpace) {
207 continue; 228 continue; /* skip repeated spaces */
208 } 229 }
230 c = ' ';
209 isPrevSpace = iTrue; 231 isPrevSpace = iTrue;
210 } 232 }
211 else { 233 else {
212 isPrevSpace = iFalse; 234 isPrevSpace = iFalse;
213 } 235 }
214 appendCStrN_String(normalized, ch, 1); 236 appendCStrN_String(normalized, &c, 1);
215 } 237 }
216 appendCStr_String(normalized, "\n"); 238 appendCStr_String(normalized, "\n");
217 } 239 }
218 set_String(&d->source, collect_String(normalized)); 240 set_String(&d->source, collect_String(normalized));
219 printf("normalized:\n%s\n", cstr_String(&d->source)); 241// printf("normalized:\n%s\n", cstr_String(&d->source));
220} 242}
221 243
222void setSource_GmDocument(iGmDocument *d, const iString *source, int width) { 244void setSource_GmDocument(iGmDocument *d, const iString *source, int width) {
@@ -244,4 +266,8 @@ void render_GmDocument(const iGmDocument *d, iRangei visRangeY, iGmDocumentRende
244 } 266 }
245} 267}
246 268
269iInt2 size_GmDocument(const iGmDocument *d) {
270 return d->size;
271}
272
247iDefineClass(GmDocument) 273iDefineClass(GmDocument)