Benjamin Otte
2007-Dec-03 12:29 UTC
[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
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 *
Seemingly Similar Threads
- 7 commits - libswfdec/swfdec_codec_gst.c libswfdec/swfdec_font.c libswfdec/swfdec_js_movie.c libswfdec/swfdec_morph_movie.c libswfdec/swfdec_pattern.c libswfdec/swfdec_pattern.h libswfdec/swfdec_shape.c libswfdec/swfdec_shape.h libswfdec/swfdec_sprite.c
- 2 commits - doc/Makefile.am doc/swfdec-sections.txt NEWS
- Changes to 'refs/tags/0.5.5'
- 5 commits - libswfdec/Makefile.am libswfdec/swfdec_color.c libswfdec/swfdec_color.h libswfdec/swfdec_font.c libswfdec/swfdec_loadertarget.c libswfdec/swfdec_movie.h libswfdec/swfdec_pattern.c libswfdec/swfdec_pattern.h libswfdec/swfdec_player.c
- 4 commits - libswfdec/swfdec_shape_parser.c NEWS README test/trace