[cairo] src surface clip problems
vladimirv at gmail.com
Thu Aug 17 16:30:09 PDT 2006
On 8/17/06, Carl Worth <cworth at cworth.org> wrote:
> On Thu, 17 Aug 2006 14:53:55 -0700, "Vladimir Vukicevic" wrote:
> > > > (Note that the resulting image still isn't correct, due to broken
> > > > pixman upscaling -- in particular, the left and right edges should be
> > > > solid green, and not green-mixed-with-.. black? transparent black?
> > > > something.)
> > Yep, I'm looking at the left and right edges of the image, not the
> > green-to-blue transition (which is correct). pixman has all pixels
> > that are not contained within the image as transparent black; the
> > problem is that the sampling functions don't take into account image
> > edges at all, and instead read from the transparent black
> > out-of-bounds region even if they're not part of the compositing
> > operation. Specifically, the leftmost and rightmost column of pixels
> > in that image sould be solid green, not (0.25,0.75,0.0).
> Ah, so I was looking at the wrong pixels.
> Now, the cairo semantics for reading from the "outside" portions of a
> pattern depend on the extend mode of the pattern, (please see
> cairo_pattern_set_extend). For surface patterns, the default extend
> mode is EXTEND_NONE which means that any read from outside the surface
> will be transparent black. So the result does seem consistent.
Right, though I'm not reading from the outside of a surface, just the
sampling function is. The contents of my source bounds are fully
defined in the surface, so the only read from outside the surface area
is by the sampling function (which I think needs to special-case
this). So I guess the result is consistent, just not very expected
(or, IMO, useful).
> Note: The reason we have the default extend mode for surface patterns
> as EXTEND_NONE is so that the idiom of:
> cairo_set_source_surface (cr, surface, x, y);
> cairo_paint (cr);
> can be used to copy an image to x,y.
And it will -- but if you add a scale to the matrix, it won't give
what I would expect (based on every other 2D API that I can think of,
or at least their defaults). We have a bug open on this at
https://bugzilla.mozilla.org/attachment.cgi?id=209616 that gives this
output: http://people.mozilla.com/~vladimir/misc/snap034.png when each
red field should be solid red with no blending at the edges.
Now, the issue becomes what should happen if the destination is bigger
than the source, and there's a scale involved. I'd still argue that
there should be a sharp edge there, with the undefined area being
transparent as it is currently, based on expectations.
> Though, obviously one should be able to get the result you actually
> expected. To this end we added a setting of EXTEND_PAD between cairo
> 1.0 and 1.2. Unfortunately, we noticed just before releasing cairo
> 1.2.0 that while EXTEND_PAD had been implemented for gradients, it
> hadn't yet been implemented for surface patterns (oops!).
EXTEND_PAD can work around this, but I think that would lead to having
to set EXTEND_PAD for every single surface -- and EXTEND_PAD is often
not what you want in the issue I mentioned above (where you'd have to
use EXTEND_PAD and clip).
Instead, I'd suggest defining EXTEND_NONE to work such that if the
center of the sampled area is a real pixel, then all pixels are either
real or are the nearest real pixel to the sample location. If the
center of the samped area is outside of the bounds, then it should be
transparent black. A new EXTEND_INFINITE or something cuold be
defined to obtain the current behaviour, or the default could be
changed. (I realize that this would change cairo's current behaviour,
but I can't imagine that there is any code out there that depends on
the strange scaling semantics, especially given that the sampling
center was broken for quite a while.)
More information about the cairo