Bug 51910 - Surface based patterns are drawn incorrectly when using non-default pattern matrix
Surface based patterns are drawn incorrectly when using non-default pattern m...
Product: cairo
Classification: Unclassified
Component: xlib backend
x86-64 (AMD64) Linux (All)
: medium normal
Assigned To: Carl Worth
cairo-bugs mailing list
Depends on:
  Show dependency treegraph
Reported: 2012-07-09 13:51 UTC by Albertas Vyšniauskas
Modified: 2012-07-10 05:30 UTC (History)
0 users

See Also:
i915 platform:
i915 features:

Small program replicating the bug (2.03 KB, application/x-tar)
2012-07-09 13:51 UTC, Albertas Vyšniauskas

Note You need to log in before you can comment on or make changes to this bug.
Description Albertas Vyšniauskas 2012-07-09 13:51:03 UTC
Created attachment 64019 [details]
Small program replicating the bug

Drawing surface based patterns breaks when using non-default pattern matrix in Xlib backend. The same code works correctly in, at least, image backend. 

If you have a 32x32 px pattern image, then in the following code, first two rectangles will have incorrect patterns.

pattern_surface = cairo_image_surface_create_from_png("pattern.png");
pattern = cairo_pattern_create_for_surface(pattern_surface);
cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
cairo_matrix_t matrix;
cairo_matrix_init_translate(&matrix, 14.1, 0);
cairo_pattern_set_matrix(pattern, &matrix);
cairo_set_source(cr, pattern);
for (int i = 0; i < 8; i++){
	cairo_rectangle(cr, i * 3.5, i * 32, 256, 32);

The same code works correctly when using image backend.

I attached a small program replicating this bug. This program shows the output of Xlib backend in a window and saves the output of image backend into a file test.png
Comment 1 Chris Wilson 2012-07-09 14:00:47 UTC
Wow, that is odd.

Can you add:

  if (event->area.width == widget->allocation.width &&
      event->area.height == widget->allocation.height) {
          cairo_surface_write_to_png(cairo_get_target(cr), "out.png");
to on_expose_event() and attach your out.png? I just want to confirm that you are seeing the same oddity I am!
Comment 2 Chris Wilson 2012-07-09 14:02:32 UTC
Also may I have your permission to license that example under the liberal MIT and add as as test case?
Comment 3 Chris Wilson 2012-07-09 14:23:07 UTC
That's weird, extracted your example out of the GTK+ framework and built a test case... It works as expected. Hmm.
Comment 4 Chris Wilson 2012-07-09 15:09:28 UTC
D'oh, missed the 14.1 x-translation. That's the missing piece of magic to exercise the bug.
Comment 5 Chris Wilson 2012-07-09 15:13:14 UTC
This is the essence of the bug:

000:<:0028: 16: Request(53): CreatePixmap depth=0x18 pid=0x01400006 drawable=0x01400001 width=16 height=1                                    
000:<:002a: 88: Request(72): PutImage format=ZPixmap(0x02) drawable=0x01400006 gc=0x01400004 width=16 height=1 dst-x=0 dst-y=0 left-pad=0x00 depth=0x18
000:<:002c: 20: RENDER-Request(149,4): CreatePicture pid=0x01400007 drawable=0x01400006 format=0x0000002a values={}                
000:<:002e: 44: RENDER-Request(149,28): SetPictureTransform picture=0x01400007 transform=1.000000,0.000000,-1.899994,0.000000,1.000000,-16.000000,0.000000,0.000000,1.000000;
000:<:0030: 16: RENDER-Request(149,30): SetPictureFilter picture=0x01400007 name='good' values=;                                            
000:<:0032: 16: RENDER-Request(149,5): ChangePicture picture=0x01400007 values={repeat=true(0x01)}                                                    
000:<:0034: 64: RENDER-Request(149,10): Trapezoids op=Over(0x03) src=0x01400007 xSrc=3 ySrc=17 dst=0x01400002 maskFormat=0x00000024 trapezoids={top=32.000000 bottom=64.000000 left={x1=3.500000 y1=32.000000 x2=3.500000 y2=64.000000}; right={x1=256.000000 y1=32.000000 x2=256.000000 y2=64.000000};};
000:<:0036:  8: RENDER-Request(149,7): FreePicture picture=0x01400007

we create a repeating 16x1 source image for the second row (and similar for the first) instead of the full 32x32. So the calculation of the required source size is incorrect.
Comment 6 Chris Wilson 2012-07-09 20:58:24 UTC
commit 6938592ec7e1a1b4cfccb11521ecdfdb8579f380
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Mon Jul 9 21:50:34 2012 +0100

    xlib: If a sample accesses outside of a repeating image, upload it all
    Fixes bug-51910
    Reported-by: Albertas Vyšniauskas <thezbyg@gmail.com>
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=51910
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Comment 7 Albertas Vyšniauskas 2012-07-10 05:30:07 UTC
(In reply to comment #2)
> Also may I have your permission to license that example under the liberal MIT
> and add as as test case?

Yes, and thank you for fixing this.