1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 2014,2015 Benjamin Otte
3 *
4 * Authors: Benjamin Otte <otte@gnome.org>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "config.h"
21
22 #include "gtkrendericonprivate.h"
23
24 #include "gtkcssfiltervalueprivate.h"
25 #include "gtkcssimagevalueprivate.h"
26 #include "gtkcssshadowvalueprivate.h"
27 #include "gtkcssstyleprivate.h"
28 #include "gtkcsstransformvalueprivate.h"
29 #include "gtkiconthemeprivate.h"
30 #include "gtksnapshot.h"
31 #include "gsktransform.h"
32
33 #include <math.h>
34
35 void
gtk_css_style_snapshot_icon(GtkCssStyle * style,GtkSnapshot * snapshot,double width,double height)36 gtk_css_style_snapshot_icon (GtkCssStyle *style,
37 GtkSnapshot *snapshot,
38 double width,
39 double height)
40 {
41 GskTransform *transform;
42 GtkCssImage *image;
43 gboolean has_shadow;
44
45 g_return_if_fail (GTK_IS_CSS_STYLE (style));
46 g_return_if_fail (snapshot != NULL);
47
48 if (width == 0.0 || height == 0.0)
49 return;
50
51 image = _gtk_css_image_value_get_image (style->other->icon_source);
52 if (image == NULL)
53 return;
54
55 transform = gtk_css_transform_value_get_transform (style->other->icon_transform);
56
57 gtk_snapshot_push_debug (snapshot, "CSS Icon @ %gx%g", width, height);
58
59 gtk_css_filter_value_push_snapshot (style->other->icon_filter, snapshot);
60
61 has_shadow = gtk_css_shadow_value_push_snapshot (style->icon->icon_shadow, snapshot);
62
63 if (transform == NULL)
64 {
65 gtk_css_image_snapshot (image, snapshot, width, height);
66 }
67 else
68 {
69 gtk_snapshot_save (snapshot);
70
71 /* XXX: Implement -gtk-icon-transform-origin instead of hardcoding "50% 50%" here */
72 gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (width / 2.0, height / 2.0));
73 gtk_snapshot_transform (snapshot, transform);
74 gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (- width / 2.0, - height / 2.0));
75
76 gtk_css_image_snapshot (image, snapshot, width, height);
77
78 gtk_snapshot_restore (snapshot);
79 }
80
81 if (has_shadow)
82 gtk_snapshot_pop (snapshot);
83
84 gtk_css_filter_value_pop_snapshot (style->other->icon_filter, snapshot);
85
86 gtk_snapshot_pop (snapshot);
87
88 gsk_transform_unref (transform);
89 }
90
91 void
gtk_css_style_snapshot_icon_paintable(GtkCssStyle * style,GtkSnapshot * snapshot,GdkPaintable * paintable,double width,double height)92 gtk_css_style_snapshot_icon_paintable (GtkCssStyle *style,
93 GtkSnapshot *snapshot,
94 GdkPaintable *paintable,
95 double width,
96 double height)
97 {
98 GskTransform *transform;
99 gboolean has_shadow;
100 gboolean is_icon_paintable;
101 GdkRGBA fg, sc, wc, ec;
102
103 g_return_if_fail (GTK_IS_CSS_STYLE (style));
104 g_return_if_fail (snapshot != NULL);
105 g_return_if_fail (GDK_IS_PAINTABLE (paintable));
106 g_return_if_fail (width > 0);
107 g_return_if_fail (height > 0);
108
109 transform = gtk_css_transform_value_get_transform (style->other->icon_transform);
110
111 gtk_css_filter_value_push_snapshot (style->other->icon_filter, snapshot);
112
113 has_shadow = gtk_css_shadow_value_push_snapshot (style->icon->icon_shadow, snapshot);
114
115 is_icon_paintable = GTK_IS_ICON_PAINTABLE (paintable);
116 if (is_icon_paintable)
117 {
118 gtk_icon_theme_lookup_symbolic_colors (style, &fg, &sc, &wc, &ec);
119
120 if (fg.alpha == 0.0f)
121 goto transparent;
122 }
123
124 if (transform == NULL)
125 {
126 if (is_icon_paintable)
127 gtk_icon_paintable_snapshot_with_colors (GTK_ICON_PAINTABLE (paintable), snapshot, width, height, &fg, &sc, &wc, &ec);
128 else
129 gdk_paintable_snapshot (paintable, snapshot, width, height);
130 }
131 else
132 {
133 gtk_snapshot_save (snapshot);
134
135 /* XXX: Implement -gtk-icon-transform-origin instead of hardcoding "50% 50%" here */
136 gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (width / 2.0, height / 2.0));
137 gtk_snapshot_transform (snapshot, transform);
138 gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (- width / 2.0, - height / 2.0));
139
140 if (is_icon_paintable)
141 gtk_icon_paintable_snapshot_with_colors (GTK_ICON_PAINTABLE (paintable), snapshot, width, height, &fg, &sc, &wc, &ec);
142 else
143 gdk_paintable_snapshot (paintable, snapshot, width, height);
144
145 gtk_snapshot_restore (snapshot);
146 }
147
148 transparent:
149 if (has_shadow)
150 gtk_snapshot_pop (snapshot);
151
152 gtk_css_filter_value_pop_snapshot (style->other->icon_filter, snapshot);
153
154 gsk_transform_unref (transform);
155 }
156