Rename FontRenderer* symbols as FR_*

This commit is contained in:
Francesco Abbate 2020-06-11 18:12:47 +02:00
parent 117714390a
commit 00c3983da6
3 changed files with 57 additions and 61 deletions

View File

@ -10,15 +10,15 @@
// Important: when a subpixel scale is used the width below will be the width in logical pixel. // 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 // As each logical pixel contains 3 subpixels it means that the 'pixels' pointer
// will hold enough space for '3 * width' uint8_t values. // will hold enough space for '3 * width' uint8_t values.
struct FontRendererBitmap { struct FR_Bitmap {
agg::int8u *pixels; agg::int8u *pixels;
int width, height; int width, height;
}; };
typedef agg::blender_rgb_gamma<agg::rgba8, agg::order_bgra, agg::gamma_lut<> > blender_gamma_type; typedef agg::blender_rgb_gamma<agg::rgba8, agg::order_bgra, agg::gamma_lut<> > blender_gamma_type;
FontRendererBitmap* FontRendererBitmapNew(int width, int height, int subpixel_scale) { FR_Bitmap* FR_Bitmap_New(int width, int height, int subpixel_scale) {
FontRendererBitmap *image = (FontRendererBitmap *) malloc(sizeof(FontRendererBitmap) + width * height * subpixel_scale); FR_Bitmap *image = (FR_Bitmap *) malloc(sizeof(FR_Bitmap) + width * height * subpixel_scale);
if (!image) { return NULL; } if (!image) { return NULL; }
image->pixels = (agg::int8u *) (image + 1); image->pixels = (agg::int8u *) (image + 1);
image->width = width; image->width = width;
@ -26,16 +26,16 @@ FontRendererBitmap* FontRendererBitmapNew(int width, int height, int subpixel_sc
return image; return image;
} }
void FontRendererBitmapFree(FontRendererBitmap *image) { void FR_Bitmap_Free(FR_Bitmap *image) {
free(image); free(image);
} }
class FontRendererImpl { class FR_Impl {
public: public:
// Conventional LUT values: (1./3., 2./9., 1./9.) // Conventional LUT values: (1./3., 2./9., 1./9.)
// The values below are fine tuned as in the Elementary Plot library. // The values below are fine tuned as in the Elementary Plot library.
FontRendererImpl(bool hinting, bool kerning, bool subpixel, float gamma_value) : FR_Impl(bool hinting, bool kerning, bool subpixel, float gamma_value) :
m_renderer(hinting, kerning, subpixel), m_renderer(hinting, kerning, subpixel),
m_gamma_lut(double(gamma_value)), m_gamma_lut(double(gamma_value)),
m_blender(), m_blender(),
@ -56,23 +56,23 @@ private:
agg::lcd_distribution_lut m_lcd_lut; agg::lcd_distribution_lut m_lcd_lut;
}; };
FontRenderer *FontRendererNew(unsigned int flags, float gamma) { FontRenderer *FR_New(unsigned int flags, float gamma) {
bool hinting = ((flags & FONT_RENDERER_HINTING) != 0); bool hinting = ((flags & FONT_RENDERER_HINTING) != 0);
bool kerning = ((flags & FONT_RENDERER_KERNING) != 0); bool kerning = ((flags & FONT_RENDERER_KERNING) != 0);
bool subpixel = ((flags & FONT_RENDERER_SUBPIXEL) != 0); bool subpixel = ((flags & FONT_RENDERER_SUBPIXEL) != 0);
return new FontRendererImpl(hinting, kerning, subpixel, gamma); return new FR_Impl(hinting, kerning, subpixel, gamma);
} }
void FontRendererFree(FontRenderer *font_renderer) { void FR_Free(FontRenderer *font_renderer) {
delete font_renderer; delete font_renderer;
} }
int FontRendererLoadFont(FontRenderer *font_renderer, const char *filename) { int FR_Load_Font(FontRenderer *font_renderer, const char *filename) {
bool success = font_renderer->renderer_alpha().load_font(filename); bool success = font_renderer->renderer_alpha().load_font(filename);
return (success ? 0 : 1); return (success ? 0 : 1);
} }
int FontRendererGetFontHeight(FontRenderer *font_renderer, float size) { int FR_Get_Font_Height(FontRenderer *font_renderer, float size) {
font_renderer_alpha& renderer_alpha = font_renderer->renderer_alpha(); font_renderer_alpha& renderer_alpha = font_renderer->renderer_alpha();
double ascender, descender; double ascender, descender;
renderer_alpha.get_font_vmetrics(ascender, descender); renderer_alpha.get_font_vmetrics(ascender, descender);
@ -81,7 +81,7 @@ int FontRendererGetFontHeight(FontRenderer *font_renderer, float size) {
return int((ascender - descender) * face_height * scale + 0.5); return int((ascender - descender) * face_height * scale + 0.5);
} }
static void glyph_trim_rect(agg::rendering_buffer& ren_buf, GlyphBitmapInfo& gli, int subpixel_scale) { static void glyph_trim_rect(agg::rendering_buffer& ren_buf, FR_Bitmap_Glyph_Metrics& gli, int subpixel_scale) {
const int height = ren_buf.height(); const int height = ren_buf.height();
int x0 = gli.x0 * subpixel_scale, x1 = gli.x1 * subpixel_scale; int x0 = gli.x0 * subpixel_scale, x1 = gli.x1 * subpixel_scale;
int y0 = gli.y0, y1 = gli.y1; int y0 = gli.y0, y1 = gli.y1;
@ -145,7 +145,7 @@ static void glyph_trim_rect(agg::rendering_buffer& ren_buf, GlyphBitmapInfo& gli
gli.y1 = y1; gli.y1 = y1;
} }
static void glyph_lut_convolution(agg::rendering_buffer ren_buf, agg::lcd_distribution_lut& lcd_lut, agg::int8u *covers_buf, GlyphBitmapInfo& gli) { static void glyph_lut_convolution(agg::rendering_buffer ren_buf, agg::lcd_distribution_lut& lcd_lut, agg::int8u *covers_buf, FR_Bitmap_Glyph_Metrics& gli) {
const int subpixel = 3; const int subpixel = 3;
const int x0 = gli.x0, y0 = gli.y0, x1 = gli.x1, y1 = gli.y1; const int x0 = gli.x0, y0 = gli.y0, x1 = gli.x1, y1 = gli.y1;
const int len = (x1 - x0) * subpixel; const int len = (x1 - x0) * subpixel;
@ -169,9 +169,9 @@ static int ceil_to_multiple(int n, int p) {
return p * ((n + p - 1) / p); return p * ((n + p - 1) / p);
} }
int FontRendererBakeFontBitmap(FontRenderer *font_renderer, int font_height, int FR_Bake_Font_Bitmap(FontRenderer *font_renderer, int font_height,
FontRendererBitmap *image, FR_Bitmap *image,
int first_char, int num_chars, GlyphBitmapInfo *glyphs, int subpixel_scale) int first_char, int num_chars, FR_Bitmap_Glyph_Metrics *glyphs, int subpixel_scale)
{ {
font_renderer_alpha& renderer_alpha = font_renderer->renderer_alpha(); font_renderer_alpha& renderer_alpha = font_renderer->renderer_alpha();
@ -222,7 +222,7 @@ int FontRendererBakeFontBitmap(FontRenderer *font_renderer, int font_height,
int x_next_i = (subpixel_scale == 1 ? int(x_next + 1.0) : ceil_to_multiple(x_next + 0.5, subpixel_scale)); int x_next_i = (subpixel_scale == 1 ? int(x_next + 1.0) : ceil_to_multiple(x_next + 0.5, subpixel_scale));
// Below x and x_next_i will always be integer multiples of subpixel_scale. // Below x and x_next_i will always be integer multiples of subpixel_scale.
GlyphBitmapInfo& glyph_info = glyphs[i]; FR_Bitmap_Glyph_Metrics& glyph_info = glyphs[i];
glyph_info.x0 = x / subpixel_scale; glyph_info.x0 = x / subpixel_scale;
glyph_info.y0 = pixels_height - 1 - (y_baseline + ascender_px + pad_y); // FIXME: add -1 ? glyph_info.y0 = pixels_height - 1 - (y_baseline + ascender_px + pad_y); // FIXME: add -1 ?
glyph_info.x1 = x_next_i / subpixel_scale; glyph_info.x1 = x_next_i / subpixel_scale;
@ -303,7 +303,7 @@ void blend_solid_hspan_rgb_subpixel(agg::rendering_buffer& rbuf, agg::gamma_lut<
#if 0 #if 0
// destination implicitly BGRA32. Source implictly single-byte renderer_alpha coverage. // destination implicitly BGRA32. Source implictly single-byte renderer_alpha coverage.
void FontRendererBlendGamma(FontRenderer *font_renderer, uint8_t *dst, int dst_stride, uint8_t *src, int src_stride, int region_width, int region_height, FontRendererColor color) { void FR_Blend_Gamma(FontRenderer *font_renderer, uint8_t *dst, int dst_stride, uint8_t *src, int src_stride, int region_width, int region_height, FR_Color color) {
blender_gamma_type& blender = font_renderer->blender(); blender_gamma_type& blender = font_renderer->blender();
agg::rendering_buffer dst_ren_buf(dst, region_width, region_height, dst_stride); agg::rendering_buffer dst_ren_buf(dst, region_width, region_height, dst_stride);
const agg::rgba8 color_a(color.r, color.g, color.b); const agg::rgba8 color_a(color.r, color.g, color.b);
@ -316,7 +316,7 @@ void FontRendererBlendGamma(FontRenderer *font_renderer, uint8_t *dst, int dst_s
// destination implicitly BGRA32. Source implictly single-byte renderer_alpha coverage with subpixel scale = 3. // destination implicitly BGRA32. Source implictly single-byte renderer_alpha coverage with subpixel scale = 3.
// FIXME: consider using something like RenColor* instead of uint8_t * for dst. // FIXME: consider using something like RenColor* instead of uint8_t * for dst.
void FontRendererBlendGammaSubpixel(FontRenderer *font_renderer, FontRendererClipArea *clip, int x, int y, uint8_t *dst, int dst_width, const FontRendererBitmap *glyphs_bitmap, const GlyphBitmapInfo *glyph, FontRendererColor color) { void FR_Blend_Gamma_Subpixel(FontRenderer *font_renderer, FR_Clip_Area *clip, int x, int y, uint8_t *dst, int dst_width, const FR_Bitmap *glyphs_bitmap, const FR_Bitmap_Glyph_Metrics *glyph, FR_Color color) {
agg::gamma_lut<>& gamma = font_renderer->gamma(); agg::gamma_lut<>& gamma = font_renderer->gamma();
agg::lcd_distribution_lut& lcd_lut = font_renderer->lcd_distribution_lut(); agg::lcd_distribution_lut& lcd_lut = font_renderer->lcd_distribution_lut();
const int subpixel_scale = 3; const int subpixel_scale = 3;

View File

@ -10,12 +10,12 @@ extern "C" {
typedef struct { typedef struct {
unsigned short x0, y0, x1, y1; unsigned short x0, y0, x1, y1;
float xoff, yoff, xadvance; float xoff, yoff, xadvance;
} GlyphBitmapInfo; } FR_Bitmap_Glyph_Metrics;
typedef struct FontRendererBitmap FontRendererBitmap; typedef struct FR_Bitmap FR_Bitmap;
struct FontRendererImpl; struct FR_Impl;
typedef struct FontRendererImpl FontRenderer; typedef struct FR_Impl FontRenderer;
enum { enum {
FONT_RENDERER_HINTING = 1 << 0, FONT_RENDERER_HINTING = 1 << 0,
@ -25,43 +25,43 @@ enum {
typedef struct { typedef struct {
uint8_t r, g, b; uint8_t r, g, b;
} FontRendererColor; } FR_Color;
typedef struct { typedef struct {
int left, top, right, bottom; int left, top, right, bottom;
} FontRendererClipArea; } FR_Clip_Area;
FontRenderer * FontRendererNew(unsigned int flags, float gamma); FontRenderer * FR_New(unsigned int flags, float gamma);
void FontRendererFree(FontRenderer *); void FR_Free(FontRenderer *);
int FontRendererLoadFont(FontRenderer *, const char *filename); int FR_Load_Font(FontRenderer *, const char *filename);
int FontRendererGetFontHeight(FontRenderer *, float size); int FR_Get_Font_Height(FontRenderer *, float size);
int FontRendererBakeFontBitmap(FontRenderer *, int font_height, int FR_Bake_Font_Bitmap(FontRenderer *, int font_height,
FontRendererBitmap *image, FR_Bitmap *image,
int first_char, int num_chars, GlyphBitmapInfo *glyph_info, int first_char, int num_chars, FR_Bitmap_Glyph_Metrics *glyph_info,
int subpixel_scale); int subpixel_scale);
#if 0 #if 0
// FIXME: this function needs to be updated to match BlendGammaSubpixel. // FIXME: this function needs to be updated to match BlendGammaSubpixel.
void FontRendererBlendGamma(FontRenderer *, void FR_Blend_Gamma(FontRenderer *,
uint8_t *dst, int dst_stride, uint8_t *dst, int dst_stride,
uint8_t *src, int src_stride, uint8_t *src, int src_stride,
int region_width, int region_height, int region_width, int region_height,
FontRendererColor color); FR_Color color);
#endif #endif
void FontRendererBlendGammaSubpixel(FontRenderer *font_renderer, void FR_Blend_Gamma_Subpixel(FontRenderer *font_renderer,
FontRendererClipArea *clip, int x, int y, FR_Clip_Area *clip, int x, int y,
uint8_t *dst, int dst_width, uint8_t *dst, int dst_width,
const FontRendererBitmap *glyphs_bitmap, const FR_Bitmap *glyphs_bitmap,
const GlyphBitmapInfo *glyph, FontRendererColor color); const FR_Bitmap_Glyph_Metrics *glyph, FR_Color color);
FontRendererBitmap* FontRendererBitmapNew(int width, int height, int subpixel_scale); FR_Bitmap* FR_Bitmap_New(int width, int height, int subpixel_scale);
void FontRendererBitmapFree(FontRendererBitmap *image); void FR_Bitmap_Free(FR_Bitmap *image);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -13,8 +13,8 @@ struct RenImage {
}; };
struct GlyphSet { struct GlyphSet {
FontRendererBitmap *image; FR_Bitmap *image;
GlyphBitmapInfo glyphs[256]; FR_Bitmap_Glyph_Metrics glyphs[256];
}; };
typedef struct GlyphSet GlyphSet; typedef struct GlyphSet GlyphSet;
@ -29,7 +29,7 @@ struct RenFont {
static SDL_Window *window; static SDL_Window *window;
//static struct { int left, top, right, bottom; } clip; //static struct { int left, top, right, bottom; } clip;
static FontRendererClipArea clip; static FR_Clip_Area clip;
static void* check_alloc(void *ptr) { static void* check_alloc(void *ptr) {
if (!ptr) { if (!ptr) {
@ -113,17 +113,16 @@ static GlyphSet* load_glyphset(RenFont *font, int idx) {
int width = 128; int width = 128;
int height = 128; int height = 128;
retry: retry:
set->image = FontRendererBitmapNew(width, height, subpixel_scale); set->image = check_alloc(FR_Bitmap_New(width, height, subpixel_scale));
check_alloc(set->image);
int res = FontRendererBakeFontBitmap(font->renderer, font->height, int res = FR_Bake_Font_Bitmap(font->renderer, font->height,
set->image, 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 */ /* retry with a larger image buffer if the buffer wasn't large enough */
if (res < 0) { if (res < 0) {
width *= 2; width *= 2;
height *= 2; height *= 2;
FontRendererBitmapFree(set->image); FR_Bitmap_Free(set->image);
goto retry; goto retry;
} }
@ -153,15 +152,15 @@ RenFont* ren_load_font(const char *filename, float size) {
font->size = size; font->size = size;
const float gamma = 1.5; const float gamma = 1.5;
font->renderer = FontRendererNew(FONT_RENDERER_HINTING|FONT_RENDERER_SUBPIXEL, gamma); font->renderer = FR_New(FONT_RENDERER_HINTING|FONT_RENDERER_SUBPIXEL, gamma);
if (FontRendererLoadFont(font->renderer, filename)) { if (FR_Load_Font(font->renderer, filename)) {
free(font); free(font);
return NULL; return NULL;
} }
font->height = FontRendererGetFontHeight(font->renderer, size); font->height = FR_Get_Font_Height(font->renderer, size);
/* make tab and newline glyphs invisible */ /* make tab and newline glyphs invisible */
GlyphBitmapInfo *g = get_glyphset(font, '\n')->glyphs; FR_Bitmap_Glyph_Metrics *g = get_glyphset(font, '\n')->glyphs;
g['\t'].x1 = g['\t'].x0; g['\t'].x1 = g['\t'].x0;
g['\n'].x1 = g['\n'].x0; g['\n'].x1 = g['\n'].x0;
@ -173,11 +172,11 @@ void ren_free_font(RenFont *font) {
for (int i = 0; i < MAX_GLYPHSET; i++) { for (int i = 0; i < MAX_GLYPHSET; i++) {
GlyphSet *set = font->sets[i]; GlyphSet *set = font->sets[i];
if (set) { if (set) {
FontRendererBitmapFree(set->image); FR_Bitmap_Free(set->image);
free(set); free(set);
} }
} }
FontRendererFree(font->renderer); FR_Free(font->renderer);
free(font); free(font);
} }
@ -195,7 +194,7 @@ int ren_get_font_width(RenFont *font, const char *text) {
while (*p) { while (*p) {
p = utf8_to_codepoint(p, &codepoint); p = utf8_to_codepoint(p, &codepoint);
GlyphSet *set = get_glyphset(font, codepoint); GlyphSet *set = get_glyphset(font, codepoint);
GlyphBitmapInfo *g = &set->glyphs[codepoint & 0xff]; FR_Bitmap_Glyph_Metrics *g = &set->glyphs[codepoint & 0xff];
x += g->xadvance; x += g->xadvance;
} }
return x; return x;
@ -294,17 +293,14 @@ int ren_draw_text(RenFont *font, const char *text, int x, int y, RenColor color)
const char *p = text; const char *p = text;
unsigned codepoint; unsigned codepoint;
SDL_Surface *surf = SDL_GetWindowSurface(window); SDL_Surface *surf = SDL_GetWindowSurface(window);
FontRendererColor color_fr = { .r = color.r, .g = color.g, .b = color.b }; FR_Color color_fr = { .r = color.r, .g = color.g, .b = color.b };
while (*p) { while (*p) {
p = utf8_to_codepoint(p, &codepoint); p = utf8_to_codepoint(p, &codepoint);
GlyphSet *set = get_glyphset(font, codepoint); GlyphSet *set = get_glyphset(font, codepoint);
GlyphBitmapInfo *g = &set->glyphs[codepoint & 0xff]; FR_Bitmap_Glyph_Metrics *g = &set->glyphs[codepoint & 0xff];
if (color.a != 0) { if (color.a != 0) {
FontRendererBlendGammaSubpixel( FR_Blend_Gamma_Subpixel(font->renderer, &clip,
font->renderer, &clip, x, y, (uint8_t *) surf->pixels, surf->w, set->image, g, color_fr);
x, y,
(uint8_t *) surf->pixels, surf->w,
set->image, g, color_fr);
} }
x += g->xadvance; x += g->xadvance;
} }