]> Pileus Git - ~andy/gtk/blob - gtk/gtkcssimage.c
win32: Add a CssImage implementation
[~andy/gtk] / gtk / gtkcssimage.c
1 /*
2  * Copyright © 2011 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, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  *
18  * Authors: Benjamin Otte <otte@gnome.org>
19  */
20
21 #include "config.h"
22
23 #include "gtkcssimageprivate.h"
24
25 /* for the types only */
26 #include "gtk/gtkcssimagegradientprivate.h"
27 #include "gtk/gtkcssimageurlprivate.h"
28 #include "gtk/gtkcssimagewin32private.h"
29
30 G_DEFINE_ABSTRACT_TYPE (GtkCssImage, _gtk_css_image, G_TYPE_OBJECT)
31
32 static int
33 gtk_css_image_real_get_width (GtkCssImage *image)
34 {
35   return 0;
36 }
37
38 static int
39 gtk_css_image_real_get_height (GtkCssImage *image)
40 {
41   return 0;
42 }
43
44 static double
45 gtk_css_image_real_get_aspect_ratio (GtkCssImage *image)
46 {
47   int width, height;
48
49   width = _gtk_css_image_get_width (image);
50   height = _gtk_css_image_get_height (image);
51
52   if (width && height)
53     return (double) width / height;
54   else
55     return 0;
56 }
57
58 static GtkCssImage *
59 gtk_css_image_real_compute (GtkCssImage     *image,
60                             GtkStyleContext *context)
61 {
62   return g_object_ref (image);
63 }
64
65 static void
66 _gtk_css_image_class_init (GtkCssImageClass *klass)
67 {
68   klass->get_width = gtk_css_image_real_get_width;
69   klass->get_height = gtk_css_image_real_get_height;
70   klass->get_aspect_ratio = gtk_css_image_real_get_aspect_ratio;
71   klass->compute = gtk_css_image_real_compute;
72 }
73
74 static void
75 _gtk_css_image_init (GtkCssImage *image)
76 {
77 }
78
79 int
80 _gtk_css_image_get_width (GtkCssImage *image)
81 {
82   GtkCssImageClass *klass;
83
84   g_return_val_if_fail (GTK_IS_CSS_IMAGE (image), 0);
85
86   klass = GTK_CSS_IMAGE_GET_CLASS (image);
87
88   return klass->get_width (image);
89 }
90
91 int
92 _gtk_css_image_get_height (GtkCssImage *image)
93 {
94   GtkCssImageClass *klass;
95
96   g_return_val_if_fail (GTK_IS_CSS_IMAGE (image), 0);
97
98   klass = GTK_CSS_IMAGE_GET_CLASS (image);
99
100   return klass->get_height (image);
101 }
102
103 double
104 _gtk_css_image_get_aspect_ratio (GtkCssImage *image)
105 {
106   GtkCssImageClass *klass;
107
108   g_return_val_if_fail (GTK_IS_CSS_IMAGE (image), 0);
109
110   klass = GTK_CSS_IMAGE_GET_CLASS (image);
111
112   return klass->get_aspect_ratio (image);
113 }
114
115 GtkCssImage *
116 _gtk_css_image_compute (GtkCssImage     *image,
117                         GtkStyleContext *context)
118 {
119   GtkCssImageClass *klass;
120
121   g_return_val_if_fail (GTK_IS_CSS_IMAGE (image), NULL);
122   g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), NULL);
123
124   klass = GTK_CSS_IMAGE_GET_CLASS (image);
125
126   return klass->compute (image, context);
127 }
128
129 void
130 _gtk_css_image_draw (GtkCssImage        *image,
131                      cairo_t            *cr,
132                      double              width,
133                      double              height)
134 {
135   GtkCssImageClass *klass;
136
137   g_return_if_fail (GTK_IS_CSS_IMAGE (image));
138   g_return_if_fail (cr != NULL);
139
140   cairo_save (cr);
141
142   klass = GTK_CSS_IMAGE_GET_CLASS (image);
143
144   klass->draw (image, cr, width, height);
145
146   cairo_restore (cr);
147 }
148
149 void
150 _gtk_css_image_print (GtkCssImage *image,
151                       GString     *string)
152 {
153   GtkCssImageClass *klass;
154
155   g_return_if_fail (GTK_IS_CSS_IMAGE (image));
156   g_return_if_fail (string != NULL);
157
158   klass = GTK_CSS_IMAGE_GET_CLASS (image);
159
160   klass->print (image, string);
161 }
162
163 GtkCssImage *
164 _gtk_css_image_new_parse (GtkCssParser *parser,
165                           GFile        *base)
166 {
167   static const struct {
168     const char *prefix;
169     GType (* type_func) (void);
170   } image_types[] = {
171     { "url", _gtk_css_image_url_get_type },
172     { "-gtk-gradient", _gtk_css_image_gradient_get_type },
173     { "-gtk-win32-theme-part", _gtk_css_image_win32_get_type }
174   };
175   guint i;
176
177   g_return_val_if_fail (parser != NULL, NULL);
178   g_return_val_if_fail (G_IS_FILE (base), NULL);
179
180   for (i = 0; i < G_N_ELEMENTS (image_types); i++)
181     {
182       if (_gtk_css_parser_has_prefix (parser, image_types[i].prefix))
183         {
184           GtkCssImage *image;
185           GtkCssImageClass *klass;
186
187           image = g_object_new (image_types[i].type_func (), NULL);
188
189           klass = GTK_CSS_IMAGE_GET_CLASS (image);
190           if (!klass->parse (image, parser, base))
191             {
192               g_object_unref (image);
193               return NULL;
194             }
195
196           return image;
197         }
198     }
199
200   _gtk_css_parser_error (parser, "Not a valid image");
201   return NULL;
202 }
203