diff --git a/lib/font_renderer/font_renderer.cpp b/lib/font_renderer/font_renderer.cpp index c49426a8..d49399e5 100644 --- a/lib/font_renderer/font_renderer.cpp +++ b/lib/font_renderer/font_renderer.cpp @@ -61,6 +61,10 @@ void FR_Renderer_Free(FR_Renderer *font_renderer) { delete font_renderer; } +int FR_Subpixel_Scale(FR_Renderer *font_renderer) { + return font_renderer->subpixel_scale(); +} + int FR_Load_Font(FR_Renderer *font_renderer, const char *filename) { bool success = font_renderer->renderer_alpha().load_font(filename); return (success ? 0 : 1); @@ -283,7 +287,9 @@ FR_Bitmap *FR_Bake_Font_Bitmap(FR_Renderer *font_renderer, int font_height, glyph_info.xoff = 0; glyph_info.yoff = -pad_y - gbounds.y2 + ascender_px; - glyph_info.xadvance = (x_next - x) / subpixel_scale; + // Note that below the xadvance is in pixels times the subpixel_scale. + // This is meant for subpixel positioning. + glyph_info.xadvance = roundf(x_next - x); if (subpixel_scale != 1 && glyph_info.x1 > glyph_info.x0) { glyph_lut_convolution(ren_buf, lcd_lut, cover_swap_buffer, glyph_info); @@ -346,15 +352,18 @@ void blend_solid_hspan_subpixel(agg::rendering_buffer& rbuf, agg::lcd_distributi // 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. -void FR_Blend_Glyph(FR_Renderer *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) { +void FR_Blend_Glyph(FR_Renderer *font_renderer, FR_Clip_Area *clip, int x_mult, int y, uint8_t *dst, int dst_width, const FR_Bitmap *glyphs_bitmap, const FR_Bitmap_Glyph_Metrics *glyph, FR_Color color) { agg::lcd_distribution_lut& lcd_lut = font_renderer->lcd_distribution_lut(); const int subpixel_scale = font_renderer->subpixel_scale(); const int pixel_size = 4; // Pixel size for BGRA32 format. + int x = x_mult / subpixel_scale; + x += glyph->xoff; y += glyph->yoff; int glyph_x = glyph->x0, glyph_y = glyph->y0; + int glyph_x_subpixel = -(x_mult % subpixel_scale); int glyph_width = glyph->x1 - glyph->x0; int glyph_height = glyph->y1 - glyph->y0; @@ -371,7 +380,7 @@ void FR_Blend_Glyph(FR_Renderer *font_renderer, FR_Clip_Area *clip, int x, int y dst += (x + y * dst_width) * pixel_size; agg::rendering_buffer dst_ren_buf(dst, glyph_width, glyph_height, dst_width * pixel_size); - uint8_t *src = glyphs_bitmap->pixels + (glyph_x + glyph_y * glyphs_bitmap->width) * subpixel_scale; + uint8_t *src = glyphs_bitmap->pixels + (glyph_x + glyph_y * glyphs_bitmap->width) * subpixel_scale + glyph_x_subpixel; int src_stride = glyphs_bitmap->width * subpixel_scale; const agg::rgba8 color_a(color.r, color.g, color.b); diff --git a/lib/font_renderer/font_renderer.h b/lib/font_renderer/font_renderer.h index f6e77ea6..69696340 100644 --- a/lib/font_renderer/font_renderer.h +++ b/lib/font_renderer/font_renderer.h @@ -49,6 +49,9 @@ void FR_Blend_Glyph(FR_Renderer *font_renderer, uint8_t *dst, int dst_width, const FR_Bitmap *glyphs_bitmap, const FR_Bitmap_Glyph_Metrics *glyph, FR_Color color); +int FR_Subpixel_Scale(FR_Renderer *); + +#define FR_XADVANCE_TO_PIXELS(x, scale) (((x) + (scale) / 2) / (scale)) #ifdef __cplusplus } diff --git a/src/renderer.c b/src/renderer.c index 24eae283..6b31aaca 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -109,11 +109,6 @@ static GlyphSet* load_glyphset(RenFont *font, int idx) { set->image = FR_Bake_Font_Bitmap(font->renderer, font->height, idx << 8, 256, set->glyphs); check_alloc(set->image); - /* adjust glyph's xadvance */ - for (int i = 0; i < 256; i++) { - set->glyphs[i].xadvance = floor(set->glyphs[i].xadvance + 0.5); - } - return set; } @@ -188,13 +183,14 @@ int ren_get_font_width(RenFont *font, const char *text) { int x = 0; const char *p = text; unsigned codepoint; + const int subpixel_scale = FR_Subpixel_Scale(font->renderer); while (*p) { p = utf8_to_codepoint(p, &codepoint); GlyphSet *set = get_glyphset(font, codepoint); FR_Bitmap_Glyph_Metrics *g = &set->glyphs[codepoint & 0xff]; x += g->xadvance; } - return x; + return FR_XADVANCE_TO_PIXELS(x, subpixel_scale); } @@ -291,15 +287,17 @@ int ren_draw_text(RenFont *font, const char *text, int x, int y, RenColor color) unsigned codepoint; SDL_Surface *surf = SDL_GetWindowSurface(window); FR_Color color_fr = { .r = color.r, .g = color.g, .b = color.b }; + const int subpixel_scale = FR_Subpixel_Scale(font->renderer); + int x_mult = subpixel_scale * x; while (*p) { p = utf8_to_codepoint(p, &codepoint); GlyphSet *set = get_glyphset(font, codepoint); FR_Bitmap_Glyph_Metrics *g = &set->glyphs[codepoint & 0xff]; if (color.a != 0) { FR_Blend_Glyph(font->renderer, &clip, - x, y, (uint8_t *) surf->pixels, surf->w, set->image, g, color_fr); + x_mult, y, (uint8_t *) surf->pixels, surf->w, set->image, g, color_fr); } - x += g->xadvance; + x_mult += g->xadvance; } - return x; + return FR_XADVANCE_TO_PIXELS(x_mult, subpixel_scale); }