Benjamin Otte
2007-Apr-13 08:23 UTC
[Swfdec] 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 libswfdec/swfdec_player_internal.h libswfdec/swfdec_shape.c libswfdec/swfdec_sprite.c libswfdec/swfdec_sprite.h libswfdec/swfdec_stroke.c libswfdec/swfdec_stroke.h libswfdec/swfdec_swf_decoder.c libswfdec/swfdec_tag.c player/swfdec_debug_widget.c
libswfdec/Makefile.am | 2 libswfdec/swfdec_color.c | 23 +++ libswfdec/swfdec_color.h | 3 libswfdec/swfdec_font.c | 5 libswfdec/swfdec_loadertarget.c | 2 libswfdec/swfdec_movie.h | 5 libswfdec/swfdec_pattern.c | 229 ++++--------------------------------- libswfdec/swfdec_pattern.h | 24 ++- libswfdec/swfdec_player.c | 5 libswfdec/swfdec_player_internal.h | 7 - libswfdec/swfdec_shape.c | 11 - libswfdec/swfdec_sprite.c | 48 +++++++ libswfdec/swfdec_sprite.h | 1 libswfdec/swfdec_stroke.c | 210 +++++++++++++++++++++++++++++++++ libswfdec/swfdec_stroke.h | 69 +++++++++++ libswfdec/swfdec_swf_decoder.c | 8 - libswfdec/swfdec_tag.c | 2 player/swfdec_debug_widget.c | 2 18 files changed, 423 insertions(+), 233 deletions(-) New commits: diff-tree 26ee7f5d85a1d809daa20b2f67cf4cb99420ed66 (from 61c1915ce1a6b610a5023443af62d64632322b6a) Author: Benjamin Otte <otte@gnome.org> Date: Fri Apr 13 17:24:04 2007 +0200 fix crash with 0x0 sized movies (fixes #10629) diff --git a/libswfdec/swfdec_loadertarget.c b/libswfdec/swfdec_loadertarget.c index 40ad26f..a19a0bf 100644 --- a/libswfdec/swfdec_loadertarget.c +++ b/libswfdec/swfdec_loadertarget.c @@ -125,8 +125,6 @@ swfdec_loader_target_parse_default (Swfd { SwfdecPlayer *player; player = swfdec_loader_target_get_player (target); - g_assert (dec->width > 0); - g_assert (dec->height > 0); swfdec_player_initialize (player, dec->rate, dec->width, dec->height); if (!swfdec_loader_target_init (target)) { diff --git a/libswfdec/swfdec_player.c b/libswfdec/swfdec_player.c index 6e03f55..517b2cb 100644 --- a/libswfdec/swfdec_player.c +++ b/libswfdec/swfdec_player.c @@ -1023,8 +1023,6 @@ void swfdec_player_initialize (SwfdecPlayer *player, guint rate, guint width, guint height) { g_return_if_fail (SWFDEC_IS_PLAYER (player)); - g_return_if_fail (width > 0); - g_return_if_fail (height > 0); if (swfdec_player_is_initialized (player)) return; @@ -1033,6 +1031,7 @@ swfdec_player_initialize (SwfdecPlayer * player->rate = rate; player->width = width; player->height = height; + player->initialized = TRUE; if (rate) { player->iterate_timeout.timestamp = player->time + SWFDEC_TICKS_PER_SECOND * 256 / rate; swfdec_player_add_timeout (player, &player->iterate_timeout); @@ -1334,7 +1333,7 @@ swfdec_player_is_initialized (SwfdecPlay { g_return_val_if_fail (SWFDEC_IS_PLAYER (player), FALSE); - return player->width > 0 && player->height > 0; + return player->initialized; } /** diff --git a/libswfdec/swfdec_player_internal.h b/libswfdec/swfdec_player_internal.h index f4de1a1..527ee6e 100644 --- a/libswfdec/swfdec_player_internal.h +++ b/libswfdec/swfdec_player_internal.h @@ -42,9 +42,10 @@ struct _SwfdecPlayer GObject object; /* global properties */ - guint rate; /* divide by 256 to get iterations per second */ - guint width; /* width of movie */ - guint height; /* height of movie */ + gboolean initialized; /* if width and height are set already */ + guint rate; /* divide by 256 to get iterations per second */ + guint width; /* width of movie */ + guint height; /* height of movie */ GList * roots; /* all the root movies */ SwfdecCache * cache; /* player cache */ gboolean bgcolor_set; /* TRUE if the background color has been set */ diff --git a/libswfdec/swfdec_swf_decoder.c b/libswfdec/swfdec_swf_decoder.c index 97f6965..f8a34b1 100644 --- a/libswfdec/swfdec_swf_decoder.c +++ b/libswfdec/swfdec_swf_decoder.c @@ -194,9 +194,11 @@ swf_parse_header2 (SwfdecSwfDecoder * s) swfdec_bits_get_rect (&s->b, &rect); if (rect.x0 != 0.0 || rect.y0 != 0.0) - SWFDEC_ERROR ("SWF window doesn't start at 0 0 but at %g %g\n", rect.x0, rect.y0); - dec->width = ceil (rect.x1 / SWFDEC_TWIPS_SCALE_FACTOR); - dec->height = ceil (rect.y1 / SWFDEC_TWIPS_SCALE_FACTOR); + SWFDEC_ERROR ("SWF window doesn't start at 0 0 but at %g %g", rect.x0, rect.y0); + SWFDEC_INFO ("SWF size: %g x %g pixels", rect.x1 / SWFDEC_TWIPS_SCALE_FACTOR, + rect.y1 / SWFDEC_TWIPS_SCALE_FACTOR); + dec->width = MAX (0, ceil (rect.x1 / SWFDEC_TWIPS_SCALE_FACTOR)); + dec->height = MAX (0, ceil (rect.y1 / SWFDEC_TWIPS_SCALE_FACTOR)); swfdec_bits_syncbits (&s->b); dec->rate = swfdec_bits_get_u16 (&s->b); SWFDEC_LOG ("rate = %g", dec->rate / 256.0); diff-tree 61c1915ce1a6b610a5023443af62d64632322b6a (from ffd9d1fab29d4f256c59b597aac0a11ee1f58317) Author: Benjamin Otte <otte@gnome.org> Date: Fri Apr 13 14:50:00 2007 +0200 split out the stroke pattern as a seperate object. This is inpreparation for Flash 8's new strokes diff --git a/libswfdec/Makefile.am b/libswfdec/Makefile.am index 352d46b..54710bf 100644 --- a/libswfdec/Makefile.am +++ b/libswfdec/Makefile.am @@ -79,6 +79,7 @@ libswfdec_@SWFDEC_MAJORMINOR@_la_SOURCES swfdec_scriptable.c \ swfdec_shape.c \ swfdec_sound.c \ + swfdec_stroke.c \ swfdec_sprite.c \ swfdec_sprite_movie.c \ swfdec_swf_decoder.c \ @@ -159,6 +160,7 @@ noinst_HEADERS = \ swfdec_sprite.h \ swfdec_sprite_movie.h \ swfdec_swf_decoder.h \ + swfdec_stroke.h \ swfdec_tag.h \ swfdec_text.h \ swfdec_types.h \ diff --git a/libswfdec/swfdec_color.c b/libswfdec/swfdec_color.c index 23fda5a..83be167 100644 --- a/libswfdec/swfdec_color.c +++ b/libswfdec/swfdec_color.c @@ -250,3 +250,26 @@ swfdec_matrix_get_rotation (const cairo_ return atan2 (matrix->yx, matrix->xx) * 180 / G_PI; } +void +swfdec_matrix_morph (cairo_matrix_t *dest, const cairo_matrix_t *start, + const cairo_matrix_t *end, guint ratio) +{ + guint inv_ratio = 65535 - ratio; + g_assert (ratio < 65536); + + if (ratio == 0) { + *dest = *start; + return; + } + if (ratio == 65535) { + *dest = *end; + return; + } + dest->xx = (start->xx * inv_ratio + end->xx * ratio) / 65535; + dest->xy = (start->xy * inv_ratio + end->xy * ratio) / 65535; + dest->yy = (start->yy * inv_ratio + end->yy * ratio) / 65535; + dest->yx = (start->yx * inv_ratio + end->yx * ratio) / 65535; + dest->x0 = (start->x0 * inv_ratio + end->x0 * ratio) / 65535; + dest->y0 = (start->y0 * inv_ratio + end->y0 * ratio) / 65535; +} + diff --git a/libswfdec/swfdec_color.h b/libswfdec/swfdec_color.h index 296311b..e43458f 100644 --- a/libswfdec/swfdec_color.h +++ b/libswfdec/swfdec_color.h @@ -80,5 +80,8 @@ void swfdec_matrix_ensure_invertible (ca double swfdec_matrix_get_xscale (const cairo_matrix_t *matrix); double swfdec_matrix_get_yscale (const cairo_matrix_t *matrix); double swfdec_matrix_get_rotation (const cairo_matrix_t *matrix); +void swfdec_matrix_morph (cairo_matrix_t *dest, const cairo_matrix_t *start, + const cairo_matrix_t *end, guint ratio); + #endif diff --git a/libswfdec/swfdec_font.c b/libswfdec/swfdec_font.c index 1b032d8..9efe573 100644 --- a/libswfdec/swfdec_font.c +++ b/libswfdec/swfdec_font.c @@ -27,6 +27,7 @@ #include "swfdec_bits.h" #include "swfdec_debug.h" #include "swfdec_shape.h" +#include "swfdec_stroke.h" #include "swfdec_swf_decoder.h" G_DEFINE_TYPE (SwfdecFont, swfdec_font, SWFDEC_TYPE_CHARACTER) @@ -184,7 +185,7 @@ swfdec_font_parse_shape (SwfdecSwfDecode entry->shape = shape; g_ptr_array_add (shape->fills, swfdec_pattern_new_color (0xFFFFFFFF)); - g_ptr_array_add (shape->lines, swfdec_pattern_new_stroke (20, 0xFFFFFFFF)); + g_ptr_array_add (shape->lines, swfdec_stroke_new (20, 0xFFFFFFFF)); shape->n_fill_bits = swfdec_bits_getbits (&s->b, 4); SWFDEC_LOG ("n_fill_bits = %d", shape->n_fill_bits); @@ -327,7 +328,7 @@ tag_func_define_font_2 (SwfdecSwfDecoder entry->shape = shape; g_ptr_array_add (shape->fills, swfdec_pattern_new_color (0xFFFFFFFF)); - g_ptr_array_add (shape->lines, swfdec_pattern_new_stroke (20, 0xFFFFFFFF)); + g_ptr_array_add (shape->lines, swfdec_stroke_new (20, 0xFFFFFFFF)); swfdec_bits_syncbits (&s->b); shape->n_fill_bits = swfdec_bits_getbits (&s->b, 4); diff --git a/libswfdec/swfdec_pattern.c b/libswfdec/swfdec_pattern.c index c3214cb..8a2bda7 100644 --- a/libswfdec/swfdec_pattern.c +++ b/libswfdec/swfdec_pattern.c @@ -29,31 +29,7 @@ #include "swfdec_debug.h" #include "swfdec_decoder.h" #include "swfdec_image.h" - -/*** MORPHING ***/ - -static void -swfdec_matrix_morph (cairo_matrix_t *dest, const cairo_matrix_t *start, - const cairo_matrix_t *end, guint ratio) -{ - guint inv_ratio = 65535 - ratio; - g_assert (ratio < 65536); - - if (ratio == 0) { - *dest = *start; - return; - } - if (ratio == 65535) { - *dest = *end; - return; - } - dest->xx = (start->xx * inv_ratio + end->xx * ratio) / 65535; - dest->xy = (start->xy * inv_ratio + end->xy * ratio) / 65535; - dest->yy = (start->yy * inv_ratio + end->yy * ratio) / 65535; - dest->yx = (start->yx * inv_ratio + end->yx * ratio) / 65535; - dest->x0 = (start->x0 * inv_ratio + end->x0 * ratio) / 65535; - dest->y0 = (start->y0 * inv_ratio + end->y0 * ratio) / 65535; -} +#include "swfdec_stroke.h" /*** PATTERN ***/ @@ -71,131 +47,6 @@ swfdec_pattern_init (SwfdecPattern *patt cairo_matrix_init_identity (&pattern->end_transform); } -/*** STROKE PATTERN ***/ - -#define MAX_ALIGN 10 - -typedef struct _SwfdecStrokePattern SwfdecStrokePattern; -typedef struct _SwfdecStrokePatternClass SwfdecStrokePatternClass; - -#define SWFDEC_TYPE_STROKE_PATTERN (swfdec_stroke_pattern_get_type()) -#define SWFDEC_IS_STROKE_PATTERN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_STROKE_PATTERN)) -#define SWFDEC_IS_STROKE_PATTERN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_STROKE_PATTERN)) -#define SWFDEC_STROKE_PATTERN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_STROKE_PATTERN, SwfdecStrokePattern)) -#define SWFDEC_STROKE_PATTERN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_STROKE_PATTERN, SwfdecStrokePatternClass)) -#define SWFDEC_STROKE_PATTERN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_STROKE_PATTERN, SwfdecStrokePatternClass)) - -struct _SwfdecStrokePattern -{ - SwfdecPattern pattern; - - guint start_width; /* width of line */ - SwfdecColor start_color; /* color to paint with */ - guint end_width; /* width of line */ - SwfdecColor end_color; /* color to paint with */ -}; - -struct _SwfdecStrokePatternClass -{ - SwfdecPatternClass pattern_class; -}; - -G_DEFINE_TYPE (SwfdecStrokePattern, swfdec_stroke_pattern, SWFDEC_TYPE_PATTERN); - -static void -swfdec_pattern_append_path_snapped (cairo_t *cr, const cairo_path_t *path) -{ - cairo_path_data_t *data; - double x, y; - int i; - - data = path->data; - for (i = 0; i < path->num_data; i++) { - switch (data[i].header.type) { - case CAIRO_PATH_MOVE_TO: - i++; - x = data[i].point.x; - y = data[i].point.y; - cairo_user_to_device (cr, &x, &y); - x = rint (x - 0.5) + 0.5; - y = rint (y - 0.5) + 0.5; - cairo_device_to_user (cr, &x, &y); - /* FIXME: currently we need to clamp this due to extents */ - x = CLAMP (x, data[i].point.x - MAX_ALIGN, data[i].point.x + MAX_ALIGN); - y = CLAMP (y, data[i].point.y - MAX_ALIGN, data[i].point.y + MAX_ALIGN); - cairo_move_to (cr, x, y); - break; - case CAIRO_PATH_LINE_TO: - i++; - x = data[i].point.x; - y = data[i].point.y; - cairo_user_to_device (cr, &x, &y); - x = rint (x - 0.5) + 0.5; - y = rint (y - 0.5) + 0.5; - cairo_device_to_user (cr, &x, &y); - /* FIXME: currently we need to clamp this due to extents */ - x = CLAMP (x, data[i].point.x - MAX_ALIGN, data[i].point.x + MAX_ALIGN); - y = CLAMP (y, data[i].point.y - MAX_ALIGN, data[i].point.y + MAX_ALIGN); - cairo_line_to (cr, x, y); - break; - case CAIRO_PATH_CURVE_TO: - x = data[i+3].point.x; - y = data[i+3].point.y; - cairo_user_to_device (cr, &x, &y); - x = rint (x - 0.5) + 0.5; - y = rint (y - 0.5) + 0.5; - cairo_device_to_user (cr, &x, &y); - /* FIXME: currently we need to clamp this due to extents */ - x = CLAMP (x, data[i+3].point.x - MAX_ALIGN, data[i+3].point.x + MAX_ALIGN); - y = CLAMP (y, data[i+3].point.y - MAX_ALIGN, data[i+3].point.y + MAX_ALIGN); - cairo_curve_to (cr, data[i+1].point.x, data[i+1].point.y, - data[i+2].point.x, data[i+2].point.y, x, y); - i += 3; - break; - case CAIRO_PATH_CLOSE_PATH: - /* doesn't exist in our code */ - default: - g_assert_not_reached (); - } - } -} - -static void -swfdec_stroke_pattern_paint (SwfdecPattern *pattern, cairo_t *cr, const cairo_path_t *path, - const SwfdecColorTransform *trans, guint ratio) -{ - SwfdecColor color; - double width; - SwfdecStrokePattern *stroke = SWFDEC_STROKE_PATTERN (pattern); - - swfdec_pattern_append_path_snapped (cr, path); - color = swfdec_color_apply_morph (stroke->start_color, stroke->end_color, ratio); - color = swfdec_color_apply_transform (color, trans); - swfdec_color_set_source (cr, color); - if (ratio == 0) { - width = stroke->start_width; - } else if (ratio == 65535) { - width = stroke->end_width; - } else { - width = (stroke->start_width * (65535 - ratio) + stroke->end_width * ratio) / 65535; - } - if (width < SWFDEC_TWIPS_SCALE_FACTOR) - width = SWFDEC_TWIPS_SCALE_FACTOR; - cairo_set_line_width (cr, width); - cairo_stroke (cr); -} - -static void -swfdec_stroke_pattern_class_init (SwfdecStrokePatternClass *klass) -{ - SWFDEC_PATTERN_CLASS (klass)->paint = swfdec_stroke_pattern_paint; -} - -static void -swfdec_stroke_pattern_init (SwfdecStrokePattern *pattern) -{ -} - /*** COLOR PATTERN ***/ typedef struct _SwfdecColorPattern SwfdecColorPattern; @@ -663,63 +514,14 @@ 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 (pattern)) { - SwfdecStrokePattern *line = SWFDEC_STROKE_PATTERN (pattern); + } 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)); } } -SwfdecPattern * -swfdec_pattern_parse_stroke (SwfdecSwfDecoder *dec, gboolean rgba) -{ - SwfdecBits *bits = &dec->b; - SwfdecStrokePattern *pattern = g_object_new (SWFDEC_TYPE_STROKE_PATTERN, NULL); - - pattern->start_width = swfdec_bits_get_u16 (bits); - pattern->end_width = pattern->start_width; - if (rgba) { - pattern->start_color = swfdec_bits_get_rgba (bits); - } else { - pattern->start_color = swfdec_bits_get_color (bits); - } - pattern->end_color = pattern->start_color; - SWFDEC_LOG ("new stroke pattern: width %u color %08x", pattern->start_width, pattern->start_color); - - return SWFDEC_PATTERN (pattern); -} - -SwfdecPattern * -swfdec_pattern_parse_morph_stroke (SwfdecSwfDecoder *dec) -{ - SwfdecBits *bits = &dec->b; - SwfdecStrokePattern *pattern = g_object_new (SWFDEC_TYPE_STROKE_PATTERN, NULL); - - pattern->start_width = swfdec_bits_get_u16 (bits); - pattern->end_width = swfdec_bits_get_u16 (bits); - pattern->start_color = swfdec_bits_get_rgba (bits); - pattern->end_color = swfdec_bits_get_rgba (bits); - SWFDEC_LOG ("new stroke pattern: width %u => %u color %08X => %08X", - pattern->start_width, pattern->end_width, - pattern->start_color, pattern->end_color); - - return SWFDEC_PATTERN (pattern); -} - -SwfdecPattern * -swfdec_pattern_new_stroke (guint width, SwfdecColor color) -{ - SwfdecStrokePattern *pattern = g_object_new (SWFDEC_TYPE_STROKE_PATTERN, NULL); - - pattern->start_width = width; - pattern->end_width = width; - pattern->start_color = color; - pattern->end_color = color; - - return SWFDEC_PATTERN (pattern); -} - static void swfdec_path_get_extents (const cairo_path_t *path, SwfdecRect *extents, double line_width) { @@ -791,11 +593,13 @@ swfdec_path_get_extents (const cairo_pat #undef ADD_POINT } +#define MAX_ALIGN 10 + void swfdec_pattern_get_path_extents (SwfdecPattern *pattern, const cairo_path_t *path, SwfdecRect *extents) { - if (SWFDEC_IS_STROKE_PATTERN (pattern)) { - SwfdecStrokePattern *stroke = SWFDEC_STROKE_PATTERN (pattern); + if (SWFDEC_IS_STROKE (pattern)) { + SwfdecStroke *stroke = SWFDEC_STROKE (pattern); double line_width = MAX (stroke->start_width, stroke->end_width); line_width = MAX (line_width, SWFDEC_TWIPS_SCALE_FACTOR); swfdec_path_get_extents (path, extents, line_width / 2); diff --git a/libswfdec/swfdec_pattern.h b/libswfdec/swfdec_pattern.h index e2112da..7ea97f5 100644 --- a/libswfdec/swfdec_pattern.h +++ b/libswfdec/swfdec_pattern.h @@ -59,14 +59,9 @@ struct _SwfdecPatternClass GType swfdec_pattern_get_type (void); SwfdecPattern * swfdec_pattern_new_color (SwfdecColor color); -SwfdecPattern * swfdec_pattern_new_stroke (guint width, - SwfdecColor color); SwfdecPattern * swfdec_pattern_parse (SwfdecSwfDecoder * dec, gboolean rgba); -SwfdecPattern * swfdec_pattern_parse_stroke (SwfdecSwfDecoder * dec, - gboolean rgba); SwfdecPattern * swfdec_pattern_parse_morph (SwfdecSwfDecoder * dec); -SwfdecPattern * swfdec_pattern_parse_morph_stroke (SwfdecSwfDecoder * dec); void swfdec_pattern_paint (SwfdecPattern * pattern, cairo_t * cr, diff --git a/libswfdec/swfdec_shape.c b/libswfdec/swfdec_shape.c index 49dfa7b..65a5166 100644 --- a/libswfdec/swfdec_shape.c +++ b/libswfdec/swfdec_shape.c @@ -1,7 +1,7 @@ /* Swfdec * Copyright (C) 2003-2006 David Schleef <ds@schleef.org> * 2005-2006 Eric Anholt <eric@anholt.net> - * 2006 Benjamin Otte <otte@gnome.org> + * 2006-2007 Benjamin Otte <otte@gnome.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -29,6 +29,7 @@ #include "swfdec_shape.h" #include "swfdec.h" #include "swfdec_debug.h" +#include "swfdec_stroke.h" G_DEFINE_TYPE (SwfdecShape, swfdec_shape, SWFDEC_TYPE_GRAPHIC) @@ -367,13 +368,13 @@ parse_rgba (SwfdecSwfDecoder * s) static SwfdecPattern * parse_stroke_rgb (SwfdecSwfDecoder * s) { - return swfdec_pattern_parse_stroke (s, FALSE); + return swfdec_stroke_parse (s, FALSE); } static SwfdecPattern * parse_stroke_rgba (SwfdecSwfDecoder * s) { - return swfdec_pattern_parse_stroke (s, TRUE); + return swfdec_stroke_parse (s, TRUE); } int @@ -936,7 +937,7 @@ swfdec_morph_shape_get_recs (SwfdecSwfDe switch (start_type) { case SWFDEC_SHAPE_TYPE_CHANGE: start_path = swfdec_shape_parse_change (s, shape, start_path_array, start_path, &start_x, &start_y, - swfdec_pattern_parse_morph, swfdec_pattern_parse_morph_stroke); + swfdec_pattern_parse_morph, swfdec_stroke_parse_morph); end_path = swfdec_morph_shape_do_change (end_bits, start_path, morph, end_path_array, end_path, &end_x, &end_y); break; case SWFDEC_SHAPE_TYPE_LINE: @@ -1023,7 +1024,7 @@ tag_define_morph_shape (SwfdecSwfDecoder bits->end = end_bits.ptr; swfdec_shape_add_styles (s, SWFDEC_SHAPE (morph), - swfdec_pattern_parse_morph, swfdec_pattern_parse_morph_stroke); + swfdec_pattern_parse_morph, swfdec_stroke_parse_morph); morph->n_fill_bits = swfdec_bits_getbits (&end_bits, 4); morph->n_line_bits = swfdec_bits_getbits (&end_bits, 4); diff --git a/libswfdec/swfdec_stroke.c b/libswfdec/swfdec_stroke.c new file mode 100644 index 0000000..7239479 --- /dev/null +++ b/libswfdec/swfdec_stroke.c @@ -0,0 +1,210 @@ +/* Swfdec + * Copyright (C) 2006-2007 Benjamin Otte <otte@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_stroke.h" +#include "swfdec_bits.h" +#include "swfdec_color.h" +#include "swfdec_debug.h" +#include "swfdec_decoder.h" +#include "swfdec_image.h" + +#define MAX_ALIGN 10 + +G_DEFINE_TYPE (SwfdecStroke, swfdec_stroke, SWFDEC_TYPE_PATTERN); + +static void +swfdec_stroke_append_path_snapped (cairo_t *cr, const cairo_path_t *path) +{ + cairo_path_data_t *data; + double x, y; + int i; + + data = path->data; + for (i = 0; i < path->num_data; i++) { + switch (data[i].header.type) { + case CAIRO_PATH_MOVE_TO: + i++; + x = data[i].point.x; + y = data[i].point.y; + cairo_user_to_device (cr, &x, &y); + x = rint (x - 0.5) + 0.5; + y = rint (y - 0.5) + 0.5; + cairo_device_to_user (cr, &x, &y); + /* FIXME: currently we need to clamp this due to extents */ + x = CLAMP (x, data[i].point.x - MAX_ALIGN, data[i].point.x + MAX_ALIGN); + y = CLAMP (y, data[i].point.y - MAX_ALIGN, data[i].point.y + MAX_ALIGN); + cairo_move_to (cr, x, y); + break; + case CAIRO_PATH_LINE_TO: + i++; + x = data[i].point.x; + y = data[i].point.y; + cairo_user_to_device (cr, &x, &y); + x = rint (x - 0.5) + 0.5; + y = rint (y - 0.5) + 0.5; + cairo_device_to_user (cr, &x, &y); + /* FIXME: currently we need to clamp this due to extents */ + x = CLAMP (x, data[i].point.x - MAX_ALIGN, data[i].point.x + MAX_ALIGN); + y = CLAMP (y, data[i].point.y - MAX_ALIGN, data[i].point.y + MAX_ALIGN); + cairo_line_to (cr, x, y); + break; + case CAIRO_PATH_CURVE_TO: + x = data[i+3].point.x; + y = data[i+3].point.y; + cairo_user_to_device (cr, &x, &y); + x = rint (x - 0.5) + 0.5; + y = rint (y - 0.5) + 0.5; + cairo_device_to_user (cr, &x, &y); + /* FIXME: currently we need to clamp this due to extents */ + x = CLAMP (x, data[i+3].point.x - MAX_ALIGN, data[i+3].point.x + MAX_ALIGN); + y = CLAMP (y, data[i+3].point.y - MAX_ALIGN, data[i+3].point.y + MAX_ALIGN); + cairo_curve_to (cr, data[i+1].point.x, data[i+1].point.y, + data[i+2].point.x, data[i+2].point.y, x, y); + i += 3; + break; + case CAIRO_PATH_CLOSE_PATH: + /* doesn't exist in our code */ + default: + g_assert_not_reached (); + } + } +} + +static void +swfdec_stroke_paint (SwfdecPattern *pattern, 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); + color = swfdec_color_apply_transform (color, trans); + swfdec_color_set_source (cr, color); + if (ratio == 0) { + width = stroke->start_width; + } else if (ratio == 65535) { + width = stroke->end_width; + } else { + width = (stroke->start_width * (65535 - ratio) + stroke->end_width * ratio) / 65535; + } + if (width < SWFDEC_TWIPS_SCALE_FACTOR) + width = SWFDEC_TWIPS_SCALE_FACTOR; + cairo_set_line_width (cr, width); + cairo_stroke (cr); +} + +static void +swfdec_stroke_class_init (SwfdecStrokeClass *klass) +{ + SWFDEC_PATTERN_CLASS (klass)->paint = swfdec_stroke_paint; +} + +static void +swfdec_stroke_init (SwfdecStroke *stroke) +{ +} + +/*** EXPORTED API ***/ + +SwfdecPattern * +swfdec_stroke_parse (SwfdecSwfDecoder *dec, gboolean rgba) +{ + 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->end_color = stroke->start_color; + SWFDEC_LOG ("new stroke stroke: width %u color %08x", stroke->start_width, stroke->start_color); + + return SWFDEC_PATTERN (stroke); +} + +SwfdecPattern * +swfdec_stroke_parse_morph (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 = swfdec_bits_get_u16 (bits); + stroke->start_color = swfdec_bits_get_rgba (bits); + stroke->end_color = swfdec_bits_get_rgba (bits); + SWFDEC_LOG ("new stroke stroke: width %u => %u color %08X => %08X", + stroke->start_width, stroke->end_width, + stroke->start_color, stroke->end_color); + + return SWFDEC_PATTERN (stroke); +} + +SwfdecPattern * +swfdec_stroke_new (guint width, SwfdecColor color) +{ + SwfdecStroke *stroke = g_object_new (SWFDEC_TYPE_STROKE, NULL); + + stroke->start_width = width; + stroke->end_width = width; + stroke->start_color = color; + stroke->end_color = color; + + return SWFDEC_PATTERN (stroke); +} + +static SwfdecPattern * +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); +} + +SwfdecPattern * +swfdec_stroke_parse_extended (SwfdecSwfDecoder *dec, SwfdecPattern *fill_styles, + guint n_fill_styles) +{ + 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); +} + +SwfdecPattern * +swfdec_stroke_parse_morph_extended (SwfdecSwfDecoder *dec, SwfdecPattern *fill_styles, + guint n_fill_styles) +{ + 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); +} diff --git a/libswfdec/swfdec_stroke.h b/libswfdec/swfdec_stroke.h new file mode 100644 index 0000000..51dbf07 --- /dev/null +++ b/libswfdec/swfdec_stroke.h @@ -0,0 +1,69 @@ +/* Swfdec + * Copyright (C) 2006-2007 Benjamin Otte <otte@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_STROKE_H_ +#define _SWFDEC_STROKE_H_ + +#include <libswfdec/swfdec_pattern.h> + +G_BEGIN_DECLS + +typedef struct _SwfdecStroke SwfdecStroke; +typedef struct _SwfdecStrokeClass SwfdecStrokeClass; + +#define SWFDEC_TYPE_STROKE (swfdec_stroke_get_type()) +#define SWFDEC_IS_STROKE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_STROKE)) +#define SWFDEC_IS_STROKE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_STROKE)) +#define SWFDEC_STROKE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_STROKE, SwfdecStroke)) +#define SWFDEC_STROKE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_STROKE, SwfdecStrokeClass)) +#define SWFDEC_STROKE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_STROKE, SwfdecStrokeClass)) + +struct _SwfdecStroke +{ + SwfdecPattern pattern; + + guint start_width; /* width of line */ + SwfdecColor start_color; /* color to paint with */ + guint end_width; /* width of line */ + SwfdecColor end_color; /* color to paint with */ +}; + +struct _SwfdecStrokeClass +{ + SwfdecPatternClass pattern_class; +}; + +GType swfdec_stroke_get_type (void); + +SwfdecPattern * swfdec_stroke_new (guint width, + SwfdecColor color); +SwfdecPattern * swfdec_stroke_parse (SwfdecSwfDecoder * dec, + gboolean rgba); +SwfdecPattern * 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 + (SwfdecSwfDecoder * dec, + SwfdecPattern * fill_styles, + guint n_fill_styles); + + +G_END_DECLS +#endif diff-tree ffd9d1fab29d4f256c59b597aac0a11ee1f58317 (from 2fd1d7c21735f01ac9df501dbd42b47da0a5a868) Author: Benjamin Otte <otte@gnome.org> Date: Fri Apr 13 10:04:53 2007 +0200 use current scale, not user-set one diff --git a/player/swfdec_debug_widget.c b/player/swfdec_debug_widget.c index 4c7ebcc..953b918 100644 --- a/player/swfdec_debug_widget.c +++ b/player/swfdec_debug_widget.c @@ -60,7 +60,7 @@ swfdec_debug_widget_button_press (GtkWid return FALSE; if (event->button == 1 && swfdec_gtk_widget_get_interactive (widget)) { - double scale = swfdec_gtk_widget_get_scale (widget); + double scale = swfdec_gtk_widget_get_current_scale (widget); SwfdecPlayer *player = swfdec_gtk_widget_get_player (widget); switch (event->type) { case GDK_BUTTON_PRESS: diff-tree 2fd1d7c21735f01ac9df501dbd42b47da0a5a868 (from 10622f56c90f64ad45f3c239bf0a0750590ad5e5) Author: Benjamin Otte <otte@gnome.org> Date: Fri Apr 13 10:04:23 2007 +0200 add copyright header diff --git a/libswfdec/swfdec_pattern.c b/libswfdec/swfdec_pattern.c index 4e32436..c3214cb 100644 --- a/libswfdec/swfdec_pattern.c +++ b/libswfdec/swfdec_pattern.c @@ -1,3 +1,22 @@ +/* Swfdec + * Copyright (C) 2006-2007 Benjamin Otte <otte@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 diff --git a/libswfdec/swfdec_pattern.h b/libswfdec/swfdec_pattern.h index b25dd56..e2112da 100644 --- a/libswfdec/swfdec_pattern.h +++ b/libswfdec/swfdec_pattern.h @@ -1,4 +1,21 @@ - +/* Swfdec + * Copyright (C) 2006-2007 Benjamin Otte <otte@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_PATTERN_H_ #define _SWFDEC_PATTERN_H_ diff-tree 10622f56c90f64ad45f3c239bf0a0750590ad5e5 (from d2d5d5c377fd595bd8fef79d9773c9ed78410fc1) Author: Benjamin Otte <otte@gnome.org> Date: Sun Apr 8 20:57:46 2007 +0200 Add initial support PlaceObject3 the code only reads the tag and aborts when parsing filters. diff --git a/libswfdec/swfdec_movie.h b/libswfdec/swfdec_movie.h index f1db624..5b56656 100644 --- a/libswfdec/swfdec_movie.h +++ b/libswfdec/swfdec_movie.h @@ -45,11 +45,12 @@ struct _SwfdecContent { SwfdecGraphic * graphic; /* object to display or NULL */ int depth; /* at which depth to display */ int clip_depth; /* clip depth of object */ - guint ratio; + guint ratio; cairo_matrix_t transform; SwfdecColorTransform color_transform; char * name; SwfdecEventList * events; + cairo_operator_t operator; /* operator to use when painting (aka blend mode) */ SwfdecContent * sequence; /* first element in sequence this content belongs to */ /* NB: the next two elements are only filled for the sequence leader */ @@ -57,7 +58,7 @@ struct _SwfdecContent { guint end; /* first frame that does not contain this sequence anymore */ }; #define SWFDEC_CONTENT_DEFAULT { NULL, -1, 0, 0, { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 }, \ - { 256, 0, 256, 0, 256, 0, 256, 0 }, NULL, NULL, NULL, 0, G_MAXUINT } + { 256, 0, 256, 0, 256, 0, 256, 0 }, NULL, NULL, CAIRO_OPERATOR_OVER, NULL, 0, G_MAXUINT } #define SWFDEC_TYPE_MOVIE (swfdec_movie_get_type()) #define SWFDEC_IS_MOVIE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_MOVIE)) diff --git a/libswfdec/swfdec_sprite.c b/libswfdec/swfdec_sprite.c index 7bb3629..86f7997 100644 --- a/libswfdec/swfdec_sprite.c +++ b/libswfdec/swfdec_sprite.c @@ -274,6 +274,7 @@ swfdec_content_new (int depth) cairo_matrix_init_identity (&content->transform); swfdec_color_transform_init_identity (&content->color_transform); content->depth = depth; + content->operator = CAIRO_OPERATOR_OVER; content->sequence = content; content->end = G_MAXUINT; return content; @@ -313,8 +314,14 @@ swfdec_contents_create (SwfdecSprite *sp return content; } -int -swfdec_spriteseg_place_object_2 (SwfdecSwfDecoder * s) +static cairo_operator_t +swfdec_sprite_convert_operator (guint operator) +{ + return CAIRO_OPERATOR_OVER; +} + +static int +swfdec_spriteseg_do_place_object (SwfdecSwfDecoder *s, unsigned int version) { SwfdecBits *bits = &s->b; int has_clip_actions; @@ -326,6 +333,9 @@ swfdec_spriteseg_place_object_2 (SwfdecS int has_character; int move; int depth; + int cache; + int has_blend_mode = 0; + int has_filter = 0; SwfdecContent *content; has_clip_actions = swfdec_bits_getbit (bits); @@ -349,6 +359,15 @@ swfdec_spriteseg_place_object_2 (SwfdecS 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 (" has filter = %d", has_filter); + SWFDEC_LOG (" has blend mode = %d", has_blend_mode); + } + /* new name always means new object */ content = swfdec_contents_create (s->parse_sprite, depth, move, has_character || has_name); if (has_character) { @@ -402,6 +421,19 @@ swfdec_spriteseg_place_object_2 (SwfdecS content->clip_depth = swfdec_bits_get_u16 (bits) - 16384; SWFDEC_LOG (" clip_depth = %d (=> %d)", content->clip_depth + 16384, content->clip_depth); } + if (has_filter) { + SWFDEC_ERROR ("filters aren't implemented, skipping PlaceObject tag!"); + g_hash_table_remove (s->parse_sprite->live_content, GUINT_TO_POINTER (content->depth)); + swfdec_content_free (content); + swfdec_sprite_remove_last_action (s->parse_sprite, + s->parse_sprite->parse_frame); + return SWFDEC_STATUS_OK; + } + if (has_blend_mode) { + guint operator = swfdec_bits_get_u8 (bits); + content->operator = swfdec_sprite_convert_operator (operator); + SWFDEC_ERROR (" operator = %u", operator); + } if (has_clip_actions) { int reserved, clip_event_flags, event_flags, key_code; char *script_name; @@ -450,6 +482,18 @@ swfdec_spriteseg_place_object_2 (SwfdecS } int +swfdec_spriteseg_place_object_2 (SwfdecSwfDecoder * s) +{ + return swfdec_spriteseg_do_place_object (s, 2); +} + +int +swfdec_spriteseg_place_object_3 (SwfdecSwfDecoder * s) +{ + return swfdec_spriteseg_do_place_object (s, 3); +} + +int swfdec_spriteseg_remove_object (SwfdecSwfDecoder * s) { int depth; diff --git a/libswfdec/swfdec_sprite.h b/libswfdec/swfdec_sprite.h index 1812302..43aa4d1 100644 --- a/libswfdec/swfdec_sprite.h +++ b/libswfdec/swfdec_sprite.h @@ -102,6 +102,7 @@ void swfdec_content_free (SwfdecContent int tag_show_frame (SwfdecSwfDecoder * s); int tag_func_set_background_color (SwfdecSwfDecoder * s); int swfdec_spriteseg_place_object_2 (SwfdecSwfDecoder * s); +int swfdec_spriteseg_place_object_3 (SwfdecSwfDecoder * s); int swfdec_spriteseg_remove_object (SwfdecSwfDecoder * s); int swfdec_spriteseg_remove_object_2 (SwfdecSwfDecoder * s); diff --git a/libswfdec/swfdec_tag.c b/libswfdec/swfdec_tag.c index c2f8343..c7373eb 100644 --- a/libswfdec/swfdec_tag.c +++ b/libswfdec/swfdec_tag.c @@ -558,7 +558,7 @@ static struct tag_func_struct tag_funcs[ [SWFDEC_TAG_SCRIPTLIMITS] = {"ScriptLimits", NULL, 0}, [SWFDEC_TAG_SETTABINDEX] = {"SetTabIndex", NULL, 0}, [SWFDEC_TAG_FILEATTRIBUTES] = {"FileAttributes", tag_func_file_attributes, 0}, - [SWFDEC_TAG_PLACEOBJECT3] = {"PlaceObject3", NULL, 0}, + [SWFDEC_TAG_PLACEOBJECT3] = {"PlaceObject3", swfdec_spriteseg_place_object_3, SPRITE}, [SWFDEC_TAG_IMPORTASSETS2] = {"ImportAssets2", NULL, 0}, [SWFDEC_TAG_DEFINEFONTALIGNZONES] = {"DefineFontAlignZones", NULL, 0}, [SWFDEC_TAG_CSMTEXTSETTINGS] = {"CSMTextSettings", NULL, 0},
Reasonably Related 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
- 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
- libswfdec-gtk/swfdec_playback_alsa.c libswfdec/swfdec_audio_event.h libswfdec/swfdec_audio_flv.h libswfdec/swfdec_audio_stream.h libswfdec/swfdec_bits.c libswfdec/swfdec_bits.h libswfdec/swfdec_buffer.c libswfdec/swfdec_buffer.h libswfdec/swfdec_cache.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