diff options
author | Matthias Clasen <mclasen@redhat.com> | 2005-05-25 19:33:35 +0000 |
---|---|---|
committer | Matthias Clasen <matthiasc@src.gnome.org> | 2005-05-25 19:33:35 +0000 |
commit | 734b31563b7b523a240b0aa48a8c60b95053389d (patch) | |
tree | 9ed30d0dab8be885282773cba7c2f0c5cfd8d0d0 /gdk-pixbuf | |
parent | c02454f9cfda48e041b55c679390d7c32d66483b (diff) | |
download | gdk-pixbuf-734b31563b7b523a240b0aa48a8c60b95053389d.tar.gz |
Add new files.
2005-05-25 Matthias Clasen <mclasen@redhat.com>
* Makefile.am: Add new files.
* gdk-pixbuf.symbols: Add new api.
* gdk-pixbuf.h: Include gdk-pixbuf-simple-anim.h here.
* gdk-pixbuf-simple-anim.[hc]: Add a way to construct
simple animations out of pixbufs. (#135161, Dom Lachowicz)
Diffstat (limited to 'gdk-pixbuf')
-rw-r--r-- | gdk-pixbuf/ChangeLog | 11 | ||||
-rw-r--r-- | gdk-pixbuf/Makefile.am | 22 | ||||
-rw-r--r-- | gdk-pixbuf/gdk-pixbuf-simple-anim.c | 427 | ||||
-rw-r--r-- | gdk-pixbuf/gdk-pixbuf-simple-anim.h | 66 | ||||
-rw-r--r-- | gdk-pixbuf/gdk-pixbuf.h | 1 | ||||
-rw-r--r-- | gdk-pixbuf/gdk-pixbuf.symbols | 9 |
6 files changed, 526 insertions, 10 deletions
diff --git a/gdk-pixbuf/ChangeLog b/gdk-pixbuf/ChangeLog index 05bcfb5cc..8685cbd68 100644 --- a/gdk-pixbuf/ChangeLog +++ b/gdk-pixbuf/ChangeLog @@ -1,3 +1,14 @@ +2005-05-25 Matthias Clasen <mclasen@redhat.com> + + * Makefile.am: Add new files. + + * gdk-pixbuf.symbols: Add new api. + + * gdk-pixbuf.h: Include gdk-pixbuf-simple-anim.h here. + + * gdk-pixbuf-simple-anim.[hc]: Add a way to construct + simple animations out of pixbufs. (#135161, Dom Lachowicz) + 2005-05-24 Sven Neumann <sven@gimp.org> * io-png.c: allow to specify the PNG compression level by passing diff --git a/gdk-pixbuf/Makefile.am b/gdk-pixbuf/Makefile.am index 3dccc1d2f..1d29d63ae 100644 --- a/gdk-pixbuf/Makefile.am +++ b/gdk-pixbuf/Makefile.am @@ -307,16 +307,17 @@ gdk_pixbuf_query_loaders_SOURCES = queryloaders.c # The GdkPixBuf library # libgdk_pixbufincludedir = $(includedir)/gtk-2.0/gdk-pixbuf -libgdk_pixbuf_2_0_la_SOURCES = \ - gdk-pixbuf-i18n.h \ - gdk-pixbuf.c \ - gdk-pixbuf-animation.c \ - gdk-pixbuf-data.c \ - gdk-pixbuf-io.c \ - gdk-pixbuf-loader.c \ - gdk-pixbuf-scale.c \ - gdk-pixbuf-util.c \ - gdk-pixdata.c \ +libgdk_pixbuf_2_0_la_SOURCES = \ + gdk-pixbuf-i18n.h \ + gdk-pixbuf.c \ + gdk-pixbuf-animation.c \ + gdk-pixbuf-data.c \ + gdk-pixbuf-io.c \ + gdk-pixbuf-loader.c \ + gdk-pixbuf-scale.c \ + gdk-pixbuf-simple-anim.c \ + gdk-pixbuf-util.c \ + gdk-pixdata.c \ gdk-pixbuf-enum-types.c libgdk_pixbuf_2_0_la_LDFLAGS = \ @@ -335,6 +336,7 @@ gdk_pixbuf_headers = \ gdk-pixbuf-transform.h \ gdk-pixbuf-io.h \ gdk-pixbuf-animation.h \ + gdk-pixbuf-simple-anim.h \ gdk-pixbuf-loader.h libgdk_pixbufinclude_HEADERS = \ diff --git a/gdk-pixbuf/gdk-pixbuf-simple-anim.c b/gdk-pixbuf/gdk-pixbuf-simple-anim.c new file mode 100644 index 000000000..82d908fc8 --- /dev/null +++ b/gdk-pixbuf/gdk-pixbuf-simple-anim.c @@ -0,0 +1,427 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ +/* GdkPixbuf library - Simple frame-based animations + * + * Copyright (C) Dom Lachowicz + * + * Authors: Dom Lachowicz <cinamod@hotmail.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Based on code originally by: + * Jonathan Blandford <jrb@redhat.com> + * Havoc Pennington <hp@redhat.com> + */ + +#include <glib.h> + +#include "gdk-pixbuf.h" +#include "gdk-pixbuf-io.h" +#include "gdk-pixbuf-simple-anim.h" +#include "gdk-pixbuf-alias.h" + +struct _GdkPixbufSimpleAnimClass +{ + GdkPixbufAnimationClass parent_class; +}; + +/* Private part of the GdkPixbufSimpleAnim structure */ +struct _GdkPixbufSimpleAnim +{ + GdkPixbufAnimation parent_instance; + + gint n_frames; + + gfloat rate; + gint total_time; + + GList *frames; + + gint width; + gint height; + + gboolean loop; +}; + +struct _GdkPixbufSimpleAnimIterClass +{ + GdkPixbufAnimationIterClass parent_class; +}; + +struct _GdkPixbufSimpleAnimIter +{ + GdkPixbufAnimationIter parent_instance; + + GdkPixbufSimpleAnim *simple_anim; + + GTimeVal start_time; + GTimeVal current_time; + + gint position; + + GList *current_frame; +}; + +typedef struct _GdkPixbufFrame GdkPixbufFrame; +struct _GdkPixbufFrame +{ + GdkPixbuf *pixbuf; + gint delay_time; + gint elapsed; +}; + +static void gdk_pixbuf_simple_anim_finalize (GObject *object); + +static gboolean is_static_image (GdkPixbufAnimation *animation); +static GdkPixbuf *get_static_image (GdkPixbufAnimation *animation); + +static void get_size (GdkPixbufAnimation *anim, + gint *width, + gint *height); +static GdkPixbufAnimationIter *get_iter (GdkPixbufAnimation *anim, + const GTimeVal *start_time); + + +G_DEFINE_TYPE(GdkPixbufSimpleAnim, gdk_pixbuf_simple_anim, GDK_TYPE_PIXBUF_ANIMATION); + +static void +gdk_pixbuf_simple_anim_init (GdkPixbufSimpleAnim *anim) +{ +} + +static void +gdk_pixbuf_simple_anim_class_init (GdkPixbufSimpleAnimClass *klass) +{ + GObjectClass *object_class; + GdkPixbufAnimationClass *anim_class; + + object_class = G_OBJECT_CLASS (klass); + anim_class = GDK_PIXBUF_ANIMATION_CLASS (klass); + + object_class->finalize = gdk_pixbuf_simple_anim_finalize; + + anim_class->is_static_image = is_static_image; + anim_class->get_static_image = get_static_image; + anim_class->get_size = get_size; + anim_class->get_iter = get_iter; +} + +static void +gdk_pixbuf_simple_anim_finalize (GObject *object) +{ + GdkPixbufSimpleAnim *anim; + GList *l; + GdkPixbufFrame *frame; + + anim = GDK_PIXBUF_SIMPLE_ANIM (object); + + for (l = anim->frames; l; l = l->next) { + frame = l->data; + g_object_unref (frame->pixbuf); + g_free (frame); + } + + g_list_free (anim->frames); + + G_OBJECT_CLASS (gdk_pixbuf_simple_anim_parent_class)->finalize (object); +} + +static gboolean +is_static_image (GdkPixbufAnimation *animation) +{ + GdkPixbufSimpleAnim *anim; + + anim = GDK_PIXBUF_SIMPLE_ANIM (animation); + + return (anim->frames != NULL && anim->frames->next == NULL); +} + +static GdkPixbuf * +get_static_image (GdkPixbufAnimation *animation) +{ + GdkPixbufSimpleAnim *anim; + + anim = GDK_PIXBUF_SIMPLE_ANIM (animation); + + if (anim->frames == NULL) + return NULL; + else + return ((GdkPixbufFrame *)anim->frames->data)->pixbuf; +} + +static void +get_size (GdkPixbufAnimation *animation, + gint *width, + gint *height) +{ + GdkPixbufSimpleAnim *anim; + + anim = GDK_PIXBUF_SIMPLE_ANIM (animation); + + if (width) + *width = anim->width; + + if (height) + *height = anim->height; +} + +static void +iter_clear (GdkPixbufSimpleAnimIter *iter) +{ + iter->current_frame = NULL; +} + +static void +iter_restart (GdkPixbufSimpleAnimIter *iter) +{ + iter_clear (iter); + + iter->current_frame = iter->simple_anim->frames; +} + +static GdkPixbufAnimationIter * +get_iter (GdkPixbufAnimation *anim, + const GTimeVal *start_time) +{ + GdkPixbufSimpleAnimIter *iter; + + iter = g_object_new (GDK_TYPE_PIXBUF_SIMPLE_ANIM_ITER, NULL); + + iter->simple_anim = GDK_PIXBUF_SIMPLE_ANIM (anim); + + g_object_ref (iter->simple_anim); + + iter_restart (iter); + + iter->start_time = *start_time; + iter->current_time = *start_time; + + return GDK_PIXBUF_ANIMATION_ITER (iter); +} + +static void gdk_pixbuf_simple_anim_iter_finalize (GObject *object); + +static gint get_delay_time (GdkPixbufAnimationIter *iter); +static GdkPixbuf *get_pixbuf (GdkPixbufAnimationIter *iter); +static gboolean on_currently_loading_frame (GdkPixbufAnimationIter *iter); +static gboolean advance (GdkPixbufAnimationIter *iter, + const GTimeVal *current_time); + +G_DEFINE_TYPE (GdkPixbufSimpleAnimIter, gdk_pixbuf_simple_anim_iter, GDK_TYPE_PIXBUF_ANIMATION_ITER); + +static void +gdk_pixbuf_simple_anim_iter_init (GdkPixbufSimpleAnimIter *iter) +{ +} + +static void +gdk_pixbuf_simple_anim_iter_class_init (GdkPixbufSimpleAnimIterClass *klass) +{ + GObjectClass *object_class; + GdkPixbufAnimationIterClass *anim_iter_class; + + object_class = G_OBJECT_CLASS (klass); + anim_iter_class = GDK_PIXBUF_ANIMATION_ITER_CLASS (klass); + + object_class->finalize = gdk_pixbuf_simple_anim_iter_finalize; + + anim_iter_class->get_delay_time = get_delay_time; + anim_iter_class->get_pixbuf = get_pixbuf; + anim_iter_class->on_currently_loading_frame = on_currently_loading_frame; + anim_iter_class->advance = advance; +} + +static void +gdk_pixbuf_simple_anim_iter_finalize (GObject *object) +{ + GdkPixbufSimpleAnimIter *iter; + + iter = GDK_PIXBUF_SIMPLE_ANIM_ITER (object); + iter_clear (iter); + + g_object_unref (iter->simple_anim); + + G_OBJECT_CLASS (gdk_pixbuf_simple_anim_iter_parent_class)->finalize (object); +} + +static gboolean +advance (GdkPixbufAnimationIter *anim_iter, + const GTimeVal *current_time) +{ + GdkPixbufSimpleAnimIter *iter; + gint elapsed; + gint loop; + GList *tmp; + GList *old; + + iter = GDK_PIXBUF_SIMPLE_ANIM_ITER (anim_iter); + + iter->current_time = *current_time; + + /* We use milliseconds for all times */ + elapsed = (((iter->current_time.tv_sec - iter->start_time.tv_sec) * G_USEC_PER_SEC + + iter->current_time.tv_usec - iter->start_time.tv_usec)) / 1000; + + if (elapsed < 0) { + /* Try to compensate; probably the system clock + * was set backwards + */ + iter->start_time = iter->current_time; + elapsed = 0; + } + + g_assert (iter->simple_anim->total_time > 0); + + /* See how many times we've already played the full animation, + * and subtract time for that. + */ + loop = elapsed / iter->simple_anim->total_time; + elapsed = elapsed % iter->simple_anim->total_time; + + iter->position = elapsed; + + /* Now move to the proper frame */ + if (loop < 1) + tmp = iter->simple_anim->frames; + else + tmp = NULL; + + while (tmp != NULL) { + GdkPixbufFrame *frame = tmp->data; + + if (iter->position >= frame->elapsed && + iter->position < (frame->elapsed + frame->delay_time)) + break; + + tmp = tmp->next; + } + + old = iter->current_frame; + + iter->current_frame = tmp; + + return iter->current_frame != old; +} + +static gint +get_delay_time (GdkPixbufAnimationIter *anim_iter) +{ + GdkPixbufFrame *frame; + GdkPixbufSimpleAnimIter *iter; + + iter = GDK_PIXBUF_SIMPLE_ANIM_ITER (anim_iter); + + if (iter->current_frame) { + frame = iter->current_frame->data; + return frame->delay_time - (iter->position - frame->elapsed); + } + else { + return -1; /* show last frame forever */ + } +} + +static GdkPixbuf * +get_pixbuf (GdkPixbufAnimationIter *anim_iter) +{ + GdkPixbufSimpleAnimIter *iter; + GdkPixbufFrame *frame; + + iter = GDK_PIXBUF_SIMPLE_ANIM_ITER (anim_iter); + + if (iter->current_frame) + frame = iter->current_frame->data; + else if (g_list_length (iter->simple_anim->frames) > 0) + frame = g_list_last (iter->simple_anim->frames)->data; + else + frame = NULL; + + if (frame == NULL) + return NULL; + + return frame->pixbuf; +} + +static gboolean +on_currently_loading_frame (GdkPixbufAnimationIter *anim_iter) +{ + GdkPixbufSimpleAnimIter *iter; + + iter = GDK_PIXBUF_SIMPLE_ANIM_ITER (anim_iter); + + return iter->current_frame == NULL || iter->current_frame->next == NULL; +} + +/** + * gdk_pixbuf_simple_anim_new: + * @width: the width of the animation + * @height: the height of the animation + * @rate: the speed of the animation, in frames per second + * + * Creates a new, empty animation. + * + * Returns: a newly allocated #GdkPixbufSimpleAnim + * + * Since: 2.8 + */ +GdkPixbufSimpleAnim * +gdk_pixbuf_simple_anim_new (gint width, + gint height, + gfloat rate) +{ + GdkPixbufSimpleAnim *anim; + + anim = g_object_new (GDK_TYPE_PIXBUF_SIMPLE_ANIM, NULL); + anim->width = width; + anim->height = height; + anim->rate = rate; + + return anim; +} + +/** + * gdk_pixbuf_simple_anim_add_frame: + * @animation: a #GdkPixbufSimpleAnim + * @pixbuf: the pixbuf to add + * + * Adds a new frame to @animation. The @pixbuf must + * have the dimensions specified when the animation + * was constructed. + * + * Since: 2.8 + */ +void +gdk_pixbuf_simple_anim_add_frame (GdkPixbufSimpleAnim *animation, + GdkPixbuf *pixbuf) +{ + GdkPixbufFrame *frame; + int nframe = 0; + + g_return_if_fail (animation != NULL); + g_return_if_fail (pixbuf != NULL); + + nframe = g_list_length (animation->frames) + 1; + + frame = g_new0 (GdkPixbufFrame, 1); + frame->delay_time = (gint) (1000 / animation->rate); + frame->elapsed = (gint) (frame->delay_time * nframe); + animation->total_time += frame->delay_time; + frame->pixbuf = GDK_PIXBUF (g_object_ref (pixbuf)); + + animation->frames = g_list_append (animation->frames, frame); +} + + +#define __GDK_PIXBUF_SIMPLE_ANIM_C__ +#include "gdk-pixbuf-aliasdef.c" diff --git a/gdk-pixbuf/gdk-pixbuf-simple-anim.h b/gdk-pixbuf/gdk-pixbuf-simple-anim.h new file mode 100644 index 000000000..bdb2cba11 --- /dev/null +++ b/gdk-pixbuf/gdk-pixbuf-simple-anim.h @@ -0,0 +1,66 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ +/* GdkPixbuf library - Simple frame-based animations + * + * Copyright (C) 2004 Dom Lachowicz + * + * Authors: Dom Lachowicz <cinamod@hotmail.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef GDK_PIXBUF_SIMPLE_ANIM_H +#define GDK_PIXBUF_SIMPLE_ANIM_H + +#include <gdk-pixbuf/gdk-pixbuf-animation.h> + +G_BEGIN_DECLS + +typedef struct _GdkPixbufSimpleAnim GdkPixbufSimpleAnim; +typedef struct _GdkPixbufSimpleAnimClass GdkPixbufSimpleAnimClass; + +#define GDK_TYPE_PIXBUF_SIMPLE_ANIM (gdk_pixbuf_simple_anim_get_type ()) +#define GDK_PIXBUF_SIMPLE_ANIM(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_PIXBUF_SIMPLE_ANIM, GdkPixbufSimpleAnim)) +#define GDK_IS_PIXBUF_SIMPLE_ANIM(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_PIXBUF_SIMPLE_ANIM)) + +#define GDK_PIXBUF_SIMPLE_ANIM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_PIXBUF_SIMPLE_ANIM, GdkPixbufSimpleAnimClass)) +#define GDK_IS_PIXBUF_SIMPLE_ANIM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_PIXBUF_SIMPLE_ANIM)) +#define GDK_PIXBUF_SIMPLE_ANIM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_PIXBUF_SIMPLE_ANIM, GdkPixbufSimpleAnimClass)) + +GType gdk_pixbuf_simple_anim_get_type (void) G_GNUC_CONST; + +typedef struct _GdkPixbufSimpleAnimIter GdkPixbufSimpleAnimIter; +typedef struct _GdkPixbufSimpleAnimIterClass GdkPixbufSimpleAnimIterClass; + +#define GDK_TYPE_PIXBUF_SIMPLE_ANIM_ITER (gdk_pixbuf_simple_anim_iter_get_type ()) +#define GDK_PIXBUF_SIMPLE_ANIM_ITER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_PIXBUF_SIMPLE_ANIM_ITER, GdkPixbufSimpleAnimIter)) +#define GDK_IS_PIXBUF_SIMPLE_ANIM_ITER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_PIXBUF_SIMPLE_ANIM_ITER)) + +#define GDK_PIXBUF_SIMPLE_ANIM_ITER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_PIXBUF_SIMPLE_ANIM_ITER, GdkPixbufSimpleAnimIterClass)) +#define GDK_IS_PIXBUF_SIMPLE_ANIM_ITER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_PIXBUF_SIMPLE_ANIM_ITER)) +#define GDK_PIXBUF_SIMPLE_ANIM_ITER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_PIXBUF_SIMPLE_ANIM_ITER, GdkPixbufSimpleAnimIterClass)) + +GType gdk_pixbuf_simple_anim_iter_get_type (void) G_GNUC_CONST; + +GdkPixbufSimpleAnim *gdk_pixbuf_simple_anim_new (gint width, + gint height, + gfloat rate); +void gdk_pixbuf_simple_anim_add_frame (GdkPixbufSimpleAnim *animation, + GdkPixbuf *pixbuf); + +G_END_DECLS + + +#endif /* GDK_PIXBUF_SIMPLE_ANIM_H */ diff --git a/gdk-pixbuf/gdk-pixbuf.h b/gdk-pixbuf/gdk-pixbuf.h index 5827db61b..0d77b2bfd 100644 --- a/gdk-pixbuf/gdk-pixbuf.h +++ b/gdk-pixbuf/gdk-pixbuf.h @@ -33,6 +33,7 @@ #include <gdk-pixbuf/gdk-pixbuf-core.h> #include <gdk-pixbuf/gdk-pixbuf-transform.h> #include <gdk-pixbuf/gdk-pixbuf-animation.h> +#include <gdk-pixbuf/gdk-pixbuf-simple-anim.h> #include <gdk-pixbuf/gdk-pixbuf-io.h> #include <gdk-pixbuf/gdk-pixbuf-loader.h> #include <gdk-pixbuf/gdk-pixbuf-enum-types.h> diff --git a/gdk-pixbuf/gdk-pixbuf.symbols b/gdk-pixbuf/gdk-pixbuf.symbols index 949757cbe..457c95edd 100644 --- a/gdk-pixbuf/gdk-pixbuf.symbols +++ b/gdk-pixbuf/gdk-pixbuf.symbols @@ -122,6 +122,15 @@ gdk_pixbuf_non_anim_new #endif #endif +#if IN_HEADER(GDK_PIXBUF_SIMPLE_ANIM_H) +#if IN_FILE(__GDK_PIXBUF_SIMPLE_ANIM_C__) +gdk_pixbuf_simple_anim_get_type G_GNUC_CONST +gdk_pixbuf_simple_anim_new +gdk_pixbuf_simple_anim_add_frame +gdk_pixbuf_simple_anim_iter_get_type G_GNUC_CONST +#endif +#endif + #if IN_HEADER(GDK_PIXBUF_IO_H) #if IN_FILE(__GDK_PIXBUF_IO_C__) gdk_pixbuf_get_formats |