Benjamin Otte
2007-Feb-15 08:29 UTC
[Swfdec] 8 commits - libswfdec/swfdec_bits.h libswfdec/swfdec_font.c libswfdec/swfdec_font.h libswfdec/swfdec_loader.c libswfdec/swfdec_loader_internal.h libswfdec/swfdec_tag.c libswfdec/swfdec_text.c libswfdec/swfdec_text.h test/swfedit_token.c test/various
libswfdec/swfdec_bits.h | 2 libswfdec/swfdec_font.c | 289 ++++++++++++++++++++++++++++++++++++- libswfdec/swfdec_font.h | 16 +- libswfdec/swfdec_loader.c | 144 ++++++++++++++++++ libswfdec/swfdec_loader_internal.h | 9 + libswfdec/swfdec_tag.c | 158 -------------------- libswfdec/swfdec_text.c | 12 + libswfdec/swfdec_text.h | 2 test/swfedit_token.c | 5 test/various/.gitignore | 1 test/various/Makefile.am | 6 test/various/ringbuffer.c | 19 ++ test/various/urlencode.c | 109 +++++++++++++ 13 files changed, 598 insertions(+), 174 deletions(-) New commits: diff-tree 5a3b6dc3f4091163b071a50172bfb21de3aa31fd (from 42c7ba48f3741051f0c5dcab9590a3db0c7b23c7) Author: Benjamin Otte <otte@gnome.org> Date: Thu Feb 15 17:25:03 2007 +0100 Add testing for urlencode functions diff --git a/test/various/.gitignore b/test/various/.gitignore index 4dd479e..ce5fcf8 100644 --- a/test/various/.gitignore +++ b/test/various/.gitignore @@ -9,3 +9,4 @@ Makefile.in *.o ringbuffer +urlencode diff --git a/test/various/Makefile.am b/test/various/Makefile.am index b7dac49..b16762f 100644 --- a/test/various/Makefile.am +++ b/test/various/Makefile.am @@ -1,9 +1,11 @@ -check_PROGRAMS = ringbuffer +check_PROGRAMS = ringbuffer urlencode TESTS = $(check_PROGRAMS) ringbuffer_SOURCES = ringbuffer.c - ringbuffer_CFLAGS = $(GLOBAL_CFLAGS) $(SWF_CFLAGS) $(CAIRO_CFLAGS) ringbuffer_LDFLAGS = $(SWF_LIBS) $(CAIRO_LIBS) +urlencode_SOURCES = urlencode.c +urlencode_CFLAGS = $(GLOBAL_CFLAGS) $(SWF_CFLAGS) $(CAIRO_CFLAGS) +urlencode_LDFLAGS = $(SWF_LIBS) $(CAIRO_LIBS) diff --git a/test/various/urlencode.c b/test/various/urlencode.c new file mode 100644 index 0000000..6555675 --- /dev/null +++ b/test/various/urlencode.c @@ -0,0 +1,109 @@ +/* Swfdec + * Copyright (C) 2006 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 "libswfdec/swfdec_loader_internal.h" + +typedef struct { + char * encoded; + char * names[10]; + char * values[10]; + guint n_props; +} Test; +Test tests[] = { + { "a=b", { "a" }, { "b" }, 1 }, + { "a=b&c=d", { "a", "c" }, { "b", "d" }, 2 }, + { "owned=Your+Mom", { "owned" }, { "Your Mom" }, 1 } +}; + +#define ERROR(...) G_STMT_START { \ + g_printerr ("ERROR (line %u): ", __LINE__); \ + g_printerr (__VA_ARGS__); \ + g_printerr ("\n"); \ + errors++; \ +}G_STMT_END + +static guint +run_test_encode (Test *test) +{ + GString *string; + guint i, errors = 0; + + string = g_string_new (""); + for (i = 0; i < test->n_props; i++) { + swfdec_string_append_urlencoded (string, test->names[i], test->values[i]); + } + if (!g_str_equal (test->encoded, string->str)) { + ERROR ("encoded string is \"%s\", but should be \"%s\"", string->str, test->encoded); + } + g_string_free (string, TRUE); + return errors; +} + +static guint +run_test_decode (Test *test) +{ + guint i, errors = 0; + char *name, *value; + const char *s = test->encoded; + + for (i = 0; i < test->n_props; i++) { + if (*s == '\0') { + ERROR ("string only contains %u properties, but should contain %u", i, test->n_props); + break; + } + if (i > 0) { + if (*s != '&') { + ERROR ("properties not delimited by &"); + } + s++; + } + if (!swfdec_urldecode_one (s, &name, &value, &s)) { + ERROR ("could not decode property %u", i); + continue; + } + if (!g_str_equal (name, test->names[i])) { + ERROR ("names don't match: is %s, should be %s", name, test->names[i]); + } + if (!g_str_equal (value, test->values[i])) { + ERROR ("names don't match: is %s, should be %s", value, test->values[i]); + } + g_free (name); + g_free (value); + } + return errors; +} + +int +main (int argc, char **argv) +{ + guint i, errors = 0; + + for (i = 0; i < G_N_ELEMENTS (tests); i++) { + errors += run_test_encode (&tests[i]); + errors += run_test_decode (&tests[i]); + } + + g_print ("TOTAL ERRORS: %u\n", errors); + return errors; +} + diff-tree 42c7ba48f3741051f0c5dcab9590a3db0c7b23c7 (from 0c8821a7ed95734d5d5b29e2e5f488e4e5faef13) Author: Benjamin Otte <otte@gnome.org> Date: Thu Feb 15 17:23:57 2007 +0100 Add code to convert to/from application/x-www-form-urlencoded mime type diff --git a/libswfdec/swfdec_loader.c b/libswfdec/swfdec_loader.c index 756e174..70027be 100644 --- a/libswfdec/swfdec_loader.c +++ b/libswfdec/swfdec_loader.c @@ -393,3 +393,147 @@ swfdec_loader_get_filename (SwfdecLoader return ret; } +static void +swfdec_urlencode_append_string (GString *str, const char *s) +{ + g_assert (s != NULL); + while (*s) { + if (g_ascii_isalnum (*s)) + g_string_append_c (str, *s); + else if (*s == ' ') + g_string_append_c (str, '+'); + else + g_string_append_printf (str, "%%%02X", (guint) *s); + s++; + } +} + +static char * +swfdec_urldecode_one_string (const char *s, const char **out) +{ + GString *ret = g_string_new (""); + + while (*s) { + if (g_ascii_isalnum (*s)) { + g_string_append_c (ret, *s); + } else if (*s == '+') { + g_string_append_c (ret, ' '); + } else if (*s == '%') { + guint byte; + s++; + if (*s >= '0' && *s <= '9') { + byte = *s - '0'; + } else if (*s >= 'A' && *s <= 'F') { + byte = *s - 'A' + 10; + } else if (*s >= 'a' && *s <= 'f') { + byte = *s - 'a' + 10; + } else { + g_string_free (ret, TRUE); + *out = s; + return NULL; + } + byte *= 16; + s++; + if (*s >= '0' && *s <= '9') { + byte += *s - '0'; + } else if (*s >= 'A' && *s <= 'F') { + byte += *s - 'A' + 10; + } else if (*s >= 'a' && *s <= 'f') { + byte += *s - 'a' + 10; + } else { + g_string_free (ret, TRUE); + *out = s; + return NULL; + } + g_assert (byte < 256); + g_string_append_c (ret, byte); + } else { + break; + } + s++; + } + *out = s; + return g_string_free (ret, FALSE); +} + +/** + * swfdec_string_append_urlencoded: + * @str: a #GString + * @name: name of the property to append + * @value: value of property to append or NULL for empty + * + * Appends a name/value pair in encoded as 'application/x-www-form-urlencoded' + * to the given @str + **/ +void +swfdec_string_append_urlencoded (GString *str, char *name, char *value) +{ + g_return_if_fail (str != NULL); + g_return_if_fail (name != NULL); + + if (str->len > 0) + g_string_append_c (str, '&'); + swfdec_urlencode_append_string (str, name); + g_string_append_c (str, '='); + if (value) + swfdec_urlencode_append_string (str, value); +} + +/** + * swfdec_urldecode_one: + * @string: string in 'application/x-www-form-urlencoded' form + * @name: pointer that will hold a newly allocated string for the name of the + * parsed property or NULL + * @value: pointer that will hold a newly allocated string containing the + * value of the parsed property or NULL + * @end: If not %NULL, on success, pointer to the first byte in @s that was + * not parsed. On failure it will point to the byte causing the problem + * + * Tries to parse the given @string into a name/value pair, assuming the string + * is in the application/x-www-form-urlencoded format. If the parsing succeeds, + * @name and @value will contain the parsed values and %TRUE will be returned. + * + * Returns: %TRUE if parsing the property succeeded, %FALSE otherwise + */ +gboolean +swfdec_urldecode_one (const char *string, char **name, char **value, const char **end) +{ + char *name_str, *value_str; + + g_return_val_if_fail (string != NULL, FALSE); + + name_str = swfdec_urldecode_one_string (string, &string); + if (name_str == NULL) + goto fail; + if (*string != '=') { + g_free (name_str); + goto fail; + } + string++; + value_str = swfdec_urldecode_one_string (string, &string); + if (value_str == NULL) { + g_free (name_str); + goto fail; + } + + if (name) + *name = name_str; + else + g_free (name_str); + if (value) + *value = value_str; + else + g_free (value_str); + if (end) + *end = string; + return TRUE; + +fail: + if (name) + *name = NULL; + if (value) + *value = NULL; + if (end) + *end = string; + return FALSE; +} diff --git a/libswfdec/swfdec_loader_internal.h b/libswfdec/swfdec_loader_internal.h index c7f595d..8f9a3db 100644 --- a/libswfdec/swfdec_loader_internal.h +++ b/libswfdec/swfdec_loader_internal.h @@ -32,7 +32,14 @@ void swfdec_loader_parse (SwfdecLoade void swfdec_loader_parse_internal (SwfdecLoader * loader); void swfdec_loader_set_target (SwfdecLoader * loader, SwfdecLoaderTarget * target); - + +gboolean swfdec_urldecode_one (const char * string, + char ** name, + char ** value, + const char ** end); +void swfdec_string_append_urlencoded (GString * str, + char * name, + char * value); G_END_DECLS #endif diff-tree 0c8821a7ed95734d5d5b29e2e5f488e4e5faef13 (from b5b06e40f10336b5bc057d0fad626a88e2ff8fb2) Author: Benjamin Otte <otte@gnome.org> Date: Thu Feb 15 16:58:10 2007 +0100 add copyright header diff --git a/test/various/ringbuffer.c b/test/various/ringbuffer.c index 6f48ff3..9fa3008 100644 --- a/test/various/ringbuffer.c +++ b/test/various/ringbuffer.c @@ -1,3 +1,22 @@ +/* Swfdec + * Copyright (C) 2006 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-tree b5b06e40f10336b5bc057d0fad626a88e2ff8fb2 (from 3b4d3b8ffde2921b618208ff0fed436ec92817ba) Author: Benjamin Otte <otte@gnome.org> Date: Thu Feb 15 15:49:18 2007 +0100 Implement DefineFont3 This includes some changes for the Glyph em square scale factor, which is 1024 in DefineFont and DefineFont2, but 20*1024 in DefineFont3 diff --git a/libswfdec/swfdec_bits.h b/libswfdec/swfdec_bits.h index 0dd1dd9..d568dd8 100644 --- a/libswfdec/swfdec_bits.h +++ b/libswfdec/swfdec_bits.h @@ -26,8 +26,6 @@ #include <libswfdec/swfdec_color.h> #include <libswfdec/swfdec_buffer.h> -#define SWFDEC_TEXT_SCALE_FACTOR (1024.0) - typedef struct _SwfdecBits SwfdecBits; struct _SwfdecBits diff --git a/libswfdec/swfdec_font.c b/libswfdec/swfdec_font.c index d70a881..ac64c22 100644 --- a/libswfdec/swfdec_font.c +++ b/libswfdec/swfdec_font.c @@ -206,6 +206,7 @@ tag_func_define_font (SwfdecSwfDecoder * font = swfdec_swf_decoder_create_character (s, id, SWFDEC_TYPE_FONT); if (!font) return SWFDEC_STATUS_OK; + font->scale_factor = SWFDEC_TEXT_SCALE_FACTOR; offsets = s->b; n_glyphs = swfdec_bits_get_u16 (&s->b); @@ -234,16 +235,22 @@ tag_func_define_font (SwfdecSwfDecoder * } static void -get_kerning_record (SwfdecBits * bits, int wide_codes) +swfdec_font_parse_kerning_table (SwfdecSwfDecoder *s, SwfdecFont *font, gboolean wide_codes) { - if (wide_codes) { - swfdec_bits_get_u16 (bits); - swfdec_bits_get_u16 (bits); - } else { - swfdec_bits_get_u8 (bits); - swfdec_bits_get_u8 (bits); + SwfdecBits *bits; + guint n_kernings, i; + + n_kernings = swfdec_bits_get_u16 (bits); + for (i = 0; i < n_kernings; i++) { + if (wide_codes) { + swfdec_bits_get_u16 (bits); + swfdec_bits_get_u16 (bits); + } else { + swfdec_bits_get_u8 (bits); + swfdec_bits_get_u8 (bits); + } + swfdec_bits_get_s16 (bits); } - swfdec_bits_get_s16 (bits); } int @@ -270,13 +277,13 @@ tag_func_define_font_2 (SwfdecSwfDecoder int font_ascent; int font_descent; int font_leading; - int kerning_count; int i; id = swfdec_bits_get_u16 (bits); font = swfdec_swf_decoder_create_character (s, id, SWFDEC_TYPE_FONT); if (!font) return SWFDEC_STATUS_OK; + font->scale_factor = SWFDEC_TEXT_SCALE_FACTOR; has_layout = swfdec_bits_getbit (bits); shift_jis = swfdec_bits_getbit (bits); @@ -335,12 +342,7 @@ tag_func_define_font_2 (SwfdecSwfDecoder for (i = 0; i < n_glyphs; i++) { swfdec_bits_get_rect (bits, &rect); } - kerning_count = swfdec_bits_get_u16 (bits); - if (0) { - for (i = 0; i < kerning_count; i++) { - get_kerning_record (bits, wide_codes); - } - } + swfdec_font_parse_kerning_table (s, font, wide_codes); } return SWFDEC_STATUS_OK; @@ -349,5 +351,92 @@ tag_func_define_font_2 (SwfdecSwfDecoder int tag_func_define_font_3 (SwfdecSwfDecoder * s) { + SwfdecBits offsets, *bits = &s->b; + SwfdecFont *font; + SwfdecLanguage language; + guint i, id, len, n_glyphs, offset, next_offset; + gboolean layout, shift_jis, ansi, wide_offsets, wide_codes; + + id = swfdec_bits_get_u16 (bits); + font = swfdec_swf_decoder_create_character (s, id, SWFDEC_TYPE_FONT); + if (!font) + return SWFDEC_STATUS_OK; + SWFDEC_LOG (" id = %u", id); + font->scale_factor = 20 * SWFDEC_TEXT_SCALE_FACTOR; + + layout = swfdec_bits_getbit (bits); + SWFDEC_LOG (" layout = %d", layout); + shift_jis = swfdec_bits_getbit (bits); + SWFDEC_LOG (" JIS = %d", shift_jis); + font->small = swfdec_bits_getbit (bits); + SWFDEC_LOG (" small = %d", font->small); + ansi = swfdec_bits_getbit (bits); + SWFDEC_LOG (" ansi = %d", ansi); + wide_offsets = swfdec_bits_getbit (bits); + SWFDEC_LOG (" wide offsets = %d", wide_offsets); + wide_codes = swfdec_bits_getbit (bits); + SWFDEC_LOG (" wide codes = %d", wide_codes); + if (wide_codes == 0) { + SWFDEC_ERROR (" wide codes should be set in DefineFont3"); + } + font->italic = swfdec_bits_getbit (bits); + SWFDEC_LOG (" italic = %d", font->small); + font->bold = swfdec_bits_getbit (bits); + SWFDEC_LOG (" bold = %d", font->small); + language = swfdec_bits_get_u8 (&s->b); + SWFDEC_LOG (" language = %u", (guint) language); + len = swfdec_bits_get_u8 (&s->b); + font->name = swfdec_bits_get_string_length (&s->b, len); + SWFDEC_LOG (" name = %s", font->name); + n_glyphs = swfdec_bits_get_u16 (&s->b); + SWFDEC_LOG (" n_glyphs = %u", n_glyphs); + + offsets = *bits; + if (wide_offsets) { + if (swfdec_bits_skip_bytes (bits, n_glyphs * 4 + 4) != n_glyphs * 4 + 4) { + SWFDEC_ERROR ("DefineFont3 too short"); + return SWFDEC_STATUS_OK; + } + offset = swfdec_bits_get_u32 (&offsets); + } else { + if (swfdec_bits_skip_bytes (bits, n_glyphs * 2 + 2) != n_glyphs * 2 + 2) { + SWFDEC_ERROR ("DefineFont3 too short"); + return SWFDEC_STATUS_OK; + } + offset = swfdec_bits_get_u16 (&offsets); + } + g_array_set_size (font->glyphs, n_glyphs); + for (i = 0; i < n_glyphs; i++) { + SwfdecFontEntry *entry = &g_array_index (font->glyphs, SwfdecFontEntry, i); + if (wide_offsets) + next_offset = swfdec_bits_get_u32 (&offsets); + else + next_offset = swfdec_bits_get_u16 (&offsets); + swfdec_font_parse_shape (s, entry, next_offset - offset); + offset = next_offset; + } + for (i = 0; i < n_glyphs; i++) { + SwfdecFontEntry *entry = &g_array_index (font->glyphs, SwfdecFontEntry, i); + if (wide_codes) + entry->value = swfdec_bits_get_u16 (bits); + else + entry->value = swfdec_bits_get_u8 (bits); + } + if (layout) { + guint ascent, descent, leading; + + ascent = swfdec_bits_get_u16 (bits); + descent = swfdec_bits_get_u16 (bits); + leading = swfdec_bits_get_u16 (bits); + for (i = 0; i < n_glyphs; i++) { + /* guint advance = */ swfdec_bits_get_u16 (bits); + } + for (i = 0; i < n_glyphs; i++) { + SwfdecRect rect; + swfdec_bits_get_rect (bits, &rect); + } + swfdec_font_parse_kerning_table (s, font, wide_codes); + } + return SWFDEC_STATUS_OK; } diff --git a/libswfdec/swfdec_font.h b/libswfdec/swfdec_font.h index c8e2d04..23ecce4 100644 --- a/libswfdec/swfdec_font.h +++ b/libswfdec/swfdec_font.h @@ -31,6 +31,8 @@ G_BEGIN_DECLS typedef struct _SwfdecFontEntry SwfdecFontEntry; typedef struct _SwfdecFontClass SwfdecFontClass; +#define SWFDEC_TEXT_SCALE_FACTOR (1024) + typedef enum { SWFDEC_LANGUAGE_NONE = 0, SWFDEC_LANGUAGE_LATIN = 1, @@ -60,7 +62,8 @@ struct _SwfdecFont gboolean bold; /* font is bold */ gboolean italic; /* font is italic */ gboolean small; /* font is rendered at small sizes */ - GArray * glyphs; /* key: glyph index, value: UCS2 character */ + GArray * glyphs; /* SwfdecFontEntry */ + guint scale_factor; /* size of a font in glyph entry */ }; struct _SwfdecFontClass diff --git a/libswfdec/swfdec_text.c b/libswfdec/swfdec_text.c index 7f2ed9c..6090512 100644 --- a/libswfdec/swfdec_text.c +++ b/libswfdec/swfdec_text.c @@ -50,8 +50,8 @@ swfdec_text_mouse_in (SwfdecGraphic *gra } tmpx = x - glyph->x; tmpy = y - glyph->y; - tmpx *= SWFDEC_TEXT_SCALE_FACTOR / glyph->height; - tmpy *= SWFDEC_TEXT_SCALE_FACTOR / glyph->height; + tmpx = tmpx * glyph->font->scale_factor / glyph->height; + tmpy = tmpy * glyph->font->scale_factor / glyph->height; if (swfdec_graphic_mouse_in (SWFDEC_GRAPHIC (shape), tmpx, tmpy)) return TRUE; } @@ -87,8 +87,8 @@ swfdec_text_render (SwfdecGraphic *graph cairo_matrix_init_translate (&pos, glyph->x, glyph->y); cairo_matrix_scale (&pos, - glyph->height / SWFDEC_TEXT_SCALE_FACTOR, - glyph->height / SWFDEC_TEXT_SCALE_FACTOR); + (double) glyph->height / glyph->font->scale_factor, + (double) glyph->height / glyph->font->scale_factor); cairo_save (cr); cairo_transform (cr, &pos); if (!cairo_matrix_invert (&pos)) { diff-tree 3b4d3b8ffde2921b618208ff0fed436ec92817ba (from 13fa4a30d778a08db73566355332f7065443cdf5) Author: Benjamin Otte <otte@gnome.org> Date: Thu Feb 15 13:40:24 2007 +0100 rework tag_func_define_font to be more pedantic diff --git a/libswfdec/swfdec_font.c b/libswfdec/swfdec_font.c index 6d0c9af..d70a881 100644 --- a/libswfdec/swfdec_font.c +++ b/libswfdec/swfdec_font.c @@ -61,11 +61,24 @@ swfdec_font_init (SwfdecFont * font) font->glyphs = g_array_new (FALSE, TRUE, sizeof (SwfdecFontEntry)); } +/** + * swfdec_font_get_glyph: + * @font: a #SwfdecFont + * @glyph: id of glyph to render + * + * Tries to get the shape associated with the given glyph id. It is valid to + * call this function with any glyph id. If no such glyph exists, this function + * returns %NULL. + * + * Returns: the shape of the requested glyph or %NULL if no such glyph exists. + **/ SwfdecShape * swfdec_font_get_glyph (SwfdecFont * font, unsigned int glyph) { g_return_val_if_fail (SWFDEC_IS_FONT (font), NULL); - g_return_val_if_fail (glyph < font->glyphs->len, NULL); + + if (glyph >= font->glyphs->len) + return NULL; return g_array_index (font->glyphs, SwfdecFontEntry, glyph).shape; } @@ -154,44 +167,67 @@ tag_func_define_font_info (SwfdecSwfDeco return SWFDEC_STATUS_OK; } +static void +swfdec_font_parse_shape (SwfdecSwfDecoder *s, SwfdecFontEntry *entry, guint size) +{ + SwfdecBits save_bits = s->b; + SwfdecShape *shape = g_object_new (SWFDEC_TYPE_SHAPE, NULL); + 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)); + + shape->n_fill_bits = swfdec_bits_getbits (&s->b, 4); + SWFDEC_LOG ("n_fill_bits = %d", shape->n_fill_bits); + 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_bits_syncbits (&s->b); + if (swfdec_bits_skip_bytes (&save_bits, size) != size) { + SWFDEC_ERROR ("invalid offset value, not enough bytes available"); + } + if (swfdec_bits_left (&save_bits) != swfdec_bits_left (&s->b)) { + SWFDEC_WARNING ("parsing shape did use %d bytes too much\n", + (swfdec_bits_left (&save_bits) - swfdec_bits_left (&s->b)) / 8); + /* we trust the offsets here */ + s->b = save_bits; + } +} + int tag_func_define_font (SwfdecSwfDecoder * s) { - int id; - int i; - int n_glyphs; - int offset; - SwfdecShape *shape; + unsigned int i, id, n_glyphs, offset, next_offset; SwfdecFont *font; + SwfdecBits offsets; id = swfdec_bits_get_u16 (&s->b); font = swfdec_swf_decoder_create_character (s, id, SWFDEC_TYPE_FONT); if (!font) return SWFDEC_STATUS_OK; - offset = swfdec_bits_get_u16 (&s->b); - n_glyphs = offset / 2; - - for (i = 1; i < n_glyphs; i++) { - offset = swfdec_bits_get_u16 (&s->b); + offsets = s->b; + n_glyphs = swfdec_bits_get_u16 (&s->b); + if (n_glyphs % 2) { + SWFDEC_ERROR ("first offset is odd?!"); + } + n_glyphs /= 2; + if (swfdec_bits_skip_bytes (&s->b, n_glyphs * 2 - 2) != n_glyphs * 2 - 2) { + SWFDEC_ERROR ("invalid glyph offsets"); + return SWFDEC_STATUS_OK; } g_array_set_size (font->glyphs, n_glyphs); + offset = swfdec_bits_get_u16 (&offsets); for (i = 0; i < n_glyphs; i++) { SwfdecFontEntry *entry = &g_array_index (font->glyphs, SwfdecFontEntry, i); - shape = g_object_new (SWFDEC_TYPE_SHAPE, NULL); - 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)); - - swfdec_bits_syncbits (&s->b); - shape->n_fill_bits = swfdec_bits_getbits (&s->b, 4); - SWFDEC_LOG ("n_fill_bits = %d", shape->n_fill_bits); - 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); + if (i + 1 == n_glyphs) + next_offset = offset + swfdec_bits_left (&s->b) / 8; + else + next_offset = swfdec_bits_get_u16 (&offsets); + swfdec_font_parse_shape (s, entry, next_offset - offset); + offset = next_offset; } return SWFDEC_STATUS_OK; @@ -214,7 +250,7 @@ int tag_func_define_font_2 (SwfdecSwfDecoder * s) { SwfdecBits *bits = &s->b; - int id; + unsigned int id; SwfdecShape *shape; SwfdecFont *font; SwfdecRect rect; diff-tree 13fa4a30d778a08db73566355332f7065443cdf5 (from 64b04c7629bb463f209d642a5b0f2ae73b82e248) Author: Benjamin Otte <otte@gnome.org> Date: Thu Feb 15 13:37:28 2007 +0100 handle non-existing shape case diff --git a/libswfdec/swfdec_text.c b/libswfdec/swfdec_text.c index d7ca655..7f2ed9c 100644 --- a/libswfdec/swfdec_text.c +++ b/libswfdec/swfdec_text.c @@ -44,6 +44,10 @@ swfdec_text_mouse_in (SwfdecGraphic *gra glyph = &g_array_index (text->glyphs, SwfdecTextGlyph, i); shape = swfdec_font_get_glyph (glyph->font, glyph->glyph); + if (shape == NULL) { + SWFDEC_ERROR ("failed getting glyph %d\n", glyph->glyph); + continue; + } tmpx = x - glyph->x; tmpy = y - glyph->y; tmpx *= SWFDEC_TEXT_SCALE_FACTOR / glyph->height; diff-tree 64b04c7629bb463f209d642a5b0f2ae73b82e248 (from 436abca404e3d5afd93b13d1277e92ef0faa4714) Author: Benjamin Otte <otte@gnome.org> Date: Thu Feb 15 13:03:40 2007 +0100 move the DefineFont tags to swfdec_font.c diff --git a/libswfdec/swfdec_font.c b/libswfdec/swfdec_font.c index 8177c2b..6d0c9af 100644 --- a/libswfdec/swfdec_font.c +++ b/libswfdec/swfdec_font.c @@ -26,6 +26,7 @@ #include "swfdec_font.h" #include "swfdec_bits.h" #include "swfdec_debug.h" +#include "swfdec_shape.h" #include "swfdec_swf_decoder.h" G_DEFINE_TYPE (SwfdecFont, swfdec_font, SWFDEC_TYPE_CHARACTER) @@ -153,3 +154,164 @@ tag_func_define_font_info (SwfdecSwfDeco return SWFDEC_STATUS_OK; } +int +tag_func_define_font (SwfdecSwfDecoder * s) +{ + int id; + int i; + int n_glyphs; + int offset; + SwfdecShape *shape; + SwfdecFont *font; + + id = swfdec_bits_get_u16 (&s->b); + font = swfdec_swf_decoder_create_character (s, id, SWFDEC_TYPE_FONT); + if (!font) + return SWFDEC_STATUS_OK; + + offset = swfdec_bits_get_u16 (&s->b); + n_glyphs = offset / 2; + + for (i = 1; i < n_glyphs; i++) { + offset = swfdec_bits_get_u16 (&s->b); + } + + g_array_set_size (font->glyphs, n_glyphs); + for (i = 0; i < n_glyphs; i++) { + SwfdecFontEntry *entry = &g_array_index (font->glyphs, SwfdecFontEntry, i); + shape = g_object_new (SWFDEC_TYPE_SHAPE, NULL); + 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)); + + swfdec_bits_syncbits (&s->b); + shape->n_fill_bits = swfdec_bits_getbits (&s->b, 4); + SWFDEC_LOG ("n_fill_bits = %d", shape->n_fill_bits); + 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); + } + + return SWFDEC_STATUS_OK; +} + +static void +get_kerning_record (SwfdecBits * bits, int wide_codes) +{ + if (wide_codes) { + swfdec_bits_get_u16 (bits); + swfdec_bits_get_u16 (bits); + } else { + swfdec_bits_get_u8 (bits); + swfdec_bits_get_u8 (bits); + } + swfdec_bits_get_s16 (bits); +} + +int +tag_func_define_font_2 (SwfdecSwfDecoder * s) +{ + SwfdecBits *bits = &s->b; + int id; + SwfdecShape *shape; + SwfdecFont *font; + SwfdecRect rect; + + int has_layout; + int shift_jis; + int reserved; + int ansi; + int wide_offsets; + int wide_codes; + int italic; + int bold; + int langcode; + int font_name_len; + int n_glyphs; + int code_table_offset; + int font_ascent; + int font_descent; + int font_leading; + int kerning_count; + int i; + + id = swfdec_bits_get_u16 (bits); + font = swfdec_swf_decoder_create_character (s, id, SWFDEC_TYPE_FONT); + if (!font) + return SWFDEC_STATUS_OK; + + has_layout = swfdec_bits_getbit (bits); + shift_jis = swfdec_bits_getbit (bits); + reserved = swfdec_bits_getbit (bits); + ansi = swfdec_bits_getbit (bits); + wide_offsets = swfdec_bits_getbit (bits); + wide_codes = swfdec_bits_getbit (bits); + italic = swfdec_bits_getbit (bits); + bold = swfdec_bits_getbit (bits); + + langcode = swfdec_bits_get_u8 (bits); + SWFDEC_DEBUG("langcode %d", langcode); + + font_name_len = swfdec_bits_get_u8 (bits); + //font_name = + bits->ptr += font_name_len; + + n_glyphs = swfdec_bits_get_u16 (bits); + if (wide_offsets) { + bits->ptr += 4 * n_glyphs; + code_table_offset = swfdec_bits_get_u32 (bits); + } else { + bits->ptr += 2 * n_glyphs; + code_table_offset = swfdec_bits_get_u16 (bits); + } + + g_array_set_size (font->glyphs, n_glyphs); + + for (i = 0; i < n_glyphs; i++) { + SwfdecFontEntry *entry = &g_array_index (font->glyphs, SwfdecFontEntry, i); + shape = g_object_new (SWFDEC_TYPE_SHAPE, NULL); + 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)); + + swfdec_bits_syncbits (&s->b); + shape->n_fill_bits = swfdec_bits_getbits (&s->b, 4); + SWFDEC_LOG ("n_fill_bits = %d", shape->n_fill_bits); + 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); + } + if (wide_codes) { + swfdec_bits_skip_bytes (bits, 2 * n_glyphs); + } else { + swfdec_bits_skip_bytes (bits, 1 * n_glyphs); + } + if (has_layout) { + font_ascent = swfdec_bits_get_s16 (bits); + font_descent = swfdec_bits_get_s16 (bits); + font_leading = swfdec_bits_get_s16 (bits); + //font_advance_table = swfdec_bits_get_s16(bits); + swfdec_bits_skip_bytes (bits, 2 * n_glyphs); + for (i = 0; i < n_glyphs; i++) { + swfdec_bits_get_rect (bits, &rect); + } + kerning_count = swfdec_bits_get_u16 (bits); + if (0) { + for (i = 0; i < kerning_count; i++) { + get_kerning_record (bits, wide_codes); + } + } + } + + return SWFDEC_STATUS_OK; +} + +int +tag_func_define_font_3 (SwfdecSwfDecoder * s) +{ + return SWFDEC_STATUS_OK; +} diff --git a/libswfdec/swfdec_font.h b/libswfdec/swfdec_font.h index 1c25fc9..c8e2d04 100644 --- a/libswfdec/swfdec_font.h +++ b/libswfdec/swfdec_font.h @@ -68,11 +68,16 @@ struct _SwfdecFontClass SwfdecCharacterClass character_class; }; -GType swfdec_font_get_type (void); +GType swfdec_font_get_type (void); -SwfdecShape *swfdec_font_get_glyph (SwfdecFont * font, unsigned int glyph); +SwfdecShape * swfdec_font_get_glyph (SwfdecFont * font, + unsigned int glyph); -int tag_func_define_font_info (SwfdecSwfDecoder *s, unsigned int version); +int tag_func_define_font_info (SwfdecSwfDecoder * s, + unsigned int version); +int tag_func_define_font (SwfdecSwfDecoder * s); +int tag_func_define_font_2 (SwfdecSwfDecoder * s); +int tag_func_define_font_3 (SwfdecSwfDecoder * s); G_END_DECLS #endif diff --git a/libswfdec/swfdec_tag.c b/libswfdec/swfdec_tag.c index f4497f2..97a1e4d 100644 --- a/libswfdec/swfdec_tag.c +++ b/libswfdec/swfdec_tag.c @@ -491,162 +491,6 @@ tag_func_define_button (SwfdecSwfDecoder return SWFDEC_STATUS_OK; } -int -tag_func_define_font (SwfdecSwfDecoder * s) -{ - int id; - int i; - int n_glyphs; - int offset; - SwfdecShape *shape; - SwfdecFont *font; - - id = swfdec_bits_get_u16 (&s->b); - font = swfdec_swf_decoder_create_character (s, id, SWFDEC_TYPE_FONT); - if (!font) - return SWFDEC_STATUS_OK; - - offset = swfdec_bits_get_u16 (&s->b); - n_glyphs = offset / 2; - - for (i = 1; i < n_glyphs; i++) { - offset = swfdec_bits_get_u16 (&s->b); - } - - g_array_set_size (font->glyphs, n_glyphs); - for (i = 0; i < n_glyphs; i++) { - SwfdecFontEntry *entry = &g_array_index (font->glyphs, SwfdecFontEntry, i); - shape = g_object_new (SWFDEC_TYPE_SHAPE, NULL); - 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)); - - swfdec_bits_syncbits (&s->b); - shape->n_fill_bits = swfdec_bits_getbits (&s->b, 4); - SWFDEC_LOG ("n_fill_bits = %d", shape->n_fill_bits); - 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); - } - - return SWFDEC_STATUS_OK; -} - -static void -get_kerning_record (SwfdecBits * bits, int wide_codes) -{ - if (wide_codes) { - swfdec_bits_get_u16 (bits); - swfdec_bits_get_u16 (bits); - } else { - swfdec_bits_get_u8 (bits); - swfdec_bits_get_u8 (bits); - } - swfdec_bits_get_s16 (bits); -} - -int -tag_func_define_font_2 (SwfdecSwfDecoder * s) -{ - SwfdecBits *bits = &s->b; - int id; - SwfdecShape *shape; - SwfdecFont *font; - SwfdecRect rect; - - int has_layout; - int shift_jis; - int reserved; - int ansi; - int wide_offsets; - int wide_codes; - int italic; - int bold; - int langcode; - int font_name_len; - int n_glyphs; - int code_table_offset; - int font_ascent; - int font_descent; - int font_leading; - int kerning_count; - int i; - - id = swfdec_bits_get_u16 (bits); - font = swfdec_swf_decoder_create_character (s, id, SWFDEC_TYPE_FONT); - if (!font) - return SWFDEC_STATUS_OK; - - has_layout = swfdec_bits_getbit (bits); - shift_jis = swfdec_bits_getbit (bits); - reserved = swfdec_bits_getbit (bits); - ansi = swfdec_bits_getbit (bits); - wide_offsets = swfdec_bits_getbit (bits); - wide_codes = swfdec_bits_getbit (bits); - italic = swfdec_bits_getbit (bits); - bold = swfdec_bits_getbit (bits); - - langcode = swfdec_bits_get_u8 (bits); - SWFDEC_DEBUG("langcode %d", langcode); - - font_name_len = swfdec_bits_get_u8 (bits); - //font_name = - bits->ptr += font_name_len; - - n_glyphs = swfdec_bits_get_u16 (bits); - if (wide_offsets) { - bits->ptr += 4 * n_glyphs; - code_table_offset = swfdec_bits_get_u32 (bits); - } else { - bits->ptr += 2 * n_glyphs; - code_table_offset = swfdec_bits_get_u16 (bits); - } - - g_array_set_size (font->glyphs, n_glyphs); - - for (i = 0; i < n_glyphs; i++) { - SwfdecFontEntry *entry = &g_array_index (font->glyphs, SwfdecFontEntry, i); - shape = g_object_new (SWFDEC_TYPE_SHAPE, NULL); - 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)); - - swfdec_bits_syncbits (&s->b); - shape->n_fill_bits = swfdec_bits_getbits (&s->b, 4); - SWFDEC_LOG ("n_fill_bits = %d", shape->n_fill_bits); - 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); - } - if (wide_codes) { - swfdec_bits_skip_bytes (bits, 2 * n_glyphs); - } else { - swfdec_bits_skip_bytes (bits, 1 * n_glyphs); - } - if (has_layout) { - font_ascent = swfdec_bits_get_s16 (bits); - font_descent = swfdec_bits_get_s16 (bits); - font_leading = swfdec_bits_get_s16 (bits); - //font_advance_table = swfdec_bits_get_s16(bits); - swfdec_bits_skip_bytes (bits, 2 * n_glyphs); - for (i = 0; i < n_glyphs; i++) { - swfdec_bits_get_rect (bits, &rect); - } - kerning_count = swfdec_bits_get_u16 (bits); - if (0) { - for (i = 0; i < kerning_count; i++) { - get_kerning_record (bits, wide_codes); - } - } - } - - return SWFDEC_STATUS_OK; -} - static int tag_func_export_assets (SwfdecSwfDecoder * s) { @@ -779,7 +623,7 @@ static struct tag_func_struct tag_funcs[ [SWFDEC_TAG_IMPORTASSETS2] = {"ImportAssets2", NULL, 0}, [SWFDEC_TAG_DEFINEFONTALIGNZONES] = {"DefineFontAlignZones", NULL, 0}, [SWFDEC_TAG_CSMTEXTSETTINGS] = {"CSMTextSettings", NULL, 0}, - [SWFDEC_TAG_DEFINEFONT3] = {"DefineFont3", NULL, 0}, + [SWFDEC_TAG_DEFINEFONT3] = {"DefineFont3", tag_func_define_font_3, 0}, [SWFDEC_TAG_AVM2DECL] = {"AVM2Decl", NULL, 0}, [SWFDEC_TAG_METADATA] = {"Metadata", NULL, 0}, [SWFDEC_TAG_DEFINESCALINGGRID] = {"DefineScalingGrid", NULL, 0}, diff --git a/libswfdec/swfdec_text.h b/libswfdec/swfdec_text.h index 5bf3e98..3e8a7db 100644 --- a/libswfdec/swfdec_text.h +++ b/libswfdec/swfdec_text.h @@ -61,8 +61,6 @@ struct _SwfdecTextClass { GType swfdec_text_get_type (void); -int tag_func_define_font (SwfdecSwfDecoder * s); -int tag_func_define_font_2 (SwfdecSwfDecoder * s); int tag_func_define_text (SwfdecSwfDecoder * s); int tag_func_define_text_2 (SwfdecSwfDecoder * s); diff-tree 436abca404e3d5afd93b13d1277e92ef0faa4714 (from a879894cd4905bea3dfe323eac13d24448146807) Author: Benjamin Otte <otte@gnome.org> Date: Thu Feb 15 12:40:49 2007 +0100 to_string should work if there's no script diff --git a/test/swfedit_token.c b/test/swfedit_token.c index 06c1aa4..542da2f 100644 --- a/test/swfedit_token.c +++ b/test/swfedit_token.c @@ -336,7 +336,10 @@ swfedit_script_from_string (const char * static char * swfedit_script_to_string (gconstpointer value) { - return swfedit_binary_to_string (((SwfdecScript *) value)->buffer); + if (value == NULL) + return g_strdup (""); + else + return swfedit_binary_to_string (((SwfdecScript *) value)->buffer); } static void
Seemingly Similar Threads
- 3 commits - libswfdec/swfdec_bits.c libswfdec/swfdec_font.c libswfdec/swfdec_movie.c
- 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
- Branch 'as' - 17 commits - libswfdec/jpeg libswfdec/swfdec_bits.c libswfdec/swfdec_font.c libswfdec/swfdec_image.c libswfdec/swfdec_root_sprite.c libswfdec/swfdec_script.c libswfdec/swfdec_shape.c libswfdec/swfdec_sound.c libswfdec/swfdec_sprite.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
- 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