summaryrefslogtreecommitdiff
path: root/src/ui/text.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/text.c')
-rw-r--r--src/ui/text.c60
1 files changed, 54 insertions, 6 deletions
diff --git a/src/ui/text.c b/src/ui/text.c
index 9838fb00..889aa2e4 100644
--- a/src/ui/text.c
+++ b/src/ui/text.c
@@ -781,6 +781,7 @@ enum iRunMode {
781 permanentColorFlag_RunMode = iBit(11), 781 permanentColorFlag_RunMode = iBit(11),
782 alwaysVariableWidthFlag_RunMode = iBit(12), 782 alwaysVariableWidthFlag_RunMode = iBit(12),
783 fillBackground_RunMode = iBit(13), 783 fillBackground_RunMode = iBit(13),
784 stopAtNewline_RunMode = iBit(14), /* don't advance past \n, consider it a wrap pos */
784}; 785};
785 786
786static enum iFontId fontId_Text_(const iFont *font) { 787static enum iFontId fontId_Text_(const iFont *font) {
@@ -923,7 +924,7 @@ static iRect run_Font_(iFont *d, const iRunArgs *args) {
923 } 924 }
924 /* TODO: Check out if `uc_wordbreak_property()` from libunistring can be used here. */ 925 /* TODO: Check out if `uc_wordbreak_property()` from libunistring can be used here. */
925 if (ch == '\n') { 926 if (ch == '\n') {
926 if (args->xposLimit > 0 && ~mode & noWrapFlag_RunMode) { 927 if (args->xposLimit > 0 && mode & stopAtNewline_RunMode) {
927 /* Stop the line here, this is a hard warp. */ 928 /* Stop the line here, this is a hard warp. */
928 if (args->continueFrom_out) { 929 if (args->continueFrom_out) {
929 *args->continueFrom_out = chPos; 930 *args->continueFrom_out = chPos;
@@ -1148,7 +1149,8 @@ iInt2 advanceRange_Text(int fontId, iRangecc text) {
1148iInt2 tryAdvance_Text(int fontId, iRangecc text, int width, const char **endPos) { 1149iInt2 tryAdvance_Text(int fontId, iRangecc text, int width, const char **endPos) {
1149 int advance; 1150 int advance;
1150 const int height = run_Font_(font_Text_(fontId), 1151 const int height = run_Font_(font_Text_(fontId),
1151 &(iRunArgs){ .mode = measure_RunMode | runFlagsFromId_(fontId), 1152 &(iRunArgs){ .mode = measure_RunMode | stopAtNewline_RunMode |
1153 runFlagsFromId_(fontId),
1152 .text = text, 1154 .text = text,
1153 .xposLimit = width, 1155 .xposLimit = width,
1154 .continueFrom_out = endPos, 1156 .continueFrom_out = endPos,
@@ -1161,6 +1163,7 @@ iInt2 tryAdvanceNoWrap_Text(int fontId, iRangecc text, int width, const char **e
1161 int advance; 1163 int advance;
1162 const int height = run_Font_(font_Text_(fontId), 1164 const int height = run_Font_(font_Text_(fontId),
1163 &(iRunArgs){ .mode = measure_RunMode | noWrapFlag_RunMode | 1165 &(iRunArgs){ .mode = measure_RunMode | noWrapFlag_RunMode |
1166 stopAtNewline_RunMode |
1164 runFlagsFromId_(fontId), 1167 runFlagsFromId_(fontId),
1165 .text = text, 1168 .text = text,
1166 .xposLimit = width, 1169 .xposLimit = width,
@@ -1269,7 +1272,7 @@ int drawWrapRange_Text(int fontId, iInt2 pos, int maxWidth, int color, iRangecc
1269 const iInt2 adv = tryAdvance_Text(fontId, text, maxWidth, &endp); 1272 const iInt2 adv = tryAdvance_Text(fontId, text, maxWidth, &endp);
1270 drawRange_Text(fontId, pos, color, (iRangecc){ text.start, endp }); 1273 drawRange_Text(fontId, pos, color, (iRangecc){ text.start, endp });
1271 text.start = endp; 1274 text.start = endp;
1272 pos.y += adv.y; 1275 pos.y += iMax(adv.y, lineHeight_Text(fontId));
1273 } 1276 }
1274 return pos.y; 1277 return pos.y;
1275} 1278}
@@ -1404,9 +1407,21 @@ iString *renderBlockChars_Text(const iBlock *fontData, int height, enum iTextBlo
1404 1407
1405iDefineTypeConstructionArgs(TextBuf, (int font, int color, const char *text), font, color, text) 1408iDefineTypeConstructionArgs(TextBuf, (int font, int color, const char *text), font, color, text)
1406 1409
1407void init_TextBuf(iTextBuf *d, int font, int color, const char *text) { 1410static void initWrap_TextBuf_(iTextBuf *d, int font, int color, int maxWidth, iBool doWrap, const char *text) {
1408 SDL_Renderer *render = text_.render; 1411 SDL_Renderer *render = text_.render;
1409 d->size = advance_Text(font, text); 1412 if (maxWidth == 0) {
1413 d->size = advance_Text(font, text);
1414 }
1415 else {
1416 d->size = zero_I2();
1417 iRangecc content = range_CStr(text);
1418 while (!isEmpty_Range(&content)) {
1419 const iInt2 size = (doWrap ? tryAdvance_Text(font, content, maxWidth, &content.start)
1420 : tryAdvanceNoWrap_Text(font, content, maxWidth, &content.start));
1421 d->size.x = iMax(d->size.x, size.x);
1422 d->size.y += iMax(size.y, lineHeight_Text(font));
1423 }
1424 }
1410 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); 1425 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0");
1411 if (d->size.x * d->size.y) { 1426 if (d->size.x * d->size.y) {
1412 d->texture = SDL_CreateTexture(render, 1427 d->texture = SDL_CreateTexture(render,
@@ -1424,17 +1439,50 @@ void init_TextBuf(iTextBuf *d, int font, int color, const char *text) {
1424 SDL_SetTextureBlendMode(text_.cache, SDL_BLENDMODE_NONE); /* blended when TextBuf is drawn */ 1439 SDL_SetTextureBlendMode(text_.cache, SDL_BLENDMODE_NONE); /* blended when TextBuf is drawn */
1425 SDL_SetRenderDrawColor(text_.render, 0, 0, 0, 0); 1440 SDL_SetRenderDrawColor(text_.render, 0, 0, 0, 0);
1426 SDL_RenderClear(text_.render); 1441 SDL_RenderClear(text_.render);
1427 draw_Text_(font, zero_I2(), color | fillBackground_ColorId, range_CStr(text)); 1442 const int fg = color | fillBackground_ColorId;
1443 iRangecc range = range_CStr(text);
1444 if (maxWidth == 0) {
1445 draw_Text_(font, zero_I2(), fg, range);
1446 }
1447 else if (doWrap) {
1448 drawWrapRange_Text(font, zero_I2(), maxWidth, fg, range);
1449 }
1450 else {
1451 iInt2 pos = zero_I2();
1452 while (!isEmpty_Range(&range)) {
1453 const char *endp;
1454 tryAdvanceNoWrap_Text(font, range, maxWidth, &endp);
1455 draw_Text_(font, pos, fg, (iRangecc){ range.start, endp });
1456 range.start = endp;
1457 pos.y += lineHeight_Text(font);
1458 }
1459 }
1428 SDL_SetTextureBlendMode(text_.cache, SDL_BLENDMODE_BLEND); 1460 SDL_SetTextureBlendMode(text_.cache, SDL_BLENDMODE_BLEND);
1429 SDL_SetRenderTarget(render, oldTarget); 1461 SDL_SetRenderTarget(render, oldTarget);
1430 SDL_SetTextureBlendMode(d->texture, SDL_BLENDMODE_BLEND); 1462 SDL_SetTextureBlendMode(d->texture, SDL_BLENDMODE_BLEND);
1431 } 1463 }
1432} 1464}
1433 1465
1466void init_TextBuf(iTextBuf *d, int font, int color, const char *text) {
1467 initWrap_TextBuf_(d, font, color, 0, iFalse, text);
1468}
1469
1434void deinit_TextBuf(iTextBuf *d) { 1470void deinit_TextBuf(iTextBuf *d) {
1435 SDL_DestroyTexture(d->texture); 1471 SDL_DestroyTexture(d->texture);
1436} 1472}
1437 1473
1474iTextBuf *newBound_TextBuf(int font, int color, int boundWidth, const char *text) {
1475 iTextBuf *d = iMalloc(TextBuf);
1476 initWrap_TextBuf_(d, font, color, boundWidth, iFalse, text);
1477 return d;
1478}
1479
1480iTextBuf *newWrap_TextBuf(int font, int color, int wrapWidth, const char *text) {
1481 iTextBuf *d = iMalloc(TextBuf);
1482 initWrap_TextBuf_(d, font, color, wrapWidth, iTrue, text);
1483 return d;
1484}
1485
1438void draw_TextBuf(const iTextBuf *d, iInt2 pos, int color) { 1486void draw_TextBuf(const iTextBuf *d, iInt2 pos, int color) {
1439 const iColor clr = get_Color(color); 1487 const iColor clr = get_Color(color);
1440 SDL_SetTextureColorMod(d->texture, clr.r, clr.g, clr.b); 1488 SDL_SetTextureColorMod(d->texture, clr.r, clr.g, clr.b);