[Swfdec-commits] 4 commits - swfdec/swfdec_bitmap_data.c swfdec/swfdec_bitmap_pattern.c swfdec/swfdec_color.h swfdec/swfdec_image.c swfdec/swfdec_renderer.c swfdec/swfdec_renderer_internal.h

Benjamin Otte company at kemper.freedesktop.org
Wed Sep 17 06:44:10 PDT 2008


 swfdec/swfdec_bitmap_data.c       |   65 ++++++++++++++++++++++++++++++++++----
 swfdec/swfdec_bitmap_pattern.c    |   16 ++++++++-
 swfdec/swfdec_color.h             |   46 +++++++++++++++-----------
 swfdec/swfdec_image.c             |    7 +++-
 swfdec/swfdec_renderer.c          |   50 ++++++++++++++++++-----------
 swfdec/swfdec_renderer_internal.h |    5 ++
 6 files changed, 141 insertions(+), 48 deletions(-)

New commits:
commit 60f80707afcfed12b3aee7eebf5e325fc3e807ab
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Sep 17 15:41:50 2008 +0200

    implement BitmapData.colorTransform (no tests)
    
    makes slide 54 work

diff --git a/swfdec/swfdec_bitmap_data.c b/swfdec/swfdec_bitmap_data.c
index 22be2dd..ff94875 100644
--- a/swfdec/swfdec_bitmap_data.c
+++ b/swfdec/swfdec_bitmap_data.c
@@ -645,7 +645,56 @@ void
 swfdec_bitmap_data_colorTransform (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
-  SWFDEC_STUB ("BitmapData.colorTransform");
+  SwfdecBitmapData *bitmap;
+  SwfdecAsObject *rect, *trans;
+  SwfdecRectangle area;
+  SwfdecColorTransform ctrans;
+  cairo_surface_t *surface;
+  cairo_t *cr;
+
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_BITMAP_DATA, &bitmap, "oO", &rect, &trans);
+
+  if (bitmap->surface == NULL)
+    return;
+
+  if (!swfdec_rectangle_from_as_object (&area, rect))
+    return;
+  if (SWFDEC_IS_COLOR_TRANSFORM_AS (trans))
+    swfdec_color_transform_get_transform (SWFDEC_COLOR_TRANSFORM_AS (trans), &ctrans);
+  else
+    return;
+
+  if (area.x < 0) {
+    area.width += area.x;
+    area.x = 0;
+  } else if (area.x >= cairo_image_surface_get_width (bitmap->surface)) {
+    return;
+  }
+  if (area.y < 0) {
+    area.height += area.y;
+    area.y = 0;
+  } else if (area.y >= cairo_image_surface_get_height (bitmap->surface)) {
+    return;
+  }
+  if (area.width + area.x > cairo_image_surface_get_width (bitmap->surface)) {
+    area.width = cairo_image_surface_get_width (bitmap->surface) - 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;
+  } else if (area.height <= 0) {
+    return;
+  }
+
+  surface = swfdec_renderer_transform (SWFDEC_PLAYER (cx)->priv->renderer,
+      bitmap->surface, &ctrans, &area);
+  cr = cairo_create (bitmap->surface);
+  cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+  cairo_set_source_surface (cr, surface, 0, 0);
+  cairo_paint (cr);
+  cairo_destroy (cr);
+  cairo_surface_destroy (surface);
 }
 
 SWFDEC_AS_NATIVE (1100, 16, swfdec_bitmap_data_hitTest)
