1 /*
2 * Copyright © 2018 Benjamin Otte
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authors: Benjamin Otte <otte@gnome.org>
18 */
19
20 #include "config.h"
21
22 #include "gtkrendernodepaintableprivate.h"
23
24 #include "gtksnapshot.h"
25
26 struct _GtkRenderNodePaintable
27 {
28 GObject parent_instance;
29
30 GskRenderNode *node;
31 graphene_rect_t bounds;
32 };
33
34 struct _GtkRenderNodePaintableClass
35 {
36 GObjectClass parent_class;
37 };
38
39 static void
gtk_render_node_paintable_paintable_snapshot(GdkPaintable * paintable,GdkSnapshot * snapshot,double width,double height)40 gtk_render_node_paintable_paintable_snapshot (GdkPaintable *paintable,
41 GdkSnapshot *snapshot,
42 double width,
43 double height)
44 {
45 GtkRenderNodePaintable *self = GTK_RENDER_NODE_PAINTABLE (paintable);
46
47 if (self->bounds.size.width <= 0 ||
48 self->bounds.size.height <= 0)
49 return;
50
51 gtk_snapshot_save (snapshot);
52
53 gtk_snapshot_scale (snapshot,
54 width / (self->bounds.size.width),
55 height / (self->bounds.size.height));
56 gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (-self->bounds.origin.x, -self->bounds.origin.y));
57
58 gtk_snapshot_push_clip (snapshot, &self->bounds);
59
60 gtk_snapshot_append_node (snapshot, self->node);
61 //gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 1, 0, 0, 1 }, &self->bounds);
62
63 gtk_snapshot_pop (snapshot);
64
65 gtk_snapshot_restore (snapshot);
66 }
67
68 static GdkPaintableFlags
gtk_render_node_paintable_paintable_get_flags(GdkPaintable * paintable)69 gtk_render_node_paintable_paintable_get_flags (GdkPaintable *paintable)
70 {
71 return GDK_PAINTABLE_STATIC_CONTENTS | GDK_PAINTABLE_STATIC_SIZE;
72 }
73
74 static int
gtk_render_node_paintable_paintable_get_intrinsic_width(GdkPaintable * paintable)75 gtk_render_node_paintable_paintable_get_intrinsic_width (GdkPaintable *paintable)
76 {
77 GtkRenderNodePaintable *self = GTK_RENDER_NODE_PAINTABLE (paintable);
78
79 return ceilf (self->bounds.size.width);
80 }
81
82 static int
gtk_render_node_paintable_paintable_get_intrinsic_height(GdkPaintable * paintable)83 gtk_render_node_paintable_paintable_get_intrinsic_height (GdkPaintable *paintable)
84 {
85 GtkRenderNodePaintable *self = GTK_RENDER_NODE_PAINTABLE (paintable);
86
87 return ceilf (self->bounds.size.height);
88 }
89
90 static void
gtk_render_node_paintable_paintable_init(GdkPaintableInterface * iface)91 gtk_render_node_paintable_paintable_init (GdkPaintableInterface *iface)
92 {
93 iface->snapshot = gtk_render_node_paintable_paintable_snapshot;
94 iface->get_flags = gtk_render_node_paintable_paintable_get_flags;
95 iface->get_intrinsic_width = gtk_render_node_paintable_paintable_get_intrinsic_width;
96 iface->get_intrinsic_height = gtk_render_node_paintable_paintable_get_intrinsic_height;
97 }
98
99 G_DEFINE_TYPE_EXTENDED (GtkRenderNodePaintable, gtk_render_node_paintable, G_TYPE_OBJECT, 0,
100 G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
101 gtk_render_node_paintable_paintable_init))
102
103 static void
gtk_render_node_paintable_dispose(GObject * object)104 gtk_render_node_paintable_dispose (GObject *object)
105 {
106 GtkRenderNodePaintable *self = GTK_RENDER_NODE_PAINTABLE (object);
107
108 g_clear_pointer (&self->node, gsk_render_node_unref);
109
110 G_OBJECT_CLASS (gtk_render_node_paintable_parent_class)->dispose (object);
111 }
112
113 static void
gtk_render_node_paintable_class_init(GtkRenderNodePaintableClass * klass)114 gtk_render_node_paintable_class_init (GtkRenderNodePaintableClass *klass)
115 {
116 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
117
118 gobject_class->dispose = gtk_render_node_paintable_dispose;
119 }
120
121 static void
gtk_render_node_paintable_init(GtkRenderNodePaintable * self)122 gtk_render_node_paintable_init (GtkRenderNodePaintable *self)
123 {
124 }
125
126 GdkPaintable *
gtk_render_node_paintable_new(GskRenderNode * node,const graphene_rect_t * bounds)127 gtk_render_node_paintable_new (GskRenderNode *node,
128 const graphene_rect_t *bounds)
129 {
130 GtkRenderNodePaintable *self;
131
132 g_return_val_if_fail (GSK_IS_RENDER_NODE (node), NULL);
133 g_return_val_if_fail (bounds != NULL, NULL);
134
135 self = g_object_new (GTK_TYPE_RENDER_NODE_PAINTABLE, NULL);
136
137 self->node = gsk_render_node_ref (node);
138 self->bounds = *bounds;
139
140 return GDK_PAINTABLE (self);
141 }
142
143 GskRenderNode *
gtk_render_node_paintable_get_render_node(GtkRenderNodePaintable * self)144 gtk_render_node_paintable_get_render_node (GtkRenderNodePaintable *self)
145 {
146 g_return_val_if_fail (GTK_IS_RENDER_NODE_PAINTABLE (self), NULL);
147
148 return self->node;
149 }
150