[Swfdec-commits] 4 commits - swfdec/swfdec_bitmap_data.c swfdec/swfdec_bitmap_data.h swfdec/swfdec_bitmap_movie.c swfdec/swfdec_bitmap_pattern.c swfdec/swfdec_graphic_movie.c swfdec/swfdec_morph_movie.c swfdec/swfdec_movie.c swfdec/swfdec_player.c swfdec/swfdec_player_internal.h swfdec/swfdec_sprite_movie_as.c swfdec/swfdec_sprite_movie.c swfdec/swfdec_text_field_movie.c swfdec/swfdec_video_movie.c

Benjamin Otte company at kemper.freedesktop.org
Thu Sep 18 07:14:53 PDT 2008


 swfdec/swfdec_bitmap_data.c      |  138 ++++++++++++++++++++++++---------------
 swfdec/swfdec_bitmap_data.h      |   10 ++
 swfdec/swfdec_bitmap_movie.c     |   51 +++++++++-----
 swfdec/swfdec_bitmap_pattern.c   |   18 -----
 swfdec/swfdec_graphic_movie.c    |    3 
 swfdec/swfdec_morph_movie.c      |    3 
 swfdec/swfdec_movie.c            |    3 
 swfdec/swfdec_player.c           |   50 ++++++++++++--
 swfdec/swfdec_player_internal.h  |    5 -
 swfdec/swfdec_sprite_movie.c     |    2 
 swfdec/swfdec_sprite_movie_as.c  |    3 
 swfdec/swfdec_text_field_movie.c |    4 -
 swfdec/swfdec_video_movie.c      |    3 
 13 files changed, 192 insertions(+), 101 deletions(-)

New commits:
commit 28ea63d4d80f6a76648f2a4eb97617d733275715
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Sep 18 15:57:25 2008 +0200

    make invalidations respect filters
    
    I don't like the API this patch introduces at all - we need to rework
    invalidation handling to make the API saner.

diff --git a/swfdec/swfdec_bitmap_movie.c b/swfdec/swfdec_bitmap_movie.c
index 8e876b3..cbe6e4d 100644
--- a/swfdec/swfdec_bitmap_movie.c
+++ b/swfdec/swfdec_bitmap_movie.c
@@ -98,7 +98,8 @@ swfdec_bitmap_movie_invalidate (SwfdecMovie *movie, const cairo_matrix_t *matrix
   rect.y1 = swfdec_bitmap_data_get_height (bitmap->bitmap) * SWFDEC_TWIPS_SCALE_FACTOR;
 
   swfdec_rect_transform (&rect, &rect, matrix);
-  swfdec_player_invalidate (SWFDEC_PLAYER (swfdec_gc_object_get_context (movie)), &rect);
+  swfdec_player_invalidate (SWFDEC_PLAYER (swfdec_gc_object_get_context (movie)),
+      movie, &rect);
 }
 
 static SwfdecMovie *
diff --git a/swfdec/swfdec_graphic_movie.c b/swfdec/swfdec_graphic_movie.c
index 7fa7842..f5e3137 100644
--- a/swfdec/swfdec_graphic_movie.c
+++ b/swfdec/swfdec_graphic_movie.c
@@ -56,7 +56,8 @@ swfdec_graphic_movie_invalidate (SwfdecMovie *movie, const cairo_matrix_t *matri
   SwfdecRect rect;
 
   swfdec_rect_transform (&rect, &movie->graphic->extents, matrix);
-  swfdec_player_invalidate (SWFDEC_PLAYER (swfdec_gc_object_get_context (movie)), &rect);
+  swfdec_player_invalidate (SWFDEC_PLAYER (swfdec_gc_object_get_context (movie)), 
+      movie, &rect);
 }
 
 static SwfdecMovie *
diff --git a/swfdec/swfdec_morph_movie.c b/swfdec/swfdec_morph_movie.c
index c057c54..de0b0a8 100644
--- a/swfdec/swfdec_morph_movie.c
+++ b/swfdec/swfdec_morph_movie.c
@@ -96,7 +96,8 @@ swfdec_morph_movie_invalidate (SwfdecMovie *movie, const cairo_matrix_t *matrix,
   SwfdecRect rect;
   
   swfdec_rect_transform (&rect, &movie->original_extents, matrix);
-  swfdec_player_invalidate (SWFDEC_PLAYER (swfdec_gc_object_get_context (movie)), &rect);
+  swfdec_player_invalidate (SWFDEC_PLAYER (swfdec_gc_object_get_context (movie)),
+      movie, &rect);
 }
 
 static void
diff --git a/swfdec/swfdec_movie.c b/swfdec/swfdec_movie.c
index 0767107..dc735e7 100644
--- a/swfdec/swfdec_movie.c
+++ b/swfdec/swfdec_movie.c
@@ -1408,7 +1408,8 @@ swfdec_movie_do_invalidate (SwfdecMovie *movie, const cairo_matrix_t *matrix, gb
   }
   swfdec_rect_union (&rect, &rect, &movie->draw_extents);
   swfdec_rect_transform (&rect, &rect, matrix);
