Re: _cairo_surface_wrapper_get_target_extents() too small
Guillaume Ayoub <[email protected]>
| Newsgroups | gmane.comp.lib.cairo |
|---|---|
| Message-ID | <1364594127.1787.33.camel@liZe76> |
Le vendredi 29 mars 2013 à 15:43 +0100, Simon Sapin a écrit : > Le 27/03/2013 13:12, Simon Sapin a écrit : > > Hi, > > > > When rendering to PDF with WeasyPrint a document containing a SVG image, > > SVG elements in the right and bottom of the image are not shown in some > > cases. > > > > git bisect indicates that the bug appeared in this cairo commit: > > > > http://cgit.freedesktop.org/cairo/commit/?id=09b42c748e9dbcc923560c7d8bf5298fbffe95ef > > > > Reverting it on top of today’s master fixes the bug. > > > > > > WeasyPrint has CairoSVG render the image to an intermediate cairo SVG > > surface, which is then used in surface pattern as a source to paint in > > the final PDF surface. The bug appears when the target context has a > > scale to make the image smaller than its "intrinsic" size. Making the > > SVG surface smaller (with its content scaled accordingly) and > > compensating with a scale on the target surface works around the problem. > > > > Apparently, the rectangle returned by > > _cairo_surface_wrapper_get_target_extents() is smaller than it should > > be. Something is transformed wrong, but I’m not sure what coordinate > > system each rectangle is supposed to be in. > > > Based on further research, it appears that the wrapper->transform value > in _cairo_surface_wrapper_get_target_extents() should account for the > target context’s transformation matrix, but doesn’t. wrapper->transform > is always the identity matrix in our tests, even though the context has > a non-identity transform when painting the surface pattern. > > Removing any calls to cairo_save() and cairo_restore() also works around > the issue, but for reasons we do not understand. I finally think that I have found what's happening. In cairo-analysis-surface, the transformation matrix is stored in surface->ctm, and this matrix is handled by _add_operation for all the operations added in the analysis surface. In _analyze_recording_surface_pattern, the ctm surface is set, everything is OK for the future operations. But _analyze_recording_surface_pattern calls _cairo_recording_surface_replay_and_create_regions, calling _cairo_recording_surface_replay_internal, calling _cairo_surface_wrapper_get_target_extents. As replay_and_create_regions calls replay_internal without the surface_transform parameter, the original transformation matrix is lost. get_target_extents relies on wrapper.transform that is not set, and get_target_extents then uses the original size of the target to reduce the extents rectangle, instead of using the size multiplied by the transformation matrix. A simple solution to fix this is to add a surface_transform parameter to _cairo_recording_surface_replay_and_create_regions (as it is done in _cairo_recording_surface_replay_with_clip), and to use the invert matrix of &tmp->ctm as surface_transform parameter of _cairo_recording_surface_replay_and_create_regions. -- cairo mailing list [email protected] http://lists.cairographics.org/mailman/listinfo/cairo
signature.asc
(application/pgp-signature, 490 B)
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iQEcBAABAgAGBQJRVg3PAAoJEFDXmmt3d/ODn4wH/jHsQHffT35kkwzrNZ0TGiRR 51f7N2qRFC4V6ER28oKJGy7ylBjtD+n8F8fDlPCR0Sl/mlx/g6GzAsMltg8NU18g sQXL2BQUxLknpP5Vnl6hILBwOB/nPV1azPhuF0EVavHyGtGlLfptWHIRmAr/C55u YqYFHpCVuMOhsNJ+dVEMMaAO32Un55YcEjiy0HNHA2bRBfEJ9NOy/EzCoXTxnWlr rN9P3zeBI58bnoaKDbVPPtpTviH5EgE6xfoSUdmq8SQ9s/FtxL8+o45+dnRhNkm8 IjnUHb1f2WBa0N0mqO3ZyowQctw4UKGASzLJ3mMdmdheTHPo6EDoBxtZQNVTOD4= =2Aaz -----END PGP SIGNATURE-----