[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