-  swfdec_player_invalidate (SWFDEC_PLAYER (swfdec_gc_object_get_context (movie)), &rect);
+  swfdec_player_invalidate (SWFDEC_PLAYER (swfdec_gc_object_get_context (movie)),
+      movie, &rect);
 
   for (walk = movie->list; walk; walk = walk->next) {
     swfdec_movie_invalidate (walk->data, matrix, last);
diff --git a/swfdec/swfdec_player.c b/swfdec/swfdec_player.c
index 6515189..d771b28 100644
--- a/swfdec/swfdec_player.c
+++ b/swfdec/swfdec_player.c
@@ -35,6 +35,7 @@
 #include "swfdec_debug.h"
 #include "swfdec_enums.h"
 #include "swfdec_event.h"
+#include "swfdec_filter.h"
 #include "swfdec_internal.h"
 #include "swfdec_loader_internal.h"
 #include "swfdec_marshal.h"
@@ -931,7 +932,7 @@ swfdec_player_update_scale (SwfdecPlayer *player)
   for (walk = priv->roots; walk; walk = walk->next) {
     g_signal_emit_by_name (walk->data, "matrix-changed");
   }
-  swfdec_player_invalidate (player, NULL);
+  swfdec_player_invalidate (player, NULL, NULL);
   if (!swfdec_player_is_locked (player))
     swfdec_player_emit_signals (player);
 }
@@ -1151,7 +1152,7 @@ swfdec_player_invalidate_focusrect (SwfdecPlayer *player)
   if (swfdec_rect_is_empty (&priv->focusrect))
     return;
 
-  swfdec_player_invalidate (player, &priv->focusrect);
+  swfdec_player_invalidate (player, NULL, &priv->focusrect);
   swfdec_rect_init_empty (&priv->focusrect);
 }
 
@@ -1942,7 +1943,7 @@ swfdec_player_update_focusrect (SwfdecPlayer *player)
   priv->focusrect = movie->extents;
   if (movie->parent)
     swfdec_movie_rect_local_to_global (movie->parent, &priv->focusrect);
-  swfdec_player_invalidate (player, &priv->focusrect);
+  swfdec_player_invalidate (player, NULL, &priv->focusrect);
 }
 
 static void
@@ -2455,9 +2456,37 @@ swfdec_player_stop_sounds (SwfdecPlayer *player, SwfdecAudioRemoveFunc func, gpo
   }
 }
 
-/* rect is in global coordinates */
+static void
+swfdec_player_invalidate_movie (SwfdecMovie *movie, double xscale, double yscale,
+    SwfdecRectangle *rect)
+{
+  GSList *walk;
+
+  while (movie != NULL) {
+    g_print ("%s\n", movie->name);
+    for (walk = movie->filters; walk; walk = walk->next) {
+      g_print ("%g %g\n", xscale, yscale);
+      swfdec_filter_get_rectangle (walk->data, rect, xscale, yscale, rect);
+    }
+    movie = movie->parent;
+  }
+}
+
+/**
+ * swfdec_player_invalidate:
+ * @player: Player to invalidate in
+ * @movie: the movie that causes the invalidation or %NULL if the invalidation
+ *         is not specific to a movie. The invalid region will be enhanced by 
+ *         the area required by filters. Also the "invalidate" signal will be
+ *         emitted on the movie and all its parents.
+ * @rect: rectangle to invalidate in global coordiantes or %NULL for the 
+ *        whole player
+ *
+ * Invalidates the given area of the player. This causes this area to be 
+ * emitted as part of the SwfdecPlayer::invalidate signal.
+ **/
 void
-swfdec_player_invalidate (SwfdecPlayer *player, const SwfdecRect *rect)
+swfdec_player_invalidate (SwfdecPlayer *player, SwfdecMovie *movie, const SwfdecRect *rect)
 {
   SwfdecPlayerPrivate *priv;
   SwfdecRectangle r;
@@ -2475,6 +2504,15 @@ swfdec_player_invalidate (SwfdecPlayer *player, const SwfdecRect *rect)
 
     swfdec_rect_transform (&tmp, rect, &priv->global_to_stage);
     swfdec_rectangle_init_rect (&r, &tmp);
+    if (movie)
+      g_print ("invalidating %s: %u %u %u %u\n", movie->name, r.x, r.y, r.width, r.height);
+    swfdec_player_invalidate_movie (movie, 
+	player->priv->global_to_stage.xx * SWFDEC_TWIPS_SCALE_FACTOR,
+	player->priv->global_to_stage.yy * SWFDEC_TWIPS_SCALE_FACTOR,
+	&r);
+    if (movie)
+      g_print ("invalidating %s: %u %u %u %u\n", movie->name, r.x, r.y, r.width, r.height);
+
     /* FIXME: currently we clamp the rectangle to the visible area, it might
      * be useful to allow out-of-bounds drawing. In that case this needs to be
      * changed */
@@ -2517,7 +2555,7 @@ swfdec_player_set_background_color (SwfdecPlayer *player, SwfdecColor bgcolor)
 
   SWFDEC_INFO ("setting bgcolor to %08X", bgcolor);
   priv->bgcolor = bgcolor;
-  swfdec_player_invalidate (player, NULL);
+  swfdec_player_invalidate (player, NULL, NULL);
   g_object_notify (G_OBJECT (player), "background-color");
 }
 
diff --git a/swfdec/swfdec_player_internal.h b/swfdec/swfdec_player_internal.h
index 9f7996a..0d0cda8 100644
--- a/swfdec/swfdec_player_internal.h
+++ b/swfdec/swfdec_player_internal.h
@@ -199,14 +199,15 @@ SwfdecSocket *	swfdec_player_create_socket	(SwfdecPlayer *		player,
 						 const char *		hostname,
 						 guint			port);
 
