From 117714390a4b160f59a76f332042060324f1ad13 Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Thu, 11 Jun 2020 17:52:00 +0200 Subject: [PATCH] Make the FontRenderer's Bitmap struct opaque outside the library --- lib/font_renderer/font_renderer.cpp | 28 ++++++++++++++++++++++++++-- lib/font_renderer/font_renderer.h | 14 ++++++-------- src/renderer.c | 25 +++++-------------------- 3 files changed, 37 insertions(+), 30 deletions(-) diff --git a/lib/font_renderer/font_renderer.cpp b/lib/font_renderer/font_renderer.cpp index efa3483c..b8bf44e6 100644 --- a/lib/font_renderer/font_renderer.cpp +++ b/lib/font_renderer/font_renderer.cpp @@ -7,8 +7,29 @@ #include "font_renderer_alpha.h" +// Important: when a subpixel scale is used the width below will be the width in logical pixel. +// As each logical pixel contains 3 subpixels it means that the 'pixels' pointer +// will hold enough space for '3 * width' uint8_t values. +struct FontRendererBitmap { + agg::int8u *pixels; + int width, height; +}; + typedef agg::blender_rgb_gamma > blender_gamma_type; +FontRendererBitmap* FontRendererBitmapNew(int width, int height, int subpixel_scale) { + FontRendererBitmap *image = (FontRendererBitmap *) malloc(sizeof(FontRendererBitmap) + width * height * subpixel_scale); + if (!image) { return NULL; } + image->pixels = (agg::int8u *) (image + 1); + image->width = width; + image->height = height; + return image; +} + +void FontRendererBitmapFree(FontRendererBitmap *image) { + free(image); +} + class FontRendererImpl { public: // Conventional LUT values: (1./3., 2./9., 1./9.) @@ -149,11 +170,14 @@ static int ceil_to_multiple(int n, int p) { } int FontRendererBakeFontBitmap(FontRenderer *font_renderer, int font_height, - void *pixels, int pixels_width, int pixels_height, + FontRendererBitmap *image, int first_char, int num_chars, GlyphBitmapInfo *glyphs, int subpixel_scale) { font_renderer_alpha& renderer_alpha = font_renderer->renderer_alpha(); + agg::int8u *pixels = image->pixels; + const int pixels_width = image->width, pixels_height = image->height; + const int pixel_size = 1; memset(pixels, 0x00, pixels_width * pixels_height * subpixel_scale * pixel_size); @@ -167,7 +191,7 @@ int FontRendererBakeFontBitmap(FontRenderer *font_renderer, int font_height, const int y_step = font_height + 2 * pad_y; agg::lcd_distribution_lut& lcd_lut = font_renderer->lcd_distribution_lut(); - agg::rendering_buffer ren_buf((agg::int8u *) pixels, pixels_width * subpixel_scale, pixels_height, -pixels_width * subpixel_scale * pixel_size); + agg::rendering_buffer ren_buf(pixels, pixels_width * subpixel_scale, pixels_height, -pixels_width * subpixel_scale * pixel_size); // When using subpixel font rendering it is needed to leave a padding pixel on the left and on the right. // Since each pixel is composed by n subpixel we set below x_start to subpixel_scale instead than zero. const int x_start = subpixel_scale; diff --git a/lib/font_renderer/font_renderer.h b/lib/font_renderer/font_renderer.h index d60ad0aa..91102782 100644 --- a/lib/font_renderer/font_renderer.h +++ b/lib/font_renderer/font_renderer.h @@ -12,13 +12,7 @@ typedef struct { float xoff, yoff, xadvance; } GlyphBitmapInfo; -// Important: when a subpixel scale is used the width below will be the width in logical pixel. -// As each logical pixel contains 3 subpixels it means that the 'pixels' pointer -// will hold enough space for '3 * width' uint8_t values. -typedef struct { - uint8_t *pixels; - int width, height; -} FontRendererBitmap; +typedef struct FontRendererBitmap FontRendererBitmap; struct FontRendererImpl; typedef struct FontRendererImpl FontRenderer; @@ -46,7 +40,7 @@ int FontRendererLoadFont(FontRenderer *, const char *filename); int FontRendererGetFontHeight(FontRenderer *, float size); int FontRendererBakeFontBitmap(FontRenderer *, int font_height, - void *pixels, int pixels_width, int pixels_height, + FontRendererBitmap *image, int first_char, int num_chars, GlyphBitmapInfo *glyph_info, int subpixel_scale); @@ -65,6 +59,10 @@ void FontRendererBlendGammaSubpixel(FontRenderer *font_renderer, const FontRendererBitmap *glyphs_bitmap, const GlyphBitmapInfo *glyph, FontRendererColor color); +FontRendererBitmap* FontRendererBitmapNew(int width, int height, int subpixel_scale); + +void FontRendererBitmapFree(FontRendererBitmap *image); + #ifdef __cplusplus } #endif diff --git a/src/renderer.c b/src/renderer.c index e43337db..2668b78d 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -104,21 +104,6 @@ void ren_free_image(RenImage *image) { free(image); } -// FIXME: move this function into FontRenderer and change name. -FontRendererBitmap* ren_new_coverage_image(int width, int height, int subpixel_scale) { - assert(width > 0 && height > 0); - FontRendererBitmap *image = malloc(sizeof(FontRendererBitmap) + width * height * subpixel_scale * sizeof(uint8_t)); - check_alloc(image); - image->pixels = (void*) (image + 1); - image->width = width; - image->height = height; - return image; -} - -void ren_free_coverage_image(FontRendererBitmap *image) { - free(image); -} - static GlyphSet* load_glyphset(RenFont *font, int idx) { GlyphSet *set = check_alloc(calloc(1, sizeof(GlyphSet))); @@ -128,17 +113,17 @@ static GlyphSet* load_glyphset(RenFont *font, int idx) { int width = 128; int height = 128; retry: - set->image = ren_new_coverage_image(width, height, subpixel_scale); + set->image = FontRendererBitmapNew(width, height, subpixel_scale); + check_alloc(set->image); int res = FontRendererBakeFontBitmap(font->renderer, font->height, - (void *) set->image->pixels, width, height, - idx << 8, 256, set->glyphs, subpixel_scale); + set->image, idx << 8, 256, set->glyphs, subpixel_scale); /* retry with a larger image buffer if the buffer wasn't large enough */ if (res < 0) { width *= 2; height *= 2; - ren_free_coverage_image(set->image); + FontRendererBitmapFree(set->image); goto retry; } @@ -188,7 +173,7 @@ void ren_free_font(RenFont *font) { for (int i = 0; i < MAX_GLYPHSET; i++) { GlyphSet *set = font->sets[i]; if (set) { - ren_free_coverage_image(set->image); + FontRendererBitmapFree(set->image); free(set); } }