From 67893dc14d10f49a76652ff384ab2bf4a945ca30 Mon Sep 17 00:00:00 2001 From: Nathan Reiner Date: Sat, 22 Apr 2023 13:29:56 +0200 Subject: add glyph caching --- drw.c | 95 +++++++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 56 insertions(+), 39 deletions(-) (limited to 'drw.c') diff --git a/drw.c b/drw.c index 6683cdb..307e942 100644 --- a/drw.c +++ b/drw.c @@ -158,7 +158,7 @@ free_drw(Canvas *canvas) void push_buffer(Canvas *canvas) { - memcpy(canvas->buffer_data, canvas->data, canvas->size); + //memcpy(canvas->buffer_data, canvas->data, canvas->size); } @@ -168,7 +168,7 @@ draw_point(Canvas *canvas, unsigned x, unsigned y, uint32_t color) if (!(x < canvas->width && y < canvas->height)) return; - canvas->data[x + canvas->width * y] = color; + canvas->buffer_data[x + canvas->width * y] = color; } @@ -299,6 +299,7 @@ init_font(Font *font) FT_Stroker_New(font->library, &font->stroke); font->loaded = 1; + memset(font->cache, 0, CACHE_SIZE); } @@ -329,7 +330,7 @@ draw_bitmap(Canvas *canvas, FT_Bitmap *bitmap, unsigned x, unsigned y, uint32_t continue; } - bg = to_color(canvas->data[i + j * canvas->width]); + bg = to_color(canvas->buffer_data[i + j * canvas->width]); strength = bitmap->buffer[p + q * bitmap->width]; strength /= 255; @@ -379,59 +380,75 @@ get_font_with_charcode(FontCache *fontcache, uint_least32_t charcode) } -unsigned -draw_char(Canvas *canvas, FontCache *fontcache, uint_least32_t charcode, unsigned x, unsigned y, uint32_t color) +FT_BitmapGlyph +load_bitmap(Font *font, uint_least32_t charcode) { - FT_GlyphSlot slot; - FT_Error error; - FT_UInt glyph_index; - FT_UInt previous = 0; FT_Bool has_kerning; FT_Vector delta; - Font *font; + FT_UInt glyph_index; + FT_Error error; + FT_GlyphSlot slot; FT_BitmapGlyph bg; FT_Glyph glyph; - font = get_font_with_charcode(fontcache, charcode); - FT_Set_Pixel_Sizes(font->face, 0, fontcache->fontsize); + slot = font->face->glyph; + glyph_index = FT_Get_Char_Index(font->face, charcode); - if (boldstokemode && fontcache->fonttype == FONT_BOLD) { - FT_Stroker_Set(font->stroke, fontcache->fontsize * 2, FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, fontcache->fontsize * 2); + if (glyph_index >= CACHE_SIZE || font->cache[glyph_index] == 0) { + has_kerning = FT_HAS_KERNING(font->face); + if (has_kerning && glyph_index) { + FT_Get_Kerning(font->face, 0, glyph_index, FT_KERNING_DEFAULT, &delta); + } - y -= fontcache->fontsize * 2 / 64 + 1; + error = FT_Load_Glyph(font->face, glyph_index, FT_LOAD_DEFAULT); + if (error) { + fprintf(stderr, "warning: char not loaded, skipping...\n"); + return 0; + } + + FT_Get_Glyph(slot, &glyph); + FT_Glyph_StrokeBorder(&glyph, font->stroke, 0, 1); + if (error) { + fprintf(stderr, "warning: could not apply stroke\n"); + return 0; + } + + FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1); + bg = (FT_BitmapGlyph)glyph; + + if (glyph_index >= CACHE_SIZE) { + FT_Done_Glyph(glyph); + } else { + font->cache[glyph_index] = bg; + } } else { - FT_Stroker_Set(font->stroke, 0, FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0); + bg = font->cache[glyph_index]; } - slot = font->face->glyph; - glyph_index = FT_Get_Char_Index(font->face, charcode); + return bg; +} - has_kerning = FT_HAS_KERNING(font->face); - if (has_kerning && previous && glyph_index) { - FT_Get_Kerning(font->face, previous, glyph_index, FT_KERNING_DEFAULT, &delta); - x += delta.x >> 6; - } +void +draw_char(Canvas *canvas, FontCache *fontcache, uint_least32_t charcode, unsigned x, unsigned y, uint32_t color) +{ + Font *font; + FT_BitmapGlyph bg; - error = FT_Load_Glyph(font->face, glyph_index, FT_LOAD_DEFAULT); - if (error) { - fprintf(stderr, "warning: char not loaded, skipping...\n"); - return x; - } + font = get_font_with_charcode(fontcache, charcode); + FT_Set_Pixel_Sizes(font->face, 0, fontcache->fontsize); - FT_Get_Glyph(slot, &glyph); - FT_Glyph_StrokeBorder(&glyph, font->stroke, 0, 1); - if (error) { - fprintf(stderr, "warning: could not apply stroke\n"); - return x; + if (boldstokemode && fontcache->fonttype == FONT_BOLD) { + FT_Stroker_Set(font->stroke, fontcache->fontsize * 2, FT_STROKER_LINECAP_BUTT, FT_STROKER_LINEJOIN_ROUND, fontcache->fontsize * 2); + y -= fontcache->fontsize * 2 / 64 + 1; + } else { + FT_Stroker_Set(font->stroke, 0, FT_STROKER_LINECAP_BUTT, FT_STROKER_LINEJOIN_ROUND, 0); } - FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1); - bg = (FT_BitmapGlyph)glyph; - draw_bitmap(canvas, &bg->bitmap, x + bg->left, y - bg->top, color); - FT_Done_Glyph(glyph); + bg = load_bitmap(font, charcode); - x += fontcache->box.width >> 6; + if (bg == 0) + return; - return x; + draw_bitmap(canvas, &bg->bitmap, x + bg->left, y - bg->top, color); } -- cgit v1.2.3-70-g09d2