[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