The following python code sample creates two files: matrixbug.png and
matrixbug.svg. The png is correct, and the svg is transformed incorrectly.
Comment the second stroke to remove the need for an image fallback, and they
both appear identical in eog.
#! /usr/bin/env python
surface = cairo.SVGSurface('matrixbug.svg', 120, 120)
cr = cairo.Context(surface)
# this is not necessary to repro; premultiplied coords too.
cr.set_source_rgb(0, 0, 0)
cr.rectangle(0.25, 0.25, 0.5, 0.5)
# comment out this stroke to see the png and svg appear the same
cr.set_source_rgba(0, 0, 0, 0)
Created attachment 6381 [details]
Original test case ported to C
Thanks for the report. I ported your test case to C just to make it easier to
look closely with a debugger, (it's nice to see how similar the test is in both
So I'll actually be doing that closer look very soon.
Oh, this bug is worse than I thought.
We actually have a testcase in the test suite already that exercises this bug.
It's the fallback-resolution test. Unfortunately, it's one of those few tests
where we don't do automatic checking, but instead rely on manual verification
that the results are correct, (which we obviously neglected to do before 1.2.0).
The commit that broke this test is the following, just a couple of days before
cairo 1.2.0 was released:
We need to fix this if we have any hope of cairo-based printing working well at all.
*** Bug 7571 has been marked as a duplicate of this bug. ***
Sorry for submitting duplicates folks, although I saw this report I didn't
realise it was a duplicate. If you can tell me what needs doing, I can see what
I can do about fixing it. Afraid I don't know the code very well.
(In reply to comment #4)
> Sorry for submitting duplicates folks, although I saw this report I didn't
> realise it was a duplicate.
Oh, no apology necessary at all. I hadn't realized it was a duplicate either.
Nor had I realized that we had such a bad bug in 1.2. It's all a bit
> If you can tell me what needs doing, I can see what
> I can do about fixing it. Afraid I don't know the code very well.
I'll be working on a fix for this right away. I just need to satisfy two
constraints at the same time, (the bug fix the commit above was intending, and
the fallback_resolution behavior the commit above broke). So we have code for
satisfying either constraint separately. And we just need to come up with code
that will satisfy both at the same time.
Behdad suggested perhaps making the meta-surface replay code go through the
gstate interface rather than the surface interface. That might be the cleanest
approach to get correctness in all cases. It might not be the most efficient,
but then again, we already have a lot of inefficiency in the meta-surface code
paths, (like always copying source surfaces), so maybe it wouldn't matter too much.
Again, I'll be looking into this closer today, so don't worry if the above makes
And again, thanks for the report!
Nevertheless, I think the meta surface is one of the more brilliant innovations
in cairo, and well done to whoever came up with that idea. Perhaps, as you say,
the loss in efficiency is worth the gain in symmetry. These things normally
have a way of panning out when one takes a simple or intuitive approach. A bit
of extra abstraction goes a long way to eliminating bugs...
Just gotta say, wow guys, well done on cairo! It's an excellent and well
thought out model, and incredibly easy to use. Soooo glad it's not irrevocably
tied into pango.
Pango builds on top of Cairo. How do you expect cairo to be tied to Pango? :)
(In reply to comment #7)
> Pango builds on top of Cairo. How do you expect cairo to be tied to Pango? :)
It's not, and I'm very glad for the fact. I use cairo primarily for it's
graphics ability, not for it's text.
It's just that I know how much some people have been agitating for adding better
font support- ala pango, and the end of that road is a bloat nightmare (not to
I'm very happy with what I have, thanks :)
I've pushed out a fix for this now:
It fixes the fallback-resolution test case and I verified it also fixes the test
case attached to this bug. Please verify it fixes any other cases of interest.
PS. As it turns out, we didn't pipe meta-surface replaying through the gstate
layer. Instead we just put the old device_transform code from the surface layer
into the replay itself. It was all quite easy in fact.