Blame gdk-pixbuf/gdk-pixbuf-scaled-anim.c

Packit 979760
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
Packit 979760
/* GdkPixbuf library - Simple transformations of animations
Packit 979760
 *
Packit 979760
 * Copyright (C) Red Hat, Inc
Packit 979760
 *
Packit 979760
 * Authors: Matthias Clasen <mclasen@redhat.com>
Packit 979760
 *
Packit 979760
 * This library is free software; you can redistribute it and/or
Packit 979760
 * modify it under the terms of the GNU Lesser General Public
Packit 979760
 * License as published by the Free Software Foundation; either
Packit 979760
 * version 2 of the License, or (at your option) any later version.
Packit 979760
 *
Packit 979760
 * This library is distributed in the hope that it will be useful,
Packit 979760
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 979760
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 979760
 * Lesser General Public License for more details.
Packit 979760
 *
Packit 979760
 * You should have received a copy of the GNU Lesser General Public
Packit 979760
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
Packit 979760
 *
Packit 979760
 */
Packit 979760
Packit 979760
#include <glib.h>
Packit 979760
Packit 979760
#include "gdk-pixbuf.h"
Packit 979760
#include "gdk-pixbuf-io.h"
Packit 979760
#include "gdk-pixbuf-scaled-anim.h"
Packit 979760
Packit 979760
Packit 979760
struct _GdkPixbufScaledAnimClass
Packit 979760
{
Packit 979760
        GdkPixbufAnimationClass parent_class;
Packit 979760
};
Packit 979760
Packit 979760
struct _GdkPixbufScaledAnim
Packit 979760
{
Packit 979760
 	GdkPixbufAnimation parent_instance;
Packit 979760
Packit 979760
	GdkPixbufAnimation *anim;
Packit 979760
	gdouble xscale;
Packit 979760
	gdouble yscale;
Packit 979760
	gdouble tscale;
Packit 979760
Packit 979760
	GdkPixbuf *current;
Packit 979760
};
Packit 979760
Packit 979760
struct _GdkPixbufScaledAnimIterClass
Packit 979760
{
Packit 979760
        GdkPixbufAnimationClass parent_class;
Packit 979760
};
Packit 979760
Packit 979760
struct _GdkPixbufScaledAnimIter
Packit 979760
{
Packit 979760
 	GdkPixbufAnimationIter parent_instance;
Packit 979760
Packit 979760
	GdkPixbufScaledAnim *scaled;
Packit 979760
        GdkPixbufAnimationIter *iter;
Packit 979760
};
Packit 979760
Packit 979760
typedef struct _GdkPixbufScaledAnimIter GdkPixbufScaledAnimIter;
Packit 979760
typedef struct _GdkPixbufScaledAnimIterClass GdkPixbufScaledAnimIterClass;
Packit 979760
Packit 979760
GdkPixbufScaledAnim *
Packit 979760
_gdk_pixbuf_scaled_anim_new (GdkPixbufAnimation *anim,
Packit 979760
                             gdouble             xscale,
Packit 979760
                             gdouble             yscale,
Packit 979760
                             gdouble             tscale)
Packit 979760
{
Packit 979760
	GdkPixbufScaledAnim *scaled;
Packit 979760
Packit 979760
	scaled = g_object_new (GDK_TYPE_PIXBUF_SCALED_ANIM, NULL);
Packit 979760
Packit 979760
	scaled->anim = g_object_ref (anim);
Packit 979760
	scaled->xscale = xscale;
Packit 979760
	scaled->yscale = yscale;
Packit 979760
	scaled->tscale = tscale;
Packit 979760
Packit 979760
	return scaled;
Packit 979760
}
Packit 979760
Packit 979760
G_DEFINE_TYPE (GdkPixbufScaledAnim, gdk_pixbuf_scaled_anim, GDK_TYPE_PIXBUF_ANIMATION);
Packit 979760
Packit 979760
static void
Packit 979760
gdk_pixbuf_scaled_anim_init (GdkPixbufScaledAnim *scaled)
Packit 979760
{
Packit 979760
	scaled->xscale = 1.0;
Packit 979760
	scaled->yscale = 1.0;
Packit 979760
	scaled->tscale = 1.0;
Packit 979760
}
Packit 979760
Packit 979760
static void
Packit 979760
gdk_pixbuf_scaled_anim_finalize (GObject *object)
Packit 979760
{
Packit 979760
	GdkPixbufScaledAnim *scaled = (GdkPixbufScaledAnim *)object;
Packit 979760
Packit 979760
	if (scaled->anim) {
Packit 979760
		g_object_unref (scaled->anim);
Packit 979760
		scaled->anim = NULL;
Packit 979760
	}
Packit 979760
Packit 979760
	if (scaled->current) {
Packit 979760
		g_object_unref (scaled->current);
Packit 979760
		scaled->current = NULL;
Packit 979760
	}
Packit 979760
Packit 979760
	G_OBJECT_CLASS (gdk_pixbuf_scaled_anim_parent_class)->finalize (object);
Packit 979760
}
Packit 979760
Packit 979760
static gboolean
Packit 979760
is_static_image (GdkPixbufAnimation *anim)
Packit 979760
{
Packit 979760
	GdkPixbufScaledAnim *scaled = (GdkPixbufScaledAnim *)anim;
Packit 979760
Packit 979760
	return gdk_pixbuf_animation_is_static_image (scaled->anim);
Packit 979760
}	
Packit 979760
Packit 979760
static GdkPixbuf *
Packit 979760
get_scaled_pixbuf (GdkPixbufScaledAnim *scaled, 
Packit 979760
                   GdkPixbuf           *pixbuf)
