Add correct glyphs bitmap location rects with AGG

This commit is contained in:
Francesco Abbate 2020-05-31 13:53:27 +02:00
parent 7c57b1d6ca
commit 4ec521dd37
2 changed files with 43 additions and 16 deletions

View File

@ -46,13 +46,17 @@ public:
m_trans(m_curves, m_mtx) m_trans(m_curves, m_mtx)
{ } { }
bool get_font_vmetrics(int& ascender, int& descender) { int get_face_height() const {
return m_feng.face_height();
}
bool get_font_vmetrics(double& ascender, double& descender) {
int face_height = m_feng.face_height(); int face_height = m_feng.face_height();
if (face_height > 0) { if (face_height > 0) {
double current_height = m_feng.height(); double current_height = m_feng.height();
m_feng.height(1.0); m_feng.height(1.0);
ascender = m_feng.ascender() * face_height; ascender = m_feng.ascender();
descender = m_feng.descender() * face_height; descender = m_feng.descender();
m_feng.height(current_height); m_feng.height(current_height);
return true; return true;
} }

View File

@ -10,6 +10,12 @@
typedef struct { uint8_t b, g, r, a; } RenColor; typedef struct { uint8_t b, g, r, a; } RenColor;
typedef struct { int x, y, width, height; } RenRect; typedef struct { int x, y, width, height; } RenRect;
// Mirrors stbtt_bakedchar.
struct GlyphBitmapInfo {
unsigned short x0, y0, x1, y1;
float xoff, yoff, xadvance;
};
struct RenImage { struct RenImage {
RenColor *pixels; RenColor *pixels;
int width, height; int width, height;
@ -17,14 +23,14 @@ struct RenImage {
struct GlyphSetA { struct GlyphSetA {
RenImage *image; RenImage *image;
// FIXME: add glyphs information for AGG implementation GlyphBitmapInfo glyphs[256];
// stbtt_bakedchar glyphs[256];
}; };
struct RenFontA { struct RenFontA {
font_renderer_alpha *renderer; font_renderer_alpha *renderer;
float size; float size;
int height; int height;
float ascender, descender;
// For some reason the font's height used in renderer.c // For some reason the font's height used in renderer.c
// when calling BakeFontBitmap is 0.5 off from 'height'. // when calling BakeFontBitmap is 0.5 off from 'height'.
float height_bitmap; float height_bitmap;
@ -63,13 +69,20 @@ RenFontA* ren_load_font_agg(const char *filename, float size) {
font->renderer = new font_renderer_alpha(false, false); font->renderer = new font_renderer_alpha(false, false);
font->renderer->load_font(filename); font->renderer->load_font(filename);
int ascender, descender; double ascender, descender;
font->renderer->get_font_vmetrics(ascender, descender); font->renderer->get_font_vmetrics(ascender, descender);
fprintf(stderr, "Font metrics ascender: %d descender: %d\n", ascender, descender); int face_height = font->renderer->get_face_height();
// Gives the font's ascender and descender like stbtt.
fprintf(stderr, "Font metrics ascender: %g descender: %g\n", ascender * face_height, descender * face_height);
float scale = font->renderer->scale_for_em_to_pixels(size); float scale = font->renderer->scale_for_em_to_pixels(size);
font->height = (ascender - descender) * scale + 0.5; font->height = (ascender - descender) * face_height * scale + 0.5;
font->height_bitmap = (ascender - descender) * scale; font->height_bitmap = (ascender - descender) * face_height * scale;
font->descender = descender * font->height_bitmap;
font->ascender = ascender * font->height_bitmap;
fprintf(stderr, "Font's pixel ascender: %g descender: %g sum: %g\n", font->ascender, font->descender, font->ascender - font->descender);
fprintf(stderr, "Font height: %d\n", font->height); fprintf(stderr, "Font height: %d\n", font->height);
@ -92,22 +105,32 @@ retry:
agg::rendering_buffer ren_buf((agg::int8u *) set->image->pixels, width, height, -width * pixel_size); agg::rendering_buffer ren_buf((agg::int8u *) set->image->pixels, width, height, -width * pixel_size);
// FIXME: figure out how to precisely layout each glyph. // FIXME: figure out how to precisely layout each glyph.
double x = 4, y = height - font->height * 3 / 2; double x = 0, y = height;
int res = 0; int res = 0;
const agg::alpha8 text_color(0xff); const agg::alpha8 text_color(0xff);
for (int i = 0; i < 256; i++) { for (int i = 0; i < 256; i++) {
if (x + font->height * 3 / 2 > width) { if (x + font->height > width) {
x = 4; x = 0;
y -= font->height * 3 / 2; y -= font->height;
} }
if (y < 0) { if (y - font->height < 0) {
res = -1; res = -1;
break; break;
} }
// FIXME: we are ignoring idx and with a char we cannot pass codepoint > 255. // FIXME: we are ignoring idx and with a char we cannot pass codepoint > 255.
char text[2] = {char(i % 256), 0}; char text[2] = {char(i % 256), 0};
// FIXME: using font->size below is wrong. // FIXME: using font->height_bitmap below seems logically correct but
font->renderer->render_text(ren_buf, font->height_bitmap, text_color, x, y, text); // the font size is bigger than what printed by BakeFontBitmap.
double x_next = x, y_next = y - font->height;
font->renderer->render_text(ren_buf, font->height_bitmap, text_color, x_next, y_next, text);
set->glyphs[i].x0 = x - 1;
set->glyphs[i].y0 = y - font->descender;
set->glyphs[i].x1 = x_next - 1;
set->glyphs[i].y1 = y + font->ascender;
set->glyphs[i].xoff = -1;
set->glyphs[i].yoff = -font->ascender;
set->glyphs[i].xadvance = x_next - x;
x = x_next;
} }
/* 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 */