Benjamin Otte
2007-Apr-16 00:59 UTC
[Swfdec] 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 libswfdec/swfdec_stroke.c libswfdec/swfdec_stroke.h libswfdec/swfdec_tag.c test/dump.c
libswfdec/swfdec_codec_gst.c | 2 libswfdec/swfdec_font.c | 4 libswfdec/swfdec_js_movie.c | 39 ++++++++- libswfdec/swfdec_morph_movie.c | 18 ++-- libswfdec/swfdec_pattern.c | 130 +++++++++++++++++++------------ libswfdec/swfdec_pattern.h | 16 ++- libswfdec/swfdec_shape.c | 99 +++++++++++++----------- libswfdec/swfdec_shape.h | 11 +- libswfdec/swfdec_sprite.c | 8 + libswfdec/swfdec_stroke.c | 167 +++++++++++++++++++++++++++++++++-------- libswfdec/swfdec_stroke.h | 39 ++++++--- libswfdec/swfdec_tag.c | 2 test/dump.c | 23 +++-- 13 files changed, 380 insertions(+), 178 deletions(-) New commits: diff-tree c396c1d9b1488becf71c3ab32ea5b7cd510b8a47 (from ef3becaadc12e3167a7c02a4a8185bf02d9737e2) Author: Benjamin Otte <otte@gnome.org> Date: Mon Apr 16 09:52:20 2007 +0200 make hitTest not crash if the movie's parents don't match Attempt to do the right thing instead. (Untested) diff --git a/libswfdec/swfdec_js_movie.c b/libswfdec/swfdec_js_movie.c index 3f6333c..53fb5d9 100644 --- a/libswfdec/swfdec_js_movie.c +++ b/libswfdec/swfdec_js_movie.c @@ -308,7 +308,9 @@ mc_hitTest (JSContext *cx, JSObject *obj } if (argc == 1) { - SwfdecMovie *other; + SwfdecMovie *other, *tmp; + SwfdecRect movie_rect, other_rect; + guint movie_depth, other_depth; other = swfdec_scriptable_from_jsval (cx, argv[0], SWFDEC_TYPE_MOVIE); if (other == NULL) { SWFDEC_ERROR ("FIXME: what happens now?"); @@ -316,9 +318,36 @@ mc_hitTest (JSContext *cx, JSObject *obj } other = SWFDEC_MOVIE (JS_GetPrivate(cx, JSVAL_TO_OBJECT (argv[0]))); swfdec_movie_update (movie); - swfdec_movie_update (other); - /* FIXME */ - g_assert (movie->parent == other->parent); + if (movie->parent != other->parent) { + movie_rect = movie->original_extents; + other_rect = other->original_extents; + swfdec_movie_update (other); + tmp = movie; + for (movie_depth = 0; tmp->parent; movie_depth++) + tmp = tmp->parent; + tmp = other; + for (other_depth = 0; tmp->parent; other_depth++) + tmp = tmp->parent; + while (movie_depth > other_depth) { + swfdec_rect_transform (&movie_rect, &movie_rect, &movie->matrix); + movie = movie->parent; + movie_depth--; + } + while (other_depth > movie_depth) { + swfdec_rect_transform (&other_rect, &other_rect, &other->matrix); + other = other->parent; + other_depth--; + } + while (other != movie && other->parent) { + swfdec_rect_transform (&movie_rect, &movie_rect, &movie->matrix); + movie = movie->parent; + swfdec_rect_transform (&other_rect, &other_rect, &other->matrix); + other = other->parent; + } + } else { + movie_rect = movie->extents; + other_rect = other->extents; + } #if 0 g_print ("%g %g %g %g --- %g %g %g %g\n", SWFDEC_OBJECT (movie)->extents.x0, SWFDEC_OBJECT (movie)->extents.y0, @@ -326,7 +355,7 @@ mc_hitTest (JSContext *cx, JSObject *obj SWFDEC_OBJECT (other)->extents.x0, SWFDEC_OBJECT (other)->extents.y0, SWFDEC_OBJECT (other)->extents.x1, SWFDEC_OBJECT (other)->extents.y1); #endif - if (swfdec_rect_intersect (NULL, &movie->extents, &other->extents)) { + if (swfdec_rect_intersect (NULL, &movie_rect, &other_rect)) { *rval = BOOLEAN_TO_JSVAL (JS_TRUE); } else { *rval = BOOLEAN_TO_JSVAL (JS_FALSE); diff-tree ef3becaadc12e3167a7c02a4a8185bf02d9737e2 (from f2fadf23193be3fd4966809e4d0c34d288127b63) Author: Benjamin Otte <otte@gnome.org> Date: Mon Apr 16 09:34:18 2007 +0200 implement focal gradients diff --git a/libswfdec/swfdec_pattern.c b/libswfdec/swfdec_pattern.c index 0041aea..dc9282f 100644 --- a/libswfdec/swfdec_pattern.c +++ b/libswfdec/swfdec_pattern.c @@ -178,6 +178,7 @@ struct _SwfdecGradientPattern SwfdecGradient * gradient; /* gradient to paint */ gboolean radial; /* TRUE for radial gradient, FALSE for linear gradient */ gboolean morph; /* TRUE for morph gradients */ + double focus; /* focus point */ }; struct _SwfdecGradientPatternClass @@ -208,10 +209,12 @@ swfdec_gradient_pattern_get_pattern (Swf { cairo_matrix_t mat; swfdec_matrix_morph (&mat, &pat->start_transform, &pat->end_transform, ratio); - if (gradient->radial) - pattern = cairo_pattern_create_radial (0, 0, 0, 0, 0, 16384 / 256.0); - else + 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; @@ -289,16 +292,22 @@ swfdec_pattern_do_parse (SwfdecSwfDecode } SWFDEC_COLOR_PATTERN (pattern)->end_color = SWFDEC_COLOR_PATTERN (pattern)->start_color; SWFDEC_LOG (" color %08x", SWFDEC_COLOR_PATTERN (pattern)->start_color); - } else if (paint_style_type == 0x10 || paint_style_type == 0x12) { + } else if (paint_style_type == 0x10 || paint_style_type == 0x12 || paint_style_type == 0x13) { + SwfdecGradientPattern *gradient; pattern = g_object_new (SWFDEC_TYPE_GRADIENT_PATTERN, NULL); + gradient = SWFDEC_GRADIENT_PATTERN (pattern); swfdec_bits_get_matrix (bits, &pattern->start_transform, NULL); pattern->end_transform = pattern->start_transform; if (rgba) { - SWFDEC_GRADIENT_PATTERN (pattern)->gradient = swfdec_bits_get_gradient_rgba (bits); + gradient->gradient = swfdec_bits_get_gradient_rgba (bits); } else { - SWFDEC_GRADIENT_PATTERN (pattern)->gradient = swfdec_bits_get_gradient (bits); + gradient->gradient = swfdec_bits_get_gradient (bits); + } + gradient->radial = (paint_style_type != 0x10); + /* FIXME: need a way to ensure 0x13 only happens in Flash 8 */ + if (paint_style_type == 0x13) { + gradient->focus = swfdec_bits_get_s16 (bits) / 256.0; } - SWFDEC_GRADIENT_PATTERN (pattern)->radial = (paint_style_type == 0x12); } else if (paint_style_type >= 0x40 && paint_style_type <= 0x43) { guint paint_id = swfdec_bits_get_u16 (bits); SWFDEC_LOG (" background paint id = %d (type 0x%02x)", diff-tree f2fadf23193be3fd4966809e4d0c34d288127b63 (from a99f988c1777df84a2fe0b91a6f10292cba3d07a) Author: Benjamin Otte <otte@gnome.org> Date: Sun Apr 15 23:00:21 2007 +0200 implement DefineShape4 in a very unsupported way diff --git a/libswfdec/swfdec_font.c b/libswfdec/swfdec_font.c index 9efe573..0aca1d5 100644 --- a/libswfdec/swfdec_font.c +++ b/libswfdec/swfdec_font.c @@ -192,7 +192,7 @@ swfdec_font_parse_shape (SwfdecSwfDecode shape->n_line_bits = swfdec_bits_getbits (&s->b, 4); SWFDEC_LOG ("n_line_bits = %d", shape->n_line_bits); - swfdec_shape_get_recs (s, shape); + swfdec_shape_get_recs (s, shape, swfdec_pattern_parse, swfdec_stroke_parse); swfdec_bits_syncbits (&s->b); if (swfdec_bits_skip_bytes (&save_bits, size) != size) { SWFDEC_ERROR ("invalid offset value, not enough bytes available"); @@ -336,7 +336,7 @@ tag_func_define_font_2 (SwfdecSwfDecoder shape->n_line_bits = swfdec_bits_getbits (&s->b, 4); SWFDEC_LOG ("n_line_bits = %d", shape->n_line_bits); - swfdec_shape_get_recs (s, shape); + swfdec_shape_get_recs (s, shape, swfdec_pattern_parse, swfdec_stroke_parse); } if (wide_codes) { swfdec_bits_skip_bytes (bits, 2 * n_glyphs); diff --git a/libswfdec/swfdec_pattern.c b/libswfdec/swfdec_pattern.c index 5efac10..0041aea 100644 --- a/libswfdec/swfdec_pattern.c +++ b/libswfdec/swfdec_pattern.c @@ -269,24 +269,13 @@ swfdec_gradient_pattern_init (SwfdecGrad /*** EXPORTED API ***/ -/** - * swfdec_pattern_parse: - * @dec: a #SwfdecDecoder to parse from - * @rgba: TRUE if colors are RGBA, FALSE if they're just RGB - * - * Continues parsing @dec into a new #SwfdecPattern - * - * Returns: a new #SwfdecPattern or NULL on error - **/ -SwfdecPattern * -swfdec_pattern_parse (SwfdecSwfDecoder *dec, gboolean rgba) +static SwfdecPattern * +swfdec_pattern_do_parse (SwfdecSwfDecoder *dec, gboolean rgba) { guint paint_style_type; SwfdecBits *bits; SwfdecPattern *pattern; - g_return_val_if_fail (dec != NULL, NULL); - bits = &dec->b; paint_style_type = swfdec_bits_get_u8 (bits); SWFDEC_LOG (" type 0x%02x", paint_style_type); @@ -356,6 +345,31 @@ swfdec_pattern_parse (SwfdecSwfDecoder * } /** + * swfdec_pattern_parse: + * @dec: a #SwfdecDecoder to parse from + * @rgba: TRUE if colors are RGBA, FALSE if they're just RGB + * + * Continues parsing @dec into a new #SwfdecPattern + * + * Returns: a new #SwfdecPattern or NULL on error + **/ +SwfdecPattern * +swfdec_pattern_parse (SwfdecSwfDecoder *dec) +{ + g_return_val_if_fail (dec != NULL, NULL); + + return swfdec_pattern_do_parse (dec, FALSE); +} + +SwfdecPattern * +swfdec_pattern_parse_rgba (SwfdecSwfDecoder *dec) +{ + g_return_val_if_fail (dec != NULL, NULL); + + return swfdec_pattern_do_parse (dec, TRUE); +} + +/** * swfdec_pattern_parse_morph: * @dec: a #SwfdecDecoder to parse from * @@ -511,9 +525,6 @@ swfdec_pattern_to_string (SwfdecPattern SwfdecGradientPattern *gradient = SWFDEC_GRADIENT_PATTERN (pattern); return g_strdup_printf ("%s gradient (%u colors)", gradient->radial ? "radial" : "linear", gradient->gradient->n_gradients); - } else if (SWFDEC_IS_STROKE (pattern)) { - SwfdecStroke *line = SWFDEC_STROKE (pattern); - return g_strdup_printf ("line (width %u, color #%08X)", line->start_width, line->start_color); } else { return g_strdup_printf ("%s", G_OBJECT_TYPE_NAME (pattern)); } diff --git a/libswfdec/swfdec_pattern.h b/libswfdec/swfdec_pattern.h index 6a0d2c7..cc63645 100644 --- a/libswfdec/swfdec_pattern.h +++ b/libswfdec/swfdec_pattern.h @@ -58,8 +58,8 @@ struct _SwfdecPatternClass GType swfdec_pattern_get_type (void); SwfdecPattern * swfdec_pattern_new_color (SwfdecColor color); -SwfdecPattern * swfdec_pattern_parse (SwfdecSwfDecoder * dec, - gboolean rgba); +SwfdecPattern * swfdec_pattern_parse (SwfdecSwfDecoder * dec); +SwfdecPattern * swfdec_pattern_parse_rgba (SwfdecSwfDecoder * dec); SwfdecPattern * swfdec_pattern_parse_morph (SwfdecSwfDecoder * dec); void swfdec_pattern_paint (SwfdecPattern * pattern, diff --git a/libswfdec/swfdec_shape.c b/libswfdec/swfdec_shape.c index 3d513cc..eb7161a 100644 --- a/libswfdec/swfdec_shape.c +++ b/libswfdec/swfdec_shape.c @@ -313,8 +313,6 @@ swfdec_shape_init (SwfdecShape * shape) shape->vecs = g_array_new (FALSE, TRUE, sizeof (SwfdecShapeVec)); } -typedef SwfdecPattern * (* SwfdecPatternFunc) (SwfdecSwfDecoder * s); -typedef SwfdecStroke * (* SwfdecStrokeFunc) (SwfdecSwfDecoder * s); static void swfdec_shape_add_styles (SwfdecSwfDecoder * s, SwfdecShape * shape, SwfdecPatternFunc parse_fill, SwfdecStrokeFunc parse_stroke) @@ -356,30 +354,6 @@ swfdec_shape_add_styles (SwfdecSwfDecode shape->n_line_bits = swfdec_bits_getbits (bits, 4); } -static SwfdecPattern * -parse_rgb (SwfdecSwfDecoder * s) -{ - return swfdec_pattern_parse (s, FALSE); -} - -static SwfdecPattern * -parse_rgba (SwfdecSwfDecoder * s) -{ - return swfdec_pattern_parse (s, TRUE); -} - -static SwfdecStroke * -parse_stroke_rgb (SwfdecSwfDecoder * s) -{ - return swfdec_stroke_parse (s, FALSE); -} - -static SwfdecStroke * -parse_stroke_rgba (SwfdecSwfDecoder * s) -{ - return swfdec_stroke_parse (s, TRUE); -} - int tag_define_shape (SwfdecSwfDecoder * s) { @@ -397,9 +371,9 @@ tag_define_shape (SwfdecSwfDecoder * s) swfdec_bits_get_rect (bits, &SWFDEC_GRAPHIC (shape)->extents); - swfdec_shape_add_styles (s, shape, parse_rgb, parse_stroke_rgb); + swfdec_shape_add_styles (s, shape, swfdec_pattern_parse, swfdec_stroke_parse); - swfdec_shape_get_recs (s, shape); + swfdec_shape_get_recs (s, shape, swfdec_pattern_parse, swfdec_stroke_parse); return SWFDEC_STATUS_OK; } @@ -418,11 +392,9 @@ tag_define_shape_3 (SwfdecSwfDecoder * s swfdec_bits_get_rect (bits, &SWFDEC_GRAPHIC (shape)->extents); - shape->rgba = 1; - - swfdec_shape_add_styles (s, shape, parse_rgba, parse_stroke_rgba); + swfdec_shape_add_styles (s, shape, swfdec_pattern_parse_rgba, swfdec_stroke_parse_rgba); - swfdec_shape_get_recs (s, shape); + swfdec_shape_get_recs (s, shape, swfdec_pattern_parse_rgba, swfdec_stroke_parse_rgba); return SWFDEC_STATUS_OK; } @@ -433,29 +405,39 @@ tag_define_shape_2 (SwfdecSwfDecoder * s return tag_define_shape (s); } -#if 0 int tag_define_shape_4 (SwfdecSwfDecoder *s) { SwfdecBits *bits = &s->b; SwfdecShape *shape; int id; + SwfdecRect tmp; + gboolean has_scale_strokes, has_noscale_strokes; id = swfdec_bits_get_u16 (bits); shape = swfdec_swf_decoder_create_character (s, id, SWFDEC_TYPE_SHAPE); if (!shape) return SWFDEC_STATUS_OK; - shape->rgba = 1; swfdec_bits_get_rect (bits, &SWFDEC_GRAPHIC (shape)->extents); + SWFDEC_LOG (" extents: %g %g x %g %g", + SWFDEC_GRAPHIC (shape)->extents.x0, SWFDEC_GRAPHIC (shape)->extents.y0, + SWFDEC_GRAPHIC (shape)->extents.x1, SWFDEC_GRAPHIC (shape)->extents.y1); + swfdec_bits_get_rect (bits, &tmp); + SWFDEC_LOG (" extents: %g %g x %g %g", + tmp.x0, tmp.y0, tmp.x1, tmp.y1); + swfdec_bits_getbits (bits, 6); + has_scale_strokes = swfdec_bits_getbit (bits); + has_noscale_strokes = swfdec_bits_getbit (bits); + SWFDEC_LOG (" has scaling strokes: %d", has_scale_strokes); + SWFDEC_LOG (" has non-scaling strokes: %d", has_noscale_strokes); - swfdec_shape_add_styles (s, shape, parse_rgba, swfdec_stroke_parse_extended); + swfdec_shape_add_styles (s, shape, swfdec_pattern_parse_rgba, swfdec_stroke_parse_extended); - swfdec_shape_get_recs (s, shape); + swfdec_shape_get_recs (s, shape, swfdec_pattern_parse_rgba, swfdec_stroke_parse_extended); return SWFDEC_STATUS_OK; } -#endif /* The shape creation process is a bit complicated since it requires matching * the Flash model to the cairo model. Note that this code is just random @@ -828,7 +810,8 @@ swfdec_shape_initialize_from_sub_paths ( } void -swfdec_shape_get_recs (SwfdecSwfDecoder * s, SwfdecShape * shape) +swfdec_shape_get_recs (SwfdecSwfDecoder * s, SwfdecShape * shape, + SwfdecPatternFunc pattern_func, SwfdecStrokeFunc stroke_func) { int x = 0, y = 0; SubPath *path = NULL; @@ -842,10 +825,7 @@ swfdec_shape_get_recs (SwfdecSwfDecoder while ((type = swfdec_shape_peek_type (bits))) { switch (type) { case SWFDEC_SHAPE_TYPE_CHANGE: - if (shape->rgba) - path = swfdec_shape_parse_change (s, shape, path_array, path, &x, &y, parse_rgba, parse_stroke_rgba); - else - path = swfdec_shape_parse_change (s, shape, path_array, path, &x, &y, parse_rgb, parse_stroke_rgb); + path = swfdec_shape_parse_change (s, shape, path_array, path, &x, &y, pattern_func, stroke_func); break; case SWFDEC_SHAPE_TYPE_LINE: swfdec_shape_parse_line (bits, path, &x, &y, FALSE); diff --git a/libswfdec/swfdec_shape.h b/libswfdec/swfdec_shape.h index 9ee709e..d3d998d 100644 --- a/libswfdec/swfdec_shape.h +++ b/libswfdec/swfdec_shape.h @@ -27,6 +27,7 @@ #include <libswfdec/swfdec_bits.h> #include <libswfdec/swfdec_graphic.h> #include <libswfdec/swfdec_pattern.h> +#include <libswfdec/swfdec_stroke.h> #include <libswfdec/swfdec_swf_decoder.h> G_BEGIN_DECLS @@ -34,6 +35,9 @@ G_BEGIN_DECLS //typedef struct _SwfdecShape SwfdecShape; typedef struct _SwfdecShapeClass SwfdecShapeClass; +typedef SwfdecPattern * (* SwfdecPatternFunc) (SwfdecSwfDecoder * s); +typedef SwfdecStroke * (* SwfdecStrokeFunc) (SwfdecSwfDecoder * s); + #define SWFDEC_TYPE_SHAPE (swfdec_shape_get_type()) #define SWFDEC_IS_SHAPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_SHAPE)) #define SWFDEC_IS_SHAPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_SHAPE)) @@ -63,7 +67,6 @@ struct _SwfdecShape guint lines_offset; guint n_fill_bits; guint n_line_bits; - gboolean rgba; }; struct _SwfdecShapeClass @@ -76,7 +79,9 @@ GType swfdec_shape_get_type (void); int tag_define_shape (SwfdecSwfDecoder * s); int tag_define_shape_2 (SwfdecSwfDecoder * s); int tag_define_shape_3 (SwfdecSwfDecoder * s); -void swfdec_shape_get_recs (SwfdecSwfDecoder * s, SwfdecShape * shape); +int tag_define_shape_4 (SwfdecSwfDecoder * s); +void swfdec_shape_get_recs (SwfdecSwfDecoder * s, SwfdecShape * shape, + SwfdecPatternFunc pattern_func, SwfdecStrokeFunc stroke_func); G_END_DECLS diff --git a/libswfdec/swfdec_stroke.c b/libswfdec/swfdec_stroke.c index 4f8e5d1..893380d 100644 --- a/libswfdec/swfdec_stroke.c +++ b/libswfdec/swfdec_stroke.c @@ -143,18 +143,29 @@ swfdec_stroke_init (SwfdecStroke *stroke /*** EXPORTED API ***/ SwfdecStroke * -swfdec_stroke_parse (SwfdecSwfDecoder *dec, gboolean rgba) +swfdec_stroke_parse (SwfdecSwfDecoder *dec) { SwfdecBits *bits = &dec->b; SwfdecStroke *stroke = g_object_new (SWFDEC_TYPE_STROKE, NULL); stroke->start_width = swfdec_bits_get_u16 (bits); stroke->end_width = stroke->start_width; - if (rgba) { - stroke->start_color = swfdec_bits_get_rgba (bits); - } else { - stroke->start_color = swfdec_bits_get_color (bits); - } + stroke->start_color = swfdec_bits_get_color (bits); + stroke->end_color = stroke->start_color; + SWFDEC_LOG ("new stroke stroke: width %u color %08x", stroke->start_width, stroke->start_color); + + return stroke; +} + +SwfdecStroke * +swfdec_stroke_parse_rgba (SwfdecSwfDecoder *dec) +{ + SwfdecBits *bits = &dec->b; + SwfdecStroke *stroke = g_object_new (SWFDEC_TYPE_STROKE, NULL); + + stroke->start_width = swfdec_bits_get_u16 (bits); + stroke->end_width = stroke->start_width; + stroke->start_color = swfdec_bits_get_rgba (bits); stroke->end_color = stroke->start_color; SWFDEC_LOG ("new stroke stroke: width %u color %08x", stroke->start_width, stroke->start_color); @@ -269,7 +280,7 @@ swfdec_stroke_do_parse_extended (SwfdecS if (morph) { stroke->pattern = swfdec_pattern_parse_morph (dec); } else { - stroke->pattern = swfdec_pattern_parse (dec, TRUE); + stroke->pattern = swfdec_pattern_parse_rgba (dec); } } else { stroke->start_color = swfdec_bits_get_rgba (bits); diff --git a/libswfdec/swfdec_stroke.h b/libswfdec/swfdec_stroke.h index 016d3ca..9ad694c 100644 --- a/libswfdec/swfdec_stroke.h +++ b/libswfdec/swfdec_stroke.h @@ -70,8 +70,8 @@ void swfdec_stroke_paint (SwfdecStroke const SwfdecColorTransform *trans, guint ratio); -SwfdecStroke * swfdec_stroke_parse (SwfdecSwfDecoder * dec, - gboolean rgba); +SwfdecStroke * swfdec_stroke_parse (SwfdecSwfDecoder * dec); +SwfdecStroke * swfdec_stroke_parse_rgba (SwfdecSwfDecoder * dec); SwfdecStroke * swfdec_stroke_parse_extended (SwfdecSwfDecoder * dec); SwfdecStroke * swfdec_stroke_parse_morph (SwfdecSwfDecoder * dec); SwfdecStroke * swfdec_stroke_parse_morph_extended diff --git a/libswfdec/swfdec_tag.c b/libswfdec/swfdec_tag.c index c7373eb..e372fc1 100644 --- a/libswfdec/swfdec_tag.c +++ b/libswfdec/swfdec_tag.c @@ -567,7 +567,7 @@ static struct tag_func_struct tag_funcs[ [SWFDEC_TAG_METADATA] = {"Metadata", NULL, 0}, [SWFDEC_TAG_DEFINESCALINGGRID] = {"DefineScalingGrid", NULL, 0}, [SWFDEC_TAG_AVM2ACTION] = {"AVM2Action", NULL, 0}, - [SWFDEC_TAG_DEFINESHAPE4] = {"DefineShape4", NULL, 0}, + [SWFDEC_TAG_DEFINESHAPE4] = {"DefineShape4", tag_define_shape_4, 0}, [SWFDEC_TAG_DEFINEMORPHSHAPE2] = {"DefineMorphShape2", NULL, 0}, }; diff --git a/test/dump.c b/test/dump.c index 9c0475e..96f9328 100644 --- a/test/dump.c +++ b/test/dump.c @@ -188,17 +188,22 @@ dump_shape (SwfdecShape *shape) shapevec = &g_array_index (shape->vecs, SwfdecShapeVec, i); g_print(" %3u: ", shapevec->last_index); - if (shapevec->pattern == NULL) { - g_print ("not filled\n"); - } else { - char *str = swfdec_pattern_to_string (shapevec->pattern); + if (SWFDEC_IS_PATTERN (shapevec->pattern)) { + SwfdecPattern *pattern = shapevec->pattern; + char *str = swfdec_pattern_to_string (pattern); g_print ("%s\n", str); g_free (str); - if (verbose) - g_print (" %g %g %g %g %g %g\n", - shapevec->pattern->start_transform.xx, shapevec->pattern->start_transform.xy, - shapevec->pattern->start_transform.yx, shapevec->pattern->start_transform.yy, - shapevec->pattern->start_transform.x0, shapevec->pattern->start_transform.y0); + if (verbose) { + g_print (" %g %g %g %g %g %g\n", + pattern->start_transform.xx, pattern->start_transform.xy, + pattern->start_transform.yx, pattern->start_transform.yy, + pattern->start_transform.x0, pattern->start_transform.y0); + } + } else if (SWFDEC_IS_STROKE (shapevec->pattern)) { + SwfdecStroke *line = SWFDEC_STROKE (shapevec->pattern); + g_print ("line (width %u, color #%08X)", line->start_width, line->start_color); + } else { + g_print ("not filled\n"); } if (verbose) { dump_path (&shapevec->path); diff-tree a99f988c1777df84a2fe0b91a6f10292cba3d07a (from 4997a85872e08b16e9a0283cd60242285cb51674) Author: Benjamin Otte <otte@gnome.org> Date: Sun Apr 15 22:56:45 2007 +0200 oops, wrong order Read the depth before the new flags, which is wrong diff --git a/libswfdec/swfdec_sprite.c b/libswfdec/swfdec_sprite.c index 86f7997..f3ad17d 100644 --- a/libswfdec/swfdec_sprite.c +++ b/libswfdec/swfdec_sprite.c @@ -346,7 +346,6 @@ swfdec_spriteseg_do_place_object (Swfdec has_matrix = swfdec_bits_getbit (bits); has_character = swfdec_bits_getbit (bits); move = swfdec_bits_getbit (bits); - depth = swfdec_bits_get_u16 (bits); SWFDEC_LOG (" has_clip_actions = %d", has_clip_actions); SWFDEC_LOG (" has_clip_depth = %d", has_clip_depth); @@ -356,18 +355,21 @@ swfdec_spriteseg_do_place_object (Swfdec SWFDEC_LOG (" has_matrix = %d", has_matrix); SWFDEC_LOG (" has_character = %d", has_character); SWFDEC_LOG (" move = %d", move); - SWFDEC_LOG (" depth = %d (=> %d)", depth, depth - 16384); - depth -= 16384; if (version > 2) { swfdec_bits_getbits (bits, 5); cache = swfdec_bits_getbit (bits); has_blend_mode = swfdec_bits_getbit (bits); has_filter = swfdec_bits_getbit (bits); + SWFDEC_LOG (" cache = %d", cache); SWFDEC_LOG (" has filter = %d", has_filter); SWFDEC_LOG (" has blend mode = %d", has_blend_mode); } + depth = swfdec_bits_get_u16 (bits); + SWFDEC_LOG (" depth = %d (=> %d)", depth, depth - 16384); + depth -= 16384; + /* new name always means new object */ content = swfdec_contents_create (s->parse_sprite, depth, move, has_character || has_name); if (has_character) { diff-tree 4997a85872e08b16e9a0283cd60242285cb51674 (from ab7ac15f7e1f4290125e5bd938541fc28ade5aed) Author: Benjamin Otte <otte@gnome.org> Date: Sat Apr 14 00:13:33 2007 +0200 implement the Flash 8 linestyle reading This includes some shuffling around of code (like where line caps and joins are set) diff --git a/libswfdec/swfdec_morph_movie.c b/libswfdec/swfdec_morph_movie.c index 46ebd30..34b4d68 100644 --- a/libswfdec/swfdec_morph_movie.c +++ b/libswfdec/swfdec_morph_movie.c @@ -50,8 +50,6 @@ swfdec_morph_movie_render (SwfdecMovie * cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); - cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); - cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); for (i = 0; i < shape->vecs->len; i++) { SwfdecShapeVec *vec = &g_array_index (shape->vecs, SwfdecShapeVec, i); diff --git a/libswfdec/swfdec_shape.c b/libswfdec/swfdec_shape.c index 34e85a9..3d513cc 100644 --- a/libswfdec/swfdec_shape.c +++ b/libswfdec/swfdec_shape.c @@ -238,8 +238,6 @@ swfdec_shape_render (SwfdecGraphic *grap cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); - cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); - cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); for (i = 0; i < shape->vecs->len; i++) { SwfdecShapeVec *vec = &g_array_index (shape->vecs, SwfdecShapeVec, i); diff --git a/libswfdec/swfdec_stroke.c b/libswfdec/swfdec_stroke.c index 30adef9..4f8e5d1 100644 --- a/libswfdec/swfdec_stroke.c +++ b/libswfdec/swfdec_stroke.c @@ -99,6 +99,17 @@ swfdec_stroke_paint (SwfdecStroke *strok SwfdecColor color; double width; + g_return_if_fail (SWFDEC_IS_STROKE (stroke)); + g_return_if_fail (cr != NULL); + g_return_if_fail (path != NULL); + g_return_if_fail (trans != NULL); + g_return_if_fail (ratio < 65536); + + cairo_set_line_cap (cr, stroke->start_cap); + cairo_set_line_join (cr, stroke->join); + if (stroke->join == CAIRO_LINE_JOIN_MITER) + cairo_set_miter_limit (cr, stroke->miter_limit); + swfdec_stroke_append_path_snapped (cr, path); color = swfdec_color_apply_morph (stroke->start_color, stroke->end_color, ratio); color = swfdec_color_apply_transform (color, trans); @@ -124,6 +135,9 @@ swfdec_stroke_class_init (SwfdecStrokeCl static void swfdec_stroke_init (SwfdecStroke *stroke) { + stroke->start_cap = CAIRO_LINE_CAP_ROUND; + stroke->end_cap = CAIRO_LINE_CAP_ROUND; + stroke->join = CAIRO_LINE_JOIN_ROUND; } /*** EXPORTED API ***/ @@ -177,32 +191,112 @@ swfdec_stroke_new (guint width, SwfdecCo return stroke; } +static cairo_line_cap_t +swfdec_line_cap_get (guint cap) +{ + switch (cap) { + case 0: + return CAIRO_LINE_CAP_ROUND; + case 1: + return CAIRO_LINE_CAP_BUTT; + case 2: + return CAIRO_LINE_CAP_SQUARE; + default: + SWFDEC_ERROR ("invalid line cap value %u", cap); + return CAIRO_LINE_CAP_ROUND; + } +} +static cairo_line_join_t +swfdec_line_join_get (guint join) +{ + switch (join) { + case 0: + return CAIRO_LINE_JOIN_ROUND; + case 1: + return CAIRO_LINE_JOIN_BEVEL; + case 2: + return CAIRO_LINE_JOIN_MITER; + default: + SWFDEC_ERROR ("invalid line join value %u", join); + return CAIRO_LINE_JOIN_ROUND; + } +} + static SwfdecStroke * -swfdec_stroke_do_parse_extended (SwfdecBits *bits, gboolean morph, - SwfdecPattern *fill_styles, guint n_fill_styles) +swfdec_stroke_do_parse_extended (SwfdecSwfDecoder *dec, gboolean morph) { + SwfdecBits *bits = &dec->b; + guint tmp; + gboolean has_pattern; SwfdecStroke *stroke = g_object_new (SWFDEC_TYPE_STROKE, NULL); - SWFDEC_ERROR ("FIXME: implement"); + stroke->start_width = swfdec_bits_get_u16 (bits); + if (morph) { + stroke->end_width = swfdec_bits_get_u16 (bits); + SWFDEC_LOG (" width: %u => %u", stroke->start_width, stroke->end_width); + } else { + stroke->end_width = stroke->start_width; + SWFDEC_LOG (" width: %u", stroke->start_width); + } + tmp = swfdec_bits_getbits (bits, 2); + SWFDEC_LOG (" start cap: %u", tmp); + stroke->start_cap = swfdec_line_cap_get (tmp); + tmp = swfdec_bits_getbits (bits, 2); + SWFDEC_LOG (" line join: %u", tmp); + stroke->join = swfdec_line_join_get (tmp); + has_pattern = swfdec_bits_getbit (bits); + SWFDEC_LOG (" has pattern: %d", has_pattern); + stroke->no_hscale = swfdec_bits_getbit (bits); + SWFDEC_LOG (" no hscale: %d", stroke->no_hscale); + stroke->no_vscale = swfdec_bits_getbit (bits); + SWFDEC_LOG (" no vscale: %d", stroke->no_vscale); + stroke->align_pixel = swfdec_bits_getbit (bits); + SWFDEC_LOG (" align pixels: %d", stroke->align_pixel); + tmp = swfdec_bits_getbits (bits, 5); + stroke->no_close = swfdec_bits_getbit (bits); + SWFDEC_LOG (" no close: %d", stroke->no_close); + tmp = swfdec_bits_getbits (bits, 2); + SWFDEC_LOG (" end cap: %u", tmp); + stroke->end_cap = swfdec_line_cap_get (tmp); + if (stroke->end_cap != stroke->start_cap) { + SWFDEC_WARNING ("FIXME: different caps on start and end of line are unsupported"); + } + if (stroke->join == CAIRO_LINE_JOIN_MITER) { + stroke->miter_limit = swfdec_bits_get_u16 (bits); + SWFDEC_LOG (" miter limit: %u", stroke->miter_limit); + } + if (has_pattern) { + if (morph) { + stroke->pattern = swfdec_pattern_parse_morph (dec); + } else { + stroke->pattern = swfdec_pattern_parse (dec, TRUE); + } + } else { + stroke->start_color = swfdec_bits_get_rgba (bits); + if (morph) { + stroke->end_color = swfdec_bits_get_rgba (bits); + SWFDEC_LOG (" color: #%08X", stroke->start_color); + } else { + stroke->end_color = stroke->start_color; + SWFDEC_LOG (" color: #%08X", stroke->start_color); + } + } + return stroke; } SwfdecStroke * -swfdec_stroke_parse_extended (SwfdecSwfDecoder *dec, SwfdecPattern *fill_styles, - guint n_fill_styles) +swfdec_stroke_parse_extended (SwfdecSwfDecoder *dec) { g_return_val_if_fail (SWFDEC_IS_SWF_DECODER (dec), NULL); - g_return_val_if_fail (n_fill_styles == 0 || fill_styles != NULL, NULL); - return swfdec_stroke_do_parse_extended (&dec->b, FALSE, fill_styles, n_fill_styles); + return swfdec_stroke_do_parse_extended (dec, FALSE); } SwfdecStroke * -swfdec_stroke_parse_morph_extended (SwfdecSwfDecoder *dec, SwfdecPattern *fill_styles, - guint n_fill_styles) +swfdec_stroke_parse_morph_extended (SwfdecSwfDecoder *dec) { g_return_val_if_fail (SWFDEC_IS_SWF_DECODER (dec), NULL); - g_return_val_if_fail (n_fill_styles == 0 || fill_styles != NULL, NULL); - return swfdec_stroke_do_parse_extended (&dec->b, TRUE, fill_styles, n_fill_styles); + return swfdec_stroke_do_parse_extended (dec, TRUE); } diff --git a/libswfdec/swfdec_stroke.h b/libswfdec/swfdec_stroke.h index 37fd990..016d3ca 100644 --- a/libswfdec/swfdec_stroke.h +++ b/libswfdec/swfdec_stroke.h @@ -42,6 +42,16 @@ struct _SwfdecStroke SwfdecColor start_color; /* color to paint with */ guint end_width; /* width of line */ SwfdecColor end_color; /* color to paint with */ + /* Flash 8 */ + SwfdecPattern * pattern; /* pattern to use instead of color if not NULL */ + cairo_line_cap_t start_cap; + cairo_line_cap_t end_cap; + cairo_line_join_t join; + guint miter_limit; /* only set when join = MITER */ + gboolean no_vscale; /* don't scale line in vertical direction */ + gboolean no_hscale; /* don't scale line in horizontal direction */ + gboolean align_pixel; /* align control points on pixel boundaries */ + gboolean no_close; /* don't auto-close lines */ }; struct _SwfdecStrokeClass @@ -62,14 +72,10 @@ void swfdec_stroke_paint (SwfdecStroke SwfdecStroke * swfdec_stroke_parse (SwfdecSwfDecoder * dec, gboolean rgba); -SwfdecStroke * swfdec_stroke_parse_extended (SwfdecSwfDecoder * dec, - SwfdecPattern * fill_styles, - guint n_fill_styles); +SwfdecStroke * swfdec_stroke_parse_extended (SwfdecSwfDecoder * dec); SwfdecStroke * swfdec_stroke_parse_morph (SwfdecSwfDecoder * dec); SwfdecStroke * swfdec_stroke_parse_morph_extended - (SwfdecSwfDecoder * dec, - SwfdecPattern * fill_styles, - guint n_fill_styles); + (SwfdecSwfDecoder * dec); G_END_DECLS diff-tree ab7ac15f7e1f4290125e5bd938541fc28ade5aed (from 9a64282b9188bf335b9be029fd91e8a66ffddc8d) Author: Benjamin Otte <otte@gnome.org> Date: Fri Apr 13 22:36:15 2007 +0200 Make stroke and pattern 2 different objects Also change the way drawing patterns is handled. Still preparation for Flash 8 strokes. diff --git a/libswfdec/swfdec_morph_movie.c b/libswfdec/swfdec_morph_movie.c index 85ccc96..46ebd30 100644 --- a/libswfdec/swfdec_morph_movie.c +++ b/libswfdec/swfdec_morph_movie.c @@ -23,6 +23,7 @@ #include "swfdec_morph_movie.h" #include "swfdec_debug.h" +#include "swfdec_stroke.h" G_DEFINE_TYPE (SwfdecMorphMovie, swfdec_morph_movie, SWFDEC_TYPE_MOVIE) @@ -63,13 +64,18 @@ swfdec_morph_movie_render (SwfdecMovie * continue; /* hack to not append paths for lines */ - if (!fill && vec->last_index % 2 != 0) + if (!fill && SWFDEC_IS_STROKE (vec->pattern)) continue; - if (fill) - swfdec_pattern_paint (vec->pattern, cr, path, trans, movie->content->ratio); - else - cairo_append_path (cr, &vec->path); + if (fill) { + if (SWFDEC_IS_PATTERN (vec->pattern)) { + swfdec_pattern_paint (vec->pattern, cr, path, trans, movie->content->ratio); + } else { + swfdec_stroke_paint (vec->pattern, cr, path, trans, movie->content->ratio); + } + } else { + cairo_append_path (cr, path); + } } } diff --git a/libswfdec/swfdec_pattern.c b/libswfdec/swfdec_pattern.c index 8a2bda7..5efac10 100644 --- a/libswfdec/swfdec_pattern.c +++ b/libswfdec/swfdec_pattern.c @@ -74,24 +74,24 @@ struct _SwfdecColorPatternClass G_DEFINE_TYPE (SwfdecColorPattern, swfdec_color_pattern, SWFDEC_TYPE_PATTERN); -static void -swfdec_color_pattern_paint (SwfdecPattern *pat, cairo_t *cr, const cairo_path_t *path, +static cairo_pattern_t * +swfdec_color_pattern_get_pattern (SwfdecPattern *pat, const SwfdecColorTransform *trans, guint ratio) { SwfdecColorPattern *pattern = SWFDEC_COLOR_PATTERN (pat); SwfdecColor color; - cairo_append_path (cr, (cairo_path_t *) path); color = swfdec_color_apply_morph (pattern->start_color, pattern->end_color, ratio); color = swfdec_color_apply_transform (color, trans); - swfdec_color_set_source (cr, color); - cairo_fill (cr); + return cairo_pattern_create_rgba ( + SWFDEC_COLOR_R (color) / 255.0, SWFDEC_COLOR_G (color) / 255.0, + SWFDEC_COLOR_B (color) / 255.0, SWFDEC_COLOR_A (color) / 255.0); } static void swfdec_color_pattern_class_init (SwfdecColorPatternClass *klass) { - SWFDEC_PATTERN_CLASS (klass)->paint = swfdec_color_pattern_paint; + SWFDEC_PATTERN_CLASS (klass)->get_pattern = swfdec_color_pattern_get_pattern; } static void @@ -127,8 +127,8 @@ struct _SwfdecImagePatternClass G_DEFINE_TYPE (SwfdecImagePattern, swfdec_image_pattern, SWFDEC_TYPE_PATTERN); -static void -swfdec_image_pattern_paint (SwfdecPattern *pat, cairo_t *cr, const cairo_path_t *path, +static cairo_pattern_t * +swfdec_image_pattern_get_pattern (SwfdecPattern *pat, const SwfdecColorTransform *trans, guint ratio) { SwfdecImagePattern *image = SWFDEC_IMAGE_PATTERN (pat); @@ -138,23 +138,20 @@ swfdec_image_pattern_paint (SwfdecPatter surface = swfdec_image_create_surface_transformed (image->image, trans); if (surface == NULL) - return; - cairo_append_path (cr, (cairo_path_t *) path); + return NULL; pattern = cairo_pattern_create_for_surface (surface); cairo_surface_destroy (surface); swfdec_matrix_morph (&mat, &pat->start_transform, &pat->end_transform, ratio); cairo_pattern_set_matrix (pattern, &mat); cairo_pattern_set_extend (pattern, image->extend); cairo_pattern_set_filter (pattern, image->filter); - cairo_set_source (cr, pattern); - cairo_pattern_destroy (pattern); - cairo_fill (cr); + return pattern; } static void swfdec_image_pattern_class_init (SwfdecImagePatternClass *klass) { - SWFDEC_PATTERN_CLASS (klass)->paint = swfdec_image_pattern_paint; + SWFDEC_PATTERN_CLASS (klass)->get_pattern = swfdec_image_pattern_get_pattern; } static void @@ -190,8 +187,8 @@ struct _SwfdecGradientPatternClass G_DEFINE_TYPE (SwfdecGradientPattern, swfdec_gradient_pattern, SWFDEC_TYPE_PATTERN); -static void -swfdec_gradient_pattern_paint (SwfdecPattern *pat, cairo_t *cr, const cairo_path_t *path, +static cairo_pattern_t * +swfdec_gradient_pattern_get_pattern (SwfdecPattern *pat, const SwfdecColorTransform *trans, guint ratio) { guint i; @@ -200,7 +197,6 @@ swfdec_gradient_pattern_paint (SwfdecPat double offset; SwfdecGradientPattern *gradient = SWFDEC_GRADIENT_PATTERN (pat); - cairo_append_path (cr, (cairo_path_t *) path); #if 0 /* use this when https://bugs.freedesktop.org/show_bug.cgi?id=8341 is fixed */ if (gradient->radial) @@ -244,9 +240,7 @@ swfdec_gradient_pattern_paint (SwfdecPat SWFDEC_COLOR_B(color) / 255.0, SWFDEC_COLOR_A(color) / 255.0); } } - cairo_set_source (cr, pattern); - cairo_pattern_destroy (pattern); - cairo_fill (cr); + return pattern; } static void @@ -265,7 +259,7 @@ swfdec_gradient_pattern_class_init (Swfd { G_OBJECT_CLASS (klass)->dispose = swfdec_gradient_pattern_dispose; - SWFDEC_PATTERN_CLASS (klass)->paint = swfdec_gradient_pattern_paint; + SWFDEC_PATTERN_CLASS (klass)->get_pattern = swfdec_gradient_pattern_get_pattern; } static void @@ -458,7 +452,7 @@ void swfdec_pattern_paint (SwfdecPattern *pattern, cairo_t *cr, const cairo_path_t *path, const SwfdecColorTransform *trans, guint ratio) { - SwfdecPatternClass *klass; + cairo_pattern_t *cpattern; g_return_if_fail (SWFDEC_IS_PATTERN (pattern)); g_return_if_fail (cr != NULL); @@ -466,10 +460,13 @@ swfdec_pattern_paint (SwfdecPattern *pat g_return_if_fail (trans != NULL); g_return_if_fail (ratio < 65536); - klass = SWFDEC_PATTERN_GET_CLASS (pattern); - g_return_if_fail (klass->paint); - - klass->paint (pattern, cr, path, trans, ratio); + cpattern = swfdec_pattern_get_pattern (pattern, trans, ratio); + if (cpattern == NULL) + return; + cairo_append_path (cr, path); + cairo_set_source (cr, cpattern); + cairo_pattern_destroy (cpattern); + cairo_fill (cr); } /** @@ -613,3 +610,18 @@ swfdec_pattern_get_path_extents (SwfdecP } } +cairo_pattern_t * +swfdec_pattern_get_pattern (SwfdecPattern *pattern, + const SwfdecColorTransform *trans, guint ratio) +{ + SwfdecPatternClass *klass; + + g_return_val_if_fail (SWFDEC_IS_PATTERN (pattern), NULL); + g_return_val_if_fail (trans != NULL, NULL); + g_return_val_if_fail (ratio < 65536, NULL); + + klass = SWFDEC_PATTERN_GET_CLASS (pattern); + g_assert (klass->get_pattern); + return klass->get_pattern (pattern, trans, ratio); +} + diff --git a/libswfdec/swfdec_pattern.h b/libswfdec/swfdec_pattern.h index 7ea97f5..6a0d2c7 100644 --- a/libswfdec/swfdec_pattern.h +++ b/libswfdec/swfdec_pattern.h @@ -49,11 +49,10 @@ struct _SwfdecPatternClass { GObjectClass object_class; - void (* paint) (SwfdecPattern * pattern, - cairo_t * cr, - const cairo_path_t * path, + /* create a cairo pattern for the given values */ + cairo_pattern_t * (* get_pattern) (SwfdecPattern * pattern, const SwfdecColorTransform * trans, - guint ratio); + guint ratio); }; GType swfdec_pattern_get_type (void); @@ -67,7 +66,10 @@ void swfdec_pattern_paint (SwfdecPatte cairo_t * cr, const cairo_path_t * path, const SwfdecColorTransform * trans, - guint ratio); + guint ratio); +cairo_pattern_t *swfdec_pattern_get_pattern (SwfdecPattern * pattern, + const SwfdecColorTransform * trans, + guint ratio); void swfdec_pattern_get_path_extents (SwfdecPattern * pattern, const cairo_path_t * path, SwfdecRect * extents); diff --git a/libswfdec/swfdec_shape.c b/libswfdec/swfdec_shape.c index 65a5166..34e85a9 100644 --- a/libswfdec/swfdec_shape.c +++ b/libswfdec/swfdec_shape.c @@ -253,10 +253,15 @@ swfdec_shape_render (SwfdecGraphic *grap if (!fill && vec->last_index % 2 != 0) continue; - if (fill) - swfdec_pattern_paint (vec->pattern, cr, &vec->path, trans, 0); - else + if (fill) { + if (SWFDEC_IS_PATTERN (vec->pattern)) { + swfdec_pattern_paint (vec->pattern, cr, &vec->path, trans, 0); + } else { + swfdec_stroke_paint (vec->pattern, cr, &vec->path, trans, 0); + } + } else { cairo_append_path (cr, &vec->path); + } } } @@ -274,7 +279,7 @@ swfdec_shape_mouse_in (SwfdecGraphic *gr g_assert (shapevec->path.num_data); g_assert (shapevec->pattern); /* FIXME: handle strokes */ - if (shapevec->last_index & 1) + if (SWFDEC_IS_STROKE (shapevec->pattern)) continue; if (shapevec->fill_cr == NULL) { /* FIXME: do less memory intensive fill checking plz */ @@ -311,9 +316,10 @@ swfdec_shape_init (SwfdecShape * shape) } typedef SwfdecPattern * (* SwfdecPatternFunc) (SwfdecSwfDecoder * s); +typedef SwfdecStroke * (* SwfdecStrokeFunc) (SwfdecSwfDecoder * s); static void swfdec_shape_add_styles (SwfdecSwfDecoder * s, SwfdecShape * shape, - SwfdecPatternFunc parse_fill, SwfdecPatternFunc parse_stroke) + SwfdecPatternFunc parse_fill, SwfdecStrokeFunc parse_stroke) { int n_fill_styles; int n_line_styles; @@ -344,8 +350,7 @@ swfdec_shape_add_styles (SwfdecSwfDecode } SWFDEC_LOG (" n_line_styles %d", n_line_styles); for (i = 0; i < n_line_styles; i++) { - SwfdecPattern *pattern = parse_stroke (s); - g_ptr_array_add (shape->lines, pattern); + g_ptr_array_add (shape->lines, parse_stroke (s)); } swfdec_bits_syncbits (bits); @@ -365,13 +370,13 @@ parse_rgba (SwfdecSwfDecoder * s) return swfdec_pattern_parse (s, TRUE); } -static SwfdecPattern * +static SwfdecStroke * parse_stroke_rgb (SwfdecSwfDecoder * s) { return swfdec_stroke_parse (s, FALSE); } -static SwfdecPattern * +static SwfdecStroke * parse_stroke_rgba (SwfdecSwfDecoder * s) { return swfdec_stroke_parse (s, TRUE); @@ -430,6 +435,30 @@ tag_define_shape_2 (SwfdecSwfDecoder * s return tag_define_shape (s); } +#if 0 +int +tag_define_shape_4 (SwfdecSwfDecoder *s) +{ + SwfdecBits *bits = &s->b; + SwfdecShape *shape; + int id; + + id = swfdec_bits_get_u16 (bits); + shape = swfdec_swf_decoder_create_character (s, id, SWFDEC_TYPE_SHAPE); + if (!shape) + return SWFDEC_STATUS_OK; + shape->rgba = 1; + + swfdec_bits_get_rect (bits, &SWFDEC_GRAPHIC (shape)->extents); + + swfdec_shape_add_styles (s, shape, parse_rgba, swfdec_stroke_parse_extended); + + swfdec_shape_get_recs (s, shape); + + return SWFDEC_STATUS_OK; +} +#endif + /* The shape creation process is a bit complicated since it requires matching * the Flash model to the cairo model. Note that this code is just random * guessing and nothing substantial. Otherwise I'd have a testsuite. :) @@ -709,7 +738,7 @@ swfdec_shape_parse_line (SwfdecBits *bit SubPath * swfdec_shape_parse_change (SwfdecSwfDecoder *s, SwfdecShape *shape, GArray *path_array, SubPath *path, - int *x, int *y, SwfdecPatternFunc parse_fill, SwfdecPatternFunc parse_stroke) + int *x, int *y, SwfdecPatternFunc parse_fill, SwfdecStrokeFunc parse_stroke) { int state_new_styles, state_line_styles, state_fill_styles1, state_fill_styles0, state_moveto; SwfdecBits *bits = &s->b; diff --git a/libswfdec/swfdec_shape.h b/libswfdec/swfdec_shape.h index cce6cf8..9ee709e 100644 --- a/libswfdec/swfdec_shape.h +++ b/libswfdec/swfdec_shape.h @@ -42,7 +42,7 @@ typedef struct _SwfdecShapeClass SwfdecS struct _SwfdecShapeVec { - SwfdecPattern *pattern; /* pattern to display */ + gpointer pattern; /* pattern or stroke to display */ cairo_path_t path; /* accumulated path */ SwfdecRect extents; /* extents of path */ guint last_index; /* index of last segment that was added */ diff --git a/libswfdec/swfdec_stroke.c b/libswfdec/swfdec_stroke.c index 7239479..30adef9 100644 --- a/libswfdec/swfdec_stroke.c +++ b/libswfdec/swfdec_stroke.c @@ -32,7 +32,7 @@ #define MAX_ALIGN 10 -G_DEFINE_TYPE (SwfdecStroke, swfdec_stroke, SWFDEC_TYPE_PATTERN); +G_DEFINE_TYPE (SwfdecStroke, swfdec_stroke, G_TYPE_OBJECT); static void swfdec_stroke_append_path_snapped (cairo_t *cr, const cairo_path_t *path) @@ -92,13 +92,12 @@ swfdec_stroke_append_path_snapped (cairo } } -static void -swfdec_stroke_paint (SwfdecPattern *pattern, cairo_t *cr, const cairo_path_t *path, +void +swfdec_stroke_paint (SwfdecStroke *stroke, cairo_t *cr, const cairo_path_t *path, const SwfdecColorTransform *trans, guint ratio) { SwfdecColor color; double width; - SwfdecStroke *stroke = SWFDEC_STROKE (pattern); swfdec_stroke_append_path_snapped (cr, path); color = swfdec_color_apply_morph (stroke->start_color, stroke->end_color, ratio); @@ -120,7 +119,6 @@ swfdec_stroke_paint (SwfdecPattern *patt static void swfdec_stroke_class_init (SwfdecStrokeClass *klass) { - SWFDEC_PATTERN_CLASS (klass)->paint = swfdec_stroke_paint; } static void @@ -130,7 +128,7 @@ swfdec_stroke_init (SwfdecStroke *stroke /*** EXPORTED API ***/ -SwfdecPattern * +SwfdecStroke * swfdec_stroke_parse (SwfdecSwfDecoder *dec, gboolean rgba) { SwfdecBits *bits = &dec->b; @@ -146,10 +144,10 @@ swfdec_stroke_parse (SwfdecSwfDecoder *d stroke->end_color = stroke->start_color; SWFDEC_LOG ("new stroke stroke: width %u color %08x", stroke->start_width, stroke->start_color); - return SWFDEC_PATTERN (stroke); + return stroke; } -SwfdecPattern * +SwfdecStroke * swfdec_stroke_parse_morph (SwfdecSwfDecoder *dec) { SwfdecBits *bits = &dec->b; @@ -163,10 +161,10 @@ swfdec_stroke_parse_morph (SwfdecSwfDeco stroke->start_width, stroke->end_width, stroke->start_color, stroke->end_color); - return SWFDEC_PATTERN (stroke); + return stroke; } -SwfdecPattern * +SwfdecStroke * swfdec_stroke_new (guint width, SwfdecColor color) { SwfdecStroke *stroke = g_object_new (SWFDEC_TYPE_STROKE, NULL); @@ -176,20 +174,20 @@ swfdec_stroke_new (guint width, SwfdecCo stroke->start_color = color; stroke->end_color = color; - return SWFDEC_PATTERN (stroke); + return stroke; } -static SwfdecPattern * +static SwfdecStroke * swfdec_stroke_do_parse_extended (SwfdecBits *bits, gboolean morph, SwfdecPattern *fill_styles, guint n_fill_styles) { SwfdecStroke *stroke = g_object_new (SWFDEC_TYPE_STROKE, NULL); SWFDEC_ERROR ("FIXME: implement"); - return SWFDEC_PATTERN (stroke); + return stroke; } -SwfdecPattern * +SwfdecStroke * swfdec_stroke_parse_extended (SwfdecSwfDecoder *dec, SwfdecPattern *fill_styles, guint n_fill_styles) { @@ -199,7 +197,7 @@ swfdec_stroke_parse_extended (SwfdecSwfD return swfdec_stroke_do_parse_extended (&dec->b, FALSE, fill_styles, n_fill_styles); } -SwfdecPattern * +SwfdecStroke * swfdec_stroke_parse_morph_extended (SwfdecSwfDecoder *dec, SwfdecPattern *fill_styles, guint n_fill_styles) { diff --git a/libswfdec/swfdec_stroke.h b/libswfdec/swfdec_stroke.h index 51dbf07..37fd990 100644 --- a/libswfdec/swfdec_stroke.h +++ b/libswfdec/swfdec_stroke.h @@ -36,7 +36,7 @@ typedef struct _SwfdecStrokeClass Swfdec struct _SwfdecStroke { - SwfdecPattern pattern; + GObject object; guint start_width; /* width of line */ SwfdecColor start_color; /* color to paint with */ @@ -46,20 +46,27 @@ struct _SwfdecStroke struct _SwfdecStrokeClass { - SwfdecPatternClass pattern_class; + GObjectClass object_class; }; GType swfdec_stroke_get_type (void); -SwfdecPattern * swfdec_stroke_new (guint width, +SwfdecStroke * swfdec_stroke_new (guint width, SwfdecColor color); -SwfdecPattern * swfdec_stroke_parse (SwfdecSwfDecoder * dec, + +void swfdec_stroke_paint (SwfdecStroke * stroke, + cairo_t * cr, + const cairo_path_t * path, + const SwfdecColorTransform *trans, + guint ratio); + +SwfdecStroke * swfdec_stroke_parse (SwfdecSwfDecoder * dec, gboolean rgba); -SwfdecPattern * swfdec_stroke_parse_extended (SwfdecSwfDecoder * dec, +SwfdecStroke * swfdec_stroke_parse_extended (SwfdecSwfDecoder * dec, SwfdecPattern * fill_styles, guint n_fill_styles); -SwfdecPattern * swfdec_stroke_parse_morph (SwfdecSwfDecoder * dec); -SwfdecPattern * swfdec_stroke_parse_morph_extended +SwfdecStroke * swfdec_stroke_parse_morph (SwfdecSwfDecoder * dec); +SwfdecStroke * swfdec_stroke_parse_morph_extended (SwfdecSwfDecoder * dec, SwfdecPattern * fill_styles, guint n_fill_styles); diff-tree 9a64282b9188bf335b9be029fd91e8a66ffddc8d (from 26ee7f5d85a1d809daa20b2f67cf4cb99420ed66) Author: Benjamin Otte <otte@gnome.org> Date: Fri Apr 13 20:53:03 2007 +0200 that function should be static diff --git a/libswfdec/swfdec_codec_gst.c b/libswfdec/swfdec_codec_gst.c index 64c335c..6c1ae37 100644 --- a/libswfdec/swfdec_codec_gst.c +++ b/libswfdec/swfdec_codec_gst.c @@ -176,7 +176,7 @@ swfdec_audio_decoder_gst_link (GstElemen } } -GstBusSyncReply +static GstBusSyncReply swfdec_audio_decoder_gst_handle_bus (GstBus *bus, GstMessage *message, gpointer data) { SwfdecGstAudio *player = data;
Possibly Parallel Threads
- 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.c libswfdec/swfdec_stroke.c test/dump.c
- 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
- 10 commits - configure.ac doc/Makefile.am doc/swfdec-sections.txt libswfdec/swfdec_buffer.c libswfdec/swfdec_movie_as_drawing.c test/image test/sound
- 15 commits - libswfdec/jpeg libswfdec/swfdec_bits.c libswfdec/swfdec_edittext.c libswfdec/swfdec_font.c libswfdec/swfdec_image.c libswfdec/swfdec_root_sprite.c libswfdec/swfdec_script.c libswfdec/swfdec_shape.c libswfdec/swfdec_sprite.c