summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2020-07-22 13:44:59 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2020-07-22 13:44:59 +0300
commitf2f64e2fbca93e81a7367efac1be635f7f00919c (patch)
tree26f67dece0127a0b41a3507530ce748972064b8b /src
parent6bd965b490b791e471b755e81887557bd14c755d (diff)
Text: Operate on Rangecc strings
Diffstat (limited to 'src')
-rw-r--r--src/ui/text.c64
1 files changed, 45 insertions, 19 deletions
diff --git a/src/ui/text.c b/src/ui/text.c
index a01de2ce..23e28e4d 100644
--- a/src/ui/text.c
+++ b/src/ui/text.c
@@ -362,16 +362,29 @@ static const iGlyph *glyph_Font_(iFont *d, iChar ch) {
362 362
363enum iRunMode { measure_RunMode, draw_RunMode, drawPermanentColor_RunMode }; 363enum iRunMode { measure_RunMode, draw_RunMode, drawPermanentColor_RunMode };
364 364
365static iInt2 run_Font_(iFont *d, enum iRunMode mode, const char *text, size_t maxLen, iInt2 pos, 365static iChar nextChar_(const char **chPos, const char *end) {
366 if (*chPos == end) {
367 return 0;
368 }
369 iChar ch;
370 int len = decodeBytes_MultibyteChar(*chPos, end - *chPos, &ch);
371 if (len <= 0) {
372 (*chPos)++; /* skip it */
373 return 0;
374 }
375 (*chPos) += len;
376 return ch;
377}
378
379static iInt2 run_Font_(iFont *d, enum iRunMode mode, iRangecc text, size_t maxLen, iInt2 pos,
366 int *runAdvance_out) { 380 int *runAdvance_out) {
367 iInt2 size = zero_I2(); 381 iInt2 size = zero_I2();
368 const iInt2 orig = pos; 382 const iInt2 orig = pos;
369 const stbtt_fontinfo *info = &d->font; 383 const stbtt_fontinfo *info = &d->font;
370 float xpos = pos.x; 384 float xpos = pos.x;
371 float xposMax = xpos; 385 float xposMax = xpos;
372 const iString textStr = iStringLiteral(text); 386 for (const char *chPos = text.start; chPos != text.end; ) {
373 iConstForEach(String, i, &textStr) { 387 iChar ch = nextChar_(&chPos, text.end);
374 iChar ch = i.value;
375 /* Special instructions. */ { 388 /* Special instructions. */ {
376 if (ch == '\n') { 389 if (ch == '\n') {
377 xpos = pos.x; 390 xpos = pos.x;
@@ -379,8 +392,8 @@ static iInt2 run_Font_(iFont *d, enum iRunMode mode, const char *text, size_t ma
379 continue; 392 continue;
380 } 393 }
381 if (ch == '\r') { 394 if (ch == '\r') {
382 next_StringConstIterator(&i); 395 const iChar esc = nextChar_(&chPos, text.end);
383 const iColor clr = get_Color(i.value - '0'); 396 const iColor clr = get_Color(esc - '0');
384 if (mode == draw_RunMode) { 397 if (mode == draw_RunMode) {
385 SDL_SetTextureColorMod(text_.cache, clr.r, clr.g, clr.b); 398 SDL_SetTextureColorMod(text_.cache, clr.r, clr.g, clr.b);
386 } 399 }
@@ -408,9 +421,9 @@ static iInt2 run_Font_(iFont *d, enum iRunMode mode, const char *text, size_t ma
408 xpos += d->scale * advance; 421 xpos += d->scale * advance;
409 xposMax = iMax(xposMax, xpos); 422 xposMax = iMax(xposMax, xpos);
410 /* Check the next character. */ { 423 /* Check the next character. */ {
411 iStringConstIterator j = i; 424 /* TODO: No need to decode the next char twice; check this on the next iteration. */
412 next_StringConstIterator(&j); 425 const char *peek = chPos;
413 const iChar next = j.value; 426 const iChar next = nextChar_(&peek, text.end);
414 if (next) { 427 if (next) {
415 xpos += d->scale * stbtt_GetCodepointKernAdvance(info, ch, next); 428 xpos += d->scale * stbtt_GetCodepointKernAdvance(info, ch, next);
416 } 429 }
@@ -433,14 +446,20 @@ iInt2 measure_Text(int fontId, const char *text) {
433 if (!*text) { 446 if (!*text) {
434 return init_I2(0, lineHeight_Text(fontId)); 447 return init_I2(0, lineHeight_Text(fontId));
435 } 448 }
436 return run_Font_(&text_.fonts[fontId], measure_RunMode, text, iInvalidSize, zero_I2(), NULL); 449 return run_Font_(
450 &text_.fonts[fontId], measure_RunMode, range_CStr(text), iInvalidSize, zero_I2(), NULL);
437} 451}
438 452
439iInt2 advance_Text(int fontId, const char *text) { 453iInt2 advance_Text(int fontId, const char *text) {
440 int advance; 454 int advance;
441 const int height = 455 const int height = run_Font_(&text_.fonts[fontId],
442 run_Font_(&text_.fonts[fontId], measure_RunMode, text, iInvalidSize, zero_I2(), &advance).y; 456 measure_RunMode,
443 return init_I2(advance, height); //lineHeight_Text(fontId)); 457 range_CStr(text),
458 iInvalidSize,
459 zero_I2(),
460 &advance)
461 .y;
462 return init_I2(advance, height);
444} 463}
445 464
446iInt2 advanceN_Text(int fontId, const char *text, size_t n) { 465iInt2 advanceN_Text(int fontId, const char *text, size_t n) {
@@ -448,7 +467,7 @@ iInt2 advanceN_Text(int fontId, const char *text, size_t n) {
448 return init_I2(0, lineHeight_Text(fontId)); 467 return init_I2(0, lineHeight_Text(fontId));
449 } 468 }
450 int advance; 469 int advance;
451 run_Font_(&text_.fonts[fontId], measure_RunMode, text, n, zero_I2(), &advance); 470 run_Font_(&text_.fonts[fontId], measure_RunMode, range_CStr(text), n, zero_I2(), &advance);
452 return init_I2(advance, lineHeight_Text(fontId)); 471 return init_I2(advance, lineHeight_Text(fontId));
453} 472}
454 473
@@ -461,7 +480,13 @@ iInt2 advanceRange_Text(int fontId, iRangecc text) {
461 return metrics; 480 return metrics;
462} 481}
463 482
464static void draw_Text_(int fontId, iInt2 pos, int color, const char *text) { 483iInt2 tryAdvanceRange_Text(int fontId, iRangecc text, int width, const char **endPos) {
484 int advance;
485 const int height = run_Font_(&text_.fonts[fontId], measure_RunMode, text, iInvalidSize, zero_I2(), &advance).y;
486
487}
488
489static void draw_Text_(int fontId, iInt2 pos, int color, iRangecc text) {
465 iText *d = &text_; 490 iText *d = &text_;
466 const iColor clr = get_Color(color & mask_ColorId); 491 const iColor clr = get_Color(color & mask_ColorId);
467 SDL_SetTextureColorMod(d->cache, clr.r, clr.g, clr.b); 492 SDL_SetTextureColorMod(d->cache, clr.r, clr.g, clr.b);
@@ -489,12 +514,12 @@ void draw_Text(int fontId, iInt2 pos, int color, const char *text, ...) {
489 /* Bottom-aligned. */ 514 /* Bottom-aligned. */
490 pos.y = -pos.y - lineHeight_Text(fontId); 515 pos.y = -pos.y - lineHeight_Text(fontId);
491 } 516 }
492 draw_Text_(fontId, pos, color, cstr_Block(&chars)); 517 draw_Text_(fontId, pos, color, (iRangecc){ constBegin_Block(&chars), constEnd_Block(&chars) });
493 deinit_Block(&chars); 518 deinit_Block(&chars);
494} 519}
495 520
496void drawString_Text(int fontId, iInt2 pos, int color, const iString *text) { 521void drawString_Text(int fontId, iInt2 pos, int color, const iString *text) {
497 draw_Text_(fontId, pos, color, cstr_String(text)); 522 draw_Text_(fontId, pos, color, range_String(text));
498} 523}
499 524
500void drawCentered_Text(int fontId, iRect rect, int color, const char *text, ...) { 525void drawCentered_Text(int fontId, iRect rect, int color, const char *text, ...) {
@@ -506,7 +531,8 @@ void drawCentered_Text(int fontId, iRect rect, int color, const char *text, ...)
506 va_end(args); 531 va_end(args);
507 } 532 }
508 const iInt2 textSize = advance_Text(fontId, cstr_Block(&chars)); 533 const iInt2 textSize = advance_Text(fontId, cstr_Block(&chars));
509 draw_Text_(fontId, sub_I2(mid_Rect(rect), divi_I2(textSize, 2)), color, cstr_Block(&chars)); 534 draw_Text_(fontId, sub_I2(mid_Rect(rect), divi_I2(textSize, 2)), color,
535 (iRangecc){ constBegin_Block(&chars), constEnd_Block(&chars) });
510 deinit_Block(&chars); 536 deinit_Block(&chars);
511} 537}
512 538
@@ -528,7 +554,7 @@ void init_TextBuf(iTextBuf *d, int font, const char *text) {
528 d->size.y); 554 d->size.y);
529 SDL_SetTextureBlendMode(d->texture, SDL_BLENDMODE_BLEND); 555 SDL_SetTextureBlendMode(d->texture, SDL_BLENDMODE_BLEND);
530 SDL_SetRenderTarget(render, d->texture); 556 SDL_SetRenderTarget(render, d->texture);
531 draw_Text_(font, zero_I2(), white_ColorId, text); 557 draw_Text_(font, zero_I2(), white_ColorId, range_CStr(text));
532 SDL_SetRenderTarget(render, NULL); 558 SDL_SetRenderTarget(render, NULL);
533} 559}
534 560