[Swfdec-commits] 2 commits - swfdec-gtk/swfdec_gtk_widget.c swfdec/swfdec_graphic.c swfdec/swfdec_graphic.h swfdec/swfdec_graphic_movie.c swfdec/swfdec_marshal.list swfdec/swfdec_morph_movie.c swfdec/swfdec_movie.c swfdec/swfdec_movie.h swfdec/swfdec_player.c swfdec/swfdec_player.h swfdec/swfdec_player_internal.h swfdec/swfdec_shape.c swfdec/swfdec_text.c swfdec/swfdec_text_field_movie.c swfdec/swfdec_video_movie.c test/swfdec_test_plugin.c tools/crashfinder.c tools/swfdec-extract.c

Benjamin Otte company at kemper.freedesktop.org
Wed Jul 2 00:58:54 PDT 2008


 swfdec-gtk/swfdec_gtk_widget.c   |    7 +-
 swfdec/swfdec_graphic.c          |    4 -
 swfdec/swfdec_graphic.h          |    7 --
 swfdec/swfdec_graphic_movie.c    |    4 -
 swfdec/swfdec_marshal.list       |    2 
 swfdec/swfdec_morph_movie.c      |    7 +-
 swfdec/swfdec_movie.c            |  110 ++++++++++++++++-----------------------
 swfdec/swfdec_movie.h            |    6 --
 swfdec/swfdec_player.c           |   72 +++++++------------------
 swfdec/swfdec_player.h           |   12 ----
 swfdec/swfdec_player_internal.h  |    1 
 swfdec/swfdec_shape.c            |    7 +-
 swfdec/swfdec_text.c             |    5 -
 swfdec/swfdec_text_field_movie.c |   10 ++-
 swfdec/swfdec_video_movie.c      |    2 
 test/swfdec_test_plugin.c        |    4 -
 tools/crashfinder.c              |    2 
 tools/swfdec-extract.c           |    2 
 18 files changed, 107 insertions(+), 157 deletions(-)

New commits:
commit 78848dd0917439219e47ff70412e6dbebdc63993
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Jul 2 09:50:41 2008 +0200

    make "invalidate" signal not emit extents anymore
    
    Since we can now use clipping for drawing, users can just keep all the
    rectangles and cairo_clip() with them prior to rendering

diff --git a/swfdec-gtk/swfdec_gtk_widget.c b/swfdec-gtk/swfdec_gtk_widget.c
index 95f63b6..5822442 100644
--- a/swfdec-gtk/swfdec_gtk_widget.c
+++ b/swfdec-gtk/swfdec_gtk_widget.c
@@ -684,7 +684,7 @@ swfdec_gtk_widget_do_invalidate (gpointer widgetp)
 }
 
 static void
