diff options
author | Benjamin Otte <otte@redhat.com> | 2016-12-13 09:37:51 +0100 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2016-12-20 18:01:10 +0100 |
commit | 1f988d8b050b039f031122e906b0abb72f227cac (patch) | |
tree | 1a937bdd461be22133dd0794d3a1bbc49393e209 /gsk | |
parent | 68a54ae81fde71422beee789bb3e1a152b4722b5 (diff) | |
download | gtk+-1f988d8b050b039f031122e906b0abb72f227cac.tar.gz |
gsk: Add gsk_clip_node_new()
The node is a simple clipping node: It does a rectangular clip of its
contents.
Diffstat (limited to 'gsk')
-rw-r--r-- | gsk/gskenums.h | 4 | ||||
-rw-r--r-- | gsk/gskrendernode.h | 6 | ||||
-rw-r--r-- | gsk/gskrendernodeimpl.c | 125 | ||||
-rw-r--r-- | gsk/gskrendernodeprivate.h | 2 |
4 files changed, 136 insertions, 1 deletions
diff --git a/gsk/gskenums.h b/gsk/gskenums.h index caba77f6ab..7b37715ee6 100644 --- a/gsk/gskenums.h +++ b/gsk/gskenums.h @@ -32,6 +32,7 @@ * @GSK_TRANSFORM_NODE: A node that renders its child after applying a * matrix transform * @GSK_OPACITY_NODE: A node that changes the opacity of its child + * @GSK_CLIP_NODE: A node that clips its child to a rectangular area * * The type of a node determines what the node is rendering. * @@ -44,7 +45,8 @@ typedef enum { GSK_COLOR_NODE, GSK_TEXTURE_NODE, GSK_TRANSFORM_NODE, - GSK_OPACITY_NODE + GSK_OPACITY_NODE, + GSK_CLIP_NODE } GskRenderNodeType; /** diff --git a/gsk/gskrendernode.h b/gsk/gskrendernode.h index 3be25035b1..cdd52b7cb0 100644 --- a/gsk/gskrendernode.h +++ b/gsk/gskrendernode.h @@ -80,6 +80,12 @@ GDK_AVAILABLE_IN_3_90 GskRenderNode * gsk_opacity_node_get_child (GskRenderNode *node); GDK_AVAILABLE_IN_3_90 +GskRenderNode * gsk_clip_node_new (GskRenderNode *child, + const graphene_rect_t *clip); +GDK_AVAILABLE_IN_3_90 +GskRenderNode * gsk_clip_node_get_child (GskRenderNode *node); + +GDK_AVAILABLE_IN_3_90 void gsk_render_node_set_blend_mode (GskRenderNode *node, GskBlendMode blend_mode); diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c index 764b702df8..9797f23c9d 100644 --- a/gsk/gskrendernodeimpl.c +++ b/gsk/gskrendernodeimpl.c @@ -819,3 +819,128 @@ gsk_opacity_node_get_opacity (GskRenderNode *node) return self->opacity; } +/*** GSK_CLIP_NODE ***/ + +typedef struct _GskClipNode GskClipNode; + +struct _GskClipNode +{ + GskRenderNode render_node; + + GskRenderNode *child; + graphene_rect_t clip; +}; + +static void +gsk_clip_node_finalize (GskRenderNode *node) +{ + GskClipNode *self = (GskClipNode *) node; + + gsk_render_node_unref (self->child); +} + +static void +gsk_clip_node_make_immutable (GskRenderNode *node) +{ + GskClipNode *self = (GskClipNode *) node; + + gsk_render_node_make_immutable (self->child); +} + +static void +gsk_clip_node_draw (GskRenderNode *node, + cairo_t *cr) +{ + GskClipNode *self = (GskClipNode *) node; + + cairo_save (cr); + + cairo_rectangle (cr, + self->clip.origin.x, self->clip.origin.y, + self->clip.size.width, self->clip.size.height); + cairo_clip (cr); + + gsk_render_node_draw (self->child, cr); + + cairo_restore (cr); +} + +static void +gsk_clip_node_get_bounds (GskRenderNode *node, + graphene_rect_t *bounds) +{ + GskClipNode *self = (GskClipNode *) node; + graphene_rect_t child_bounds; + + gsk_render_node_get_bounds (self->child, &child_bounds); + + graphene_rect_intersection (&self->clip, &child_bounds, bounds); +} + +static const GskRenderNodeClass GSK_CLIP_NODE_CLASS = { + GSK_CLIP_NODE, + sizeof (GskClipNode), + "GskClipNode", + gsk_clip_node_finalize, + gsk_clip_node_make_immutable, + gsk_clip_node_draw, + gsk_clip_node_get_bounds +}; + +/** + * gsk_clip_node_new: + * @child: The node to draw + * @clip: The clip to apply + * + * Creates a #GskRenderNode that will clip the @child to the area + * given by @clip. + * + * Returns: A new #GskRenderNode + * + * Since: 3.90 + */ +GskRenderNode * +gsk_clip_node_new (GskRenderNode *child, + const graphene_rect_t *clip) +{ + GskClipNode *self; + + g_return_val_if_fail (GSK_IS_RENDER_NODE (child), NULL); + g_return_val_if_fail (clip != NULL, NULL); + + self = (GskClipNode *) gsk_render_node_new (&GSK_CLIP_NODE_CLASS); + + self->child = gsk_render_node_ref (child); + graphene_rect_normalize_r (clip, &self->clip); + + return &self->render_node; +} + +/** + * gsk_clip_node_get_child: + * @node: a clip @GskRenderNode + * + * Gets the child node that is getting clipped by the given @node. + * + * Returns: (transfer none): The child that is getting clipped + **/ +GskRenderNode * +gsk_clip_node_get_child (GskRenderNode *node) +{ + GskClipNode *self = (GskClipNode *) node; + + g_return_val_if_fail (GSK_IS_RENDER_NODE_TYPE (node, GSK_CLIP_NODE), NULL); + + return self->child; +} + +const graphene_rect_t * +gsk_clip_node_peek_clip (GskRenderNode *node) +{ + GskClipNode *self = (GskClipNode *) node; + + g_return_val_if_fail (GSK_IS_RENDER_NODE_TYPE (node, GSK_CLIP_NODE), NULL); + + return &self->clip; +} + diff --git a/gsk/gskrendernodeprivate.h b/gsk/gskrendernodeprivate.h index 3ad5c43658..1bb06394cf 100644 --- a/gsk/gskrendernodeprivate.h +++ b/gsk/gskrendernodeprivate.h @@ -60,6 +60,8 @@ GskTexture *gsk_texture_node_get_texture (GskRenderNode *node); const GdkRGBA *gsk_color_node_peek_color (GskRenderNode *node); +const graphene_rect_t * gsk_clip_node_peek_clip (GskRenderNode *node); + void gsk_transform_node_get_transform (GskRenderNode *node, graphene_matrix_t *transform); GskBlendMode gsk_render_node_get_blend_mode (GskRenderNode *node); |