Packit 979760
{
Packit 979760
	GQuark  quark;
Packit 979760
	gchar **options;
Packit 979760
Packit 979760
	if (scaled->current) 
Packit 979760
		g_object_unref (scaled->current);
Packit 979760
Packit 979760
	/* Preserve the options associated with the original pixbuf 
Packit 979760
	   (if present), mostly so that client programs can use the
Packit 979760
	   "orientation" option (if present) to rotate the image 
Packit 979760
	   appropriately. gdk_pixbuf_scale_simple (and most other
Packit 979760
           gdk transform operations) does not preserve the attached
Packit 979760
           options when returning a new pixbuf. */
Packit 979760
Packit 979760
	quark = g_quark_from_static_string ("gdk_pixbuf_options");
Packit 979760
	options = g_object_get_qdata (G_OBJECT (pixbuf), quark);
Packit 979760
Packit 979760
	/* Get a new scaled pixbuf */
Packit 979760
	scaled->current  = gdk_pixbuf_scale_simple (pixbuf, 
Packit 979760
                        MAX((int) ((gdouble) gdk_pixbuf_get_width (pixbuf) * scaled->xscale + .5), 1),
Packit 979760
                        MAX((int) ((gdouble) gdk_pixbuf_get_height (pixbuf) * scaled->yscale + .5), 1),
Packit 979760
			GDK_INTERP_BILINEAR);
Packit 979760
Packit 979760
	/* Copy the original pixbuf options to the scaled pixbuf */
Packit 979760
        if (options && scaled->current)
Packit 979760
	          g_object_set_qdata_full (G_OBJECT (scaled->current), quark, 
Packit 979760
                                           g_strdupv (options), (GDestroyNotify) g_strfreev);
Packit 979760
Packit 979760
	return scaled->current;
Packit 979760
}
Packit 979760
Packit 979760
static GdkPixbuf *
Packit 979760
get_static_image (GdkPixbufAnimation *anim)
Packit 979760
{
Packit 979760
	GdkPixbufScaledAnim *scaled = (GdkPixbufScaledAnim *)anim;
Packit 979760
	GdkPixbuf *pixbuf;
Packit 979760
	
Packit 979760
	pixbuf = gdk_pixbuf_animation_get_static_image (scaled->anim);
Packit 979760
	return get_scaled_pixbuf (scaled, pixbuf);
Packit 979760
}
Packit 979760
Packit 979760
static void
Packit 979760
get_size (GdkPixbufAnimation *anim,
Packit 979760
	  int                *width,
Packit 979760
	  int 		     *height)
Packit 979760
{
Packit 979760
	GdkPixbufScaledAnim *scaled = (GdkPixbufScaledAnim *)anim;
Packit 979760
Packit 979760
        GDK_PIXBUF_ANIMATION_GET_CLASS (scaled->anim)->get_size (scaled->anim, width, height);
Packit 979760
	if (width) 
Packit 979760
		*width = (int)(*width * scaled->xscale + .5);
Packit 979760
	if (height)
Packit 979760
		*height = (int)(*height * scaled->yscale + .5);
Packit 979760
}
Packit 979760
Packit 979760
static GdkPixbufAnimationIter *
Packit 979760
get_iter (GdkPixbufAnimation *anim,
Packit 979760
          const GTimeVal     *start_time)
