[Swfdec-commits] 20 commits - configure.ac swfdec-gtk/swfdec_gtk_widget.c swfdec/Makefile.am swfdec/swfdec_actor.c swfdec/swfdec_cache.c swfdec/swfdec_cached.c swfdec/swfdec_cached.h swfdec/swfdec_cached_image.c swfdec/swfdec_cached_image.h swfdec/swfdec_cache.h swfdec/swfdec_gradient_pattern.c swfdec/swfdec.h swfdec/swfdec_image.c swfdec/swfdec_image_decoder.c swfdec/swfdec_image.h swfdec/swfdec_movie.c swfdec/swfdec_pattern.c swfdec/swfdec_pattern.h swfdec/swfdec_player.c swfdec/swfdec_player.h swfdec/swfdec_player_internal.h swfdec/swfdec_renderer.c swfdec/swfdec_renderer.h swfdec/swfdec_renderer_internal.h swfdec/swfdec_sound.c swfdec/swfdec_sound.h swfdec/swfdec_stroke.c swfdec/swfdec_swf_decoder.c swfdec/swfdec_text_field_movie.c swfdec/swfdec_text_field_movie.h swfdec/swfdec_types.h tools/dump.c tools/swfdec-extract.c
Benjamin Otte
company at kemper.freedesktop.org
Tue Apr 8 11:01:40 PDT 2008
configure.ac | 2
swfdec-gtk/swfdec_gtk_widget.c | 56 ++++-
swfdec/Makefile.am | 4
swfdec/swfdec.h | 1
swfdec/swfdec_actor.c | 14 +
swfdec/swfdec_cache.c | 245 ++++++++++++++----------
swfdec/swfdec_cache.h | 61 +++---
swfdec/swfdec_cached.c | 124 ++++++------
swfdec/swfdec_cached.h | 26 +-
swfdec/swfdec_cached_image.c | 98 +++++++++
swfdec/swfdec_cached_image.h | 67 ++++++
swfdec/swfdec_gradient_pattern.c | 3
swfdec/swfdec_image.c | 281 +++++++++++++++++----------
swfdec/swfdec_image.h | 15 -
swfdec/swfdec_image_decoder.c | 2
swfdec/swfdec_movie.c | 4
swfdec/swfdec_pattern.c | 20 +
swfdec/swfdec_pattern.h | 2
swfdec/swfdec_player.c | 100 +++++++++
swfdec/swfdec_player.h | 23 +-
swfdec/swfdec_player_internal.h | 2
swfdec/swfdec_renderer.c | 386 ++++++++++++++++++++++++++++++++++++++
swfdec/swfdec_renderer.h | 70 ++++++
swfdec/swfdec_renderer_internal.h | 55 +++++
swfdec/swfdec_sound.c | 20 -
swfdec/swfdec_sound.h | 6
swfdec/swfdec_stroke.c | 4
swfdec/swfdec_swf_decoder.c | 3
swfdec/swfdec_text_field_movie.c | 68 +++---
swfdec/swfdec_text_field_movie.h | 6
swfdec/swfdec_types.h | 2
tools/dump.c | 2
tools/swfdec-extract.c | 2
33 files changed, 1362 insertions(+), 412 deletions(-)
New commits:
commit 07c175aa23267639cd4093a2be120eaa9ecdb047
Merge: df9b708... bc28022...
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Apr 8 19:49:23 2008 +0200
Merge branch 'cache'
commit df9b7083c6a9665a5f8f4f7df5c41ad860d29f43
Merge: d46085e... f07cf46...
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Apr 8 19:47:29 2008 +0200
Merge branch 'master' of ssh://company@git.freedesktop.org/git/swfdec/swfdec
commit bc2802229f625b0e34c1471b16e7139ac407c2ad
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Apr 8 19:46:47 2008 +0200
update tools to API changes
diff --git a/tools/dump.c b/tools/dump.c
index 1b8d701..c6c1da3 100644
--- a/tools/dump.c
+++ b/tools/dump.c
@@ -316,7 +316,7 @@ get_image_type_name (SwfdecImageType type)
static void
dump_image (SwfdecImage *image)
{
- cairo_surface_destroy (swfdec_image_create_surface (image));
+ cairo_surface_destroy (swfdec_image_create_surface (image, NULL));
g_print (" %s %u x %u\n", get_image_type_name (image->type),
image->width, image->height);
}
diff --git a/tools/swfdec-extract.c b/tools/swfdec-extract.c
index 1e57034..ebcba2c 100644
--- a/tools/swfdec-extract.c
+++ b/tools/swfdec-extract.c
@@ -228,7 +228,7 @@ export_graphic (SwfdecGraphic *graphic, const char *filename)
static gboolean
export_image (SwfdecImage *image, const char *filename)
{
- cairo_surface_t *surface = swfdec_image_create_surface (image);
+ cairo_surface_t *surface = swfdec_image_create_surface (image, NULL);
if (surface == NULL)
return FALSE;
commit 2542db0bdcd2dba742fca023c9af48b29329d139
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Apr 8 19:46:32 2008 +0200
implement transformed surfaces without crashing
diff --git a/swfdec/swfdec_image.c b/swfdec/swfdec_image.c
index 005d23d..ccf43d1 100644
--- a/swfdec/swfdec_image.c
+++ b/swfdec/swfdec_image.c
@@ -705,8 +705,10 @@ swfdec_image_create_surface_transformed (SwfdecImage *image, SwfdecRenderer *ren
source = swfdec_image_lookup_surface (image, renderer, &mask);
if (source == NULL) {
source = swfdec_image_create_surface (image, NULL);
+ if (source == NULL)
+ return NULL;
if (renderer) {
- cached = swfdec_cached_image_new (surface, image->width * image->height * 4);
+ cached = swfdec_cached_image_new (source, image->width * image->height * 4);
swfdec_cached_image_set_color_transform (cached, &mask);
swfdec_renderer_add_cache (renderer, image, SWFDEC_CACHED (cached));
g_object_unref (cached);
commit 5a27f9bfb76eb05b7e4d787e7e2324da118a1b51
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Apr 8 19:24:55 2008 +0200
we require glib 2.16 now
diff --git a/configure.ac b/configure.ac
index a5bb805..4da21cf 100644
--- a/configure.ac
+++ b/configure.ac
@@ -92,7 +92,7 @@ AC_ARG_WITH(pkg-config-path,
dnl Check for essential libraries first:
dnl ====================================
-GLIB_VER=2.12
+GLIB_VER=2.16
PKG_CHECK_MODULES(GLIB, glib-2.0 >= $GLIB_VER gobject-2.0 >= $GLIB_VER gthread-2.0 >= $GLIB_VER,
HAVE_GLIB=yes, HAVE_GLIB=no)
if test "$HAVE_GLIB" = "no"; then
commit fb42d401651aa07bc2755ae814f9f6b64ee92a3f
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Apr 8 15:19:21 2008 +0200
use a proper SwfdecRenderer here
diff --git a/swfdec-gtk/swfdec_gtk_widget.c b/swfdec-gtk/swfdec_gtk_widget.c
index 7b96da6..5830681 100644
--- a/swfdec-gtk/swfdec_gtk_widget.c
+++ b/swfdec-gtk/swfdec_gtk_widget.c
@@ -33,6 +33,7 @@ struct _SwfdecGtkWidgetPrivate
gboolean renderer_set; /* TRUE if a special renderer has been set */
cairo_surface_type_t renderer_type; /* the renderer that was set */
gboolean interactive; /* TRUE if this widget propagates keyboard and mouse events */
+ SwfdecRenderer * renderer; /* renderer in use */
};
enum {
@@ -316,6 +317,8 @@ swfdec_gtk_widget_dispose (GObject *object)
swfdec_gtk_widget_set_player (widget, NULL);
+ g_assert (widget->priv->renderer == NULL);
+
G_OBJECT_CLASS (swfdec_gtk_widget_parent_class)->dispose (object);
}
@@ -407,6 +410,32 @@ swfdec_gtk_widget_update_cursor (SwfdecGtkWidget *widget)
}
static void
+swfdec_gtk_widget_update_renderer (SwfdecGtkWidget *widget)
+{
+ SwfdecGtkWidgetPrivate *priv = widget->priv;
+ gboolean needs_renderer;
+
+ needs_renderer = GTK_WIDGET_REALIZED (widget) &&
+ priv->player != NULL;
+
+ if (priv->renderer != NULL) {
+ swfdec_player_set_renderer (priv->player, NULL);
+ g_object_unref (priv->renderer);
+ priv->renderer = NULL;
+ }
+ if (needs_renderer) {
+ cairo_t *cr = gdk_cairo_create (GTK_WIDGET (widget)->window);
+
+ if (priv->renderer_set)
+ g_printerr ("FIXME: create the right renderer\n");
+ priv->renderer = swfdec_renderer_new_for_player (
+ cairo_get_target (cr), priv->player);
+ swfdec_player_set_renderer (priv->player, priv->renderer);
+ cairo_destroy (cr);
+ }
+}
+
+static void
swfdec_gtk_widget_realize (GtkWidget *widget)
{
GdkWindowAttr attributes;
@@ -442,6 +471,15 @@ swfdec_gtk_widget_realize (GtkWidget *widget)
if (SWFDEC_GTK_WIDGET (widget)->priv->player) {
swfdec_gtk_widget_update_cursor (SWFDEC_GTK_WIDGET (widget));
}
+ swfdec_gtk_widget_update_renderer (SWFDEC_GTK_WIDGET (widget));
+}
+
+static void
+swfdec_gtk_widget_unrealize (GtkWidget *widget)
+{
+ GTK_WIDGET_CLASS (swfdec_gtk_widget_parent_class)->unrealize (widget);
+
+ swfdec_gtk_widget_update_renderer (SWFDEC_GTK_WIDGET (widget));
}
static void
@@ -469,6 +507,7 @@ swfdec_gtk_widget_class_init (SwfdecGtkWidgetClass * g_class)
0, G_MAXUINT, CAIRO_SURFACE_TYPE_IMAGE, G_PARAM_READWRITE));
widget_class->realize = swfdec_gtk_widget_realize;
+ widget_class->unrealize = swfdec_gtk_widget_unrealize;
widget_class->size_request = swfdec_gtk_widget_size_request;
widget_class->size_allocate = swfdec_gtk_widget_size_allocate;
widget_class->expose_event = swfdec_gtk_widget_expose;
@@ -561,6 +600,7 @@ swfdec_gtk_widget_set_player (SwfdecGtkWidget *widget, SwfdecPlayer *player)
priv->player = player;
gtk_widget_queue_resize (GTK_WIDGET (widget));
g_object_notify (G_OBJECT (widget), "player");
+ swfdec_gtk_widget_update_renderer (widget);
}
/**
@@ -655,6 +695,7 @@ swfdec_gtk_widget_set_renderer (SwfdecGtkWidget *widget, cairo_surface_type_t re
g_object_notify (G_OBJECT (widget), "renderer-set");
}
g_object_notify (G_OBJECT (widget), "renderer");
+ swfdec_gtk_widget_update_renderer (widget);
}
/**
@@ -673,6 +714,7 @@ swfdec_gtk_widget_unset_renderer (SwfdecGtkWidget *widget)
return;
widget->priv->renderer_set = FALSE;
g_object_notify (G_OBJECT (widget), "renderer-set");
+ swfdec_gtk_widget_update_renderer (widget);
}
/**
commit fc0a5d065b069030821981138125eb16f95b910e
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Apr 8 15:02:37 2008 +0200
rename renderer member to renderer_type
diff --git a/swfdec-gtk/swfdec_gtk_widget.c b/swfdec-gtk/swfdec_gtk_widget.c
index f0c47b6..7b96da6 100644
--- a/swfdec-gtk/swfdec_gtk_widget.c
+++ b/swfdec-gtk/swfdec_gtk_widget.c
@@ -31,7 +31,7 @@ struct _SwfdecGtkWidgetPrivate
SwfdecPlayer * player; /* the video we play */
gboolean renderer_set; /* TRUE if a special renderer has been set */
- cairo_surface_type_t renderer; /* the renderer that was set */
+ cairo_surface_type_t renderer_type; /* the renderer that was set */
gboolean interactive; /* TRUE if this widget propagates keyboard and mouse events */
};
@@ -231,7 +231,7 @@ swfdec_gtk_widget_expose (GtkWidget *gtkwidget, GdkEventExpose *event)
return FALSE;
if (!priv->renderer_set ||
- (surface = swfdec_gtk_widget_create_renderer (priv->renderer,
+ (surface = swfdec_gtk_widget_create_renderer (priv->renderer_type,
event->area.width, event->area.height)) == NULL) {
cr = gdk_cairo_create (gtkwidget->window);
} else {
@@ -272,7 +272,7 @@ swfdec_gtk_widget_get_property (GObject *object, guint param_id, GValue *value,
g_value_set_boolean (value, priv->renderer_set);
break;
case PROP_RENDERER:
- g_value_set_uint (value, priv->renderer);
+ g_value_set_uint (value, priv->renderer_type);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
@@ -299,7 +299,7 @@ swfdec_gtk_widget_set_property (GObject *object, guint param_id, const GValue *v
gtk_widget_queue_draw (GTK_WIDGET (widget));
break;
case PROP_RENDERER:
- priv->renderer = g_value_get_uint (value);
+ priv->renderer_type = g_value_get_uint (value);
if (priv->renderer_set)
gtk_widget_queue_draw (GTK_WIDGET (widget));
break;
@@ -493,7 +493,7 @@ swfdec_gtk_widget_init (SwfdecGtkWidget * widget)
priv = widget->priv = G_TYPE_INSTANCE_GET_PRIVATE (widget, SWFDEC_TYPE_GTK_WIDGET, SwfdecGtkWidgetPrivate);
priv->interactive = TRUE;
- priv->renderer = CAIRO_SURFACE_TYPE_IMAGE;
+ priv->renderer_type = CAIRO_SURFACE_TYPE_IMAGE;
GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS);
}
@@ -649,7 +649,7 @@ swfdec_gtk_widget_set_renderer (SwfdecGtkWidget *widget, cairo_surface_type_t re
{
g_return_if_fail (SWFDEC_IS_GTK_WIDGET (widget));
- widget->priv->renderer = renderer;
+ widget->priv->renderer_type = renderer;
if (widget->priv->renderer_set == FALSE) {
widget->priv->renderer_set = TRUE;
g_object_notify (G_OBJECT (widget), "renderer-set");
@@ -690,7 +690,7 @@ swfdec_gtk_widget_get_renderer (SwfdecGtkWidget *widget)
{
g_return_val_if_fail (SWFDEC_IS_GTK_WIDGET (widget), CAIRO_SURFACE_TYPE_IMAGE);
- return widget->priv->renderer;
+ return widget->priv->renderer_type;
}
/**
commit 07959353bac5b375cbcf9f06eaeee4a395e5eeff
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Apr 8 14:59:33 2008 +0200
make SwfdecPatternClass.get_pattern require a renderer argument
diff --git a/swfdec/swfdec_gradient_pattern.c b/swfdec/swfdec_gradient_pattern.c
index 2f63634..da4661a 100644
--- a/swfdec/swfdec_gradient_pattern.c
+++ b/swfdec/swfdec_gradient_pattern.c
@@ -54,7 +54,8 @@ swfdec_gradient_pattern_morph (SwfdecDraw *dest, SwfdecDraw *source, guint ratio
}
static cairo_pattern_t *
-swfdec_gradient_pattern_get_pattern (SwfdecPattern *pat, const SwfdecColorTransform *trans)
+swfdec_gradient_pattern_get_pattern (SwfdecPattern *pat, SwfdecRenderer *renderer,
+ const SwfdecColorTransform *trans)
{
guint i, ratio;
cairo_pattern_t *pattern;
diff --git a/swfdec/swfdec_pattern.c b/swfdec/swfdec_pattern.c
index 70a3292..b642293 100644
--- a/swfdec/swfdec_pattern.c
+++ b/swfdec/swfdec_pattern.c
@@ -31,6 +31,7 @@
#include "swfdec_gradient_pattern.h"
#include "swfdec_image.h"
#include "swfdec_path.h"
+#include "swfdec_renderer_internal.h"
#include "swfdec_stroke.h"
/*** PATTERN ***/
@@ -48,7 +49,8 @@ swfdec_pattern_paint (SwfdecDraw *draw, cairo_t *cr, const SwfdecColorTransform
{
cairo_pattern_t *pattern;
- pattern = swfdec_pattern_get_pattern (SWFDEC_PATTERN (draw), trans);
+ pattern = swfdec_pattern_get_pattern (SWFDEC_PATTERN (draw), swfdec_renderer_get (cr),
+ trans);
if (pattern == NULL)
return;
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
@@ -143,7 +145,8 @@ swfdec_color_pattern_morph (SwfdecDraw *dest, SwfdecDraw *source, guint ratio)
}
static cairo_pattern_t *
-swfdec_color_pattern_get_pattern (SwfdecPattern *pat, const SwfdecColorTransform *trans)
+swfdec_color_pattern_get_pattern (SwfdecPattern *pat, SwfdecRenderer *renderer,
+ const SwfdecColorTransform *trans)
{
SwfdecColor color = SWFDEC_COLOR_PATTERN (pat)->start_color;
@@ -209,10 +212,10 @@ swfdec_image_pattern_morph (SwfdecDraw *dest, SwfdecDraw *source, guint ratio)
}
static cairo_pattern_t *
-swfdec_image_pattern_get_pattern (SwfdecPattern *pat, const SwfdecColorTransform *trans)
+swfdec_image_pattern_get_pattern (SwfdecPattern *pat, SwfdecRenderer *renderer,
+ const SwfdecColorTransform *trans)
{
SwfdecImagePattern *image = SWFDEC_IMAGE_PATTERN (pat);
- SwfdecRenderer *renderer = NULL;
cairo_pattern_t *pattern;
cairo_surface_t *surface;
@@ -546,15 +549,17 @@ swfdec_pattern_to_string (SwfdecPattern *pattern)
}
cairo_pattern_t *
-swfdec_pattern_get_pattern (SwfdecPattern *pattern, const SwfdecColorTransform *trans)
+swfdec_pattern_get_pattern (SwfdecPattern *pattern, SwfdecRenderer *renderer,
+ const SwfdecColorTransform *trans)
{
SwfdecPatternClass *klass;
g_return_val_if_fail (SWFDEC_IS_PATTERN (pattern), NULL);
+ g_return_val_if_fail (SWFDEC_IS_RENDERER (renderer), NULL);
g_return_val_if_fail (trans != NULL, NULL);
klass = SWFDEC_PATTERN_GET_CLASS (pattern);
g_assert (klass->get_pattern);
- return klass->get_pattern (pattern, trans);
+ return klass->get_pattern (pattern, renderer, trans);
}
diff --git a/swfdec/swfdec_pattern.h b/swfdec/swfdec_pattern.h
index 811389d..16021a8 100644
--- a/swfdec/swfdec_pattern.h
+++ b/swfdec/swfdec_pattern.h
@@ -52,6 +52,7 @@ struct _SwfdecPatternClass
/* create a cairo pattern for the given values */
cairo_pattern_t * (* get_pattern) (SwfdecPattern * pattern,
+ SwfdecRenderer * renderer,
const SwfdecColorTransform * trans);
};
@@ -66,6 +67,7 @@ SwfdecDraw * swfdec_pattern_parse_morph (SwfdecBits * bits,
SwfdecSwfDecoder * dec);
cairo_pattern_t *swfdec_pattern_get_pattern (SwfdecPattern * pattern,
+ SwfdecRenderer * renderer,
const SwfdecColorTransform * trans);
/* debug */
diff --git a/swfdec/swfdec_stroke.c b/swfdec/swfdec_stroke.c
index f043727..0e966eb 100644
--- a/swfdec/swfdec_stroke.c
+++ b/swfdec/swfdec_stroke.c
@@ -29,6 +29,7 @@
#include "swfdec_debug.h"
#include "swfdec_decoder.h"
#include "swfdec_path.h"
+#include "swfdec_renderer_internal.h"
#define MAX_ALIGN 10
@@ -113,7 +114,8 @@ swfdec_stroke_paint (SwfdecDraw *draw, cairo_t *cr, const SwfdecColorTransform *
cairo_append_path (cr, &draw->path);
if (stroke->pattern) {
- cairo_pattern_t *pattern = swfdec_pattern_get_pattern (stroke->pattern, trans);
+ cairo_pattern_t *pattern = swfdec_pattern_get_pattern (stroke->pattern,
+ swfdec_renderer_get (cr), trans);
cairo_set_source (cr, pattern);
cairo_pattern_destroy (pattern);
} else {
commit 4291a54b08aaa31b7ece0d911f4794ddf810255b
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Apr 8 14:58:26 2008 +0200
add API to render with a given renderer
and actually attach the renderer to the cairo_t when rendering.
It might be useful to use the SwfdecRenderer directly instead of handing the cr
around.
diff --git a/swfdec/swfdec_player.c b/swfdec/swfdec_player.c
index 3924b2f..29ca9f8 100644
--- a/swfdec/swfdec_player.c
+++ b/swfdec/swfdec_player.c
@@ -2846,12 +2846,38 @@ swfdec_player_render_focusrect (SwfdecPlayer *player, cairo_t *cr, SwfdecRect *i
* @width: width of area to render or 0 for full width
* @height: height of area to render or 0 for full height
*
- * Renders the given area of the current frame to @cr.
+ * Renders the given area of the current frame to @cr using the player's
+ * renderer.
**/
void
swfdec_player_render (SwfdecPlayer *player, cairo_t *cr,
double x, double y, double width, double height)
{
+ g_return_if_fail (SWFDEC_IS_PLAYER (player));
+ g_return_if_fail (cr != NULL);
+ g_return_if_fail (width >= 0.0);
+ g_return_if_fail (height >= 0.0);
+
+ swfdec_player_render_with_renderer (player, cr, player->priv->renderer,
+ x, y, width, height);
+}
+
+/**
+ * swfdec_player_render:
+ * @player: a #SwfdecPlayer
+ * @cr: #cairo_t to render to
+ * @renderer: Renderer to use for rendering
+ * @x: x coordinate of top left position to render
+ * @y: y coordinate of top left position to render
+ * @width: width of area to render or 0 for full width
+ * @height: height of area to render or 0 for full height
+ *
+ * Renders the given area of the current frame to @cr.
+ **/
+void
+swfdec_player_render_with_renderer (SwfdecPlayer *player, cairo_t *cr,
+ SwfdecRenderer *renderer, double x, double y, double width, double height)
+{
static const SwfdecColorTransform trans = { FALSE, 256, 0, 256, 0, 256, 0, 256, 0 };
SwfdecPlayerPrivate *priv;
GList *walk;
@@ -2859,6 +2885,7 @@ swfdec_player_render (SwfdecPlayer *player, cairo_t *cr,
g_return_if_fail (SWFDEC_IS_PLAYER (player));
g_return_if_fail (cr != NULL);
+ g_return_if_fail (SWFDEC_IS_RENDERER (renderer));
g_return_if_fail (width >= 0.0);
g_return_if_fail (height >= 0.0);
@@ -2871,6 +2898,8 @@ swfdec_player_render (SwfdecPlayer *player, cairo_t *cr,
width = priv->stage_width;
if (height == 0.0)
height = priv->stage_height;
+
+ swfdec_renderer_attach (renderer, cr);
/* clip the area */
cairo_save (cr);
cairo_rectangle (cr, x, y, width, height);
diff --git a/swfdec/swfdec_player.h b/swfdec/swfdec_player.h
index a0a9e94..49cfe39 100644
--- a/swfdec/swfdec_player.h
+++ b/swfdec/swfdec_player.h
@@ -153,12 +153,19 @@ SwfdecRenderer *swfdec_player_get_renderer (SwfdecPlayer * player);
void swfdec_player_set_renderer (SwfdecPlayer * player,
SwfdecRenderer * renderer);
-void swfdec_player_render (SwfdecPlayer * player,
- cairo_t * cr,
- double x,
- double y,
- double width,
- double height);
+void swfdec_player_render (SwfdecPlayer * player,
+ cairo_t * cr,
+ double x,
+ double y,
+ double width,
+ double height);
+void swfdec_player_render_with_renderer (SwfdecPlayer * player,
+ cairo_t * cr,
+ SwfdecRenderer * renderer,
+ double x,
+ double y,
+ double width,
+ double height);
gulong swfdec_player_advance (SwfdecPlayer * player,
gulong msecs);
gboolean swfdec_player_mouse_move (SwfdecPlayer * player,
commit 75c3b01ca0c265192ac122efeeb2cf72fef70b6e
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Apr 8 14:58:08 2008 +0200
actually create the hash table we use
diff --git a/swfdec/swfdec_renderer.c b/swfdec/swfdec_renderer.c
index ad62d70..dc88721 100644
--- a/swfdec/swfdec_renderer.c
+++ b/swfdec/swfdec_renderer.c
@@ -192,8 +192,12 @@ swfdec_renderer_class_init (SwfdecRendererClass *klass)
static void
swfdec_renderer_init (SwfdecRenderer *renderer)
{
- renderer->priv = G_TYPE_INSTANCE_GET_PRIVATE (renderer, SWFDEC_TYPE_RENDERER, SwfdecRendererPrivate);
- renderer->priv->cache = swfdec_cache_new (8 * 1024 * 1024);
+ SwfdecRendererPrivate *priv;
+
+ renderer->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE (renderer, SWFDEC_TYPE_RENDERER, SwfdecRendererPrivate);
+
+ priv->cache = swfdec_cache_new (8 * 1024 * 1024);
+ priv->cache_lookup = g_hash_table_new (g_direct_hash, g_direct_equal);
}
/*** INTERNAL API ***/
commit 4d275c48cfacd4d3f8cf8cfcfde32faa9a3b9caf
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Apr 8 13:54:11 2008 +0200
rewrite image handling to use the new caching mechanism in SwfdecRenderer
diff --git a/swfdec/swfdec_cached_image.c b/swfdec/swfdec_cached_image.c
index 2cc6c76..2640b5f 100644
--- a/swfdec/swfdec_cached_image.c
+++ b/swfdec/swfdec_cached_image.c
@@ -54,33 +54,7 @@ swfdec_cached_image_init (SwfdecCachedImage *cached)
}
SwfdecCachedImage *
-swfdec_cached_image_new (guint8 *image_data, cairo_format_t format,
- guint width, guint height, guint rowstride)
-{
- SwfdecCachedImage *image;
- static const cairo_user_data_key_t key;
- gulong size;
-
- g_return_val_if_fail (image_data != NULL, NULL);
- g_return_val_if_fail (width > 0, NULL);
- g_return_val_if_fail (height > 0, NULL);
- g_return_val_if_fail (rowstride > 0, NULL);
-
- /* FIXME: sizeof (cairo_surface_t) */
- size = sizeof (SwfdecCachedImage) + height * rowstride;
- image = g_object_new (SWFDEC_TYPE_CACHED_IMAGE, "size", size, NULL);
- image->surface = cairo_image_surface_create_for_data (image_data, format,
- width, height, rowstride);
- if (cairo_surface_set_user_data (image->surface, &key, image_data, g_free) != CAIRO_STATUS_SUCCESS) {
- /* guess we should abort here due to OOM? */
- g_warning ("failed to register data free function");
- }
-
- return image;
-}
-
-SwfdecCachedImage *
-swfdec_cached_image_new_for_surface (cairo_surface_t *surface, gsize size)
+swfdec_cached_image_new (cairo_surface_t *surface, gsize size)
{
SwfdecCachedImage *image;
@@ -102,3 +76,23 @@ swfdec_cached_image_get_surface (SwfdecCachedImage *image)
return cairo_surface_reference (image->surface);
}
+void
+swfdec_cached_image_get_color_transform (SwfdecCachedImage *image,
+ SwfdecColorTransform *trans)
+{
+ g_return_if_fail (SWFDEC_IS_CACHED_IMAGE (image));
+ g_return_if_fail (trans != NULL);
+
+ *trans = image->trans;
+}
+
+void
+swfdec_cached_image_set_color_transform (SwfdecCachedImage *image,
+ const SwfdecColorTransform *trans)
+{
+ g_return_if_fail (SWFDEC_IS_CACHED_IMAGE (image));
+ g_return_if_fail (trans != NULL);
+
+ image->trans = *trans;
+}
+
diff --git a/swfdec/swfdec_cached_image.h b/swfdec/swfdec_cached_image.h
index d370a06..89a08b1 100644
--- a/swfdec/swfdec_cached_image.h
+++ b/swfdec/swfdec_cached_image.h
@@ -51,18 +51,17 @@ struct _SwfdecCachedImageClass
GType swfdec_cached_image_get_type (void);
-SwfdecCachedImage * swfdec_cached_image_new (guint8 * image_data,
- cairo_format_t format,
- guint width,
- guint height,
- guint rowstride);
-SwfdecCachedImage * swfdec_cached_image_new_for_surface
- (cairo_surface_t * surface,
+SwfdecCachedImage * swfdec_cached_image_new (cairo_surface_t * surface,
gsize size);
cairo_surface_t * swfdec_cached_image_get_surface (SwfdecCachedImage * image);
-
+void swfdec_cached_image_get_color_transform
+ (SwfdecCachedImage * image,
+ SwfdecColorTransform * trans);
+void swfdec_cached_image_set_color_transform
+ (SwfdecCachedImage * image,
+ const SwfdecColorTransform *trans);
G_END_DECLS
#endif
diff --git a/swfdec/swfdec_image.c b/swfdec/swfdec_image.c
index 1be91b8..005d23d 100644
--- a/swfdec/swfdec_image.c
+++ b/swfdec/swfdec_image.c
@@ -31,10 +31,9 @@
#include "swfdec_image.h"
#include "swfdec_cached_image.h"
#include "swfdec_debug.h"
+#include "swfdec_renderer_internal.h"
#include "swfdec_swf_decoder.h"
-static const cairo_user_data_key_t key;
-
static void merge_alpha (SwfdecImage * image, unsigned char *image_data,
unsigned char *alpha);
static void swfdec_image_colormap_decode (SwfdecImage * image,
@@ -151,8 +150,25 @@ swfdec_jpeg_decode_argb (unsigned char *data1, int length1,
return ret;
}
-static SwfdecCachedImage *
-swfdec_image_jpeg_load (SwfdecImage *image)
+static cairo_surface_t *
+swfdec_image_create_surface_for_data (SwfdecRenderer *renderer, guint8 *data,
+ cairo_format_t format, guint width, guint height, guint rowstride)
+{
+ cairo_surface_t *surface;
+
+ if (renderer) {
+ surface = swfdec_renderer_create_for_data (renderer, data, format, width, height, rowstride);
+ } else {
+ static const cairo_user_data_key_t key;
+ surface = cairo_image_surface_create_for_data (data,
+ format, width, height, rowstride);
+ cairo_surface_set_user_data (surface, &key, data, g_free);
+ }
+ return surface;
+}
+
+static cairo_surface_t *
+swfdec_image_jpeg_load (SwfdecImage *image, SwfdecRenderer *renderer)
{
gboolean ret;
guint8 *data;
@@ -175,8 +191,8 @@ swfdec_image_jpeg_load (SwfdecImage *image)
SWFDEC_LOG (" width = %d", image->width);
SWFDEC_LOG (" height = %d", image->height);
- return swfdec_cached_image_new (data, CAIRO_FORMAT_RGB24, image->width,
- image->height, 4 * image->width);
+ return swfdec_image_create_surface_for_data (renderer, data,
+ CAIRO_FORMAT_RGB24, image->width, image->height, 4 * image->width);
}
int
@@ -199,8 +215,8 @@ tag_func_define_bits_jpeg_2 (SwfdecSwfDecoder * s, guint tag)
return SWFDEC_STATUS_OK;
}
-static SwfdecCachedImage *
-swfdec_image_jpeg2_load (SwfdecImage *image)
+static cairo_surface_t *
+swfdec_image_jpeg2_load (SwfdecImage *image, SwfdecRenderer *renderer)
{
gboolean ret;
guint8 *data;
@@ -214,8 +230,8 @@ swfdec_image_jpeg2_load (SwfdecImage *image)
SWFDEC_LOG (" width = %d", image->width);
SWFDEC_LOG (" height = %d", image->height);
- return swfdec_cached_image_new (data, CAIRO_FORMAT_RGB24, image->width,
- image->height, 4 * image->width);
+ return swfdec_image_create_surface_for_data (renderer, data,
+ CAIRO_FORMAT_RGB24, image->width, image->height, 4 * image->width);
}
int
@@ -238,8 +254,8 @@ tag_func_define_bits_jpeg_3 (SwfdecSwfDecoder * s, guint tag)
return SWFDEC_STATUS_OK;
}
-static SwfdecCachedImage *
-swfdec_image_jpeg3_load (SwfdecImage *image)
+static cairo_surface_t *
+swfdec_image_jpeg3_load (SwfdecImage *image, SwfdecRenderer *renderer)
{
SwfdecBits bits;
SwfdecBuffer *buffer;
@@ -273,8 +289,8 @@ swfdec_image_jpeg3_load (SwfdecImage *image)
SWFDEC_LOG (" width = %d", image->width);
SWFDEC_LOG (" height = %d", image->height);
- return swfdec_cached_image_new (data, CAIRO_FORMAT_RGB24, image->width,
- image->height, 4 * image->width);
+ return swfdec_image_create_surface_for_data (renderer, data,
+ CAIRO_FORMAT_RGB24, image->width, image->height, 4 * image->width);
}
static void
@@ -294,8 +310,8 @@ merge_alpha (SwfdecImage * image, unsigned char *image_data,
}
}
-static SwfdecCachedImage *
-swfdec_image_lossless_load (SwfdecImage *image)
+static cairo_surface_t *
+swfdec_image_lossless_load (SwfdecImage *image, SwfdecRenderer *renderer)
{
int format;
guint color_table_size;
@@ -450,7 +466,7 @@ swfdec_image_lossless_load (SwfdecImage *image)
}
out:
- return swfdec_cached_image_new (data,
+ return swfdec_image_create_surface_for_data (renderer, data,
have_alpha ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24,
image->width, image->height, image->width * 4);
}
@@ -546,72 +562,126 @@ swfdec_image_png_read (void *bitsp, unsigned char *data, unsigned int length)
return CAIRO_STATUS_SUCCESS;
}
-static SwfdecCachedImage *
-swfdec_image_png_load (SwfdecImage *image)
+static cairo_surface_t *
+swfdec_image_png_load (SwfdecImage *image, SwfdecRenderer *renderer)
{
SwfdecBits bits;
cairo_surface_t *surface;
- SwfdecCachedImage *cached;
swfdec_bits_init (&bits, image->raw_data);
surface = cairo_image_surface_create_from_png_stream (
swfdec_image_png_read, &bits);
+ if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) {
+ cairo_surface_destroy (surface);
+ return NULL;
+ }
+
image->width = cairo_image_surface_get_width (surface);
image->height = cairo_image_surface_get_height (surface);
- cached = swfdec_cached_image_new_for_surface (surface,
- image->height * cairo_image_surface_get_stride (surface));
- cairo_surface_destroy (surface);
- return cached;
+ if (renderer)
+ surface = swfdec_renderer_create_similar (renderer, surface);
+ return surface;
+}
+
+static gboolean
+swfdec_image_find_by_transform (SwfdecCached *cached, gpointer data)
+{
+ const SwfdecColorTransform *trans = data;
+ SwfdecColorTransform ctrans;
+
+ swfdec_cached_image_get_color_transform (SWFDEC_CACHED_IMAGE (cached),
+ &ctrans);
+ if (trans->mask != ctrans.mask)
+ return FALSE;
+ if (trans->mask)
+ return TRUE;
+ return (trans->ra == ctrans.ra &&
+ trans->rb == ctrans.rb &&
+ trans->ga == ctrans.ga &&
+ trans->gb == ctrans.gb &&
+ trans->ba == ctrans.ba &&
+ trans->bb == ctrans.bb &&
+ trans->aa == ctrans.aa &&
+ trans->ab == ctrans.ab);
+}
+
+static cairo_surface_t *
+swfdec_image_lookup_surface (SwfdecImage *image, SwfdecRenderer *renderer,
+ const SwfdecColorTransform *trans)
+{
+ if (renderer) {
+ SwfdecCached *cached = swfdec_renderer_get_cache (renderer, image,
+ swfdec_image_find_by_transform, (gpointer) trans);
+ if (cached) {
+ swfdec_cached_use (cached);
+ return swfdec_cached_image_get_surface (SWFDEC_CACHED_IMAGE (cached));
+ }
+ }
+ return NULL;
}
cairo_surface_t *
-swfdec_image_create_surface (SwfdecImage *image)
+swfdec_image_create_surface (SwfdecImage *image, SwfdecRenderer *renderer)
{
+ SwfdecColorTransform trans;
SwfdecCachedImage *cached;
cairo_surface_t *surface;
+ g_return_val_if_fail (SWFDEC_IS_IMAGE (image), NULL);
+ g_return_val_if_fail (renderer == NULL || SWFDEC_IS_RENDERER (renderer), NULL);
+
if (image->raw_data == NULL)
return NULL;
- if (TRUE) {
- switch (image->type) {
- case SWFDEC_IMAGE_TYPE_JPEG:
- cached = swfdec_image_jpeg_load (image);
- break;
- case SWFDEC_IMAGE_TYPE_JPEG2:
- cached = swfdec_image_jpeg2_load (image);
- break;
- case SWFDEC_IMAGE_TYPE_JPEG3:
- cached = swfdec_image_jpeg3_load (image);
- break;
- case SWFDEC_IMAGE_TYPE_LOSSLESS:
- cached = swfdec_image_lossless_load (image);
- break;
- case SWFDEC_IMAGE_TYPE_LOSSLESS2:
- cached = swfdec_image_lossless_load (image);
- break;
- case SWFDEC_IMAGE_TYPE_PNG:
- cached = swfdec_image_png_load (image);
- break;
- case SWFDEC_IMAGE_TYPE_UNKNOWN:
- default:
- g_assert_not_reached ();
- break;
- }
- if (cached == NULL) {
- SWFDEC_WARNING ("failed to decode image");
- return NULL;
- }
+ swfdec_color_transform_init_identity (&trans);
+ surface = swfdec_image_lookup_surface (image, renderer, &trans);
+ if (surface)
+ return surface;
+
+ switch (image->type) {
+ case SWFDEC_IMAGE_TYPE_JPEG:
+ surface = swfdec_image_jpeg_load (image, renderer);
+ break;
+ case SWFDEC_IMAGE_TYPE_JPEG2:
+ surface = swfdec_image_jpeg2_load (image, renderer);
+ break;
+ case SWFDEC_IMAGE_TYPE_JPEG3:
+ surface = swfdec_image_jpeg3_load (image, renderer);
+ break;
+ case SWFDEC_IMAGE_TYPE_LOSSLESS:
+ surface = swfdec_image_lossless_load (image, renderer);
+ break;
+ case SWFDEC_IMAGE_TYPE_LOSSLESS2:
+ surface = swfdec_image_lossless_load (image, renderer);
+ break;
+ case SWFDEC_IMAGE_TYPE_PNG:
+ surface = swfdec_image_png_load (image, renderer);
+ break;
+ case SWFDEC_IMAGE_TYPE_UNKNOWN:
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+ if (surface == NULL) {
+ SWFDEC_WARNING ("failed to decode image");
+ return NULL;
+ }
+ if (renderer) {
+ /* FIXME: The size is just an educated guess */
+ cached = swfdec_cached_image_new (surface, image->width * image->height * 4);
+ swfdec_renderer_add_cache (renderer, image, SWFDEC_CACHED (cached));
+ g_object_unref (cached);
}
- surface = swfdec_cached_image_get_surface (cached);
- g_object_unref (cached);
return surface;
}
cairo_surface_t *
-swfdec_image_create_surface_transformed (SwfdecImage *image, const SwfdecColorTransform *trans)
+swfdec_image_create_surface_transformed (SwfdecImage *image, SwfdecRenderer *renderer,
+ const SwfdecColorTransform *trans)
{
+ SwfdecColorTransform mask;
+ SwfdecCachedImage *cached;
cairo_surface_t *surface, *source;
guint32 *tdata;
const guint32 *sdata;
@@ -619,13 +689,30 @@ swfdec_image_create_surface_transformed (SwfdecImage *image, const SwfdecColorTr
gboolean has_alpha = FALSE;
g_return_val_if_fail (SWFDEC_IS_IMAGE (image), NULL);
+ g_return_val_if_fail (renderer == NULL || SWFDEC_IS_RENDERER (renderer), NULL);
g_return_val_if_fail (trans != NULL, NULL);
+ surface = swfdec_image_lookup_surface (image, renderer, trans);
+ if (surface)
+ return surface;
/* obvious optimization */
if (swfdec_color_transform_is_identity (trans))
- return swfdec_image_create_surface (image);
+ return swfdec_image_create_surface (image, renderer);
+
+ /* need to create an image surface here, so we can modify it. Will upload later */
+ /* NB: we use the mask property here to inidicate an image surface */
+ swfdec_color_transform_init_mask (&mask);
+ source = swfdec_image_lookup_surface (image, renderer, &mask);
+ if (source == NULL) {
+ source = swfdec_image_create_surface (image, NULL);
+ if (renderer) {
+ cached = swfdec_cached_image_new (surface, image->width * image->height * 4);
+ swfdec_cached_image_set_color_transform (cached, &mask);
+ swfdec_renderer_add_cache (renderer, image, SWFDEC_CACHED (cached));
+ g_object_unref (cached);
+ }
+ }
- source = swfdec_image_create_surface (image);
tdata = g_try_malloc (image->width * image->height * 4);
if (!tdata) {
SWFDEC_ERROR ("failed to allocate memory for transformed image");
@@ -642,10 +729,16 @@ swfdec_image_create_surface_transformed (SwfdecImage *image, const SwfdecColorTr
has_alpha |= SWFDEC_COLOR_A (tdata[i]) != 0xFF;
}
cairo_surface_destroy (source);
- surface = cairo_image_surface_create_for_data ((unsigned char *) tdata,
+ surface = swfdec_image_create_surface_for_data (renderer, (guchar *) tdata,
has_alpha ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24,
image->width, image->height, image->width * 4);
- cairo_surface_set_user_data (surface, &key, tdata, g_free);
+ if (renderer) {
+ /* FIXME: The size is just an educated guess */
+ cached = swfdec_cached_image_new (surface, image->width * image->height * 4);
+ swfdec_cached_image_set_color_transform (cached, trans);
+ swfdec_renderer_add_cache (renderer, image, SWFDEC_CACHED (cached));
+ g_object_unref (cached);
+ }
return surface;
}
diff --git a/swfdec/swfdec_image.h b/swfdec/swfdec_image.h
index 3e2d53d..b127e5d 100644
--- a/swfdec/swfdec_image.h
+++ b/swfdec/swfdec_image.h
@@ -67,9 +67,11 @@ GType swfdec_image_get_type (void);
SwfdecImageType swfdec_image_detect (const guint8 * data);
SwfdecImage * swfdec_image_new (SwfdecBuffer * buffer);
-cairo_surface_t * swfdec_image_create_surface (SwfdecImage * image);
+cairo_surface_t * swfdec_image_create_surface (SwfdecImage * image,
+ SwfdecRenderer * renderer);
cairo_surface_t * swfdec_image_create_surface_transformed
(SwfdecImage * image,
+ SwfdecRenderer * renderer,
const SwfdecColorTransform *trans);
int swfdec_image_jpegtables (SwfdecSwfDecoder * s, guint tag);
diff --git a/swfdec/swfdec_image_decoder.c b/swfdec/swfdec_image_decoder.c
index 7a50d16..30ef283 100644
--- a/swfdec/swfdec_image_decoder.c
+++ b/swfdec/swfdec_image_decoder.c
@@ -65,7 +65,7 @@ swfdec_image_get_size (SwfdecImage *image, guint *w, guint *h)
{
cairo_surface_t *surface;
- surface = swfdec_image_create_surface (image);
+ surface = swfdec_image_create_surface (image, NULL);
if (surface == NULL)
return FALSE;
diff --git a/swfdec/swfdec_movie.c b/swfdec/swfdec_movie.c
index 57704dc..27e6486 100644
--- a/swfdec/swfdec_movie.c
+++ b/swfdec/swfdec_movie.c
@@ -40,6 +40,7 @@
#include "swfdec_player_internal.h"
#include "swfdec_sprite.h"
#include "swfdec_sprite_movie.h"
+#include "swfdec_renderer_internal.h"
#include "swfdec_resource.h"
#include "swfdec_system.h"
#include "swfdec_text_field_movie.h"
@@ -1163,8 +1164,9 @@ swfdec_movie_do_render (SwfdecMovie *movie, cairo_t *cr,
/* if the movie loaded an image, draw it here now */
if (movie->image) {
+ SwfdecRenderer *renderer = swfdec_renderer_get (cr);
cairo_surface_t *surface = swfdec_image_create_surface_transformed (movie->image,
- ctrans);
+ renderer, ctrans);
if (surface) {
static const cairo_matrix_t matrix = { 1.0 / SWFDEC_TWIPS_SCALE_FACTOR, 0, 0, 1.0 / SWFDEC_TWIPS_SCALE_FACTOR, 0, 0 };
cairo_pattern_t *pattern = cairo_pattern_create_for_surface (surface);
diff --git a/swfdec/swfdec_pattern.c b/swfdec/swfdec_pattern.c
index d641556..70a3292 100644
--- a/swfdec/swfdec_pattern.c
+++ b/swfdec/swfdec_pattern.c
@@ -212,10 +212,11 @@ static cairo_pattern_t *
swfdec_image_pattern_get_pattern (SwfdecPattern *pat, const SwfdecColorTransform *trans)
{
SwfdecImagePattern *image = SWFDEC_IMAGE_PATTERN (pat);
+ SwfdecRenderer *renderer = NULL;
cairo_pattern_t *pattern;
cairo_surface_t *surface;
- surface = swfdec_image_create_surface_transformed (image->image, trans);
+ surface = swfdec_image_create_surface_transformed (image->image, renderer, trans);
if (surface == NULL)
return NULL;
pattern = cairo_pattern_create_for_surface (surface);
@@ -524,7 +525,7 @@ swfdec_pattern_to_string (SwfdecPattern *pattern)
if (SWFDEC_IS_IMAGE_PATTERN (pattern)) {
SwfdecImagePattern *image = SWFDEC_IMAGE_PATTERN (pattern);
if (image->image->width == 0)
- cairo_surface_destroy (swfdec_image_create_surface (image->image));
+ cairo_surface_destroy (swfdec_image_create_surface (image->image, NULL));
return g_strdup_printf ("%ux%u image %u (%s, %s)", image->image->width,
image->image->height, SWFDEC_CHARACTER (image->image)->id,
image->extend == CAIRO_EXTEND_REPEAT ? "repeat" : "no repeat",
commit 235d21d8c19db6157eb71835d35f0856bbffb756
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Apr 8 12:53:09 2008 +0200
add create_similar and create_for_data functions
diff --git a/swfdec/swfdec_renderer.c b/swfdec/swfdec_renderer.c
index 00cf5a5..ad62d70 100644
--- a/swfdec/swfdec_renderer.c
+++ b/swfdec/swfdec_renderer.c
@@ -132,6 +132,43 @@ swfdec_renderer_set_property (GObject *object, guint param_id, const GValue *val
}
}
+static cairo_surface_t *
+swfdec_renderer_do_create_similar (SwfdecRenderer *renderer, cairo_surface_t *surface)
+{
+ SwfdecRendererPrivate *priv;
+ cairo_surface_t *result;
+ cairo_t *cr;
+
+ priv = renderer->priv;
+ if (cairo_surface_get_type (priv->surface) == CAIRO_SURFACE_TYPE_IMAGE)
+ return surface;
+
+ result = cairo_surface_create_similar (priv->surface,
+ cairo_surface_get_content (surface),
+ cairo_image_surface_get_width (surface),
+ cairo_image_surface_get_height (surface));
+ cr = cairo_create (result);
+
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_paint (cr);
+
+ cairo_destroy (cr);
+ cairo_surface_destroy (surface);
+ return result;
+}
+
+static cairo_surface_t *
+swfdec_renderer_do_create_for_data (SwfdecRenderer *renderer, guint8 *data,
+ cairo_format_t format, guint width, guint height, guint rowstride)
+{
+ static const cairo_user_data_key_t key;
+ cairo_surface_t *surface;
+
+ surface = cairo_image_surface_create_for_data (data, format, width, height, rowstride);
+ cairo_surface_set_user_data (surface, &key, data, g_free);
+ return swfdec_renderer_create_similar (renderer, surface);
+}
+
static void
swfdec_renderer_class_init (SwfdecRendererClass *klass)
{
@@ -147,6 +184,9 @@ swfdec_renderer_class_init (SwfdecRendererClass *klass)
g_object_class_install_property (object_class, PROP_SURFACE,
g_param_spec_pointer ("surface", "surface", "cairo surface in use by this renderer",
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ klass->create_similar = swfdec_renderer_do_create_similar;
+ klass->create_for_data = swfdec_renderer_do_create_for_data;
}
static void
@@ -247,6 +287,48 @@ swfdec_renderer_get (cairo_t *cr)
return cairo_get_user_data (cr, &cr_key);
}
+/**
+ * swfdec_renderer_create_similar:
+ * @renderer: a renderer
+ * @surface: an image surface; this function takes ownership of the passed-in image.
+ *
+ * Creates a surface with the same contents and size as the given image
+ * @surface, but optimized for use in @renderer. You should use this function
+ * before caching a surface.
+ *
+ * Returns: A surface with the same contents as @surface. You own a reference to the
+ * returned surface.
+ **/
+cairo_surface_t *
+swfdec_renderer_create_similar (SwfdecRenderer *renderer, cairo_surface_t *surface)
+{
+ SwfdecRendererClass *klass;
+
+ g_return_val_if_fail (SWFDEC_IS_RENDERER (renderer), NULL);
+ g_return_val_if_fail (surface != NULL, NULL);
+ g_return_val_if_fail (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_IMAGE, NULL);
+
+ klass = SWFDEC_RENDERER_GET_CLASS (renderer);
+ return klass->create_similar (renderer, surface);
+}
+
+/* FIXME: get data parameter const */
+cairo_surface_t *
+swfdec_renderer_create_for_data (SwfdecRenderer *renderer, guint8 *data,
+ cairo_format_t format, guint width, guint height, guint rowstride)
+{
+ SwfdecRendererClass *klass;
+
+ g_return_val_if_fail (SWFDEC_IS_RENDERER (renderer), NULL);
+ g_return_val_if_fail (data != NULL, NULL);
+ g_return_val_if_fail (width > 0, NULL);
+ g_return_val_if_fail (height > 0, NULL);
+ g_return_val_if_fail (rowstride > 0, NULL);
+
+ klass = SWFDEC_RENDERER_GET_CLASS (renderer);
+ return klass->create_for_data (renderer, data, format, width, height, rowstride);
+}
+
/*** PUBLIC API ***/
/**
diff --git a/swfdec/swfdec_renderer.h b/swfdec/swfdec_renderer.h
index 5d3ce71..1b1ffe0 100644
--- a/swfdec/swfdec_renderer.h
+++ b/swfdec/swfdec_renderer.h
@@ -46,6 +46,15 @@ struct _SwfdecRenderer {
struct _SwfdecRendererClass
{
GObjectClass object_class;
+
+ cairo_surface_t * (* create_similar) (SwfdecRenderer * renderer,
+ cairo_surface_t * surface);
+ cairo_surface_t * (* create_for_data) (SwfdecRenderer * renderer,
+ guint8 * data,
+ cairo_format_t format,
+ guint width,
+ guint height,
+ guint rowstride);
};
GType swfdec_renderer_get_type (void);
diff --git a/swfdec/swfdec_renderer_internal.h b/swfdec/swfdec_renderer_internal.h
index 1f23333..b8a3dd9 100644
--- a/swfdec/swfdec_renderer_internal.h
+++ b/swfdec/swfdec_renderer_internal.h
@@ -41,6 +41,15 @@ SwfdecCached * swfdec_renderer_get_cache (SwfdecRenderer * renderer,
SwfdecRendererSearchFunc func,
gpointer data);
+cairo_surface_t * swfdec_renderer_create_similar (SwfdecRenderer * renderer,
+ cairo_surface_t * surface);
+cairo_surface_t * swfdec_renderer_create_for_data (SwfdecRenderer * renderer,
+ guint8 * data,
+ cairo_format_t format,
+ guint width,
+ guint height,
+ guint rowstride);
+
G_END_DECLS
#endif
commit 89dee153a1cc4b8410e786e31b6d13a124e5f13b
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Apr 8 11:12:09 2008 +0200
use the current renderer for computing layouts
diff --git a/swfdec/swfdec_text_field_movie.c b/swfdec/swfdec_text_field_movie.c
index 8c4cbc2..7bf23d5 100644
--- a/swfdec/swfdec_text_field_movie.c
+++ b/swfdec/swfdec_text_field_movie.c
@@ -552,8 +552,12 @@ swfdec_text_field_movie_get_layouts (SwfdecTextFieldMovie *text, int *num,
g_assert (SWFDEC_IS_TEXT_FIELD_MOVIE (text));
- if (cr == NULL)
- cr = text->cr;
+ if (cr == NULL) {
+ cr = cairo_create (swfdec_renderer_get_surface (
+ SWFDEC_PLAYER (SWFDEC_AS_OBJECT (text)->context)->priv->renderer));
+ } else {
+ cairo_reference (cr);
+ }
if (paragraphs == NULL) {
paragraphs_free = swfdec_text_field_movie_get_paragraphs (text, NULL);
@@ -766,6 +770,7 @@ swfdec_text_field_movie_get_layouts (SwfdecTextFieldMovie *text, int *num,
if (num != NULL)
*num = layouts->len;
+ cairo_destroy (cr);
return (SwfdecLayout *) (void *) g_array_free (layouts, FALSE);
}
@@ -1246,11 +1251,6 @@ swfdec_text_field_movie_dispose (GObject *object)
g_string_free (text->input, TRUE);
text->input = NULL;
- cairo_destroy (text->cr);
- text->cr = NULL;
- cairo_surface_destroy (text->surface);
- text->surface = NULL;
-
G_OBJECT_CLASS (swfdec_text_field_movie_parent_class)->dispose (object);
}
@@ -1729,9 +1729,6 @@ swfdec_text_field_movie_class_init (SwfdecTextFieldMovieClass * g_class)
static void
swfdec_text_field_movie_init (SwfdecTextFieldMovie *text)
{
- text->surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
- text->cr = cairo_create (text->surface);
-
text->input = g_string_new ("");
text->scroll = 1;
text->mouse_wheel_enabled = TRUE;
diff --git a/swfdec/swfdec_text_field_movie.h b/swfdec/swfdec_text_field_movie.h
index 5d8eebd..7bd978b 100644
--- a/swfdec/swfdec_text_field_movie.h
+++ b/swfdec/swfdec_text_field_movie.h
@@ -135,11 +135,6 @@ struct _SwfdecTextFieldMovie {
gsize cursor_start; /* index of cursor (aka insertion point) in ->input */
gsize cursor_end; /* end of cursor, either equal to cursor_start or if text selected smaller or bigger */
guint character_pressed;
-
- // FIXME: Temporary using image surface, until there is a way to get cairo_t
- // outside the rendering functions
- cairo_surface_t * surface;
- cairo_t * cr;
};
struct _SwfdecTextFieldMovieClass {
commit 40d8e8517dc61888fac3bec6cb1ff19b43c91e43
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Apr 8 11:11:57 2008 +0200
include swfdec_renderer.h
diff --git a/swfdec/swfdec.h b/swfdec/swfdec.h
index 1e769b3..2dec954 100644
--- a/swfdec/swfdec.h
+++ b/swfdec/swfdec.h
@@ -40,6 +40,7 @@
#include <swfdec/swfdec_player.h>
#include <swfdec/swfdec_player_scripting.h>
#include <swfdec/swfdec_rectangle.h>
+#include <swfdec/swfdec_renderer.h>
#include <swfdec/swfdec_socket.h>
#include <swfdec/swfdec_stream.h>
#include <swfdec/swfdec_system.h>
commit 68f6e7ec4285eec6b9265dd020e18bd05380ef34
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Apr 8 11:01:22 2008 +0200
add long-awaited SwfdecRenderer object
diff --git a/swfdec/Makefile.am b/swfdec/Makefile.am
index f158c66..b218079 100644
--- a/swfdec/Makefile.am
+++ b/swfdec/Makefile.am
@@ -117,6 +117,7 @@ libswfdec_source_files = \
swfdec_policy_file.c \
swfdec_rect.c \
swfdec_rectangle.c \
+ swfdec_renderer.c \
swfdec_resource.c \
swfdec_ringbuffer.c \
swfdec_sandbox.c \
@@ -195,6 +196,7 @@ public_headers = \
swfdec_player.h \
swfdec_player_scripting.h \
swfdec_rectangle.h \
+ swfdec_renderer.h \
swfdec_script.h \
swfdec_socket.h \
swfdec_stream.h \
diff --git a/swfdec/swfdec_player.c b/swfdec/swfdec_player.c
index 0ba1ac2..3924b2f 100644
--- a/swfdec/swfdec_player.c
+++ b/swfdec/swfdec_player.c
@@ -44,6 +44,7 @@
#include "swfdec_loader_internal.h"
#include "swfdec_marshal.h"
#include "swfdec_movie.h"
+#include "swfdec_renderer_internal.h"
#include "swfdec_resource.h"
#include "swfdec_script_internal.h"
#include "swfdec_sprite_movie.h"
@@ -664,7 +665,8 @@ enum {
PROP_URL,
PROP_VARIABLES,
PROP_START_TIME,
- PROP_FOCUS
+ PROP_FOCUS,
+ PROP_RENDERER
};
G_DEFINE_TYPE (SwfdecPlayer, swfdec_player, SWFDEC_TYPE_AS_CONTEXT)
@@ -787,6 +789,9 @@ swfdec_player_get_property (GObject *object, guint param_id, GValue *value,
case PROP_FOCUS:
g_value_set_boolean (value, priv->has_focus);
break;
+ case PROP_RENDERER:
+ g_value_set_object (value, priv->renderer);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
@@ -931,6 +936,9 @@ swfdec_player_set_property (GObject *object, guint param_id, const GValue *value
case PROP_FOCUS:
swfdec_player_set_focus (player, g_value_get_boolean (value));
break;
+ case PROP_RENDERER:
+ swfdec_player_set_renderer (player, g_value_get_object (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
@@ -2010,6 +2018,9 @@ swfdec_player_class_init (SwfdecPlayerClass *klass)
g_object_class_install_property (object_class, PROP_FOCUS,
g_param_spec_boolean ("focus", "focus", "TRUE if the player has keyboard focus",
TRUE, G_PARAM_READWRITE));
+ g_object_class_install_property (object_class, PROP_RENDERER,
+ g_param_spec_object ("renderer", "renderer", "the renderer used by this player",
+ SWFDEC_TYPE_RENDERER, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
/**
* SwfdecPlayer::invalidate:
@@ -3395,6 +3406,52 @@ swfdec_player_set_focus (SwfdecPlayer *player, gboolean focus)
}
/**
+ * swfdec_player_get_renderer:
+ * @player: a player
+ *
+ * Gets the current renderer in use. See swfdec_player_set_renderer() for
+ * details.
+ *
+ * Returns: the current #SwfdecRenderer in use.
+ **/
+SwfdecRenderer *
+swfdec_player_get_renderer (SwfdecPlayer *player)
+{
+ g_return_val_if_fail (SWFDEC_IS_PLAYER (player), NULL);
+
+ return player->priv->renderer;
+}
+
+/**
+ * swfdec_player_set_renderer:
+ * @player: a player
+ * @renderer: the renderer to use
+ *
+ * Sets the renderer to be used by the @player. Setting the correct renderer is
+ * mostly relevant for TextField flash objects with native fonts, as the
+ * renderer provides those. It can also be very relevant for performance
+ * reasons. See the #SwfdecRenderer documentation for details.
+ **/
+void
+swfdec_player_set_renderer (SwfdecPlayer *player, SwfdecRenderer *renderer)
+{
+ SwfdecPlayerPrivate *priv;
+
+ g_return_if_fail (SWFDEC_IS_PLAYER (player));
+
+ priv = player->priv;
+ if (renderer) {
+ g_object_ref (renderer);
+ } else {
+ renderer = swfdec_renderer_new_default (player);
+ }
+ if (priv->renderer)
+ g_object_unref (renderer);
+ priv->renderer = renderer;
+ g_object_notify (G_OBJECT (player), "renderer");
+}
+
+/**
* swfdec_player_get_base_url:
* @player: a #SwfdecPlayer
*
diff --git a/swfdec/swfdec_player.h b/swfdec/swfdec_player.h
index 21f6670..a0a9e94 100644
--- a/swfdec/swfdec_player.h
+++ b/swfdec/swfdec_player.h
@@ -59,6 +59,7 @@ GType swfdec_time_val_get_type (void);
/* forward declarations */
typedef struct _SwfdecPlayerScripting SwfdecPlayerScripting;
+typedef struct _SwfdecRenderer SwfdecRenderer;
typedef struct _SwfdecPlayer SwfdecPlayer;
typedef struct _SwfdecPlayerPrivate SwfdecPlayerPrivate;
@@ -148,6 +149,9 @@ void swfdec_player_set_scripting (SwfdecPlayer * player,
gboolean swfdec_player_get_focus (SwfdecPlayer * player);
void swfdec_player_set_focus (SwfdecPlayer * player,
gboolean focus);
+SwfdecRenderer *swfdec_player_get_renderer (SwfdecPlayer * player);
+void swfdec_player_set_renderer (SwfdecPlayer * player,
+ SwfdecRenderer * renderer);
void swfdec_player_render (SwfdecPlayer * player,
cairo_t * cr,
diff --git a/swfdec/swfdec_player_internal.h b/swfdec/swfdec_player_internal.h
index 7d03034..7b9dd54 100644
--- a/swfdec/swfdec_player_internal.h
+++ b/swfdec/swfdec_player_internal.h
@@ -77,6 +77,7 @@ struct _SwfdecPlayerPrivate
char * variables; /* variables to set on the player */
SwfdecURL * url; /* url or NULL if not set yet */
SwfdecURL * base_url; /* base url or NULL if not set yet */
+ SwfdecRenderer * renderer; /* the renderer to use */
SwfdecPlayerScripting *scripting; /* scripting object */
GHashTable * scripting_callbacks; /* GC string => SwfdecAsFunction mapping of script callbacks */
GType loader_type; /* type to use for creating sockets */
diff --git a/swfdec/swfdec_renderer.c b/swfdec/swfdec_renderer.c
new file mode 100644
index 0000000..00cf5a5
--- /dev/null
+++ b/swfdec/swfdec_renderer.c
@@ -0,0 +1,300 @@
+/* Swfdec
+ * Copyright (C) 2008 Benjamin Otte <otte at gnome.org>
+ *
+ * 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.1 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., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "swfdec_renderer.h"
+#include "swfdec_renderer_internal.h"
+#include "swfdec_cache.h"
+#include "swfdec_player_internal.h"
+
+struct _SwfdecRendererPrivate {
+ cairo_surface_t * surface; /* the surface we assume we render to */
+ SwfdecCache * cache; /* the cache we use for cached items */
+ GHashTable * cache_lookup; /* gpointer => GList mapping */
+};
+
+/*** GTK-DOC ***/
+
+/**
+ * SECTION:SwfdecRenderer
+ * @title: SwfdecRenderer
+ * @short_description: provide accelerated rendering and caching abilities
+ *
+ * The #SwfdecRenderer object is used internally to improve rendering done by
+ * Swfdec.
+ *
+ * The first thing #SwfdecRenderer does is provide a way to cache data relevant
+ * to rendering.
+ *
+ * The second thing it does is provide access to the surface that is used for
+ * rendering, even when not in the process of rendering. This is relevant for
+ * font backends, as different surfaces provide different native fonts. See
+ * swfdec_player_set_default_backend() for details about this.
+ *
+ * The third thing it does is provide a list of virtual functions for critical
+ * operations that you can optimize using subclasses to provide faster
+ * implementations. Note that a working default implementation is provided, so
+ * you only need to override the functions you care about.
+ * See #SwfdecRendererClass for details about these functions.
+ */
+
+
+/*** OBJECT ***/
+
+G_DEFINE_TYPE (SwfdecRenderer, swfdec_renderer, G_TYPE_OBJECT)
+
+enum {
+ PROP_0,
+ PROP_SURFACE
+};
+
+static void
+swfdec_renderer_dispose (GObject *object)
+{
+ SwfdecRendererPrivate *priv = SWFDEC_RENDERER (object)->priv;
+
+ if (priv->surface) {
+ cairo_surface_destroy (priv->surface);
+ priv->surface = NULL;
+ }
+ if (priv->cache_lookup) {
+ GHashTableIter iter;
+ GList *walk;
+ gpointer list;
+ g_hash_table_iter_init (&iter, priv->cache_lookup);
+ while (g_hash_table_iter_next (&iter, NULL, &list)) {
+ for (walk = list; walk; walk = walk->next) {
+ g_object_remove_weak_pointer (walk->data, &walk->data);
+ }
+ g_list_free (list);
+ }
+ g_hash_table_destroy (priv->cache_lookup);
+ priv->cache_lookup = NULL;
+ }
+ if (priv->cache) {
+ g_object_unref (priv->cache);
+ priv->cache = NULL;
+ }
+
+ G_OBJECT_CLASS (swfdec_renderer_parent_class)->dispose (object);
+}
+
+static void
+swfdec_renderer_get_property (GObject *object, guint param_id, GValue *value,
+ GParamSpec *pspec)
+{
+ SwfdecRendererPrivate *priv = SWFDEC_RENDERER (object)->priv;
+
+ switch (param_id) {
+ case PROP_SURFACE:
+ g_value_set_pointer (value, priv->surface);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
+
+static void
+swfdec_renderer_set_property (GObject *object, guint param_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ SwfdecRendererPrivate *priv = SWFDEC_RENDERER (object)->priv;
+
+ switch (param_id) {
+ case PROP_SURFACE:
+ priv->surface = g_value_get_pointer (value);
+ g_assert (priv->surface != NULL);
+ cairo_surface_reference (priv->surface);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
+
+static void
+swfdec_renderer_class_init (SwfdecRendererClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (SwfdecRendererPrivate));
+
+ object_class->dispose = swfdec_renderer_dispose;
+ object_class->get_property = swfdec_renderer_get_property;
+ object_class->set_property = swfdec_renderer_set_property;
+
+ /* FIXME: should be g_param_spec_size(), but no such thing exists */
+ g_object_class_install_property (object_class, PROP_SURFACE,
+ g_param_spec_pointer ("surface", "surface", "cairo surface in use by this renderer",
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+swfdec_renderer_init (SwfdecRenderer *renderer)
+{
+ renderer->priv = G_TYPE_INSTANCE_GET_PRIVATE (renderer, SWFDEC_TYPE_RENDERER, SwfdecRendererPrivate);
+ renderer->priv->cache = swfdec_cache_new (8 * 1024 * 1024);
+}
+
+/*** INTERNAL API ***/
+
+void
+swfdec_renderer_add_cache (SwfdecRenderer *renderer, gpointer key, SwfdecCached *cached)
+{
+ SwfdecRendererPrivate *priv;
+ GList *list;
+
+ g_return_if_fail (SWFDEC_IS_RENDERER (renderer));
+ g_return_if_fail (key != NULL);
+ g_return_if_fail (SWFDEC_IS_CACHED (cached));
+
+ priv = renderer->priv;
+ list = g_hash_table_lookup (priv->cache_lookup, key);
+ list = g_list_prepend (list, cached);
+ /* NB: empty list entries mean object was deleted */
+ g_object_add_weak_pointer (G_OBJECT (cached), &list->data);
+ g_hash_table_insert (priv->cache_lookup, key, list);
+ swfdec_cache_add (priv->cache, cached);
+}
+
+SwfdecCached *
+swfdec_renderer_get_cache (SwfdecRenderer *renderer, gpointer key,
+ SwfdecRendererSearchFunc func, gpointer data)
+{
+ SwfdecRendererPrivate *priv;
+ GList *list, *org, *walk;
+ SwfdecCached *result = NULL;
+
+ g_return_val_if_fail (SWFDEC_IS_RENDERER (renderer), NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+
+ priv = renderer->priv;
+ org = g_hash_table_lookup (priv->cache_lookup, key);
+ list = org;
+ walk = list;
+ while (walk) {
+ /* NB: empty list entries mean object was deleted */
+ if (walk->data == NULL) {
+ GList *next = walk->next;
+ list = g_list_delete_link (list, walk);
+ walk = next;
+ continue;
+ }
+ if (!func || func (walk->data, data)) {
+ result = walk->data;
+ break;
+ }
+ walk = walk->next;
+ }
+ if (org != list)
+ g_hash_table_insert (priv->cache_lookup, key, list);
+ return result;
+}
+
+SwfdecRenderer *
+swfdec_renderer_new_default (SwfdecPlayer *player)
+{
+ cairo_surface_t *surface;
+ SwfdecRenderer *renderer;
+
+ g_return_val_if_fail (SWFDEC_IS_PLAYER (player), NULL);
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 1, 1);
+ renderer = swfdec_renderer_new_for_player (surface, player);
+ cairo_surface_destroy (surface);
+ return renderer;
+}
+
+static const cairo_user_data_key_t cr_key;
+
+void
+swfdec_renderer_attach (SwfdecRenderer *renderer, cairo_t *cr)
+{
+ g_return_if_fail (SWFDEC_IS_RENDERER (renderer));
+ g_return_if_fail (cr != NULL);
+
+ g_object_ref (renderer);
+ if (cairo_set_user_data (cr, &cr_key, renderer, g_object_unref) != CAIRO_STATUS_SUCCESS) {
+ g_warning ("could not attach user data");
+ }
+}
+
+SwfdecRenderer *
+swfdec_renderer_get (cairo_t *cr)
+{
+ g_return_val_if_fail (cr != NULL, NULL);
+
+ return cairo_get_user_data (cr, &cr_key);
+}
+
+/*** PUBLIC API ***/
+
+/**
+ * swfdec_renderer_new:
+ * @surface: a cairo surface
+ *
+ * Creates a new renderer to be used with the given @surface.
+ *
+ * Returns: a new renderer
+ **/
+SwfdecRenderer *
+swfdec_renderer_new (cairo_surface_t *surface)
+{
+ g_return_val_if_fail (surface != NULL, NULL);
+
+ return g_object_new (SWFDEC_TYPE_RENDERER, "surface", surface, NULL);
+}
+
+SwfdecRenderer *
+swfdec_renderer_new_for_player (cairo_surface_t *surface, SwfdecPlayer *player)
+{
+ SwfdecRendererPrivate *priv;
+ SwfdecRenderer *renderer;
+
+ g_return_val_if_fail (surface != NULL, NULL);
+ g_return_val_if_fail (SWFDEC_IS_PLAYER (player), NULL);
+
+ renderer = swfdec_renderer_new (surface);
+ priv = renderer->priv;
+ g_object_unref (priv->cache);
+ priv->cache = g_object_ref (player->priv->cache);
+
+ return renderer;
+}
+
+/**
+ * swfdec_renderer_get_surface:
+ * @renderer: a renderer
+ *
+ * Gets the surface that was used when creating this surface.
+ *
+ * Returns: the surface used by this renderer
+ **/
+cairo_surface_t *
+swfdec_renderer_get_surface (SwfdecRenderer *renderer)
+{
+ g_return_val_if_fail (SWFDEC_IS_RENDERER (renderer), NULL);
+
+ return renderer->priv->surface;
+}
+
diff --git a/swfdec/swfdec_renderer.h b/swfdec/swfdec_renderer.h
new file mode 100644
index 0000000..5d3ce71
--- /dev/null
+++ b/swfdec/swfdec_renderer.h
@@ -0,0 +1,61 @@
+/* Swfdec
+ * Copyright (c) 2008 Benjamin Otte <otte at gnome.org>
+ *
+ * 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.1 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., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifndef _SWFDEC_RENDERER_H_
+#define _SWFDEC_RENDERER_H_
+
+#include <cairo.h>
+#include <swfdec/swfdec_player.h>
+
+G_BEGIN_DECLS
+
+//typedef struct _SwfdecRenderer SwfdecRenderer;
+typedef struct _SwfdecRendererPrivate SwfdecRendererPrivate;
+typedef struct _SwfdecRendererClass SwfdecRendererClass;
+
+#define SWFDEC_TYPE_RENDERER (swfdec_renderer_get_type())
+#define SWFDEC_IS_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_RENDERER))
+#define SWFDEC_IS_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_RENDERER))
+#define SWFDEC_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_RENDERER, SwfdecRenderer))
+#define SWFDEC_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_RENDERER, SwfdecRendererClass))
+#define SWFDEC_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_RENDERER, SwfdecRendererClass))
+
+
+struct _SwfdecRenderer {
+ GObject object;
+
+ SwfdecRendererPrivate *priv;
+};
+
+struct _SwfdecRendererClass
+{
+ GObjectClass object_class;
+};
+
+GType swfdec_renderer_get_type (void);
+
+SwfdecRenderer * swfdec_renderer_new (cairo_surface_t * surface);
+SwfdecRenderer * swfdec_renderer_new_for_player (cairo_surface_t * surface,
+ SwfdecPlayer * player);
+
+cairo_surface_t * swfdec_renderer_get_surface (SwfdecRenderer * renderer);
+
+
+G_END_DECLS
+#endif
diff --git a/swfdec/swfdec_renderer_internal.h b/swfdec/swfdec_renderer_internal.h
new file mode 100644
index 0000000..1f23333
--- /dev/null
+++ b/swfdec/swfdec_renderer_internal.h
@@ -0,0 +1,46 @@
+/* Swfdec
+ * Copyright (c) 2008 Benjamin Otte <otte at gnome.org>
+ *
+ * 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.1 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., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifndef _SWFDEC_RENDERER_INTERNAL_H_
+#define _SWFDEC_RENDERER_INTERNAL_H_
+
+#include <swfdec/swfdec_renderer.h>
+#include <swfdec/swfdec_cached.h>
+
+G_BEGIN_DECLS
+
+
+typedef gboolean SwfdecRendererSearchFunc (SwfdecCached *cached, gpointer data);
+
+SwfdecRenderer * swfdec_renderer_new_default (SwfdecPlayer * player);
+
+void swfdec_renderer_attach (SwfdecRenderer * renderer,
+ cairo_t * cr);
+SwfdecRenderer * swfdec_renderer_get (cairo_t * cr);
+void swfdec_renderer_add_cache (SwfdecRenderer * renderer,
+ gpointer key,
+ SwfdecCached * value);
+SwfdecCached * swfdec_renderer_get_cache (SwfdecRenderer * renderer,
+ gpointer key,
+ SwfdecRendererSearchFunc func,
+ gpointer data);
+
+
+G_END_DECLS
+#endif
commit 9861871f7b09a893d63f85d2619047a5acc06294
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Apr 8 10:54:50 2008 +0200
terminate vararg list with NULL
Why didn't gcc warn me?!
diff --git a/swfdec/swfdec_cache.c b/swfdec/swfdec_cache.c
index 465a945..1528fac 100644
--- a/swfdec/swfdec_cache.c
+++ b/swfdec/swfdec_cache.c
@@ -122,7 +122,7 @@ swfdec_cache_init (SwfdecCache *cache)
SwfdecCache *
swfdec_cache_new (gsize max_size)
{
- return g_object_new (SWFDEC_TYPE_CACHE, "max-cache-size", max_size);
+ return g_object_new (SWFDEC_TYPE_CACHE, "max-cache-size", max_size, NULL);
}
gsize
commit 787f705e69e82cc2cdd6aa417fdc054d914c8e59
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Apr 7 21:57:01 2008 +0200
remove useless headers
diff --git a/swfdec/swfdec_cache.h b/swfdec/swfdec_cache.h
index 4b87701..84d9a3a 100644
--- a/swfdec/swfdec_cache.h
+++ b/swfdec/swfdec_cache.h
@@ -20,8 +20,6 @@
#ifndef _SWFDEC_CACHE_H_
#define _SWFDEC_CACHE_H_
-#include <cairo.h>
-#include <swfdec/swfdec_cache.h>
#include <swfdec/swfdec_cached.h>
G_BEGIN_DECLS
commit 4ce79386fbbeb5557cd17981806f8ed67926cf6a
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Apr 7 21:52:07 2008 +0200
rewrite cache handling
we now create objects to be cached and don't use a member of some base objects
for caching. The nice side effect is that we can now cache n elements per object
and not just one.
diff --git a/swfdec/Makefile.am b/swfdec/Makefile.am
index 016c2a9..f158c66 100644
--- a/swfdec/Makefile.am
+++ b/swfdec/Makefile.am
@@ -53,6 +53,7 @@ libswfdec_source_files = \
swfdec_button_movie_as.c \
swfdec_cache.c \
swfdec_cached.c \
+ swfdec_cached_image.c \
swfdec_camera.c \
swfdec_character.c \
swfdec_codec_adpcm.c \
@@ -230,6 +231,7 @@ noinst_HEADERS = \
swfdec_button_movie.h \
swfdec_cache.h \
swfdec_cached.h \
+ swfdec_cached_image.h \
swfdec_character.h \
swfdec_codec_audio.h \
swfdec_codec_video.h \
diff --git a/swfdec/swfdec_cache.c b/swfdec/swfdec_cache.c
index 48104e6..465a945 100644
--- a/swfdec/swfdec_cache.c
+++ b/swfdec/swfdec_cache.c
@@ -1,6 +1,6 @@
/* Swfdec
* Copyright (C) 2005 David Schleef <ds at schleef.org>
- * 2007 Benjamin Otte <otte at gnome.org>
+ * 2007-2008 Benjamin Otte <otte at gnome.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -25,140 +25,183 @@
#include "swfdec_cache.h"
#include "swfdec_debug.h"
-SwfdecCache *
-swfdec_cache_new (gulong max_size)
-{
- SwfdecCache *cache;
-
- g_return_val_if_fail (max_size > 0, NULL);
- cache = g_new0 (SwfdecCache, 1);
- cache->refcount = 1;
- cache->queue = g_queue_new ();
- cache->max_size = max_size;
+G_DEFINE_TYPE (SwfdecCache, swfdec_cache, G_TYPE_OBJECT)
+
+enum {
+ PROP_0,
+ PROP_CACHE_SIZE,
+ PROP_MAX_CACHE_SIZE,
+};
- return cache;
+/* NB: assumes that the cached was already removed from cache->list */
+static void
+swfdec_cache_remove (SwfdecCache *cache, SwfdecCached *cached)
+{
+ cache->size -= swfdec_cached_get_size (cached);
+ g_signal_handlers_disconnect_matched (cached,
+ G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, cache);
+ g_object_unref (cached);
}
-void
-swfdec_cache_ref (SwfdecCache *cache)
+static void
+swfdec_cache_dispose (GObject *object)
{
- g_return_if_fail (cache != NULL);
+ SwfdecCache *cache = SWFDEC_CACHE (object);
+ SwfdecCached *cached;
+
+ if (cache->queue) {
+ while ((cached = g_queue_pop_tail (cache->queue)))
+ swfdec_cache_remove (cache, cached);
+ g_queue_free (cache->queue);
+ }
+ g_assert (cache->size == 0);
- cache->refcount++;
+ G_OBJECT_CLASS (swfdec_cache_parent_class)->dispose (object);
}
-void
-swfdec_cache_unref (SwfdecCache *cache)
+static void
+swfdec_cache_get_property (GObject *object, guint param_id, GValue *value,
+ GParamSpec *pspec)
{
- g_return_if_fail (cache != NULL);
- g_return_if_fail (cache->refcount > 0);
+ SwfdecCache *cache = SWFDEC_CACHE (object);
+
+ switch (param_id) {
+ case PROP_CACHE_SIZE:
+ g_value_set_ulong (value, cache->size);
+ break;
+ case PROP_MAX_CACHE_SIZE:
+ g_value_set_ulong (value, cache->max_size);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
- cache->refcount--;
- if (cache->refcount > 0)
- return;
+static void
+swfdec_cache_set_property (GObject *object, guint param_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ SwfdecCache *cache = SWFDEC_CACHE (object);
+
+ switch (param_id) {
+ case PROP_MAX_CACHE_SIZE:
+ swfdec_cache_set_max_cache_size (cache, g_value_get_ulong (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
- g_queue_free (cache->queue);
- g_free (cache);
+static void
+swfdec_cache_class_init (SwfdecCacheClass * g_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (g_class);
+
+ object_class->dispose = swfdec_cache_dispose;
+ object_class->get_property = swfdec_cache_get_property;
+ object_class->set_property = swfdec_cache_set_property;
+
+ /* FIXME: should be g_param_spec_size(), but no such thing exists */
+ g_object_class_install_property (object_class, PROP_CACHE_SIZE,
+ g_param_spec_ulong ("cache-size", "cache-size", "current size of cache",
+ 0, G_MAXULONG, 0, G_PARAM_READABLE));
+ g_object_class_install_property (object_class, PROP_MAX_CACHE_SIZE,
+ g_param_spec_ulong ("max-cache-size", "max-cache-size", "maximum allowed size of cache",
+ 0, G_MAXULONG, 1024 * 1024, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
}
-gulong
-swfdec_cache_get_usage (SwfdecCache *cache)
+static void
+swfdec_cache_init (SwfdecCache *cache)
{
- g_return_val_if_fail (cache != NULL, 0);
+ cache->queue = g_queue_new ();
+}
- return cache->usage;
+SwfdecCache *
+swfdec_cache_new (gsize max_size)
+{
+ return g_object_new (SWFDEC_TYPE_CACHE, "max-cache-size", max_size);
}
-void
-swfdec_cache_shrink (SwfdecCache *cache, gulong max_usage)
+gsize
+swfdec_cache_get_cache_size (SwfdecCache *cache)
{
- g_return_if_fail (cache != NULL);
-
- while (cache->usage > max_usage) {
- SwfdecCacheHandle *handle = g_queue_pop_tail (cache->queue);
- g_assert (handle);
- cache->usage -= handle->size;
- SWFDEC_LOG ("%p removing %p (%lu => %lu)", cache, handle,
- cache->usage + handle->size, cache->usage);
- handle->unload (handle);
- }
+ g_return_val_if_fail (SWFDEC_IS_CACHE (cache), 0);
+
+ return cache->size;
}
-gulong
-swfdec_cache_get_size (SwfdecCache *cache)
+gsize
+swfdec_cache_get_max_cache_size (SwfdecCache *cache)
{
- g_return_val_if_fail (cache != NULL, 0);
+ g_return_val_if_fail (SWFDEC_IS_CACHE (cache), 0);
return cache->max_size;
}
void
-swfdec_cache_set_size (SwfdecCache *cache, gulong max_usage)
+swfdec_cache_set_max_cache_size (SwfdecCache *cache, gsize max_size)
{
- g_return_if_fail (cache != NULL);
+ g_return_if_fail (SWFDEC_IS_CACHE (cache));
- swfdec_cache_shrink (cache, max_usage);
- cache->max_size = max_usage;
+ cache->max_size = max_size;
+ swfdec_cache_shrink (cache, max_size);
+ g_object_notify (G_OBJECT (cache), "max-cache-size");
}
-/**
- * swfdec_cache_add_handle:
- * @cache: a #SwfdecCache
- * @handle: a handle to add
- *
- * Adds @handle to @cache. If not enough space is available in the cache,
- * the cache will unload existing handles first. If handle is already part
- * of cache, its usage information will be updated. This will make it less
- * likely that it gets unloaded.
- **/
void
-swfdec_cache_add_handle (SwfdecCache *cache, const SwfdecCacheHandle *handle)
+swfdec_cache_shrink (SwfdecCache *cache, gsize size)
{
- GList *list;
-
- g_return_if_fail (cache != NULL);
- g_return_if_fail (handle != NULL);
- g_return_if_fail (handle->size > 0);
- g_return_if_fail (handle->unload != NULL);
-
- list = g_queue_find (cache->queue, handle);
- if (list) {
- /* bring to front of queue */
- g_queue_unlink (cache->queue, list);
- g_queue_push_head_link (cache->queue, list);
- } else {
- swfdec_cache_shrink (cache, cache->max_size - handle->size);
- g_queue_push_head (cache->queue, (gpointer) handle);
- cache->usage += handle->size;
- SWFDEC_LOG ("%p adding %p (%lu => %lu)", cache, handle,
- cache->usage - handle->size, cache->usage);
- }
+ SwfdecCached *cached;
+
+ g_return_if_fail (SWFDEC_IS_CACHE (cache));
+
+ if (size >= cache->size)
+ return;
+
+ do {
+ cached = g_queue_pop_tail (cache->queue);
+ g_assert (cached);
+ swfdec_cache_remove (cache, cached);
+ } while (size < cache->size);
+ g_object_notify (G_OBJECT (cache), "cache-size");
+}
+
+static void
+swfdec_cache_use_cached (SwfdecCached *cached, SwfdecCache *cache)
+{
+ /* move cached item to the front of the queue */
+ g_queue_remove (cache->queue, cached);
+ g_queue_push_head (cache->queue, cached);
+}
+
+static void
+swfdec_cache_unuse_cached (SwfdecCached *cached, SwfdecCache *cache)
+{
+ /* move cached item to the front of the queue */
+ g_queue_remove (cache->queue, cached);
+ swfdec_cache_remove (cache, cached);
}
-/**
- * swfdec_cache_remove_handle:
- * @cache: a #SwfdecCache
- * @handle: the handle to remove
- *
- * Removes the given @handle from the @cache, if it was part of it. If the
- * handle wasn't part of the cache, nothing happens.
- **/
void
-swfdec_cache_remove_handle (SwfdecCache *cache, const SwfdecCacheHandle *handle)
+swfdec_cache_add (SwfdecCache *cache, SwfdecCached *cached)
{
- GList *list;
-
- g_return_if_fail (cache != NULL);
- g_return_if_fail (handle != NULL);
- g_return_if_fail (handle->size > 0);
- g_return_if_fail (handle->unload != NULL);
-
- list = g_queue_find (cache->queue, handle);
- if (list) {
- g_queue_delete_link (cache->queue, list);
- cache->usage -= handle->size;
- SWFDEC_LOG ("%p removing %p (%lu => %lu)", cache, handle,
- cache->usage + handle->size, cache->usage);
- }
+ gsize needed_size;
+
+ g_return_if_fail (SWFDEC_IS_CACHE (cache));
+ g_return_if_fail (SWFDEC_IS_CACHED (cached));
+
+ needed_size = swfdec_cached_get_size (cached);
+ if (needed_size > cache->max_size)
+ return;
+
+ g_object_ref (cached);
+ swfdec_cache_shrink (cache, cache->max_size - needed_size);
+ cache->size += needed_size;
+ g_signal_connect (cached, "use", G_CALLBACK (swfdec_cache_use_cached), cache);
+ g_signal_connect (cached, "unuse", G_CALLBACK (swfdec_cache_unuse_cached), cache);
+ g_queue_push_head (cache->queue, cached);
}
+
diff --git a/swfdec/swfdec_cache.h b/swfdec/swfdec_cache.h
index 89b589d..4b87701 100644
--- a/swfdec/swfdec_cache.h
+++ b/swfdec/swfdec_cache.h
@@ -1,6 +1,5 @@
/* Swfdec
- * Copyright (C) 2005 David Schleef <ds at schleef.org>
- * 2007 Benjamin Otte <otte at gnome.org>
+ * Copyright (c) 2008 Benjamin Otte <otte at gnome.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -21,43 +20,53 @@
#ifndef _SWFDEC_CACHE_H_
#define _SWFDEC_CACHE_H_
-#include <swfdec/swfdec_types.h>
+#include <cairo.h>
+#include <swfdec/swfdec_cache.h>
+#include <swfdec/swfdec_cached.h>
G_BEGIN_DECLS
-//typedef struct _SwfdecCache SwfdecCache;
-//typedef struct _SwfdecCacheHandle SwfdecCacheHandle;
+typedef struct _SwfdecCache SwfdecCache;
+typedef struct _SwfdecCacheClass SwfdecCacheClass;
+
+#define SWFDEC_TYPE_CACHE (swfdec_cache_get_type())
+#define SWFDEC_IS_CACHE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_CACHE))
+#define SWFDEC_IS_CACHE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_CACHE))
+#define SWFDEC_CACHE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_CACHE, SwfdecCache))
+#define SWFDEC_CACHE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_CACHE, SwfdecCacheClass))
+#define SWFDEC_CACHE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_CACHE, SwfdecCacheClass))
+
struct _SwfdecCache {
- guint refcount; /* reference count */
- gulong max_size; /* max size of cache */
- gulong usage; /* current size of cache */
+ GObject object;
- GQueue * queue; /* queue of loaded SwfdecCacheHandle, sorted by most recently used */
-};
+ gsize max_size; /* maximum amount of data allowed in cache, before starting to purge */
+ gsize size; /* current amount of data in cache */
-struct _SwfdecCacheHandle {
- gulong size; /* size of this item */
+ GQueue * queue; /* queue of SwfdecCached, most recently used first */
+};
- GDestroyNotify unload; /* function called when unloading this handle */
+struct _SwfdecCacheClass
+{
+ GObjectClass object_class;
};
-SwfdecCache * swfdec_cache_new (gulong max_size);
-void swfdec_cache_ref (SwfdecCache * cache);
-void swfdec_cache_unref (SwfdecCache * cache);
+GType swfdec_cache_get_type (void);
-gulong swfdec_cache_get_size (SwfdecCache * cache);
-void swfdec_cache_set_size (SwfdecCache * cache,
- gulong max_usage);
-gulong swfdec_cache_get_usage (SwfdecCache * cache);
-void swfdec_cache_shrink (SwfdecCache * cache,
- gulong max_usage);
-void swfdec_cache_add_handle (SwfdecCache * cache,
- const SwfdecCacheHandle *handle);
-void swfdec_cache_remove_handle (SwfdecCache * cache,
- const SwfdecCacheHandle *handle);
+SwfdecCache * swfdec_cache_new (gsize max_size);
+gsize swfdec_cache_get_cache_size (SwfdecCache * cache);
+gsize swfdec_cache_get_max_cache_size (SwfdecCache * cache);
+void swfdec_cache_set_max_cache_size (SwfdecCache * cache,
+ gsize max_size);
-G_END_DECLS
+void swfdec_cache_shrink (SwfdecCache * cache,
+ gsize size);
+void swfdec_cache_add (SwfdecCache * cache,
+ SwfdecCached * cached);
+
+
+
+G_END_DECLS
#endif
diff --git a/swfdec/swfdec_cached.c b/swfdec/swfdec_cached.c
index 4279d1e..173868e 100644
--- a/swfdec/swfdec_cached.c
+++ b/swfdec/swfdec_cached.c
@@ -1,5 +1,5 @@
/* Swfdec
- * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ * Copyright (C) 2008 Benjamin Otte <otte at gnome.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -25,99 +25,101 @@
#include "swfdec_debug.h"
-G_DEFINE_ABSTRACT_TYPE (SwfdecCached, swfdec_cached, SWFDEC_TYPE_CHARACTER)
+G_DEFINE_ABSTRACT_TYPE (SwfdecCached, swfdec_cached, G_TYPE_OBJECT)
-static void
-swfdec_cached_dispose (GObject *object)
-{
- SwfdecCached * cached = SWFDEC_CACHED (object);
+enum {
+ PROP_0,
+ PROP_SIZE
+};
- swfdec_cached_unload (cached);
- swfdec_cached_set_cache (cached, NULL);
+enum {
+ USE,
+ UNUSE,
+ LAST_SIGNAL
+};
- G_OBJECT_CLASS (swfdec_cached_parent_class)->dispose (object);
-}
+guint signals[LAST_SIGNAL] = { 0, };
static void
-swfdec_cached_class_init (SwfdecCachedClass * g_class)
+swfdec_cached_get_property (GObject *object, guint param_id, GValue *value,
+ GParamSpec *pspec)
{
- GObjectClass *object_class = G_OBJECT_CLASS (g_class);
-
- object_class->dispose = swfdec_cached_dispose;
+ SwfdecCached *cached = SWFDEC_CACHED (object);
+
+ switch (param_id) {
+ case PROP_SIZE:
+ g_value_set_ulong (value, cached->size);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
}
static void
-swfdec_cached_init (SwfdecCached * cached)
+swfdec_cached_set_property (GObject *object, guint param_id, const GValue *value,
+ GParamSpec *pspec)
{
+ SwfdecCached *cached = SWFDEC_CACHED (object);
+
+ switch (param_id) {
+ case PROP_SIZE:
+ cached->size = g_value_get_ulong (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
}
-void
-swfdec_cached_set_cache (SwfdecCached *cached, SwfdecCache *cache)
+static void
+swfdec_cached_class_init (SwfdecCachedClass * g_class)
{
- g_return_if_fail (SWFDEC_IS_CACHED (cached));
+ GObjectClass *object_class = G_OBJECT_CLASS (g_class);
- if (cached->cache) {
- if (cached->handle.unload)
- swfdec_cache_remove_handle (cached->cache, &cached->handle);
- swfdec_cache_unref (cached->cache);
- }
- cached->cache = cache;
- if (cache) {
- swfdec_cache_ref (cache);
- if (cached->handle.unload)
- swfdec_cache_add_handle (cached->cache, &cached->handle);
- }
+ object_class->get_property = swfdec_cached_get_property;
+ object_class->set_property = swfdec_cached_set_property;
+
+ /* FIXME: should be g_param_spec_size(), but no such thing exists */
+ g_object_class_install_property (object_class, PROP_SIZE,
+ g_param_spec_ulong ("size", "size", "size of this object in bytes",
+ 0, G_MAXULONG, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ signals[USE] = g_signal_new ("use", G_TYPE_FROM_CLASS (g_class),
+ G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ signals[UNUSE] = g_signal_new ("unuse", G_TYPE_FROM_CLASS (g_class),
+ G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
}
static void
-swfdec_cached_unload_func (gpointer data)
+swfdec_cached_init (SwfdecCached * cached)
{
- SwfdecCached *cached = SWFDEC_CACHED ((void *) ((guint8 *) data - G_STRUCT_OFFSET (SwfdecCached, handle)));
-
- cached->handle.unload = NULL;
- swfdec_cached_unload (cached);
+ cached->size = sizeof (SwfdecCached);
}
void
-swfdec_cached_load (SwfdecCached *cached, guint size)
+swfdec_cached_use (SwfdecCached *cached)
{
g_return_if_fail (SWFDEC_IS_CACHED (cached));
- g_return_if_fail (cached->handle.unload == NULL);
- g_return_if_fail (size > 0);
- cached->handle.unload = swfdec_cached_unload_func;
- cached->handle.size = size;
- if (cached->cache)
- swfdec_cache_add_handle (cached->cache, &cached->handle);
+ g_signal_emit (cached, signals[USE], 0);
}
void
-swfdec_cached_use (SwfdecCached *cached)
+swfdec_cached_unuse (SwfdecCached *cached)
{
g_return_if_fail (SWFDEC_IS_CACHED (cached));
- g_return_if_fail (cached->handle.unload != NULL);
- if (cached->cache)
- swfdec_cache_add_handle (cached->cache, &cached->handle);
+ g_signal_emit (cached, signals[UNUSE], 0);
}
-void
-swfdec_cached_unload (SwfdecCached *cached)
+gsize
+swfdec_cached_get_size (SwfdecCached *cached)
{
- g_return_if_fail (SWFDEC_IS_CACHED (cached));
+ g_return_val_if_fail (SWFDEC_IS_CACHED (cached), 0);
- if (cached->handle.unload) {
- if (cached->cache)
- swfdec_cache_remove_handle (cached->cache, &cached->handle);
- cached->handle.unload = NULL;
- }
- if (cached->handle.size) {
- SwfdecCachedClass *klass;
-
- klass = SWFDEC_CACHED_GET_CLASS (cached);
- cached->handle.size = 0;
- g_return_if_fail (klass->unload != NULL);
- klass->unload (cached);
- }
+ return cached->size;
}
diff --git a/swfdec/swfdec_cached.h b/swfdec/swfdec_cached.h
index 52365f4..5eb37b9 100644
--- a/swfdec/swfdec_cached.h
+++ b/swfdec/swfdec_cached.h
@@ -1,5 +1,5 @@
/* Swfdec
- * Copyright (c) 2007 Benjamin Otte <otte at gnome.org>
+ * Copyright (c) 2008 Benjamin Otte <otte at gnome.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -20,9 +20,7 @@
#ifndef _SWFDEC_CACHED_H_
#define _SWFDEC_CACHED_H_
-#include <cairo.h>
-#include <swfdec/swfdec_cache.h>
-#include <swfdec/swfdec_character.h>
+#include <glib-object.h>
G_BEGIN_DECLS
@@ -38,27 +36,27 @@ typedef struct _SwfdecCachedClass SwfdecCachedClass;
struct _SwfdecCached {
- SwfdecCharacter character;
+ GObject object;
- SwfdecCache * cache; /* cache to use for cached */
- SwfdecCacheHandle handle; /* handle to unload surface */
+ gsize size;
};
struct _SwfdecCachedClass
{
- SwfdecCharacterClass character_class;
+ GObjectClass object_class;
- void (* unload) (SwfdecCached * cached);
+ /* signals */
+ void (* use) (SwfdecCached * cached);
+ void (* unuse) (SwfdecCached * cached);
};
GType swfdec_cached_get_type (void);
-void swfdec_cached_load (SwfdecCached * cached,
- guint size);
+gsize swfdec_cached_get_size (SwfdecCached * cached);
+
+/* for subclasses */
void swfdec_cached_use (SwfdecCached * cached);
-void swfdec_cached_unload (SwfdecCached * cached);
-void swfdec_cached_set_cache (SwfdecCached * cached,
- SwfdecCache * cache);
+void swfdec_cached_unuse (SwfdecCached * cached);
G_END_DECLS
diff --git a/swfdec/swfdec_cached_image.c b/swfdec/swfdec_cached_image.c
new file mode 100644
index 0000000..2cc6c76
--- /dev/null
+++ b/swfdec/swfdec_cached_image.c
@@ -0,0 +1,104 @@
+/* Swfdec
+ * Copyright (C) 2008 Benjamin Otte <otte at gnome.org>
+ *
+ * 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.1 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., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "swfdec_cached_image.h"
+#include "swfdec_debug.h"
+
+G_DEFINE_TYPE (SwfdecCachedImage, swfdec_cached_image, SWFDEC_TYPE_CACHED)
+
+static void
+swfdec_cached_image_dispose (GObject *object)
+{
+ SwfdecCachedImage *image = SWFDEC_CACHED_IMAGE (object);
+
+ if (image->surface) {
+ cairo_surface_destroy (image->surface);
+ image->surface = NULL;
+ }
+
+ G_OBJECT_CLASS (swfdec_cached_image_parent_class)->dispose (object);
+}
+
+static void
+swfdec_cached_image_class_init (SwfdecCachedImageClass * g_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (g_class);
+
+ object_class->dispose = swfdec_cached_image_dispose;
+}
+
+static void
+swfdec_cached_image_init (SwfdecCachedImage *cached)
+{
+ swfdec_color_transform_init_identity (&cached->trans);
+}
+
+SwfdecCachedImage *
+swfdec_cached_image_new (guint8 *image_data, cairo_format_t format,
+ guint width, guint height, guint rowstride)
+{
+ SwfdecCachedImage *image;
+ static const cairo_user_data_key_t key;
+ gulong size;
+
+ g_return_val_if_fail (image_data != NULL, NULL);
+ g_return_val_if_fail (width > 0, NULL);
+ g_return_val_if_fail (height > 0, NULL);
+ g_return_val_if_fail (rowstride > 0, NULL);
+
+ /* FIXME: sizeof (cairo_surface_t) */
+ size = sizeof (SwfdecCachedImage) + height * rowstride;
+ image = g_object_new (SWFDEC_TYPE_CACHED_IMAGE, "size", size, NULL);
+ image->surface = cairo_image_surface_create_for_data (image_data, format,
+ width, height, rowstride);
+ if (cairo_surface_set_user_data (image->surface, &key, image_data, g_free) != CAIRO_STATUS_SUCCESS) {
+ /* guess we should abort here due to OOM? */
+ g_warning ("failed to register data free function");
+ }
+
+ return image;
+}
+
+SwfdecCachedImage *
+swfdec_cached_image_new_for_surface (cairo_surface_t *surface, gsize size)
+{
+ SwfdecCachedImage *image;
+
+ g_return_val_if_fail (surface != NULL, NULL);
+ g_return_val_if_fail (size > 0, NULL);
+
+ size += sizeof (SwfdecCachedImage);
+ image = g_object_new (SWFDEC_TYPE_CACHED_IMAGE, "size", size, NULL);
+ image->surface = cairo_surface_reference (surface);
+
+ return image;
+}
+
+cairo_surface_t *
+swfdec_cached_image_get_surface (SwfdecCachedImage *image)
+{
+ g_return_val_if_fail (SWFDEC_IS_CACHED_IMAGE (image), NULL);
+
+ return cairo_surface_reference (image->surface);
+}
+
diff --git a/swfdec/swfdec_cached_image.h b/swfdec/swfdec_cached_image.h
new file mode 100644
index 0000000..d370a06
--- /dev/null
+++ b/swfdec/swfdec_cached_image.h
@@ -0,0 +1,68 @@
+/* Swfdec
+ * Copyright (c) 2008 Benjamin Otte <otte at gnome.org>
+ *
+ * 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.1 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., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifndef _SWFDEC_CACHED_IMAGE_H_
+#define _SWFDEC_CACHED_IMAGE_H_
+
+#include <cairo.h>
+#include <swfdec/swfdec_cached.h>
+#include <swfdec/swfdec_color.h>
+
+G_BEGIN_DECLS
+
+typedef struct _SwfdecCachedImage SwfdecCachedImage;
+typedef struct _SwfdecCachedImageClass SwfdecCachedImageClass;
+
+#define SWFDEC_TYPE_CACHED_IMAGE (swfdec_cached_image_get_type())
+#define SWFDEC_IS_CACHED_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_CACHED_IMAGE))
+#define SWFDEC_IS_CACHED_IMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_CACHED_IMAGE))
+#define SWFDEC_CACHED_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_CACHED_IMAGE, SwfdecCachedImage))
+#define SWFDEC_CACHED_IMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_CACHED_IMAGE, SwfdecCachedImageClass))
+#define SWFDEC_CACHED_IMAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_CACHED_IMAGE, SwfdecCachedImageClass))
+
+
+struct _SwfdecCachedImage {
+ SwfdecCached cached;
+
+ cairo_surface_t * surface; /* the surface */
+ SwfdecColorTransform trans; /* the transform that has been applied to this surface */
+};
+
+struct _SwfdecCachedImageClass
+{
+ SwfdecCachedClass cached_class;
+};
+
+GType swfdec_cached_image_get_type (void);
+
+SwfdecCachedImage * swfdec_cached_image_new (guint8 * image_data,
+ cairo_format_t format,
+ guint width,
+ guint height,
+ guint rowstride);
+SwfdecCachedImage * swfdec_cached_image_new_for_surface
+ (cairo_surface_t * surface,
+ gsize size);
+
+
+cairo_surface_t * swfdec_cached_image_get_surface (SwfdecCachedImage * image);
+
+
+G_END_DECLS
+#endif
diff --git a/swfdec/swfdec_image.c b/swfdec/swfdec_image.c
index b4bff6c..1be91b8 100644
--- a/swfdec/swfdec_image.c
+++ b/swfdec/swfdec_image.c
@@ -1,7 +1,7 @@
/* Swfdec
* Copyright (C) 2003-2006 David Schleef <ds at schleef.org>
* 2005-2006 Eric Anholt <eric at anholt.net>
- * 2006-2007 Benjamin Otte <otte at gnome.org>
+ * 2006-2008 Benjamin Otte <otte at gnome.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -29,7 +29,7 @@
#include "jpeg.h"
#include "swfdec_image.h"
-#include "swfdec_cache.h"
+#include "swfdec_cached_image.h"
#include "swfdec_debug.h"
#include "swfdec_swf_decoder.h"
@@ -41,18 +41,7 @@ static void swfdec_image_colormap_decode (SwfdecImage * image,
unsigned char *dest,
unsigned char *src, unsigned char *colormap, int colormap_len);
-G_DEFINE_TYPE (SwfdecImage, swfdec_image, SWFDEC_TYPE_CACHED)
-
-static void
-swfdec_image_unload (SwfdecCached *cached)
-{
- SwfdecImage *image = SWFDEC_IMAGE (cached);
-
- if (image->surface) {
- cairo_surface_destroy (image->surface);
- image->surface = NULL;
- }
-}
+G_DEFINE_TYPE (SwfdecImage, swfdec_image, SWFDEC_TYPE_CHARACTER)
static void
swfdec_image_dispose (GObject *object)
@@ -69,19 +58,14 @@ swfdec_image_dispose (GObject *object)
}
G_OBJECT_CLASS (swfdec_image_parent_class)->dispose (object);
-
- g_assert (image->surface == NULL);
}
static void
swfdec_image_class_init (SwfdecImageClass * g_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (g_class);
- SwfdecCachedClass *cached_class = SWFDEC_CACHED_CLASS (g_class);
object_class->dispose = swfdec_image_dispose;
-
- cached_class->unload = swfdec_image_unload;
}
static void
@@ -167,7 +151,7 @@ swfdec_jpeg_decode_argb (unsigned char *data1, int length1,
return ret;
}
-static void
+static SwfdecCachedImage *
swfdec_image_jpeg_load (SwfdecImage *image)
{
gboolean ret;
@@ -186,15 +170,13 @@ swfdec_image_jpeg_load (SwfdecImage *image)
}
if (!ret)
- return;
-
- swfdec_cached_load (SWFDEC_CACHED (image), 4 * image->width * image->height);
- image->surface = cairo_image_surface_create_for_data (data, CAIRO_FORMAT_RGB24,
- image->width, image->height, image->width * 4);
- cairo_surface_set_user_data (image->surface, &key, data, g_free);
+ return NULL;
SWFDEC_LOG (" width = %d", image->width);
SWFDEC_LOG (" height = %d", image->height);
+
+ return swfdec_cached_image_new (data, CAIRO_FORMAT_RGB24, image->width,
+ image->height, 4 * image->width);
}
int
@@ -217,7 +199,7 @@ tag_func_define_bits_jpeg_2 (SwfdecSwfDecoder * s, guint tag)
return SWFDEC_STATUS_OK;
}
-static void
+static SwfdecCachedImage *
swfdec_image_jpeg2_load (SwfdecImage *image)
{
gboolean ret;
@@ -227,15 +209,13 @@ swfdec_image_jpeg2_load (SwfdecImage *image)
NULL, 0,
(void *)&data, &image->width, &image->height);
if (!ret)
- return;
-
- swfdec_cached_load (SWFDEC_CACHED (image), 4 * image->width * image->height);
- image->surface = cairo_image_surface_create_for_data (data, CAIRO_FORMAT_RGB24,
- image->width, image->height, image->width * 4);
- cairo_surface_set_user_data (image->surface, &key, data, g_free);
+ return NULL;
SWFDEC_LOG (" width = %d", image->width);
SWFDEC_LOG (" height = %d", image->height);
+
+ return swfdec_cached_image_new (data, CAIRO_FORMAT_RGB24, image->width,
+ image->height, 4 * image->width);
}
int
@@ -258,7 +238,7 @@ tag_func_define_bits_jpeg_3 (SwfdecSwfDecoder * s, guint tag)
return SWFDEC_STATUS_OK;
}
-static void
+static SwfdecCachedImage *
swfdec_image_jpeg3_load (SwfdecImage *image)
{
SwfdecBits bits;
@@ -272,7 +252,7 @@ swfdec_image_jpeg3_load (SwfdecImage *image)
jpeg_length = swfdec_bits_get_u32 (&bits);
buffer = swfdec_bits_get_buffer (&bits, jpeg_length);
if (buffer == NULL)
- return;
+ return NULL;
ret = swfdec_jpeg_decode_argb (buffer->data, buffer->length,
NULL, 0,
@@ -280,9 +260,7 @@ swfdec_image_jpeg3_load (SwfdecImage *image)
swfdec_buffer_unref (buffer);
if (!ret)
- return;
-
- swfdec_cached_load (SWFDEC_CACHED (image), 4 * image->width * image->height);
+ return NULL;
buffer = swfdec_bits_decompress (&bits, -1, image->width * image->height);
if (buffer) {
@@ -295,9 +273,8 @@ swfdec_image_jpeg3_load (SwfdecImage *image)
SWFDEC_LOG (" width = %d", image->width);
SWFDEC_LOG (" height = %d", image->height);
- image->surface = cairo_image_surface_create_for_data (data,
- CAIRO_FORMAT_ARGB32, image->width, image->height, image->width * 4);
- cairo_surface_set_user_data (image->surface, &key, data, g_free);
+ return swfdec_cached_image_new (data, CAIRO_FORMAT_RGB24, image->width,
+ image->height, 4 * image->width);
}
static void
@@ -317,7 +294,7 @@ merge_alpha (SwfdecImage * image, unsigned char *image_data,
}
}
-static void
+static SwfdecCachedImage *
swfdec_image_lossless_load (SwfdecImage *image)
{
int format;
@@ -347,8 +324,7 @@ swfdec_image_lossless_load (SwfdecImage *image)
SWFDEC_LOG ("color_table_size = %d", color_table_size);
if (image->width == 0 || image->height == 0)
- return;
- swfdec_cached_load (SWFDEC_CACHED (image), 4 * image->width * image->height);
+ return NULL;
if (format == 3) {
SwfdecBuffer *buffer;
@@ -467,22 +443,16 @@ swfdec_image_lossless_load (SwfdecImage *image)
p++;
}
}
- image->surface = cairo_image_surface_create_for_data (data,
- have_alpha ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24,
- image->width, image->height, image->width * 4);
- cairo_surface_set_user_data (image->surface, &key, buffer,
- (cairo_destroy_func_t) swfdec_buffer_unref);
- return;
+ data = g_memdup (buffer->data, buffer->length);
} else {
SWFDEC_ERROR ("unknown lossless image format %u", format);
- return;
+ return NULL;
}
out:
- image->surface = cairo_image_surface_create_for_data (data,
+ return swfdec_cached_image_new (data,
have_alpha ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24,
image->width, image->height, image->width * 4);
- cairo_surface_set_user_data (image->surface, &key, data, g_free);
}
int
@@ -576,59 +546,67 @@ swfdec_image_png_read (void *bitsp, unsigned char *data, unsigned int length)
return CAIRO_STATUS_SUCCESS;
}
-static void
+static SwfdecCachedImage *
swfdec_image_png_load (SwfdecImage *image)
{
SwfdecBits bits;
+ cairo_surface_t *surface;
+ SwfdecCachedImage *cached;
swfdec_bits_init (&bits, image->raw_data);
- image->surface = cairo_image_surface_create_from_png_stream (
+ surface = cairo_image_surface_create_from_png_stream (
swfdec_image_png_read, &bits);
- image->width = cairo_image_surface_get_width (image->surface);
- image->height = cairo_image_surface_get_height (image->surface);
- swfdec_cached_load (SWFDEC_CACHED (image), image->height *
- cairo_image_surface_get_stride (image->surface));
+ image->width = cairo_image_surface_get_width (surface);
+ image->height = cairo_image_surface_get_height (surface);
+ cached = swfdec_cached_image_new_for_surface (surface,
+ image->height * cairo_image_surface_get_stride (surface));
+ cairo_surface_destroy (surface);
+ return cached;
}
cairo_surface_t *
swfdec_image_create_surface (SwfdecImage *image)
{
+ SwfdecCachedImage *cached;
+ cairo_surface_t *surface;
+
if (image->raw_data == NULL)
return NULL;
- if (image->surface == NULL) {
+ if (TRUE) {
switch (image->type) {
case SWFDEC_IMAGE_TYPE_JPEG:
- swfdec_image_jpeg_load (image);
+ cached = swfdec_image_jpeg_load (image);
break;
case SWFDEC_IMAGE_TYPE_JPEG2:
- swfdec_image_jpeg2_load (image);
+ cached = swfdec_image_jpeg2_load (image);
break;
case SWFDEC_IMAGE_TYPE_JPEG3:
- swfdec_image_jpeg3_load (image);
+ cached = swfdec_image_jpeg3_load (image);
break;
case SWFDEC_IMAGE_TYPE_LOSSLESS:
- swfdec_image_lossless_load (image);
+ cached = swfdec_image_lossless_load (image);
break;
case SWFDEC_IMAGE_TYPE_LOSSLESS2:
- swfdec_image_lossless_load (image);
+ cached = swfdec_image_lossless_load (image);
break;
case SWFDEC_IMAGE_TYPE_PNG:
- swfdec_image_png_load (image);
+ cached = swfdec_image_png_load (image);
break;
case SWFDEC_IMAGE_TYPE_UNKNOWN:
default:
g_assert_not_reached ();
break;
}
- if (image->surface == NULL) {
+ if (cached == NULL) {
SWFDEC_WARNING ("failed to decode image");
return NULL;
}
- } else {
- swfdec_cached_use (SWFDEC_CACHED (image));
}
- return cairo_surface_reference (image->surface);
+
+ surface = swfdec_cached_image_get_surface (cached);
+ g_object_unref (cached);
+ return surface;
}
cairo_surface_t *
diff --git a/swfdec/swfdec_image.h b/swfdec/swfdec_image.h
index 8e41db9..3e2d53d 100644
--- a/swfdec/swfdec_image.h
+++ b/swfdec/swfdec_image.h
@@ -1,7 +1,7 @@
/* Swfdec
* Copyright (C) 2003-2006 David Schleef <ds at schleef.org>
* 2005-2006 Eric Anholt <eric at anholt.net>
- * 2006-2007 Benjamin Otte <otte at gnome.org>
+ * 2006-2008 Benjamin Otte <otte at gnome.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -23,10 +23,11 @@
#define _SWFDEC_IMAGE_H_
#include <cairo.h>
-#include <swfdec/swfdec_cached.h>
+#include <swfdec/swfdec_character.h>
#include <swfdec/swfdec_decoder.h>
G_BEGIN_DECLS
+
//typedef struct _SwfdecImage SwfdecImage;
typedef struct _SwfdecImageClass SwfdecImageClass;
@@ -48,11 +49,10 @@ typedef enum {
} SwfdecImageType;
struct _SwfdecImage {
- SwfdecCached cached;
+ SwfdecCharacter character;
int width; /* width of image or 0 if not known yet */
int height; /* height of image or 0 if not known yet */
- cairo_surface_t * surface; /* surface when cache loaded or NULL */
SwfdecImageType type;
SwfdecBuffer * jpegtables;
@@ -60,8 +60,7 @@ struct _SwfdecImage {
};
struct _SwfdecImageClass {
- SwfdecCachedClass cached_class;
-
+ SwfdecCharacterClass character_class;
};
GType swfdec_image_get_type (void);
diff --git a/swfdec/swfdec_player.c b/swfdec/swfdec_player.c
index 83a43bd..0ba1ac2 100644
--- a/swfdec/swfdec_player.c
+++ b/swfdec/swfdec_player.c
@@ -728,7 +728,7 @@ swfdec_player_get_property (GObject *object, guint param_id, GValue *value,
g_value_set_uint (value, swfdec_player_get_background_color (player));
break;
case PROP_CACHE_SIZE:
- g_value_set_ulong (value, swfdec_cache_get_size (priv->cache));
+ g_value_set_ulong (value, swfdec_cache_get_max_cache_size (priv->cache));
break;
case PROP_INITIALIZED:
g_value_set_boolean (value, swfdec_player_is_initialized (player));
@@ -875,7 +875,7 @@ swfdec_player_set_property (GObject *object, guint param_id, const GValue *value
swfdec_player_set_background_color (player, g_value_get_uint (value));
break;
case PROP_CACHE_SIZE:
- swfdec_cache_set_size (priv->cache, g_value_get_ulong (value));
+ swfdec_cache_set_max_cache_size (priv->cache, g_value_get_ulong (value));
break;
case PROP_WIDTH:
swfdec_player_set_size (player, g_value_get_int (value), priv->stage_height);
@@ -1010,7 +1010,7 @@ swfdec_player_dispose (GObject *object)
g_assert (priv->timeouts == NULL);
g_list_free (priv->intervals);
priv->intervals = NULL;
- swfdec_cache_unref (priv->cache);
+ g_object_unref (priv->cache);
if (priv->system) {
g_object_unref (priv->system);
priv->system = NULL;
@@ -2188,7 +2188,7 @@ swfdec_player_init (SwfdecPlayer *player)
priv->actions[i] = swfdec_ring_buffer_new_for_type (SwfdecPlayerAction, 16);
}
priv->external_actions = swfdec_ring_buffer_new_for_type (SwfdecPlayerExternalAction, 8);
- priv->cache = swfdec_cache_new (50 * 1024 * 1024); /* 100 MB */
+ priv->cache = swfdec_cache_new (16 * 1024 * 1024);
priv->bgcolor = SWFDEC_COLOR_COMBINE (0xFF, 0xFF, 0xFF, 0xFF);
priv->socket_type = SWFDEC_TYPE_SOCKET;
diff --git a/swfdec/swfdec_player_internal.h b/swfdec/swfdec_player_internal.h
index 340c658..7d03034 100644
--- a/swfdec/swfdec_player_internal.h
+++ b/swfdec/swfdec_player_internal.h
@@ -23,6 +23,7 @@
#include <swfdec/swfdec_player.h>
#include <swfdec/swfdec_audio.h>
#include <swfdec/swfdec_audio_internal.h>
+#include <swfdec/swfdec_cache.h>
#include <swfdec/swfdec_event.h>
#include <swfdec/swfdec_function_list.h>
#include <swfdec/swfdec_loader.h>
diff --git a/swfdec/swfdec_sound.c b/swfdec/swfdec_sound.c
index a788b14..76e21fc 100644
--- a/swfdec/swfdec_sound.c
+++ b/swfdec/swfdec_sound.c
@@ -33,24 +33,15 @@
#include "swfdec_sprite.h"
#include "swfdec_swf_decoder.h"
-G_DEFINE_TYPE (SwfdecSound, swfdec_sound, SWFDEC_TYPE_CACHED)
-
-static void
-swfdec_sound_unload (SwfdecCached *cached)
-{
- SwfdecSound * sound = SWFDEC_SOUND (cached);
-
- if (sound->decoded) {
- swfdec_buffer_unref (sound->decoded);
- sound->decoded = NULL;
- }
-}
+G_DEFINE_TYPE (SwfdecSound, swfdec_sound, SWFDEC_TYPE_CHARACTER)
static void
swfdec_sound_dispose (GObject *object)
{
SwfdecSound * sound = SWFDEC_SOUND (object);
+ if (sound->decoded)
+ swfdec_buffer_unref (sound->decoded);
if (sound->encoded)
swfdec_buffer_unref (sound->encoded);
@@ -61,11 +52,8 @@ static void
swfdec_sound_class_init (SwfdecSoundClass * g_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (g_class);
- SwfdecCachedClass *cached_class = SWFDEC_CACHED_CLASS (g_class);
object_class->dispose = swfdec_sound_dispose;
-
- cached_class->unload = swfdec_sound_unload;
}
static void
@@ -177,7 +165,6 @@ swfdec_sound_get_decoded (SwfdecSound *sound, SwfdecAudioFormat *format)
g_return_val_if_fail (format != NULL, NULL);
if (sound->decoded) {
- swfdec_cached_use (SWFDEC_CACHED (sound));
*format = sound->decoded_format;
return sound->decoded;
}
@@ -201,7 +188,6 @@ swfdec_sound_get_decoded (SwfdecSound *sound, SwfdecAudioFormat *format)
SWFDEC_ERROR ("decoding didn't produce any data, bailing");
return NULL;
}
- swfdec_cached_load (SWFDEC_CACHED (sound), depth);
tmp = swfdec_buffer_queue_pull (queue, depth);
swfdec_buffer_queue_unref (queue);
diff --git a/swfdec/swfdec_sound.h b/swfdec/swfdec_sound.h
index cea0a58..4d63b6e 100644
--- a/swfdec/swfdec_sound.h
+++ b/swfdec/swfdec_sound.h
@@ -22,7 +22,7 @@
#ifndef _SWFDEC_SOUND_H_
#define _SWFDEC_SOUND_H_
-#include <swfdec/swfdec_cached.h>
+#include <swfdec/swfdec_character.h>
#include <swfdec/swfdec_codec_audio.h>
#include <swfdec/swfdec_swf_decoder.h>
#include <swfdec/swfdec_types.h>
@@ -61,7 +61,7 @@ struct _SwfdecSoundChunk
struct _SwfdecSound
{
- SwfdecCached cached;
+ SwfdecCharacter character;
guint codec; /* codec in use */
SwfdecAudioFormat format; /* channel/rate/width information for codec */
@@ -75,7 +75,7 @@ struct _SwfdecSound
struct _SwfdecSoundClass
{
- SwfdecCachedClass cached_class;
+ SwfdecCharacterClass character_class;
};
GType swfdec_sound_get_type (void);
diff --git a/swfdec/swfdec_swf_decoder.c b/swfdec/swfdec_swf_decoder.c
index 733faa7..da750e1 100644
--- a/swfdec/swfdec_swf_decoder.c
+++ b/swfdec/swfdec_swf_decoder.c
@@ -459,9 +459,6 @@ swfdec_swf_decoder_create_character (SwfdecSwfDecoder * s, guint id, GType type)
result = g_object_new (type, NULL);
result->id = id;
g_hash_table_insert (s->characters, GUINT_TO_POINTER (id), result);
- if (SWFDEC_IS_CACHED (result)) {
- swfdec_cached_set_cache (SWFDEC_CACHED (result), SWFDEC_DECODER (s)->player->priv->cache);
- }
return result;
}
diff --git a/swfdec/swfdec_types.h b/swfdec/swfdec_types.h
index eafb4f3..1beb94b 100644
--- a/swfdec/swfdec_types.h
+++ b/swfdec/swfdec_types.h
@@ -33,8 +33,6 @@ typedef int SwfdecFixed;
typedef struct _SwfdecActor SwfdecActor;
typedef struct _SwfdecButton SwfdecButton;
-typedef struct _SwfdecCache SwfdecCache;
-typedef struct _SwfdecCacheHandle SwfdecCacheHandle;
typedef struct _SwfdecCharacter SwfdecCharacter;
typedef struct _SwfdecColorTransform SwfdecColorTransform;
typedef struct _SwfdecDecoder SwfdecDecoder;
commit 4db428f0a4adf930fbadd01e4e56917a7f7e0341
Author: Benjamin Otte <otte at gnome.org>
Date: Sun Apr 6 21:37:36 2008 +0200
fix maximum value to be ulong
diff --git a/swfdec/swfdec_player.c b/swfdec/swfdec_player.c
index 56145d0..83a43bd 100644
--- a/swfdec/swfdec_player.c
+++ b/swfdec/swfdec_player.c
@@ -1964,7 +1964,7 @@ swfdec_player_class_init (SwfdecPlayerClass *klass)
-1, G_MAXLONG, -1, G_PARAM_READABLE));
g_object_class_install_property (object_class, PROP_CACHE_SIZE,
g_param_spec_ulong ("cache-size", "cache size", "maximum cache size in bytes",
- 0, G_MAXUINT, 50 * 1024 * 1024, G_PARAM_READWRITE));
+ 0, G_MAXULONG, 50 * 1024 * 1024, G_PARAM_READWRITE));
g_object_class_install_property (object_class, PROP_BACKGROUND_COLOR,
g_param_spec_uint ("background-color", "background color", "ARGB color used to draw the background",
0, G_MAXUINT, SWFDEC_COLOR_COMBINE (0xFF, 0xFF, 0xFF, 0xFF), G_PARAM_READWRITE));
commit d46085ebf1a0c873f73394456361eedde6794fe8
Author: Benjamin Otte <otte at gnome.org>
Date: Sun Apr 6 15:59:25 2008 +0200
emit onChanged after changes
the method is completely bogus, but makes some flash files work.
diff --git a/swfdec/swfdec_actor.c b/swfdec/swfdec_actor.c
index 7f853c5..f6b3e53 100644
--- a/swfdec/swfdec_actor.c
+++ b/swfdec/swfdec_actor.c
@@ -219,6 +219,16 @@ swfdec_actor_execute (SwfdecActor *actor, SwfdecEventType condition)
} else if (condition == SWFDEC_EVENT_ENTER) {
if (SWFDEC_MOVIE (actor)->state >= SWFDEC_MOVIE_STATE_REMOVED)
return;
+ } else if (condition == SWFDEC_EVENT_SCROLL || condition == SWFDEC_EVENT_CHANGED) {
+ SwfdecAsValue argv[2];
+
+ SWFDEC_AS_VALUE_SET_STRING (&argv[0], SWFDEC_AS_STR_onScroller);
+ SWFDEC_AS_VALUE_SET_OBJECT (&argv[1], SWFDEC_AS_OBJECT (actor));
+ swfdec_sandbox_use (SWFDEC_MOVIE (actor)->resource->sandbox);
+ swfdec_as_object_call (SWFDEC_AS_OBJECT (actor),
+ SWFDEC_AS_STR_broadcastMessage, 2, argv, NULL);
+ swfdec_sandbox_unuse (SWFDEC_MOVIE (actor)->resource->sandbox);
+ return;
}
swfdec_sandbox_use (SWFDEC_MOVIE (actor)->resource->sandbox);
@@ -284,11 +294,9 @@ swfdec_actor_queue_script (SwfdecActor *actor, SwfdecEventType condition)
case SWFDEC_EVENT_DRAG_OVER:
case SWFDEC_EVENT_DRAG_OUT:
case SWFDEC_EVENT_KEY_PRESS:
- importance = SWFDEC_PLAYER_ACTION_QUEUE_NORMAL;
- break;
case SWFDEC_EVENT_CHANGED:
case SWFDEC_EVENT_SCROLL:
- importance = SWFDEC_PLAYER_ACTION_QUEUE_PRIORITY;
+ importance = SWFDEC_PLAYER_ACTION_QUEUE_NORMAL;
break;
default:
g_return_if_reached ();
diff --git a/swfdec/swfdec_text_field_movie.c b/swfdec/swfdec_text_field_movie.c
index d348eae..8c4cbc2 100644
--- a/swfdec/swfdec_text_field_movie.c
+++ b/swfdec/swfdec_text_field_movie.c
@@ -1364,18 +1364,12 @@ swfdec_text_field_movie_iterate (SwfdecActor *actor)
{
SwfdecTextFieldMovie *text = SWFDEC_TEXT_FIELD_MOVIE (actor);
+ while (text->changed) {
+ swfdec_actor_queue_script (actor, SWFDEC_EVENT_CHANGED);
+ text->changed--;
+ }
if (text->scroll_changed) {
- SwfdecAsValue argv[2];
-
- SWFDEC_FIXME ("I'm pretty sure this is swfdec_player_add_action()'d");
- SWFDEC_AS_VALUE_SET_STRING (&argv[0], SWFDEC_AS_STR_onScroller);
- SWFDEC_AS_VALUE_SET_OBJECT (&argv[1], SWFDEC_AS_OBJECT (text));
- swfdec_sandbox_use (SWFDEC_MOVIE (actor)->resource->sandbox);
- swfdec_as_object_call (SWFDEC_AS_OBJECT (text),
- SWFDEC_AS_STR_broadcastMessage, 2, argv, NULL);
- swfdec_sandbox_unuse (SWFDEC_MOVIE (actor)->resource->sandbox);
-
- /* FIXME: unset this before or after emitting the event? */
+ swfdec_actor_queue_script (actor, SWFDEC_EVENT_SCROLL);
text->scroll_changed = FALSE;
}
}
@@ -1619,6 +1613,12 @@ swfdec_text_field_movie_focus_out (SwfdecActor *actor)
}
static void
+swfdec_text_field_movie_changed (SwfdecTextFieldMovie *text)
+{
+ text->changed++;
+}
+
+static void
swfdec_text_field_movie_key_press (SwfdecActor *actor, guint keycode, guint character)
{
SwfdecTextFieldMovie *text = SWFDEC_TEXT_FIELD_MOVIE (actor);
@@ -1654,17 +1654,23 @@ swfdec_text_field_movie_key_press (SwfdecActor *actor, guint keycode, guint char
if (swfdec_text_field_movie_has_cursor (text)) {
start = BACKWARD (text, start);
}
- swfdec_sandbox_use (SWFDEC_MOVIE (text)->resource->sandbox);
- swfdec_text_field_movie_replace_text (text, start, end, "");
- swfdec_sandbox_unuse (SWFDEC_MOVIE (text)->resource->sandbox);
+ if (start != end) {
+ swfdec_sandbox_use (SWFDEC_MOVIE (text)->resource->sandbox);
+ swfdec_text_field_movie_replace_text (text, start, end, "");
+ swfdec_sandbox_unuse (SWFDEC_MOVIE (text)->resource->sandbox);
+ swfdec_text_field_movie_changed (text);
+ }
return;
case SWFDEC_KEY_DELETE:
if (swfdec_text_field_movie_has_cursor (text)) {
end = FORWARD (text, end);
}
- swfdec_sandbox_use (SWFDEC_MOVIE (text)->resource->sandbox);
- swfdec_text_field_movie_replace_text (text, start, end, "");
- swfdec_sandbox_unuse (SWFDEC_MOVIE (text)->resource->sandbox);
+ if (start != end) {
+ swfdec_sandbox_use (SWFDEC_MOVIE (text)->resource->sandbox);
+ swfdec_text_field_movie_replace_text (text, start, end, "");
+ swfdec_sandbox_unuse (SWFDEC_MOVIE (text)->resource->sandbox);
+ swfdec_text_field_movie_changed (text);
+ }
return;
default:
break;
@@ -1673,10 +1679,13 @@ swfdec_text_field_movie_key_press (SwfdecActor *actor, guint keycode, guint char
if (character == 0)
return;
len = g_unichar_to_utf8 (character, insert);
- insert[len] = 0;
- swfdec_sandbox_use (SWFDEC_MOVIE (text)->resource->sandbox);
- swfdec_text_field_movie_replace_text (text, start, end, insert);
- swfdec_sandbox_unuse (SWFDEC_MOVIE (text)->resource->sandbox);
+ if (len) {
+ insert[len] = 0;
+ swfdec_sandbox_use (SWFDEC_MOVIE (text)->resource->sandbox);
+ swfdec_text_field_movie_replace_text (text, start, end, insert);
+ swfdec_sandbox_unuse (SWFDEC_MOVIE (text)->resource->sandbox);
+ swfdec_text_field_movie_changed (text);
+ }
}
static void
diff --git a/swfdec/swfdec_text_field_movie.h b/swfdec/swfdec_text_field_movie.h
index ea8ddd9..5d8eebd 100644
--- a/swfdec/swfdec_text_field_movie.h
+++ b/swfdec/swfdec_text_field_movie.h
@@ -118,6 +118,7 @@ struct _SwfdecTextFieldMovie {
const char * style_sheet_input; /* saved input, so it can be used to apply stylesheet again */
gboolean scroll_changed; /* if any of the scroll attributes have changed and we haven't fired the event yet */
+ guint changed; /* number of onChanged events we have to emit */
int scroll;
int scroll_max;
int scroll_bottom;
More information about the Swfdec-commits
mailing list