[Swfdec-commits] 5 commits - swfdec/swfdec_bitmap_data.c swfdec/swfdec_renderer.c

Benjamin Otte company at kemper.freedesktop.org
Mon Jul 28 14:48:17 PDT 2008


 swfdec/swfdec_bitmap_data.c |  110 ++++++++++++++++++++++++++++++++++++++++++--
 swfdec/swfdec_renderer.c    |    4 -
 2 files changed, 107 insertions(+), 7 deletions(-)

New commits:
commit 53c99c6be76babff26edac328a76dd479bb2e0ea
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Jul 28 23:44:59 2008 +0200

    implement BitmapData.draw

diff --git a/swfdec/swfdec_bitmap_data.c b/swfdec/swfdec_bitmap_data.c
index 06d6327..9abc1e5 100644
--- a/swfdec/swfdec_bitmap_data.c
+++ b/swfdec/swfdec_bitmap_data.c
@@ -370,12 +370,104 @@ swfdec_bitmap_data_fillRect (SwfdecAsContext *cx, SwfdecAsObject *object,
   SWFDEC_STUB ("BitmapData.fillRect");
 }
 
+static gboolean
+swfdec_rectangle_from_as_object (SwfdecRectangle *rect, SwfdecAsObject *object)
+{
+  SwfdecAsValue *val;
+  SwfdecAsContext *cx = swfdec_gc_object_get_context (object);
+
+  /* FIXME: This function is untested */
+  val = swfdec_as_object_peek_variable (object, SWFDEC_AS_STR_x);
+  rect->x = swfdec_as_value_to_integer (cx, val);
+  val = swfdec_as_object_peek_variable (object, SWFDEC_AS_STR_y);
+  rect->y = swfdec_as_value_to_integer (cx, val);
+  val = swfdec_as_object_peek_variable (object, SWFDEC_AS_STR_width);
+  rect->width = swfdec_as_value_to_integer (cx, val);
+  val = swfdec_as_object_peek_variable (object, SWFDEC_AS_STR_height);
+  rect->height = swfdec_as_value_to_integer (cx, val);
+  return rect->width > 0 && rect->height > 0;
+}
+
+static void
+swfdec_point_from_as_object (int *x, int *y, SwfdecAsObject *object)
+{
+  SwfdecAsValue *val;
+  SwfdecAsContext *cx = swfdec_gc_object_get_context (object);
+
+  /* FIXME: This function is untested */
+  val = swfdec_as_object_peek_variable (object, SWFDEC_AS_STR_x);
+  *x = swfdec_as_value_to_integer (cx, val);
+  val = swfdec_as_object_peek_variable (object, SWFDEC_AS_STR_y);
+  *y = swfdec_as_value_to_integer (cx, val);
+}
+
 SWFDEC_AS_NATIVE (1100, 4, swfdec_bitmap_data_copyPixels)
 void
 swfdec_bitmap_data_copyPixels (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
-  SWFDEC_STUB ("BitmapData.copyPixels");
+  SwfdecBitmapData *bitmap, *source, *alpha;
+  SwfdecAsObject *recto, *apt, *pt;
+  SwfdecRectangle rect;
+  gboolean copy_alpha;
+  cairo_t *cr;
+  int x, y;
+
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_BITMAP_DATA, &bitmap, "ooo|OOb", &source, &recto, &pt,
+      &alpha, &apt, &copy_alpha);
+
+  if (bitmap->surface == NULL ||
+      !SWFDEC_IS_BITMAP_DATA (source) ||
+      source->surface == NULL ||
+      (argc > 3 && (!SWFDEC_IS_BITMAP_DATA (alpha) || alpha->surface == NULL)) ||
+      !swfdec_rectangle_from_as_object (&rect, recto))
+    return;
+
+  x = rect.x;
+  y = rect.y;
+  swfdec_point_from_as_object (&rect.x, &rect.y, pt);
+  cr = cairo_create (bitmap->surface);
+  if (bitmap == source) {
+    cairo_surface_t *copy = cairo_surface_create_similar (source->surface,
+	cairo_surface_get_content (source->surface),
+	rect.width, rect.height);
+    cairo_t *cr2 = cairo_create (copy);
+    cairo_set_source_surface (cr2, source->surface, x, y);
+    cairo_paint (cr2);
+    cairo_destroy (cr2);
+    cairo_set_source_surface (cr, copy, rect.x, rect.y);
+    cairo_surface_destroy (copy);
+  } else {
+    cairo_set_source_surface (cr, source->surface, rect.x - x, rect.y - y);
+  }
+
+  if (swfdec_surface_has_alpha (bitmap->surface) && !copy_alpha) {
+    cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+  }
+
+  cairo_rectangle (cr, rect.x, rect.y, rect.width, rect.height);
+  if (alpha) {
+    cairo_surface_t *mask = cairo_surface_create_similar (alpha->surface,
+	CAIRO_CONTENT_COLOR_ALPHA, rect.width, rect.height);
+    cairo_t *cr2 = cairo_create (mask);
+
+    cairo_surface_set_device_offset (mask, -rect.x, -rect.y);
+    cairo_set_source (cr2, cairo_get_source (cr));
+    if (apt) {
+      swfdec_point_from_as_object (&x, &y, apt);
+    } else {
+      x = y = 0;
+    }
+    cairo_mask_surface (cr2, alpha->surface, rect.x - x, rect.y - y);
+    cairo_destroy (cr2);
+    cairo_surface_write_to_png (mask, "foo.png");
+    cairo_set_source_surface (cr, mask, 0, 0);
+    cairo_surface_destroy (mask);
+  }
+  cairo_fill (cr);
+  cairo_destroy (cr);
+  cairo_surface_mark_dirty_rectangle (bitmap->surface, rect.x, rect.y, 
+      rect.width, rect.height);
 }
 
 SWFDEC_AS_NATIVE (1100, 5, swfdec_bitmap_data_applyFilter)
