From e01ba599babda002eb912c213090e21ca8fa1f33 Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Tue, 2 Jun 2020 18:46:44 +0200 Subject: [PATCH] Optimize glyph set bitmap rectangles by trimming empty regions --- src/font_renderer.cpp | 54 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/src/font_renderer.cpp b/src/font_renderer.cpp index f4188646..a2c440be 100644 --- a/src/font_renderer.cpp +++ b/src/font_renderer.cpp @@ -51,6 +51,57 @@ int FontRendererGetFontHeight(FontRenderer *font_renderer, float size) { return int((ascender - descender) * face_height * scale + 0.5); } +static void glyph_trim_rect(agg::rendering_buffer& ren_buf, GlyphBitmapInfo *gli) { + const int height = ren_buf.height(); + int x0 = gli->x0, y0 = gli->y0, x1 = gli->x1, y1 = gli->y1; + for (int y = gli->y0; y < gli->y1; y++) { + uint8_t *row = ren_buf.row_ptr(height - 1 - y); + unsigned int row_bitsum = 0; + for (int x = x0; x < x1; x++) { + row_bitsum |= row[x]; + } + if (row_bitsum == 0) { + y0++; + } else { + break; + } + } + for (int y = gli->y1 - 1; y >= gli->y0; y--) { + uint8_t *row = ren_buf.row_ptr(height - 1 - y); + unsigned int row_bitsum = 0; + for (int x = x0; x < x1; x++) { + row_bitsum |= row[x]; + } + if (row_bitsum == 0) { + y1--; + } else { + break; + } + } + int xtriml = x0, xtrimr = x1; + for (int y = y0; y < y1; y++) { + uint8_t *row = ren_buf.row_ptr(height - 1 - y); + for (int x = x0; x < x1; x++) { + if (row[x]) { + if (x < xtriml) xtriml = x; + break; + } + } + for (int x = x1 - 1; x >= x0; x--) { + if (row[x]) { + if (x > xtrimr) xtrimr = x + 1; + break; + } + } + } + gli->xoff += (xtriml - x0); + gli->yoff += (y0 - gli->y0); + gli->x0 = xtriml; + gli->y0 = y0; + gli->x1 = xtrimr; + gli->y1 = y1; +} + int FontRendererBakeFontBitmap(FontRenderer *font_renderer, int font_height, void *pixels, int pixels_width, int pixels_height, int first_char, int num_chars, GlyphBitmapInfo *glyphs) @@ -99,10 +150,13 @@ int FontRendererBakeFontBitmap(FontRenderer *font_renderer, int font_height, glyph_info.y0 = pixels_height - (y_baseline + ascender_px + pad_y); glyph_info.x1 = x_next_i; glyph_info.y1 = pixels_height - (y_baseline + descender_px - pad_y); + glyph_info.xoff = 0; glyph_info.yoff = -pad_y; glyph_info.xadvance = x_next - x; + glyph_trim_rect(ren_buf, &glyph_info); + x = x_next_i + pad_x; #ifdef FONT_RENDERER_DEBUG