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.c61
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 */
53int enableKerning_Text = iTrue; /* looking up kern pairs is slow */ 54int enableKerning_Text = iTrue; /* looking up kern pairs is slow */
54 55
55static iBool enableRaster_Text_ = iTrue; 56static iBool enableRaster_Text_ = iTrue;
56static int numPendingRasterization_Text_ = 0;
57 57
58enum iGlyphFlag { 58enum 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
205static iText text_; 206static 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
430static void deinitCache_Text_(iText *d) { 430static 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
435void init_Text(SDL_Renderer *render) { 436void 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
463void setOpacity_Text(float opacity) { 466void setOpacity_Text(float opacity) {
@@ -503,8 +506,8 @@ void resetFonts_Text(void) {
503 initFonts_Text_(d); 506 initFonts_Text_(d);
504} 507}
505 508
506int numPendingGlyphs_Text(void) { 509size_t numPendingGlyphs_Text(void) {
507 return numPendingRasterization_Text_; 510 return size_PtrSet(text_.pendingRaster);
508} 511}
509 512
510iLocalDef iFont *font_Text_(enum iFontId id) { 513iLocalDef 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
578static iBool cache_Font_(iFont *d, iGlyph *glyph, int hoff) { 581static 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
647static 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
644static const iGlyph *glyph_Font_(iFont *d, iChar ch) { 667static 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
700void 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
691enum iRunMode { 710enum iRunMode {
692 measure_RunMode = 0, 711 measure_RunMode = 0,
693 draw_RunMode = 1, 712 draw_RunMode = 1,