[cairo-commit] cairo/src cairo_glitz_surface.c, 1.22,
1.23 cairo_pattern.c, 1.25, 1.26 cairo_win32_surface.c, 1.7,
1.8 cairoint.h, 1.102, 1.103
Owen Taylor
commit at pdx.freedesktop.org
Fri Mar 4 09:41:36 PST 2005
Committed by: otaylor
Update of /cvs/cairo/cairo/src
In directory gabe:/tmp/cvs-serv960/src
Modified Files:
cairo_glitz_surface.c cairo_pattern.c cairo_win32_surface.c
cairoint.h
Log Message:
2005-03-04 Owen Taylor <otaylor at redhat.com>
* src/cairoint.h src/cairo_pattern.c src/cairo_glitz_surface.c:
Add _cairo_pattern_is_opaque, use it rather than
pattern->alpha == 1.0.
Index: cairo_glitz_surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_glitz_surface.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- cairo_glitz_surface.c 4 Mar 2005 02:55:28 -0000 1.22
+++ cairo_glitz_surface.c 4 Mar 2005 17:41:34 -0000 1.23
@@ -556,7 +556,7 @@
/* can't do alpha as gradient color interpolation must be done to
unpremultiplied colors. */
- if (pattern->alpha != 1.0)
+ if (_cairo_pattern_is_opaque (pattern))
break;
/* glitz doesn't support inner and outer circle with different
@@ -730,28 +730,46 @@
{
cairo_int_status_t status;
cairo_pattern_union_t tmp;
+ cairo_bool_t src_opaque, mask_opaque;
double src_alpha, mask_alpha;
- if (src->type != CAIRO_PATTERN_SOLID)
+ src_opaque = _cairo_pattern_is_opaque (src);
+ mask_opaque = !mask || _cairo_pattern_is_opaque (mask);
+
+ /* For surface patterns, we move any translucency from src->alpha
+ * to mask->alpha so we can use the source unchanged. Otherwise we
+ * move the translucency from mask->alpha to src->alpha so that
+ * we can drop the mask if possible.
+ */
+ if (src->type == CAIRO_PATTERN_SURFACE)
{
- if (mask)
+ if (mask) {
+ mask_opaque = mask_opaque && src_opaque;
mask_alpha = mask->alpha * src->alpha;
- else
+ } else {
+ mask_opaque = src_opaque;
mask_alpha = src->alpha;
+ }
src_alpha = 1.0;
+ src_opaque = TRUE;
}
else
{
if (mask)
{
+ src_opaque = mask_opaque && src_opaque;
src_alpha = mask->alpha * src->alpha;
+ /* FIXME: This needs changing when we support RENDER
+ * style 4-channel masks.
+ */
if (mask->type == CAIRO_PATTERN_SOLID)
mask = NULL;
} else
src_alpha = src->alpha;
mask_alpha = 1.0;
+ mask_opaque = TRUE;
}
_cairo_pattern_init_copy (&tmp.base, src);
@@ -767,7 +785,7 @@
if (status)
return status;
- if (mask || mask_alpha != 1.0)
+ if (mask || !mask_opaque)
{
if (mask)
_cairo_pattern_init_copy (&tmp.base, mask);
Index: cairo_pattern.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_pattern.c,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -d -r1.25 -r1.26
--- cairo_pattern.c 4 Mar 2005 02:46:49 -0000 1.25
+++ cairo_pattern.c 4 Mar 2005 17:41:34 -0000 1.26
@@ -913,6 +913,32 @@
return CAIRO_STATUS_SUCCESS;
}
+
+/**
+ * _cairo_pattern_is_opaque
+ *
+ * Convenience function to determine whether a pattern has an opaque
+ * alpha value. This is done by testing whether the pattern's alpha
+ * value when converted to a byte is 255, so if a backend actually
+ * supported deep alpha channels this function might not do the right
+ * thing.
+ *
+ * Note that for a gradient or surface pattern, the overall resulting
+ * alpha for the pattern can be non-opaque even this function returns
+ * %TRUE, since the resulting alpha is the multiplication of the
+ * alpha of the gradient or surface with the pattern's alpha. In
+ * the future, alpha will be moved from the base pattern to the
+ * solid pattern subtype, at which point this function should
+ * probably be renamed to _cairo_pattern_is_opaque_solid()
+ *
+ * Return value: %TRUE if the pattern is opaque
+ **/
+cairo_bool_t
+_cairo_pattern_is_opaque (cairo_pattern_t *pattern)
+{
+ return (pattern->alpha >= ((double)0xff00 / (double)0xffff));
+}
+
static cairo_int_status_t
_cairo_pattern_acquire_surface_for_surface (cairo_surface_pattern_t *pattern,
cairo_surface_t *dst,
@@ -928,7 +954,7 @@
attr->acquired = FALSE;
/* handle pattern opacity */
- if (pattern->base.alpha != 1.0)
+ if (!_cairo_pattern_is_opaque (&pattern->base))
{
cairo_surface_pattern_t tmp;
cairo_color_t color;
@@ -1130,29 +1156,48 @@
cairo_surface_attributes_t *mask_attributes)
{
cairo_int_status_t status;
+
cairo_pattern_union_t tmp;
+ cairo_bool_t src_opaque, mask_opaque;
double src_alpha, mask_alpha;
+ src_opaque = _cairo_pattern_is_opaque (src);
+ mask_opaque = !mask || _cairo_pattern_is_opaque (mask);
+
+ /* For surface patterns, we move any translucency from src->alpha
+ * to mask->alpha so we can use the source unchanged. Otherwise we
+ * move the translucency from mask->alpha to src->alpha so that
+ * we can drop the mask if possible.
+ */
if (src->type == CAIRO_PATTERN_SURFACE)
{
- if (mask)
+ if (mask) {
+ mask_opaque = mask_opaque && src_opaque;
mask_alpha = mask->alpha * src->alpha;
- else
+ } else {
+ mask_opaque = src_opaque;
mask_alpha = src->alpha;
+ }
src_alpha = 1.0;
+ src_opaque = TRUE;
}
else
{
if (mask)
{
+ src_opaque = mask_opaque && src_opaque;
src_alpha = mask->alpha * src->alpha;
+ /* FIXME: This needs changing when we support RENDER
+ * style 4-channel masks.
+ */
if (mask->type == CAIRO_PATTERN_SOLID)
mask = NULL;
} else
src_alpha = src->alpha;
mask_alpha = 1.0;
+ mask_opaque = TRUE;
}
_cairo_pattern_init_copy (&tmp.base, src);
@@ -1168,7 +1213,7 @@
if (status)
return status;
- if (mask || mask_alpha != 1.0)
+ if (mask || !mask_opaque)
{
if (mask)
_cairo_pattern_init_copy (&tmp.base, mask);
Index: cairo_win32_surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_win32_surface.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- cairo_win32_surface.c 24 Feb 2005 23:48:07 -0000 1.7
+++ cairo_win32_surface.c 4 Mar 2005 17:41:34 -0000 1.8
@@ -591,7 +591,7 @@
static cairo_int_status_t
_cairo_win32_surface_composite (cairo_operator_t operator,
cairo_pattern_t *pattern,
- cairo_surface_t *generic_mask,
+ cairo_pattern_t *mask_pattern,
void *abstract_dst,
int src_x,
int src_y,
@@ -604,7 +604,7 @@
{
cairo_win32_surface_t *dst = abstract_dst;
cairo_win32_surface_t *src;
- cairo_win32_surface_t *mask = (cairo_win32_surface_t *)generic_mask;
+ cairo_win32_surface_t *mask;
int alpha;
int integer_transform;
int itx, ity;
Index: cairoint.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairoint.h,v
retrieving revision 1.102
retrieving revision 1.103
diff -u -d -r1.102 -r1.103
--- cairoint.h 4 Mar 2005 02:39:06 -0000 1.102
+++ cairoint.h 4 Mar 2005 17:41:34 -0000 1.103
@@ -1715,6 +1715,9 @@
_cairo_pattern_transform (cairo_pattern_t *pattern,
cairo_matrix_t *ctm_inverse);
+cairo_private cairo_bool_t
+_cairo_pattern_is_opaque (cairo_pattern_t *pattern);
+
cairo_private cairo_int_status_t
_cairo_pattern_acquire_surface (cairo_pattern_t *pattern,
cairo_surface_t *dst,
More information about the cairo-commit
mailing list