pangocairo: text with a non-1:1 scale looks wrong
This comes from librsvg#730 (closed)
The following renders output.png
with four lines of text that should be identical. They just differ in the scale of the cairo_t
's current transform, and in the font size, but they should compound to produce text of the same size.
/* gcc -Wall -g -O0 -o scaling scaling.c `pkg-config --cflags --libs pangocairo` */
#include <cairo.h>
#include <pango/pango.h>
#include <pango/pangocairo.h>
static void
show_text(PangoContext *context, cairo_t *cr, double x, double y, double scale, double xofs, double yofs, double font_size)
{
PangoFontDescription *desc = pango_context_get_font_description(context);
pango_font_description_set_family(desc, "sans");
pango_font_description_set_size(desc, (int) (font_size * PANGO_SCALE));
PangoLayout *layout = pango_layout_new(context);
pango_layout_set_font_description(layout, desc);
pango_layout_set_text(layout, "How vexingly quick daft zebras jump!", -1);
cairo_save(cr);
cairo_translate(cr, x, y);
cairo_scale(cr, scale, scale);
pango_cairo_update_context(cr, context);
cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
cairo_move_to(cr, xofs, yofs);
pango_cairo_show_layout(cr, layout);
cairo_restore(cr);
g_object_unref(layout);
}
int
main(void)
{
cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 500, 200);
cairo_t *cr = cairo_create(surface);
PangoFontMap *font_map = pango_cairo_font_map_get_default();
PangoContext *context = pango_font_map_create_context(font_map);
/* Uncomment this to get correct output.
*
* pango_context_set_round_glyph_positions(context, FALSE);
*/
pango_cairo_update_context(cr, context);
pango_cairo_context_set_resolution(context, 72.0);
cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0);
cairo_paint(cr);
show_text(context, cr, 10.0, 0.0, 1, 0.0, 25.000, 20.0);
show_text(context, cr, 10.0, 40.0, 2, 0.0, 12.500, 10.0);
show_text(context, cr, 10.0, 80.0, 4, 0.0, 6.250, 5.0);
show_text(context, cr, 10.0, 120.0, 8, 0.0, 3.125, 2.5);
cairo_surface_write_to_png(surface, "output.png");
g_object_unref (context);
g_object_unref (font_map);
cairo_destroy(cr);
cairo_surface_destroy(surface);
return 0;
}
This is the output with the default round_glyph_positions=true
:
If one comments out the corresponding line, this is the output with round_glyph_positions=false
:
I'm not sure if the rounding is being done in user space, not device space, but this looks quite wrong?