[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