Bug 51910 - Surface based patterns are drawn incorrectly when using non-default pattern matrix
Summary: Surface based patterns are drawn incorrectly when using non-default pattern m...
Status: RESOLVED FIXED
Alias: None
Product: cairo
Classification: Unclassified
Component: xlib backend (show other bugs)
Version: 1.12.2
Hardware: x86-64 (AMD64) Linux (All)
: medium normal
Assignee: Carl Worth
QA Contact: cairo-bugs mailing list
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
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:


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

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);
	cairo_fill(cr);
}

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.


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.