commit a2b45d7fc2c124d858c5e95d69ac5147fdec02e1
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Jul 28 23:44:44 2008 +0200

    make sure we set TRUE or FALSE, and not something else

diff --git a/swfdec/swfdec_bitmap_data.c b/swfdec/swfdec_bitmap_data.c
index 6110383..06d6327 100644
--- a/swfdec/swfdec_bitmap_data.c
+++ b/swfdec/swfdec_bitmap_data.c
@@ -279,7 +279,8 @@ swfdec_bitmap_data_get_transparent (SwfdecAsContext *cx,
   SWFDEC_AS_CHECK (SWFDEC_TYPE_BITMAP_DATA, &bitmap, "");
 
   if (bitmap->surface) {
-    SWFDEC_AS_VALUE_SET_BOOLEAN (ret, swfdec_surface_has_alpha (bitmap->surface));
+    SWFDEC_AS_VALUE_SET_BOOLEAN (ret, 
+	swfdec_surface_has_alpha (bitmap->surface) ? TRUE : FALSE);
   } else {
     SWFDEC_AS_VALUE_SET_INT (ret, -1);
   }
commit f3482830238a0ba8ad064c80598cb9b8af2d3dc6
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Jul 28 21:44:53 2008 +0200

    setPixel32 works different on opaque surfaces

diff --git a/swfdec/swfdec_bitmap_data.c b/swfdec/swfdec_bitmap_data.c
index 794b915..6110383 100644
--- a/swfdec/swfdec_bitmap_data.c
+++ b/swfdec/swfdec_bitmap_data.c
@@ -552,7 +552,11 @@ swfdec_bitmap_data_setPixel32 (SwfdecAsContext *cx, SwfdecAsObject *object,
   addr = cairo_image_surface_get_data (bitmap->surface);
   addr += cairo_image_surface_get_stride (bitmap->surface) * y;
   addr += 4 * x;
-  *(SwfdecColor *) addr = SWFDEC_COLOR_MULTIPLY ((SwfdecColor) color);
+  if (swfdec_surface_has_alpha (bitmap->surface)) {
+    *(SwfdecColor *) addr = SWFDEC_COLOR_MULTIPLY ((SwfdecColor) color);
+  } else {
+    *(SwfdecColor *) addr = SWFDEC_COLOR_OPAQUE ((SwfdecColor) color);
+  }
   cairo_surface_mark_dirty_rectangle (bitmap->surface, x, y, 1, 1);
   swfdec_bitmap_data_invalidate (bitmap, x, y, 1, 1);
 }
commit f85e48b3aea0876d90096fe01875b099e98acfb8
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Jul 28 21:32:30 2008 +0200

    use correct method to query if a surface has alpha contents

diff --git a/swfdec/swfdec_bitmap_data.c b/swfdec/swfdec_bitmap_data.c
index d713ea0..794b915 100644
--- a/swfdec/swfdec_bitmap_data.c
+++ b/swfdec/swfdec_bitmap_data.c
@@ -136,6 +136,8 @@ swfdec_bitmap_data_new (SwfdecAsContext *context, gboolean transparent, guint wi
   return bitmap;
 }
 
+#define swfdec_surface_has_alpha(surface) (cairo_surface_get_content (surface) & CAIRO_CONTENT_ALPHA)
+
 SWFDEC_AS_NATIVE (1100, 40, swfdec_bitmap_data_loadBitmap)
 void
 swfdec_bitmap_data_loadBitmap (SwfdecAsContext *cx, SwfdecAsObject *object,
@@ -163,7 +165,7 @@ swfdec_bitmap_data_loadBitmap (SwfdecAsContext *cx, SwfdecAsObject *object,
 
   /* FIXME: use image directly instead of doing a copy and then deleting it */
   bitmap = swfdec_bitmap_data_new (cx, 
-      cairo_image_surface_get_format (isurface) != CAIRO_FORMAT_RGB24,
+      swfdec_surface_has_alpha (isurface),
       cairo_image_surface_get_width (isurface),
       cairo_image_surface_get_height (isurface));
   if (bitmap == NULL)
@@ -277,8 +279,7 @@ swfdec_bitmap_data_get_transparent (SwfdecAsContext *cx,
   SWFDEC_AS_CHECK (SWFDEC_TYPE_BITMAP_DATA, &bitmap, "");
 
   if (bitmap->surface) {
-    SWFDEC_AS_VALUE_SET_BOOLEAN (ret, 
-	cairo_image_surface_get_format (bitmap->surface) != CAIRO_FORMAT_RGB24);
+    SWFDEC_AS_VALUE_SET_BOOLEAN (ret, swfdec_surface_has_alpha (bitmap->surface));
   } else {
     SWFDEC_AS_VALUE_SET_INT (ret, -1);
   }
@@ -643,7 +644,7 @@ swfdec_bitmap_data_clone (SwfdecAsContext *cx, SwfdecAsObject *object,
     return;
 
   clone = swfdec_bitmap_data_new (cx,
-      cairo_image_surface_get_format (bitmap->surface) != CAIRO_FORMAT_RGB24,
+      swfdec_surface_has_alpha (bitmap->surface),
       cairo_image_surface_get_width (bitmap->surface),
       cairo_image_surface_get_height (bitmap->surface));
   if (clone == NULL)
diff --git a/swfdec/swfdec_renderer.c b/swfdec/swfdec_renderer.c
index 00357e8..7e4495c 100644
--- a/swfdec/swfdec_renderer.c
+++ b/swfdec/swfdec_renderer.c
@@ -418,8 +418,8 @@ swfdec_renderer_transform (SwfdecRenderer *renderer, cairo_surface_t *surface,
   h = cairo_image_surface_get_height (surface);
   sdata = cairo_image_surface_get_data (surface);
   sstride = cairo_image_surface_get_stride (surface);
-  mask = cairo_image_surface_get_format (surface) == CAIRO_FORMAT_RGB24 ? 
-    SWFDEC_COLOR_COMBINE (0, 0, 0, 0xFF) : 0;
+  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);
commit 05e7ef07fe13c557badea24bd2bfbf0846eede1d
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Jul 28 13:43:12 2008 +0200

    add a FIXME about a bug

diff --git a/swfdec/swfdec_bitmap_data.c b/swfdec/swfdec_bitmap_data.c
index 4944e48..d713ea0 100644
--- a/swfdec/swfdec_bitmap_data.c
+++ b/swfdec/swfdec_bitmap_data.c
@@ -483,6 +483,8 @@ swfdec_bitmap_data_draw (SwfdecAsContext *cx, SwfdecAsObject *object,
       } else {
 	cairo_surface_t *transformed = swfdec_renderer_transform (renderer,
 	    SWFDEC_BITMAP_DATA (o)->surface, &ctrans);
+	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);
       }


More information about the Swfdec-commits mailing list