aboutsummaryrefslogtreecommitdiff
path: root/drw.c
diff options
context:
space:
mode:
authorNathan Reiner <nathan@nathanreiner.xyz>2023-04-22 13:29:56 +0200
committerNathan Reiner <nathan@nathanreiner.xyz>2023-04-22 13:29:56 +0200
commit67893dc14d10f49a76652ff384ab2bf4a945ca30 (patch)
treec0612519116b0cfad0c1a1ae9df9beb92a9908e0 /drw.c
parentdc8f8644293b17f056edefa9e0e4a786686816a1 (diff)
add glyph caching
Diffstat (limited to 'drw.c')
-rw-r--r--drw.c95
1 files changed, 56 insertions, 39 deletions
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);
}