diff options
Diffstat (limited to 'src/ui/text.c')
-rw-r--r-- | src/ui/text.c | 61 |
1 files changed, 40 insertions, 21 deletions
diff --git a/src/ui/text.c b/src/ui/text.c index b08bdc60..f380b67b 100644 --- a/src/ui/text.c +++ b/src/ui/text.c | |||
@@ -36,6 +36,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |||
36 | #include <the_Foundation/stringlist.h> | 36 | #include <the_Foundation/stringlist.h> |
37 | #include <the_Foundation/regexp.h> | 37 | #include <the_Foundation/regexp.h> |
38 | #include <the_Foundation/path.h> | 38 | #include <the_Foundation/path.h> |
39 | #include <the_Foundation/ptrset.h> | ||
39 | #include <the_Foundation/vec2.h> | 40 | #include <the_Foundation/vec2.h> |
40 | 41 | ||
41 | #include <SDL_surface.h> | 42 | #include <SDL_surface.h> |
@@ -53,7 +54,6 @@ int enableHalfPixelGlyphs_Text = iTrue; /* debug setting */ | |||
53 | int enableKerning_Text = iTrue; /* looking up kern pairs is slow */ | 54 | int enableKerning_Text = iTrue; /* looking up kern pairs is slow */ |
54 | 55 | ||
55 | static iBool enableRaster_Text_ = iTrue; | 56 | static iBool enableRaster_Text_ = iTrue; |
56 | static int numPendingRasterization_Text_ = 0; | ||
57 | 57 | ||
58 | enum iGlyphFlag { | 58 | enum iGlyphFlag { |
59 | rasterized0_GlyphFlag = iBit(1), /* zero offset */ | 59 | rasterized0_GlyphFlag = iBit(1), /* zero offset */ |
@@ -200,6 +200,7 @@ struct Impl_Text { | |||
200 | iArray cacheRows; | 200 | iArray cacheRows; |
201 | SDL_Palette * grayscale; | 201 | SDL_Palette * grayscale; |
202 | iRegExp * ansiEscape; | 202 | iRegExp * ansiEscape; |
203 | iPtrSet * pendingRaster; /* glyphs */ | ||
203 | }; | 204 | }; |
204 | 205 | ||
205 | static iText text_; | 206 | static iText text_; |
@@ -424,12 +425,12 @@ static void initCache_Text_(iText *d) { | |||
424 | d->cacheSize.x, | 425 | d->cacheSize.x, |
425 | d->cacheSize.y); | 426 | d->cacheSize.y); |
426 | SDL_SetTextureBlendMode(d->cache, SDL_BLENDMODE_BLEND); | 427 | SDL_SetTextureBlendMode(d->cache, SDL_BLENDMODE_BLEND); |
427 | numPendingRasterization_Text_ = 0; | ||
428 | } | 428 | } |
429 | 429 | ||
430 | static void deinitCache_Text_(iText *d) { | 430 | static void deinitCache_Text_(iText *d) { |
431 | deinit_Array(&d->cacheRows); | 431 | deinit_Array(&d->cacheRows); |
432 | SDL_DestroyTexture(d->cache); | 432 | SDL_DestroyTexture(d->cache); |
433 | clear_PtrSet(text_.pendingRaster); | ||
433 | } | 434 | } |
434 | 435 | ||
435 | void init_Text(SDL_Renderer *render) { | 436 | void init_Text(SDL_Renderer *render) { |
@@ -447,6 +448,7 @@ void init_Text(SDL_Renderer *render) { | |||
447 | d->grayscale = SDL_AllocPalette(256); | 448 | d->grayscale = SDL_AllocPalette(256); |
448 | SDL_SetPaletteColors(d->grayscale, colors, 0, 256); | 449 | SDL_SetPaletteColors(d->grayscale, colors, 0, 256); |
449 | } | 450 | } |
451 | d->pendingRaster = new_PtrSet(); | ||
450 | initCache_Text_(d); | 452 | initCache_Text_(d); |
451 | initFonts_Text_(d); | 453 | initFonts_Text_(d); |
452 | } | 454 | } |
@@ -458,6 +460,7 @@ void deinit_Text(void) { | |||
458 | deinitCache_Text_(d); | 460 | deinitCache_Text_(d); |
459 | d->render = NULL; | 461 | d->render = NULL; |
460 | iRelease(d->ansiEscape); | 462 | iRelease(d->ansiEscape); |
463 | delete_PtrSet(d->pendingRaster); | ||
461 | } | 464 | } |
462 | 465 | ||
463 | void setOpacity_Text(float opacity) { | 466 | void setOpacity_Text(float opacity) { |
@@ -503,8 +506,8 @@ void resetFonts_Text(void) { | |||
503 | initFonts_Text_(d); | 506 | initFonts_Text_(d); |
504 | } | 507 | } |
505 | 508 | ||
506 | int numPendingGlyphs_Text(void) { | 509 | size_t numPendingGlyphs_Text(void) { |
507 | return numPendingRasterization_Text_; | 510 | return size_PtrSet(text_.pendingRaster); |
508 | } | 511 | } |
509 | 512 | ||
510 | iLocalDef iFont *font_Text_(enum iFontId id) { | 513 | iLocalDef iFont *font_Text_(enum iFontId id) { |
@@ -575,7 +578,7 @@ static void allocate_Font_(iFont *d, iGlyph *glyph, int hoff) { | |||
575 | } | 578 | } |
576 | } | 579 | } |
577 | 580 | ||
578 | static iBool cache_Font_(iFont *d, iGlyph *glyph, int hoff) { | 581 | static iBool cache_Font_(const iFont *d, iGlyph *glyph, int hoff) { |
579 | iText * txt = &text_; | 582 | iText * txt = &text_; |
580 | SDL_Renderer *render = txt->render; | 583 | SDL_Renderer *render = txt->render; |
581 | SDL_Texture * tex = NULL; | 584 | SDL_Texture * tex = NULL; |
@@ -641,6 +644,26 @@ iLocalDef iFont *characterFont_Font_(iFont *d, iChar ch, uint32_t *glyphIndex) { | |||
641 | return font; | 644 | return font; |
642 | } | 645 | } |
643 | 646 | ||
647 | static void doRaster_Font_(const iFont *font, iGlyph *glyph) { | ||
648 | SDL_Texture *oldTarget = SDL_GetRenderTarget(text_.render); | ||
649 | SDL_SetRenderTarget(text_.render, text_.cache); | ||
650 | if (!isRasterized_Glyph_(glyph, 0)) { | ||
651 | if (cache_Font_(font, glyph, 0)) { | ||
652 | if (isFullyRasterized_Glyph_(glyph)) { | ||
653 | remove_PtrSet(text_.pendingRaster, glyph); | ||
654 | } | ||
655 | } | ||
656 | } | ||
657 | if (!isRasterized_Glyph_(glyph, 1)) { | ||
658 | if (cache_Font_(font, glyph, 1)) { /* half-pixel offset */ | ||
659 | if (isFullyRasterized_Glyph_(glyph)) { | ||
660 | remove_PtrSet(text_.pendingRaster, glyph); | ||
661 | } | ||
662 | } | ||
663 | } | ||
664 | SDL_SetRenderTarget(text_.render, oldTarget); | ||
665 | } | ||
666 | |||
644 | static const iGlyph *glyph_Font_(iFont *d, iChar ch) { | 667 | static const iGlyph *glyph_Font_(iFont *d, iChar ch) { |
645 | iGlyph * glyph; | 668 | iGlyph * glyph; |
646 | uint32_t glyphIndex = 0; | 669 | uint32_t glyphIndex = 0; |
@@ -666,28 +689,24 @@ static const iGlyph *glyph_Font_(iFont *d, iChar ch) { | |||
666 | allocate_Font_(font, glyph, 0); | 689 | allocate_Font_(font, glyph, 0); |
667 | allocate_Font_(font, glyph, 1); | 690 | allocate_Font_(font, glyph, 1); |
668 | insert_Hash(&font->glyphs, &glyph->node); | 691 | insert_Hash(&font->glyphs, &glyph->node); |
669 | numPendingRasterization_Text_ += 2; | 692 | insert_PtrSet(text_.pendingRaster, glyph); |
670 | } | 693 | } |
671 | if (enableRaster_Text_ && !isFullyRasterized_Glyph_(glyph)) { | 694 | if (enableRaster_Text_ && !isFullyRasterized_Glyph_(glyph)) { |
672 | SDL_Texture *oldTarget = SDL_GetRenderTarget(text_.render); | 695 | doRaster_Font_(font, glyph); |
673 | SDL_SetRenderTarget(text_.render, text_.cache); | ||
674 | if (!isRasterized_Glyph_(glyph, 0)) { | ||
675 | if (cache_Font_(font, glyph, 0)) { | ||
676 | numPendingRasterization_Text_--; | ||
677 | iAssert(numPendingRasterization_Text_ >= 0); | ||
678 | } | ||
679 | } | ||
680 | if (!isRasterized_Glyph_(glyph, 1)) { | ||
681 | if (cache_Font_(font, glyph, 1)) { /* half-pixel offset */ | ||
682 | numPendingRasterization_Text_--; | ||
683 | iAssert(numPendingRasterization_Text_ >= 0); | ||
684 | } | ||
685 | } | ||
686 | SDL_SetRenderTarget(text_.render, oldTarget); | ||
687 | } | 696 | } |
688 | return glyph; | 697 | return glyph; |
689 | } | 698 | } |
690 | 699 | ||
700 | void rasterizeSomePendingGlyphs_Text(void) { | ||
701 | size_t count = 5; | ||
702 | iForEach(PtrSet, i, text_.pendingRaster) { | ||
703 | iGlyph *glyph = *i.value; | ||
704 | remove_PtrSet(text_.pendingRaster, glyph); | ||
705 | doRaster_Font_(glyph->font, glyph); | ||
706 | if (!count--) break; | ||
707 | } | ||
708 | } | ||
709 | |||
691 | enum iRunMode { | 710 | enum iRunMode { |
692 | measure_RunMode = 0, | 711 | measure_RunMode = 0, |
693 | draw_RunMode = 1, | 712 | draw_RunMode = 1, |