[cairo-commit] cairo/src cairo-font.c, 1.69, 1.70 cairo-ft-font.c,
1.102, 1.103 cairo-gstate.c, 1.164,
1.165 cairo-image-surface.c, 1.58, 1.59 cairo-surface.c, 1.92,
1.93 cairo-xlib-surface.c, 1.109, 1.110
Owen Taylor
commit at pdx.freedesktop.org
Thu Aug 18 15:50:39 PDT 2005
- Previous message: [cairo-commit] cairo/test .cvsignore, 1.43, 1.44 Makefile.am, 1.79,
1.80 clip-operator-ref.png, 1.2, 1.3 operator-clear-ref.png,
NONE, 1.1 operator-clear.c, NONE, 1.1 operator-source-ref.png,
NONE, 1.1 operator-source.c, NONE,
1.1 unbounded-operator-ref.png, 1.1, 1.2 unbounded-operator.c,
1.1, 1.2
- Next message: [cairo-commit] cairo ChangeLog,1.906,1.907
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Committed by: otaylor
Update of /cvs/cairo/cairo/src
In directory gabe:/tmp/cvs-serv10706/src
Modified Files:
cairo-font.c cairo-ft-font.c cairo-gstate.c
cairo-image-surface.c cairo-surface.c cairo-xlib-surface.c
Log Message:
2005-08-17 Owen Taylor <otaylor at redhat.com>
* src/cairo-gstate.c: Implement new equations for CLEAR and SOURCE
CLEAR: (mask IN clip) ? 0 : dest
SOURCE: (mask IN clip) ? src : dest
That behave more like what people expect.
* src/cairo-gstate.c (_cairo_operator_bounded): CLEAR and SOURCE are
now bounded.
* src/cairo-font.c (_cairo_ft_scaled_font_show_glyphs)
* src/cairo-surface.c (_cairo_surface_composite_trapezoids):
Assert that SOURCE and CLEAR aren't passed to these functions.
* src/cairo-surface.c (_cairo_surface_composite):
Assert that SOURCE and CLEAR aren't passed to these functions
when there is a mask.
* src/cairo-xlib-surface.c (_cairo_xlib_surface_composite)
* src/cairo-image-surface.c (_cairo_image_surface_composite):
Do fixups for SOURCE and CLEAR as well as unbounded operators,
since in the absence of a mask, we need SOURCE to work
correctly (don't care about CLEAR)
* src/cairo-ft-font.c (_transform_glyph_bitmap, _cairo_ft_font_show_glyphs)
Consistently use CLEAR/TRANSPARENT (source doesn't matter)
rather than SOURCE/TRANSPARENT when clearing rectangles.
* src/cairo-xlib-surface.c src/cairo-surface.c: Use
IN rather than SOURCE as an example of an unbounded operator in
docs.
* test/unbounded-operator.c: Remove CLEAR/SOURCE columns since
they are no longer unbounded.
* test/operator-clear.c test/operator-source Makefile.am: Add
targetted tests of CLEAR/SOURCE.
Index: cairo-font.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-font.c,v
retrieving revision 1.69
retrieving revision 1.70
diff -u -d -r1.69 -r1.70
--- cairo-font.c 13 Aug 2005 08:38:55 -0000 1.69
+++ cairo-font.c 18 Aug 2005 22:50:36 -0000 1.70
@@ -890,6 +890,11 @@
{
cairo_status_t status;
+ /* These operators aren't interpreted the same way by the backends;
+ * they are implemented in terms of other operators in cairo-gstate.c
+ */
+ assert (operator != CAIRO_OPERATOR_SOURCE && operator != CAIRO_OPERATOR_CLEAR);
+
if (scaled_font->status)
return scaled_font->status;
Index: cairo-ft-font.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-ft-font.c,v
retrieving revision 1.102
retrieving revision 1.103
diff -u -d -r1.102 -r1.103
--- cairo-ft-font.c 17 Aug 2005 16:51:09 -0000 1.102
+++ cairo-ft-font.c 18 Aug 2005 22:50:36 -0000 1.103
@@ -1133,7 +1133,7 @@
/* Initialize it to empty
*/
- _cairo_surface_fill_rectangle (image, CAIRO_OPERATOR_SOURCE,
+ _cairo_surface_fill_rectangle (image, CAIRO_OPERATOR_CLEAR,
CAIRO_COLOR_TRANSPARENT,
0, 0,
width, height);
@@ -1960,7 +1960,7 @@
if (!mask)
goto CLEANUP_ENTRIES;
- status = _cairo_surface_fill_rectangle (mask, CAIRO_OPERATOR_SOURCE,
+ status = _cairo_surface_fill_rectangle (mask, CAIRO_OPERATOR_CLEAR,
CAIRO_COLOR_TRANSPARENT,
0, 0, width, height);
if (status)
Index: cairo-gstate.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-gstate.c,v
retrieving revision 1.164
retrieving revision 1.165
diff -u -d -r1.164 -r1.165
--- cairo-gstate.c 17 Aug 2005 01:22:16 -0000 1.164
+++ cairo-gstate.c 18 Aug 2005 22:50:36 -0000 1.165
@@ -258,8 +258,8 @@
_cairo_surface_set_drawableWH (gstate->target, pix, width, height);
status = _cairo_surface_fill_rectangle (gstate->target,
- CAIRO_OPERATOR_SOURCE,
- &CAIRO_COLOR_TRANSPARENT,
+ CAIRO_OPERATOR_CLEAR,
+ CAIRO_COLOR_TRANSPARENT,
0, 0,
_cairo_surface_get_width (gstate->target),
_cairo_surface_get_height (gstate->target));
@@ -723,6 +723,8 @@
_cairo_operator_bounded (cairo_operator_t operator)
{
switch (operator) {
+ case CAIRO_OPERATOR_CLEAR:
+ case CAIRO_OPERATOR_SOURCE:
case CAIRO_OPERATOR_OVER:
case CAIRO_OPERATOR_ATOP:
case CAIRO_OPERATOR_DEST:
@@ -732,8 +734,6 @@
case CAIRO_OPERATOR_ADD:
case CAIRO_OPERATOR_SATURATE:
return TRUE;
- case CAIRO_OPERATOR_CLEAR:
- case CAIRO_OPERATOR_SOURCE:
case CAIRO_OPERATOR_OUT:
case CAIRO_OPERATOR_IN:
case CAIRO_OPERATOR_DEST_IN:
@@ -753,6 +753,47 @@
int dst_y,
const cairo_rectangle_t *extents);
+static cairo_status_t
+_create_composite_mask_pattern (cairo_surface_pattern_t *mask_pattern,
+ cairo_clip_t *clip,
+ cairo_draw_func_t draw_func,
+ void *draw_closure,
+ cairo_surface_t *dst,
+ const cairo_rectangle_t *extents)
+{
+ cairo_surface_t *mask;
+ cairo_status_t status;
+
+ mask = cairo_surface_create_similar (dst,
+ CAIRO_CONTENT_ALPHA,
+ extents->width,
+ extents->height);
+ if (mask->status)
+ return CAIRO_STATUS_NO_MEMORY;
+
+ status = (*draw_func) (draw_closure, CAIRO_OPERATOR_ADD,
+ NULL, mask,
+ extents->x, extents->y,
+ extents);
+ if (status)
+ goto CLEANUP_SURFACE;
+
+ if (clip->surface)
+ status = _cairo_clip_combine_to_surface (clip, CAIRO_OPERATOR_IN,
+ mask,
+ extents->x, extents->y,
+ extents);
+ if (status)
+ goto CLEANUP_SURFACE;
+
+ _cairo_pattern_init_for_surface (mask_pattern, mask);
+
+ CLEANUP_SURFACE:
+ cairo_surface_destroy (mask);
+
+ return status;
+}
+
/* Handles compositing with a clip surface when the operator allows
* us to combine the clip with the mask
*/
@@ -765,50 +806,30 @@
cairo_surface_t *dst,
const cairo_rectangle_t *extents)
{
- cairo_surface_t *intermediate;
- cairo_surface_pattern_t intermediate_pattern;
+ cairo_surface_pattern_t mask_pattern;
cairo_status_t status;
- intermediate = cairo_surface_create_similar (clip->surface,
- CAIRO_CONTENT_ALPHA,
- extents->width,
- extents->height);
- if (intermediate->status)
- return CAIRO_STATUS_NO_MEMORY;
-
- status = (*draw_func) (draw_closure, CAIRO_OPERATOR_SOURCE,
- NULL, intermediate,
- extents->x, extents->y,
- extents);
- if (status)
- goto CLEANUP_SURFACE;
-
- status = _cairo_clip_combine_to_surface (clip, CAIRO_OPERATOR_IN,
- intermediate,
- extents->x, extents->y,
- extents);
+ status = _create_composite_mask_pattern (&mask_pattern,
+ clip,
+ draw_func, draw_closure,
+ dst, extents);
if (status)
- goto CLEANUP_SURFACE;
-
- _cairo_pattern_init_for_surface (&intermediate_pattern, intermediate);
-
+ return status;
+
status = _cairo_surface_composite (operator,
- src, &intermediate_pattern.base, dst,
+ src, &mask_pattern.base, dst,
extents->x, extents->y,
0, 0,
extents->x, extents->y,
extents->width, extents->height);
- _cairo_pattern_fini (&intermediate_pattern.base);
-
- CLEANUP_SURFACE:
- cairo_surface_destroy (intermediate);
+ _cairo_pattern_fini (&mask_pattern.base);
return status;
}
-/* Handles compositing with a clip surface when the operator allows
- * us to combine the clip with the mask
+/* Handles compositing with a clip surface when we have to do the operation
+ * in two pieces and combine them together.
*/
static cairo_status_t
_cairo_gstate_clip_and_composite_combine (cairo_clip_t *clip,
@@ -827,6 +848,7 @@
/* We'd be better off here creating a surface identical in format
* to dst, but we have no way of getting that information.
* A CAIRO_CONTENT_CLONE or something might be useful.
+ * cairo_surface_create_similar() also unnecessarily clears the surface.
*/
intermediate = cairo_surface_create_similar (dst,
CAIRO_CONTENT_COLOR_ALPHA,
@@ -895,6 +917,55 @@
return status;
}
+/* Handles compositing for CAIRO_OPERATOR_SOURCE, which is special; it's
+ * defined as (src IN mask IN clip) ADD (dst OUT (mask IN clip))
+ */
+static cairo_status_t
+_cairo_gstate_clip_and_composite_source (cairo_clip_t *clip,
+ cairo_pattern_t *src,
+ cairo_draw_func_t draw_func,
+ void *draw_closure,
+ cairo_surface_t *dst,
+ const cairo_rectangle_t *extents)
+{
+ cairo_surface_pattern_t mask_pattern;
+ cairo_status_t status;
+
+ /* Create a surface that is mask IN clip
+ */
+ status = _create_composite_mask_pattern (&mask_pattern,
+ clip,
+ draw_func, draw_closure,
+ dst, extents);
+ if (status)
+ return status;
+
+ /* Compute dest' = dest OUT (mask IN clip)
+ */
+ status = _cairo_surface_composite (CAIRO_OPERATOR_DEST_OUT,
+ &mask_pattern.base, NULL, dst,
+ 0, 0,
+ 0, 0,
+ extents->x, extents->y,
+ extents->width, extents->height);
+
+ if (status)
+ goto CLEANUP_MASK_PATTERN;
+
+ /* Now compute (src IN (mask IN clip)) ADD dest'
+ */
+ status = _cairo_surface_composite (CAIRO_OPERATOR_ADD,
+ src, &mask_pattern.base, dst,
+ extents->x, extents->y,
+ 0, 0,
+ extents->x, extents->y,
+ extents->width, extents->height);
+
+ CLEANUP_MASK_PATTERN:
+ _cairo_pattern_fini (&mask_pattern.base);
+ return status;
+}
+
static int
_cairo_rectangle_empty (const cairo_rectangle_t *rect)
{
@@ -931,30 +1002,49 @@
cairo_surface_t *dst,
const cairo_rectangle_t *extents)
{
+ cairo_pattern_union_t solid_pattern;
+ cairo_status_t status;
+
if (_cairo_rectangle_empty (extents))
/* Nothing to do */
return CAIRO_STATUS_SUCCESS;
- if (clip->surface)
+ if (operator == CAIRO_OPERATOR_CLEAR) {
+ _cairo_pattern_init_solid (&solid_pattern.solid, CAIRO_COLOR_WHITE);
+ src = &solid_pattern.base;
+ operator = CAIRO_OPERATOR_DEST_OUT;
+ }
+
+ if (clip->surface || operator == CAIRO_OPERATOR_SOURCE)
{
- if (_cairo_operator_bounded (operator))
- return _cairo_gstate_clip_and_composite_with_mask (clip, operator,
+ if (operator == CAIRO_OPERATOR_SOURCE)
+ status = _cairo_gstate_clip_and_composite_source (clip,
+ src,
+ draw_func, draw_closure,
+ dst, extents);
+ else if (_cairo_operator_bounded (operator))
+ status = _cairo_gstate_clip_and_composite_with_mask (clip, operator,
+ src,
+ draw_func, draw_closure,
+ dst, extents);
+ else
+ status = _cairo_gstate_clip_and_composite_combine (clip, operator,
src,
draw_func, draw_closure,
dst, extents);
- else
- return _cairo_gstate_clip_and_composite_combine (clip, operator,
- src,
- draw_func, draw_closure,
- dst, extents);
}
else
{
- return (*draw_func) (draw_closure, operator,
- src, dst,
- 0, 0,
- extents);
+ status = (*draw_func) (draw_closure, operator,
+ src, dst,
+ 0, 0,
+ extents);
}
+
+ if (src == &solid_pattern.base)
+ _cairo_pattern_fini (&solid_pattern.base);
+
+ return status;
}
@@ -1158,10 +1248,17 @@
cairo_rectangle_t *extents)
{
cairo_status_t status;
+ cairo_pattern_union_t solid_pattern;
cairo_pattern_union_t mask;
int num_rects = pixman_region_num_rects (trap_region);
unsigned int clip_serial;
+ if (clip->surface && operator == CAIRO_OPERATOR_CLEAR) {
+ _cairo_pattern_init_solid (&solid_pattern.solid, CAIRO_COLOR_WHITE);
+ src = &solid_pattern.base;
+ operator = CAIRO_OPERATOR_DEST_OUT;
+ }
+
if (num_rects == 0)
return CAIRO_STATUS_SUCCESS;
@@ -1193,6 +1290,9 @@
if (clip->surface)
_cairo_pattern_fini (&mask.base);
+ if (src == &solid_pattern.base)
+ _cairo_pattern_fini (&solid_pattern.base);
+
return status;
}
@@ -1308,21 +1408,28 @@
if (trap_region)
{
- if (src->type == CAIRO_PATTERN_SOLID && !clip->surface)
+ if ((src->type == CAIRO_PATTERN_SOLID || operator == CAIRO_OPERATOR_CLEAR) &&
+ !clip->surface)
{
+ const cairo_color_t *color;
+
+ if (operator == CAIRO_OPERATOR_CLEAR)
+ color = CAIRO_COLOR_TRANSPARENT;
+ else
+ color = &((cairo_solid_pattern_t *)src)->color;
+
/* Solid rectangles special case */
- status = _cairo_surface_fill_region (dst, operator,
- &((cairo_solid_pattern_t *)src)->color,
- trap_region);
+ status = _cairo_surface_fill_region (dst, operator, color, trap_region);
if (!status && clear_region)
- status = _cairo_surface_fill_region (dst, operator,
+ status = _cairo_surface_fill_region (dst, CAIRO_OPERATOR_CLEAR,
CAIRO_COLOR_TRANSPARENT,
clear_region);
goto out;
}
- if (_cairo_operator_bounded (operator) || !clip->surface)
+ if ((_cairo_operator_bounded (operator) && operator != CAIRO_OPERATOR_SOURCE) ||
+ !clip->surface)
{
/* For a simple rectangle, we can just use composite(), for more
* rectangles, we have to set a clip region. The cost of rasterizing
@@ -1330,8 +1437,10 @@
* worthwhile even if a region is needed.
*
* If we have a clip surface, we set it as the mask; this only works
- * for bounded operators; for unbounded operators, clip and mask
- * cannot be interchanged.
+ * for bounded operators other than SOURCE; for unbounded operators,
+ * clip and mask cannot be interchanged. For SOURCE, the operator
+ * as implemented by the backends is different in it's handling
+ * of the mask then what we want.
*
* CAIRO_INT_STATUS_UNSUPPORTED will be returned if the region has
* more than rectangle and the destination doesn't support clip
Index: cairo-image-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-image-surface.c,v
retrieving revision 1.58
retrieving revision 1.59
diff -u -d -r1.58 -r1.59
--- cairo-image-surface.c 17 Aug 2005 01:22:16 -0000 1.58
+++ cairo-image-surface.c 18 Aug 2005 22:50:36 -0000 1.59
@@ -616,7 +616,9 @@
width, height);
}
- if (!_cairo_operator_bounded (operator))
+ if (!_cairo_operator_bounded (operator) ||
+ operator == CAIRO_OPERATOR_SOURCE ||
+ operator == CAIRO_OPERATOR_CLEAR)
status = _cairo_surface_composite_fixup_unbounded (&dst->base,
&src_attr, src->width, src->height,
mask ? &mask_attr : NULL,
Index: cairo-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-surface.c,v
retrieving revision 1.92
retrieving revision 1.93
diff -u -d -r1.92 -r1.93
--- cairo-surface.c 17 Aug 2005 01:22:16 -0000 1.92
+++ cairo-surface.c 18 Aug 2005 22:50:36 -0000 1.93
@@ -817,6 +817,13 @@
{
cairo_int_status_t status;
+ if (mask) {
+ /* These operators aren't interpreted the same way by the backends;
+ * they are implemented in terms of other operators in cairo-gstate.c
+ */
+ assert (operator != CAIRO_OPERATOR_SOURCE && operator != CAIRO_OPERATOR_CLEAR);
+ }
+
if (dst->status)
return dst->status;
@@ -1013,7 +1020,7 @@
*
* Applies an operator to a set of rectangles using a solid color
* as the source. Note that even if the operator is an unbounded operator
- * such as %CAIRO_OPERATOR_CLEAR, only the given set of rectangles
+ * such as %CAIRO_OPERATOR_IN, only the given set of rectangles
* is affected. This differs from _cairo_surface_composite_trapezoids()
* where the entire destination rectangle is cleared.
*
@@ -1152,6 +1159,11 @@
{
cairo_int_status_t status;
+ /* These operators aren't interpreted the same way by the backends;
+ * they are implemented in terms of other operators in cairo-gstate.c
+ */
+ assert (operator != CAIRO_OPERATOR_SOURCE && operator != CAIRO_OPERATOR_CLEAR);
+
if (dst->status)
return dst->status;
Index: cairo-xlib-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-xlib-surface.c,v
retrieving revision 1.109
retrieving revision 1.110
diff -u -d -r1.109 -r1.110
--- cairo-xlib-surface.c 17 Aug 2005 01:22:16 -0000 1.109
+++ cairo-xlib-surface.c 18 Aug 2005 22:50:36 -0000 1.110
@@ -1140,7 +1140,9 @@
width, height);
}
- if (!_cairo_operator_bounded (operator))
+ if (!_cairo_operator_bounded (operator) ||
+ operator == CAIRO_OPERATOR_SOURCE ||
+ operator == CAIRO_OPERATOR_CLEAR)
status = _cairo_surface_composite_fixup_unbounded (&dst->base,
&src_attr, src->width, src->height,
mask ? &mask_attr : NULL,
@@ -2517,7 +2519,7 @@
/* Handles clearing the regions that are outside of the temporary
* mask created by XRenderCompositeText[N] but should be affected
- * by an unbounded operator like CAIRO_OPERATOR_SOURCE.
+ * by an unbounded operator like CAIRO_OPERATOR_IN
*/
static cairo_status_t
_show_glyphs_fixup_unbounded (cairo_xlib_surface_t *self,
- Previous message: [cairo-commit] cairo/test .cvsignore, 1.43, 1.44 Makefile.am, 1.79,
1.80 clip-operator-ref.png, 1.2, 1.3 operator-clear-ref.png,
NONE, 1.1 operator-clear.c, NONE, 1.1 operator-source-ref.png,
NONE, 1.1 operator-source.c, NONE,
1.1 unbounded-operator-ref.png, 1.1, 1.2 unbounded-operator.c,
1.1, 1.2
- Next message: [cairo-commit] cairo ChangeLog,1.906,1.907
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the cairo-commit
mailing list