+void		swfdec_player_invalidate	(SwfdecPlayer *		player,
+						 SwfdecMovie *		movie,
+						 const SwfdecRect *	rect);
 void		swfdec_player_invalidate_focusrect (SwfdecPlayer *	player);
 void		swfdec_player_grab_focus	(SwfdecPlayer *		player,
 						 SwfdecActor *		actor);
 #define swfdec_player_has_focus(player,actor) ((player)->priv->focus == (actor))
 #define swfdec_player_is_key_pressed(player,key) ((player)->priv->key_pressed[(key) / 8] & (1 << ((key) % 8)))
 #define swfdec_player_is_mouse_pressed(player) ((player)->priv->mouse_button & 1)
-void		swfdec_player_invalidate	(SwfdecPlayer *		player,
-						 const SwfdecRect *	rect);
 void		swfdec_player_add_timeout	(SwfdecPlayer *		player,
 						 SwfdecTimeout *	timeout);
 void		swfdec_player_remove_timeout	(SwfdecPlayer *		player,
diff --git a/swfdec/swfdec_sprite_movie.c b/swfdec/swfdec_sprite_movie.c
index 25558ad..ba85e5d 100644
--- a/swfdec/swfdec_sprite_movie.c
+++ b/swfdec/swfdec_sprite_movie.c
@@ -348,7 +348,9 @@ out:
   if (has_filter) {
     if (cur->filters)
       g_slist_free (cur->filters);
+    swfdec_movie_invalidate_next (cur);
     cur->filters = filters;
+    g_print ("%s: setting %u filters\n", cur->name, g_slist_length (filters));
   }
 
   if (events)
diff --git a/swfdec/swfdec_sprite_movie_as.c b/swfdec/swfdec_sprite_movie_as.c
index 181f2c1..5bf9b68 100644
--- a/swfdec/swfdec_sprite_movie_as.c
+++ b/swfdec/swfdec_sprite_movie_as.c
@@ -153,6 +153,9 @@ swfdec_sprite_movie_set_filters (SwfdecAsContext *cx, SwfdecAsObject *object,
 
   SWFDEC_AS_CHECK (SWFDEC_TYPE_MOVIE, &movie, "o", &array);
 
+  swfdec_movie_invalidate_next (movie);
+  g_print ("movie %s gets filters, w00t!\n", movie->name);
+
   swfdec_as_object_get_variable (array, SWFDEC_AS_STR_length, &val);
   length = swfdec_as_value_to_integer (cx, &val);
 
diff --git a/swfdec/swfdec_text_field_movie.c b/swfdec/swfdec_text_field_movie.c
index 9864b34..4c9505a 100644
--- a/swfdec/swfdec_text_field_movie.c
+++ b/swfdec/swfdec_text_field_movie.c
@@ -207,8 +207,8 @@ swfdec_text_field_movie_invalidate (SwfdecMovie *movie, const cairo_matrix_t *ma
 
   swfdec_rect_transform (&rect, &rect,
       &SWFDEC_PLAYER (swfdec_gc_object_get_context (text))->priv->stage_to_global);
-  swfdec_player_invalidate (
-      SWFDEC_PLAYER (swfdec_gc_object_get_context (movie)), &rect);
+  swfdec_player_invalidate (SWFDEC_PLAYER (swfdec_gc_object_get_context (movie)),
+      movie, &rect);
 }
 
 static gboolean
diff --git a/swfdec/swfdec_video_movie.c b/swfdec/swfdec_video_movie.c
index 86aa47f..6369b7f 100644
--- a/swfdec/swfdec_video_movie.c
+++ b/swfdec/swfdec_video_movie.c
@@ -185,7 +185,8 @@ swfdec_video_movie_invalidate (SwfdecMovie *movie, const cairo_matrix_t *matrix,
     SWFDEC_TWIPS_SCALE_FACTOR * org->height };
 
   swfdec_rect_transform (&rect, &rect, matrix);
-  swfdec_player_invalidate (SWFDEC_PLAYER (swfdec_gc_object_get_context (movie)), &rect);
+  swfdec_player_invalidate (SWFDEC_PLAYER (swfdec_gc_object_get_context (movie)),
+      movie, &rect);
 }
 
 static GObject *
commit 5406a3c27a07bc0bddd4c46d740d531b133b9672
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Sep 17 19:21:22 2008 +0200

    use swfdec_bitmap_data_get_pattern() in BitmapData.draw

diff --git a/swfdec/swfdec_bitmap_data.c b/swfdec/swfdec_bitmap_data.c
index 8b9636c..381a5f1 100644
--- a/swfdec/swfdec_bitmap_data.c
+++ b/swfdec/swfdec_bitmap_data.c
@@ -522,19 +522,12 @@ swfdec_bitmap_data_draw (SwfdecAsContext *cx, SwfdecAsObject *object,
   cairo_transform (cr, &mat);
 
   if (SWFDEC_IS_BITMAP_DATA (o)) {
-    SwfdecBitmapData *src = SWFDEC_BITMAP_DATA (o);
-    if (src->surface) {
-      if (swfdec_color_transform_is_identity (&ctrans)) {
-	cairo_set_source_surface (cr, SWFDEC_BITMAP_DATA (o)->surface, 0, 0);
-      } else {
-	cairo_surface_t *transformed = swfdec_renderer_transform (renderer,
-	    SWFDEC_BITMAP_DATA (o)->surface, &ctrans, &area);
-	SWFDEC_FIXME ("unmodified pixels will be treated as -1, not as 0 as in our "
-	    "transform code, but we don't know if a pixel is unmodified.");
-	cairo_set_source_surface (cr, transformed, 0, 0);
-	cairo_surface_destroy (transformed);
-      }
+    cairo_pattern_t *pattern = swfdec_bitmap_data_get_pattern (
+	SWFDEC_BITMAP_DATA (o), renderer, &ctrans);
+    if (pattern) {
+      cairo_set_source (cr, pattern);
       cairo_paint (cr);
+      cairo_pattern_destroy (pattern);
     }
   } else if (SWFDEC_IS_MOVIE (o)) {
     SwfdecMovie *movie = SWFDEC_MOVIE (o);
@@ -860,6 +853,8 @@ swfdec_bitmap_data_get_pattern (SwfdecBitmapData *bitmap, SwfdecRenderer *render
     SwfdecRectangle area = { 0, 0, bitmap->width, bitmap->height };
     cairo_surface_t *surface = swfdec_renderer_transform (renderer,
 	bitmap->surface, ctrans, &area);
+    SWFDEC_FIXME ("unmodified pixels will be treated as -1, not as 0 as in our "
+	"transform code, but we don't know if a pixel is unmodified.");
     pattern = cairo_pattern_create_for_surface (surface);
     cairo_surface_destroy (surface);
   }
commit 3f71c20cc31cf9b5e7e9f055e466248cdfaeccb5
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Sep 17 19:14:29 2008 +0200

    add swfdec_bitmap_data_get_pattern()
    
    and use it for BitmapMovie/BitmapPattern

diff --git a/swfdec/swfdec_bitmap_data.c b/swfdec/swfdec_bitmap_data.c
index 944b674..8b9636c 100644
--- a/swfdec/swfdec_bitmap_data.c
+++ b/swfdec/swfdec_bitmap_data.c
@@ -819,6 +819,8 @@ swfdec_bitmap_data_construct (SwfdecAsContext *cx, SwfdecAsObject *object,
   }
 }
 
+/*** PUBLIC API ***/
+
 guint
 swfdec_bitmap_data_get_width (SwfdecBitmapData *bitmap)
 {
@@ -835,3 +837,32 @@ swfdec_bitmap_data_get_height (SwfdecBitmapData *bitmap)
   return bitmap->surface ? bitmap->height : 0;
 }
 
+cairo_pattern_t *
+swfdec_bitmap_data_get_pattern (SwfdecBitmapData *bitmap, SwfdecRenderer *renderer,
+    const SwfdecColorTransform *ctrans)
+{
+  cairo_pattern_t *pattern;
+
+  g_return_val_if_fail (SWFDEC_IS_BITMAP_DATA (bitmap), NULL);
+  g_return_val_if_fail (SWFDEC_IS_RENDERER (renderer), NULL);
+  g_return_val_if_fail (ctrans != NULL, NULL);
+  g_return_val_if_fail (!swfdec_color_transform_is_mask (ctrans), NULL);
+
+  /* FIXME: Is this correct for the case where the surface is NULL?
+   * Do we want a red surface */
+  if (bitmap->surface == NULL)
+    return NULL;
+
+  if (swfdec_color_transform_is_identity (ctrans)) {
+    pattern = cairo_pattern_create_for_surface (bitmap->surface);
+  } else {
+    /* FIXME: do caching? */
+    SwfdecRectangle area = { 0, 0, bitmap->width, bitmap->height };
+    cairo_surface_t *surface = swfdec_renderer_transform (renderer,
+	bitmap->surface, ctrans, &area);
+    pattern = cairo_pattern_create_for_surface (surface);
+    cairo_surface_destroy (surface);
+  }
+
+  return pattern;
+}
diff --git a/swfdec/swfdec_bitmap_data.h b/swfdec/swfdec_bitmap_data.h
index a799014..f8efa6b 100644
--- a/swfdec/swfdec_bitmap_data.h
+++ b/swfdec/swfdec_bitmap_data.h
@@ -22,6 +22,8 @@
 
 #include <cairo.h>
 #include <swfdec/swfdec_as_object.h>
+#include <swfdec/swfdec_renderer.h>
+#include <swfdec/swfdec_types.h>
 
 G_BEGIN_DECLS
 
@@ -55,6 +57,9 @@ SwfdecBitmapData *	swfdec_bitmap_data_new			(SwfdecAsContext *	context,
 
 guint			swfdec_bitmap_data_get_width		(SwfdecBitmapData *	data);
 guint			swfdec_bitmap_data_get_height		(SwfdecBitmapData *	data);
+cairo_pattern_t *	swfdec_bitmap_data_get_pattern		(SwfdecBitmapData *	data,
+								 SwfdecRenderer *	renderer,
+								 const SwfdecColorTransform *ctrans);
 
 
 G_END_DECLS
diff --git a/swfdec/swfdec_bitmap_movie.c b/swfdec/swfdec_bitmap_movie.c
index 1fe4f5e..8e876b3 100644
--- a/swfdec/swfdec_bitmap_movie.c
+++ b/swfdec/swfdec_bitmap_movie.c
@@ -24,6 +24,7 @@
 #include "swfdec_bitmap_movie.h"
 #include "swfdec_debug.h"
 #include "swfdec_player_internal.h"
+#include "swfdec_renderer_internal.h"
 
 G_DEFINE_TYPE (SwfdecBitmapMovie, swfdec_bitmap_movie, SWFDEC_TYPE_MOVIE)
 
@@ -45,31 +46,42 @@ swfdec_bitmap_movie_update_extents (SwfdecMovie *movie,
 
 static void
 swfdec_bitmap_movie_render (SwfdecMovie *movie, cairo_t *cr, 
-    const SwfdecColorTransform *trans)
+    const SwfdecColorTransform *ctrans)
 {
   SwfdecBitmapMovie *bitmap = SWFDEC_BITMAP_MOVIE (movie);
+  SwfdecRenderer *renderer;
+  cairo_pattern_t *pattern;
 
-  if (bitmap->bitmap->surface == NULL)
-    return;
+  renderer = swfdec_renderer_get (cr);
 
   cairo_scale (cr, SWFDEC_TWIPS_SCALE_FACTOR, SWFDEC_TWIPS_SCALE_FACTOR);
-  if (swfdec_color_transform_is_mask (trans)) {
+  if (swfdec_color_transform_is_mask (ctrans)) {
     SWFDEC_FIXME ("does attachBitmap mask?");
     cairo_set_source_rgb (cr, 0, 0, 0);
     cairo_rectangle (cr, 0, 0, 
-	swfdec_bitmap_data_get_width (bitmap->bitmap) * SWFDEC_TWIPS_SCALE_FACTOR,
-	swfdec_bitmap_data_get_height (bitmap->bitmap) * SWFDEC_TWIPS_SCALE_FACTOR);
+	swfdec_bitmap_data_get_width (bitmap->bitmap),
+	swfdec_bitmap_data_get_height (bitmap->bitmap));
     cairo_fill (cr);
-  } else if (swfdec_color_transform_is_identity (trans)) {
-    cairo_set_source_surface (cr, bitmap->bitmap->surface, 0, 0);
-    cairo_paint (cr);
-  } else if (swfdec_color_transform_is_alpha (trans)) {
-    cairo_set_source_surface (cr, bitmap->bitmap->surface, 0, 0);
-    cairo_paint_with_alpha (cr, trans->aa / 255.0);
+  } else if (!swfdec_color_transform_is_identity (ctrans) &&
+      swfdec_color_transform_is_alpha (ctrans)) {
+    /* optimization for alpha fills */
+    SwfdecColorTransform identity;
+    swfdec_color_transform_init_identity (&identity);
+    pattern = swfdec_bitmap_data_get_pattern (bitmap->bitmap,
+	renderer, &identity);
+    if (pattern == NULL)
+      return;
+    cairo_set_source (cr, pattern);
+    cairo_paint_with_alpha (cr, ctrans->aa / 255.0);
+    cairo_pattern_destroy (pattern);
   } else {
-    SWFDEC_FIXME ("properly color-transform bitmap");
-    cairo_set_source_surface (cr, bitmap->bitmap->surface, 0, 0);
+    pattern = swfdec_bitmap_data_get_pattern (bitmap->bitmap, 
+	renderer, ctrans);
+    if (pattern == NULL)
+      return;
+    cairo_set_source (cr, pattern);
     cairo_paint (cr);
+    cairo_pattern_destroy (pattern);
   }
 }
 
diff --git a/swfdec/swfdec_bitmap_pattern.c b/swfdec/swfdec_bitmap_pattern.c
index e6c7861..2b953bc 100644
--- a/swfdec/swfdec_bitmap_pattern.c
+++ b/swfdec/swfdec_bitmap_pattern.c
@@ -41,23 +41,9 @@ swfdec_bitmap_pattern_get_pattern (SwfdecPattern *pat, SwfdecRenderer *renderer,
   SwfdecBitmapPattern *bitmap = SWFDEC_BITMAP_PATTERN (pat);
   cairo_pattern_t *pattern;
 
-  /* FIXME: Is this correct for the case where the surface is NULL?
-   * Do we want a red surface */
-  if (bitmap->bitmap->surface == NULL)
+  pattern = swfdec_bitmap_data_get_pattern (bitmap->bitmap, renderer, ctrans);
+  if (pattern == NULL)
     return NULL;
-
-  if (swfdec_color_transform_is_identity (ctrans)) {
-    pattern = cairo_pattern_create_for_surface (bitmap->bitmap->surface);
-  } else {
-    /* FIXME: more caching? */
-    SwfdecRectangle area = { 0, 0, 
-      swfdec_bitmap_data_get_width (bitmap->bitmap),
-      swfdec_bitmap_data_get_height (bitmap->bitmap) };
-    cairo_surface_t *surface = swfdec_renderer_transform (renderer,
-	bitmap->bitmap->surface, ctrans, &area);
-    pattern = cairo_pattern_create_for_surface (surface);
-    cairo_surface_destroy (surface);
-  }
   cairo_pattern_set_matrix (pattern, &pat->transform);
   cairo_pattern_set_extend (pattern, bitmap->extend);
   cairo_pattern_set_filter (pattern, bitmap->filter);
commit 9c1ee28063a25e154c81a76aa2b69941606dfb9a
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Sep 17 18:09:54 2008 +0200

    keep width/height in the BitmapData object itself
    
    This is the first step to abstracting away the surface

diff --git a/swfdec/swfdec_bitmap_data.c b/swfdec/swfdec_bitmap_data.c
index ff94875..944b674 100644
--- a/swfdec/swfdec_bitmap_data.c
+++ b/swfdec/swfdec_bitmap_data.c
@@ -63,17 +63,16 @@ swfdec_bitmap_data_invalidate (SwfdecBitmapData *bitmap, guint x, guint y, guint
 static void
 swfdec_bitmap_data_clear (SwfdecBitmapData *bitmap)
 {
-  int w, h;
-
   if (bitmap->surface == NULL)
     return;
 
-  w = cairo_image_surface_get_width (bitmap->surface);
-  h = cairo_image_surface_get_height (bitmap->surface);
-  swfdec_bitmap_data_invalidate (bitmap, 0, 0, w, h);
-  swfdec_as_context_unuse_mem (swfdec_gc_object_get_context (bitmap), 4 * w * h);
+  swfdec_bitmap_data_invalidate (bitmap, 0, 0, bitmap->width, bitmap->height);
   cairo_surface_destroy (bitmap->surface);
+  swfdec_as_context_unuse_mem (swfdec_gc_object_get_context (bitmap), 
+      4 * bitmap->width * bitmap->height);
   bitmap->surface = NULL;
+  bitmap->width = 0;
+  bitmap->height = 0;
 }
 
 static void
@@ -116,6 +115,8 @@ swfdec_bitmap_data_new (SwfdecAsContext *context, gboolean transparent, guint wi
     return NULL;
 
   bitmap = g_object_new (SWFDEC_TYPE_BITMAP_DATA, "context", context, NULL);
+  bitmap->width = width;
+  bitmap->height = height;
   bitmap->surface = cairo_image_surface_create (
       transparent ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24, width, height);
 
@@ -169,17 +170,16 @@ swfdec_bitmap_data_loadBitmap (SwfdecAsContext *cx, SwfdecAsObject *object,
 }
 
 // properties
-SWFDEC_AS_NATIVE (1100, 100, swfdec_bitmap_data_get_width)
+SWFDEC_AS_NATIVE (1100, 100, swfdec_bitmap_data_do_get_width)
 void
-swfdec_bitmap_data_get_width (SwfdecAsContext *cx, SwfdecAsObject *object,
+swfdec_bitmap_data_do_get_width (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
   SwfdecBitmapData *bitmap;
 
   SWFDEC_AS_CHECK (SWFDEC_TYPE_BITMAP_DATA, &bitmap, "");
 
-  SWFDEC_AS_VALUE_SET_INT (ret, bitmap->surface ? 
-      cairo_image_surface_get_width (bitmap->surface) : -1);
+  SWFDEC_AS_VALUE_SET_INT (ret, bitmap->surface ? (int) bitmap->width : -1);
 }
 
 SWFDEC_AS_NATIVE (1100, 101, swfdec_bitmap_data_set_width)
@@ -190,17 +190,16 @@ swfdec_bitmap_data_set_width (SwfdecAsContext *cx, SwfdecAsObject *object,
   SWFDEC_STUB ("BitmapData.width (set)");
 }
 
-SWFDEC_AS_NATIVE (1100, 102, swfdec_bitmap_data_get_height)
+SWFDEC_AS_NATIVE (1100, 102, swfdec_bitmap_data_do_get_height)
 void
-swfdec_bitmap_data_get_height (SwfdecAsContext *cx, SwfdecAsObject *object,
+swfdec_bitmap_data_do_get_height (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
   SwfdecBitmapData *bitmap;
 
   SWFDEC_AS_CHECK (SWFDEC_TYPE_BITMAP_DATA, &bitmap, "");
 
-  SWFDEC_AS_VALUE_SET_INT (ret, bitmap->surface ? 
-      cairo_image_surface_get_height (bitmap->surface) : -1);
+  SWFDEC_AS_VALUE_SET_INT (ret, bitmap->surface ? (int) bitmap->height : -1);
 }
 
 SWFDEC_AS_NATIVE (1100, 103, swfdec_bitmap_data_set_height)
@@ -243,8 +242,8 @@ swfdec_bitmap_data_get_rectangle (SwfdecAsContext *cx, SwfdecAsObject *object,
 
   SWFDEC_AS_VALUE_SET_INT (&args[0], 0);
   SWFDEC_AS_VALUE_SET_INT (&args[1], 0);
-  SWFDEC_AS_VALUE_SET_INT (&args[2], cairo_image_surface_get_width (bitmap->surface));
-  SWFDEC_AS_VALUE_SET_INT (&args[3], cairo_image_surface_get_width (bitmap->surface));
+  SWFDEC_AS_VALUE_SET_INT (&args[2], bitmap->width);
+  SWFDEC_AS_VALUE_SET_INT (&args[3], bitmap->height);
   swfdec_as_object_create (SWFDEC_AS_FUNCTION (o), 4, args, ret);
 }
 
@@ -308,9 +307,7 @@ swfdec_bitmap_data_getPixel (SwfdecAsContext *cx, SwfdecAsObject *object,
 
   SWFDEC_AS_CHECK (SWFDEC_TYPE_BITMAP_DATA, &bitmap, "ii", &x, &y);
 
-  if (bitmap->surface == NULL ||
-      x >= (guint) cairo_image_surface_get_width (bitmap->surface) ||
-      y >= (guint) cairo_image_surface_get_height (bitmap->surface))
+  if (bitmap->surface == NULL || x >= (guint) bitmap->width || y >= (guint) bitmap->height)
     return;
 
   addr = cairo_image_surface_get_data (bitmap->surface);
@@ -334,9 +331,7 @@ swfdec_bitmap_data_setPixel (SwfdecAsContext *cx, SwfdecAsObject *object,
 
   SWFDEC_AS_CHECK (SWFDEC_TYPE_BITMAP_DATA, &bitmap, "iii", &x, &y, &color);
 
-  if (bitmap->surface == NULL ||
-      x >= (guint) cairo_image_surface_get_width (bitmap->surface) ||
-      y >= (guint) cairo_image_surface_get_height (bitmap->surface))
+  if (bitmap->surface == NULL || x >= bitmap->width || y >= bitmap->height)
     return;
 
   addr = cairo_image_surface_get_data (bitmap->surface);
@@ -517,8 +512,8 @@ swfdec_bitmap_data_draw (SwfdecAsContext *cx, SwfdecAsObject *object,
   /* FIXME: compute area from arguments */
   area.x = 0;
   area.y = 0;
-  area.width = cairo_image_surface_get_width (bitmap->surface);
-  area.height = cairo_image_surface_get_height (bitmap->surface);
+  area.width = bitmap->width;
+  area.height = bitmap->height;
 
   cr = cairo_create (bitmap->surface);
   /* FIXME: Do we have a better renderer? */
@@ -574,9 +569,7 @@ swfdec_bitmap_data_getPixel32 (SwfdecAsContext *cx, SwfdecAsObject *object,
 
   SWFDEC_AS_CHECK (SWFDEC_TYPE_BITMAP_DATA, &bitmap, "ii", &x, &y);
 
-  if (bitmap->surface == NULL ||
-      x >= (guint) cairo_image_surface_get_width (bitmap->surface) ||
-      y >= (guint) cairo_image_surface_get_height (bitmap->surface))
+  if (bitmap->surface == NULL || x >= bitmap->width || y >= bitmap->height)
     return;
 
   addr = cairo_image_surface_get_data (bitmap->surface);
@@ -598,9 +591,7 @@ swfdec_bitmap_data_setPixel32 (SwfdecAsContext *cx, SwfdecAsObject *object,
 
   SWFDEC_AS_CHECK (SWFDEC_TYPE_BITMAP_DATA, &bitmap, "iii", &x, &y, &color);
 
-  if (bitmap->surface == NULL ||
-      x >= (guint) cairo_image_surface_get_width (bitmap->surface) ||
-      y >= (guint) cairo_image_surface_get_height (bitmap->surface))
+  if (bitmap->surface == NULL || x >= bitmap->width || y >= bitmap->height)
     return;
 
   addr = cairo_image_surface_get_data (bitmap->surface);
@@ -667,22 +658,22 @@ swfdec_bitmap_data_colorTransform (SwfdecAsContext *cx, SwfdecAsObject *object,
   if (area.x < 0) {
     area.width += area.x;
     area.x = 0;
-  } else if (area.x >= cairo_image_surface_get_width (bitmap->surface)) {
+  } else if ((guint) area.x >= bitmap->width) {
     return;
   }
   if (area.y < 0) {
     area.height += area.y;
     area.y = 0;
-  } else if (area.y >= cairo_image_surface_get_height (bitmap->surface)) {
+  } else if ((guint) area.y >= bitmap->height) {
     return;
   }
-  if (area.width + area.x > cairo_image_surface_get_width (bitmap->surface)) {
-    area.width = cairo_image_surface_get_width (bitmap->surface) - area.x;
+  if (area.width + area.x > (int) bitmap->width) {
+    area.width = bitmap->width - area.x;
   } else if (area.width <= 0) {
     return;
   }
-  if (area.height + area.x > cairo_image_surface_get_height (bitmap->surface)) {
-    area.height = cairo_image_surface_get_height (bitmap->surface) - area.y;
+  if (area.height + area.y > (int) bitmap->height) {
+    area.height = bitmap->height - area.y;
   } else if (area.height <= 0) {
     return;
   }
@@ -750,10 +741,8 @@ swfdec_bitmap_data_clone (SwfdecAsContext *cx, SwfdecAsObject *object,
   if (bitmap->surface == NULL)
     return;
 
-  clone = swfdec_bitmap_data_new (cx,
-      swfdec_surface_has_alpha (bitmap->surface),
-      cairo_image_surface_get_width (bitmap->surface),
-      cairo_image_surface_get_height (bitmap->surface));
+  clone = swfdec_bitmap_data_new (cx, swfdec_surface_has_alpha (bitmap->surface),
+      bitmap->width, bitmap->height);
   if (clone == NULL)
     return;
 
@@ -817,6 +806,8 @@ swfdec_bitmap_data_construct (SwfdecAsContext *cx, SwfdecAsObject *object,
 
   if (!swfdec_as_context_try_use_mem (cx, w * h * 4))
     return;
+  bitmap->width = w;
+  bitmap->height = h;
   bitmap->surface = cairo_image_surface_create (
       transparent ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24, w, h);
 
@@ -827,3 +818,20 @@ swfdec_bitmap_data_construct (SwfdecAsContext *cx, SwfdecAsObject *object,
     cairo_destroy (cr);
   }
 }
+
+guint
+swfdec_bitmap_data_get_width (SwfdecBitmapData *bitmap)
+{
+  g_return_val_if_fail (SWFDEC_IS_BITMAP_DATA (bitmap), 0);
+
+  return bitmap->surface ? bitmap->width : 0;
+}
+
+guint
+swfdec_bitmap_data_get_height (SwfdecBitmapData *bitmap)
+{
+  g_return_val_if_fail (SWFDEC_IS_BITMAP_DATA (bitmap), 0);
+
+  return bitmap->surface ? bitmap->height : 0;
+}
+
diff --git a/swfdec/swfdec_bitmap_data.h b/swfdec/swfdec_bitmap_data.h
index 425e315..a799014 100644
--- a/swfdec/swfdec_bitmap_data.h
+++ b/swfdec/swfdec_bitmap_data.h
@@ -38,6 +38,8 @@ struct _SwfdecBitmapData {
   SwfdecAsObject	object;
 
   cairo_surface_t *	surface;	/* An image surface or NULL */
+  guint			width;		/* width of surface */
+  guint			height;		/* height of surface */
 };
 
 struct _SwfdecBitmapDataClass {
@@ -51,6 +53,9 @@ SwfdecBitmapData *	swfdec_bitmap_data_new			(SwfdecAsContext *	context,
 								 guint			width,
 								 guint			height);
 
+guint			swfdec_bitmap_data_get_width		(SwfdecBitmapData *	data);
+guint			swfdec_bitmap_data_get_height		(SwfdecBitmapData *	data);
+
 
 G_END_DECLS
 #endif
diff --git a/swfdec/swfdec_bitmap_movie.c b/swfdec/swfdec_bitmap_movie.c
index a117feb..1fe4f5e 100644
--- a/swfdec/swfdec_bitmap_movie.c
+++ b/swfdec/swfdec_bitmap_movie.c
@@ -37,8 +37,8 @@ swfdec_bitmap_movie_update_extents (SwfdecMovie *movie,
   if (bitmap->bitmap->surface == NULL)
     return;
 
-  rect.x1 = cairo_image_surface_get_width (bitmap->bitmap->surface) * SWFDEC_TWIPS_SCALE_FACTOR;
-  rect.y1 = cairo_image_surface_get_height (bitmap->bitmap->surface) * SWFDEC_TWIPS_SCALE_FACTOR;
+  rect.x1 = swfdec_bitmap_data_get_width (bitmap->bitmap) * SWFDEC_TWIPS_SCALE_FACTOR;
+  rect.y1 = swfdec_bitmap_data_get_height (bitmap->bitmap) * SWFDEC_TWIPS_SCALE_FACTOR;
 
   swfdec_rect_union (extents, extents, &rect);
 }
@@ -57,8 +57,8 @@ swfdec_bitmap_movie_render (SwfdecMovie *movie, cairo_t *cr,
     SWFDEC_FIXME ("does attachBitmap mask?");
     cairo_set_source_rgb (cr, 0, 0, 0);
     cairo_rectangle (cr, 0, 0, 
-	cairo_image_surface_get_width (bitmap->bitmap->surface),
-	cairo_image_surface_get_height (bitmap->bitmap->surface));
+	swfdec_bitmap_data_get_width (bitmap->bitmap) * SWFDEC_TWIPS_SCALE_FACTOR,
+	swfdec_bitmap_data_get_height (bitmap->bitmap) * SWFDEC_TWIPS_SCALE_FACTOR);
     cairo_fill (cr);
   } else if (swfdec_color_transform_is_identity (trans)) {
     cairo_set_source_surface (cr, bitmap->bitmap->surface, 0, 0);
@@ -82,8 +82,8 @@ swfdec_bitmap_movie_invalidate (SwfdecMovie *movie, const cairo_matrix_t *matrix
   if (bitmap->bitmap->surface == NULL)
     return;
 
-  rect.x1 = cairo_image_surface_get_width (bitmap->bitmap->surface) * SWFDEC_TWIPS_SCALE_FACTOR;
-  rect.y1 = cairo_image_surface_get_height (bitmap->bitmap->surface) * SWFDEC_TWIPS_SCALE_FACTOR;
+  rect.x1 = swfdec_bitmap_data_get_width (bitmap->bitmap) * SWFDEC_TWIPS_SCALE_FACTOR;
+  rect.y1 = swfdec_bitmap_data_get_height (bitmap->bitmap) * SWFDEC_TWIPS_SCALE_FACTOR;
 
   swfdec_rect_transform (&rect, &rect, matrix);
   swfdec_player_invalidate (SWFDEC_PLAYER (swfdec_gc_object_get_context (movie)), &rect);
diff --git a/swfdec/swfdec_bitmap_pattern.c b/swfdec/swfdec_bitmap_pattern.c
index aa22af1..e6c7861 100644
--- a/swfdec/swfdec_bitmap_pattern.c
+++ b/swfdec/swfdec_bitmap_pattern.c
@@ -51,8 +51,8 @@ swfdec_bitmap_pattern_get_pattern (SwfdecPattern *pat, SwfdecRenderer *renderer,
   } else {
     /* FIXME: more caching? */
     SwfdecRectangle area = { 0, 0, 
-      cairo_image_surface_get_width (bitmap->bitmap->surface),
-      cairo_image_surface_get_height (bitmap->bitmap->surface) };
+      swfdec_bitmap_data_get_width (bitmap->bitmap),
+      swfdec_bitmap_data_get_height (bitmap->bitmap) };
     cairo_surface_t *surface = swfdec_renderer_transform (renderer,
 	bitmap->bitmap->surface, ctrans, &area);
     pattern = cairo_pattern_create_for_surface (surface);


More information about the Swfdec-commits mailing list