-swfdec_gtk_widget_invalidate_cb (SwfdecPlayer *player, const SwfdecRectangle *extents,
+swfdec_gtk_widget_invalidate_cb (SwfdecPlayer *player,
     const SwfdecRectangle *rect, guint n_rects, SwfdecGtkWidget *widget)
 {
   SwfdecGtkWidgetPrivate *priv = widget->priv;
diff --git a/swfdec/swfdec_marshal.list b/swfdec/swfdec_marshal.list
index fb33a3e..f7b96b7 100644
--- a/swfdec/swfdec_marshal.list
+++ b/swfdec/swfdec_marshal.list
@@ -1,6 +1,6 @@
 BOOLEAN:DOUBLE,DOUBLE,INT
 BOOLEAN:UINT,UINT,BOOLEAN
-VOID:BOXED,POINTER,UINT
+VOID:POINTER,UINT
 VOID:STRING,STRING
 VOID:STRING,STRING,BOXED,UINT,BOXED,BOXED
 VOID:ULONG,UINT
diff --git a/swfdec/swfdec_player.c b/swfdec/swfdec_player.c
index 829bca0..9c291bb 100644
--- a/swfdec/swfdec_player.c
+++ b/swfdec/swfdec_player.c
@@ -69,7 +69,7 @@
  * to the player by calling for example swfdec_player_handle_mouse().
  *
  * You can use swfdec_player_render() to draw the current state of the player.
- * After that, connect to the SwfdecPlayer::invalidate signal to be notified of
+ * After that, connect to the SwfdecPlayer:invalidate signal to be notified of
  * changes.
  *
  * Audio output is handled via the 
@@ -817,10 +817,9 @@ swfdec_player_emit_signals (SwfdecPlayer *player)
   GList *walk;
 
   /* emit invalidate signal */
-  if (!swfdec_rectangle_is_empty (&priv->invalid_extents)) {
-    g_signal_emit (player, signals[INVALIDATE], 0, &priv->invalid_extents,
+  if (priv->invalidations->len != 0) {
+    g_signal_emit (player, signals[INVALIDATE], 0,
 	priv->invalidations->data, priv->invalidations->len);
-    swfdec_rectangle_init_empty (&priv->invalid_extents);
     g_array_set_size (priv->invalidations, 0);
   }
 
@@ -1835,7 +1834,7 @@ swfdec_player_lock_soft (SwfdecPlayer *player)
 {
   g_return_if_fail (SWFDEC_IS_PLAYER (player));
   g_assert (!swfdec_player_is_locked (player));
-  g_assert (swfdec_rectangle_is_empty (&player->priv->invalid_extents));
+  g_assert (player->priv->invalidations->len == 0);
 
   g_object_freeze_notify (G_OBJECT (player));
   g_timer_start (player->priv->runtime);
@@ -2179,7 +2178,6 @@ swfdec_player_class_init (SwfdecPlayerClass *klass)
   /**
    * SwfdecPlayer::invalidate:
    * @player: the #SwfdecPlayer affected
-   * @extents: the smallest rectangle enclosing the full region of changes
    * @rectangles: a number of smaller rectangles for fine-grained control over 
    *              changes
    * @n_rectangles: number of rectangles in @rectangles
@@ -2192,8 +2190,8 @@ swfdec_player_class_init (SwfdecPlayerClass *klass)
    * provides a way to handle regions.
    */
   signals[INVALIDATE] = g_signal_new ("invalidate", G_TYPE_FROM_CLASS (klass),
-      G_SIGNAL_RUN_LAST, 0, NULL, NULL, swfdec_marshal_VOID__BOXED_POINTER_UINT,
-      G_TYPE_NONE, 3, SWFDEC_TYPE_RECTANGLE, G_TYPE_POINTER, G_TYPE_UINT);
+      G_SIGNAL_RUN_LAST, 0, NULL, NULL, swfdec_marshal_VOID__POINTER_UINT,
+      G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_UINT);
   /**
    * SwfdecPlayer::advance:
    * @player: the #SwfdecPlayer affected
@@ -2443,19 +2441,14 @@ swfdec_player_invalidate (SwfdecPlayer *player, const SwfdecRect *rect)
       break;
     if (swfdec_rectangle_contains (&r, cur)) {
       *cur = r;
-      swfdec_rectangle_union (&priv->invalid_extents, &priv->invalid_extents, &r);
       break;
     }
   }
   if (i == priv->invalidations->len) {
     g_array_append_val (priv->invalidations, r);
-    swfdec_rectangle_union (&priv->invalid_extents, &priv->invalid_extents, &r);
   }
-  SWFDEC_DEBUG ("toplevel invalidation of %d %d  %d %d - invalid region now %d %d  %d %d (%u subregions)",
+  SWFDEC_DEBUG ("toplevel invalidation of %d %d  %d %d - now %u subregions",
       r.x, r.y, r.width, r.height,
-      priv->invalid_extents.x, priv->invalid_extents.y, 
-      priv->invalid_extents.x + priv->invalid_extents.width,
-      priv->invalid_extents.y + priv->invalid_extents.height,
       priv->invalidations->len);
 }
 
diff --git a/swfdec/swfdec_player_internal.h b/swfdec/swfdec_player_internal.h
index 8a83bf4..2a0867a 100644
--- a/swfdec/swfdec_player_internal.h
+++ b/swfdec/swfdec_player_internal.h
@@ -107,7 +107,6 @@ struct _SwfdecPlayerPrivate
   GHashTable *		registered_classes;	/* name => SwfdecAsObject constructor */
 
   /* rendering */
-  SwfdecRectangle     	invalid_extents;      	/* extents of area that needs a redraw in global coordinates */
   GArray *		invalidations;		/* fine-grained areas in need of redraw */
   GSList *		invalid_pending;	/* pending invalidations due to invalidate_last */
   gboolean		fullscreen;		/* TRUE if the player has gone fullscreen */
commit 6efa5a0a70511667c9a620d3791c80228f881bd3
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Jul 2 09:43:30 2008 +0200

    get rid of passing invalid areas when rendering
    
    Use cairo_clip_extents() instead

diff --git a/swfdec-gtk/swfdec_gtk_widget.c b/swfdec-gtk/swfdec_gtk_widget.c
index f6eb96e..95f63b6 100644
--- a/swfdec-gtk/swfdec_gtk_widget.c
+++ b/swfdec-gtk/swfdec_gtk_widget.c
@@ -276,8 +276,9 @@ swfdec_gtk_widget_expose (GtkWidget *gtkwidget, GdkEventExpose *event)
     cairo_surface_set_device_offset (surface, -event->area.x, -event->area.y);
     cr = cairo_create (surface);
   }
-  swfdec_player_render (priv->player, cr,
-      event->area.x, event->area.y, event->area.width, event->area.height);
+  gdk_cairo_region (cr, event->region);
+  cairo_clip (cr);
+  swfdec_player_render (priv->player, cr);
   cairo_show_page (cr);
   cairo_destroy (cr);
 
diff --git a/swfdec/swfdec_graphic.c b/swfdec/swfdec_graphic.c
index c316084..0d3c260 100644
--- a/swfdec/swfdec_graphic.c
+++ b/swfdec/swfdec_graphic.c
@@ -51,12 +51,12 @@ swfdec_graphic_init (SwfdecGraphic *graphic)
 
 void
 swfdec_graphic_render (SwfdecGraphic *graphic, cairo_t *cr,
-    const SwfdecColorTransform *trans, const SwfdecRect *inval)
+    const SwfdecColorTransform *trans)
 {
   SwfdecGraphicClass *klass = SWFDEC_GRAPHIC_GET_CLASS (graphic);
 
   if (klass->render)
-    klass->render (graphic, cr, trans, inval);
+    klass->render (graphic, cr, trans);
 }
 
 gboolean
diff --git a/swfdec/swfdec_graphic.h b/swfdec/swfdec_graphic.h
index 52e0f74..3c96ba3 100644
--- a/swfdec/swfdec_graphic.h
+++ b/swfdec/swfdec_graphic.h
@@ -24,7 +24,6 @@
 
 #include <glib-object.h>
 #include <swfdec/swfdec_character.h>
-#include <swfdec/swfdec_rect.h>
 #include <swfdec/swfdec_types.h>
 
 G_BEGIN_DECLS
@@ -56,8 +55,7 @@ struct _SwfdecGraphicClass
   /* optional vfuncs */
   void			(* render)	(SwfdecGraphic *	      	graphic, 
                                          cairo_t *			cr,
-					 const SwfdecColorTransform *	trans,
-					 const SwfdecRect *		inval);
+					 const SwfdecColorTransform *	trans);
   gboolean		(* mouse_in)	(SwfdecGraphic *      		graphic,
 					 double				x,
 					 double				y);
@@ -67,8 +65,7 @@ GType		swfdec_graphic_get_type	(void);
 
 void		swfdec_graphic_render	(SwfdecGraphic *		graphic,
                                          cairo_t *			cr,
-					 const SwfdecColorTransform *	trans,
-					 const SwfdecRect *		inval);
+					 const SwfdecColorTransform *	trans);
 gboolean	swfdec_graphic_mouse_in	(SwfdecGraphic *      		graphic,
 					 double				x,
 					 double				y);
