[cairo] Unbounded source operators in the backends

Owen Taylor otaylor at redhat.com
Sat Aug 6 11:04:27 PDT 2005

The revised clipping patch I'm working on deals primarily with the 6
"unbounded" operators:


These are the operators that have an effect even where the mask or
source are transparent.

It turns out that beyond the clipping equation there are a whole 
slew of problems with the implementation of these operators:

A few of them:

- RenderCompositeGlyphs and RenderCompositeTrapezoids create 
   temporary masks that are the size of the bounds of the 
   glyphs or trapezoids and only composite that area. 

- The implementation of RenderComposite clips untransformed
   rendering to the intersection of the source and the mask.

   [ The RenderCompositeTrapezoids and RenderComposite problems
     also occur in the corresponding pixman functions ]

- _cairo_ft_scaled_font_show_glyphs() assumes that it is
   possible to composite each glyph individually and get the
   same result as compositing them all at once.

As always, we could attack these problems at multiple levels:

1) The cairo_gstate() code could avoid triggering these problems
   by always, when rendering with an unbounded operator, generating
   a full-size source copy, and a full-size mask and then 
   only calling _cairo_surface_composite() on these.

2) We could fix and work around the problems backend-by-backend
   in cairo.

3) We could consider these to be problems to be fixed in the
   underlying libraries and servers.

My feeling is that 2) is the appropriate level to work at
(while filing bugs for 3) so that the problems aren't forgotten).
1) would be simpler to code, but also increases the overall
complexity of the gstate => surface interface by adding more
special conditions.

A related question is the interpretation of width, height

cairo_private cairo_status_t
_cairo_surface_composite_trapezoids (cairo_operator_t   operator,
                                     cairo_pattern_t    *pattern,
                                     cairo_surface_t    *dst,
                                     int                src_x,
                                     int                src_y,
                                     int                dst_x,
                                     int                dst_y,
                                     unsigned int       width,
                                     unsigned int       height,
                                     cairo_trapezoid_t  *traps,
                                     int                ntraps);

cairo_private cairo_status_t
_cairo_surface_show_glyphs (cairo_scaled_font_t         *scaled_font,
                            cairo_operator_t            operator,
                            cairo_pattern_t             *pattern,
                            cairo_surface_t             *surface,
                            int                         source_x,
                            int                         source_y,
                            int                         dest_x,
                            int                         dest_y,
                            unsigned int                width,
                            unsigned int                height,
                            const cairo_glyph_t         *glyphs,
                            int                         num_glyphs);

Currently they act as "hints" - the backend is allowed to assume that
the glyphs or trapezoids, once they have been clipped by any clip region
set on the surface, don't extend outside the rectangle 
[dst_x, dst_y, width, height], but once we add unbounded operators into
the picture, things get more complicated, since we have to know 
how far to extend the operation.

Can we stop at the edges of the rectangle, or do we need to paint all 
the way out to the surface clip? My feeling is that the first
interpretation is the right one - it is consistent with how 
width, height work for:

cairo_private cairo_status_t
_cairo_surface_composite (cairo_operator_t      operator,
                          cairo_pattern_t       *src,
                          cairo_pattern_t       *mask,
                          cairo_surface_t       *dst,
                          int                   src_x,
                          int                   src_y,
                          int                   mask_x,
                          int                   mask_y,
                          int                   dst_x,
                          int                   dst_y,
                          unsigned int          width,
                          unsigned int          height);

In other words, composite_glyphs(), composite_trapezoids() are
just providing alternate representations for 'mask', and otherwise
should work just like composite().


-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
Url : http://lists.freedesktop.org/archives/cairo/attachments/20050806/c8265eb5/attachment.pgp

More information about the cairo mailing list