GNOME Bugzilla – Bug 570901
Rendering with a scaling transformation matrix breaks kerning in strange ways
Last modified: 2009-02-08 00:24:49 UTC
Please describe the problem: When rendering to an ImageSurface with a cairo transformation matrix that scales in both the X and Y directions, the horizontal separation between certain letters is completely broken. I have discovered that setting a pango matrix with the scaling factors both set to 1 fixes the problem, *but* calling Pango::Layout::get_line_count() at the wrong point breaks this workaround. Steps to reproduce: #include <gtkmm.h> #include <cairomm/cairomm.h> int main(int argc, char *argv[]) { Gtk::Main kit(argc, argv); //Pango::init(); Cairo::RefPtr<Cairo::ImageSurface> surface = Cairo::ImageSurface::create( Cairo::FORMAT_ARGB32, 640, 480); Cairo::RefPtr<Cairo::Context> context = Cairo::Context::create(surface); context->set_source_rgba(0, 0, 0, 0); context->rectangle(0, 0, 640, 480); context->fill(); Pango::FontDescription font; font.set_family("Sans"); font.set_size(12*PANGO_SCALE); Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context); context->move_to(10, 50); context->set_source_rgba(0, 0, 0, 1); layout->set_font_description(font); layout->set_text("This is a test"); layout->update_from_cairo_context(context); layout->add_to_cairo_context(context); context->fill(); context->move_to(10, 50); //context->set_source_rgba(0, 1, 0, 1); //layout->set_spacing(1000); layout->set_font_description(font); layout->set_markup("<span foreground='#118800'>This <span foreground='#FF0000'>is</span>\012 a tegYt</span>"); layout->update_from_cairo_context(context); //layout->add_to_cairo_context(context); layout->get_line(0)->show_in_cairo_context(context); layout->get_line(1)->show_in_cairo_context(context); Pango::Rectangle rect0 = layout->get_line(0)->get_logical_extents(); Pango::Rectangle rect1 = layout->get_line(1)->get_logical_extents(); //context->fill(); surface->write_to_png("TEST.png"); uint32_t size = surface->get_stride() * surface->get_height(); //saveFile(surface->get_data(), size, "RAW.bin"); Cairo::RefPtr<Cairo::ImageSurface> surface2 = Cairo::ImageSurface ::create(Cairo::FORMAT_A8, 640*16, 480*16); context = Cairo::Context::create(surface2); Cairo::Matrix matrix = {16, 0, 0, 16, 0, 0}; Pango::Matrix pmatrix = {1, 0, 0, 1, 0, 0}; context->set_matrix(matrix); context->set_source_rgba(0, 0, 0, 0); context->rectangle(0, 0, 640*16, 480*16); context->fill(); layout = Pango::Layout::create(context); //context->set_source_rgba(0, 1, 0, 1); layout->set_font_description(font); layout->set_width(640*Pango::SCALE); layout->set_markup("<span foreground='#FFFF00'>This is a test with a really really really really REALLY long line that will hopefully wrap at some point.</span>"); //layout->update_from_cairo_context(context); layout->get_context()->set_matrix(pmatrix); uint32_t lines = layout->get_line_count(); Pango::Rectangle rect = layout->get_line(0)->get_pixel_logical_extents(); context->move_to(10, rect.get_ascent()); layout->get_line(0)->show_in_cairo_context(context); size = surface2->get_stride() * surface2->get_height(); surface2->write_to_png("TEST.png"); //saveFile(surface2->get_data(), size, "RAWBIT.bin"); return 0; } In this example this work fine. However, transposing the these two lines: layout->get_context()->set_matrix(pmatrix); uint32_t lines = layout->get_line_count(); causes the problem to return. As of course does removing the 'set_matrix()' call altogether. The results can be seen by looking at the TEST.png image after running the program. Actual results: Expected results: Does this happen every time? Yes. Other information:
Created attachment 128192 [details] Broken kerning Sorry about the size. I changed as little as possible in my original code to create the example
Created attachment 128193 [details] Kerning is OK.
*** Bug 570900 has been marked as a duplicate of this bug. ***
*** This bug has been marked as a duplicate of 341481 ***