[cairo] Zero matrix transformation

Daniel Kraft d at domob.eu
Thu Mar 20 01:05:04 PDT 2008


Jeff Muizelaar wrote:
> In your example, if you call cairo_status(cr) after the call to
> cairo_scale(cr, 0, 0) you should get CAIRO_STATUS_INVALID_MATRIX.
> Alternatively, you can try changing the scale back to 1, 1 with
> cairo_set_matrix after setting it to 0, 0 and you should not be able to
> draw anything.
> 
> The desired behaviour is that nothing be drawn only when the matrix is
> degenerate. If it becomes well-formed drawing should work as normal
> instead of the cairo context remaining in an error state.

Once again, I now managed to reproduce the behaviour and dived a bit 
into the source; currently, there seems to be the "invariant" that the 
transformation matrix must always be invertible and the inverse is 
always kept at hand (I suppose for device-to-user transformations, right?).

Allowing zero matrices would of course break this; what is the desired 
behaviour there?  Should device-to-user coordinates always map to 
+-Infinity?  Or should such an attempt trigger an error state?  Also, 
once the matrix is zero, should further transforming, like rotating, be 
allowed or should this trigger an error then?

I'd tend to say all this should be allowed to stay consistent with 
"allow zero matrices, simply draw nothing/shade with average colour", 
but well, this is probably not my decision ;)

I can think of two possible solutions:

1) Simply make the matrix all zero, and add special handling to 
inversion routines to allow this one and define the inverse as, say,
   / Inf 0   \
   \ 0   Inf /.
I'm not sure if this is 100% consistent with, say, rotating the matrix 
by 90/180 degrees and expecting that the inverse mapping produces 
Infinity with the "correct" signs and such.  But this is probably not 
something very needed, anyway.

2) Store to each matrix in addition to the six components a scalar 
factor; this would allow the structure of the matrix to be kept when 
scaling it down to zero (and possibly to simply set the factor to 
something else later to restore it) and would be easier to keep 
consistent.  On the other hand this would mean a lot of extra 
multiplications every time something is transformed.  Would this be a 
performance problem?

BTW, should a matrix like (0, 0, 0, 0, 1, 1) be allowed, that is, 
mapping every point to (1, 1)?  (But this can only be done by 
cairo_set_matrix as scaling would bring the offset down to zero, too, I 
suppose).

Thanks and now really off,
Daniel

PS: Why does _cairo_gstate_scale_matrix, for instance, not use 
cairo_matrix_scale and similar for other transformations?  Does this 
code need to be duplicated?

-- 
Done:     Bar-Sam-Val-Wiz, Dwa-Elf-Hum-Orc, Cha-Law, Fem-Mal
Underway: Ran-Gno-Neu-Fem
To go:    Arc-Cav-Hea-Kni-Mon-Pri-Rog-Tou


More information about the cairo mailing list