From d17fde1b13b2bdce88b0243e5c84a423f9742160 Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Sat, 6 Jun 2020 10:52:50 +0200 Subject: [PATCH] WIP: debugging stuff --- lib/font_renderer/font_renderer.cpp | 24 +++++++------ src/renderer.c | 53 +++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 10 deletions(-) diff --git a/lib/font_renderer/font_renderer.cpp b/lib/font_renderer/font_renderer.cpp index 474d9d6e..0ebf4af0 100644 --- a/lib/font_renderer/font_renderer.cpp +++ b/lib/font_renderer/font_renderer.cpp @@ -147,7 +147,7 @@ static void glyph_lut_convolution(agg::rendering_buffer ren_buf, agg::lcd_distri const int height = ren_buf.height(); for (int y = y0; y < y1; y++) { // FIXME: clarify why we do not use height - 1 below. - agg::int8u *covers = ren_buf.row_ptr(height - y) + x0 * subpixel; + agg::int8u *covers = ren_buf.row_ptr(height - 1 - y) + x0 * subpixel; memcpy(covers_buf, covers, len); #if 0 if (len >= 24) { @@ -190,18 +190,20 @@ int FontRendererBakeFontBitmap(FontRenderer *font_renderer, int font_height, double ascender, descender; renderer_alpha.get_font_vmetrics(ascender, descender); - const int ascender_px = int(ascender * font_height + 0.5); - const int descender_px = int(descender * font_height + 0.5); + // FIXME: depending how we approximate ascender - descender could differ from font_height + const int ascender_px = int( ascender * font_height + 1.0); + const int descender_px = -int(-descender * font_height + 1.0); + const int font_height_ext = ascender_px - descender_px; const int pad_y = font_height / 10; - const int y_step = font_height + 2 * pad_y; + const int y_step = font_height_ext + 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); // 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; - int x = x_start, y = pixels_height; + int x = x_start, y = pixels_height - 1; // - 20; // -20 is for debug int res = 0; const agg::alpha8 text_color(0xff); #ifdef FONT_RENDERER_HEIGHT_HACK @@ -209,28 +211,30 @@ int FontRendererBakeFontBitmap(FontRenderer *font_renderer, int font_height, #else const int font_height_reduced = font_height; #endif + fprintf(stderr, "FONT HEIGHT %d, ASCENDER: %d DESCENDER: %d\n", font_height, ascender_px, descender_px); for (int i = 0; i < num_chars; i++) { int codepoint = first_char + i; if (x + font_height * subpixel_scale > pixels_width * subpixel_scale) { x = x_start; y -= y_step; } - if (y - font_height - 2 * pad_y < 0) { + if (y - y_step < 0) { res = -1; break; } - const int y_baseline = y - pad_y - font_height; + const int y_baseline = y - pad_y - ascender_px; double x_next = x, y_next = y_baseline; + fprintf(stderr, "GLYPH (%d, %d)\n", x, y_baseline); renderer_alpha.render_codepoint(ren_buf, font_height_reduced, text_color, x_next, y_next, codepoint, 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. GlyphBitmapInfo& glyph_info = glyphs[i]; glyph_info.x0 = x / subpixel_scale; - glyph_info.y0 = pixels_height - (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.y1 = pixels_height - (y_baseline + descender_px - pad_y); // FIXME: add -1 ? + glyph_info.y1 = pixels_height - 1 - (y_baseline + descender_px - pad_y); // FIXME: add -1 ? glyph_info.xoff = 0; glyph_info.yoff = -pad_y; @@ -240,7 +244,7 @@ int FontRendererBakeFontBitmap(FontRenderer *font_renderer, int font_height, agg::int8u *covers_buf = ren_buf.row_ptr(0); glyph_lut_convolution(ren_buf, lcd_lut, covers_buf, glyph_info); } - glyph_trim_rect(ren_buf, glyph_info, subpixel_scale); + // glyph_trim_rect(ren_buf, glyph_info, subpixel_scale); // When subpixel is activated we need at least two more subpixels on the right. x = x_next_i + 2 * subpixel_scale; diff --git a/src/renderer.c b/src/renderer.c index b3118bb9..7a360af5 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -126,6 +126,33 @@ void ren_free_coverage(RenCoverageImage *coverage) { free(coverage); } +void debug_bitmap_draw_rect(RenImage *image, GlyphBitmapInfo *glyph) { + const int subpixel = 3; + const int x0 = glyph->x0, x1 = glyph->x1; + const int y0 = glyph->y0, y1 = glyph->y1; + const int w = image->width; + RenColor *c = image->pixels + y0 * w; + for (int x = x0 * subpixel; x < x1 * subpixel; x++) { + c[x].g = c[x].g >> 1; + c[x].b = c[x].b >> 1; + } + c = image->pixels + x1 * subpixel; + for (int y = y0; y < y1; y++) { + c[y * w].g = c[y * w].g >> 1; + c[y * w].b = c[y * w].b >> 1; + } + c = image->pixels + y1 * w; + for (int x = x0 * subpixel; x < x1 * subpixel; x++) { + c[x].g = c[x].g >> 1; + c[x].b = c[x].b >> 1; + } + c = image->pixels + x0 * subpixel; + for (int y = y0 + 1; y < y1; y++) { + c[y * w].g = c[y * w].g >> 1; + c[y * w].b = c[y * w].b >> 1; + } +} + static GlyphSet* load_glyphset(RenFont *font, int idx) { GlyphSet *set = check_alloc(calloc(1, sizeof(GlyphSet))); @@ -149,6 +176,32 @@ retry: goto retry; } + static int debug_image_index = 1; + if (idx == 0) { + // DEBUG CODE + RenImage *debug_cov_image = ren_new_image(width * subpixel_scale, height); + for (int h = 0; h < height; h++) { + RenColor *d = debug_cov_image->pixels + h * width * subpixel_scale; + uint8_t *s = set->coverage->pixels + h * subpixel_scale * width; + for (int w = 0; w < width * subpixel_scale; w++) { + uint8_t cover = s[w]; + d[w] = (RenColor) {.b = 0xff - cover, .g = 0xff - cover, .r = 0xff - cover, .a = 0xff}; + } + } + for (int i = 0; i < 256; i++) { + debug_bitmap_draw_rect(debug_cov_image, &set->glyphs[i]); + } + SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormatFrom( + debug_cov_image->pixels, + width * subpixel_scale, height, 32, width * subpixel_scale * 4, + SDL_PIXELFORMAT_RGBA32); + char img_filename[64]; + sprintf(img_filename, "agg-glyphset-%03d.bmp", debug_image_index); + SDL_SaveBMP(surface, img_filename); + SDL_FreeSurface(surface); + ren_free_image(debug_cov_image); + debug_image_index++; + } /* adjust glyph's xadvance */ for (int i = 0; i < 256; i++) { set->glyphs[i].xadvance = floor(set->glyphs[i].xadvance + 0.5);