diff --git a/swfdec/swfdec_graphic_movie.c b/swfdec/swfdec_graphic_movie.c
index 24e8a77..55dfcdc 100644
--- a/swfdec/swfdec_graphic_movie.c
+++ b/swfdec/swfdec_graphic_movie.c
@@ -45,9 +45,9 @@ swfdec_graphic_movie_update_extents (SwfdecMovie *movie,
 
 static void
 swfdec_graphic_movie_render (SwfdecMovie *movie, cairo_t *cr, 
-    const SwfdecColorTransform *trans, const SwfdecRect *inval)
+    const SwfdecColorTransform *trans)
 {
-  swfdec_graphic_render (movie->graphic, cr, trans, inval);
+  swfdec_graphic_render (movie->graphic, cr, trans);
 }
 
 static void
diff --git a/swfdec/swfdec_morph_movie.c b/swfdec/swfdec_morph_movie.c
index e53f881..b060eb0 100644
--- a/swfdec/swfdec_morph_movie.c
+++ b/swfdec/swfdec_morph_movie.c
@@ -70,18 +70,21 @@ swfdec_morph_movie_create_morphs (SwfdecMorphMovie *mmovie)
 
 static void
 swfdec_morph_movie_render (SwfdecMovie *movie, cairo_t *cr, 
-    const SwfdecColorTransform *trans, const SwfdecRect *inval)
+    const SwfdecColorTransform *trans)
 {
   SwfdecMorphMovie *morph = SWFDEC_MORPH_MOVIE (movie);
+  SwfdecRect inval;
   GSList *walk;
 
   if (morph->draws == NULL)
     swfdec_morph_movie_create_morphs (morph);
 
+  cairo_clip_extents (cr, &inval.x0, &inval.y0, &inval.x1, &inval.y1);
+
   for (walk = morph->draws; walk; walk = walk->next) {
     SwfdecDraw *draw = walk->data;
 
-    if (!swfdec_rect_intersect (NULL, &draw->extents, inval))
+    if (!swfdec_rect_intersect (NULL, &draw->extents, &inval))
       continue;
     
     swfdec_draw_paint (draw, cr, trans);
diff --git a/swfdec/swfdec_movie.c b/swfdec/swfdec_movie.c
index 4779c4e..e9c8aa4 100644
--- a/swfdec/swfdec_movie.c
+++ b/swfdec/swfdec_movie.c
@@ -731,12 +731,11 @@ swfdec_movie_get_operator_for_blend_mode (guint blend_mode)
  * @cr: a cairo context which should be used for masking. The cairo context's
  *      matrix is assumed to be in the coordinate system of the movie's parent.
  * @matrix: matrix to apply before rendering
- * @inval: The region that is relevant for masking
  *
  * Creates a pattern suitable for masking. To do rendering using the returned
  * mask, you want to use code like this:
  * <informalexample><programlisting>
- * mask = swfdec_movie_mask (cr, movie, matrix, inval);
+ * mask = swfdec_movie_mask (cr, movie, matrix);
  * cairo_push_group (cr);
  * // do rendering here
  * cairo_pop_group_to_source (cr);
@@ -748,35 +747,24 @@ swfdec_movie_get_operator_for_blend_mode (guint blend_mode)
  **/
 static cairo_pattern_t *
 swfdec_movie_mask (cairo_t *cr, SwfdecMovie *movie,
-    const cairo_matrix_t *matrix, const SwfdecRect *inval)
+    const cairo_matrix_t *matrix)
 {
   SwfdecColorTransform black;
-  cairo_matrix_t inv;
-  SwfdecRect rect;
 
   swfdec_color_transform_init_mask (&black);
   cairo_push_group_with_content (cr, CAIRO_CONTENT_ALPHA);
   cairo_transform (cr, matrix);
-  inv = *matrix;
-  if (cairo_matrix_invert (&inv) == CAIRO_STATUS_SUCCESS && FALSE) {
-    swfdec_rect_transform (&rect, inval, &inv);
-  } else {
-    SWFDEC_INFO ("non-invertible matrix when computing invalid area");
-    rect.x0 = rect.y0 = -G_MAXDOUBLE;
-    rect.x1 = rect.y1 = G_MAXDOUBLE;
-  }
 
-  swfdec_movie_render (movie, cr, &black, &rect);
+  swfdec_movie_render (movie, cr, &black);
   return cairo_pop_group (cr);
 }
 
 void
 swfdec_movie_render (SwfdecMovie *movie, cairo_t *cr,
-    const SwfdecColorTransform *color_transform, const SwfdecRect *inval)
+    const SwfdecColorTransform *color_transform)
 {
   SwfdecMovieClass *klass;
   SwfdecColorTransform trans;
-  SwfdecRect rect;
   gboolean group;
 
   g_return_if_fail (SWFDEC_IS_MOVIE (movie));
@@ -785,20 +773,12 @@ swfdec_movie_render (SwfdecMovie *movie, cairo_t *cr,
     g_warning ("%s", cairo_status_to_string (cairo_status (cr)));
   }
   g_return_if_fail (color_transform != NULL);
-  g_return_if_fail (inval != NULL);
   
   if (movie->mask_of != NULL && !swfdec_color_transform_is_mask (color_transform)) {
     SWFDEC_LOG ("not rendering %s %p, movie is a mask",
 	G_OBJECT_TYPE_NAME (movie), movie->name);
     return;
   }
-  if (!swfdec_rect_intersect (NULL, &movie->extents, inval)) {
-    SWFDEC_LOG ("not rendering %s %s, extents %g %g  %g %g are not in invalid area %g %g  %g %g",
-	G_OBJECT_TYPE_NAME (movie), movie->name, 
-	movie->extents.x0, movie->extents.y0, movie->extents.x1, movie->extents.y1,
-	inval->x0, inval->y0, inval->x1, inval->y1);
-    return;
-  }
   if (!movie->visible) {
     SWFDEC_LOG ("not rendering %s %p, movie is invisible",
 	G_OBJECT_TYPE_NAME (movie), movie->name);
@@ -820,15 +800,12 @@ swfdec_movie_render (SwfdecMovie *movie, cairo_t *cr,
       movie->matrix.xy, movie->matrix.yx,
       movie->matrix.x0, movie->matrix.y0);
   cairo_transform (cr, &movie->matrix);
-  swfdec_rect_transform (&rect, inval, &movie->inverse_matrix);
-  SWFDEC_LOG ("%sinvalid area is now: %g %g  %g %g",  movie->parent ? "  " : "",
-      rect.x0, rect.y0, rect.x1, rect.y1);
   swfdec_color_transform_chain (&trans, &movie->original_ctrans, color_transform);
   swfdec_color_transform_chain (&trans, &movie->color_transform, &trans);
 
   klass = SWFDEC_MOVIE_GET_CLASS (movie);
   g_return_if_fail (klass->render);
-  klass->render (movie, cr, &trans, &rect);
+  klass->render (movie, cr, &trans);
 #if 0
   /* code to draw a red rectangle around the area occupied by this movie clip */
   {
@@ -868,7 +845,7 @@ swfdec_movie_render (SwfdecMovie *movie, cairo_t *cr,
       swfdec_movie_local_to_global_matrix (movie->masked_by->parent, &mat2);
       cairo_matrix_multiply (&mat, &mat, &mat2);
     }
-    mask = swfdec_movie_mask (cr, movie->masked_by, &mat, inval);
+    mask = swfdec_movie_mask (cr, movie->masked_by, &mat);
     cairo_pop_group_to_source (cr);
     cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
     cairo_mask (cr, mask);
@@ -1193,7 +1170,7 @@ typedef struct {
 
 static void
 swfdec_movie_do_render (SwfdecMovie *movie, cairo_t *cr,
-    const SwfdecColorTransform *ctrans, const SwfdecRect *inval)
+    const SwfdecColorTransform *ctrans)
 {
   static const cairo_matrix_t ident = { 1, 0, 0, 1, 0, 0};
   GList *g;
@@ -1201,39 +1178,46 @@ swfdec_movie_do_render (SwfdecMovie *movie, cairo_t *cr,
   GSList *clips = NULL;
   ClipEntry *clip = NULL;
 
-  /* exeute the movie's drawing commands */
-  for (walk = movie->draws; walk; walk = walk->next) {
-    SwfdecDraw *draw = walk->data;
+  if (movie->draws || movie->image) {
+    SwfdecRect inval;
 
-    if (!swfdec_rect_intersect (NULL, &draw->extents, inval))
-      continue;
-    
-    swfdec_draw_paint (draw, cr, ctrans);
-  }
+    cairo_clip_extents (cr, &inval.x0, &inval.y0, &inval.x1, &inval.y1);
 
-  /* if the movie loaded an image, draw it here now */
-  if (movie->image) {
-    SwfdecRenderer *renderer = swfdec_renderer_get (cr);
-    cairo_surface_t *surface;
-    cairo_pattern_t *pattern;
-    
-    if (swfdec_color_transform_is_mask (ctrans))
-      surface = NULL;
-    else
-      surface = swfdec_image_create_surface_transformed (movie->image,
-	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 };
-      pattern = cairo_pattern_create_for_surface (surface);
-      SWFDEC_LOG ("rendering loaded image");
-      cairo_pattern_set_matrix (pattern, &matrix);
-    } else {
-      pattern = cairo_pattern_create_rgb (1.0, 0.0, 0.0);
+    /* exeute the movie's drawing commands */
+    for (walk = movie->draws; walk; walk = walk->next) {
+      SwfdecDraw *draw = walk->data;
+
+      if (!swfdec_rect_intersect (NULL, &draw->extents, &inval))
+	continue;
+      
+      swfdec_draw_paint (draw, cr, ctrans);
+    }
+
+    /* if the movie loaded an image, draw it here now */
+    /* FIXME: add check to only draw if inside clip extents */
+    if (movie->image) {
+      SwfdecRenderer *renderer = swfdec_renderer_get (cr);
+      cairo_surface_t *surface;
+      cairo_pattern_t *pattern;
+      
+      if (swfdec_color_transform_is_mask (ctrans))
+	surface = NULL;
+      else
+	surface = swfdec_image_create_surface_transformed (movie->image,
+	  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 };
+	pattern = cairo_pattern_create_for_surface (surface);
+	SWFDEC_LOG ("rendering loaded image");
+	cairo_pattern_set_matrix (pattern, &matrix);
+      } else {
+	pattern = cairo_pattern_create_rgb (1.0, 0.0, 0.0);
+      }
+      cairo_set_source (cr, pattern);
+      cairo_paint (cr);
+      cairo_pattern_destroy (pattern);
+      cairo_surface_destroy (surface);
     }
-    cairo_set_source (cr, pattern);
-    cairo_paint (cr);
-    cairo_pattern_destroy (pattern);
-    cairo_surface_destroy (surface);
   }
 
   /* draw the children movies */
@@ -1243,7 +1227,7 @@ swfdec_movie_do_render (SwfdecMovie *movie, cairo_t *cr,
     while (clip && clip->depth < child->depth) {
       cairo_pattern_t *mask;
       SWFDEC_INFO ("unsetting clip depth %d for depth %d", clip->depth, child->depth);
-      mask = swfdec_movie_mask (cr, clip->movie, &ident, inval);
+      mask = swfdec_movie_mask (cr, clip->movie, &ident);
       cairo_pop_group_to_source (cr);
       cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
       cairo_mask (cr, mask);
@@ -1265,12 +1249,12 @@ swfdec_movie_do_render (SwfdecMovie *movie, cairo_t *cr,
     }
 
     SWFDEC_LOG ("rendering %p with depth %d", child, child->depth);
-    swfdec_movie_render (child, cr, ctrans, inval);
+    swfdec_movie_render (child, cr, ctrans);
   }
   while (clip) {
     cairo_pattern_t *mask;
     SWFDEC_INFO ("unsetting clip depth %d", clip->depth);
-    mask = swfdec_movie_mask (cr, clip->movie, &ident, inval);
+    mask = swfdec_movie_mask (cr, clip->movie, &ident);
     cairo_pop_group_to_source (cr);
     cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
     cairo_mask (cr, mask);
diff --git a/swfdec/swfdec_movie.h b/swfdec/swfdec_movie.h
index 718eed9..450ae9e 100644
--- a/swfdec/swfdec_movie.h
+++ b/swfdec/swfdec_movie.h
@@ -195,8 +195,7 @@ struct _SwfdecMovieClass {
 						 SwfdecRect *   	extents);
   void			(* render)		(SwfdecMovie *		movie, 
 						 cairo_t *		cr,
-						 const SwfdecColorTransform *trans,
-						 const SwfdecRect *	inval);
+						 const SwfdecColorTransform *trans);
   void			(* invalidate)		(SwfdecMovie *		movie,
 						 const cairo_matrix_t *	movie_to_global,
 						 gboolean		new_contents);
@@ -283,8 +282,7 @@ char *		swfdec_movie_get_path		(SwfdecMovie *		movie,
 						 gboolean		dot);
 void		swfdec_movie_render		(SwfdecMovie *		movie,
 						 cairo_t *		cr, 
-						 const SwfdecColorTransform *trans,
-						 const SwfdecRect *	inval);
+						 const SwfdecColorTransform *trans);
 SwfdecMovie *	swfdec_movie_resolve		(SwfdecMovie *		movie);
 guint		swfdec_movie_get_version	(SwfdecMovie *		movie);
 
diff --git a/swfdec/swfdec_player.c b/swfdec/swfdec_player.c
index 6c34da2..829bca0 100644
--- a/swfdec/swfdec_player.c
+++ b/swfdec/swfdec_player.c
@@ -3039,25 +3039,17 @@ swfdec_player_render_focusrect (SwfdecPlayer *player, cairo_t *cr)
  * swfdec_player_render:
  * @player: a #SwfdecPlayer
  * @cr: #cairo_t to render to
- * @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. This function just calls 
  * swfdec_player_render_with_renderer() using the @player's renderer.
  **/
 void
-swfdec_player_render (SwfdecPlayer *player, cairo_t *cr, 
-    double x, double y, double width, double height)
+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 (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_with_renderer (player, cr, player->priv->renderer);
 }
 
 /**
@@ -3065,60 +3057,45 @@ swfdec_player_render (SwfdecPlayer *player, cairo_t *cr,
  * @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.
+ * Renders the given area of the current frame to @cr. If you only want to 
+ * redraw parts of the player, like when responding to a 
+ * SwfdecPlayer:invalidate signal, set a clip on @cr using cairo_clip():
+ * <informalexample><programlisting>
+ * cairo_rectangle (cr, x, y, width, height);
+ * cairo_clip (cr);
+ * swfdec_player_render_with_renderer (player, cr, renderer);
+ * </programlisting></informalexample>
+ * Only redrawing parts of the player improves performance considerably.
  **/
 void
 swfdec_player_render_with_renderer (SwfdecPlayer *player, cairo_t *cr, 
-    SwfdecRenderer *renderer, double x, double y, double width, double height)
+    SwfdecRenderer *renderer)
 {
   static const SwfdecColorTransform trans = { FALSE, 256, 0, 256, 0, 256, 0, 256, 0 };
   SwfdecPlayerPrivate *priv;
   GList *walk;
-  SwfdecRect real;
 
   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);
 
   /* FIXME: fail when !initialized? */
   if (!swfdec_player_is_initialized (player))
     return;
 
   priv = player->priv;
-  if (width == 0.0)
-    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);
-  cairo_clip (cr);
   /* compute the rectangle */
-  real.x0 = x;
-  real.y0 = y;
-  real.x1 = x + width;
-  real.y1 = y + height;
-  swfdec_rect_transform (&real, &real, &priv->stage_to_global);
-  real.x0 = floor (real.x0);
-  real.y0 = floor (real.y0);
-  real.x1 = ceil (real.x1);
-  real.y1 = ceil (real.y1);
-  SWFDEC_INFO ("=== %p: START RENDER, area %g %g  %g %g ===", player, 
-      real.x0, real.y0, real.x1, real.y1);
+  SWFDEC_INFO ("=== %p: START RENDER ===", player);
   /* convert the cairo matrix */
   cairo_transform (cr, &priv->global_to_stage);
 
   for (walk = priv->roots; walk; walk = walk->next) {
-    swfdec_movie_render (walk->data, cr, &trans, &real);
+    swfdec_movie_render (walk->data, cr, &trans);
   }
   cairo_restore (cr);
   /* NB: we render the focusrect after restoring, so the focusrect doesn't scale */
diff --git a/swfdec/swfdec_player.h b/swfdec/swfdec_player.h
index 08b04ef..26703ac 100644
--- a/swfdec/swfdec_player.h
+++ b/swfdec/swfdec_player.h
@@ -158,18 +158,10 @@ void		swfdec_player_set_allow_fullscreen
 						 gboolean		allow);
 					 
 void		swfdec_player_render		(SwfdecPlayer *		player,
-						 cairo_t *		cr,
-						 double			x,
-						 double			y,
-						 double			width,
-						 double			height);
+						 cairo_t *		cr);
 void		swfdec_player_render_with_renderer (SwfdecPlayer *	player,
 						 cairo_t *		cr,
-						 SwfdecRenderer *	renderer,
-						 double			x,
-						 double			y,
-						 double			width,
-						 double			height);
+						 SwfdecRenderer *	renderer);
 gulong		swfdec_player_advance		(SwfdecPlayer *		player,
 						 gulong			msecs);
 gboolean	swfdec_player_mouse_move	(SwfdecPlayer *		player, 
diff --git a/swfdec/swfdec_shape.c b/swfdec/swfdec_shape.c
index ca86d8f..d873b03 100644
--- a/swfdec/swfdec_shape.c
+++ b/swfdec/swfdec_shape.c
@@ -49,15 +49,18 @@ swfdec_shape_dispose (GObject *object)
 
 static void
 swfdec_shape_render (SwfdecGraphic *graphic, cairo_t *cr, 
-    const SwfdecColorTransform *trans, const SwfdecRect *inval)
+    const SwfdecColorTransform *trans)
 {
   SwfdecShape *shape = SWFDEC_SHAPE (graphic);
+  SwfdecRect inval;
   GSList *walk;
 
+  cairo_clip_extents (cr, &inval.x0, &inval.y0, &inval.x1, &inval.y1);
+
   for (walk = shape->draws; walk; walk = walk->next) {
     SwfdecDraw *draw = walk->data;
 
-    if (!swfdec_rect_intersect (NULL, &draw->extents, inval))
+    if (!swfdec_rect_intersect (NULL, &draw->extents, &inval))
       continue;
     
     swfdec_draw_paint (draw, cr, trans);
diff --git a/swfdec/swfdec_text.c b/swfdec/swfdec_text.c
index 9205ea8..a910bf0 100644
--- a/swfdec/swfdec_text.c
+++ b/swfdec/swfdec_text.c
@@ -59,17 +59,15 @@ swfdec_text_mouse_in (SwfdecGraphic *graphic, double x, double y)
 
 static void
 swfdec_text_render (SwfdecGraphic *graphic, cairo_t *cr, 
-    const SwfdecColorTransform *trans, const SwfdecRect *inval)
+    const SwfdecColorTransform *trans)
 {
   guint i;
   SwfdecColor color;
   SwfdecText *text = SWFDEC_TEXT (graphic);
   SwfdecColorTransform force_color;
-  SwfdecRect rect, inval_moved;
 
   cairo_transform (cr, &text->transform);
   /* scale by bounds */
-  swfdec_rect_transform (&inval_moved, inval, &text->transform_inverse);
   for (i = 0; i < text->glyphs->len; i++) {
     SwfdecTextGlyph *glyph;
     SwfdecDraw *draw;
@@ -91,7 +89,6 @@ swfdec_text_render (SwfdecGraphic *graphic, cairo_t *cr,
     cairo_save (cr);
     cairo_transform (cr, &pos);
     if (!cairo_matrix_invert (&pos)) {
-      swfdec_rect_transform (&rect, &inval_moved, &pos);
       color = swfdec_color_apply_transform (glyph->color, trans);
       swfdec_color_transform_init_color (&force_color, color);
       swfdec_draw_paint (draw, cr, &force_color);
diff --git a/swfdec/swfdec_text_field_movie.c b/swfdec/swfdec_text_field_movie.c
index e80408b..917b3f2 100644
--- a/swfdec/swfdec_text_field_movie.c
+++ b/swfdec/swfdec_text_field_movie.c
@@ -220,11 +220,12 @@ swfdec_text_field_movie_has_focus (SwfdecTextFieldMovie *text)
 
 static void
 swfdec_text_field_movie_render (SwfdecMovie *movie, cairo_t *cr,
-    const SwfdecColorTransform *ctrans, const SwfdecRect *inval)
+    const SwfdecColorTransform *ctrans)
 {
   SwfdecTextFieldMovie *text = SWFDEC_TEXT_FIELD_MOVIE (movie);
   SwfdecRectangle *area;
   SwfdecColor color;
+  SwfdecRect inval;
 
   /* textfields don't mask */
   if (swfdec_color_transform_is_mask (ctrans) ||
@@ -263,8 +264,13 @@ swfdec_text_field_movie_render (SwfdecMovie *movie, cairo_t *cr,
     color = 0;
   }
 
-  /* render the layout */
   area = &text->layout_area;
+  /* Don't draw if out of clip */
+  cairo_clip_extents (cr, &inval.x0, &inval.y0, &inval.x1, &inval.y1);
+  if (inval.x1 <= area->x || inval.x0 >= area->x + area->width ||
+      inval.y1 <= area->y || inval.y0 >= area->y + area->height)
+    return;
+  /* render the layout */
   cairo_rectangle (cr, area->x, area->y, area->width, area->height);
   cairo_clip (cr);
   /* FIXME: This -1 is spacing? */
diff --git a/swfdec/swfdec_video_movie.c b/swfdec/swfdec_video_movie.c
index c846058..897aa8c 100644
--- a/swfdec/swfdec_video_movie.c
+++ b/swfdec/swfdec_video_movie.c
@@ -46,7 +46,7 @@ swfdec_video_movie_update_extents (SwfdecMovie *movie,
 
 static void
 swfdec_video_movie_render (SwfdecMovie *mov, cairo_t *cr, 
-    const SwfdecColorTransform *trans, const SwfdecRect *inval)
+    const SwfdecColorTransform *trans)
 {
   SwfdecVideoMovie *movie = SWFDEC_VIDEO_MOVIE (mov);
   cairo_surface_t *surface;
diff --git a/test/swfdec_test_plugin.c b/test/swfdec_test_plugin.c
index 352dd41..bb5a013 100644
--- a/test/swfdec_test_plugin.c
+++ b/test/swfdec_test_plugin.c
@@ -51,6 +51,7 @@ swfdec_test_plugin_swfdec_screenshot (SwfdecTestPlugin *plugin, unsigned char *d
 
   surface = cairo_image_surface_create_for_data (data, CAIRO_FORMAT_ARGB32, 
       width, height, width * 4);
+  cairo_surface_set_device_offset (surface, -(double) x, -(double) y);
   cr = cairo_create (surface);
   background  = swfdec_player_get_background_color (plugin->data);
   cairo_set_source_rgb (cr, 
@@ -59,8 +60,7 @@ swfdec_test_plugin_swfdec_screenshot (SwfdecTestPlugin *plugin, unsigned char *d
       (background & 0xFF) / 255.0);
   cairo_paint (cr);
 
-  cairo_translate (cr, -x, -y);
-  swfdec_player_render (plugin->data, cr, x, y, width, height);
+  swfdec_player_render (plugin->data, cr);
   cairo_destroy (cr);
   cairo_surface_destroy (surface);
 }
diff --git a/tools/crashfinder.c b/tools/crashfinder.c
index cb398ee..12e873c 100644
--- a/tools/crashfinder.c
+++ b/tools/crashfinder.c
@@ -125,7 +125,7 @@ main (int argc, char **argv)
 	break;
       played += swfdec_player_advance (player, advance);
 
-      swfdec_player_render (player, cr, 0, 0, 0, 0);
+      swfdec_player_render (player, cr);
     }
 
     if (elapsed >= max_per_file ||
diff --git a/tools/swfdec-extract.c b/tools/swfdec-extract.c
index 01c7965..2a8df1a 100644
--- a/tools/swfdec-extract.c
+++ b/tools/swfdec-extract.c
@@ -207,7 +207,7 @@ export_graphic (SwfdecGraphic *graphic, const char *filename)
   cairo_scale (cr, 1.0 / SWFDEC_TWIPS_SCALE_FACTOR, 1.0 / SWFDEC_TWIPS_SCALE_FACTOR);
   renderer = swfdec_renderer_new (surface);
   swfdec_renderer_attach (renderer, cr);
-  swfdec_graphic_render (graphic, cr, &trans, &graphic->extents);
+  swfdec_graphic_render (graphic, cr, &trans);
   cairo_show_page (cr);
   cairo_destroy (cr);
   g_object_unref (renderer);


More information about the Swfdec-commits mailing list