After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 570901 - Rendering with a scaling transformation matrix breaks kerning in strange ways
Rendering with a scaling transformation matrix breaks kerning in strange ways
Status: RESOLVED DUPLICATE of bug 341481
Product: pango
Classification: Platform
Component: cairo
1.0.x
Other All
: Normal normal
: ---
Assigned To: pango-maint
pango-maint
: 570900 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2009-02-07 21:55 UTC by RiscTaker
Modified: 2009-02-08 00:24 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Broken kerning (121.48 KB, image/png)
2009-02-07 21:59 UTC, RiscTaker
Details
Kerning is OK. (121.81 KB, image/png)
2009-02-07 22:01 UTC, RiscTaker
Details

Description RiscTaker 2009-02-07 21:55:00 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:
Comment 1 RiscTaker 2009-02-07 21:59:49 UTC
Created attachment 128192 [details]
Broken kerning

Sorry about the size. I changed as little as possible in my original code to create the example
Comment 2 RiscTaker 2009-02-07 22:01:56 UTC
Created attachment 128193 [details]
Kerning is OK.
Comment 3 Behdad Esfahbod 2009-02-08 00:23:29 UTC
*** Bug 570900 has been marked as a duplicate of this bug. ***
Comment 4 Behdad Esfahbod 2009-02-08 00:24:49 UTC

*** This bug has been marked as a duplicate of 341481 ***