1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
2 /* GdkPixbuf library - Simple transformations of animations
4 * Copyright (C) Red Hat, Inc
6 * Authors: Matthias Clasen <mclasen@redhat.com>
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.
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.
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.
27 #include "gdk-pixbuf.h"
28 #include "gdk-pixbuf-io.h"
29 #include "gdk-pixbuf-scaled-anim.h"
30 #include "gdk-pixbuf-alias.h"
33 struct _GdkPixbufScaledAnimClass
35 GdkPixbufAnimationClass parent_class;
38 struct _GdkPixbufScaledAnim
40 GdkPixbufAnimation parent_instance;
42 GdkPixbufAnimation *anim;
50 struct _GdkPixbufScaledAnimIterClass
52 GdkPixbufAnimationClass parent_class;
55 struct _GdkPixbufScaledAnimIter
57 GdkPixbufAnimationIter parent_instance;
59 GdkPixbufScaledAnim *scaled;
60 GdkPixbufAnimationIter *iter;
63 typedef struct _GdkPixbufScaledAnimIter GdkPixbufScaledAnimIter;
64 typedef struct _GdkPixbufScaledAnimIterClass GdkPixbufScaledAnimIterClass;
67 _gdk_pixbuf_scaled_anim_new (GdkPixbufAnimation *anim,
72 GdkPixbufScaledAnim *scaled;
74 scaled = g_object_new (GDK_TYPE_PIXBUF_SCALED_ANIM, NULL);
76 scaled->anim = g_object_ref (anim);
77 scaled->xscale = xscale;
78 scaled->yscale = yscale;
79 scaled->tscale = tscale;
84 G_DEFINE_TYPE (GdkPixbufScaledAnim, gdk_pixbuf_scaled_anim, GDK_TYPE_PIXBUF_ANIMATION);
87 gdk_pixbuf_scaled_anim_init (GdkPixbufScaledAnim *scaled)
95 gdk_pixbuf_scaled_anim_finalize (GObject *object)
97 GdkPixbufScaledAnim *scaled = (GdkPixbufScaledAnim *)object;
100 g_object_unref (scaled->anim);
104 if (scaled->current) {
105 g_object_unref (scaled->current);
106 scaled->current = NULL;
109 G_OBJECT_CLASS (gdk_pixbuf_scaled_anim_parent_class)->finalize (object);
113 is_static_image (GdkPixbufAnimation *anim)
115 GdkPixbufScaledAnim *scaled = (GdkPixbufScaledAnim *)anim;
117 return gdk_pixbuf_animation_is_static_image (scaled->anim);
121 get_scaled_pixbuf (GdkPixbufScaledAnim *scaled,
128 g_object_unref (scaled->current);
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. */
137 quark = g_quark_from_static_string ("gdk_pixbuf_options");
138 options = g_object_get_qdata (G_OBJECT (pixbuf), quark);
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);
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);
151 return scaled->current;
155 get_static_image (GdkPixbufAnimation *anim)
157 GdkPixbufScaledAnim *scaled = (GdkPixbufScaledAnim *)anim;
160 pixbuf = gdk_pixbuf_animation_get_static_image (scaled->anim);
161 return get_scaled_pixbuf (scaled, pixbuf);
165 get_size (GdkPixbufAnimation *anim,
169 GdkPixbufScaledAnim *scaled = (GdkPixbufScaledAnim *)anim;
171 GDK_PIXBUF_ANIMATION_GET_CLASS (scaled->anim)->get_size (scaled->anim, width, height);
173 *width = (int)(*width * scaled->xscale + .5);
175 *height = (int)(*height * scaled->yscale + .5);
178 static GdkPixbufAnimationIter *
179 get_iter (GdkPixbufAnimation *anim,
180 const GTimeVal *start_time)
182 GdkPixbufScaledAnim *scaled = (GdkPixbufScaledAnim *)anim;
183 GdkPixbufScaledAnimIter *iter;
185 iter = g_object_new (GDK_TYPE_PIXBUF_SCALED_ANIM_ITER, NULL);
187 iter->scaled = g_object_ref (scaled);
188 iter->iter = gdk_pixbuf_animation_get_iter (scaled->anim, start_time);
190 return (GdkPixbufAnimationIter*)iter;
194 gdk_pixbuf_scaled_anim_class_init (GdkPixbufScaledAnimClass *klass)
196 GObjectClass *object_class;
197 GdkPixbufAnimationClass *anim_class;
199 object_class = G_OBJECT_CLASS (klass);
200 anim_class = GDK_PIXBUF_ANIMATION_CLASS (klass);
202 object_class->finalize = gdk_pixbuf_scaled_anim_finalize;
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;
211 G_DEFINE_TYPE (GdkPixbufScaledAnimIter, gdk_pixbuf_scaled_anim_iter, GDK_TYPE_PIXBUF_ANIMATION_ITER);
214 gdk_pixbuf_scaled_anim_iter_init (GdkPixbufScaledAnimIter *iter)
219 get_delay_time (GdkPixbufAnimationIter *iter)
221 GdkPixbufScaledAnimIter *scaled = (GdkPixbufScaledAnimIter *)iter;
224 delay = gdk_pixbuf_animation_iter_get_delay_time (scaled->iter);
225 delay = (int)(delay * scaled->scaled->tscale);
231 get_pixbuf (GdkPixbufAnimationIter *iter)
233 GdkPixbufScaledAnimIter *scaled = (GdkPixbufScaledAnimIter *)iter;
236 pixbuf = gdk_pixbuf_animation_iter_get_pixbuf (scaled->iter);
237 return get_scaled_pixbuf (scaled->scaled, pixbuf);
241 on_currently_loading_frame (GdkPixbufAnimationIter *iter)
243 GdkPixbufScaledAnimIter *scaled = (GdkPixbufScaledAnimIter *)iter;
245 return gdk_pixbuf_animation_iter_on_currently_loading_frame (scaled->iter);
249 advance (GdkPixbufAnimationIter *iter,
250 const GTimeVal *current_time)
252 GdkPixbufScaledAnimIter *scaled = (GdkPixbufScaledAnimIter *)iter;
254 return gdk_pixbuf_animation_iter_advance (scaled->iter, current_time);
258 gdk_pixbuf_scaled_anim_iter_finalize (GObject *object)
260 GdkPixbufScaledAnimIter *iter = (GdkPixbufScaledAnimIter *)object;
262 g_object_unref (iter->iter);
263 g_object_unref (iter->scaled);
265 G_OBJECT_CLASS (gdk_pixbuf_scaled_anim_iter_parent_class)->finalize (object);
269 gdk_pixbuf_scaled_anim_iter_class_init (GdkPixbufScaledAnimIterClass *klass)
271 GObjectClass *object_class;
272 GdkPixbufAnimationIterClass *anim_iter_class;
274 object_class = G_OBJECT_CLASS (klass);
275 anim_iter_class = GDK_PIXBUF_ANIMATION_ITER_CLASS (klass);
277 object_class->finalize = gdk_pixbuf_scaled_anim_iter_finalize;
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;
285 #define __GDK_PIXBUF_SCALED_ANIM_C__
286 #include "gdk-pixbuf-aliasdef.c"