diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-07-22 13:44:59 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-07-22 13:44:59 +0300 |
commit | f2f64e2fbca93e81a7367efac1be635f7f00919c (patch) | |
tree | 26f67dece0127a0b41a3507530ce748972064b8b /src/ui | |
parent | 6bd965b490b791e471b755e81887557bd14c755d (diff) |
Text: Operate on Rangecc strings
Diffstat (limited to 'src/ui')
-rw-r--r-- | src/ui/text.c | 64 |
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 | ||
363 | enum iRunMode { measure_RunMode, draw_RunMode, drawPermanentColor_RunMode }; | 363 | enum iRunMode { measure_RunMode, draw_RunMode, drawPermanentColor_RunMode }; |
364 | 364 | ||
365 | static iInt2 run_Font_(iFont *d, enum iRunMode mode, const char *text, size_t maxLen, iInt2 pos, | 365 | static 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 | |||
379 | static 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 | ||
439 | iInt2 advance_Text(int fontId, const char *text) { | 453 | iInt2 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 | ||
446 | iInt2 advanceN_Text(int fontId, const char *text, size_t n) { | 465 | iInt2 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 | ||
464 | static void draw_Text_(int fontId, iInt2 pos, int color, const char *text) { | 483 | iInt2 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 | |||
489 | static 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 | ||
496 | void drawString_Text(int fontId, iInt2 pos, int color, const iString *text) { | 521 | void 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 | ||
500 | void drawCentered_Text(int fontId, iRect rect, int color, const char *text, ...) { | 525 | void 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 | ||