]> Pileus Git - ~andy/gtk/blob - gdk-pixbuf/gdk-pixbuf-scaled-anim.c
Adds authentication support of CUPS backend
[~andy/gtk] / gdk-pixbuf / gdk-pixbuf-scaled-anim.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
2 /* GdkPixbuf library - Simple transformations of animations
3  *
4  * Copyright (C) Red Hat, Inc
5  *
6  * Authors: Matthias Clasen <mclasen@redhat.com>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  *
23  */
24
25 #include <glib.h>
26
27 #include "gdk-pixbuf.h"
28 #include "gdk-pixbuf-io.h"
29 #include "gdk-pixbuf-scaled-anim.h"
30 #include "gdk-pixbuf-alias.h"
31
32
33 struct _GdkPixbufScaledAnimClass
34 {
35         GdkPixbufAnimationClass parent_class;
36 };
37
38 struct _GdkPixbufScaledAnim
39 {
40         GdkPixbufAnimation parent_instance;
41
42         GdkPixbufAnimation *anim;
43         gdouble xscale;
44         gdouble yscale;
45         gdouble tscale;
46
47         GdkPixbuf *current;
48 };
49
50 struct _GdkPixbufScaledAnimIterClass
51 {
52         GdkPixbufAnimationClass parent_class;
53 };
54
55 struct _GdkPixbufScaledAnimIter
56 {
57         GdkPixbufAnimationIter parent_instance;
58
59         GdkPixbufScaledAnim *scaled;
60         GdkPixbufAnimationIter *iter;
61 };
62
63 typedef struct _GdkPixbufScaledAnimIter GdkPixbufScaledAnimIter;
64 typedef struct _GdkPixbufScaledAnimIterClass GdkPixbufScaledAnimIterClass;
65
66 GdkPixbufScaledAnim *
67 _gdk_pixbuf_scaled_anim_new (GdkPixbufAnimation *anim,
68                              gdouble             xscale,
69                              gdouble             yscale,
70                              gdouble             tscale)
71 {
72         GdkPixbufScaledAnim *scaled;
73
74         scaled = g_object_new (GDK_TYPE_PIXBUF_SCALED_ANIM, NULL);
75
76         scaled->anim = g_object_ref (anim);
77         scaled->xscale = xscale;
78         scaled->yscale = yscale;
79         scaled->tscale = tscale;
80
81         return scaled;
82 }
83
84 G_DEFINE_TYPE (GdkPixbufScaledAnim, gdk_pixbuf_scaled_anim, GDK_TYPE_PIXBUF_ANIMATION);
85
86 static void
87 gdk_pixbuf_scaled_anim_init (GdkPixbufScaledAnim *scaled)
88 {
89         scaled->xscale = 1.0;
90         scaled->yscale = 1.0;
91         scaled->tscale = 1.0;
92 }
93
94 static void
95 gdk_pixbuf_scaled_anim_finalize (GObject *object)
96 {
97         GdkPixbufScaledAnim *scaled = (GdkPixbufScaledAnim *)object;
98
99         if (scaled->anim) {
100                 g_object_unref (scaled->anim);
101                 scaled->anim = NULL;
102         }
103
104         if (scaled->current) {
105                 g_object_unref (scaled->current);
106                 scaled->current = NULL;
107         }
108
109         G_OBJECT_CLASS (gdk_pixbuf_scaled_anim_parent_class)->finalize (object);
110 }
111
112 static gboolean
113 is_static_image (GdkPixbufAnimation *anim)
114 {
115         GdkPixbufScaledAnim *scaled = (GdkPixbufScaledAnim *)anim;
116
117         return gdk_pixbuf_animation_is_static_image (scaled->anim);
118 }       
119
120 static GdkPixbuf *
121 get_scaled_pixbuf (GdkPixbufScaledAnim *scaled, 
122                    GdkPixbuf           *pixbuf)
123 {
124         GQuark  quark;
125         gchar **options;
126
127         if (scaled->current) 
128                 g_object_unref (scaled->current);
129
130         /* Preserve the options associated with the original pixbuf 
131            (if present), mostly so that client programs can use the
132            "orientation" option (if present) to rotate the image 
133            appropriately. gdk_pixbuf_scale_simple (and most other
134            gdk transform operations) does not preserve the attached
135            options when returning a new pixbuf. */
136
137         quark = g_quark_from_static_string ("gdk_pixbuf_options");
138         options = g_object_get_qdata (G_OBJECT (pixbuf), quark);
139
140         /* Get a new scaled pixbuf */
141         scaled->current  = gdk_pixbuf_scale_simple (pixbuf, 
142                         (int) (gdk_pixbuf_get_width (pixbuf) * scaled->xscale + .5),
143                         (int) (gdk_pixbuf_get_height (pixbuf) * scaled->yscale + .5),
144                         GDK_INTERP_BILINEAR);
145
146         /* Copy the original pixbuf options to the scaled pixbuf */
147         if (options && scaled->current)
148                   g_object_set_qdata_full (G_OBJECT (scaled->current), quark, 
149                                            g_strdupv (options), (GDestroyNotify) g_strfreev);
150
151         return scaled->current;
152 }
153
154 static GdkPixbuf *
155 get_static_image (GdkPixbufAnimation *anim)
156 {
157         GdkPixbufScaledAnim *scaled = (GdkPixbufScaledAnim *)anim;
158         GdkPixbuf *pixbuf;
159         
160         pixbuf = gdk_pixbuf_animation_get_static_image (scaled->anim);
161         return get_scaled_pixbuf (scaled, pixbuf);
162 }
163
164 static void
165 get_size (GdkPixbufAnimation *anim,
166           int                *width,
167           int                *height)
168 {
169         GdkPixbufScaledAnim *scaled = (GdkPixbufScaledAnim *)anim;
170
171         GDK_PIXBUF_ANIMATION_GET_CLASS (scaled->anim)->get_size (scaled->anim, width, height);
172         if (width) 
173                 *width = (int)(*width * scaled->xscale + .5);
174         if (height)
175                 *height = (int)(*height * scaled->yscale + .5);
176 }
177
178 static GdkPixbufAnimationIter *
179 get_iter (GdkPixbufAnimation *anim,
180           const GTimeVal     *start_time)
181 {
182         GdkPixbufScaledAnim *scaled = (GdkPixbufScaledAnim *)anim;
183         GdkPixbufScaledAnimIter *iter;
184
185         iter = g_object_new (GDK_TYPE_PIXBUF_SCALED_ANIM_ITER, NULL);
186
187         iter->scaled = g_object_ref (scaled);
188         iter->iter = gdk_pixbuf_animation_get_iter (scaled->anim, start_time);
189         
190         return (GdkPixbufAnimationIter*)iter;
191 }
192
193 static void
194 gdk_pixbuf_scaled_anim_class_init (GdkPixbufScaledAnimClass *klass)
195 {
196         GObjectClass *object_class;
197         GdkPixbufAnimationClass *anim_class;
198
199         object_class = G_OBJECT_CLASS (klass);
200         anim_class = GDK_PIXBUF_ANIMATION_CLASS (klass);
201         
202         object_class->finalize = gdk_pixbuf_scaled_anim_finalize;
203         
204         anim_class->is_static_image = is_static_image;
205         anim_class->get_static_image = get_static_image;
206         anim_class->get_size = get_size;
207         anim_class->get_iter = get_iter;
208 }
209
210
211 G_DEFINE_TYPE (GdkPixbufScaledAnimIter, gdk_pixbuf_scaled_anim_iter, GDK_TYPE_PIXBUF_ANIMATION_ITER);
212
213 static void
214 gdk_pixbuf_scaled_anim_iter_init (GdkPixbufScaledAnimIter *iter)
215 {
216 }
217
218 static int
219 get_delay_time (GdkPixbufAnimationIter *iter)
220 {
221         GdkPixbufScaledAnimIter *scaled = (GdkPixbufScaledAnimIter *)iter;
222         int delay;
223
224         delay = gdk_pixbuf_animation_iter_get_delay_time (scaled->iter);
225         delay = (int)(delay * scaled->scaled->tscale);
226
227         return delay;
228 }
229
230 static GdkPixbuf *
231 get_pixbuf (GdkPixbufAnimationIter *iter)
232 {
233         GdkPixbufScaledAnimIter *scaled = (GdkPixbufScaledAnimIter *)iter;
234         GdkPixbuf *pixbuf;
235
236         pixbuf = gdk_pixbuf_animation_iter_get_pixbuf (scaled->iter);
237         return get_scaled_pixbuf (scaled->scaled, pixbuf);
238 }
239
240 static gboolean 
241 on_currently_loading_frame (GdkPixbufAnimationIter *iter)
242 {
243         GdkPixbufScaledAnimIter *scaled = (GdkPixbufScaledAnimIter *)iter;
244
245         return gdk_pixbuf_animation_iter_on_currently_loading_frame (scaled->iter);
246 }
247
248 static gboolean
249 advance (GdkPixbufAnimationIter *iter,
250          const GTimeVal         *current_time)
251 {
252         GdkPixbufScaledAnimIter *scaled = (GdkPixbufScaledAnimIter *)iter;
253
254         return gdk_pixbuf_animation_iter_advance (scaled->iter, current_time);
255 }
256
257 static void
258 gdk_pixbuf_scaled_anim_iter_finalize (GObject *object)
259 {
260         GdkPixbufScaledAnimIter *iter = (GdkPixbufScaledAnimIter *)object;
261         
262         g_object_unref (iter->iter);
263         g_object_unref (iter->scaled);
264
265         G_OBJECT_CLASS (gdk_pixbuf_scaled_anim_iter_parent_class)->finalize (object);
266 }
267
268 static void
269 gdk_pixbuf_scaled_anim_iter_class_init (GdkPixbufScaledAnimIterClass *klass)
270 {
271         GObjectClass *object_class;
272         GdkPixbufAnimationIterClass *anim_iter_class;
273
274         object_class = G_OBJECT_CLASS (klass);
275         anim_iter_class = GDK_PIXBUF_ANIMATION_ITER_CLASS (klass);
276         
277         object_class->finalize = gdk_pixbuf_scaled_anim_iter_finalize;
278         
279         anim_iter_class->get_delay_time = get_delay_time;
280         anim_iter_class->get_pixbuf = get_pixbuf;
281         anim_iter_class->on_currently_loading_frame = on_currently_loading_frame;
282         anim_iter_class->advance = advance;
283 }
284
285 #define __GDK_PIXBUF_SCALED_ANIM_C__
286 #include "gdk-pixbuf-aliasdef.c"