1 | /* |
2 | * Copyright © 2018 Red Hat Inc. |
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 "gtkcssimagepaintableprivate.h" |
23 | |
24 | #include "gtkprivate.h" |
25 | |
26 | G_DEFINE_TYPE (GtkCssImagePaintable, gtk_css_image_paintable, GTK_TYPE_CSS_IMAGE) |
27 | |
28 | static inline GdkPaintable * |
29 | get_paintable (GtkCssImagePaintable *paintable) |
30 | { |
31 | if (paintable->static_paintable) |
32 | return paintable->static_paintable; |
33 | |
34 | return paintable->paintable; |
35 | } |
36 | |
37 | static int |
38 | gtk_css_image_paintable_get_width (GtkCssImage *image) |
39 | { |
40 | GtkCssImagePaintable *paintable = GTK_CSS_IMAGE_PAINTABLE (image); |
41 | |
42 | return gdk_paintable_get_intrinsic_width (paintable: get_paintable (paintable)); |
43 | } |
44 | |
45 | static int |
46 | gtk_css_image_paintable_get_height (GtkCssImage *image) |
47 | { |
48 | GtkCssImagePaintable *paintable = GTK_CSS_IMAGE_PAINTABLE (image); |
49 | |
50 | return gdk_paintable_get_intrinsic_height (paintable: get_paintable (paintable)); |
51 | } |
52 | |
53 | static double |
54 | gtk_css_image_paintable_get_aspect_ratio (GtkCssImage *image) |
55 | { |
56 | GtkCssImagePaintable *paintable = GTK_CSS_IMAGE_PAINTABLE (image); |
57 | |
58 | return gdk_paintable_get_intrinsic_aspect_ratio (paintable: get_paintable (paintable)); |
59 | } |
60 | |
61 | static void |
62 | gtk_css_image_paintable_snapshot (GtkCssImage *image, |
63 | GtkSnapshot *snapshot, |
64 | double width, |
65 | double height) |
66 | { |
67 | GtkCssImagePaintable *paintable = GTK_CSS_IMAGE_PAINTABLE (image); |
68 | |
69 | gdk_paintable_snapshot (paintable: get_paintable (paintable), |
70 | snapshot, |
71 | width, height); |
72 | } |
73 | |
74 | static GtkCssImage * |
75 | gtk_css_image_paintable_get_static_image (GtkCssImage *image) |
76 | { |
77 | GtkCssImagePaintable *paintable = GTK_CSS_IMAGE_PAINTABLE (image); |
78 | GdkPaintable *static_image; |
79 | GtkCssImage *result; |
80 | |
81 | static_image = gdk_paintable_get_current_image (paintable: paintable->paintable); |
82 | |
83 | if (paintable->static_paintable == static_image) |
84 | { |
85 | result = g_object_ref (image); |
86 | } |
87 | else |
88 | { |
89 | result = gtk_css_image_paintable_new (paintable: paintable->paintable, |
90 | static_paintable: static_image); |
91 | } |
92 | |
93 | g_object_unref (object: static_image); |
94 | |
95 | return result; |
96 | } |
97 | |
98 | static GtkCssImage * |
99 | gtk_css_image_paintable_compute (GtkCssImage *image, |
100 | guint property_id, |
101 | GtkStyleProvider *provider, |
102 | GtkCssStyle *style, |
103 | GtkCssStyle *parent_style) |
104 | { |
105 | return gtk_css_image_paintable_get_static_image (image); |
106 | } |
107 | |
108 | static gboolean |
109 | gtk_css_image_paintable_equal (GtkCssImage *image1, |
110 | GtkCssImage *image2) |
111 | { |
112 | GtkCssImagePaintable *paintable1 = GTK_CSS_IMAGE_PAINTABLE (image1); |
113 | GtkCssImagePaintable *paintable2 = GTK_CSS_IMAGE_PAINTABLE (image2); |
114 | |
115 | return paintable1->paintable == paintable2->paintable |
116 | && paintable1->static_paintable == paintable2->static_paintable; |
117 | } |
118 | |
119 | #define GDK_PAINTABLE_IMMUTABLE (GDK_PAINTABLE_STATIC_SIZE | GDK_PAINTABLE_STATIC_CONTENTS) |
120 | static gboolean |
121 | gtk_css_image_paintable_is_dynamic (GtkCssImage *image) |
122 | { |
123 | GtkCssImagePaintable *paintable = GTK_CSS_IMAGE_PAINTABLE (image); |
124 | |
125 | return (gdk_paintable_get_flags (paintable: paintable->paintable) & GDK_PAINTABLE_IMMUTABLE) == GDK_PAINTABLE_IMMUTABLE; |
126 | } |
127 | |
128 | static GtkCssImage * |
129 | gtk_css_image_paintable_get_dynamic_image (GtkCssImage *image, |
130 | gint64 monotonic_time) |
131 | { |
132 | return gtk_css_image_paintable_get_static_image (image); |
133 | } |
134 | |
135 | static void |
136 | gtk_css_image_paintable_print (GtkCssImage *image, |
137 | GString *string) |
138 | { |
139 | g_string_append (string, val: "none /* FIXME */" ); |
140 | } |
141 | |
142 | static void |
143 | gtk_css_image_paintable_dispose (GObject *object) |
144 | { |
145 | GtkCssImagePaintable *paintable = GTK_CSS_IMAGE_PAINTABLE (object); |
146 | |
147 | g_clear_object (&paintable->paintable); |
148 | g_clear_object (&paintable->static_paintable); |
149 | |
150 | G_OBJECT_CLASS (gtk_css_image_paintable_parent_class)->dispose (object); |
151 | } |
152 | |
153 | static gboolean |
154 | gtk_css_image_paintable_is_computed (GtkCssImage *image) |
155 | { |
156 | GtkCssImagePaintable *self = GTK_CSS_IMAGE_PAINTABLE (image); |
157 | |
158 | return (gdk_paintable_get_flags (paintable: self->paintable) & GDK_PAINTABLE_IMMUTABLE) == GDK_PAINTABLE_IMMUTABLE; |
159 | } |
160 | |
161 | static void |
162 | gtk_css_image_paintable_class_init (GtkCssImagePaintableClass *klass) |
163 | { |
164 | GtkCssImageClass *image_class = GTK_CSS_IMAGE_CLASS (klass); |
165 | GObjectClass *object_class = G_OBJECT_CLASS (klass); |
166 | |
167 | image_class->get_width = gtk_css_image_paintable_get_width; |
168 | image_class->get_height = gtk_css_image_paintable_get_height; |
169 | image_class->get_aspect_ratio = gtk_css_image_paintable_get_aspect_ratio; |
170 | image_class->snapshot = gtk_css_image_paintable_snapshot; |
171 | image_class->print = gtk_css_image_paintable_print; |
172 | image_class->compute = gtk_css_image_paintable_compute; |
173 | image_class->equal = gtk_css_image_paintable_equal; |
174 | image_class->is_dynamic = gtk_css_image_paintable_is_dynamic; |
175 | image_class->is_computed = gtk_css_image_paintable_is_computed; |
176 | image_class->get_dynamic_image = gtk_css_image_paintable_get_dynamic_image; |
177 | |
178 | object_class->dispose = gtk_css_image_paintable_dispose; |
179 | } |
180 | |
181 | static void |
182 | gtk_css_image_paintable_init (GtkCssImagePaintable *image_paintable) |
183 | { |
184 | } |
185 | |
186 | GtkCssImage * |
187 | gtk_css_image_paintable_new (GdkPaintable *paintable, |
188 | GdkPaintable *static_paintable) |
189 | { |
190 | GtkCssImage *image; |
191 | |
192 | gtk_internal_return_val_if_fail (GDK_IS_PAINTABLE (paintable), NULL); |
193 | gtk_internal_return_val_if_fail (static_paintable == NULL || GDK_IS_PAINTABLE (static_paintable), NULL); |
194 | |
195 | image = g_object_new (GTK_TYPE_CSS_IMAGE_PAINTABLE, NULL); |
196 | |
197 | GTK_CSS_IMAGE_PAINTABLE (image)->paintable = g_object_ref (paintable); |
198 | if (static_paintable) |
199 | GTK_CSS_IMAGE_PAINTABLE (image)->static_paintable = g_object_ref (static_paintable); |
200 | |
201 | return image; |
202 | } |
203 | |