[Swfdec] 12 commits - libswfdec/Makefile.am libswfdec/swfdec_as_strings.c libswfdec/swfdec_as_types.c libswfdec/swfdec_as_types.h libswfdec/swfdec_gradient_pattern.c libswfdec/swfdec_gradient_pattern.h libswfdec/swfdec_movie_as_drawing.c libswfdec/swfdec_pattern.c test/image
Benjamin Otte
company at kemper.freedesktop.org
Mon Dec 3 04:29:51 PST 2007
libswfdec/Makefile.am | 2
libswfdec/swfdec_as_strings.c | 17 +
libswfdec/swfdec_as_types.c | 16 +
libswfdec/swfdec_as_types.h | 2
libswfdec/swfdec_gradient_pattern.c | 129 +++++++++++++++
libswfdec/swfdec_gradient_pattern.h | 67 +++++++
libswfdec/swfdec_movie_as_drawing.c | 172 +++++++++++++++++++-
libswfdec/swfdec_pattern.c | 123 --------------
test/image/Makefile.am | 23 ++
test/image/empty-gradient.swf |binary
test/image/empty-gradient.swf.png |binary
test/image/empty-gradient.xml | 40 ++++
test/image/gradient-beginGradientFill-5.swf |binary
test/image/gradient-beginGradientFill-5.swf.png |binary
test/image/gradient-beginGradientFill-6.swf |binary
test/image/gradient-beginGradientFill-6.swf.org.png |binary
test/image/gradient-beginGradientFill-6.swf.png |binary
test/image/gradient-beginGradientFill-7.swf |binary
test/image/gradient-beginGradientFill-7.swf.org.png |binary
test/image/gradient-beginGradientFill-7.swf.png |binary
test/image/gradient-beginGradientFill-8.swf |binary
test/image/gradient-beginGradientFill-8.swf.org.png |binary
test/image/gradient-beginGradientFill-8.swf.png |binary
test/image/gradient-beginGradientFill.as | 60 ++++++
test/image/gradient-end-duplication.swf |binary
test/image/gradient-end-duplication.swf.org.png |binary
test/image/gradient-end-duplication.swf.png |binary
test/image/gradient-end-duplication.xml | 59 ++++++
test/image/gradient-ratios.swf |binary
test/image/gradient-ratios.swf.org.png |binary
test/image/gradient-ratios.swf.png |binary
test/image/gradient-ratios.xml | 54 ++++++
32 files changed, 636 insertions(+), 128 deletions(-)
New commits:
commit b8e801500bc51e9f08433742a586cea8c6e66166
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Dec 3 13:15:03 2007 +0100
add a gradient test
diff --git a/test/image/Makefile.am b/test/image/Makefile.am
index 5b870fb..1ae8261 100644
--- a/test/image/Makefile.am
+++ b/test/image/Makefile.am
@@ -73,6 +73,18 @@ EXTRA_DIST = \
fillstyle-order.swf \
fillstyle-order.swf.png \
fillstyle-order.xml \
+ gradient-beginGradientFill.as \
+ gradient-beginGradientFill-5.swf \
+ gradient-beginGradientFill-5.swf.png \
+ gradient-beginGradientFill-6.swf \
+ gradient-beginGradientFill-6.swf.png \
+ gradient-beginGradientFill-6.swf.org.png \
+ gradient-beginGradientFill-7.swf \
+ gradient-beginGradientFill-7.swf.png \
+ gradient-beginGradientFill-7.swf.org.png \
+ gradient-beginGradientFill-8.swf \
+ gradient-beginGradientFill-8.swf.org.png \
+ gradient-beginGradientFill-8.swf.png \
gradient-end-duplication.swf \
gradient-end-duplication.swf.png \
gradient-end-duplication.swf.org.png \
diff --git a/test/image/gradient-beginGradientFill-5.swf b/test/image/gradient-beginGradientFill-5.swf
new file mode 100644
index 0000000..756d2ef
Binary files /dev/null and b/test/image/gradient-beginGradientFill-5.swf differ
diff --git a/test/image/gradient-beginGradientFill-5.swf.png b/test/image/gradient-beginGradientFill-5.swf.png
new file mode 100644
index 0000000..9120be2
Binary files /dev/null and b/test/image/gradient-beginGradientFill-5.swf.png differ
diff --git a/test/image/gradient-beginGradientFill-6.swf b/test/image/gradient-beginGradientFill-6.swf
new file mode 100644
index 0000000..2bbb2b4
Binary files /dev/null and b/test/image/gradient-beginGradientFill-6.swf differ
diff --git a/test/image/gradient-beginGradientFill-6.swf.org.png b/test/image/gradient-beginGradientFill-6.swf.org.png
new file mode 100644
index 0000000..922e154
Binary files /dev/null and b/test/image/gradient-beginGradientFill-6.swf.org.png differ
diff --git a/test/image/gradient-beginGradientFill-6.swf.png b/test/image/gradient-beginGradientFill-6.swf.png
new file mode 100644
index 0000000..338d94a
Binary files /dev/null and b/test/image/gradient-beginGradientFill-6.swf.png differ
diff --git a/test/image/gradient-beginGradientFill-7.swf b/test/image/gradient-beginGradientFill-7.swf
new file mode 100644
index 0000000..07aa3d7
Binary files /dev/null and b/test/image/gradient-beginGradientFill-7.swf differ
diff --git a/test/image/gradient-beginGradientFill-7.swf.org.png b/test/image/gradient-beginGradientFill-7.swf.org.png
new file mode 100644
index 0000000..1ff6bdb
Binary files /dev/null and b/test/image/gradient-beginGradientFill-7.swf.org.png differ
diff --git a/test/image/gradient-beginGradientFill-7.swf.png b/test/image/gradient-beginGradientFill-7.swf.png
new file mode 100644
index 0000000..338d94a
Binary files /dev/null and b/test/image/gradient-beginGradientFill-7.swf.png differ
diff --git a/test/image/gradient-beginGradientFill-8.swf b/test/image/gradient-beginGradientFill-8.swf
new file mode 100644
index 0000000..89d4623
Binary files /dev/null and b/test/image/gradient-beginGradientFill-8.swf differ
diff --git a/test/image/gradient-beginGradientFill-8.swf.org.png b/test/image/gradient-beginGradientFill-8.swf.org.png
new file mode 100644
index 0000000..427323e
Binary files /dev/null and b/test/image/gradient-beginGradientFill-8.swf.org.png differ
diff --git a/test/image/gradient-beginGradientFill-8.swf.png b/test/image/gradient-beginGradientFill-8.swf.png
new file mode 100644
index 0000000..338d94a
Binary files /dev/null and b/test/image/gradient-beginGradientFill-8.swf.png differ
diff --git a/test/image/gradient-beginGradientFill.as b/test/image/gradient-beginGradientFill.as
new file mode 100644
index 0000000..a30717e
--- /dev/null
+++ b/test/image/gradient-beginGradientFill.as
@@ -0,0 +1,60 @@
+// makeswf -v 7 -s 200x150 -r 1 -o gradient-beginGradientFill.swf gradient-beginGradientFill.as
+
+x = 0;
+y = 0;
+
+function do_gradient (type, colors, alphas, ratios) {
+ var matrix = { a:0, b:-80, d:80, e:0, g: x * 100 + 50, h: y * 100 + 50 };
+ beginGradientFill (type, colors, alphas, ratios, matrix);
+ moveTo (x * 100 + 10, y * 100 + 10);
+ lineTo (x * 100 + 10, y * 100 + 90);
+ lineTo (x * 100 + 90, y * 100 + 90);
+ lineTo (x * 100 + 90, y * 100 + 10);
+ lineTo (x * 100 + 10, y * 100 + 10);
+ endFill ();
+ x++;
+ if (x > 3) {
+ x = 0;
+ y++;
+ }
+};
+
+// 1
+foo = function (o, s) {
+ if (!o.x)
+ o.x = 7;
+ else
+ o.x--;
+ trace (s + " valueof: " + o.x);
+ return o.x;
+};
+c = { };
+c.length = { valueOf: function () { return foo (this, "color"); } };
+c[0] = c[2] = c[4] = c[6] = c[8] = 0xFF;
+c[1] = c[3] = c[5] = c[7] = c[9] = 0xFF00;
+a = { };
+a.length = { valueOf: function () { return foo (this, "alpha"); } };
+a[0] = a[2] = a[4] = a[6] = a[8] = 100;
+a[1] = a[3] = a[5] = a[7] = a[9] = 50;
+r = { };
+r.length = { valueOf: function () { return foo (this, "ratios"); } };
+for (i = 0; i < 10; i++)
+ r[i] = i / 9 * 255;
+do_gradient ("linear", c, a, r);
+
+// 2 - 4
+o = { };
+o.length = { valueOf: function () { trace ("length valueOf"); return 3; } };
+do_gradient ("linear", [0x40, 0xFF0000, 0xFF00], o, [0, 127, 255]);
+do_gradient ("linear", [0xFF, 0xFF0000, 0xFF00], [100, 100, 100], o);
+do_gradient ("linear", o, [100, 50, 100], [0, 127, 255]);
+
+// 5 - 12
+do_gradient ("Radial", [0xFF, 0xFF0000, 0xFF00], [255, 255, 255], [0, 127, 255]);
+do_gradient ("linear", ["255", {valueOf: function () { return 0xFF0000; }}, 0xFF00], [255, 255, 255], [0, 127, 255]);
+do_gradient ("linear", [ 0xFF, 0xFF00 ], [ undefined, 127 ], [ 0, 255 ]);
+do_gradient ("linear", [ ], [ ], [ ]);
+do_gradient ("linear", [ 0xFF ], [ 100 ], [ -1 ]);
+do_gradient ("linear", [ undefined ], [ 100 ], [ 255.8 ]);
+do_gradient ("linear", [ 0xFF ], [ 100 ], [ 256 ]);
+do_gradient ("radial", [0xFF, 0xFF0000, 0xFF00], [50, 100, 255], [undefined, 127, 255]);
commit dee7205ccdfdc5bbc514dc3b1de7313565c62222
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Dec 3 13:13:20 2007 +0100
implement beginGradientFill
It's not perfect, but good enough.
Most notably is missing support for matrices constructed with new flash.geom.Matrix()
and the Flash 8 parameters.
diff --git a/libswfdec/swfdec_as_strings.c b/libswfdec/swfdec_as_strings.c
index 7f0aeba..89896ce 100644
--- a/libswfdec/swfdec_as_strings.c
+++ b/libswfdec/swfdec_as_strings.c
@@ -466,5 +466,22 @@ const char swfdec_as_strings[] =
SWFDEC_AS_CONSTANT_STRING ("hardlight")
SWFDEC_AS_CONSTANT_STRING ("getTextExtent")
SWFDEC_AS_CONSTANT_STRING ("domain")
+ SWFDEC_AS_CONSTANT_STRING ("linear")
+ SWFDEC_AS_CONSTANT_STRING ("radial")
+ SWFDEC_AS_CONSTANT_STRING ("matrixType")
+ SWFDEC_AS_CONSTANT_STRING ("box")
+ SWFDEC_AS_CONSTANT_STRING ("a")
+ SWFDEC_AS_CONSTANT_STRING ("b")
+ SWFDEC_AS_CONSTANT_STRING ("c")
+ SWFDEC_AS_CONSTANT_STRING ("d")
+ SWFDEC_AS_CONSTANT_STRING ("e")
+ SWFDEC_AS_CONSTANT_STRING ("f")
+ SWFDEC_AS_CONSTANT_STRING ("g")
+ SWFDEC_AS_CONSTANT_STRING ("h")
+ SWFDEC_AS_CONSTANT_STRING ("i")
+ SWFDEC_AS_CONSTANT_STRING ("r")
+ SWFDEC_AS_CONSTANT_STRING ("w")
+ SWFDEC_AS_CONSTANT_STRING ("x")
+ SWFDEC_AS_CONSTANT_STRING ("y")
/* add more here */
;
diff --git a/libswfdec/swfdec_movie_as_drawing.c b/libswfdec/swfdec_movie_as_drawing.c
index b528fbd..f11810f 100644
--- a/libswfdec/swfdec_movie_as_drawing.c
+++ b/libswfdec/swfdec_movie_as_drawing.c
@@ -22,9 +22,11 @@
#endif
#include "swfdec_movie.h"
+#include "swfdec_as_internal.h"
+#include "swfdec_as_strings.h"
#include "swfdec_color.h"
#include "swfdec_debug.h"
-#include "swfdec_as_internal.h"
+#include "swfdec_gradient_pattern.h"
#include "swfdec_path.h"
#include "swfdec_pattern.h"
#include "swfdec_stroke.h"
@@ -69,6 +71,9 @@ swfdec_sprite_movie_end_fill (SwfdecMovie *movie, SwfdecDraw *new)
}
}
+#define SWFDEC_COLOR_FROM_COLOR_ALPHA(color, alpha) \
+ (((color) & 0xFFFFFF) | SWFDEC_COLOR_COMBINE (0, 0, 0, CLAMP ((alpha), 0, 100) * 255 / 100))
+
SWFDEC_AS_NATIVE (901, 1, swfdec_sprite_movie_beginFill)
void
swfdec_sprite_movie_beginFill (SwfdecAsContext *cx, SwfdecAsObject *object,
@@ -84,24 +89,175 @@ swfdec_sprite_movie_beginFill (SwfdecAsContext *cx, SwfdecAsObject *object,
if (argc == 0)
return;
color = color & 0xFFFFFF;
- if (argc > 1) {
- alpha = CLAMP (alpha, 0, 100);
- alpha = SWFDEC_COLOR_COMBINE (0, 0, 0, alpha * 255 / 100);
- } else {
- alpha = SWFDEC_COLOR_COMBINE (0, 0, 0, 255);
+ if (argc <= 1) {
+ alpha = 255;
}
- color = color | alpha;
+ color = SWFDEC_COLOR_FROM_COLOR_ALPHA (color, alpha);
draw = SWFDEC_DRAW (swfdec_pattern_new_color (color));
swfdec_path_move_to (&draw->path, movie->draw_x, movie->draw_y);
swfdec_sprite_movie_end_fill (movie, draw);
}
+static inline guint
+swfdec_sprite_movie_gradient_fill_get_length (SwfdecAsObject *o)
+{
+ int length;
+ SwfdecAsValue val;
+
+ swfdec_as_object_get_variable (o, SWFDEC_AS_STR_length, &val);
+ length = swfdec_as_value_to_integer (o->context, &val);
+ return MAX (length, 0);
+}
+
+static int
+swfdec_sprite_movie_gradient_fill_check_length (SwfdecAsObject *colors, SwfdecAsObject *alphas, SwfdecAsObject *ratios)
+{
+ guint c, a, r;
+
+ c = swfdec_sprite_movie_gradient_fill_get_length (colors);
+ a = swfdec_sprite_movie_gradient_fill_get_length (alphas);
+ r = swfdec_sprite_movie_gradient_fill_get_length (ratios);
+ if (c != a || a != r)
+ return -1;
+ return c;
+}
+
+static void
+swfdec_sprite_movie_extract_matrix (SwfdecAsObject *o, cairo_matrix_t *mat)
+{
+ SwfdecAsContext *cx = o->context;
+ SwfdecAsValue val;
+
+ /* FIXME: This function does not call valueOf in the right order */
+ if (swfdec_as_object_get_variable (o, SWFDEC_AS_STR_matrixType, &val)) {
+ const char *s = swfdec_as_value_to_string (cx, &val);
+ cairo_matrix_init_translate (mat, SWFDEC_TWIPS_SCALE_FACTOR / 2.0, SWFDEC_TWIPS_SCALE_FACTOR / 2.0);
+ cairo_matrix_scale (mat, SWFDEC_TWIPS_SCALE_FACTOR / 32768.0, SWFDEC_TWIPS_SCALE_FACTOR / 32768.0);
+ if (s == SWFDEC_AS_STR_box) {
+ double x, y, w, h, r;
+ cairo_matrix_t input;
+ swfdec_as_object_get_variable (o, SWFDEC_AS_STR_x, &val);
+ x = swfdec_as_value_to_number (cx, &val);
+ swfdec_as_object_get_variable (o, SWFDEC_AS_STR_y, &val);
+ y = swfdec_as_value_to_number (cx, &val);
+ swfdec_as_object_get_variable (o, SWFDEC_AS_STR_w, &val);
+ w = swfdec_as_value_to_number (cx, &val);
+ swfdec_as_object_get_variable (o, SWFDEC_AS_STR_h, &val);
+ h = swfdec_as_value_to_number (cx, &val);
+ swfdec_as_object_get_variable (o, SWFDEC_AS_STR_r, &val);
+ r = swfdec_as_value_to_number (cx, &val);
+ cairo_matrix_init_translate (&input, (x + w) / 2, (y + h) / 2);
+ cairo_matrix_scale (&input, w, h);
+ cairo_matrix_rotate (&input, r);
+ cairo_matrix_multiply (mat, mat, &input);
+ } else {
+ SWFDEC_WARNING ("my friend, there's no other matrixType than \"box\"");
+ }
+ } else {
+ cairo_matrix_t input;
+ swfdec_as_object_get_variable (o, SWFDEC_AS_STR_a, &val);
+ input.xx = swfdec_as_value_to_number (cx, &val);
+ swfdec_as_object_get_variable (o, SWFDEC_AS_STR_b, &val);
+ input.yx = swfdec_as_value_to_number (cx, &val);
+ swfdec_as_object_get_variable (o, SWFDEC_AS_STR_d, &val);
+ input.xy = swfdec_as_value_to_number (cx, &val);
+ swfdec_as_object_get_variable (o, SWFDEC_AS_STR_e, &val);
+ input.yy = swfdec_as_value_to_number (cx, &val);
+ swfdec_as_object_get_variable (o, SWFDEC_AS_STR_g, &val);
+ input.x0 = swfdec_as_value_to_number (cx, &val) * SWFDEC_TWIPS_SCALE_FACTOR;
+ swfdec_as_object_get_variable (o, SWFDEC_AS_STR_h, &val);
+ input.y0 = swfdec_as_value_to_number (cx, &val) * SWFDEC_TWIPS_SCALE_FACTOR;
+ cairo_matrix_init_scale (mat, SWFDEC_TWIPS_SCALE_FACTOR / 32768.0, SWFDEC_TWIPS_SCALE_FACTOR / 32768.0);
+ cairo_matrix_multiply (mat, mat, &input);
+ }
+}
+
SWFDEC_AS_NATIVE (901, 2, swfdec_sprite_movie_beginGradientFill)
void
swfdec_sprite_movie_beginGradientFill (SwfdecAsContext *cx, SwfdecAsObject *object,
guint argc, SwfdecAsValue *argv, SwfdecAsValue *rval)
{
- SWFDEC_FIXME ("implement");
+ SwfdecGradientPattern *gradient;
+ SwfdecPattern *pattern;
+ SwfdecMovie *movie;
+ SwfdecDraw *draw;
+ SwfdecAsObject *colors, *alphas, *ratios, *matrix;
+ const char *s;
+ gboolean radial;
+ int i, len;
+
+ SWFDEC_AS_CHECK (SWFDEC_TYPE_MOVIE, &movie, "|sOOOO", &s, &colors, &alphas, &ratios, &matrix);
+ movie->draw_fill = NULL;
+
+ if (colors == NULL || alphas == NULL || ratios == NULL || matrix == NULL) {
+ SWFDEC_ERROR ("could not convert one of the parameters to an object");
+ return;
+ }
+ if (s == SWFDEC_AS_STR_linear) {
+ radial = FALSE;
+ } else if (s == SWFDEC_AS_STR_radial) {
+ radial = TRUE;
+ } else {
+ SWFDEC_WARNING ("invalid fill type %s", s);
+ return;
+ }
+ len = swfdec_sprite_movie_gradient_fill_check_length (colors, alphas, ratios);
+ if (len < 0) {
+ SWFDEC_ERROR ("different lengths for colors, alphas and ratios, aborting");
+ return;
+ }
+ draw = swfdec_gradient_pattern_new ();
+ pattern = SWFDEC_PATTERN (draw);
+ gradient = SWFDEC_GRADIENT_PATTERN (draw);
+ gradient->radial = radial;
+ len = MIN (len, 8);
+ gradient->n_gradients = len;
+ for (i = 0; i < len; i++) {
+ int c, a, r;
+ SwfdecAsValue v;
+ int check = swfdec_sprite_movie_gradient_fill_check_length (colors, alphas, ratios);
+ if (check > i) {
+ const char *name = swfdec_as_integer_to_string (cx, i);
+ if (swfdec_as_object_get_variable (colors, name, &v)
+ && SWFDEC_AS_VALUE_IS_NUMBER (&v))
+ c = swfdec_as_value_to_integer (cx, &v);
+ else
+ c = 0;
+ if (!swfdec_as_object_get_variable (alphas, name, &v)) {
+ a = c;
+ } else if (!SWFDEC_AS_VALUE_IS_NUMBER (&v)) {
+ a = 0;
+ } else {
+ a = swfdec_as_value_to_integer (cx, &v);
+ }
+ if (!swfdec_as_object_get_variable (ratios, name, &v))
+ r = CLAMP (a, 0, 255);
+ else if (!SWFDEC_AS_VALUE_IS_NUMBER (&v))
+ r = 0;
+ else
+ r = swfdec_as_value_to_integer (cx, &v);
+ } else {
+ c = a = r = 0;
+ }
+ if (r > 255 || r < 0) {
+ SWFDEC_WARNING ("ratio %d not in [0, 255], ignoring gradient", r);
+ g_object_unref (draw);
+ return;
+ } else if (r < 0) {
+ r = 0;
+ }
+ gradient->gradient[i].color = SWFDEC_COLOR_FROM_COLOR_ALPHA (c, a);
+ gradient->gradient[i].ratio = r;
+ }
+ swfdec_sprite_movie_extract_matrix (matrix, &pattern->start_transform);
+ pattern->transform = pattern->start_transform;
+ if (cairo_matrix_invert (&pattern->transform)) {
+ SWFDEC_ERROR ("gradient transform matrix not invertible, resetting");
+ cairo_matrix_init_identity (&pattern->transform);
+ }
+
+ swfdec_path_move_to (&draw->path, movie->draw_x, movie->draw_y);
+ swfdec_sprite_movie_end_fill (movie, draw);
}
SWFDEC_AS_NATIVE (901, 3, swfdec_sprite_movie_moveTo)
commit d005031cfccf975ca0d98ee0a6dae83964edbd36
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Dec 3 12:37:42 2007 +0100
add swfdec_as_integer_to_string()
diff --git a/libswfdec/swfdec_as_types.c b/libswfdec/swfdec_as_types.c
index 34cbbc5..d4bbfb9 100644
--- a/libswfdec/swfdec_as_types.c
+++ b/libswfdec/swfdec_as_types.c
@@ -216,6 +216,22 @@ swfdec_as_str_concat (SwfdecAsContext *cx, const char * s1, const char *s2)
/**
* swfdec_as_double_to_string:
* @context: a #SwfdecAsContext
+ * @i: an integer that fits into 32 bits
+ *
+ * Converts @d into a string using the same conversion algorithm as the
+ * official Flash player.
+ *
+ * Returns: a garbage-collected string
+ **/
+const char *
+swfdec_as_integer_to_string (SwfdecAsContext *context, int i)
+{
+ return swfdec_as_context_give_string (context, g_strdup_printf ("%d", i));
+}
+
+/**
+ * swfdec_as_double_to_string:
+ * @context: a #SwfdecAsContext
* @d: a double
*
* Converts @d into a string using the same conversion algorithm as the
diff --git a/libswfdec/swfdec_as_types.h b/libswfdec/swfdec_as_types.h
index 3501fac..e90174d 100644
--- a/libswfdec/swfdec_as_types.h
+++ b/libswfdec/swfdec_as_types.h
@@ -125,6 +125,8 @@ const char * swfdec_as_value_to_string (SwfdecAsContext * context,
char * swfdec_as_value_to_debug (const SwfdecAsValue * value);
/* special conversion functions */
+const char * swfdec_as_integer_to_string (SwfdecAsContext * context,
+ int i);
const char * swfdec_as_double_to_string (SwfdecAsContext * context,
double d);
const char * swfdec_as_str_concat (SwfdecAsContext * cx,
commit 472aa34b00d9a7643de4c42eefae7cffecba094e
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Dec 3 12:37:17 2007 +0100
add another test for gradients
And this one too, doesn't work 100% perfect
diff --git a/test/image/Makefile.am b/test/image/Makefile.am
index bc9c292..5b870fb 100644
--- a/test/image/Makefile.am
+++ b/test/image/Makefile.am
@@ -73,6 +73,10 @@ EXTRA_DIST = \
fillstyle-order.swf \
fillstyle-order.swf.png \
fillstyle-order.xml \
+ gradient-end-duplication.swf \
+ gradient-end-duplication.swf.png \
+ gradient-end-duplication.swf.org.png \
+ gradient-end-duplication.xml \
gradient-ratios.swf \
gradient-ratios.swf.png \
gradient-ratios.swf.org.png \
diff --git a/test/image/gradient-end-duplication.swf b/test/image/gradient-end-duplication.swf
new file mode 100644
index 0000000..bb0cb1d
Binary files /dev/null and b/test/image/gradient-end-duplication.swf differ
diff --git a/test/image/gradient-end-duplication.swf.org.png b/test/image/gradient-end-duplication.swf.org.png
new file mode 100644
index 0000000..afcf1f8
Binary files /dev/null and b/test/image/gradient-end-duplication.swf.org.png differ
diff --git a/test/image/gradient-end-duplication.swf.png b/test/image/gradient-end-duplication.swf.png
new file mode 100644
index 0000000..fcf6a3b
Binary files /dev/null and b/test/image/gradient-end-duplication.swf.png differ
diff --git a/test/image/gradient-end-duplication.xml b/test/image/gradient-end-duplication.xml
new file mode 100644
index 0000000..7eeb9ee
--- /dev/null
+++ b/test/image/gradient-end-duplication.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0"?>
+<swf version="7" compressed="1">
+ <Header framerate="30" frames="1">
+ <size>
+ <Rectangle left="0" right="6120" top="0" bottom="3000"/>
+ </size>
+ <tags>
+ <DefineShape2 objectID="1">
+ <bounds>
+ <Rectangle left="500" right="5620" top="500" bottom="2500"/>
+ </bounds>
+ <styles>
+ <StyleList>
+ <fillStyles>
+ <LinearGradient spreadMode="1" interpolationMode="0">
+ <matrix>
+ <Transform scaleX="0.05625" scaleY="1" skewX="0" skewY="0" transX="3060" transY="1500"/>
+ </matrix>
+ <gradientColors>
+ <GradientItem position="254">
+ <color>
+ <Color red="255" green="0" blue="0" alpha="255"/>
+ </color>
+ </GradientItem>
+ <GradientItem position="0">
+ <color>
+ <Color red="0" green="0" blue="255" alpha="255"/>
+ </color>
+ </GradientItem>
+ <GradientItem position="0">
+ <color>
+ <Color red="0" green="255" blue="0" alpha="255"/>
+ </color>
+ </GradientItem>
+ </gradientColors>
+ </LinearGradient>
+ </fillStyles>
+ <lineStyles />
+ </StyleList>
+ </styles>
+ <shapes>
+ <Shape>
+ <edges>
+ <ShapeSetup x="500" y="500" fillStyle0="1"/>
+ <LineTo x="0" y="2000"/>
+ <LineTo x="5120" y="0"/>
+ <LineTo x="0" y="-2000"/>
+ <LineTo x="-5120" y="0"/>
+ <ShapeSetup/>
+ </edges>
+ </Shape>
+ </shapes>
+ </DefineShape2>
+ <PlaceObject2 replace="0" depth="0" objectID="1" />
+ <ShowFrame/>
+ <End/>
+ </tags>
+ </Header>
+</swf>
commit 1c94cb756031ebcd939f82120469b56911866a38
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Dec 3 12:35:49 2007 +0100
update reference image to work with Swfdec for now
diff --git a/test/image/Makefile.am b/test/image/Makefile.am
index e7b60f0..bc9c292 100644
--- a/test/image/Makefile.am
+++ b/test/image/Makefile.am
@@ -75,6 +75,7 @@ EXTRA_DIST = \
fillstyle-order.xml \
gradient-ratios.swf \
gradient-ratios.swf.png \
+ gradient-ratios.swf.org.png \
gradient-ratios.xml \
image-jpeg-alpha.swf \
image-jpeg-alpha.swf.png \
diff --git a/test/image/gradient-ratios.swf.org.png b/test/image/gradient-ratios.swf.org.png
new file mode 100644
index 0000000..76c1bcc
Binary files /dev/null and b/test/image/gradient-ratios.swf.org.png differ
diff --git a/test/image/gradient-ratios.swf.png b/test/image/gradient-ratios.swf.png
index 76c1bcc..cb3c43f 100644
Binary files a/test/image/gradient-ratios.swf.png and b/test/image/gradient-ratios.swf.png differ
commit a04781850be00b7fa87d974d888c60c8dd763526
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Dec 3 12:27:50 2007 +0100
ratios must be increasing - if they're not, we force them to be
diff --git a/libswfdec/swfdec_gradient_pattern.c b/libswfdec/swfdec_gradient_pattern.c
index ca5f8c4..2f63634 100644
--- a/libswfdec/swfdec_gradient_pattern.c
+++ b/libswfdec/swfdec_gradient_pattern.c
@@ -56,7 +56,7 @@ swfdec_gradient_pattern_morph (SwfdecDraw *dest, SwfdecDraw *source, guint ratio
static cairo_pattern_t *
swfdec_gradient_pattern_get_pattern (SwfdecPattern *pat, const SwfdecColorTransform *trans)
{
- guint i;
+ guint i, ratio;
cairo_pattern_t *pattern;
SwfdecColor color;
double offset;
@@ -89,13 +89,20 @@ swfdec_gradient_pattern_get_pattern (SwfdecPattern *pat, const SwfdecColorTransf
}
#endif
cairo_pattern_set_extend (pattern, gradient->extend);
+ /* we check here that ratios increase linearly, because both gradients parsed
+ * from the SWF and gradients created with beginGradientFill have this
+ * behavior */
+ ratio = 0;
for (i = 0; i < gradient->n_gradients; i++){
color = swfdec_color_apply_transform (gradient->gradient[i].color,
trans);
- offset = gradient->gradient[i].ratio / 255.0;
+ ratio = MAX (ratio, gradient->gradient[i].ratio);
+ offset = ratio / 255.0;
cairo_pattern_add_color_stop_rgba (pattern, offset,
SWFDEC_COLOR_R(color) / 255.0, SWFDEC_COLOR_G(color) / 255.0,
SWFDEC_COLOR_B(color) / 255.0, SWFDEC_COLOR_A(color) / 255.0);
+ if (++ratio > 255)
+ break;
}
return pattern;
}
commit fbcffb9baba0ab49f24886787f8ace22131fa0e5
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Dec 3 11:46:56 2007 +0100
add a test that ensures non-increasing gradient ratios work
diff --git a/test/image/Makefile.am b/test/image/Makefile.am
index bf08ce2..e7b60f0 100644
--- a/test/image/Makefile.am
+++ b/test/image/Makefile.am
@@ -73,6 +73,9 @@ EXTRA_DIST = \
fillstyle-order.swf \
fillstyle-order.swf.png \
fillstyle-order.xml \
+ gradient-ratios.swf \
+ gradient-ratios.swf.png \
+ gradient-ratios.xml \
image-jpeg-alpha.swf \
image-jpeg-alpha.swf.png \
image-lossless-alpha.swf \
diff --git a/test/image/gradient-ratios.swf b/test/image/gradient-ratios.swf
new file mode 100644
index 0000000..8248060
Binary files /dev/null and b/test/image/gradient-ratios.swf differ
diff --git a/test/image/gradient-ratios.swf.png b/test/image/gradient-ratios.swf.png
new file mode 100644
index 0000000..76c1bcc
Binary files /dev/null and b/test/image/gradient-ratios.swf.png differ
diff --git a/test/image/gradient-ratios.xml b/test/image/gradient-ratios.xml
new file mode 100644
index 0000000..5e2c6ec
--- /dev/null
+++ b/test/image/gradient-ratios.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0"?>
+<swf version="7" compressed="1">
+ <Header framerate="30" frames="1">
+ <size>
+ <Rectangle left="0" right="4000" top="0" bottom="3000"/>
+ </size>
+ <tags>
+ <DefineShape2 objectID="1">
+ <bounds>
+ <Rectangle left="500" right="3500" top="500" bottom="2500"/>
+ </bounds>
+ <styles>
+ <StyleList>
+ <fillStyles>
+ <LinearGradient spreadMode="1" interpolationMode="0">
+ <matrix>
+ <Transform scaleX="0.091552734" scaleY="1" skewX="0" skewY="0" transX="2000" transY="1500"/>
+ </matrix>
+ <gradientColors>
+ <GradientItem position="127">
+ <color>
+ <Color red="255" green="0" blue="0" alpha="255"/>
+ </color>
+ </GradientItem>
+ <GradientItem position="0">
+ <color>
+ <Color red="0" green="255" blue="0" alpha="255"/>
+ </color>
+ </GradientItem>
+ </gradientColors>
+ </LinearGradient>
+ </fillStyles>
+ <lineStyles />
+ </StyleList>
+ </styles>
+ <shapes>
+ <Shape>
+ <edges>
+ <ShapeSetup x="500" y="500" fillStyle0="1"/>
+ <LineTo x="0" y="2000"/>
+ <LineTo x="3000" y="0"/>
+ <LineTo x="0" y="-2000"/>
+ <LineTo x="-3000" y="0"/>
+ <ShapeSetup/>
+ </edges>
+ </Shape>
+ </shapes>
+ </DefineShape2>
+ <PlaceObject2 replace="0" depth="0" objectID="1" />
+ <ShowFrame/>
+ <End/>
+ </tags>
+ </Header>
+</swf>
commit b4966ebfcb734200030b8db95a07274c9fb60354
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Dec 3 11:36:21 2007 +0100
empty gradients are solid black
diff --git a/libswfdec/swfdec_gradient_pattern.c b/libswfdec/swfdec_gradient_pattern.c
index ed206cc..ca5f8c4 100644
--- a/libswfdec/swfdec_gradient_pattern.c
+++ b/libswfdec/swfdec_gradient_pattern.c
@@ -62,6 +62,10 @@ swfdec_gradient_pattern_get_pattern (SwfdecPattern *pat, const SwfdecColorTransf
double offset;
SwfdecGradientPattern *gradient = SWFDEC_GRADIENT_PATTERN (pat);
+ if (gradient->n_gradients == 0) {
+ /* cairo interprets an empty gradient as translucent, not as solid black */
+ return cairo_pattern_create_rgb (0, 0, 0);
+ }
#if 0
/* use this when https://bugs.freedesktop.org/show_bug.cgi?id=8341 is fixed */
if (gradient->radial)
commit da2103799165cc57165a2ef9fa486eff330f3d79
Author: Benjamin Otte <otte at gnome.org>
Date: Mon Dec 3 11:35:50 2007 +0100
gradients (like images) pad by default
diff --git a/libswfdec/swfdec_gradient_pattern.c b/libswfdec/swfdec_gradient_pattern.c
index b87fc1a..ed206cc 100644
--- a/libswfdec/swfdec_gradient_pattern.c
+++ b/libswfdec/swfdec_gradient_pattern.c
@@ -105,8 +105,9 @@ swfdec_gradient_pattern_class_init (SwfdecGradientPatternClass *klass)
}
static void
-swfdec_gradient_pattern_init (SwfdecGradientPattern *pattern)
+swfdec_gradient_pattern_init (SwfdecGradientPattern *gradient)
{
+ gradient->extend = CAIRO_EXTEND_PAD;
}
SwfdecDraw *
commit 9660a4b24a464585adc7f228bb5e058d0463e6a5
Author: Benjamin Otte <otte at gnome.org>
Date: Sun Dec 2 15:29:49 2007 +0100
add test for empty gradients
diff --git a/test/image/Makefile.am b/test/image/Makefile.am
index 9993ebc..bf08ce2 100644
--- a/test/image/Makefile.am
+++ b/test/image/Makefile.am
@@ -67,6 +67,9 @@ EXTRA_DIST = \
drawing-zorder-8.swf \
drawing-zorder-8.swf.org.png \
drawing-zorder-8.swf.png \
+ empty-gradient.swf \
+ empty-gradient.swf.png \
+ empty-gradient.xml \
fillstyle-order.swf \
fillstyle-order.swf.png \
fillstyle-order.xml \
diff --git a/test/image/empty-gradient.swf b/test/image/empty-gradient.swf
new file mode 100644
index 0000000..8aa5404
Binary files /dev/null and b/test/image/empty-gradient.swf differ
diff --git a/test/image/empty-gradient.swf.png b/test/image/empty-gradient.swf.png
new file mode 100644
index 0000000..08d2512
Binary files /dev/null and b/test/image/empty-gradient.swf.png differ
diff --git a/test/image/empty-gradient.xml b/test/image/empty-gradient.xml
new file mode 100644
index 0000000..7bf74ce
--- /dev/null
+++ b/test/image/empty-gradient.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0"?>
+<swf version="7" compressed="1">
+ <Header framerate="30" frames="1">
+ <size>
+ <Rectangle left="0" right="4000" top="0" bottom="3000"/>
+ </size>
+ <tags>
+ <DefineShape2 objectID="1">
+ <bounds>
+ <Rectangle left="500" right="3500" top="500" bottom="2500"/>
+ </bounds>
+ <styles>
+ <StyleList>
+ <fillStyles>
+ <LinearGradient spreadMode="1" interpolationMode="0">
+ <gradientColors/>
+ </LinearGradient>
+ </fillStyles>
+ <lineStyles />
+ </StyleList>
+ </styles>
+ <shapes>
+ <Shape>
+ <edges>
+ <ShapeSetup x="500" y="500" fillStyle0="1"/>
+ <LineTo x="0" y="2000"/>
+ <LineTo x="3000" y="0"/>
+ <LineTo x="0" y="-2000"/>
+ <LineTo x="-3000" y="0"/>
+ <ShapeSetup/>
+ </edges>
+ </Shape>
+ </shapes>
+ </DefineShape2>
+ <PlaceObject2 replace="0" depth="0" objectID="1" />
+ <ShowFrame/>
+ <End/>
+ </tags>
+ </Header>
+</swf>
commit ecd4f9072a0d8e778b44b26f70491eb5cddf6a0e
Author: Benjamin Otte <otte at gnome.org>
Date: Sun Dec 2 15:25:57 2007 +0100
add swfdec_gradient_pattern_new()
diff --git a/libswfdec/swfdec_gradient_pattern.c b/libswfdec/swfdec_gradient_pattern.c
index d8d9738..b87fc1a 100644
--- a/libswfdec/swfdec_gradient_pattern.c
+++ b/libswfdec/swfdec_gradient_pattern.c
@@ -108,3 +108,10 @@ static void
swfdec_gradient_pattern_init (SwfdecGradientPattern *pattern)
{
}
+
+SwfdecDraw *
+swfdec_gradient_pattern_new (void)
+{
+ return g_object_new (SWFDEC_TYPE_GRADIENT_PATTERN, NULL);
+}
+
diff --git a/libswfdec/swfdec_gradient_pattern.h b/libswfdec/swfdec_gradient_pattern.h
index b845104..6b85608 100644
--- a/libswfdec/swfdec_gradient_pattern.h
+++ b/libswfdec/swfdec_gradient_pattern.h
@@ -60,6 +60,8 @@ struct _SwfdecGradientPatternClass
GType swfdec_gradient_pattern_get_type (void);
+SwfdecDraw * swfdec_gradient_pattern_new (void);
+
G_END_DECLS
#endif
diff --git a/libswfdec/swfdec_pattern.c b/libswfdec/swfdec_pattern.c
index 49db137..d641556 100644
--- a/libswfdec/swfdec_pattern.c
+++ b/libswfdec/swfdec_pattern.c
@@ -262,7 +262,7 @@ swfdec_pattern_do_parse (SwfdecBits *bits, SwfdecSwfDecoder *dec, gboolean rgba)
} else if (paint_style_type == 0x10 || paint_style_type == 0x12 || paint_style_type == 0x13) {
SwfdecGradientPattern *gradient;
guint i, interpolation;
- pattern = g_object_new (SWFDEC_TYPE_GRADIENT_PATTERN, NULL);
+ pattern = SWFDEC_PATTERN (swfdec_gradient_pattern_new ());
gradient = SWFDEC_GRADIENT_PATTERN (pattern);
swfdec_bits_get_matrix (bits, &pattern->start_transform, NULL);
pattern->end_transform = pattern->start_transform;
@@ -409,7 +409,7 @@ swfdec_pattern_parse_morph (SwfdecBits *bits, SwfdecSwfDecoder *dec)
} else if (paint_style_type == 0x10 || paint_style_type == 0x12 || paint_style_type == 0x13) {
SwfdecGradientPattern *gradient;
guint i, interpolation;
- pattern = g_object_new (SWFDEC_TYPE_GRADIENT_PATTERN, NULL);
+ pattern = SWFDEC_PATTERN (swfdec_gradient_pattern_new ());
gradient = SWFDEC_GRADIENT_PATTERN (pattern);
swfdec_bits_get_matrix (bits, &pattern->start_transform, NULL);
swfdec_bits_get_matrix (bits, &pattern->end_transform, NULL);
commit f98b8cd67045b92bd7ee79aa12d99a7b8c8669cf
Author: Benjamin Otte <otte at gnome.org>
Date: Sun Dec 2 15:17:58 2007 +0100
split out graident pattern code into its own file
This is to ease implementation of beginGradientFill
diff --git a/libswfdec/Makefile.am b/libswfdec/Makefile.am
index 6c42eb0..aad0e05 100644
--- a/libswfdec/Makefile.am
+++ b/libswfdec/Makefile.am
@@ -89,6 +89,7 @@ libswfdec_ at SWFDEC_MAJORMINOR@_la_SOURCES = \
swfdec_font.c \
swfdec_glow_filter.c \
swfdec_gradient_filter.c \
+ swfdec_gradient_pattern.c \
swfdec_graphic.c \
swfdec_graphic_movie.c \
swfdec_image.c \
@@ -231,6 +232,7 @@ noinst_HEADERS = \
swfdec_flash_security.h \
swfdec_flv_decoder.h \
swfdec_font.h \
+ swfdec_gradient_pattern.h \
swfdec_graphic.h \
swfdec_graphic_movie.h \
swfdec_image.h \
diff --git a/libswfdec/swfdec_gradient_pattern.c b/libswfdec/swfdec_gradient_pattern.c
new file mode 100644
index 0000000..d8d9738
--- /dev/null
+++ b/libswfdec/swfdec_gradient_pattern.c
@@ -0,0 +1,110 @@
+/* Swfdec
+ * Copyright (C) 2006-2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <math.h>
+
+#include "swfdec_gradient_pattern.h"
+#include "swfdec_color.h"
+#include "swfdec_debug.h"
+#include "swfdec_path.h"
+
+G_DEFINE_TYPE (SwfdecGradientPattern, swfdec_gradient_pattern, SWFDEC_TYPE_PATTERN);
+
+static void
+swfdec_gradient_pattern_morph (SwfdecDraw *dest, SwfdecDraw *source, guint ratio)
+{
+ guint i;
+
+ SwfdecGradientPattern *dpattern = SWFDEC_GRADIENT_PATTERN (dest);
+ SwfdecGradientPattern *spattern = SWFDEC_GRADIENT_PATTERN (source);
+
+ g_return_if_fail (spattern->end_gradient != NULL);
+ dpattern->radial = spattern->radial;
+ dpattern->focus = spattern->focus;
+ dpattern->extend = spattern->extend;
+ dpattern->n_gradients = spattern->n_gradients;
+ for (i = 0; i < spattern->n_gradients; i++) {
+ dpattern->gradient[i].color = swfdec_color_apply_morph (spattern->gradient[i].color,
+ spattern->end_gradient[i].color, ratio);
+ dpattern->gradient[i].ratio = (spattern->gradient[i].ratio * (65535 - ratio) +
+ spattern->end_gradient[i].ratio * ratio) / 65535;
+ }
+
+ SWFDEC_DRAW_CLASS (swfdec_gradient_pattern_parent_class)->morph (dest, source, ratio);
+}
+
+static cairo_pattern_t *
+swfdec_gradient_pattern_get_pattern (SwfdecPattern *pat, const SwfdecColorTransform *trans)
+{
+ guint i;
+ cairo_pattern_t *pattern;
+ SwfdecColor color;
+ double offset;
+ SwfdecGradientPattern *gradient = SWFDEC_GRADIENT_PATTERN (pat);
+
+#if 0
+ /* use this when https://bugs.freedesktop.org/show_bug.cgi?id=8341 is fixed */
+ if (gradient->radial)
+ pattern = cairo_pattern_create_radial (0, 0, 0, 0, 0, 16384);
+ else
+ pattern = cairo_pattern_create_linear (-16384.0, 0, 16384.0, 0);
+ cairo_pattern_set_matrix (pattern, &pat->transform);
+#else
+ {
+ cairo_matrix_t mat = pat->transform;
+ if (gradient->radial) {
+ pattern = cairo_pattern_create_radial ((16384.0 / 256.0) * gradient->focus,
+ 0, 0, 0, 0, 16384 / 256.0);
+ } else {
+ pattern = cairo_pattern_create_linear (-16384.0 / 256.0, 0, 16384.0 / 256.0, 0);
+ }
+ cairo_matrix_scale (&mat, 1 / 256.0, 1 / 256.0);
+ mat.x0 /= 256.0;
+ mat.y0 /= 256.0;
+ cairo_pattern_set_matrix (pattern, &mat);
+ }
+#endif
+ cairo_pattern_set_extend (pattern, gradient->extend);
+ for (i = 0; i < gradient->n_gradients; i++){
+ color = swfdec_color_apply_transform (gradient->gradient[i].color,
+ trans);
+ offset = gradient->gradient[i].ratio / 255.0;
+ cairo_pattern_add_color_stop_rgba (pattern, offset,
+ SWFDEC_COLOR_R(color) / 255.0, SWFDEC_COLOR_G(color) / 255.0,
+ SWFDEC_COLOR_B(color) / 255.0, SWFDEC_COLOR_A(color) / 255.0);
+ }
+ return pattern;
+}
+
+static void
+swfdec_gradient_pattern_class_init (SwfdecGradientPatternClass *klass)
+{
+ SWFDEC_DRAW_CLASS (klass)->morph = swfdec_gradient_pattern_morph;
+
+ SWFDEC_PATTERN_CLASS (klass)->get_pattern = swfdec_gradient_pattern_get_pattern;
+}
+
+static void
+swfdec_gradient_pattern_init (SwfdecGradientPattern *pattern)
+{
+}
diff --git a/libswfdec/swfdec_gradient_pattern.h b/libswfdec/swfdec_gradient_pattern.h
new file mode 100644
index 0000000..b845104
--- /dev/null
+++ b/libswfdec/swfdec_gradient_pattern.h
@@ -0,0 +1,65 @@
+/* Swfdec
+ * Copyright (C) 2006-2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifndef _SWFDEC_GRADIENT_PATTERN_H_
+#define _SWFDEC_GRADIENT_PATTERN_H_
+
+#include <libswfdec/swfdec_pattern.h>
+
+G_BEGIN_DECLS
+
+typedef struct _SwfdecGradientPattern SwfdecGradientPattern;
+typedef struct _SwfdecGradientPatternClass SwfdecGradientPatternClass;
+
+typedef struct _SwfdecGradientEntry SwfdecGradientEntry;
+
+#define SWFDEC_TYPE_GRADIENT_PATTERN (swfdec_gradient_pattern_get_type())
+#define SWFDEC_IS_GRADIENT_PATTERN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_GRADIENT_PATTERN))
+#define SWFDEC_IS_GRADIENT_PATTERN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_GRADIENT_PATTERN))
+#define SWFDEC_GRADIENT_PATTERN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_GRADIENT_PATTERN, SwfdecGradientPattern))
+#define SWFDEC_GRADIENT_PATTERN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_GRADIENT_PATTERN, SwfdecGradientPatternClass))
+#define SWFDEC_GRADIENT_PATTERN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_GRADIENT_PATTERN, SwfdecGradientPatternClass))
+
+struct _SwfdecGradientEntry {
+ guint ratio;
+ SwfdecColor color;
+};
+
+struct _SwfdecGradientPattern
+{
+ SwfdecPattern pattern;
+
+ SwfdecGradientEntry gradient[16]; /* gradient to paint */
+ SwfdecGradientEntry end_gradient[16]; /* end gradient for morphs */
+ guint n_gradients; /* number of gradients */
+ cairo_extend_t extend; /* extend of gradient */
+ gboolean radial; /* TRUE for radial gradient, FALSE for linear gradient */
+ double focus; /* focus point */
+};
+
+struct _SwfdecGradientPatternClass
+{
+ SwfdecPatternClass pattern_class;
+};
+
+GType swfdec_gradient_pattern_get_type (void);
+
+
+G_END_DECLS
+#endif
diff --git a/libswfdec/swfdec_pattern.c b/libswfdec/swfdec_pattern.c
index d5aaaaa..49db137 100644
--- a/libswfdec/swfdec_pattern.c
+++ b/libswfdec/swfdec_pattern.c
@@ -28,6 +28,7 @@
#include "swfdec_color.h"
#include "swfdec_debug.h"
#include "swfdec_decoder.h"
+#include "swfdec_gradient_pattern.h"
#include "swfdec_image.h"
#include "swfdec_path.h"
#include "swfdec_stroke.h"
@@ -238,124 +239,6 @@ swfdec_image_pattern_init (SwfdecImagePattern *pattern)
{
}
-/*** GRADIENT PATTERN ***/
-
-typedef struct _SwfdecGradientPattern SwfdecGradientPattern;
-typedef struct _SwfdecGradientPatternClass SwfdecGradientPatternClass;
-
-typedef struct _SwfdecGradientEntry SwfdecGradientEntry;
-
-#define SWFDEC_TYPE_GRADIENT_PATTERN (swfdec_gradient_pattern_get_type())
-#define SWFDEC_IS_GRADIENT_PATTERN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_GRADIENT_PATTERN))
-#define SWFDEC_IS_GRADIENT_PATTERN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_GRADIENT_PATTERN))
-#define SWFDEC_GRADIENT_PATTERN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_GRADIENT_PATTERN, SwfdecGradientPattern))
-#define SWFDEC_GRADIENT_PATTERN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_GRADIENT_PATTERN, SwfdecGradientPatternClass))
-#define SWFDEC_GRADIENT_PATTERN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_GRADIENT_PATTERN, SwfdecGradientPatternClass))
-
-struct _SwfdecGradientEntry {
- guint ratio;
- SwfdecColor color;
-};
-
-struct _SwfdecGradientPattern
-{
- SwfdecPattern pattern;
-
- SwfdecGradientEntry gradient[16]; /* gradient to paint */
- SwfdecGradientEntry end_gradient[16]; /* end gradient for morphs */
- guint n_gradients; /* number of gradients */
- cairo_extend_t extend; /* extend of gradient */
- gboolean radial; /* TRUE for radial gradient, FALSE for linear gradient */
- double focus; /* focus point */
-};
-
-struct _SwfdecGradientPatternClass
-{
- SwfdecPatternClass pattern_class;
-};
-
-GType swfdec_gradient_pattern_get_type (void);
-G_DEFINE_TYPE (SwfdecGradientPattern, swfdec_gradient_pattern, SWFDEC_TYPE_PATTERN);
-
-static void
-swfdec_gradient_pattern_morph (SwfdecDraw *dest, SwfdecDraw *source, guint ratio)
-{
- guint i;
-
- SwfdecGradientPattern *dpattern = SWFDEC_GRADIENT_PATTERN (dest);
- SwfdecGradientPattern *spattern = SWFDEC_GRADIENT_PATTERN (source);
-
- g_return_if_fail (spattern->end_gradient != NULL);
- dpattern->radial = spattern->radial;
- dpattern->focus = spattern->focus;
- dpattern->extend = spattern->extend;
- dpattern->n_gradients = spattern->n_gradients;
- for (i = 0; i < spattern->n_gradients; i++) {
- dpattern->gradient[i].color = swfdec_color_apply_morph (spattern->gradient[i].color,
- spattern->end_gradient[i].color, ratio);
- dpattern->gradient[i].ratio = (spattern->gradient[i].ratio * (65535 - ratio) +
- spattern->end_gradient[i].ratio * ratio) / 65535;
- }
-
- SWFDEC_DRAW_CLASS (swfdec_gradient_pattern_parent_class)->morph (dest, source, ratio);
-}
-
-static cairo_pattern_t *
-swfdec_gradient_pattern_get_pattern (SwfdecPattern *pat, const SwfdecColorTransform *trans)
-{
- guint i;
- cairo_pattern_t *pattern;
- SwfdecColor color;
- double offset;
- SwfdecGradientPattern *gradient = SWFDEC_GRADIENT_PATTERN (pat);
-
-#if 0
- /* use this when https://bugs.freedesktop.org/show_bug.cgi?id=8341 is fixed */
- if (gradient->radial)
- pattern = cairo_pattern_create_radial (0, 0, 0, 0, 0, 16384);
- else
- pattern = cairo_pattern_create_linear (-16384.0, 0, 16384.0, 0);
- cairo_pattern_set_matrix (pattern, &pat->transform);
-#else
- {
- cairo_matrix_t mat = pat->transform;
- if (gradient->radial) {
- pattern = cairo_pattern_create_radial ((16384.0 / 256.0) * gradient->focus,
- 0, 0, 0, 0, 16384 / 256.0);
- } else {
- pattern = cairo_pattern_create_linear (-16384.0 / 256.0, 0, 16384.0 / 256.0, 0);
- }
- cairo_matrix_scale (&mat, 1 / 256.0, 1 / 256.0);
- mat.x0 /= 256.0;
- mat.y0 /= 256.0;
- cairo_pattern_set_matrix (pattern, &mat);
- }
-#endif
- cairo_pattern_set_extend (pattern, gradient->extend);
- for (i = 0; i < gradient->n_gradients; i++){
- color = swfdec_color_apply_transform (gradient->gradient[i].color,
- trans);
- offset = gradient->gradient[i].ratio / 255.0;
- cairo_pattern_add_color_stop_rgba (pattern, offset,
- SWFDEC_COLOR_R(color) / 255.0, SWFDEC_COLOR_G(color) / 255.0,
- SWFDEC_COLOR_B(color) / 255.0, SWFDEC_COLOR_A(color) / 255.0);
- }
- return pattern;
-}
-
-static void
-swfdec_gradient_pattern_class_init (SwfdecGradientPatternClass *klass)
-{
- SWFDEC_DRAW_CLASS (klass)->morph = swfdec_gradient_pattern_morph;
-
- SWFDEC_PATTERN_CLASS (klass)->get_pattern = swfdec_gradient_pattern_get_pattern;
-}
-
-static void
-swfdec_gradient_pattern_init (SwfdecGradientPattern *pattern)
-{
-}
-
/*** EXPORTED API ***/
static SwfdecDraw *
More information about the Swfdec
mailing list