Packit 979760
{
Packit 979760
	GdkPixbufScaledAnim *scaled = (GdkPixbufScaledAnim *)anim;
Packit 979760
	GdkPixbufScaledAnimIter *iter;
Packit 979760
Packit 979760
	iter = g_object_new (GDK_TYPE_PIXBUF_SCALED_ANIM_ITER, NULL);
Packit 979760
Packit 979760
	iter->scaled = g_object_ref (scaled);
Packit 979760
	iter->iter = gdk_pixbuf_animation_get_iter (scaled->anim, start_time);
Packit 979760
	
Packit 979760
	return (GdkPixbufAnimationIter*)iter;
Packit 979760
}
Packit 979760
Packit 979760
static void
Packit 979760
gdk_pixbuf_scaled_anim_class_init (GdkPixbufScaledAnimClass *klass)
Packit 979760
{
Packit 979760
        GObjectClass *object_class;
Packit 979760
        GdkPixbufAnimationClass *anim_class;
Packit 979760
Packit 979760
        object_class = G_OBJECT_CLASS (klass);
Packit 979760
        anim_class = GDK_PIXBUF_ANIMATION_CLASS (klass);
Packit 979760
        
Packit 979760
        object_class->finalize = gdk_pixbuf_scaled_anim_finalize;
Packit 979760
        
Packit 979760
        anim_class->is_static_image = is_static_image;
Packit 979760
        anim_class->get_static_image = get_static_image;
Packit 979760
        anim_class->get_size = get_size;
Packit 979760
        anim_class->get_iter = get_iter;
Packit 979760
}
Packit 979760
Packit 979760
Packit 979760
G_DEFINE_TYPE (GdkPixbufScaledAnimIter, gdk_pixbuf_scaled_anim_iter, GDK_TYPE_PIXBUF_ANIMATION_ITER);
Packit 979760
Packit 979760
static void
Packit 979760
gdk_pixbuf_scaled_anim_iter_init (GdkPixbufScaledAnimIter *iter)
Packit 979760
{
Packit 979760
}
Packit 979760
Packit 979760
static int
Packit 979760
get_delay_time (GdkPixbufAnimationIter *iter)
Packit 979760
{
Packit 979760
	GdkPixbufScaledAnimIter *scaled = (GdkPixbufScaledAnimIter *)iter;
Packit 979760
	int delay;
Packit 979760
Packit 979760
	delay = gdk_pixbuf_animation_iter_get_delay_time (scaled->iter);
Packit 979760
	delay = (int)(delay * scaled->scaled->tscale);
Packit 979760
Packit 979760
	return delay;
Packit 979760
}
Packit 979760
Packit 979760
static GdkPixbuf *
Packit 979760
get_pixbuf (GdkPixbufAnimationIter *iter)
Packit 979760
{
Packit 979760
	GdkPixbufScaledAnimIter *scaled = (GdkPixbufScaledAnimIter *)iter;
Packit 979760
	GdkPixbuf *pixbuf;
Packit 979760
Packit 979760
	pixbuf = gdk_pixbuf_animation_iter_get_pixbuf (scaled->iter);
Packit 979760
	return get_scaled_pixbuf (scaled->scaled, pixbuf);
Packit 979760
}
Packit 979760
Packit 979760
static gboolean 
Packit 979760
on_currently_loading_frame (GdkPixbufAnimationIter *iter)
Packit 979760
{
Packit 979760
	GdkPixbufScaledAnimIter *scaled = (GdkPixbufScaledAnimIter *)iter;
Packit 979760
Packit 979760
	return gdk_pixbuf_animation_iter_on_currently_loading_frame (scaled->iter);
Packit 979760
}
Packit 979760
Packit 979760
static gboolean
Packit 979760
advance (GdkPixbufAnimationIter *iter,
Packit 979760
	 const GTimeVal         *current_time)
Packit 979760
{
Packit 979760
	GdkPixbufScaledAnimIter *scaled = (GdkPixbufScaledAnimIter *)iter;
Packit 979760
Packit 979760
	return gdk_pixbuf_animation_iter_advance (scaled->iter, current_time);
Packit 979760
}
Packit 979760
Packit 979760
static void
Packit 979760
gdk_pixbuf_scaled_anim_iter_finalize (GObject *object)
Packit 979760
{
Packit 979760
        GdkPixbufScaledAnimIter *iter = (GdkPixbufScaledAnimIter *)object;
Packit 979760
        
Packit 979760
	g_object_unref (iter->iter);
Packit 979760
   	g_object_unref (iter->scaled);
Packit 979760
Packit 979760
	G_OBJECT_CLASS (gdk_pixbuf_scaled_anim_iter_parent_class)->finalize (object);
Packit 979760
}
Packit 979760
Packit 979760
static void
Packit 979760
gdk_pixbuf_scaled_anim_iter_class_init (GdkPixbufScaledAnimIterClass *klass)
Packit 979760
{
Packit 979760
        GObjectClass *object_class;
Packit 979760
        GdkPixbufAnimationIterClass *anim_iter_class;
Packit 979760
Packit 979760
        object_class = G_OBJECT_CLASS (klass);
Packit 979760
        anim_iter_class = GDK_PIXBUF_ANIMATION_ITER_CLASS (klass);
Packit 979760
        
Packit 979760
        object_class->finalize = gdk_pixbuf_scaled_anim_iter_finalize;
Packit 979760
        
Packit 979760
        anim_iter_class->get_delay_time = get_delay_time;
Packit 979760
        anim_iter_class->get_pixbuf = get_pixbuf;
Packit 979760
        anim_iter_class->on_currently_loading_frame = on_currently_loading_frame;
Packit 979760
        anim_iter_class->advance = advance;
Packit 979760
}