static gboolean
gsk_porter_duff_is_bound_by_source (GskPorterDuff porter_duff)
{ switch (porter_duff)
{ case GSK_PORTER_DUFF_DEST: /* this is a no-op */ case GSK_PORTER_DUFF_SOURCE_OVER_DEST: case GSK_PORTER_DUFF_DEST_OVER_SOURCE: case GSK_PORTER_DUFF_DEST_OUT_SOURCE: case GSK_PORTER_DUFF_SOURCE_ATOP_DEST: case GSK_PORTER_DUFF_XOR: returnTRUE;
case GSK_PORTER_DUFF_SOURCE: case GSK_PORTER_DUFF_SOURCE_IN_DEST: case GSK_PORTER_DUFF_DEST_IN_SOURCE: case GSK_PORTER_DUFF_SOURCE_OUT_DEST: case GSK_PORTER_DUFF_DEST_ATOP_SOURCE: case GSK_PORTER_DUFF_CLEAR: returnFALSE;
default:
g_return_val_if_reached (TRUE);
}
}
static cairo_operator_t
gsk_porter_duff_to_cairo_operator (GskPorterDuff porter_duff)
{ switch (porter_duff)
{ case GSK_PORTER_DUFF_SOURCE: return CAIRO_OPERATOR_SOURCE; case GSK_PORTER_DUFF_DEST: return CAIRO_OPERATOR_DEST; case GSK_PORTER_DUFF_SOURCE_OVER_DEST: return CAIRO_OPERATOR_OVER; case GSK_PORTER_DUFF_DEST_OVER_SOURCE: return CAIRO_OPERATOR_DEST_OVER; case GSK_PORTER_DUFF_SOURCE_IN_DEST: return CAIRO_OPERATOR_IN; case GSK_PORTER_DUFF_DEST_IN_SOURCE: return CAIRO_OPERATOR_DEST_IN; case GSK_PORTER_DUFF_SOURCE_OUT_DEST: return CAIRO_OPERATOR_OUT; case GSK_PORTER_DUFF_DEST_OUT_SOURCE: return CAIRO_OPERATOR_DEST_OUT; case GSK_PORTER_DUFF_SOURCE_ATOP_DEST: return CAIRO_OPERATOR_ATOP; case GSK_PORTER_DUFF_DEST_ATOP_SOURCE: return CAIRO_OPERATOR_DEST_ATOP; case GSK_PORTER_DUFF_XOR: return CAIRO_OPERATOR_XOR; case GSK_PORTER_DUFF_CLEAR: return CAIRO_OPERATOR_CLEAR; default:
g_return_val_if_reached (CAIRO_OPERATOR_OVER);
}
}
static cairo_operator_t
gsk_porter_duff_clears_background (GskPorterDuff porter_duff)
{ switch (porter_duff)
{ case GSK_PORTER_DUFF_SOURCE: case GSK_PORTER_DUFF_DEST_OVER_SOURCE: case GSK_PORTER_DUFF_SOURCE_IN_DEST: case GSK_PORTER_DUFF_DEST_IN_SOURCE: case GSK_PORTER_DUFF_SOURCE_OUT_DEST: case GSK_PORTER_DUFF_DEST_OUT_SOURCE: case GSK_PORTER_DUFF_SOURCE_ATOP_DEST: case GSK_PORTER_DUFF_DEST_ATOP_SOURCE: case GSK_PORTER_DUFF_XOR: case GSK_PORTER_DUFF_CLEAR: returnTRUE;
case GSK_PORTER_DUFF_DEST: case GSK_PORTER_DUFF_SOURCE_OVER_DEST: returnFALSE;
default:
g_return_val_if_reached (TRUE);
}
}
static cairo_operator_t
gsk_porter_duff_clears_foreground (GskPorterDuff porter_duff)
{ switch (porter_duff)
{ case GSK_PORTER_DUFF_DEST: case GSK_PORTER_DUFF_SOURCE_IN_DEST: case GSK_PORTER_DUFF_SOURCE_OUT_DEST: case GSK_PORTER_DUFF_DEST_OUT_SOURCE: case GSK_PORTER_DUFF_SOURCE_ATOP_DEST: case GSK_PORTER_DUFF_XOR: case GSK_PORTER_DUFF_CLEAR: returnTRUE;
case GSK_PORTER_DUFF_SOURCE: case GSK_PORTER_DUFF_SOURCE_OVER_DEST: case GSK_PORTER_DUFF_DEST_OVER_SOURCE: case GSK_PORTER_DUFF_DEST_IN_SOURCE: case GSK_PORTER_DUFF_DEST_ATOP_SOURCE: returnFALSE;
/* clip so the push_group() creates a smaller surface */
gdk_cairo_rectangle_snap_to_grid (cr, &node->bounds);
cairo_clip (cr); if (gdk_cairo_is_all_clipped (cr)) return;
/* First, copy the current target contents into a new offscreen */
cairo_push_group (cr);
cairo_save (cr);
cairo_identity_matrix (cr);
cairo_set_source_surface (cr, bg, 0, 0);
cairo_paint (cr);
cairo_restore (cr);
/* Then, draw the child into the offscreen as if no mask existed */
cairo_push_group (cr);
gsk_render_node_draw_full (self->child, cr, data);
cairo_pop_group_to_source (cr);
cairo_set_operator (cr, gsk_porter_duff_to_cairo_operator (self->op));
cairo_paint (cr);
/* Next, clear according to the mask */
cairo_pop_group_to_source (cr);
cairo_push_group (cr);
gsk_render_node_draw_full (self->mask, cr, data);
mask_pattern = cairo_pop_group (cr);
cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
cairo_mask (cr, mask_pattern);
/* Finally, add the offscreen using the mask */
cairo_set_operator (cr, CAIRO_OPERATOR_ADD);
cairo_mask (cr, mask_pattern);
}
}
switch (self->op)
{ case GSK_PORTER_DUFF_SOURCE: case GSK_PORTER_DUFF_DEST_ATOP_SOURCE:
case GSK_PORTER_DUFF_SOURCE_OVER_DEST: case GSK_PORTER_DUFF_DEST_OVER_SOURCE:
{
GskOpacityData child_data = GSK_OPACITY_DATA_INIT_EMPTY (data->copies);
case GSK_PORTER_DUFF_DEST: case GSK_PORTER_DUFF_SOURCE_ATOP_DEST: /* no changes */ break;
case GSK_PORTER_DUFF_SOURCE_IN_DEST: case GSK_PORTER_DUFF_DEST_IN_SOURCE: case GSK_PORTER_DUFF_SOURCE_OUT_DEST: case GSK_PORTER_DUFF_DEST_OUT_SOURCE: case GSK_PORTER_DUFF_XOR: /* feel free to implement these. For now: */ case GSK_PORTER_DUFF_CLEAR: if (!gsk_rect_subtract (&data->opaque, &self->mask->bounds, &data->opaque))
data->opaque = GRAPHENE_RECT_INIT (0, 0, 0, 0); break;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.