[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