[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

Benjamin Otte company at kemper.freedesktop.org
Thu Feb 15 08:29:40 PST 2007


 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 at 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 at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "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 at 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 at 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 at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
diff-tree b5b06e40f10336b5bc057d0fad626a88e2ff8fb2 (from 3b4d3b8ffde2921b618208ff0fed436ec92817ba)
Author: Benjamin Otte <otte at 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 at 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 at 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 at 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 at 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


More information about the Swfdec mailing list