commit 5a40f0f03d4675f7466626df5d0b2e2fe50d4de1
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Sep 17 15:22:59 2008 +0200

    make bitmap patterns respect color transforms
    
    ... in a very slow way :(

diff --git a/swfdec/swfdec_bitmap_pattern.c b/swfdec/swfdec_bitmap_pattern.c
index 3fc722b..aa22af1 100644
--- a/swfdec/swfdec_bitmap_pattern.c
+++ b/swfdec/swfdec_bitmap_pattern.c
@@ -24,6 +24,7 @@
 #include "swfdec_bitmap_pattern.h"
 #include "swfdec_debug.h"
 #include "swfdec_player_internal.h"
+#include "swfdec_renderer_internal.h"
 
 enum {
   INVALIDATE,
@@ -35,7 +36,7 @@ static guint signals[LAST_SIGNAL];
 
 static cairo_pattern_t *
 swfdec_bitmap_pattern_get_pattern (SwfdecPattern *pat, SwfdecRenderer *renderer,
-    const SwfdecColorTransform *trans)
+    const SwfdecColorTransform *ctrans)
 {
   SwfdecBitmapPattern *bitmap = SWFDEC_BITMAP_PATTERN (pat);
   cairo_pattern_t *pattern;
@@ -45,7 +46,18 @@ swfdec_bitmap_pattern_get_pattern (SwfdecPattern *pat, SwfdecRenderer *renderer,
   if (bitmap->bitmap->surface == NULL)
     return NULL;
 
-  pattern = cairo_pattern_create_for_surface (bitmap->bitmap->surface);
+  if (swfdec_color_transform_is_identity (ctrans)) {
+    pattern = cairo_pattern_create_for_surface (bitmap->bitmap->surface);
+  } else {
+    /* FIXME: more caching? */
+    SwfdecRectangle area = { 0, 0, 
+      cairo_image_surface_get_width (bitmap->bitmap->surface),
+      cairo_image_surface_get_height (bitmap->bitmap->surface) };
+    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 90dab77f5639ee9d3d75eb739557350aa432e353
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Sep 17 13:29:11 2008 +0200

    make color transforming an image take a rectangle argument
    
    BitmapData sometimes only wants to transform part of the image

diff --git a/swfdec/swfdec_bitmap_data.c b/swfdec/swfdec_bitmap_data.c
index 34dd64f..22be2dd 100644
--- a/swfdec/swfdec_bitmap_data.c
+++ b/swfdec/swfdec_bitmap_data.c
@@ -487,11 +487,12 @@ swfdec_bitmap_data_draw (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
   SwfdecAsObject *o, *matrix = NULL, *trans = NULL;
-  cairo_t *cr;
   SwfdecColorTransform ctrans;
   SwfdecBitmapData *bitmap;
   SwfdecRenderer *renderer;
+  SwfdecRectangle area;
   cairo_matrix_t mat;
+  cairo_t *cr;
 
   SWFDEC_AS_CHECK (SWFDEC_TYPE_BITMAP_DATA, &bitmap, "o|OO", &o, &matrix, &trans);
 
@@ -513,6 +514,11 @@ swfdec_bitmap_data_draw (SwfdecAsContext *cx, SwfdecAsObject *object,
   if (argc > 3) {
     SWFDEC_FIXME ("only the first 3 arguments to Bitmap.draw() are implemented");
   }
+  /* 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);
 
   cr = cairo_create (bitmap->surface);
   /* FIXME: Do we have a better renderer? */
@@ -527,7 +533,7 @@ swfdec_bitmap_data_draw (SwfdecAsContext *cx, SwfdecAsObject *object,
 	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);
+	    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);
@@ -546,9 +552,7 @@ swfdec_bitmap_data_draw (SwfdecAsContext *cx, SwfdecAsObject *object,
   }
 
   cairo_destroy (cr);
-  swfdec_bitmap_data_invalidate (bitmap, 0, 0, 
-      cairo_image_surface_get_width (bitmap->surface),
-      cairo_image_surface_get_height (bitmap->surface));
+  swfdec_bitmap_data_invalidate (bitmap, area.x, area.y, area.width, area.height);
 }
 
 SWFDEC_AS_NATIVE (1100, 9, swfdec_bitmap_data_pixelDissolve)
diff --git a/swfdec/swfdec_image.c b/swfdec/swfdec_image.c
index 92bef53..65890ad 100644
--- a/swfdec/swfdec_image.c
+++ b/swfdec/swfdec_image.c
@@ -661,6 +661,7 @@ swfdec_image_create_surface_transformed (SwfdecImage *image, SwfdecRenderer *ren
   SwfdecColorTransform mask;
   SwfdecCachedImage *cached;
   cairo_surface_t *surface, *source;
+  SwfdecRectangle area;
 
   g_return_val_if_fail (SWFDEC_IS_IMAGE (image), NULL);
   g_return_val_if_fail (renderer == NULL || SWFDEC_IS_RENDERER (renderer), NULL);
@@ -692,7 +693,11 @@ swfdec_image_create_surface_transformed (SwfdecImage *image, SwfdecRenderer *ren
     }
   }
 
-  surface = swfdec_renderer_transform (renderer, source, trans);
+  area.x = area.y = 0;
+  area.width = image->width;
+  area.height = image->height;
+  surface = swfdec_renderer_transform (renderer, source, trans, &area);
+
   if (renderer) {
     surface = swfdec_renderer_create_similar (renderer, surface);
     /* FIXME: The size is just an educated guess */
diff --git a/swfdec/swfdec_renderer.c b/swfdec/swfdec_renderer.c
index 259f28a..48b0bbb 100644
--- a/swfdec/swfdec_renderer.c
+++ b/swfdec/swfdec_renderer.c
@@ -402,40 +402,52 @@ swfdec_renderer_create_for_data (SwfdecRenderer *renderer, guint8 *data,
 
 cairo_surface_t *
 swfdec_renderer_transform (SwfdecRenderer *renderer, cairo_surface_t *surface,
-    const SwfdecColorTransform *trans)
+    const SwfdecColorTransform *trans, const SwfdecRectangle *rect)
 {
   cairo_surface_t *target;
-  guint w, h, x, y, sstride, tstride, color;
+  guint stride, color;
   SwfdecColor mask;
-  guint8 *sdata, *tdata;
+  guint8 *data;
+  cairo_t *cr;
+  int x, y;
 
   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);
   g_return_val_if_fail (trans != NULL, NULL);
   g_return_val_if_fail (!swfdec_color_transform_is_mask (trans), NULL);
+  g_return_val_if_fail (rect != NULL, NULL);
+  g_return_val_if_fail (rect->x >= 0, NULL);
+  g_return_val_if_fail (rect->y >= 0, NULL);
+  g_return_val_if_fail (rect->x + rect->width <= cairo_image_surface_get_width (surface), NULL);
+  g_return_val_if_fail (rect->y + rect->height <= cairo_image_surface_get_height (surface), NULL);
 
   /* FIXME: This function should likely be a vfunc. 
    * Or better: it should compile to a shader */
-  w = cairo_image_surface_get_width (surface);
-  h = cairo_image_surface_get_height (surface);
-  sdata = cairo_image_surface_get_data (surface);
-  sstride = cairo_image_surface_get_stride (surface);
-  mask = cairo_surface_get_content (surface) | CAIRO_CONTENT_ALPHA ? 
-    0 : SWFDEC_COLOR_COMBINE (0, 0, 0, 0xFF);
-
-  target = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h);
-  tdata = cairo_image_surface_get_data (target);
-  tstride = cairo_image_surface_get_stride (target);
-  for (y = 0; y < h; y++) {
-    for (x = 0; x < w; x++) {
-      color = ((guint32 *) sdata)[x];
+  if (cairo_surface_get_content (surface) & CAIRO_CONTENT_ALPHA) {
+    target = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, rect->width, rect->height);
+    mask = 0;
+  } else {
+    target = cairo_image_surface_create (CAIRO_FORMAT_RGB24, rect->width, rect->height);
+    mask = SWFDEC_COLOR_COMBINE (0, 0, 0, 0xFF);
+  }
+  cairo_surface_set_device_offset (target, -rect->x, -rect->y);
+
+  cr = cairo_create (target);
+  cairo_set_source_surface (cr, surface, 0, 0);
+  cairo_paint (cr);
+  cairo_destroy (cr);
+
+  data = cairo_image_surface_get_data (target);
+  stride = cairo_image_surface_get_stride (target);
+  for (y = 0; y < rect->height; y++) {
+    for (x = 0; x < rect->width; x++) {
+      color = ((guint32 *) data)[x];
       color |= mask;
       color = swfdec_color_apply_transform_premultiplied (color, trans);
-      ((guint32 *) tdata)[x] = color;
+      ((guint32 *) data)[x] = color;
     }
-    sdata += sstride;
-    tdata += tstride;
+    data += stride;
   }
 
   return target;
diff --git a/swfdec/swfdec_renderer_internal.h b/swfdec/swfdec_renderer_internal.h
index 6d69ef2..682383e 100644
--- a/swfdec/swfdec_renderer_internal.h
+++ b/swfdec/swfdec_renderer_internal.h
@@ -21,8 +21,10 @@
 #define _SWFDEC_RENDERER_INTERNAL_H_
 
 #include <swfdec/swfdec_renderer.h>
+
 #include <swfdec/swfdec_cached.h>
 #include <swfdec/swfdec_color.h>
+#include <swfdec/swfdec_rectangle.h>
 
 G_BEGIN_DECLS
 
@@ -57,7 +59,8 @@ cairo_surface_t *	swfdec_renderer_create_for_data	(SwfdecRenderer *	renderer,
 							 guint			rowstride);
 cairo_surface_t *	swfdec_renderer_transform	(SwfdecRenderer *	renderer,
 							 cairo_surface_t *	surface,
-							 const SwfdecColorTransform *trans);
+							 const SwfdecColorTransform *trans,
+							 const SwfdecRectangle *rect);
 
 
 G_END_DECLS
commit 7393a1f9f1817f2a259016980e6fe1b8d17bd7b0
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Sep 17 12:57:09 2008 +0200

    indent

diff --git a/swfdec/swfdec_color.h b/swfdec/swfdec_color.h
index 6ec5842..1c0e70a 100644
--- a/swfdec/swfdec_color.h
+++ b/swfdec/swfdec_color.h
@@ -55,27 +55,35 @@ struct _SwfdecColorTransform {
 
 #define SWFDEC_COLOR_WHITE		SWFDEC_COLOR_COMBINE (0xFF, 0xFF, 0xFF, 0xFF)
 
-SwfdecColor swfdec_color_apply_morph (SwfdecColor start, SwfdecColor end, guint ratio);
-void swfdec_color_set_source (cairo_t *cr, SwfdecColor color);
-void swfdec_color_transform_init_identity (SwfdecColorTransform * trans);
-void swfdec_color_transform_init_mask (SwfdecColorTransform * trans);
-void swfdec_color_transform_init_color (SwfdecColorTransform *trans, SwfdecColor color);
-gboolean swfdec_color_transform_is_identity (const SwfdecColorTransform * trans);
-gboolean swfdec_color_transform_is_alpha (const SwfdecColorTransform * trans);
+SwfdecColor	swfdec_color_apply_morph			(SwfdecColor	      	start,
+								 SwfdecColor		end,
+								 guint			ratio);
+void		swfdec_color_set_source				(cairo_t *		cr,
+								 SwfdecColor		color);
+void		swfdec_color_transform_init_identity		(SwfdecColorTransform *	trans);
+void		swfdec_color_transform_init_mask		(SwfdecColorTransform *	trans);
+void		swfdec_color_transform_init_color		(SwfdecColorTransform *	trans,
+								 SwfdecColor		color);
+gboolean	swfdec_color_transform_is_identity		(const SwfdecColorTransform *	trans);
+gboolean	swfdec_color_transform_is_alpha			(const SwfdecColorTransform *	trans);
 #define swfdec_color_transform_is_mask(trans) ((trans)->mask)
-void swfdec_color_transform_chain (SwfdecColorTransform *dest,
-    const SwfdecColorTransform *last, const SwfdecColorTransform *first);
-SwfdecColor swfdec_color_apply_transform (SwfdecColor in,
-    const SwfdecColorTransform * trans);
-SwfdecColor swfdec_color_apply_transform_premultiplied (SwfdecColor in, 
-    const SwfdecColorTransform * trans);
+void		swfdec_color_transform_chain			(SwfdecColorTransform *	dest,
+								 const SwfdecColorTransform *	last,
+								 const SwfdecColorTransform *	first);
+SwfdecColor	swfdec_color_apply_transform			(SwfdecColor		in,
+								 const SwfdecColorTransform *	trans);
+SwfdecColor	swfdec_color_apply_transform_premultiplied	(SwfdecColor		in, 
+								 const SwfdecColorTransform *	trans);
 
-void swfdec_matrix_ensure_invertible (cairo_matrix_t *matrix, cairo_matrix_t *inverse);
-double swfdec_matrix_get_xscale (const cairo_matrix_t *matrix);
-double swfdec_matrix_get_yscale (const cairo_matrix_t *matrix);
-double swfdec_matrix_get_rotation (const cairo_matrix_t *matrix);
-void swfdec_matrix_morph (cairo_matrix_t *dest, const cairo_matrix_t *start,
-    const cairo_matrix_t *end, guint ratio);
+void		swfdec_matrix_ensure_invertible			(cairo_matrix_t *	matrix,
+								 cairo_matrix_t *	inverse);
+double		swfdec_matrix_get_xscale			(const cairo_matrix_t *	matrix);
+double		swfdec_matrix_get_yscale			(const cairo_matrix_t *	matrix);
+double		swfdec_matrix_get_rotation			(const cairo_matrix_t *	matrix);
+void		swfdec_matrix_morph				(cairo_matrix_t *	dest,
+								 const cairo_matrix_t *	start,
+								 const cairo_matrix_t *	end,
+								 guint			ratio);
 
 
 G_END_DECLS


More information about the Swfdec-commits mailing list