gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] gnash ChangeLog configure.ac gui/Makefile.am gu...


From: Sandro Santilli
Subject: [Gnash-commit] gnash ChangeLog configure.ac gui/Makefile.am gu...
Date: Thu, 24 Aug 2006 00:57:21 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Sandro Santilli <strk>  06/08/24 00:57:20

Modified files:
        .              : ChangeLog configure.ac 
        gui            : Makefile.am gtk.cpp gui.cpp 
        server         : Makefile.am sprite_instance.h 
        server/asobj   : Makefile.am 
Added files:
        server/asobj   : MovieClip.cpp MovieClip.h 
        server/parser  : Makefile.am action_buffer.cpp action_buffer.h 
                         bitmap_character_def.h character_def.cpp 
                         character_def.h edit_text_character_def.cpp 
                         edit_text_character_def.h movie_def_impl.cpp 
                         movie_def_impl.h movie_definition.h 
                         shape_character_def.cpp shape_character_def.h 
                         sprite_definition.cpp sprite_definition.h 
                         text_character_def.h 
Removed files:
        server         : MovieClip.cpp MovieClip.h Object.h 
                         action_buffer.cpp action_buffer.h 
                         bitmap_character_def.h character_def.cpp 
                         character_def.h edit_text_character_def.cpp 
                         edit_text_character_def.h movie_def_impl.cpp 
                         movie_def_impl.h movie_definition.h 
                         shape_character_def.cpp shape_character_def.h 
                         sprite_definition.cpp sprite_definition.h 

Log message:
                Moved some of parser's files under their own dir/lib (not yet
                finished); also moved MovieClip under asobj/, where it belongs.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.697&r2=1.698
http://cvs.savannah.gnu.org/viewcvs/gnash/configure.ac?cvsroot=gnash&r1=1.102&r2=1.103
http://cvs.savannah.gnu.org/viewcvs/gnash/gui/Makefile.am?cvsroot=gnash&r1=1.14&r2=1.15
http://cvs.savannah.gnu.org/viewcvs/gnash/gui/gtk.cpp?cvsroot=gnash&r1=1.17&r2=1.18
http://cvs.savannah.gnu.org/viewcvs/gnash/gui/gui.cpp?cvsroot=gnash&r1=1.15&r2=1.16
http://cvs.savannah.gnu.org/viewcvs/gnash/server/Makefile.am?cvsroot=gnash&r1=1.59&r2=1.60
http://cvs.savannah.gnu.org/viewcvs/gnash/server/sprite_instance.h?cvsroot=gnash&r1=1.19&r2=1.20
http://cvs.savannah.gnu.org/viewcvs/gnash/server/MovieClip.cpp?cvsroot=gnash&r1=1.3&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/server/MovieClip.h?cvsroot=gnash&r1=1.1&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/server/Object.h?cvsroot=gnash&r1=1.11&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/server/action_buffer.cpp?cvsroot=gnash&r1=1.18&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/server/action_buffer.h?cvsroot=gnash&r1=1.5&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/server/bitmap_character_def.h?cvsroot=gnash&r1=1.1&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/server/character_def.cpp?cvsroot=gnash&r1=1.3&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/server/character_def.h?cvsroot=gnash&r1=1.8&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/server/edit_text_character_def.cpp?cvsroot=gnash&r1=1.9&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/server/edit_text_character_def.h?cvsroot=gnash&r1=1.8&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/server/movie_def_impl.cpp?cvsroot=gnash&r1=1.35&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/server/movie_def_impl.h?cvsroot=gnash&r1=1.22&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/server/movie_definition.h?cvsroot=gnash&r1=1.11&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/server/shape_character_def.cpp?cvsroot=gnash&r1=1.7&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/server/shape_character_def.h?cvsroot=gnash&r1=1.2&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/server/sprite_definition.cpp?cvsroot=gnash&r1=1.13&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/server/sprite_definition.h?cvsroot=gnash&r1=1.16&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/Makefile.am?cvsroot=gnash&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/MovieClip.cpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/MovieClip.h?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/Makefile.am?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/action_buffer.cpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/action_buffer.h?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/bitmap_character_def.h?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/character_def.cpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/character_def.h?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/edit_text_character_def.cpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/edit_text_character_def.h?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/movie_def_impl.cpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/movie_def_impl.h?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/movie_definition.h?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/shape_character_def.cpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/shape_character_def.h?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/sprite_definition.cpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/sprite_definition.h?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/text_character_def.h?cvsroot=gnash&rev=1.1

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.697
retrieving revision 1.698
diff -u -b -r1.697 -r1.698
--- ChangeLog   24 Aug 2006 00:47:28 -0000      1.697
+++ ChangeLog   24 Aug 2006 00:57:20 -0000      1.698
@@ -1,3 +1,31 @@
+2006-08-24 Sandro Santilli  <address@hidden>
+
+       * configure.ac, gui/Makefile.am, gui/gtk.cpp, gui/gui.cpp,
+         server/Makefile.am, server/MovieClip.cpp, server/MovieClip.h,
+         server/Object.h, server/action_buffer.cpp, server/action_buffer.h,
+         server/bitmap_character_def.h, server/character_def.cpp,
+         server/character_def.h, server/edit_text_character_def.cpp,
+         server/edit_text_character_def.h, server/movie_def_impl.cpp,
+         server/movie_def_impl.h, server/movie_definition.h,
+         server/shape_character_def.cpp, server/shape_character_def.h,
+         server/sprite_definition.cpp, server/sprite_definition.h,
+         server/sprite_instance.h, server/asobj/Makefile.am,
+         server/asobj/MovieClip.cpp, server/asobj/MovieClip.h,
+         server/parser/Makefile.am, server/parser/action_buffer.cpp,
+         server/parser/action_buffer.h, server/parser/bitmap_character_def.h,
+         server/parser/character_def.cpp, server/parser/character_def.h,
+         server/parser/edit_text_character_def.cpp,
+         server/parser/edit_text_character_def.h,
+         server/parser/movie_def_impl.cpp, server/parser/movie_def_impl.h,
+         server/parser/movie_definition.h,
+         server/parser/shape_character_def.cpp,
+         server/parser/shape_character_def.h,
+         server/parser/sprite_definition.cpp,
+         server/parser/sprite_definition.h,
+         server/parser/text_character_def.h:
+       Moved some of parser's files under their own dir/lib (not yet
+       finished); also moved MovieClip under asobj/, where it belongs.
+
 2006-08-23 Sandro Santilli  <address@hidden>
 
        * server/swf_function.h, server/swf_function.cpp:

Index: configure.ac
===================================================================
RCS file: /sources/gnash/gnash/configure.ac,v
retrieving revision 1.102
retrieving revision 1.103
diff -u -b -r1.102 -r1.103
--- configure.ac        23 Aug 2006 20:28:20 -0000      1.102
+++ configure.ac        24 Aug 2006 00:57:20 -0000      1.103
@@ -483,6 +483,7 @@
 libgeometry/Makefile
 server/Makefile
 server/asobj/Makefile
+server/parser/Makefile
 libamf/Makefile
 backend/Makefile
 utilities/Makefile

Index: gui/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/gui/Makefile.am,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -b -r1.14 -r1.15
--- gui/Makefile.am     13 Aug 2006 15:54:16 -0000      1.14
+++ gui/Makefile.am     24 Aug 2006 00:57:20 -0000      1.15
@@ -86,6 +86,7 @@
        -I$(kde_includes)/kio $(all_includes) \
         -I$(top_srcdir) \
         -I$(top_srcdir)/server \
+        -I$(top_srcdir)/server/parser \
         -I$(top_srcdir)/libbase \
         -I$(top_srcdir)/backend \
         -I$(top_srcdir)/libgeometry \

Index: gui/gtk.cpp
===================================================================
RCS file: /sources/gnash/gnash/gui/gtk.cpp,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -b -r1.17 -r1.18
--- gui/gtk.cpp 11 Aug 2006 20:53:44 -0000      1.17
+++ gui/gtk.cpp 24 Aug 2006 00:57:20 -0000      1.18
@@ -40,7 +40,7 @@
 #endif
 
 #include "gnash.h"
-#include "movie_definition.h" 
+//#include "movie_definition.h" 
 #include "log.h"
 
 #include "gui.h"

Index: gui/gui.cpp
===================================================================
RCS file: /sources/gnash/gnash/gui/gui.cpp,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -b -r1.15 -r1.16
--- gui/gui.cpp 10 Aug 2006 11:19:30 -0000      1.15
+++ gui/gui.cpp 24 Aug 2006 00:57:20 -0000      1.16
@@ -44,7 +44,7 @@
 
 #include "log.h"
 #include "gnash.h"
-#include "movie_definition.h"
+//#include "movie_definition.h"
 #include "sprite_instance.h"
 #include "gui.h"
 

Index: server/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/server/Makefile.am,v
retrieving revision 1.59
retrieving revision 1.60
diff -u -b -r1.59 -r1.60
--- server/Makefile.am  23 Aug 2006 23:03:21 -0000      1.59
+++ server/Makefile.am  24 Aug 2006 00:57:20 -0000      1.60
@@ -40,7 +40,7 @@
 
 AM_CPPFLAGS = 
 
-SUBDIRS = asobj
+SUBDIRS = asobj parser
 
 # noinst_LTLIBRARIES = libserver.la 
 lib_LTLIBRARIES = libgnashserver.la
@@ -50,6 +50,7 @@
 INCLUDES = \
        -I$(top_srcdir)/server/swf \
        -I$(top_srcdir)/server/asobj \
+       -I$(top_srcdir)/server/parser \
         -I$(top_srcdir)/libbase \
         -I$(top_srcdir)        \
        $(PTHREAD_CFLAGS) \
@@ -75,14 +76,12 @@
        as_function.cpp         \
        swf_function.cpp        \
        character.cpp \
-       character_def.cpp \
         textformat.cpp \
         timers.cpp \
         xml.cpp \
         xmlattrs.cpp \
         xmlnode.cpp \
        movie_root.cpp \
-       movie_def_impl.cpp \
         xmlsocket.cpp \
         string.cpp \
         action.cpp \
@@ -91,18 +90,14 @@
         button.cpp \
         dlist.cpp \
        edit_text_character.cpp \
-       edit_text_character_def.cpp \
         font.cpp \
         fontlib.cpp \
         impl.cpp \
         morph2.cpp \
-       MovieClip.cpp \
         render.cpp \
         shape.cpp \
-       shape_character_def.cpp \
        shm.cpp \
         sound.cpp \
-       sprite_definition.cpp \
        sprite_instance.cpp \
        movie_instance.cpp \
         stream.cpp \
@@ -133,11 +128,8 @@
        button.h \
        dlist.h \
        character.h \
-       character_def.h \
        generic_character.h \
-       bitmap_character_def.h \
        edit_text_character.h \
-       edit_text_character_def.h \
        execute_tag.h \
        font.h \
        fontlib.h \
@@ -147,22 +139,16 @@
        impl.h \
        morph2.h \
        morph.h \
-       MovieClip.h \
        movie.h \
-       movie_definition.h \
-       movie_def_impl.h \
        movie_interface.h \
        movie_root.h \
-       Object.h \
        resource.h \
        ref_counted.h \
        render.h \
        shape.h \
-       shape_character_def.h \
        shm.h \
        sound.h \
        Sprite.h \
-       sprite_definition.h \
        sprite_instance.h \
        movie_instance.h \
        stream.h \
@@ -170,6 +156,7 @@
        URLAccessManager.h      \
        styles.h \
        swf.h \
+       swf_event.h \
        tesselate.h \
        textformat.h \
        text.h \
@@ -188,9 +175,9 @@
 libgnashserver_la_LIBADD = \
        ../libbase/libgnashbase.la \
        asobj/libgnashasobjs.la \
+       parser/libgnashparser.la \
        $(ZLIB_LIBS) \
        $(LIBXML_LIBS) \
-       $(LIBXML_LIBS) \
        $(OPENGL_LIBS)
 
 #libserver_la_LDFLAGS = -module -avoid-version -no-undefined

Index: server/sprite_instance.h
===================================================================
RCS file: /sources/gnash/gnash/server/sprite_instance.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -b -r1.19 -r1.20
--- server/sprite_instance.h    23 Aug 2006 21:30:49 -0000      1.19
+++ server/sprite_instance.h    24 Aug 2006 00:57:20 -0000      1.20
@@ -47,7 +47,7 @@
 
 #include <vector>
 
-#include "movie_definition.h"
+#include "movie_definition.h" // for inlines
 #include "dlist.h" // DisplayList 
 #include "stream.h"
 #include "log.h"

Index: server/asobj/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/Makefile.am,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- server/asobj/Makefile.am    13 Aug 2006 15:54:16 -0000      1.4
+++ server/asobj/Makefile.am    24 Aug 2006 00:57:20 -0000      1.5
@@ -46,6 +46,7 @@
 INCLUDES = \
        -I$(top_srcdir)/server \
        -I$(top_srcdir)/server/swf \
+       -I$(top_srcdir)/server/parser \
         -I$(top_srcdir)/libbase \
         -I$(top_srcdir)/libamf \
         -I$(top_srcdir)        \
@@ -80,6 +81,7 @@
        LocalConnection.cpp\
        Microphone.cpp  \
        Mouse.cpp       \
+       MovieClip.cpp   \
         MovieClipLoader.cpp\
        NetConnection.cpp\
        NetStream.cpp   \
@@ -106,6 +108,7 @@
        Microphone.h    \
        GMath.h         \
        Mouse.h         \
+       MovieClip.h     \
        MovieClipLoader.h \
        NetConnection.h \
        NetStream.h     \

Index: server/asobj/MovieClip.cpp
===================================================================
RCS file: server/asobj/MovieClip.cpp
diff -N server/asobj/MovieClip.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/asobj/MovieClip.cpp  24 Aug 2006 00:57:20 -0000      1.1
@@ -0,0 +1,89 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+// 
+// This program 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 General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+// Linking Gnash statically or dynamically with other modules is making a
+// combined work based on Gnash. Thus, the terms and conditions of the GNU
+// General Public License cover the whole combination.
+//
+// As a special exception, the copyright holders of Gnash give you
+// permission to combine Gnash with free software programs or libraries
+// that are released under the GNU LGPL and with code included in any
+// release of Talkback distributed by the Mozilla Foundation. You may
+// copy and distribute such a system following the terms of the GNU GPL
+// for all but the LGPL-covered parts and Talkback, and following the
+// LGPL for the LGPL-covered parts.
+//
+// Note that people who make modified versions of Gnash are not obligated
+// to grant this special exception for their modified versions; it is their
+// choice whether to do so. The GNU General Public License gives permission
+// to release a modified version without this exception; this exception
+// also makes it possible to release a modified version which carries
+// forward this exception.
+// 
+//
+#ifdef HAVE_PTHREADS
+#include <pthread.h>
+#endif
+
+#include <iostream>
+#include <string>
+
+#include "MovieClip.h"
+#include "tu_file.h"
+#include "zlib_adapter.h"
+//#include "stream.h"
+//#include "jpeg.h"
+//#include "fontlib.h"
+//#include "font.h"
+#include "log.h"
+//#include "Sprite.h"
+//#include "sprite_instance.h"
+#include "render.h"
+
+using namespace std;
+
+namespace gnash
+{
+
+// Forward declarations
+
+// @@ should be found somewhere else I guess..
+//movie_interface* create_instance();
+
+void
+movieclip_init(as_object* /* global */)
+{
+#if 0
+    // This is going to be the global MovieClip "class"/"function"
+    static as_function *func=new function_as_object();
+
+    // We make the 'prototype' element be a reference to
+    // the __proto__ element
+    as_object* proto = func->m_prototype;
+    proto->add_ref();
+
+    proto->set_member("constructor", func); //as_value(func));
+    proto->set_member_flags("constructor", 1);
+
+    func->set_member("prototype", as_value(proto));
+
+    // Register _global.Function
+    global->set_member("Function", func);
+#endif
+}
+
+} // namespace gnash
+

Index: server/asobj/MovieClip.h
===================================================================
RCS file: server/asobj/MovieClip.h
diff -N server/asobj/MovieClip.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/asobj/MovieClip.h    24 Aug 2006 00:57:20 -0000      1.1
@@ -0,0 +1,51 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+// 
+// This program 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 General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+// Linking Gnash statically or dynamically with other modules is making a
+// combined work based on Gnash. Thus, the terms and conditions of the GNU
+// General Public License cover the whole combination.
+//
+// As a special exception, the copyright holders of Gnash give you
+// permission to combine Gnash with free software programs or libraries
+// that are released under the GNU LGPL and with code included in any
+// release of Talkback distributed by the Mozilla Foundation. You may
+// copy and distribute such a system following the terms of the GNU GPL
+// for all but the LGPL-covered parts and Talkback, and following the
+// LGPL for the LGPL-covered parts.
+//
+// Note that people who make modified versions of Gnash are not obligated
+// to grant this special exception for their modified versions; it is their
+// choice whether to do so. The GNU General Public License gives permission
+// to release a modified version without this exception; this exception
+// also makes it possible to release a modified version which carries
+// forward this exception.
+// 
+//
+
+#ifndef GNASH_MOVIECLIP_H
+#define GNASH_MOVIECLIP_H
+
+namespace gnash
+{
+
+class as_object;
+
+/// Initialize the global MovieClip constructor
+void movieclip_init(as_object* global);
+
+} // namespace gnash
+
+#endif // GNASH_MOVIECLIP_H

Index: server/parser/Makefile.am
===================================================================
RCS file: server/parser/Makefile.am
diff -N server/parser/Makefile.am
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/parser/Makefile.am   24 Aug 2006 00:57:20 -0000      1.1
@@ -0,0 +1,97 @@
+## Process this file with automake to generate Makefile.in
+# 
+#   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+# 
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# This program 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 General Public License for more details.
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+# Linking Gnash statically or dynamically with other modules is making a
+# combined work based on Gnash. Thus, the terms and conditions of the GNU
+# General Public License cover the whole combination.
+#
+# As a special exception, the copyright holders of Gnash give you
+# permission to combine Gnash with free software programs or libraries
+# that are released under the GNU LGPL and with code included in any
+# release of Talkback distributed by the Mozilla Foundation. You may
+# copy and distribute such a system following the terms of the GNU GPL
+# for all but the LGPL-covered parts and Talkback, and following the
+# LGPL for the LGPL-covered parts.
+#
+# Note that people who make modified versions of Gnash are not obligated
+# to grant this special exception for their modified versions; it is their
+# choice whether to do so. The GNU General Public License gives permission
+# to release a modified version without this exception; this exception
+# also makes it possible to release a modified version which carries
+# forward this exception.
+# 
+#
+
+AUTOMAKE_OPTIONS = 
+
+AM_CPPFLAGS = 
+
+noinst_LTLIBRARIES = libgnashparser.la 
+
+# Only enable if we're configured with --enable-mp3
+INCLUDES = \
+       -I$(top_srcdir)/server \
+       -I$(top_srcdir)/server/swf \
+       -I$(top_srcdir)/server/parser \
+        -I$(top_srcdir)/libbase \
+        -I$(top_srcdir)/libamf \
+        -I$(top_srcdir)        \
+       $(PTHREAD_CFLAGS) \
+        $(ENGINE_INCLUDE) \
+        $(ZLIB_CFLAGS) \
+        $(OGG_CFLAGS) \
+        $(JPEG_CFLAGS) \
+        $(SDL_CFLAGS) \
+        $(SDL_MIXER_CFLAGS) \
+        $(OPENGL_CFLAGS) \
+       $(GTK2_CFLAGS) \
+       $(PANGO_CFLAGS) \
+       $(GLIB_CFLAGS) \
+       $(CAIRO_CFLAGS) \
+       $(ATK_CFLAGS) \
+       $(DMALLOC_CFLAGS) \
+        $(LIBXML_CFLAGS)
+
+libgnashparser_la_SOURCES = \
+       action_buffer.cpp \
+       character_def.cpp \
+       edit_text_character_def.cpp \
+       movie_def_impl.cpp \
+       shape_character_def.cpp \
+       sprite_definition.cpp 
+
+noinst_HEADERS = \
+       action_buffer.h \
+       character_def.h \
+       bitmap_character_def.h \
+       edit_text_character_def.h \
+       movie_definition.h \
+       movie_def_impl.h \
+       shape_character_def.h \
+       sprite_definition.h 
+
+libgnashparser_la_LIBADD = \
+       ../../libbase/libgnashbase.la 
+
+# Rebuild with GCC 4.x Mudflap support
+mudflap:
+       @echo "Rebuilding with GCC Mudflap support"
+       $(MAKE) CXXFLAGS="$(CXXFLAGS) -fmudflap" LDFLAGS="$(LDFLAGS) -lmudflap"
+
+clean-hook:
+       -rm -f core.*
+

Index: server/parser/action_buffer.cpp
===================================================================
RCS file: server/parser/action_buffer.cpp
diff -N server/parser/action_buffer.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/parser/action_buffer.cpp     24 Aug 2006 00:57:20 -0000      1.1
@@ -0,0 +1,479 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+// 
+// This program 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 General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+// Linking Gnash statically or dynamically with other modules is making a
+// combined work based on Gnash. Thus, the terms and conditions of the GNU
+// General Public License cover the whole combination.
+//
+// As a special exception, the copyright holders of Gnash give you
+// permission to combine Gnash with free software programs or libraries
+// that are released under the GNU LGPL and with code included in any
+// release of Talkback distributed by the Mozilla Foundation. You may
+// copy and distribute such a system following the terms of the GNU GPL
+// for all but the LGPL-covered parts and Talkback, and following the
+// LGPL for the LGPL-covered parts.
+//
+// Note that people who make modified versions of Gnash are not obligated
+// to grant this special exception for their modified versions; it is their
+// choice whether to do so. The GNU General Public License gives permission
+// to release a modified version without this exception; this exception
+// also makes it possible to release a modified version which carries
+// forward this exception.
+//
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "action_buffer.h"
+#include "ActionExec.h"
+#include "log.h"
+#include "stream.h"
+
+#include "swf.h"
+#include "ASHandlers.h"
+#include "as_environment.h"
+
+#include <typeinfo> 
+
+#if !defined(_WIN32) && !defined(WIN32)
+# include <pthread.h> 
+#endif
+
+#include <string>
+#include <stdlib.h> // for strtod
+
+using namespace gnash;
+using namespace SWF;
+using std::string;
+using std::endl;
+
+
+namespace gnash {
+
+static const SWFHandlers& ash = SWFHandlers::instance();
+
+action_buffer::action_buffer()
+    :
+    m_decl_dict_processed_at(-1)
+{
+//     static int count=0;
+//     printf("Action buffer %d created\n", ++count);
+}
+
+
+void
+action_buffer::read(stream* in)
+{
+    // Read action bytes.
+    for (;;) {
+#if 0
+       size_t instruction_start = m_buffer.size();
+       size_t pc = m_buffer.size();
+#endif
+
+       uint8_t action_id = in->read_u8();
+       m_buffer.push_back(action_id);
+       
+       if (action_id & 0x80) {
+           // Action contains extra data.  Read it.
+           uint16_t length = in->read_u16();
+           m_buffer.push_back(length & 0x0FF);
+           m_buffer.push_back((length >> 8) & 0x0FF);
+           for (uint16_t i = 0; i < length; i++) {
+               uint8_t b = in->read_u8();
+               m_buffer.push_back(b);
+           }
+       }
+       
+       if (action_id == SWF::ACTION_END)
+       {
+           // end of action buffer.
+           break;
+       }
+    }
+}
+
+
+/*public*/
+void
+action_buffer::process_decl_dict(size_t start_pc, size_t stop_pc) const
+{
+    assert(stop_pc <= m_buffer.size());
+    
+    if (static_cast<size_t>(m_decl_dict_processed_at) == start_pc) {
+       // We've already processed this decl_dict.
+#ifndef NDEBUG
+       int count = read_int16(start_pc+3);
+       assert((int) m_dictionary.size() == count);
+#endif
+       return;
+    }
+    
+    if (m_decl_dict_processed_at != -1)        {
+       log_error("process_decl_dict(%zd, %zd): decl_dict was already processed 
at %d\n",
+                 start_pc,
+                 stop_pc,
+                 m_decl_dict_processed_at);
+       return;
+    }
+    
+    m_decl_dict_processed_at = start_pc;
+    
+    // Actual processing.
+    size_t i = start_pc;
+    int16 length = read_int16(i+1);
+    int16 count = read_int16(i+3);
+    i += 2;
+    
+//log_msg("Start at %d, stop at %d, length read was %d, count read was %d", 
start_pc, stop_pc, length, count);
+
+    assert(start_pc + 3 + length == stop_pc);
+    
+    m_dictionary.resize(count);
+    
+    // Index the strings.
+    for (int ct = 0; ct < count; ct++) {
+       // Point into the current action buffer.
+       m_dictionary[ct] = (const char*) &m_buffer[3 + i];
+       
+       while (m_buffer[3 + i]) {
+           // safety check.
+           if (i >= stop_pc) {
+               log_error("action buffer dict length exceeded\n");
+               
+               // Jam something into the remaining (invalid) entries.
+               while (ct < count) {
+                   m_dictionary[ct] = "<invalid>";
+                   ct++;
+               }
+               return;
+           }
+           i++;
+       }
+       i++;
+    }
+}
+
+// Interpret the actions in this action buffer, and evaluate
+// them in the given environment.  Execute our whole buffer,
+// without any arguments passed in.
+void
+action_buffer::execute(as_environment* env) const
+{
+       assert(env);
+
+       int local_stack_top = env->get_local_frame_top();
+       env->add_frame_barrier();
+
+       ActionExec exec(*this, *env);
+       exec();
+    
+       env->set_local_frame_top(local_stack_top);
+}
+
+// Interpret the specified subset of the actions in our
+// buffer.  Caller is responsible for cleaning up our local
+// stack frame (it may have passed its arguments in via the
+// local stack frame).
+// 
+// The is_function2 flag determines whether to use global or local registers.
+void
+action_buffer::execute(
+    as_environment* env,
+    size_t start_pc,
+    size_t exec_bytes, // used when invoked as a function call
+    as_value* retval, // used when invoked as a function call
+    const std::vector<with_stack_entry>& initial_with_stack,
+    bool is_function2) const
+{
+       assert(env);
+       ActionExec exec(*this, *env, start_pc, exec_bytes, retval,
+               initial_with_stack, is_function2);
+       exec();
+}
+
+// Disassemble one instruction to the log.
+static void
+disasm(const unsigned char* instruction_data)
+{    
+
+    as_arg_t fmt = ARG_HEX;
+    action_type        action_id = (action_type)instruction_data[0];
+    unsigned char num[10];
+    memset(num, 0, 10);
+
+    dbglogfile.setStamp(false);
+    // Show instruction.
+    if (action_id > ash.lastType()) {
+       dbglogfile << "<unknown>[0x" << action_id  << "]" << endl;
+    } else {
+       dbglogfile << ash[action_id].getName().c_str() << endl;
+       fmt = ash[action_id].getArgFormat();
+    }
+
+    // Show instruction argument(s).
+    if (action_id & 0x80) {
+       assert(fmt != ARG_NONE);
+       int length = instruction_data[1] | (instruction_data[2] << 8);
+       if (fmt == ARG_HEX) {
+           for (int i = 0; i < length; i++) {
+               hexify(num, (const unsigned char *)&instruction_data[3 + i], 1, 
false);
+               dbglogfile << "0x" << num << " ";
+//             dbglogfile << instruction_data[3 + i] << " ";
+           }
+           dbglogfile << endl;
+       } else if (fmt == ARG_STR) {
+           string str;
+           for (int i = 0; i < length; i++) {
+               str = instruction_data[3 + i];
+           }
+           dbglogfile << "\"" << str.c_str() << "\"" << endl;
+       } else if (fmt == ARG_U8) {
+           int val = instruction_data[3];
+           dbglogfile << " " << val << endl;
+       } else if (fmt == ARG_U16) {
+           int val = instruction_data[3] | (instruction_data[4] << 8);
+           dbglogfile << " " << val << endl;
+       } else if (fmt == ARG_S16) {
+           int val = instruction_data[3] | (instruction_data[4] << 8);
+           if (val & 0x8000) val |= ~0x7FFF;   // sign-extend
+           dbglogfile << " " << val << endl;
+       } else if (fmt == ARG_PUSH_DATA) {
+           dbglogfile << endl;
+           int i = 0;
+           while (i < length) {
+               int     type = instruction_data[3 + i];
+               i++;
+               if (type == 0) {
+                   // string
+                   string str;
+                   while (instruction_data[3 + i]) {
+                       str += instruction_data[3 + i];
+                       i++;
+                   }
+                   i++;
+                   dbglogfile << "\t\"" << str.c_str() << "\"" << endl;
+               } else if (type == 1) {
+                   // float (little-endian)
+                   union {
+                       float   f;
+                       uint32_t        i;
+                   } u;
+                   compiler_assert(sizeof(u) == sizeof(u.i));
+                   
+                   memcpy(&u.i, instruction_data + 3 + i, 4);
+                   u.i = swap_le32(u.i);
+                   i += 4;
+                   
+                   dbglogfile << "(float) " << u.f << endl;
+               } else if (type == 2) {
+                   dbglogfile << "NULL" << endl;
+               } else if (type == 3) {
+                   dbglogfile << "undef" << endl;
+               } else if (type == 4) {
+                   // contents of register
+                   int reg = instruction_data[3 + i];
+                   i++;
+                   dbglogfile << "reg[" << reg << "]" << endl;
+               } else if (type == 5) {
+                   int bool_val = instruction_data[3 + i];
+                   i++;
+                   dbglogfile << "bool(" << bool_val << ")" << endl;
+               } else if (type == 6) {
+                   // double
+                   // wacky format: 45670123
+                   union {
+                       double  d;
+                       uint64  i;
+                       struct {
+                           uint32_t    lo;
+                           uint32_t    hi;
+                       } sub;
+                   } u;
+                   compiler_assert(sizeof(u) == sizeof(u.i));
+                   
+                   memcpy(&u.sub.hi, instruction_data + 3 + i, 4);
+                   memcpy(&u.sub.lo, instruction_data + 3 + i + 4, 4);
+                   u.i = swap_le64(u.i);
+                   i += 8;
+                   
+                   dbglogfile << "(double) " << u.d << endl;
+               } else if (type == 7) {
+                   // int32
+                   int32_t     val = instruction_data[3 + i]
+                       | (instruction_data[3 + i + 1] << 8)
+                       | (instruction_data[3 + i + 2] << 16)
+                       | (instruction_data[3 + i + 3] << 24);
+                   i += 4;
+                   dbglogfile << "(int) " << val << endl;
+               } else if (type == 8) {
+                   int id = instruction_data[3 + i];
+                   i++;
+                   dbglogfile << "dict_lookup[" << id << "]" << endl;
+               } else if (type == 9) {
+                   int id = instruction_data[3 + i] | (instruction_data[3 + i 
+ 1] << 8);
+                   i += 2;
+                   dbglogfile << "dict_lookup_lg[" << id << "]" << endl;
+               }
+           }
+       } else if (fmt == ARG_DECL_DICT) {
+           int i = 0;
+           int count = instruction_data[3 + i] | (instruction_data[3 + i + 1] 
<< 8);
+           i += 2;
+           
+           dbglogfile << " [" << count << "]" << endl;
+           
+           // Print strings.
+           for (int ct = 0; ct < count; ct++) {
+               dbglogfile << "\t" << endl;     // indent
+               
+               string str;
+               while (instruction_data[3 + i]) {
+                       // safety check.
+                   if (i >= length) {
+                       dbglogfile << "<disasm error -- length exceeded>" << 
endl;
+                       break;
+                   }
+                   str += instruction_data[3 + i];
+                   i++;
+               }
+               dbglogfile << "\"" << str.c_str() << "\"" << endl;
+               i++;
+           }
+       } else if (fmt == ARG_FUNCTION2) {
+           // Signature info for a function2 opcode.
+           int i = 0;
+           const char* function_name = (const char*) &instruction_data[3 + i];
+           i += strlen(function_name) + 1;
+           
+           int arg_count = instruction_data[3 + i] | (instruction_data[3 + i + 
1] << 8);
+           i += 2;
+           
+           int reg_count = instruction_data[3 + i];
+           i++;
+
+           dbglogfile << "\t\tname = '" << function_name << "'"
+                      << " arg_count = " << arg_count
+                      << " reg_count = " << reg_count << endl;
+           
+           uint16      flags = (instruction_data[3 + i]) | (instruction_data[3 
+ i + 1] << 8);
+           i += 2;
+           
+           // @@ What is the difference between "super" and "_parent"?
+           
+           bool        preload_global = (flags & 0x100) != 0;
+           bool        preload_parent = (flags & 0x80) != 0;
+           bool        preload_root   = (flags & 0x40) != 0;
+           bool        suppress_super = (flags & 0x20) != 0;
+           bool        preload_super  = (flags & 0x10) != 0;
+           bool        suppress_args  = (flags & 0x08) != 0;
+           bool        preload_args   = (flags & 0x04) != 0;
+           bool        suppress_this  = (flags & 0x02) != 0;
+           bool        preload_this   = (flags & 0x01) != 0;
+           
+           log_msg("\t\t        pg = %d\n"
+                   "\t\t        pp = %d\n"
+                   "\t\t        pr = %d\n"
+                   "\t\tss = %d, ps = %d\n"
+                   "\t\tsa = %d, pa = %d\n"
+                   "\t\tst = %d, pt = %d\n",
+                   int(preload_global),
+                   int(preload_parent),
+                   int(preload_root),
+                   int(suppress_super),
+                   int(preload_super),
+                   int(suppress_args),
+                   int(preload_args),
+                   int(suppress_this),
+                   int(preload_this));
+           
+           for (int argi = 0; argi < arg_count; argi++) {
+               int     arg_register = instruction_data[3 + i];
+               i++;
+               const char*     arg_name = (const char*) &instruction_data[3 + 
i];
+               i += strlen(arg_name) + 1;
+               
+               dbglogfile << "\t\targ[" << argi << "]"
+                          << " - reg[" << arg_register << "]"
+                          << " - '" << arg_name << "'" << endl;
+           }
+           
+           int function_length = instruction_data[3 + i] | (instruction_data[3 
+ i + 1] << 8);
+           i += 2;
+           
+           dbglogfile << "\t\tfunction length = " << function_length << endl;
+       }
+    } else {
+       dbglogfile << endl;
+    }
+    dbglogfile.setStamp(true);
+}
+
+// Disassemble one instruction to the log.
+void
+action_buffer::log_disasm(size_t pc) const
+{    
+       const unsigned char* instruction_data =
+               (const unsigned char *)&m_buffer[pc];
+       disasm(instruction_data);
+}
+
+
+float
+action_buffer::read_float_little(size_t pc) const
+{
+       union {
+               float   f;
+               uint32_t        i;
+       } u;
+       compiler_assert(sizeof(u) == sizeof(u.i));
+       memcpy(&u.i, &m_buffer[pc], 4);
+       u.i = swap_le32(u.i);
+       return u.f;
+}
+
+double
+action_buffer::read_double_wacky(size_t pc) const
+{
+       // double
+       // wacky format: 45670123
+       union {
+               double  d;
+               uint64  i;
+               struct {
+                       uint32_t        lo;
+                       uint32_t        hi;
+               } sub;
+       } u;
+
+       compiler_assert(sizeof(u) == sizeof(u.i));
+
+       // this works, but is pretty dirty
+       memcpy(&u.sub.hi, &m_buffer[pc], 4);
+       memcpy(&u.sub.lo, &m_buffer[pc + 4], 4);
+       u.i = swap_le64(u.i);
+
+       return u.d;
+}
+
+}
+
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:

Index: server/parser/action_buffer.h
===================================================================
RCS file: server/parser/action_buffer.h
diff -N server/parser/action_buffer.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/parser/action_buffer.h       24 Aug 2006 00:57:20 -0000      1.1
@@ -0,0 +1,250 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+// 
+// This program 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 General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+// Linking Gnash statically or dynamically with other modules is making a
+// combined work based on Gnash. Thus, the terms and conditions of the GNU
+// General Public License cover the whole combination.
+//
+// As a special exception, the copyright holders of Gnash give you
+// permission to combine Gnash with free software programs or libraries
+// that are released under the GNU LGPL and with code included in any
+// release of Talkback distributed by the Mozilla Foundation. You may
+// copy and distribute such a system following the terms of the GNU GPL
+// for all but the LGPL-covered parts and Talkback, and following the
+// LGPL for the LGPL-covered parts.
+//
+// Note that people who make modified versions of Gnash are not obligated
+// to grant this special exception for their modified versions; it is their
+// choice whether to do so. The GNU General Public License gives permission
+// to release a modified version without this exception; this exception
+// also makes it possible to release a modified version which carries
+// forward this exception.
+// 
+//
+//
+
+#ifndef GNASH_ACTION_BUFFER_H
+#define GNASH_ACTION_BUFFER_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#include "gnash.h"
+//#include "as_object.h"
+#include "types.h"
+#include <wchar.h>
+
+#include "container.h"
+#include "smart_ptr.h"
+//#include "log.h"
+#include "with_stack_entry.h"
+
+// Forward declarations
+namespace gnash {
+       struct as_environment;
+       struct as_value;
+       namespace SWF {
+               class ActionHandler;
+       }
+}
+
+
+namespace gnash {
+
+class ActionExec;
+
+/// A code segment.
+//
+/// This currently holds the actions in a memory
+/// buffer, but I'm workin toward making this unneeded
+/// so to eventually use a gnash::stream directly and
+/// avoid full loads. (not before profiling!).
+//
+class action_buffer
+{
+
+public:
+
+       friend class ActionExec;
+
+       action_buffer();
+
+       /// Read action bytes from input stream
+       void    read(stream* in);
+
+       /// \brief
+       /// Interpret the actions in this action buffer, and evaluate
+       /// them in the given environment. 
+       //
+       /// Execute our whole buffer,
+       /// without any arguments passed in.
+       /// 
+       /// FIXME: obsolete this, use ActionExec instead.
+       ///
+       void    execute(as_environment* env) const;
+
+       /// Interpret the specified subset of the actions in our buffer.
+       //
+       /// Caller is responsible for cleaning up our local
+       /// stack frame (it may have passed its arguments in via the
+       /// local stack frame).
+       ///
+       /// FIXME: obsolete this, use ActionExec instead.
+       ///
+       void execute(
+               as_environment* env,
+               size_t start_pc,
+               size_t exec_bytes,
+               as_value* retval, // we should probably drop this parameter
+               const std::vector<with_stack_entry>& initial_with_stack,
+               bool is_function2) const;
+
+       bool is_null() const
+       {
+               return m_buffer.size() < 1 || m_buffer[0] == 0;
+       }
+
+       // kept for backward compatibility, should drop and see
+       // what breaks.
+       size_t get_length() const { return size(); }
+
+       size_t size() const { return m_buffer.size(); }
+
+       uint8_t operator[] (size_t off) const
+       {
+               assert(off < m_buffer.size() );
+               return m_buffer[off];
+       }
+
+       /// Disassemble instruction at given offset to the log.
+       void log_disasm(size_t pc) const;
+
+       /// Get a null-terminated string from given offset
+       //
+       /// Useful to hide complexity of underlying buffer access.
+       ///
+       const char* read_string(size_t pc) const
+       {
+               return (const char*)(&m_buffer[pc]);
+       }
+
+       /// Get an integer value from given offset
+       //
+       /// Useful to hide complexity of underlying buffer access.
+       ///
+       int16_t read_int16(size_t pc) const
+       {
+               int ret = m_buffer[pc] | (m_buffer[pc + 1] << 8);
+               return ret;
+       }
+
+       /// Read a 32-bit integer starting at given offset.
+       //
+       /// Useful to hide complexity of underlying buffer access.
+       ///
+       int32_t read_int32(size_t pc) const
+       {
+               int32_t val = m_buffer[pc]
+                     | (m_buffer[pc + 1] << 8)
+                     | (m_buffer[pc + 2] << 16)
+                     | (m_buffer[pc + 3] << 24);
+               return val;
+       }
+
+       /// Read a little-endian 32-bit float starting at given offset
+       //
+       /// Useful to hide complexity of underlying buffer access.
+       ///
+       float read_float_little(size_t pc) const;
+
+       /// Read a 64-bit double starting at given offset.
+       //
+       /// wacky format: 45670123
+       /// Useful to hide complexity of underlying buffer access.
+       ///
+       double read_double_wacky(size_t pc) const;
+
+       /// Return number of entries in the constant pool
+       size_t dictionary_size() const
+       {
+               return m_dictionary.size();
+       }
+
+       /// Return a value from the constant pool
+       const char* dictionary_get(size_t n) const
+       {
+               return m_dictionary[n];
+       }
+
+       /// \brief
+       /// Interpret the SWF::ACTION_CONSTANTPOOL opcode. 
+       //
+       /// Don't read stop_pc or later. 
+       ///
+       /// A dictionary is some static strings embedded in the
+       /// action buffer; there should only be one dictionary per
+       /// action buffer.
+       ///
+       /// NOTE: Normally the dictionary is declared as the first
+       /// action in an action buffer, but I've seen what looks like
+       /// some form of copy protection that amounts to:
+       ///
+       /// <start of action buffer>
+       ///          push true
+       ///          branch_if_true label
+       ///          decl_dict   [0]   // this is never executed, but has lots 
of orphan data declared in the opcode
+       /// label:   // (embedded inside the previous opcode; looks like an 
invalid jump)
+       ///          ... "protected" code here, including the real decl_dict 
opcode ...
+       ///          <end of the dummy decl_dict [0] opcode>
+       ///
+       /// So we just interpret the first decl_dict we come to, and
+       /// cache the results.  If we ever hit a different decl_dict in
+       /// the same action_buffer, then we log an error and ignore it.
+       ///
+       void process_decl_dict(size_t start_pc, size_t stop_pc) const;
+
+private:
+
+       // Don't put these as values in std::vector<>!  They contain
+       // internal pointers and cannot be moved or copied.
+       // If you need to keep an array of them, keep pointers
+       // to new'd instances.
+       action_buffer(const action_buffer& /*a*/) { assert(0); }
+
+       /// the code itself, as read from the SWF
+       std::vector<uint8_t> m_buffer;
+
+       /// The dictionary
+       mutable std::vector<const char*> m_dictionary;
+
+       /// FIXME: move to ActionExec
+       mutable int m_decl_dict_processed_at;
+
+};
+
+
+}      // end namespace gnash
+
+
+#endif // GNASH_ACTION_BUFFER_H
+
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:

Index: server/parser/bitmap_character_def.h
===================================================================
RCS file: server/parser/bitmap_character_def.h
diff -N server/parser/bitmap_character_def.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/parser/bitmap_character_def.h        24 Aug 2006 00:57:20 -0000      
1.1
@@ -0,0 +1,114 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+// 
+// This program 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 General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+// Linking Gnash statically or dynamically with other modules is making a
+// combined work based on Gnash. Thus, the terms and conditions of the GNU
+// General Public License cover the whole combination.
+//
+// As a special exception, the copyright holders of Gnash give you
+// permission to combine Gnash with free software programs or libraries
+// that are released under the GNU LGPL and with code included in any
+// release of Talkback distributed by the Mozilla Foundation. You may
+// copy and distribute such a system following the terms of the GNU GPL
+// for all but the LGPL-covered parts and Talkback, and following the
+// LGPL for the LGPL-covered parts.
+//
+// Note that people who make modified versions of Gnash are not obligated
+// to grant this special exception for their modified versions; it is their
+// choice whether to do so. The GNU General Public License gives permission
+// to release a modified version without this exception; this exception
+// also makes it possible to release a modified version which carries
+// forward this exception.
+// 
+//
+//
+
+#ifndef GNASH_BITMAP_CHARACTER_DEF_H
+#define GNASH_BITMAP_CHARACTER_DEF_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "gnash.h" // for bitmap_info definition
+#include "character_def.h" // for character_def inheritance
+#include "action.h"
+#include "types.h"
+#include "log.h"
+#include "container.h"
+#include "utility.h"
+#include "smart_ptr.h"
+//#include "movie_interface.h"
+#include <stdarg.h>
+
+#include <cassert>
+
+namespace gnash {
+
+/// What's this ? An interface ?
+struct bitmap_character_def : public character_def
+{
+    virtual gnash::bitmap_info*        get_bitmap_info() = 0;
+};
+
+#if 1
+/// Bitmap character
+struct bitmap_character : public bitmap_character_def
+{
+    bitmap_character(bitmap_info* bi)
+       :
+       m_bitmap_info(bi)
+       {
+       }
+
+//             bitmap_character(image::rgb* image)
+//             {
+//                     assert(image != 0);
+
+//                     // Create our bitmap info, from our image.
+//                     m_bitmap_info = 
gnash::render::create_bitmap_info_rgb(image);
+//             }
+
+//             bitmap_character(image::rgba* image)
+//             {
+//                     assert(image != 0);
+
+//                     // Create our bitmap info, from our image.
+//                     m_bitmap_info = 
gnash::render::create_bitmap_info_rgba(image);
+//             }
+
+    gnash::bitmap_info*        get_bitmap_info()
+       {
+           return m_bitmap_info.get_ptr();
+       }
+
+private:
+    smart_ptr<gnash::bitmap_info>      m_bitmap_info;
+};
+
+#endif
+
+
+}      // end namespace gnash
+
+
+#endif // GNASH_BITMAP_CHARACTER_DEF_H
+
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:

Index: server/parser/character_def.cpp
===================================================================
RCS file: server/parser/character_def.cpp
diff -N server/parser/character_def.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/parser/character_def.cpp     24 Aug 2006 00:57:20 -0000      1.1
@@ -0,0 +1,60 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+// 
+// This program 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 General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+// Linking Gnash statically or dynamically with other modules is making a
+// combined work based on Gnash. Thus, the terms and conditions of the GNU
+// General Public License cover the whole combination.
+//
+// As a special exception, the copyright holders of Gnash give you
+// permission to combine Gnash with free software programs or libraries
+// that are released under the GNU LGPL and with code included in any
+// release of Talkback distributed by the Mozilla Foundation. You may
+// copy and distribute such a system following the terms of the GNU GPL
+// for all but the LGPL-covered parts and Talkback, and following the
+// LGPL for the LGPL-covered parts.
+//
+// Note that people who make modified versions of Gnash are not obligated
+// to grant this special exception for their modified versions; it is their
+// choice whether to do so. The GNU General Public License gives permission
+// to release a modified version without this exception; this exception
+// also makes it possible to release a modified version which carries
+// forward this exception.
+// 
+//
+//
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <character_def.h>
+#include <generic_character.h>
+
+namespace gnash
+{
+
+character*
+character_def::create_character_instance(character* parent, int id)
+{
+       return new generic_character(this, parent, id);
+}
+
+}
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:

Index: server/parser/character_def.h
===================================================================
RCS file: server/parser/character_def.h
diff -N server/parser/character_def.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/parser/character_def.h       24 Aug 2006 00:57:20 -0000      1.1
@@ -0,0 +1,132 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+// 
+// This program 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 General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+// Linking Gnash statically or dynamically with other modules is making a
+// combined work based on Gnash. Thus, the terms and conditions of the GNU
+// General Public License cover the whole combination.
+//
+// As a special exception, the copyright holders of Gnash give you
+// permission to combine Gnash with free software programs or libraries
+// that are released under the GNU LGPL and with code included in any
+// release of Talkback distributed by the Mozilla Foundation. You may
+// copy and distribute such a system following the terms of the GNU GPL
+// for all but the LGPL-covered parts and Talkback, and following the
+// LGPL for the LGPL-covered parts.
+//
+// Note that people who make modified versions of Gnash are not obligated
+// to grant this special exception for their modified versions; it is their
+// choice whether to do so. The GNU General Public License gives permission
+// to release a modified version without this exception; this exception
+// also makes it possible to release a modified version which carries
+// forward this exception.
+// 
+//
+
+#ifndef GNASH_CHARACTER_DEF_H
+#define GNASH_CHARACTER_DEF_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "resource.h" // for inheritance from resource class
+
+// Forward declarations
+class tu_file;
+namespace gnash {
+       class character;
+       struct cache_options;
+       //class sprite_instance;
+}
+
+namespace gnash {
+
+/// Immutable data representing the template of a movie element.
+//
+/// This is not really a public interface.  It's here so it
+/// can be mixed into movie_definition and sprite_definition,
+/// without using multiple inheritance.
+///
+struct character_def : public resource
+{
+private:
+       int     m_id;
+       
+public:
+       character_def()
+               :
+               m_id(-1)
+               {
+               }
+       
+       virtual ~character_def() {}
+       
+       virtual void display(character* /*instance_info*/)
+       {
+       }
+
+       virtual bool point_test_local(float /*x*/, float /*y*/)
+       {
+               return false;
+       }
+
+       virtual float get_height_local()
+       {
+               return 0.0f;
+       }
+
+       virtual float get_width_local()
+       {
+               return 0.0f;
+       }
+       
+       /// Should stick the result in a smart_ptr immediately.
+       //
+       /// default is to make a generic_character
+       ///
+       virtual character* create_character_instance(character* parent,
+                       int id);
+       
+       // From resource interface.
+       virtual character_def*  cast_to_character_def()
+       {
+               return this;
+       }
+       
+       //
+       // Caching.
+       //
+       
+       virtual void output_cached_data(tu_file* /*out*/,
+                       const cache_options& /*options*/)
+       {
+       }
+
+       virtual void    input_cached_data(tu_file* /*in*/)
+       {
+       }
+};
+
+
+}      // namespace gnash
+
+#endif // GNASH_CHARACTER_DEF_H
+
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:

Index: server/parser/edit_text_character_def.cpp
===================================================================
RCS file: server/parser/edit_text_character_def.cpp
diff -N server/parser/edit_text_character_def.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/parser/edit_text_character_def.cpp   24 Aug 2006 00:57:20 -0000      
1.1
@@ -0,0 +1,137 @@
+// text.cpp    -- Thatcher Ulrich <address@hidden> 2003
+
+// This source code has been donated to the Public Domain.  Do
+// whatever you want with it.
+
+// Code for the text tags.
+
+
+#include "stream.h"
+#include "log.h"
+#include "movie_definition.h" // for m_root_def use
+
+#include "edit_text_character_def.h"
+#include "edit_text_character.h"
+
+namespace gnash {
+
+// Forward declarations
+struct movie_definition;
+
+void
+edit_text_character_def::read(stream* in, int tag_type,
+               movie_definition* m)
+{
+       assert(m != NULL);
+       assert(tag_type == SWF::DEFINEEDITTEXT); // 37
+
+       m_rect.read(in);
+
+       in->align();
+       bool    has_text = in->read_uint(1) ? true : false;
+       m_word_wrap = in->read_uint(1) ? true : false;
+       m_multiline = in->read_uint(1) ? true : false;
+       m_password = in->read_uint(1) ? true : false;
+       m_readonly = in->read_uint(1) ? true : false;
+       bool    has_color = in->read_uint(1) ? true : false;
+       bool    has_max_length = in->read_uint(1) ? true : false;
+       bool    has_font = in->read_uint(1) ? true : false;
+
+       in->read_uint(1);       // reserved
+       m_auto_size = in->read_uint(1) ? true : false;
+       bool    has_layout = in->read_uint(1) ? true : false;
+       m_no_select = in->read_uint(1) ? true : false;
+       m_border = in->read_uint(1) ? true : false;
+       in->read_uint(1);       // reserved
+       m_html = in->read_uint(1) ? true : false;
+       m_use_outlines = in->read_uint(1) ? true : false;
+
+       if (has_font)
+       {
+               m_font_id = in->read_u16();
+               m_text_height = in->read_u16();
+       }
+
+       if (has_color)
+       {
+               m_color.read_rgba(in);
+       }
+
+       if (has_max_length)
+       {
+               m_max_length = in->read_u16();
+       }
+
+       if (has_layout)
+       {
+               m_alignment = (alignment) in->read_u8();
+               //m_left_margin = (float) in->read_u16();
+               m_left_margin = in->read_u16();
+               //m_right_margin = (float) in->read_u16();
+               m_right_margin = in->read_u16();
+               m_indent = in->read_s16();
+               m_leading = in->read_s16();
+       }
+
+       char*   name = in->read_string();
+       m_default_name = name;
+       delete [] name;
+
+       if (has_text)
+       {
+               char*   str = in->read_string();
+               m_default_text = str;
+               delete [] str;
+       }
+
+       IF_VERBOSE_PARSE (
+               log_parse("edit_text_char:\n"
+                       " default varname = %s\n"
+                       " text = ``%s''\n"
+                       " font_id: %d\n"
+                       " text_height: %d",
+                       m_default_name.c_str(),
+                       m_default_text.c_str(),
+                       m_font_id,
+                       m_text_height);
+       );
+}
+
+const font*
+edit_text_character_def::get_font() 
+{
+       if (m_font == NULL)
+       {
+               // Resolve the font, if possible.
+               m_font = m_root_def->get_font(m_font_id);
+               if (m_font == NULL)
+               {
+                       log_error("error: text style with undefined font; 
font_id = %d\n", m_font_id);
+               }
+       }
+
+       return m_font;
+}
+
+character*
+edit_text_character_def::create_character_instance(character* parent,
+               int id)
+{
+       // Resolve the font, if possible
+       get_font();
+       edit_text_character* ch = new edit_text_character(parent, this, id);
+
+       ch->set_name(m_default_name.c_str());
+
+       return ch;
+}
+
+
+} // namespace gnash
+
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:
+

Index: server/parser/edit_text_character_def.h
===================================================================
RCS file: server/parser/edit_text_character_def.h
diff -N server/parser/edit_text_character_def.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/parser/edit_text_character_def.h     24 Aug 2006 00:57:20 -0000      
1.1
@@ -0,0 +1,308 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+// 
+// This program 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 General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+// Linking Gnash statically or dynamically with other modules is making a
+// combined work based on Gnash. Thus, the terms and conditions of the GNU
+// General Public License cover the whole combination.
+//
+// As a special exception, the copyright holders of Gnash give you
+// permission to combine Gnash with free software programs or libraries
+// that are released under the GNU LGPL and with code included in any
+// release of Talkback distributed by the Mozilla Foundation. You may
+// copy and distribute such a system following the terms of the GNU GPL
+// for all but the LGPL-covered parts and Talkback, and following the
+// LGPL for the LGPL-covered parts.
+//
+// Note that people who make modified versions of Gnash are not obligated
+// to grant this special exception for their modified versions; it is their
+// choice whether to do so. The GNU General Public License gives permission
+// to release a modified version without this exception; this exception
+// also makes it possible to release a modified version which carries
+// forward this exception.
+// 
+//
+
+
+#ifndef _GNASH_EDIT_TEXT_CHARACTER_DEF_H_
+#define _GNASH_EDIT_TEXT_CHARACTER_DEF_H_
+
+#include "character_def.h" // for inheritance
+#include "gnash.h" // for composition (struct rect)
+#include "textformat.h" // for composition
+
+namespace gnash {
+
+// Forward declarations
+struct movie_definition;
+
+/// \brief
+/// A definition for a text display character, whose text can
+/// be changed at runtime (by script or host).
+/// This object is defined by SWF tag 37 (SWF::DEFINEEDITTEXT)
+///
+class edit_text_character_def : public character_def
+{
+
+public:
+
+       /// Text alignment values
+       enum alignment
+       {
+               ALIGN_LEFT = 0,
+               ALIGN_RIGHT,
+               ALIGN_CENTER,
+               /// probably don't need to implement...
+               ALIGN_JUSTIFY
+       };
+
+       edit_text_character_def(movie_definition* root_def)
+               :
+               m_root_def(root_def),
+               m_format(),
+               m_word_wrap(false),
+               m_multiline(false),
+               m_password(false),
+               m_readonly(false),
+               m_auto_size(false),
+               m_no_select(false),
+               m_border(false),
+               m_html(false),
+               m_use_outlines(false),
+               m_font_id(-1),
+               m_font(NULL),
+               m_text_height(1),
+               m_max_length(0),
+               m_alignment(ALIGN_LEFT),
+               m_left_margin(0),
+               m_right_margin(0),
+               m_indent(0),
+               m_leading(0)
+       {
+               assert(m_root_def);
+
+               m_color.set(0, 0, 0, 255);
+       }
+
+       /// Set the format of the text
+       void    set_format(text_format &format)
+       {
+               m_format = format;
+       }
+       
+       ~edit_text_character_def()
+       {
+       }
+
+       /// Get width of this definition (by definition)
+       float width() const { return m_rect.width(); }
+
+       /// Get height of this definition (by definition)
+       float height() const { return m_rect.height(); }
+
+       /// Create an instance of this character
+       character* create_character_instance(character* parent, int id);
+
+       /// Initialize from SWF input stream (tag 37)
+       void read(stream* in, int tag_type, movie_definition* m);
+
+       /// Return a reference to the default text associated
+       /// with this EditText definition.
+       const tu_string& get_default_text() const {
+               return m_default_text;
+       }
+
+       /// Return a reference to the default name for
+       /// instances of this EditText definition. (?)
+       const tu_string& get_default_name() const {
+               return m_default_name;
+       }
+
+       /// \brief
+       /// Return the maximum length of text this widget
+       /// can hold.
+       int get_max_length() const {
+               return m_max_length;
+       }
+
+       /// Get boundaries of this movie
+       //
+       /// Return a reference to private space, copy
+       /// it if you need it  for longer then this
+       /// object's lifetime.
+       ///
+       const rect& get_bounds() const {
+               return m_rect;
+       }
+
+       /// Get right margin in twips
+       uint16_t get_right_margin() const {
+               return m_right_margin;
+       }
+
+       /// Get left margin in twips
+       uint16_t get_left_margin() const {
+               return m_left_margin;
+       }
+
+       /// Get indentation in  twips
+       uint16_t get_indent() const {
+               return m_indent;
+       }
+
+       /// Get height of font  in twips.
+       // @@ what if has_font is false ??
+       uint16_t get_font_height() const {
+               return m_text_height;
+       }
+
+       /// Get font.
+       //
+       /// Note: use add_ref() on the return if you need to keep
+       /// it alive after this definition gets destructed.
+       ///
+       const font* get_font();
+
+       /// Get color of the text
+       const rgba& get_text_color() const {
+               return m_color;
+       }
+
+       /// \brief
+       /// Get extra space between lines (in twips).
+       //
+       /// This is in addition to default font line spacing.
+       uint16_t get_leading() const {
+               return m_leading;
+       }
+
+       /// Get text alignment
+       alignment get_alignment() const {
+               return m_alignment;
+       }
+
+       /// Is border requested ?
+       bool has_border() const {
+               return m_border;
+       }
+
+       /// Word wrap requested ?
+       bool do_word_wrap() const {
+               return m_word_wrap;
+       }
+
+       /// Get root movie definition
+       movie_definition* get_root_def() {
+               return m_root_def;
+       }
+
+       bool get_readonly() const
+       {
+               return m_readonly;
+       }
+
+private:
+
+       /// Root movie_definition
+       movie_definition*       m_root_def;
+
+       rect                    m_rect;
+       tu_string               m_default_name;
+       text_format             m_format;
+       bool                    m_word_wrap;
+       bool                    m_multiline;
+       /// show asterisks instead of actual characters
+       bool                    m_password;
+       bool                    m_readonly;
+       /// resize our bound to fit the text
+       bool                    m_auto_size;
+       bool                    m_no_select;
+
+       /// forces white background and black border.
+       /// silly, but sometimes used
+       bool                    m_border;
+
+       /// Allowed HTML (from Alexi's SWF Reference).
+       //
+       /// <a href=url target=targ>...</a> -- hyperlink
+       /// <b>...</b> -- bold
+       /// <br> -- line break
+       /// <font face=name size=[+|-][0-9]+ color=#RRGGBB>...</font>  -- font 
change; size in TWIPS
+       /// <i>...</i> -- italic
+       /// <li>...</li> -- list item
+       /// <p>...</p> -- paragraph
+       /// <tab> -- insert tab
+       /// <TEXTFORMAT>  </TEXTFORMAT>
+       ///   [ BLOCKINDENT=[0-9]+ ]
+       ///   [ INDENT=[0-9]+ ]
+       ///   [ LEADING=[0-9]+ ]
+       ///   [ LEFTMARGIN=[0-9]+ ]
+       ///   [ RIGHTMARGIN=[0-9]+ ]
+       ///   [ TABSTOPS=[0-9]+{,[0-9]+} ]
+       ///
+       /// Change the different parameters as indicated. The
+       /// sizes are all in TWIPs. There can be multiple
+       /// positions for the tab stops. These are seperated by
+       /// commas.
+       /// <U>...</U> -- underline
+       ///
+       bool                    m_html;
+
+
+
+       /// \brief
+       /// When true, use specified SWF internal font. 
+       /// Otherwise, renderer picks a default font
+       bool    m_use_outlines;
+
+       int     m_font_id;
+       font*   m_font;
+
+       /// height of font text, in twips
+       uint16_t m_text_height;
+
+       /// Text color
+       rgba    m_color;
+
+       /// Maximum length of text this widget can display (number of chars?)
+       int     m_max_length;
+
+       alignment m_alignment;
+       
+       /// extra space between box's left border and text (in twips)
+       uint16_t m_left_margin;
+       //float m_left_margin;
+
+       /// extra space between box's right border and text (in twips)
+       uint16_t m_right_margin;
+       //float m_right_margin;
+
+       /// how much to indent the first line of multiline text (in twips)
+       uint16_t        m_indent;
+       //float m_indent;
+
+       /// \brief
+       /// Extra space between lines
+       /// (in addition to default font line spacing)
+       uint16_t        m_leading;
+
+       /// The default text to be displayed
+       tu_string       m_default_text;
+
+};
+
+} // namespace gnash
+
+#endif // _GNASH_EDIT_TEXT_CHARACTER_DEF_H_

Index: server/parser/movie_def_impl.cpp
===================================================================
RCS file: server/parser/movie_def_impl.cpp
diff -N server/parser/movie_def_impl.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/parser/movie_def_impl.cpp    24 Aug 2006 00:57:20 -0000      1.1
@@ -0,0 +1,1024 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+// 
+// This program 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 General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+// Linking Gnash statically or dynamically with other modules is making a
+// combined work based on Gnash. Thus, the terms and conditions of the GNU
+// General Public License cover the whole combination.
+//
+// As a special exception, the copyright holders of Gnash give you
+// permission to combine Gnash with free software programs or libraries
+// that are released under the GNU LGPL and with code included in any
+// release of Talkback distributed by the Mozilla Foundation. You may
+// copy and distribute such a system following the terms of the GNU GPL
+// for all but the LGPL-covered parts and Talkback, and following the
+// LGPL for the LGPL-covered parts.
+//
+// Note that people who make modified versions of Gnash are not obligated
+// to grant this special exception for their modified versions; it is their
+// choice whether to do so. The GNU General Public License gives permission
+// to release a modified version without this exception; this exception
+// also makes it possible to release a modified version which carries
+// forward this exception.
+// 
+//
+#ifdef HAVE_PTHREADS
+#include <pthread.h>
+#endif
+
+#include <iostream>
+#include <string>
+
+#include "movie_def_impl.h"
+#include "movie_definition.h" // for inheritance
+#include "movie_instance.h"
+#include "tu_file.h"
+#include "zlib_adapter.h"
+#include "stream.h"
+#include "jpeg.h"
+#include "fontlib.h"
+#include "font.h"
+#include "log.h"
+//#include "Sprite.h"
+#include "sprite_instance.h"
+#include "render.h"
+#include "bitmap_character_def.h"
+#include "smart_ptr.h"
+#include "swf/TagLoadersTable.h"
+#include "execute_tag.h"
+#include "movie_root.h"
+
+using namespace std;
+
+// Increment this when the cache data format changes.
+#define CACHE_FILE_VERSION 4
+
+// If != 0 this is the number of frames to load at each iteration
+// of the main loop. Loading in chunks greatly speeds the process up
+#define FRAMELOAD_CHUNK 0
+
+// Debug frames load
+#undef DEBUG_FRAMES_LOAD 
+
+// Define this this to load movies using a separate thread
+// (undef and it will fully load a movie before starting to play it)
+#define LOAD_MOVIES_IN_A_SEPARATE_THREAD 1
+
+// Debug threads locking
+#undef DEBUG_THREADS_LOCKING
+
+namespace gnash
+{
+
+#ifdef USE_SDL_THREADS
+
+MovieLoader::MovieLoader(movie_def_impl& md)
+       :
+       _waiting_for_frame(0),
+       _movie_def(md)
+{
+       _frame_reached_condition = SDL_CreateCond();
+       _mutex = SDL_CreateMutex();
+}
+
+MovieLoader::~MovieLoader()
+{
+       SDL_DestroyMutex(_mutex);
+       SDL_DestroyCond(_frame_reached_condition);
+}
+
+int MovieLoader::execute(void* arg)
+{
+       movie_def_impl* md = static_cast<movie_def_impl*>(arg);
+       md->read_all_swf();
+       return 0;
+}
+
+bool MovieLoader::start()
+{
+        _thread = SDL_CreateThread(execute, &_movie_def);
+        if (_thread == NULL)
+        {
+                return false;
+        }
+       return true;
+}
+
+void MovieLoader::signal_frame_loaded(size_t frameno)
+{
+       if (_waiting_for_frame &&
+               frameno >= _waiting_for_frame )
+       {
+               SDL_CondSignal(_frame_reached_condition);
+       }
+}
+
+void MovieLoader::wait_for_frame(size_t framenum)
+{
+
+       lock();
+
+       if (_movie_def.get_loading_frame() < framenum)
+       {
+               //log_msg("Waiting for frame %u to load", framenum);
+
+               assert(_waiting_for_frame == 0);
+               _waiting_for_frame = framenum;
+
+               do
+               {
+                       SDL_CondWait(_frame_reached_condition, _mutex);
+               }
+               while (_movie_def.get_loading_frame() < framenum);
+
+               _waiting_for_frame = 0;
+
+               //log_msg("Done waiting (frame %u/%u loaded)",
+               //      _movie_def.get_loading_frame(),
+               //      _movie_def.get_frame_count());
+       }
+
+       unlock();
+}
+
+void MovieLoader::lock()
+{
+       if ( -1 == SDL_mutexP(_mutex) )
+       {
+               log_error("Error unlocking MovieLoader");
+       }
+}
+
+void MovieLoader::unlock()
+{
+       if ( -1 == SDL_mutexV(_mutex) )
+       {
+               log_error("Error unlocking MovieLoader");
+       }
+}
+
+#else
+
+MovieLoader::MovieLoader(movie_def_impl& md)
+       :
+       _waiting_for_frame(0),
+       _movie_def(md)
+{
+       pthread_cond_init(&_frame_reached_condition, NULL);
+       pthread_mutex_init(&_mutex, NULL);
+}
+
+MovieLoader::~MovieLoader()
+{
+       if ( pthread_cond_destroy(&_frame_reached_condition) != 0 )
+       {
+               log_error("Error destroying MovieLoader condition");
+       }
+
+       if ( pthread_mutex_destroy(&_mutex) != 0 )
+       {
+               log_error("Error destroying MovieLoader mutex");
+       }
+}
+
+void*
+MovieLoader::execute(void* arg)
+{
+       movie_def_impl* md = static_cast<movie_def_impl*>(arg);
+       md->read_all_swf();
+       // maybe this frees all resources and that's bad !
+       //pthread_exit(NULL);
+       
+       /* Better to cancel yourself methinks: 'man 3p pthread_cancel' */
+       pthread_cancel(pthread_self());
+        pthread_testcancel();
+       return NULL;
+}
+
+bool
+MovieLoader::start()
+{
+       if ( pthread_create(&_thread, NULL, execute, &_movie_def) )
+       {
+               return false;
+       }
+
+       // should set some mutexes ?
+
+       return true;
+}
+
+void
+MovieLoader::signal_frame_loaded(size_t frameno)
+{
+       if (_waiting_for_frame &&
+               frameno >= _waiting_for_frame )
+       {
+               pthread_cond_signal(&_frame_reached_condition);
+       }
+}
+
+void
+MovieLoader::lock()
+{
+
+#ifdef DEBUG_THREADS_LOCKING
+       // debugging
+       if ( pthread_equal(pthread_self(), _thread) ) {
+               log_msg("MovieLoader locking itself");
+       } else {
+               log_msg("MovieLoader being locked by another thread");
+       }
+#endif
+
+       if ( pthread_mutex_lock(&_mutex) != 0 )
+       {
+               log_error("Error locking MovieLoader");
+       }
+
+#ifdef DEBUG_THREADS_LOCKING
+       // debugging
+       if ( pthread_equal(pthread_self(), _thread) ) {
+               log_msg("MovieLoader locked by itself");
+       } else {
+               log_msg("MovieLoader locked by another thread");
+       }
+#endif
+}
+
+void
+MovieLoader::unlock()
+{
+
+#ifdef DEBUG_THREADS_LOCKING
+       // debugging
+       if ( pthread_equal(pthread_self(), _thread) ) {
+               log_msg("MovieLoader unlocking itself");
+       } else {
+               log_msg("MovieLoader being unlocked by another thread");
+       }
+#endif
+
+       if ( pthread_mutex_unlock(&_mutex) != 0 )
+       {
+               log_error("Error unlocking MovieLoader");
+       }
+
+#ifdef DEBUG_THREADS_LOCKING
+       // debugging
+       if ( pthread_equal(pthread_self(), _thread) ) {
+               log_msg("MovieLoader unlocked itself");
+       } else {
+               log_msg("MovieLoader unlocked by another thread");
+       }
+#endif
+}
+
+void
+MovieLoader::wait_for_frame(size_t framenum)
+{
+
+       // lock the loader so we can rely on m_loading_frame
+       lock();
+
+       if ( _movie_def.get_loading_frame() < framenum )
+       {
+               assert(_waiting_for_frame == 0);
+               _waiting_for_frame = framenum;
+               pthread_cond_wait(&_frame_reached_condition, &_mutex);
+               _waiting_for_frame = 0;
+       }
+
+       unlock();
+}
+
+#endif // PTHREAD MovieLoader
+
+
+//
+// some utility stuff
+//
+
+void   dump_tag_bytes(stream* in)
+    // Log the contents of the current tag, in hex.
+{
+    static const int   ROW_BYTES = 16;
+    char       row_buf[ROW_BYTES];
+    int        row_count = 0;
+
+    while(in->get_position() < in->get_tag_end_position())
+        {
+            int        c = in->read_u8();
+            log_msg("%02X", c);
+
+            if (c < 32) c = '.';
+            if (c > 127) c = '.';
+            row_buf[row_count] = c;
+                               
+            row_count++;
+            if (row_count >= ROW_BYTES)
+                {
+                    log_msg("    ");
+                    for (int i = 0; i < ROW_BYTES; i++)
+                        {
+                            log_msg("%c", row_buf[i]);
+                        }
+
+                    log_msg("\n");
+                    row_count = 0;
+                }
+            else
+                {
+                    log_msg(" ");
+                }
+        }
+
+    if (row_count > 0)
+        {
+            log_msg("\n");
+        }
+}
+
+
+//
+// progress callback stuff (from Vitaly)
+//
+progress_callback      s_progress_function = NULL;
+
+// Host calls this to register a function for progress bar handling
+// during loading movies.
+void
+register_progress_callback(progress_callback progress_handle)
+{
+    s_progress_function = progress_handle;
+}
+
+//
+// movie_def_impl
+//
+
+movie_def_impl::movie_def_impl(create_bitmaps_flag cbf,
+               create_font_shapes_flag cfs)
+       :
+       _tag_loaders(s_tag_loaders), // FIXME: use a class-static 
TagLoadersTable for movie_def_impl
+       m_create_bitmaps(cbf),
+       m_create_font_shapes(cfs),
+       m_frame_rate(30.0f),
+       m_frame_count(0u),
+       m_version(0),
+       m_loading_frame(0u),
+       _loaded_bytes(0u),
+       m_jpeg_in(0),
+       _loader(*this)
+{
+}
+
+movie_def_impl::~movie_def_impl()
+{
+    // Release our playlist data.
+    {for (int i = 0, n = m_playlist.size(); i < n; i++)
+        {
+            for (int j = 0, m = m_playlist[i].size(); j < m; j++)
+                {
+                    delete m_playlist[i][j];
+                }
+        }}
+
+    // Release init action data.
+    {for (size_t i = 0, n = m_init_action_list.size(); i < n; i++)
+        {
+            for (size_t j = 0, m = m_init_action_list[i].size(); j < m; j++)
+                {
+                    delete m_init_action_list[i][j];
+                }
+        }}
+
+       // It's supposed to be cleaned up in read()
+       // TODO: join with loader thread instead ?
+       //assert(m_jpeg_in.get() == NULL);
+}
+
+bool movie_def_impl::in_import_table(int character_id)
+{
+    for (int i = 0, n = m_imports.size(); i < n; i++)
+        {
+            if (m_imports[i].m_character_id == character_id)
+                {
+                    return true;
+                }
+        }
+    return false;
+}
+
+void movie_def_impl::visit_imported_movies(import_visitor* visitor)
+{
+    stringi_hash<bool> visited;        // ugh!
+
+    for (int i = 0, n = m_imports.size(); i < n; i++)
+        {
+            const import_info& inf = m_imports[i];
+            if (visited.find(inf.m_source_url) == visited.end())
+                {
+                    // Call back the visitor.
+                    visitor->visit(inf.m_source_url.c_str());
+                    visited[inf.m_source_url] = true;
+                }
+        }
+}
+
+void movie_def_impl::resolve_import(const char* source_url, movie_definition* 
source_movie)
+{
+    // @@ should be safe, but how can we verify
+    // it?  Compare a member function pointer, or
+    // something?
+    movie_def_impl*    def_impl = static_cast<movie_def_impl*>(source_movie);
+    movie_definition*  def = static_cast<movie_definition*>(def_impl);
+
+    // Iterate in reverse, since we remove stuff along the way.
+    for (int i = m_imports.size() - 1; i >= 0; i--)
+        {
+            const import_info& inf = m_imports[i];
+            if (inf.m_source_url == source_url)
+                {
+                    // Do the import.
+                    smart_ptr<resource> res = 
def->get_exported_resource(inf.m_symbol);
+                    bool        imported = true;
+
+                    if (res == NULL)
+                        {
+                            log_error("import error: resource '%s' is not 
exported from movie '%s'\n",
+                                      inf.m_symbol.c_str(), source_url);
+                        }
+                    else if (font* f = res->cast_to_font())
+                        {
+                            // Add this shared font to our fonts.
+                            add_font(inf.m_character_id, f);
+                            imported = true;
+                        }
+                    else if (character_def* ch = res->cast_to_character_def())
+                        {
+                            // Add this character to our characters.
+                            add_character(inf.m_character_id, ch);
+                            imported = true;
+                        }
+                    else
+                        {
+                            log_error("import error: resource '%s' from movie 
'%s' has unknown type\n",
+                                      inf.m_symbol.c_str(), source_url);
+                        }
+
+                    if (imported)
+                        {
+                            m_imports.erase(m_imports.begin() + i);
+
+                            // Hold a ref, to keep this source 
movie_definition alive.
+                            m_import_source_movies.push_back(source_movie);
+                        }
+                }
+        }
+}
+
+void movie_def_impl::add_character(int character_id, character_def* c)
+{
+       assert(c);
+       _dictionary.add_character(character_id, c);
+}
+
+character_def*
+movie_def_impl::get_character_def(int character_id)
+{
+#ifndef NDEBUG
+    // make sure character_id is resolved
+    if (in_import_table(character_id))
+        {
+            log_error("get_character_def(): character_id %d is still waiting 
to be imported\n",
+                      character_id);
+        }
+#endif // not NDEBUG
+
+       smart_ptr<character_def> ch = _dictionary.get_character(character_id);
+       assert(ch == NULL || ch->get_ref_count() > 1);
+       return ch.get_ptr(); // mm... why don't we return the smart_ptr?
+}
+
+void movie_def_impl::add_font(int font_id, font* f)
+{
+    assert(f);
+    m_fonts.add(font_id, f);
+}
+
+font* movie_def_impl::get_font(int font_id)
+{
+#ifndef NDEBUG
+    // make sure font_id is resolved
+    if (in_import_table(font_id))
+        {
+            log_error("get_font(): font_id %d is still waiting to be 
imported\n",
+                      font_id);
+        }
+#endif // not NDEBUG
+
+    smart_ptr<font>    f;
+    m_fonts.get(font_id, &f);
+    assert(f == NULL || f->get_ref_count() > 1);
+    return f.get_ptr();
+}
+
+bitmap_character_def* movie_def_impl::get_bitmap_character(int character_id)
+{
+    smart_ptr<bitmap_character_def>    ch;
+    m_bitmap_characters.get(character_id, &ch);
+    assert(ch == NULL || ch->get_ref_count() > 1);
+    return ch.get_ptr();
+}
+
+void movie_def_impl::add_bitmap_character(int character_id, 
bitmap_character_def* ch)
+{
+    assert(ch);
+    //log_msg("Add bitmap character %d", character_id);
+    m_bitmap_characters.add(character_id, ch);
+
+    add_bitmap_info(ch->get_bitmap_info());
+}
+
+sound_sample* movie_def_impl::get_sound_sample(int character_id)
+{
+    smart_ptr<sound_sample>    ch;
+    m_sound_samples.get(character_id, &ch);
+    assert(ch == NULL || ch->get_ref_count() > 1);
+    return ch.get_ptr();
+}
+
+void movie_def_impl::add_sound_sample(int character_id, sound_sample* sam)
+{
+    assert(sam);
+       log_msg("Add sound sample %d", character_id);
+    m_sound_samples.add(character_id, sam);
+}
+
+
+// Read a .SWF movie.
+bool
+movie_def_impl::read(tu_file* in, const std::string& url)
+{
+
+       // we only read a movie once (well, headers at least)
+       assert(_str.get() == NULL);
+
+       if ( url == "" ) _url = "<anonymous>";
+       else _url = url;
+
+       uint32_t file_start_pos = in->get_position();
+       uint32_t header = in->read_le32();
+       m_file_length = in->read_le32();
+       _swf_end_pos = file_start_pos + m_file_length;
+
+       m_version = (header >> 24) & 255;
+       if ((header & 0x0FFFFFF) != 0x00535746
+               && (header & 0x0FFFFFF) != 0x00535743)
+        {
+               // ERROR
+               log_error("gnash::movie_def_impl::read() -- "
+                       "file does not start with a SWF header!\n");
+               return false;
+        }
+       bool    compressed = (header & 255) == 'C';
+    
+       IF_VERBOSE_PARSE(
+               log_parse("version = %d, file_length = %d",
+                       m_version, m_file_length);
+       );
+
+       tu_file* original_in = NULL;
+       if (compressed)
+        {
+#if TU_CONFIG_LINK_TO_ZLIB == 0
+               log_error("movie_def_impl::read(): unable to read "
+                       "zipped SWF data; TU_CONFIG_LINK_TO_ZLIB is 0\n");
+               return false;
+#endif
+
+               IF_VERBOSE_PARSE(
+                       log_parse("file is compressed.");
+               );
+
+               original_in = in;
+
+               // Uncompress the input as we read it.
+               _zlib_file.reset(zlib_adapter::make_inflater(original_in));
+               in = _zlib_file.get();
+
+               // Subtract the size of the 8-byte header, since
+               // it's not included in the compressed
+               // stream length.
+               _swf_end_pos = m_file_length - 8;
+        }
+
+       //stream str(in);
+       _str.reset(new stream(in));
+
+       m_frame_size.read(_str.get());
+       m_frame_rate = _str->read_u16() / 256.0f;
+       m_frame_count = _str->read_u16();
+
+       // hack
+       // Vitaly: I am not assured that it correctly
+       m_frame_count = (m_frame_count == 0) ? 1 : m_frame_count;
+
+       m_playlist.resize(m_frame_count);
+       m_init_action_list.resize(m_frame_count);
+
+       IF_VERBOSE_PARSE(
+               m_frame_size.print();
+               log_parse("frame rate = %f, frames = %d",
+                       m_frame_rate, m_frame_count);
+       );
+
+#ifdef LOAD_MOVIES_IN_A_SEPARATE_THREAD
+
+       // Start the loading frame
+       if ( ! _loader.start() )
+       {
+               log_error("Could not start loading thread");
+       }
+
+       // Wait until 'startup_frames' have been loaded
+#if 1
+       size_t startup_frames = 1;
+#else
+       size_t startup_frames = m_frame_count;
+#endif
+       ensure_frame_loaded(startup_frames);
+
+#else // undef LOAD_MOVIES_IN_A_SEPARATE_THREAD
+
+       read_all_swf();
+#endif
+
+// Can't delete here as we will keep reading from it while playing
+// FIXME: remove this at end of reading (or in destructor)
+#if 0
+       if (original_in)
+        {
+            // Done with the zlib_adapter.
+            delete in;
+        }
+#endif
+
+       return true;
+}
+
+
+// 1-based frame number
+bool
+movie_def_impl::ensure_frame_loaded(size_t framenum)
+{
+        //log_msg("Waiting for frame %u to be loaded", framenum);
+       _loader.wait_for_frame(framenum);
+        //log_msg("Condition reached (m_loading_frame=%u)", m_loading_frame);
+
+
+       // TODO: return false on timeout 
+       return true;
+}
+
+
+/* movie_def_impl */
+void movie_def_impl::get_owned_fonts(std::vector<font*>* fonts)
+    // Fill up *fonts with fonts that we own.
+{
+    assert(fonts);
+    fonts->resize(0);
+
+    std::vector<int>   font_ids;
+
+    for (hash<int, smart_ptr<font> >::iterator it = m_fonts.begin();
+         it != m_fonts.end();
+         ++it)
+        {
+            font*      f = it->second.get_ptr();
+            if (f->get_owning_movie() == this)
+                {
+                    // Sort by character id, so the ordering is
+                    // consistent for cache read/write.
+                    int        id = it->first;
+
+                    // Insert in correct place.
+                    unsigned int insert;
+                    for (insert = 0; insert < font_ids.size(); insert++)
+                        {
+                            if (font_ids[insert] > id)
+                                {
+                                    // We want to insert here.
+                                    break;
+                                }
+                        }
+                    fonts->insert(fonts->begin() + insert, f);
+                    font_ids.insert(font_ids.begin() + insert, id);
+                }
+        }
+}
+
+
+/* movie_def_impl */
+void movie_def_impl::generate_font_bitmaps()
+    // Generate bitmaps for our fonts, if necessary.
+{
+    // Collect list of fonts.
+    std::vector<font*> fonts;
+    get_owned_fonts(&fonts);
+    fontlib::generate_font_bitmaps(fonts, this);
+}
+
+void
+movie_def_impl::output_cached_data(tu_file* out, const cache_options& options)
+{
+    // Write a little header.
+    char       header[5];
+    strcpy(header, "gscX");
+    header[3] = CACHE_FILE_VERSION;
+    compiler_assert(CACHE_FILE_VERSION < 256);
+
+    out->write_bytes(header, 4);
+
+    // Write font data.
+    std::vector<font*> fonts;
+    get_owned_fonts(&fonts);
+    fontlib::output_cached_data(out, fonts, this, options);
+
+       // Write character data.
+       {
+
+       for ( CharacterDictionary::iterator
+               it = _dictionary.begin(), itEnd = _dictionary.end();
+               it != itEnd;
+               ++it )
+       {
+               out->write_le16(it->first);
+               it->second->output_cached_data(out, options);
+       }
+                       
+#if 0
+       for (hash<int, smart_ptr<character_def> >::iterator it = 
m_characters.begin();
+          it != m_characters.end();
+          ++it)
+        {
+            out->write_le16(it->first);
+            it->second->output_cached_data(out, options);
+        }
+#endif
+       }
+
+    out->write_le16((int16_t) -1);     // end of characters marker
+}
+
+
+void
+movie_def_impl::input_cached_data(tu_file* in)
+{
+    // Read the header & check version.
+    unsigned char      header[4];
+    in->read_bytes(header, 4);
+    if (header[0] != 'g' || header[1] != 's' || header[2] != 'c')
+        {
+            log_error("cache file does not have the correct format; 
skipping\n");
+            return;
+        }
+    else if (header[3] != CACHE_FILE_VERSION)
+        {
+            log_error(
+                "cached data is version %d, but we require version %d; 
skipping\n",
+                int(header[3]), CACHE_FILE_VERSION);
+            return;
+        }
+
+    // Read the cached font data.
+    std::vector<font*> fonts;
+    get_owned_fonts(&fonts);
+    fontlib::input_cached_data(in, fonts, this);
+
+    // Read the cached character data.
+    for (;;)
+        {
+            if (in->get_error() != TU_FILE_NO_ERROR)
+                {
+                    log_error("error reading cache file (characters); 
skipping\n");
+                    return;
+                }
+            if (in->get_eof())
+                {
+                    log_error("unexpected eof reading cache file (characters); 
skipping\n");
+                    return;
+                }
+
+            int16_t    id = in->read_le16();
+            if (id == (int16_t) -1) { break; } // done
+
+            smart_ptr<character_def> ch = _dictionary.get_character(id);
+            //m_characters.get(id, &ch);
+            if (ch != NULL)
+                {
+                    ch->input_cached_data(in);
+                }
+            else
+                {
+                    log_error("sync error in cache file (reading characters)!  
"
+                              "Skipping rest of cache data.\n");
+                    return;
+                }
+        }
+}
+
+movie_interface*
+movie_def_impl::create_instance()
+{
+    movie_root*        m = new movie_root(this);
+    assert(m);
+
+    sprite_instance* root_movie = new movie_instance(this, m, NULL);
+    assert(root_movie);
+
+    root_movie->set_name("_root");
+    m->set_root_movie(root_movie);
+
+    // @@ somewhere in here I *might* add _url variable
+    // (or is it a member?)
+
+    m->add_ref();
+
+               root_movie->execute_frame_tags(0); // create _root dlist
+
+    return m;
+}
+
+
+//
+// CharacterDictionary
+//
+
+void
+CharacterDictionary::dump_chars() const
+{
+       for ( const_iterator it=begin(), endIt=end();
+               it != endIt; ++it )
+       {
+               log_msg("Character %d @ %p", it->first, it->second.get_ptr());
+               //character_def* cdef = it->second;
+       }
+}
+
+smart_ptr<character_def>
+CharacterDictionary::get_character(int id)
+{
+       container::iterator it = _map.find(id);
+       if ( it == _map.end() )
+       {
+               log_msg("Could not find char %d, dump is:", id);
+               dump_chars();
+               return smart_ptr<character_def>();
+       }
+       else return it->second;
+}
+
+void
+CharacterDictionary::add_character(int id, smart_ptr<character_def> c)
+{
+       //log_msg("CharacterDictionary: add char %d", id);
+       _map[id] = c;
+       //dump_chars();
+}
+
+// Load next chunk of this sprite frames.
+// This is possibly better defined in movie_definition
+void
+movie_def_impl::load_next_frame_chunk()
+{
+
+       size_t framecount = get_frame_count();
+       size_t lastloaded = get_loading_frame();
+
+       // nothing to do
+       if ( lastloaded == framecount ) return;
+
+       size_t nextframe = lastloaded+1;
+
+#if FRAMELOAD_CHUNK
+       nextframe += FRAMELOAD_CHUNK; // load in chunks of 10 frames 
+       if ( nextframe > framecount ) nextframe = framecount;
+#endif
+       //log_msg("Framecount: %u, Lastloaded: %u", framecount, lastloaded);
+       if ( nextframe <= framecount )
+       {
+#ifdef DEBUG_FRAMES_LOAD // debugging
+               log_msg("Ensure load of frame %u/%u (last loaded is: %u)",
+                       nextframe, framecount, lastloaded);
+#endif
+               if ( ! ensure_frame_loaded(nextframe) )
+               {
+                       log_error("Could not advance to frame %d!",
+                               nextframe);
+                       // these kind of errors should be handled by callers
+                       assert(0);
+               }
+       }
+#ifdef DEBUG_FRAMES_LOAD
+       else
+       {
+               log_msg("No more frames to load. Framecount: %u, Lastloaded: 
%u, next to load: %u", framecount, lastloaded, nextframe);
+       }
+#endif
+}
+
+void
+movie_def_impl::read_all_swf()
+{
+       assert(_str.get() != NULL);
+
+       stream& str=*_str;
+
+       //size_t it=0;
+       while ( (uint32_t) str.get_position() < _swf_end_pos )
+       {
+               // Get exclusive lock on loader, to avoid
+               // race conditions with wait_for_frame
+               _loader.lock();
+
+               //log_msg("Loading thread iteration %u", it++);
+
+               SWF::tag_type tag_type = str.open_tag();
+
+               if (s_progress_function != NULL)
+                {
+                       s_progress_function((uint32_t)str.get_position(),
+                               _swf_end_pos);
+                }
+
+               SWF::TagLoadersTable::loader_function lf = NULL;
+               //log_parse("tag_type = %d\n", tag_type);
+               if (tag_type == SWF::SHOWFRAME)
+               {
+                       // show frame tag -- advance to the next frame.
+
+                       IF_VERBOSE_PARSE(
+                               log_parse("  show_frame\n");
+                       );
+
+                       ++m_loading_frame;
+
+                       // signal load of frame
+                       _loader.signal_frame_loaded(m_loading_frame);
+
+#if DEBUG_FRAMES_LOAD
+                       log_msg("Loaded frame %u/%u",
+                               m_loading_frame, m_frame_count);
+#endif
+               }
+               else if (_tag_loaders.get(tag_type, &lf))
+                {
+                       // call the tag loader.  The tag loader should add
+                       // characters or tags to the movie data structure.
+                       (*lf)(&str, tag_type, this);
+               }
+               else
+               {
+                       // no tag loader for this tag type.
+                               log_error("*** no tag loader for type %d 
(movie)",
+                                       tag_type);
+                               dump_tag_bytes(&str);
+               } 
+
+               str.close_tag();
+
+               if (tag_type == SWF::END)
+                {
+                       if ((unsigned int) str.get_position() != _swf_end_pos)
+                        {
+                               // Safety break, so we don't read past
+                               // the end of the  movie.
+                               log_warning("hit stream-end tag, "
+                                       "but not at the advertised SWF end; "
+                                       "stopping for safety.");
+                               _loader.unlock();
+                               break;
+                       }
+               }
+               _loader.unlock();
+
+       }
+
+}
+
+} // namespace gnash
+

Index: server/parser/movie_def_impl.h
===================================================================
RCS file: server/parser/movie_def_impl.h
diff -N server/parser/movie_def_impl.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/parser/movie_def_impl.h      24 Aug 2006 00:57:20 -0000      1.1
@@ -0,0 +1,570 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+// 
+// This program 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 General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+// Linking Gnash statically or dynamically with other modules is making a
+// combined work based on Gnash. Thus, the terms and conditions of the GNU
+// General Public License cover the whole combination.
+//
+// As a special exception, the copyright holders of Gnash give you
+// permission to combine Gnash with free software programs or libraries
+// that are released under the GNU LGPL and with code included in any
+// release of Talkback distributed by the Mozilla Foundation. You may
+// copy and distribute such a system following the terms of the GNU GPL
+// for all but the LGPL-covered parts and Talkback, and following the
+// LGPL for the LGPL-covered parts.
+//
+// Note that people who make modified versions of Gnash are not obligated
+// to grant this special exception for their modified versions; it is their
+// choice whether to do so. The GNU General Public License gives permission
+// to release a modified version without this exception; this exception
+// also makes it possible to release a modified version which carries
+// forward this exception.
+// 
+//
+
+#ifndef GNASH_MOVIE_DEF_IMPL_H
+#define GNASH_MOVIE_DEF_IMPL_H
+
+#include "container.h"
+#include "smart_ptr.h"
+#include "button.h" // for mouse_button_state
+#include "timers.h" // for Timer
+#include "fontlib.h"
+#include "font.h"
+#include "jpeg.h"
+#include "tu_file.h"
+#include "movie_definition.h" // for inheritance
+#include "character_def.h" // for smart_ptr visibility of dtor
+#include "bitmap_character_def.h" // for smart_ptr visibility of dtor
+#include "resource.h" // for smart_ptr visibility of dtor
+#include "stream.h" // for get_bytes_loaded
+
+#include <map> // for CharacterDictionary
+#include <string>
+#include <memory> // for auto_ptr
+
+// We'd avoid SDL threads if possible. Please define the macro below
+// if you experience problems and report the difference on gnash-dev
+#undef REALLY_USE_SDL_THREADS
+
+#ifdef REALLY_USE_SDL_THREADS
+#ifdef HAVE_SDL_H
+# define USE_SDL_THREADS 1
+#endif
+#endif
+
+#ifdef USE_SDL_THREADS
+#      include "SDL.h"
+#      include "SDL_thread.h"
+#endif
+
+
+namespace gnash
+{
+
+// Forward declarations
+class import_info;
+class movie_def_impl;
+class movie_root;
+
+//
+// Helper for movie_def_impl
+//
+
+class import_info
+{
+    friend class movie_def_impl;
+
+    tu_string  m_source_url;
+    int                m_character_id;
+    tu_string  m_symbol;
+
+    import_info()
+       :
+       m_character_id(-1)
+       {
+       }
+
+    import_info(const char* source, int id, const char* symbol)
+       :
+       m_source_url(source),
+       m_character_id(id),
+       m_symbol(symbol)
+       {
+       }
+};
+
+/// \brief
+/// movie_def_impl helper class handling start and execution of
+/// an SWF loading thread
+///
+class MovieLoader
+{
+
+public:
+
+       MovieLoader(movie_def_impl& md);
+
+       ~MovieLoader();
+
+       /// Start loading thread.
+       //
+       /// The associated movie_def_impl instance
+       /// is expected to have already read the SWF
+       /// header and applied a zlib adapter if needed.
+       ///
+       bool start();
+
+       /// Wait for specified frame number (1-based) to be loaded
+       //
+       /// Block caller thread until frame is loaded.
+       ///
+       void wait_for_frame(size_t framenum);
+
+       /// Signal load of given frame number (if anyone waiting for it)
+       void signal_frame_loaded(size_t frameno);
+
+       void lock();
+
+       void unlock();
+
+private:
+
+       size_t _waiting_for_frame;
+       movie_def_impl& _movie_def;
+
+#ifdef USE_SDL_THREADS
+
+       static int execute(void* arg);
+
+       SDL_Thread* _thread;
+       SDL_cond* _frame_reached_condition;
+       SDL_mutex* _mutex;
+
+#else
+
+       pthread_cond_t _frame_reached_condition;
+       pthread_mutex_t _mutex;
+       pthread_t _thread;
+
+       /// Entry point for the actual thread
+       static void *execute(void* arg);
+
+#endif
+
+};
+
+/// The Characters dictionary associated with each SWF file.
+//
+/// This is a set of Characters defined by define tags and
+/// getting assigned a unique ID. 
+///
+class CharacterDictionary
+{
+
+public:
+
+       /// The container used by this dictionary
+       //
+       /// It contains pairs of 'int' and 'smart_ptr<character_def>'
+       ///
+       typedef std::map< int, smart_ptr<character_def> > container;
+       //typedef hash< int, smart_ptr<character_def> >container;
+
+       typedef container::iterator iterator;
+
+       typedef container::const_iterator const_iterator;
+
+       /// Get the Character with the given id
+       //
+       /// returns a NULL if the id is unknown.
+       ///
+       smart_ptr<character_def> get_character(int id);
+
+       /// Add a Character assigning it the given id
+       //
+       /// replaces any existing character with the same id
+       ///
+       void add_character(int id, smart_ptr<character_def> c);
+
+       /// Return an iterator to the first dictionary element
+       iterator begin() { return _map.begin(); }
+
+       /// Return a const_iterator to the first dictionary element
+       const_iterator begin() const { return _map.begin(); }
+
+       /// Return an iterator to one-past last dictionary element
+       iterator end() { return _map.end(); }
+
+       /// Return a const_iterator to one-past last dictionary element
+       const_iterator end() const { return _map.end(); }
+
+       /// Dump content of the dictionary (debugging only)
+       void dump_chars(void) const;
+private:
+
+       container _map;
+
+};
+
+
+/// Immutable definition of a movie's contents.
+//
+/// It cannot be played directly, and does not hold
+/// current state; for that you need to call create_instance()
+/// to get a movie instance (gnash::movie_interface).
+///
+class movie_def_impl : public movie_definition
+{
+       /// Characters Dictionary
+       CharacterDictionary     _dictionary;
+       //hash<int, smart_ptr<character_def> >          m_characters;
+
+       /// Tags loader table
+       SWF::TagLoadersTable& _tag_loaders;
+
+       hash<int, smart_ptr<font> >                     m_fonts;
+       hash<int, smart_ptr<bitmap_character_def> >     m_bitmap_characters;
+       hash<int, smart_ptr<sound_sample> >             m_sound_samples;
+       hash<int, smart_ptr<sound_sample> >             m_sound_streams;
+
+       /// A list of movie control events for each frame.
+       std::vector<std::vector<execute_tag*> >         m_playlist;
+
+       /// Init actions for each frame.
+       std::vector<std::vector<execute_tag*> >    m_init_action_list;
+
+       /// 0-based frame #'s
+       stringi_hash<size_t> m_named_frames;
+
+       stringi_hash<smart_ptr<resource> > m_exports;
+
+       /// Items we import.
+       std::vector<import_info> m_imports;
+
+       /// Movies we import from; hold a ref on these,
+       /// to keep them alive
+       std::vector<smart_ptr<movie_definition> > m_import_source_movies;
+
+       /// Bitmaps used in this movie; collected in one place to make
+       /// it possible for the host to manage them as textures.
+       std::vector<smart_ptr<bitmap_info> >    m_bitmap_list;
+
+       create_bitmaps_flag     m_create_bitmaps;
+       create_font_shapes_flag m_create_font_shapes;
+
+       rect    m_frame_size;
+       float   m_frame_rate;
+       size_t  m_frame_count;
+       int     m_version;
+       size_t  m_loading_frame;
+       int     m_loading_sound_stream;
+       uint32  m_file_length;
+       size_t  _loaded_bytes;
+
+       std::auto_ptr<jpeg::input> m_jpeg_in;
+
+       std::string _url;
+
+       std::auto_ptr<stream> _str;
+
+       tu_file* in;
+
+       std::auto_ptr<tu_file> _zlib_file;
+
+       /// swf end position (as read from header)
+       unsigned int _swf_end_pos;
+
+       /// asyncronous SWF loader and parser
+       MovieLoader _loader;
+
+public:
+
+       movie_def_impl(create_bitmaps_flag cbf, create_font_shapes_flag cfs);
+
+       ~movie_def_impl();
+
+       // ...
+       size_t get_frame_count() const { return m_frame_count; }
+       float   get_frame_rate() const { return m_frame_rate; }
+       const rect& get_frame_size() const { return m_frame_size; }
+
+       float   get_width_pixels() const
+       {
+               return ceilf(TWIPS_TO_PIXELS(m_frame_size.width()));
+       }
+
+       float   get_height_pixels() const
+       {
+               return ceilf(TWIPS_TO_PIXELS(m_frame_size.height()));
+       }
+
+       virtual int     get_version() const { return m_version; }
+
+       virtual size_t  get_loading_frame() const
+       {
+               return m_loading_frame;
+       }
+
+#if 0 // renamed to get_bytes_total
+       uint32  get_file_bytes() const {
+               return m_file_length;
+       }
+#endif
+
+       /// Get number of bytes loaded from input stream
+       size_t  get_bytes_loaded() const {
+#if 0 // temporarly disabled because broken
+               uint32 ret = _loaded_bytes;
+#else
+               uint32 ret = m_file_length;
+#endif
+               log_msg("get_bytes_loaded returning %u (loaded frame: %zu/%zu)",
+                       ret, m_loading_frame, m_frame_count);
+               return ret;
+       }
+
+       /// Get total number of bytes in input stream
+       size_t  get_bytes_total() const {
+               log_msg("get_bytes_total returning %u", m_file_length);
+               return m_file_length;
+       }
+
+       /// Returns DO_CREATE_BITMAPS if we're supposed to
+       /// initialize our bitmap infos, or DO_NOT_INIT_BITMAPS
+       /// if we're supposed to create blank placeholder
+       /// bitmaps (to be init'd later explicitly by the host
+       /// program).
+       virtual create_bitmaps_flag get_create_bitmaps() const
+       {
+               return m_create_bitmaps;
+       }
+
+       /// Returns DO_LOAD_FONT_SHAPES if we're supposed to
+       /// initialize our font shape info, or
+       /// DO_NOT_LOAD_FONT_SHAPES if we're supposed to not
+       /// create any (vector) font glyph shapes, and instead
+       /// rely on precached textured fonts glyphs.
+       virtual create_font_shapes_flag get_create_font_shapes() const
+       {
+           return m_create_font_shapes;
+       }
+
+       /// All bitmap_info's used by this movie should be
+       /// registered with this API.
+       virtual void    add_bitmap_info(bitmap_info* bi)
+       {
+           m_bitmap_list.push_back(bi);
+       }
+
+       virtual int get_bitmap_info_count() const
+       {
+               return m_bitmap_list.size();
+       }
+
+       virtual bitmap_info*    get_bitmap_info(int i) const
+       {
+               return m_bitmap_list[i].get_ptr();
+       }
+
+       /// Expose one of our resources under the given symbol,
+       /// for export.  Other movies can import it.
+       virtual void export_resource(const tu_string& symbol,
+                       resource* res)
+       {
+           // SWF sometimes exports the same thing more than once!
+           m_exports[symbol] = res;
+       }
+
+       /// Get the named exported resource, if we expose it.
+       /// Otherwise return NULL.
+       virtual smart_ptr<resource> get_exported_resource(const tu_string& 
symbol)
+       {
+           smart_ptr<resource> res;
+           m_exports.get(symbol, &res);
+           return res;
+       }
+
+       /// Adds an entry to a table of resources that need to
+       /// be imported from other movies.  Client code must
+       /// call resolve_import() later, when the source movie
+       /// has been loaded, so that the actual resource can be
+       /// used.
+       virtual void add_import(const char* source_url, int id, const char* 
symbol)
+       {
+           assert(in_import_table(id) == false);
+
+           m_imports.push_back(import_info(source_url, id, symbol));
+       }
+
+       /// Debug helper; returns true if the given
+       /// character_id is listed in the import table.
+       bool in_import_table(int character_id);
+
+       /// Calls back the visitor for each movie that we
+       /// import symbols from.
+       virtual void visit_imported_movies(import_visitor* visitor);
+
+       /// Grabs the stuff we want from the source movie.
+       virtual void resolve_import(const char* source_url,
+               movie_definition* source_movie);
+
+       void add_character(int character_id, character_def* c);
+
+       /// \brief
+       /// Return a character from the dictionary
+       /// NOTE: call add_ref() on the return or put in a smart_ptr<>
+       /// TODO: return a smart_ptr<> directly...
+       ///
+       character_def*  get_character_def(int character_id);
+
+       /// Returns 0-based frame #
+       bool get_labeled_frame(const char* label, size_t* frame_number)
+       {
+               return m_named_frames.get(label, frame_number);
+       }
+
+       void    add_font(int font_id, font* f);
+       font*   get_font(int font_id);
+       bitmap_character_def*   get_bitmap_character(int character_id);
+       void    add_bitmap_character(int character_id, bitmap_character_def* 
ch);
+       sound_sample*   get_sound_sample(int character_id);
+       virtual void    add_sound_sample(int character_id, sound_sample* sam);
+       virtual void    set_loading_sound_stream_id(int id) { 
m_loading_sound_stream = id; }
+       int             get_loading_sound_stream_id() { return 
m_loading_sound_stream; }
+
+       /// Add an execute_tag to this movie_definition's playlist
+       void    add_execute_tag(execute_tag* e)
+       {
+           assert(e);
+           m_playlist[m_loading_frame].push_back(e);
+       }
+
+       /// Need to execute the given tag before entering the
+       /// currently-loading frame for the first time.
+       ///
+       /// @@ AFAIK, the sprite_id is totally pointless -- correct?
+       //void  add_init_action(int sprite_id, execute_tag* e)
+       void    add_init_action(execute_tag* e)
+       {
+           assert(e);
+           m_init_action_list[m_loading_frame].push_back(e);
+       }
+
+       /// Labels the frame currently being loaded with the
+       /// given name.  A copy of the name string is made and
+       /// kept in this object.
+       void    add_frame_name(const char* name)
+       {
+           assert(m_loading_frame < m_frame_count);
+
+           tu_string   n = name;
+
+                       if (m_named_frames.get(n, NULL) == false)       // 
frame should not already have a name (?)
+                       {
+                   m_named_frames.add(n, m_loading_frame);     // stores 
0-based frame #
+                       }
+       }
+
+       /// Set an input object for later loading DefineBits
+       /// images (JPEG images without the table info).
+       void    set_jpeg_loader(std::auto_ptr<jpeg::input> j_in)
+       {
+           assert(m_jpeg_in.get() == NULL);
+           m_jpeg_in = j_in;
+       }
+
+       /// Get the jpeg input loader, to load a DefineBits
+       /// image (one without table info).
+       //
+       /// NOTE: ownership is NOT transferred
+       ///
+       jpeg::input*    get_jpeg_loader()
+       {
+           return m_jpeg_in.get();
+       }
+
+       virtual const std::vector<execute_tag*>& get_playlist(size_t 
frame_number)
+       {
+               return m_playlist[frame_number];
+       }
+
+       virtual const std::vector<execute_tag*>* get_init_actions(size_t 
frame_number)
+       {
+               assert(frame_number <= m_loading_frame);
+               //ensure_frame_loaded(frame_number);
+               return &m_init_action_list[frame_number];
+       }
+
+       /// Read (w/out playing) a Movie definition from an SWF file.
+       //
+       /// Note that the *full* SWF is read before
+       /// this function returns. We should change this
+       /// interface to both read and play a file instead.
+       ///
+       /// This function uses a private TagLoadersTable
+       /// to interpret specific tag types.
+       /// Currently the TagLoadersTable in use is the
+       /// gnash::s_tag_loaders global variable
+       ///
+       /// @param in the tu_file from which to read SWF
+       /// @param url the url associated with the input
+       /// @return false if SWF file could not be parsed
+       ///
+       bool read(tu_file *in, const std::string& url);
+
+       /// \brief
+       /// Ensure that frame number 'framenum' (1-based offset)
+       /// has been loaded (load on demand).
+       ///
+       bool ensure_frame_loaded(size_t framenum);
+
+       /// Read and parse all the SWF stream (blocking until load is finished)
+       void read_all_swf();
+
+       virtual void load_next_frame_chunk();
+
+       /// Fill up *fonts with fonts that we own.
+       void get_owned_fonts(std::vector<font*>* fonts);
+
+       /// Generate bitmaps for our fonts, if necessary.
+       void generate_font_bitmaps();
+
+       /// Dump our cached data into the given stream.
+       void output_cached_data(tu_file* out,
+               const cache_options& options);
+
+       /// \brief
+       /// Read in cached data and use it to prime our
+       /// loaded characters.
+       void    input_cached_data(tu_file* in);
+
+       /// \brief
+       /// Create a playable movie_root instance from a def.
+       //
+       /// The _root reference of the newly created instance
+       /// will be set to a newly created sprite_instace (Help!)
+       ///
+       movie_interface* create_instance();
+
+       virtual const std::string& get_url() const { return _url; }
+
+
+};
+
+} // namespace gnash
+
+#endif // GNASH_MOVIE_DEF_IMPL_H

Index: server/parser/movie_definition.h
===================================================================
RCS file: server/parser/movie_definition.h
diff -N server/parser/movie_definition.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/parser/movie_definition.h    24 Aug 2006 00:57:20 -0000      1.1
@@ -0,0 +1,269 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+// 
+// This program 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 General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+// Linking Gnash statically or dynamically with other modules is making a
+// combined work based on Gnash. Thus, the terms and conditions of the GNU
+// General Public License cover the whole combination.
+//
+// As a special exception, the copyright holders of Gnash give you
+// permission to combine Gnash with free software programs or libraries
+// that are released under the GNU LGPL and with code included in any
+// release of Talkback distributed by the Mozilla Foundation. You may
+// copy and distribute such a system following the terms of the GNU GPL
+// for all but the LGPL-covered parts and Talkback, and following the
+// LGPL for the LGPL-covered parts.
+//
+// Note that people who make modified versions of Gnash are not obligated
+// to grant this special exception for their modified versions; it is their
+// choice whether to do so. The GNU General Public License gives permission
+// to release a modified version without this exception; this exception
+// also makes it possible to release a modified version which carries
+// forward this exception.
+// 
+//
+
+
+/// \page movie SWF Movies
+///
+/// SWF Movies definitions are created by reading an SWF stream.
+/// Gnash doesn't play SWF Movie definitions, but instances.
+/// So you can play the same SWF file (Movie definiton) using
+/// multiple instances.
+///
+/// A Movie definition is defined by the gnash::movie_definition class.
+/// A Movie instance is defined by the gnash::movie_interface class.
+/// 
+/// A Movie instance exposes the ActionScript
+/// Object base interface (gnash::as_object),
+/// thus it can manage gnash::as_value members.
+///
+/// The implementation of SWF parsing for a Movie definition
+/// is found in gnash::movie_def_impl::read.
+/// Note that movie_definition is also used as a base class
+/// to sprite_definition, which is a sub-movie defined in an SWF
+/// file. This seems to be the only reason to have a
+/// movie_def_impl class, being the top-level definition of
+/// a movie (the one with a CharacterDictionary in it).
+///
+
+
+#ifndef GNASH_MOVIE_DEFINITION_H
+#define GNASH_MOVIE_DEFINITION_H
+
+#include "container.h"
+#include "button.h" // for mouse_button_state
+#include "timers.h" // for Timer
+#include "fontlib.h"
+#include "font.h"
+#include "jpeg.h"
+#include "tu_file.h"
+
+#include <string>
+#include <memory> // for auto_ptr
+
+namespace gnash
+{
+
+/// Client program's interface to the definition of a movie
+//
+/// (i.e. the shared constant source info).
+///
+struct movie_definition : public character_def
+{
+       virtual int     get_version() const = 0;
+       virtual float   get_width_pixels() const = 0;
+       virtual float   get_height_pixels() const = 0;
+       virtual size_t  get_frame_count() const = 0;
+       virtual float   get_frame_rate() const = 0;
+
+       virtual size_t get_bytes_loaded() const = 0;
+       virtual size_t get_bytes_total() const = 0;
+       
+       /// Create a playable movie instance from a def.
+       //
+       /// This calls add_ref() on the movie_interface internally.
+       /// Call drop_ref() on the movie_interface when you're done with it.
+       /// Or use smart_ptr<T> from base/smart_ptr.h if you want.
+       ///
+       virtual movie_interface*        create_instance() = 0;
+       
+       virtual void    output_cached_data(tu_file* out, const cache_options& 
options) = 0;
+       virtual void    input_cached_data(tu_file* in) = 0;
+       
+       /// \brief
+       /// Causes this movie def to generate texture-mapped
+       /// versions of all the fonts it owns. 
+       //
+       /// This improves
+       /// speed and quality of text rendering.  The
+       /// texture-map data is serialized in the
+       /// output/input_cached_data() calls, so you can
+       /// preprocess this if you load cached data.
+       ///
+       virtual void    generate_font_bitmaps() = 0;
+       
+       //
+       // (optional) API to support gnash::create_movie_no_recurse().
+       //
+       
+       /// \brief
+       /// Call visit_imported_movies() to retrieve a list of
+       /// names of movies imported into this movie.
+       //
+       /// visitor->visit() will be called back with the name
+       /// of each imported movie.
+       struct import_visitor
+       {
+           virtual ~import_visitor() {}
+           virtual void        visit(const char* imported_movie_filename) = 0;
+       };
+       virtual void    visit_imported_movies(import_visitor* visitor) = 0;
+       
+       /// Call this to resolve an import of the given movie.
+       /// Replaces the dummy placeholder with the real
+       /// movie_definition* given.
+       virtual void    resolve_import(const char* name, movie_definition* def) 
= 0;
+       
+       //
+       // (optional) API to support host-driven creation of textures.
+       //
+       // Create the movie using gnash::create_movie_no_recurse(..., 
DO_NOT_LOAD_BITMAPS),
+       // and then initialize each bitmap info via get_bitmap_info_count(), 
get_bitmap_info(),
+       // and bitmap_info::init_*_image() or your own subclassed API.
+       //
+       // E.g.:
+       //
+       // // During preprocessing:
+       // // This will create bitmap_info's using the rgba, rgb, alpha 
contructors.
+       // my_def = gnash::create_movie_no_recurse("myfile.swf", 
DO_LOAD_BITMAPS);
+       // int ct = my_def->get_bitmap_info_count();
+       // for (int i = 0; i < ct; i++)
+       // {
+       //      my_bitmap_info_subclass*        bi = NULL;
+       //      my_def->get_bitmap_info(i, (bitmap_info**) &bi);
+       //      
my_precomputed_textures.push_back(bi->m_my_internal_texture_reference);
+       // }
+       // // Save out my internal data.
+       // my_precomputed_textures->write_into_some_cache_stream(...);
+       //
+       // // Later, during run-time loading:
+       // my_precomputed_textures->read_from_some_cache_stream(...);
+       // // This will create blank bitmap_info's.
+       // my_def = gnash::create_movie_no_recurse("myfile.swf", 
DO_NOT_LOAD_BITMAPS);
+       // 
+       // // Push cached texture info into the movie's bitmap_info structs.
+       // int  ct = my_def->get_bitmap_info_count();
+       // for (int i = 0; i < ct; i++)
+       // {
+       //      my_bitmap_info_subclass*        bi = (my_bitmap_info_subclass*) 
my_def->get_bitmap_info(i);
+       //      bi->set_internal_texture_reference(my_precomputed_textures[i]);
+       // }
+       virtual int     get_bitmap_info_count() const = 0;
+       virtual bitmap_info*    get_bitmap_info(int i) const = 0;
+
+       // From movie_definition_sub
+
+       virtual const std::vector<execute_tag*>& get_playlist(size_t 
frame_number) = 0;
+       virtual const std::vector<execute_tag*>* get_init_actions(size_t 
frame_number) = 0;
+       virtual smart_ptr<resource>     get_exported_resource(const tu_string& 
symbol) = 0;
+
+
+       /// \brief
+       /// Get a character from the dictionary.
+       ///
+       /// Note that only top-level movies (those belonging to a single
+       /// SWF stream) have a characters dictionary, thus our
+       /// movie_def_impl. The other derived class, sprite_definition
+       /// will seek for characters in it's base movie_def_impl.
+       ///
+       virtual character_def*  get_character_def(int id) = 0;
+
+       virtual bool get_labeled_frame(const char* label, size_t* frame_number) 
= 0;
+
+       //
+       // For use during creation.
+       //
+
+       /// Returns 1 based index. Ex: if 1 then 1st frame as been fully loaded
+       virtual size_t  get_loading_frame() const = 0;
+
+       virtual void    add_character(int id, character_def* ch) = 0;
+
+       virtual void    add_font(int id, font* ch) = 0;
+
+       virtual font*   get_font(int id) = 0;
+
+       virtual void    add_execute_tag(execute_tag* c) = 0;
+
+       // sprite_id was useless
+       //virtual void  add_init_action(int sprite_id, execute_tag* c) = 0;
+       virtual void    add_init_action(execute_tag* c) = 0;
+
+       virtual void    add_frame_name(const char* name) = 0;
+
+       virtual void    set_jpeg_loader(std::auto_ptr<jpeg::input> j_in) = 0;
+
+       virtual jpeg::input*    get_jpeg_loader() = 0;
+
+       virtual bitmap_character_def* get_bitmap_character(int character_id)=0;
+
+       virtual void add_bitmap_character(int character_id,
+                       bitmap_character_def* ch) = 0;
+
+       virtual sound_sample* get_sound_sample(int character_id) = 0;
+
+       virtual void add_sound_sample(int character_id, sound_sample* sam) = 0;
+
+       virtual void set_loading_sound_stream_id(int id) = 0;
+       
+       virtual int get_loading_sound_stream_id() = 0;
+
+
+       virtual void export_resource(const tu_string& symbol,
+                       resource* res) = 0;
+
+       virtual void add_import(const char* source_url, int id,
+                       const char* symbol_name) = 0;
+
+       virtual void add_bitmap_info(bitmap_info* ch) = 0;
+
+       // ...
+
+       virtual create_bitmaps_flag     get_create_bitmaps() const = 0;
+       virtual create_font_shapes_flag get_create_font_shapes() const = 0;
+
+       /// \brief
+       /// Return the URL of the SWF stream this definition has been read
+       /// from.
+       virtual const std::string& get_url() const = 0;
+
+       /// \brief
+       /// Ensure that frame number 'framenum' (1-based offset)
+       /// has been loaded (load on demand).
+       //
+       /// @return false on error (like not enough frames available).
+       ///
+       virtual bool ensure_frame_loaded(size_t framenum) = 0;
+
+       /// \brief
+       /// Load next chunk of this movie/sprite frames if available.
+       ///
+       virtual void load_next_frame_chunk() = 0;
+};
+
+} // namespace gnash
+
+#endif // GNASH_MOVIE_DEFINITION_H

Index: server/parser/shape_character_def.cpp
===================================================================
RCS file: server/parser/shape_character_def.cpp
diff -N server/parser/shape_character_def.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/parser/shape_character_def.cpp       24 Aug 2006 00:57:20 -0000      
1.1
@@ -0,0 +1,718 @@
+// shape.cpp   -- Thatcher Ulrich <address@hidden> 2003
+
+// This source code has been donated to the Public Domain.  Do
+// whatever you want with it.
+
+// Quadratic bezier outline shapes, the basis for most SWF rendering.
+
+
+#include "shape_character_def.h"
+#include "shape.h" // for mesh_set
+
+#include "impl.h"
+#include "log.h"
+#include "render.h"
+#include "stream.h"
+#include "tesselate.h"
+#include "movie_definition.h" // TODO: check if really needed
+//#include "bitmap_character_def.h"
+#include "sprite_instance.h"
+
+#include "tu_file.h"
+
+#include <float.h>
+
+
+#define DEBUG_DISPLAY_SHAPE_PATHS
+#ifdef DEBUG_DISPLAY_SHAPE_PATHS
+// For debugging only!
+bool   gnash_debug_show_paths = false;
+#endif // DEBUG_DISPLAY_SHAPE_PATHS
+
+
+namespace gnash {
+
+static float   s_curve_max_pixel_error = 1.0f;
+
+
+//
+// helper functions.
+//
+
+void   set_curve_max_pixel_error(float pixel_error)
+{
+    s_curve_max_pixel_error = fclamp(pixel_error, 1e-6f, 1e6f);
+}
+
+float  get_curve_max_pixel_error()
+{
+    return s_curve_max_pixel_error;
+}
+
+
+// Read fill styles, and push them onto the given style array.
+static void
+read_fill_styles(std::vector<fill_style>& styles, stream* in,
+               int tag_type, movie_definition* m)
+{
+    //assert(styles);
+
+    // Get the count.
+    int        fill_style_count = in->read_u8();
+    if (tag_type > 2) {
+       if (fill_style_count == 0xFF)
+           {
+               fill_style_count = in->read_u16();
+           }
+    }
+
+               IF_VERBOSE_PARSE (
+    log_parse("  read_fill_styles: count = %d", fill_style_count);
+               );
+
+    // Read the styles. 
+    for (int i = 0; i < fill_style_count; i++) {
+       styles.resize(styles.size() + 1);
+       //styles[styles.size() - 1].read(in, tag_type, m);
+       styles.back().read(in, tag_type, m);
+    }
+}
+
+
+static void
+read_line_styles(std::vector<line_style>& styles, stream* in, int tag_type)
+    // Read line styles and push them onto the back of the given array.
+{
+    // Get the count.
+    int        line_style_count = in->read_u8();
+    
+               IF_VERBOSE_PARSE
+               (
+    log_parse("  read_line_styles: count = %d", line_style_count);
+               );
+
+    // @@ does the 0xFF flag apply to all tag types?
+    // if (tag_type > 2)
+    // {
+    if (line_style_count == 0xFF) {
+       line_style_count = in->read_u16();
+               IF_VERBOSE_PARSE
+               (
+       log_parse("  read_line_styles: count2 = %d", line_style_count);
+               );
+    }
+    // }
+
+    // Read the styles.
+    for (int i = 0; i < line_style_count; i++) {
+       styles.resize(styles.size() + 1);
+       //styles[styles.size() - 1].read(in, tag_type);
+       styles.back().read(in, tag_type);
+    }
+}
+
+
+shape_character_def::shape_character_def()
+{
+}
+
+
+shape_character_def::~shape_character_def()
+{
+    // Free our mesh_sets.
+    for (unsigned int i = 0; i < m_cached_meshes.size(); i++) {
+       delete m_cached_meshes[i];
+    }
+}
+
+
+void
+shape_character_def::read(stream* in, int tag_type, bool with_style,
+       movie_definition* m)
+{
+    if (with_style) {
+       m_bound.read(in);
+       read_fill_styles(m_fill_styles, in, tag_type, m);
+       read_line_styles(m_line_styles, in, tag_type);
+    }
+
+    int        num_fill_bits = in->read_uint(4);
+    int        num_line_bits = in->read_uint(4);
+
+               IF_VERBOSE_PARSE
+               (
+    log_parse("  shape_character_def read: nfillbits = %d, nlinebits = %d", 
num_fill_bits, num_line_bits);
+               );
+
+    // These are state variables that keep the
+    // current position & style of the shape
+    // outline, and vary as we read the edge data.
+    //
+    // At the moment we just store each edge with
+    // the full necessary info to render it, which
+    // is simple but not optimally efficient.
+    int        fill_base = 0;
+    int        line_base = 0;
+    float      x = 0, y = 0;
+    path       current_path;
+
+#define SHAPE_LOG 0
+    // SHAPERECORDS
+    for (;;) {
+       int     type_flag = in->read_uint(1);
+       if (type_flag == 0) {
+           // Parse the record.
+           int flags = in->read_uint(5);
+           if (flags == 0) {
+               // End of shape records.
+
+               // Store the current path if any.
+               if (! current_path.is_empty())
+                   {
+                       m_paths.push_back(current_path);
+                       current_path.m_edges.resize(0);
+                   }
+
+               break;
+           }
+           if (flags & 0x01) {
+               // move_to = 1;
+
+               // Store the current path if any, and prepare a fresh one.
+               if (! current_path.is_empty()) {
+                   m_paths.push_back(current_path);
+                   current_path.m_edges.resize(0);
+               }
+
+               int     num_move_bits = in->read_uint(5);
+               int     move_x = in->read_sint(num_move_bits);
+               int     move_y = in->read_sint(num_move_bits);
+
+               x = (float) move_x;
+               y = (float) move_y;
+
+               // Set the beginning of the path.
+               current_path.m_ax = x;
+               current_path.m_ay = y;
+
+               IF_VERBOSE_PARSE
+               (
+               if (SHAPE_LOG) 
+                   log_parse("  shape_character read: moveto %4g %4g", x, y);
+               );
+           }
+           if ((flags & 0x02) && num_fill_bits > 0) {
+               // fill_style_0_change = 1;
+               if (! current_path.is_empty()) {
+                   m_paths.push_back(current_path);
+                   current_path.m_edges.resize(0);
+                   current_path.m_ax = x;
+                   current_path.m_ay = y;
+               }
+               int     style = in->read_uint(num_fill_bits);
+               if (style > 0) {
+                   style += fill_base;
+               }
+               current_path.m_fill0 = style;
+               IF_VERBOSE_PARSE
+               (
+               if (SHAPE_LOG) {
+                   log_parse("  shape_character read: fill0 = %d", 
current_path.m_fill0);
+               }
+               );
+               
+           }
+           if ((flags & 0x04) && num_fill_bits > 0) {
+               // fill_style_1_change = 1;
+               if (! current_path.is_empty()) {
+                   m_paths.push_back(current_path);
+                   current_path.m_edges.resize(0);
+                   current_path.m_ax = x;
+                   current_path.m_ay = y;
+               }
+               int     style = in->read_uint(num_fill_bits);
+               if (style > 0) {
+                   style += fill_base;
+               }
+               current_path.m_fill1 = style;
+               IF_VERBOSE_PARSE (
+               if (SHAPE_LOG) {
+                   log_parse("  shape_character read: fill1 = %d", 
current_path.m_fill1);
+               }
+               );
+           }
+           if ((flags & 0x08) && num_line_bits > 0) {
+               // line_style_change = 1;
+               if (! current_path.is_empty()) {
+                   m_paths.push_back(current_path);
+                   current_path.m_edges.resize(0);
+                   current_path.m_ax = x;
+                   current_path.m_ay = y;
+               }
+               int     style = in->read_uint(num_line_bits);
+               if (style > 0) {
+                   style += line_base;
+               }
+               current_path.m_line = style;
+               IF_VERBOSE_PARSE (
+               if (SHAPE_LOG)
+               {
+                   log_parse("  shape_character_read: line = %d", 
current_path.m_line);
+               }
+               );
+           }
+           if (flags & 0x10) {
+               if (tag_type == 2) {
+                   tag_type+=20;
+               }
+               assert(tag_type >= 22);
+
+               IF_VERBOSE_PARSE (
+               log_parse("  shape_character read: more fill styles");
+               );
+
+               // Store the current path if any.
+               if (! current_path.is_empty()) {
+                   m_paths.push_back(current_path);
+                   current_path.m_edges.resize(0);
+
+                   // Clear styles.
+                   current_path.m_fill0 = -1;
+                   current_path.m_fill1 = -1;
+                   current_path.m_line = -1;
+               }
+               // Tack on an empty path signalling a new shape.
+               // @@ need better understanding of whether this is correct??!?!!
+               // @@ i.e., we should just start a whole new shape here, right?
+               m_paths.push_back(path());
+               m_paths.back().m_new_shape = true;
+
+               fill_base = m_fill_styles.size();
+               line_base = m_line_styles.size();
+               read_fill_styles(m_fill_styles, in, tag_type, m);
+               read_line_styles(m_line_styles, in, tag_type);
+               num_fill_bits = in->read_uint(4);
+               num_line_bits = in->read_uint(4);
+           }
+       } else {
+           // EDGERECORD
+           int edge_flag = in->read_uint(1);
+           if (edge_flag == 0) {
+               // curved edge
+               int num_bits = 2 + in->read_uint(4);
+               float   cx = x + in->read_sint(num_bits);
+               float   cy = y + in->read_sint(num_bits);
+               float   ax = cx + in->read_sint(num_bits);
+               float   ay = cy + in->read_sint(num_bits);
+
+               IF_VERBOSE_PARSE (
+               if (SHAPE_LOG)
+               {
+                   log_parse("  shape_character read: curved edge   = %4g %4g 
- %4g %4g - %4g %4g", x, y, cx, cy, ax, ay);
+               }
+               );
+
+               current_path.m_edges.push_back(edge(cx, cy, ax, ay));
+
+               x = ax;
+               y = ay;
+           } else {
+               // straight edge
+               int     num_bits = 2 + in->read_uint(4);
+               int     line_flag = in->read_uint(1);
+               float   dx = 0, dy = 0;
+               if (line_flag) {
+                   // General line.
+                   dx = (float) in->read_sint(num_bits);
+                   dy = (float) in->read_sint(num_bits);
+               } else {
+                   int vert_flag = in->read_uint(1);
+                   if (vert_flag == 0) {
+                       // Horizontal line.
+                       dx = (float) in->read_sint(num_bits);
+                   } else {
+                       // Vertical line.
+                       dy = (float) in->read_sint(num_bits);
+                   }
+               }
+
+               IF_VERBOSE_PARSE (
+               if (SHAPE_LOG)
+               {
+                   log_parse("  shape_character_read: straight edge = %4g %4g 
- %4g %4g", x, y, x + dx, y + dy);
+               }
+               );
+
+               current_path.m_edges.push_back(edge(x + dx, y + dy, x + dx, y + 
dy));
+
+               x += dx;
+               y += dy;
+           }
+       }
+    }
+}
+
+
+void   shape_character_def::display(character* inst)
+    // Draw the shape using our own inherent styles.
+{
+//    GNASH_REPORT_FUNCTION;
+
+    matrix     mat = inst->get_world_matrix();
+    cxform     cx = inst->get_world_cxform();
+
+    float      pixel_scale = inst->get_parent()->get_pixel_scale();
+    display(mat, cx, pixel_scale, m_fill_styles, m_line_styles);
+}
+
+
+#ifdef DEBUG_DISPLAY_SHAPE_PATHS
+
+#include "ogl.h"
+
+
+static void    point_normalize(point* p)
+{
+    float      mag2 = p->m_x * p->m_x + p->m_y * p->m_y;
+    if (mag2 < 1e-9f) {
+       // Very short vector.
+       // @@ log error
+
+       // Arbitrary unit vector.
+       p->m_x = 1;
+       p->m_y = 0;
+    }
+
+    float      inv_mag = 1.0f / sqrtf(mag2);
+    p->m_x *= inv_mag;
+    p->m_y *= inv_mag;
+}
+
+
+static void    show_fill_number(const point& p, int fill_number)
+{
+    // We're inside a glBegin(GL_LINES)
+
+    // Eh, let's do it in binary, least sig four bits...
+    float      x = p.m_x;
+    float      y = p.m_y;
+
+    int        mask = 8;
+    while (mask) {
+       if (mask & fill_number) {
+           // Vert line --> 1.
+           glVertex2f(x, y - 40.0f);
+           glVertex2f(x, y + 40.0f);
+       } else {
+           // Rectangle --> 0.
+           glVertex2f(x - 10.0f, y - 40.0f);
+           glVertex2f(x + 10.0f, y - 40.0f);
+
+           glVertex2f(x + 10.0f, y - 40.0f);
+           glVertex2f(x + 10.0f, y + 40.0f);
+
+           glVertex2f(x - 10.0f, y + 40.0f);
+           glVertex2f(x + 10.0f, y + 40.0f);
+
+           glVertex2f(x - 10.0f, y - 40.0f);
+           glVertex2f(x - 10.0f, y + 40.0f);
+       }
+       x += 40.0f;
+       mask >>= 1;
+    }
+}
+
+
+static void    debug_display_shape_paths(
+    const matrix& mat,
+    float /* object_space_max_error */,
+    const std::vector<path>& paths,
+    const std::vector<fill_style>& /* fill_styles */,
+    const std::vector<line_style>& /* line_styles */)
+{
+    for (unsigned int i = 0; i < paths.size(); i++) {
+//                     if (i > 0) break;//xxxxxxxx
+       const path&     p = paths[i];
+
+       if (p.m_fill0 == 0 && p.m_fill1 == 0) {
+           continue;
+       }
+
+       gnash::render::set_matrix(mat);
+
+       // Color the line according to which side has
+       // fills.
+       if (p.m_fill0 == 0) glColor4f(1, 0, 0, 0.5);
+       else if (p.m_fill1 == 0) glColor4f(0, 1, 0, 0.5);
+       else glColor4f(0, 0, 1, 0.5);
+
+       // Offset according to which loop we are.
+       float   offset_x = (i & 1) * 80.0f;
+       float   offset_y = ((i & 2) >> 1) * 80.0f;
+       glMatrixMode(GL_MODELVIEW);
+       glPushMatrix();
+       glTranslatef(offset_x, offset_y, 0.f);
+
+       point   pt;
+
+       glBegin(GL_LINE_STRIP);
+
+       mat.transform(&pt, point(p.m_ax, p.m_ay));
+       glVertex2f(pt.m_x, pt.m_y);
+
+       for (unsigned int j = 0; j < p.m_edges.size(); j++)     {
+           mat.transform(&pt, point(p.m_edges[j].m_cx, p.m_edges[j].m_cy));
+           glVertex2f(pt.m_x, pt.m_y);
+           mat.transform(&pt, point(p.m_edges[j].m_ax, p.m_edges[j].m_ay));
+           glVertex2f(pt.m_x, pt.m_y);
+       }
+
+       glEnd();
+
+       // Draw arrowheads.
+       point   dir, right, p0, p1;
+       glBegin(GL_LINES);
+       {for (unsigned int j = 0; j < p.m_edges.size(); j++)
+           {
+               mat.transform(&p0, point(p.m_edges[j].m_cx, p.m_edges[j].m_cy));
+               mat.transform(&p1, point(p.m_edges[j].m_ax, p.m_edges[j].m_ay));
+               dir = point(p1.m_x - p0.m_x, p1.m_y - p0.m_y);
+               point_normalize(&dir);
+               right = point(-dir.m_y, dir.m_x);       // perpendicular
+
+               const float     ARROW_MAG = 60.f;       // TWIPS?
+               if (p.m_fill0 != 0)
+                   {
+                       glColor4f(0, 1, 0, 0.5);
+                       glVertex2f(p0.m_x,
+                                  p0.m_y);
+                       glVertex2f(p0.m_x - dir.m_x * ARROW_MAG - right.m_x * 
ARROW_MAG,
+                                  p0.m_y - dir.m_y * ARROW_MAG - right.m_y * 
ARROW_MAG);
+
+                       show_fill_number(point(p0.m_x - right.m_x * ARROW_MAG * 
4,
+                                              p0.m_y - right.m_y * ARROW_MAG * 
4),
+                                        p.m_fill0);
+                   }
+               if (p.m_fill1 != 0)
+                   {
+                       glColor4f(1, 0, 0, 0.5);
+                       glVertex2f(p0.m_x,
+                                  p0.m_y);
+                       glVertex2f(p0.m_x - dir.m_x * ARROW_MAG + right.m_x * 
ARROW_MAG,
+                                  p0.m_y - dir.m_y * ARROW_MAG + right.m_y * 
ARROW_MAG);
+
+                       show_fill_number(point(p0.m_x + right.m_x * ARROW_MAG * 
4,
+                                              p0.m_y + right.m_y * ARROW_MAG * 
4),
+                                        p.m_fill1);
+                   }
+           }}
+       glEnd();
+
+       glPopMatrix();
+    }
+}
+#endif // DEBUG_DISPLAY_SHAPE_PATHS
+
+               
+void   shape_character_def::display(
+    const matrix& mat,
+    const cxform& cx,
+    float pixel_scale,
+    const std::vector<fill_style>& fill_styles,
+    const std::vector<line_style>& line_styles) const
+    // Display our shape.  Use the fill_styles arg to
+    // override our default set of fill styles (e.g. when
+    // rendering text).
+{
+//    GNASH_REPORT_FUNCTION;
+
+    // Compute the error tolerance in object-space.
+    float      max_scale = mat.get_max_scale();
+    if (fabsf(max_scale) < 1e-6f) {
+       // Scale is essentially zero.
+       return;
+    }
+
+    float      object_space_max_error = 20.0f / max_scale / pixel_scale * 
s_curve_max_pixel_error;
+
+#ifdef DEBUG_DISPLAY_SHAPE_PATHS
+    // Render a debug view of shape path outlines, instead
+    // of the tesselated shapes themselves.
+    if (gnash_debug_show_paths) {
+       debug_display_shape_paths(mat, object_space_max_error, m_paths, 
fill_styles, line_styles);
+
+       return;
+    }
+#endif // DEBUG_DISPLAY_SHAPE_PATHS
+
+    // See if we have an acceptable mesh available; if so then render with it.
+    for (unsigned int i = 0, n = m_cached_meshes.size(); i < n; i++) {
+       const mesh_set* candidate = m_cached_meshes[i];
+
+       if (object_space_max_error > candidate->get_error_tolerance() * 3.0f)
+           {
+               // Mesh is too high-res; the remaining meshes are higher res,
+               // so stop searching and build an appropriately scaled mesh.
+               break;
+           }
+
+       if (object_space_max_error > candidate->get_error_tolerance()) {
+           // Do it.
+           candidate->display(mat, cx, fill_styles, line_styles);
+           return;
+       }
+    }
+
+    // Construct a new mesh to handle this error tolerance.
+    mesh_set*  m = new mesh_set(this, object_space_max_error * 0.75f);
+    m_cached_meshes.push_back(m);
+    m->display(mat, cx, fill_styles, line_styles);
+               
+    sort_and_clean_meshes();
+}
+
+
+static int     sort_by_decreasing_error(const void* A, const void* B)
+{
+    const mesh_set*    a = *(const mesh_set* const *) A;
+    const mesh_set*    b = *(const mesh_set* const *) B;
+
+    if (a->get_error_tolerance() < b->get_error_tolerance()) {
+       return 1;
+    } else if (a->get_error_tolerance() > b->get_error_tolerance()) {
+       return -1;
+    } else {
+       return 0;
+    }
+}
+
+
+void   shape_character_def::sort_and_clean_meshes() const
+    // Maintain cached meshes.  Clean out mesh_sets that haven't
+    // been used recently, and make sure they're sorted from high
+    // error to low error.
+{
+    // Re-sort.
+    if (m_cached_meshes.size() > 0) {
+       qsort(
+           &m_cached_meshes[0],
+           m_cached_meshes.size(),
+           sizeof(m_cached_meshes[0]),
+           sort_by_decreasing_error);
+
+       // Check to make sure the sort worked as intended.
+#ifndef NDEBUG
+       for (unsigned int i = 0, n = m_cached_meshes.size() - 1; i < n; i++) {
+           const mesh_set*     a = m_cached_meshes[i];
+           const mesh_set*     b = m_cached_meshes[i + 1];
+
+           assert(a->get_error_tolerance() > b->get_error_tolerance());
+       }
+#endif // not NDEBUG
+    }
+}
+
+               
+void   shape_character_def::tesselate(float error_tolerance, 
tesselate::trapezoid_accepter* accepter) const
+    // Push our shape data through the tesselator.
+{
+    tesselate::begin_shape(accepter, error_tolerance);
+    for (unsigned int i = 0; i < m_paths.size(); i++) {
+       if (m_paths[i].m_new_shape == true)     {
+           // Hm; should handle separate sub-shapes in a less lame way.
+           tesselate::end_shape();
+           tesselate::begin_shape(accepter, error_tolerance);
+       } else {
+           m_paths[i].tesselate();
+       }
+    }
+    tesselate::end_shape();
+}
+
+
+bool   shape_character_def::point_test_local(float x, float y)
+    // Return true if the specified point is on the interior of our shape.
+    // Incoming coords are local coords.
+{
+    if (m_bound.point_test(x, y) == false) {
+       // Early out.
+       return false;
+    }
+
+    // Try each of the paths.
+    for (unsigned int i = 0; i < m_paths.size(); i++) {
+       if (m_paths[i].point_test(x, y))
+           {
+               return true;
+           }
+    }
+
+    return false;
+}
+
+
+float shape_character_def::get_height_local()
+{
+    return m_bound.height();
+}
+
+float shape_character_def::get_width_local()
+{
+    return m_bound.width();
+}
+
+
+void   shape_character_def::compute_bound(rect* r) const
+    // Find the bounds of this shape, and store them in
+    // the given rectangle.
+{
+    r->m_x_min = 1e10f;
+    r->m_y_min = 1e10f;
+    r->m_x_max = -1e10f;
+    r->m_y_max = -1e10f;
+
+    for (unsigned int i = 0; i < m_paths.size(); i++) {
+       const path&     p = m_paths[i];
+       r->expand_to_point(p.m_ax, p.m_ay);
+       for (unsigned int j = 0; j < p.m_edges.size(); j++)     {
+           r->expand_to_point(p.m_edges[j].m_ax, p.m_edges[j].m_ay);
+//                                     r->expand_to_point(p.m_edges[j].m_cx, 
p.m_edges[j].m_cy);
+       }
+    }
+}
+
+
+void   shape_character_def::output_cached_data(tu_file* out, const 
cache_options& /* options */)
+    // Dump our precomputed mesh data to the given stream.
+{
+    int        n = m_cached_meshes.size();
+    out->write_le32(n);
+
+    for (int i = 0; i < n; i++) {
+       m_cached_meshes[i]->output_cached_data(out);
+    }
+}
+
+
+void   shape_character_def::input_cached_data(tu_file* in)
+    // Initialize our mesh data from the given stream.
+{
+    int        n = in->read_le32();
+
+    m_cached_meshes.resize(n);
+
+    for (int i = 0; i < n; i++)        {
+       mesh_set*       ms = new mesh_set();
+       ms->input_cached_data(in);
+       m_cached_meshes[i] = ms;
+    }
+}
+
+       
+}      // end namespace gnash
+
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:

Index: server/parser/shape_character_def.h
===================================================================
RCS file: server/parser/shape_character_def.h
diff -N server/parser/shape_character_def.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/parser/shape_character_def.h 24 Aug 2006 00:57:20 -0000      1.1
@@ -0,0 +1,85 @@
+// shape.h     -- Thatcher Ulrich <address@hidden> 2003
+
+// This source code has been donated to the Public Domain.  Do
+// whatever you want with it.
+
+// Quadratic bezier outline shapes, the basis for most SWF rendering.
+
+
+#ifndef GNASH_SHAPE_CHARACTER_DEF_H
+#define GNASH_SHAPE_CHARACTER_DEF_H
+
+
+#include "styles.h"
+#include "character_def.h" // for inheritance of shape_character_def
+#include "tesselate.h" 
+#include "shape.h" // for path
+
+
+namespace gnash {
+
+       /// \brief
+       /// Represents the outline of one or more shapes, along with
+       /// information on fill and line styles.
+       class shape_character_def : public character_def, public 
tesselate::tesselating_shape
+       {
+       public:
+               shape_character_def();
+               virtual ~shape_character_def();
+
+               virtual void    display(character* inst);
+               bool    point_test_local(float x, float y);
+
+               float   get_height_local();
+               float   get_width_local();
+
+               void    read(stream* in, int tag_type, bool with_style, 
movie_definition* m);
+               void    display(
+                       const matrix& mat,
+                       const cxform& cx,
+                       float pixel_scale,
+                       const std::vector<fill_style>& fill_styles,
+                       const std::vector<line_style>& line_styles) const;
+               virtual void    tesselate(float error_tolerance, 
tesselate::trapezoid_accepter* accepter) const;
+               const rect&     get_bound() const { return m_bound; }
+               void    compute_bound(rect* r) const;   // @@ what's the 
difference between this and get_bound?
+
+               void    output_cached_data(tu_file* out, const cache_options& 
options);
+               void    input_cached_data(tu_file* in);
+
+               const std::vector<fill_style>&  get_fill_styles() const { 
return m_fill_styles; }
+               const std::vector<line_style>&  get_line_styles() const { 
return m_line_styles; }
+               const std::vector<path>&        get_paths() const { return 
m_paths; }
+
+               // morph uses this
+               void    set_bound(const rect& r) { m_bound = r; /* should do 
some verifying */ }
+
+       protected:
+               friend class morph2_character_def;
+
+               // derived morph classes changes these
+               std::vector<fill_style> m_fill_styles;
+               std::vector<line_style> m_line_styles;
+               std::vector<path>       m_paths;
+
+       private:
+               void    sort_and_clean_meshes() const;
+               
+               rect    m_bound;
+
+               // Cached pre-tesselated meshes.
+               mutable std::vector<mesh_set*>  m_cached_meshes;
+       };
+
+}      // end namespace gnash
+
+
+#endif // GNASH_SHAPE_CHARACTER_DEF_H
+
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 8 
+// tab-width: 8
+// indent-tabs-mode: t
+// End:

Index: server/parser/sprite_definition.cpp
===================================================================
RCS file: server/parser/sprite_definition.cpp
diff -N server/parser/sprite_definition.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/parser/sprite_definition.cpp 24 Aug 2006 00:57:20 -0000      1.1
@@ -0,0 +1,181 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+// 
+// This program 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 General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+// Linking Gnash statically or dynamically with other modules is making a
+// combined work based on Gnash. Thus, the terms and conditions of the GNU
+// General Public License cover the whole combination.
+//
+// As a special exception, the copyright holders of Gnash give you
+// permission to combine Gnash with free software programs or libraries
+// that are released under the GNU LGPL and with code included in any
+// release of Talkback distributed by the Mozilla Foundation. You may
+// copy and distribute such a system following the terms of the GNU GPL
+// for all but the LGPL-covered parts and Talkback, and following the
+// LGPL for the LGPL-covered parts.
+//
+// Note that people who make modified versions of Gnash are not obligated
+// to grant this special exception for their modified versions; it is their
+// choice whether to do so. The GNU General Public License gives permission
+// to release a modified version without this exception; this exception
+// also makes it possible to release a modified version which carries
+// forward this exception.
+// 
+//
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+// This needs to be included first for NetBSD systems or we get a weird
+// problem with pthread_t being defined too many times if we use any
+// STL containers.
+#ifdef HAVE_PTHREADS
+#include <pthread.h>
+#endif
+
+#include "sprite_instance.h"
+#include "sprite_definition.h"
+#include "execute_tag.h" // for dtor visibility
+
+#include <vector>
+#include <string>
+#include <cassert>
+
+using namespace std;
+
+namespace gnash {
+
+character*
+sprite_definition::create_character_instance(character* parent,
+               int id)
+{
+       sprite_instance* si = new sprite_instance(this,
+               parent->get_root(), parent, id);
+       return si;
+}
+
+sprite_definition::~sprite_definition()
+{
+       // Release our playlist data.
+       for (int i = 0, n = m_playlist.size(); i < n; i++)
+       {
+               for (int j = 0, m = m_playlist[i].size(); j < m; j++)
+               {
+                   delete m_playlist[i][j];
+               }
+       }
+}
+
+/*private*/
+// only called from constructors
+void
+sprite_definition::read(stream* in)
+{
+       int tag_end = in->get_tag_end_position();
+
+       m_frame_count = in->read_u16();
+
+       // ALEX: some SWF files have been seen that have 0-frame sprites.
+       // The Macromedia player behaves as if they have 1 frame.
+       if (m_frame_count < 1)
+       {
+               m_frame_count = 1;
+       }
+
+       // need a playlist for each frame
+       m_playlist.resize(m_frame_count);
+
+               IF_VERBOSE_PARSE (
+       log_parse("  frames = %u", m_frame_count);
+               );
+
+       m_loading_frame = 0;
+
+       while ((uint32_t) in->get_position() < (uint32_t) tag_end)
+       {
+               SWF::tag_type tag_type = in->open_tag();
+
+               SWF::TagLoadersTable::loader_function lf = NULL;
+
+               if (tag_type == SWF::DEFINESPRITE)
+               {
+                       log_error("DefineSprite tag inside sprite "
+                               "definition - Malformed SWF!");
+               }
+
+               if (tag_type == SWF::SHOWFRAME)
+               {
+                       // show frame tag -- advance to the next frame.
+                       IF_VERBOSE_PARSE (
+                   log_parse("  show_frame (sprite)");
+                       );
+                   m_loading_frame++;
+               }
+               else if (_tag_loaders.get(tag_type, &lf))
+               {
+                   // call the tag loader.  The tag loader should add
+                   // characters or tags to the movie data structure.
+                   (*lf)(in, tag_type, this);
+               }
+               else
+               {
+                       // no tag loader for this tag type.
+                    log_error("*** no tag loader for type %d (sprite)",
+                              tag_type);
+               }
+
+               in->close_tag();
+       }
+
+               IF_VERBOSE_PARSE (
+       log_parse("  -- sprite END --");
+               );
+}
+
+/*virtual*/
+void
+sprite_definition::add_frame_name(const char* name)
+{
+       assert((int)m_loading_frame >= 0 && m_loading_frame < m_frame_count);
+
+       tu_string n = name;
+       size_t currently_assigned = 0;
+       if (m_named_frames.get(n, &currently_assigned) == true)
+       {
+               log_error("add_frame_name(%d, '%s') -- frame name "
+                       "already assigned to frame %u; overriding\n",
+                       m_loading_frame,
+                       name, currently_assigned);
+       }
+
+       // stores 0-based frame #
+       m_named_frames[n] = m_loading_frame;
+}
+
+sprite_definition::sprite_definition(movie_definition* m, stream* in)
+       :
+       _tag_loaders(s_tag_loaders),  // FIXME: use a class-static 
TagLoadersTable for sprite_definition
+       m_movie_def(m),
+       m_frame_count(0),
+       m_loading_frame(0)
+{
+       assert(m_movie_def);
+       read(in);
+}
+
+
+
+} // namespace gnash

Index: server/parser/sprite_definition.h
===================================================================
RCS file: server/parser/sprite_definition.h
diff -N server/parser/sprite_definition.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/parser/sprite_definition.h   24 Aug 2006 00:57:20 -0000      1.1
@@ -0,0 +1,369 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+// 
+// This program 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 General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+// Linking Gnash statically or dynamically with other modules is making a
+// combined work based on Gnash. Thus, the terms and conditions of the GNU
+// General Public License cover the whole combination.
+//
+// As a special exception, the copyright holders of Gnash give you
+// permission to combine Gnash with free software programs or libraries
+// that are released under the GNU LGPL and with code included in any
+// release of Talkback distributed by the Mozilla Foundation. You may
+// copy and distribute such a system following the terms of the GNU GPL
+// for all but the LGPL-covered parts and Talkback, and following the
+// LGPL for the LGPL-covered parts.
+//
+// Note that people who make modified versions of Gnash are not obligated
+// to grant this special exception for their modified versions; it is their
+// choice whether to do so. The GNU General Public License gives permission
+// to release a modified version without this exception; this exception
+// also makes it possible to release a modified version which carries
+// forward this exception.
+// 
+//
+
+#ifndef GNASH_SPRITE_DEFINITION_H
+#define GNASH_SPRITE_DEFINITION_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <vector>
+
+#include "movie_definition.h"
+#include "stream.h"
+#include "log.h"
+
+namespace gnash
+{
+
+
+/// \brief
+/// Holds the immutable data for a sprite, as read from
+/// as SWF stream.
+/// @@ should *not* derive from movie_definition, probably!
+///
+class sprite_definition : public movie_definition
+{
+
+public:
+
+       /// \brief
+       /// Read the sprite info from input stream.
+       //
+       /// A sprite definition consists of a series control tags.
+       ///
+       /// @param m
+       ///     the Top-Level movie_definition this sprite is read
+       ///     from (not a sprite_definition!)
+       ///
+       /// @param in
+       ///     The stream associated with the sprite. It is assumed
+       ///     to be already positioned right before the frame count
+       ///         
+       sprite_definition(movie_definition* m, stream* in);
+
+       /// Destructor, releases playlist data
+       ~sprite_definition();
+
+private:
+
+       void read(stream* in);
+
+       /// Tags loader table.
+       //
+       /// TODO: make it a static member, specific to sprite_definition
+       SWF::TagLoadersTable& _tag_loaders;
+
+       /// Top-level movie definition
+       /// (the definition read from SWF stream)
+       movie_definition* m_movie_def;
+
+       /// movie control events for each frame.
+       std::vector<std::vector<execute_tag*> > m_playlist;
+
+       // stores 0-based frame #'s
+       stringi_hash<size_t> m_named_frames;
+
+       size_t m_frame_count;
+
+       size_t m_loading_frame;
+
+       // overloads from movie_definition
+       virtual float   get_width_pixels() const { return 1; }
+       virtual float   get_height_pixels() const { return 1; }
+
+       virtual size_t  get_frame_count() const
+       {
+               return m_frame_count;
+       }
+
+       /// \brief
+       /// Return total bytes of the movie from which this sprite
+       /// has been read.
+       ///
+       virtual size_t get_bytes_total() const
+       {
+               return m_movie_def->get_bytes_total();
+       }
+
+       /// \brief
+       /// Return the number of bytes loaded from the stream of the
+       /// the movie from which this sprite is being read.
+       ///
+       virtual size_t get_bytes_loaded() const
+       {
+               return m_movie_def->get_bytes_loaded();
+       }
+
+       virtual float   get_frame_rate() const { return 
m_movie_def->get_frame_rate(); }
+
+       // Return number of frames loaded (of current sprite)
+       virtual size_t  get_loading_frame() const { return m_loading_frame; }
+
+       virtual int     get_version() const { return 
m_movie_def->get_version(); }
+
+       virtual void add_font(int /*id*/, font* /*ch*/)
+       {
+               log_error("add_font tag appears in sprite tags! "
+                       "Malformed SWF?\n");
+       }
+
+       virtual font* get_font(int id) { return m_movie_def->get_font(id); }
+
+       virtual void set_jpeg_loader(std::auto_ptr<jpeg::input> /*j_in*/)
+       {
+               assert(0);
+       }
+
+       virtual jpeg::input* get_jpeg_loader()
+       {
+               return NULL;
+       }
+
+       virtual bitmap_character_def* get_bitmap_character(int id)
+       {
+               return m_movie_def->get_bitmap_character(id);
+       }
+
+       virtual void add_bitmap_character(int /*id*/,
+                       bitmap_character_def* /*ch*/)
+       {
+               log_error("add_bc appears in sprite tags!"
+                       " Malformed SWF?");
+       }
+
+       virtual sound_sample* get_sound_sample(int id)
+       {
+               return m_movie_def->get_sound_sample(id);
+       }
+
+       virtual void add_sound_sample(int /*id*/, sound_sample* /*sam*/)
+       {
+               log_error("add sam appears in sprite tags!"
+                       " Malformed SWF?");
+       }
+
+       virtual void set_loading_sound_stream_id(int id) { 
+               return m_movie_def->set_loading_sound_stream_id(id);
+       }
+
+       virtual int get_loading_sound_stream_id() { 
+               return m_movie_def->get_loading_sound_stream_id();
+       }
+
+       
+       // @@ would be nicer to not inherit these...
+       virtual create_bitmaps_flag     get_create_bitmaps() const
+       { assert(0); return DO_LOAD_BITMAPS; }
+       virtual create_font_shapes_flag get_create_font_shapes() const
+       { assert(0); return DO_LOAD_FONT_SHAPES; }
+       virtual int     get_bitmap_info_count() const
+       { assert(0); return 0; }
+       virtual bitmap_info*    get_bitmap_info(int /*i*/) const
+       { assert(0); return NULL; }
+       virtual void    add_bitmap_info(bitmap_info* /*bi*/)
+       { assert(0); }
+
+       virtual void export_resource(const tu_string& /*symbol*/,
+                       resource* /*res*/)
+       {
+               log_error("can't export from sprite! Malformed SWF?");
+       }
+
+       virtual smart_ptr<resource> get_exported_resource(const tu_string& sym)
+       {
+               return m_movie_def->get_exported_resource(sym);
+       }
+
+       virtual void add_import(const char* /*source_url*/, int /*id*/,
+                       const char* /*symbol*/)
+       {
+               assert(0);
+       }
+
+       virtual void visit_imported_movies(import_visitor* /*v*/)
+       {
+               assert(0);
+       }
+
+       virtual void resolve_import(const char* /*source_url*/,
+                       movie_definition* /*d*/)
+       {
+               assert(0);
+       }
+
+
+       /// \brief
+       /// Get a character_def from this Sprite's parent
+       /// CharacterDictionary. NOTE that calling this
+       /// method on the leaf Sprite of a movie_definition
+       /// hierarchy will result in a recursive scan of
+       /// all parents until the top-level movie_definition
+       /// (movie_def_impl) is found.
+       ///
+       virtual character_def*  get_character_def(int id)
+       {
+           return m_movie_def->get_character_def(id);
+       }
+
+       /// Calls to this function should only be made when
+       /// an invalid SWF is being read, as it would mean
+       /// that a Definition tag is been found as part of
+       /// a Sprite definition
+       ///
+       virtual void add_character(int /*id*/, character_def* /*ch*/)
+       {
+               log_error("add_character tag appears in sprite tags!"
+                               " Maformed SWF?");
+       }
+
+
+       virtual void generate_font_bitmaps()
+       {
+               assert(0);
+       }
+
+       virtual void output_cached_data(tu_file* /*out*/,
+               const cache_options& /*options*/)
+       {
+           // Nothing to do.
+           return;
+       }
+
+       virtual void    input_cached_data(tu_file* /*in*/)
+       {
+           // Nothing to do.
+           return;
+       }
+
+       virtual movie_interface* create_instance()
+       {
+           return NULL;
+       }
+
+       // Create a (mutable) instance of our definition.  The
+       // instance is created to live (temporarily) on some level on
+       // the parent movie's display list.
+       //
+       // overloads from character_def
+       virtual character* create_character_instance(
+               character* parent, int id);
+
+
+       virtual void    add_execute_tag(execute_tag* c)
+       {
+               m_playlist[m_loading_frame].push_back(c);
+       }
+
+       //virtual void  add_init_action(int sprite_id, execute_tag* c)
+       virtual void    add_init_action(execute_tag* /*c*/)
+       {
+           // Sprite def's should not have do_init_action tags in them!  (@@ 
correct?)
+           log_error("sprite_definition::add_init_action called!  Ignored. 
(Malformed SWF?)\n");
+       }
+
+       /// \brief
+       /// Labels the frame currently being loaded with the
+       /// given name.  A copy of the name string is made and
+       /// kept in this object.
+       ///
+       virtual void    add_frame_name(const char* name);
+
+       /// Returns 0-based frame #
+       bool    get_labeled_frame(const char* label, size_t* frame_number)
+       {
+           return m_named_frames.get(label, frame_number);
+       }
+
+       /// frame_number is 0-based
+       const std::vector<execute_tag*>& get_playlist(size_t frame_number)
+       {
+               return m_playlist[frame_number];
+       }
+
+       // Sprites do not have init actions in their
+       // playlists!  Only the root movie
+       // (movie_def_impl) does (@@ correct?)
+       virtual const std::vector<execute_tag*>* get_init_actions(size_t 
/*frame_number*/)
+       {
+           return NULL;
+       }
+
+       virtual const std::string& get_url() const
+       {
+           return m_movie_def->get_url();
+       }
+
+       /// \brief
+       /// Ensure framenum frames of this sprite 
+       /// have been loaded.
+       ///
+       virtual bool ensure_frame_loaded(size_t framenum)
+       {
+               // TODO: return false on timeout 
+               while ( m_loading_frame < framenum )
+               {
+                       log_msg("sprite_definition: "
+                               "loading of frame %u requested "
+                               "(we are at %u/%u)",
+                               framenum, m_loading_frame, m_frame_count);
+                       // Could this ever happen ?
+                       assert(0);
+               }
+               return true;
+       }
+
+       virtual void load_next_frame_chunk()
+       {
+               /// We load full sprite definitions at once, so
+               /// this function is a no-op. 
+       }
+
+       /// Return the top-level movie definition
+       /// (the definition read from SWF stream)
+       movie_definition* get_movie_definition() {
+               return m_movie_def;
+       }
+
+
+};
+
+
+} // end of namespace gnash
+
+#endif // GNASH_SPRITE_H

Index: server/parser/text_character_def.h
===================================================================
RCS file: server/parser/text_character_def.h
diff -N server/parser/text_character_def.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/parser/text_character_def.h  24 Aug 2006 00:57:20 -0000      1.1
@@ -0,0 +1,129 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+// 
+// This program 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 General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+// Linking Gnash statically or dynamically with other modules is making a
+// combined work based on Gnash. Thus, the terms and conditions of the GNU
+// General Public License cover the whole combination.
+//
+// As a special exception, the copyright holders of Gnash give you
+// permission to combine Gnash with free software programs or libraries
+// that are released under the GNU LGPL and with code included in any
+// release of Talkback distributed by the Mozilla Foundation. You may
+// copy and distribute such a system following the terms of the GNU GPL
+// for all but the LGPL-covered parts and Talkback, and following the
+// LGPL for the LGPL-covered parts.
+//
+// Note that people who make modified versions of Gnash are not obligated
+// to grant this special exception for their modified versions; it is their
+// choice whether to do so. The GNU General Public License gives permission
+// to release a modified version without this exception; this exception
+// also makes it possible to release a modified version which carries
+// forward this exception.
+// 
+//
+//
+
+// Code for the text tags.
+
+
+#ifndef GNASH_PARSER_TEXT_CHARACTER_DEF_H
+#define GNASH_PARSER_TEXT_CHARACTER_DEF_H
+
+#include "textformat.h" // maybe we should include it here
+#include "styles.h" 
+
+namespace gnash {
+
+// Forward declarations
+struct text_character_def; 
+struct text_glyph_record; 
+
+// Helper struct.
+// @@ text_character_def friend ?
+struct text_style
+{
+       int     m_font_id;
+       mutable const font*     m_font;
+       rgba    m_color;
+       float   m_x_offset;
+       float   m_y_offset;
+       float   m_text_height;
+       bool    m_has_x_offset;
+       bool    m_has_y_offset;
+
+       text_style()
+               :
+               m_font_id(-1),
+               m_font(NULL),
+               m_x_offset(0),
+               m_y_offset(0),
+               m_text_height(1.0f),
+               m_has_x_offset(false),
+               m_has_y_offset(false)
+       {
+       }
+
+       void    resolve_font(movie_definition* root_def) const;
+};
+
+
+// Helper struct.
+// @@ text_character_def friend ?
+struct text_glyph_record
+{
+       struct glyph_entry
+       {
+               int     m_glyph_index;
+               float   m_glyph_advance;
+       };
+       text_style      m_style;
+       std::vector<glyph_entry>        m_glyphs;
+
+       void read(stream* in, int glyph_count,
+               int glyph_bits, int advance_bits);
+
+};
+
+/// Text character 
+//
+/// This is either read from SWF stream 
+/// or (hopefully) created with scripting
+///
+struct text_character_def : public character_def
+{
+       movie_definition*       m_root_def;
+       rect    m_rect;
+       matrix  m_matrix;
+       std::vector<text_glyph_record>  m_text_glyph_records;
+
+       text_character_def(movie_definition* root_def)
+               :
+               m_root_def(root_def)
+       {
+               assert(m_root_def);
+       }
+
+       void read(stream* in, int tag_type, movie_definition* m);
+
+       /// Draw the string.
+       void display(character* inst);
+
+};
+
+
+} // namespace gnash
+
+#endif // GNASH_PARSER_TEXT_CHARACTER_DEF_H

Index: server/MovieClip.cpp
===================================================================
RCS file: server/MovieClip.cpp
diff -N server/MovieClip.cpp
--- server/MovieClip.cpp        6 Aug 2006 02:00:54 -0000       1.3
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,89 +0,0 @@
-// 
-//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
-// 
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-// 
-// This program 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 General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-// Linking Gnash statically or dynamically with other modules is making a
-// combined work based on Gnash. Thus, the terms and conditions of the GNU
-// General Public License cover the whole combination.
-//
-// As a special exception, the copyright holders of Gnash give you
-// permission to combine Gnash with free software programs or libraries
-// that are released under the GNU LGPL and with code included in any
-// release of Talkback distributed by the Mozilla Foundation. You may
-// copy and distribute such a system following the terms of the GNU GPL
-// for all but the LGPL-covered parts and Talkback, and following the
-// LGPL for the LGPL-covered parts.
-//
-// Note that people who make modified versions of Gnash are not obligated
-// to grant this special exception for their modified versions; it is their
-// choice whether to do so. The GNU General Public License gives permission
-// to release a modified version without this exception; this exception
-// also makes it possible to release a modified version which carries
-// forward this exception.
-// 
-//
-#ifdef HAVE_PTHREADS
-#include <pthread.h>
-#endif
-
-#include <iostream>
-#include <string>
-
-#include "MovieClip.h"
-#include "tu_file.h"
-#include "zlib_adapter.h"
-//#include "stream.h"
-//#include "jpeg.h"
-//#include "fontlib.h"
-//#include "font.h"
-#include "log.h"
-//#include "Sprite.h"
-//#include "sprite_instance.h"
-#include "render.h"
-
-using namespace std;
-
-namespace gnash
-{
-
-// Forward declarations
-
-// @@ should be found somewhere else I guess..
-//movie_interface* create_instance();
-
-void
-movieclip_init(as_object* /* global */)
-{
-#if 0
-    // This is going to be the global MovieClip "class"/"function"
-    static as_function *func=new function_as_object();
-
-    // We make the 'prototype' element be a reference to
-    // the __proto__ element
-    as_object* proto = func->m_prototype;
-    proto->add_ref();
-
-    proto->set_member("constructor", func); //as_value(func));
-    proto->set_member_flags("constructor", 1);
-
-    func->set_member("prototype", as_value(proto));
-
-    // Register _global.Function
-    global->set_member("Function", func);
-#endif
-}
-
-} // namespace gnash
-

Index: server/MovieClip.h
===================================================================
RCS file: server/MovieClip.h
diff -N server/MovieClip.h
--- server/MovieClip.h  7 May 2006 12:19:06 -0000       1.1
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,51 +0,0 @@
-// 
-//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
-// 
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-// 
-// This program 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 General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-// Linking Gnash statically or dynamically with other modules is making a
-// combined work based on Gnash. Thus, the terms and conditions of the GNU
-// General Public License cover the whole combination.
-//
-// As a special exception, the copyright holders of Gnash give you
-// permission to combine Gnash with free software programs or libraries
-// that are released under the GNU LGPL and with code included in any
-// release of Talkback distributed by the Mozilla Foundation. You may
-// copy and distribute such a system following the terms of the GNU GPL
-// for all but the LGPL-covered parts and Talkback, and following the
-// LGPL for the LGPL-covered parts.
-//
-// Note that people who make modified versions of Gnash are not obligated
-// to grant this special exception for their modified versions; it is their
-// choice whether to do so. The GNU General Public License gives permission
-// to release a modified version without this exception; this exception
-// also makes it possible to release a modified version which carries
-// forward this exception.
-// 
-//
-
-#ifndef GNASH_MOVIECLIP_H
-#define GNASH_MOVIECLIP_H
-
-namespace gnash
-{
-
-class as_object;
-
-/// Initialize the global MovieClip constructor
-void movieclip_init(as_object* global);
-
-} // namespace gnash
-
-#endif // GNASH_MOVIECLIP_H

Index: server/Object.h
===================================================================
RCS file: server/Object.h
diff -N server/Object.h
--- server/Object.h     8 May 2006 11:43:58 -0000       1.11
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,46 +0,0 @@
-// 
-//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
-// 
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-// 
-// This program 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 General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-// Linking Gnash statically or dynamically with other modules is making a
-// combined work based on Gnash. Thus, the terms and conditions of the GNU
-// General Public License cover the whole combination.
-//
-// As a special exception, the copyright holders of Gnash give you
-// permission to combine Gnash with free software programs or libraries
-// that are released under the GNU LGPL and with code included in any
-// release of Talkback distributed by the Mozilla Foundation. You may
-// copy and distribute such a system following the terms of the GNU GPL
-// for all but the LGPL-covered parts and Talkback, and following the
-// LGPL for the LGPL-covered parts.
-//
-// Note that people who make modified versions of Gnash are not obligated
-// to grant this special exception for their modified versions; it is their
-// choice whether to do so. The GNU General Public License gives permission
-// to release a modified version without this exception; this exception
-// also makes it possible to release a modified version which carries
-// forward this exception.
-// 
-//
-
-#warning Object.h header has been split, do not include it directly
-
-#ifndef GNASH_OBJECT_H
-#define GNASH_OBJECT_H
-
-namespace gnash {
-} // namespace gnash
-
-#endif // GNASH_OBJECT_H

Index: server/action_buffer.cpp
===================================================================
RCS file: server/action_buffer.cpp
diff -N server/action_buffer.cpp
--- server/action_buffer.cpp    21 Aug 2006 12:54:47 -0000      1.18
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,479 +0,0 @@
-// 
-//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
-// 
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-// 
-// This program 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 General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-// Linking Gnash statically or dynamically with other modules is making a
-// combined work based on Gnash. Thus, the terms and conditions of the GNU
-// General Public License cover the whole combination.
-//
-// As a special exception, the copyright holders of Gnash give you
-// permission to combine Gnash with free software programs or libraries
-// that are released under the GNU LGPL and with code included in any
-// release of Talkback distributed by the Mozilla Foundation. You may
-// copy and distribute such a system following the terms of the GNU GPL
-// for all but the LGPL-covered parts and Talkback, and following the
-// LGPL for the LGPL-covered parts.
-//
-// Note that people who make modified versions of Gnash are not obligated
-// to grant this special exception for their modified versions; it is their
-// choice whether to do so. The GNU General Public License gives permission
-// to release a modified version without this exception; this exception
-// also makes it possible to release a modified version which carries
-// forward this exception.
-//
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "action_buffer.h"
-#include "ActionExec.h"
-#include "log.h"
-#include "stream.h"
-
-#include "swf.h"
-#include "ASHandlers.h"
-#include "as_environment.h"
-
-#include <typeinfo> 
-
-#if !defined(_WIN32) && !defined(WIN32)
-# include <pthread.h> 
-#endif
-
-#include <string>
-#include <stdlib.h> // for strtod
-
-using namespace gnash;
-using namespace SWF;
-using std::string;
-using std::endl;
-
-
-namespace gnash {
-
-static const SWFHandlers& ash = SWFHandlers::instance();
-
-action_buffer::action_buffer()
-    :
-    m_decl_dict_processed_at(-1)
-{
-//     static int count=0;
-//     printf("Action buffer %d created\n", ++count);
-}
-
-
-void
-action_buffer::read(stream* in)
-{
-    // Read action bytes.
-    for (;;) {
-#if 0
-       size_t instruction_start = m_buffer.size();
-       size_t pc = m_buffer.size();
-#endif
-
-       uint8_t action_id = in->read_u8();
-       m_buffer.push_back(action_id);
-       
-       if (action_id & 0x80) {
-           // Action contains extra data.  Read it.
-           uint16_t length = in->read_u16();
-           m_buffer.push_back(length & 0x0FF);
-           m_buffer.push_back((length >> 8) & 0x0FF);
-           for (uint16_t i = 0; i < length; i++) {
-               uint8_t b = in->read_u8();
-               m_buffer.push_back(b);
-           }
-       }
-       
-       if (action_id == SWF::ACTION_END)
-       {
-           // end of action buffer.
-           break;
-       }
-    }
-}
-
-
-/*public*/
-void
-action_buffer::process_decl_dict(size_t start_pc, size_t stop_pc) const
-{
-    assert(stop_pc <= m_buffer.size());
-    
-    if (static_cast<size_t>(m_decl_dict_processed_at) == start_pc) {
-       // We've already processed this decl_dict.
-#ifndef NDEBUG
-       int count = read_int16(start_pc+3);
-       assert((int) m_dictionary.size() == count);
-#endif
-       return;
-    }
-    
-    if (m_decl_dict_processed_at != -1)        {
-       log_error("process_decl_dict(%zd, %zd): decl_dict was already processed 
at %d\n",
-                 start_pc,
-                 stop_pc,
-                 m_decl_dict_processed_at);
-       return;
-    }
-    
-    m_decl_dict_processed_at = start_pc;
-    
-    // Actual processing.
-    size_t i = start_pc;
-    int16 length = read_int16(i+1);
-    int16 count = read_int16(i+3);
-    i += 2;
-    
-//log_msg("Start at %d, stop at %d, length read was %d, count read was %d", 
start_pc, stop_pc, length, count);
-
-    assert(start_pc + 3 + length == stop_pc);
-    
-    m_dictionary.resize(count);
-    
-    // Index the strings.
-    for (int ct = 0; ct < count; ct++) {
-       // Point into the current action buffer.
-       m_dictionary[ct] = (const char*) &m_buffer[3 + i];
-       
-       while (m_buffer[3 + i]) {
-           // safety check.
-           if (i >= stop_pc) {
-               log_error("action buffer dict length exceeded\n");
-               
-               // Jam something into the remaining (invalid) entries.
-               while (ct < count) {
-                   m_dictionary[ct] = "<invalid>";
-                   ct++;
-               }
-               return;
-           }
-           i++;
-       }
-       i++;
-    }
-}
-
-// Interpret the actions in this action buffer, and evaluate
-// them in the given environment.  Execute our whole buffer,
-// without any arguments passed in.
-void
-action_buffer::execute(as_environment* env) const
-{
-       assert(env);
-
-       int local_stack_top = env->get_local_frame_top();
-       env->add_frame_barrier();
-
-       ActionExec exec(*this, *env);
-       exec();
-    
-       env->set_local_frame_top(local_stack_top);
-}
-
-// Interpret the specified subset of the actions in our
-// buffer.  Caller is responsible for cleaning up our local
-// stack frame (it may have passed its arguments in via the
-// local stack frame).
-// 
-// The is_function2 flag determines whether to use global or local registers.
-void
-action_buffer::execute(
-    as_environment* env,
-    size_t start_pc,
-    size_t exec_bytes, // used when invoked as a function call
-    as_value* retval, // used when invoked as a function call
-    const std::vector<with_stack_entry>& initial_with_stack,
-    bool is_function2) const
-{
-       assert(env);
-       ActionExec exec(*this, *env, start_pc, exec_bytes, retval,
-               initial_with_stack, is_function2);
-       exec();
-}
-
-// Disassemble one instruction to the log.
-static void
-disasm(const unsigned char* instruction_data)
-{    
-
-    as_arg_t fmt = ARG_HEX;
-    action_type        action_id = (action_type)instruction_data[0];
-    unsigned char num[10];
-    memset(num, 0, 10);
-
-    dbglogfile.setStamp(false);
-    // Show instruction.
-    if (action_id > ash.lastType()) {
-       dbglogfile << "<unknown>[0x" << action_id  << "]" << endl;
-    } else {
-       dbglogfile << ash[action_id].getName().c_str() << endl;
-       fmt = ash[action_id].getArgFormat();
-    }
-
-    // Show instruction argument(s).
-    if (action_id & 0x80) {
-       assert(fmt != ARG_NONE);
-       int length = instruction_data[1] | (instruction_data[2] << 8);
-       if (fmt == ARG_HEX) {
-           for (int i = 0; i < length; i++) {
-               hexify(num, (const unsigned char *)&instruction_data[3 + i], 1, 
false);
-               dbglogfile << "0x" << num << " ";
-//             dbglogfile << instruction_data[3 + i] << " ";
-           }
-           dbglogfile << endl;
-       } else if (fmt == ARG_STR) {
-           string str;
-           for (int i = 0; i < length; i++) {
-               str = instruction_data[3 + i];
-           }
-           dbglogfile << "\"" << str.c_str() << "\"" << endl;
-       } else if (fmt == ARG_U8) {
-           int val = instruction_data[3];
-           dbglogfile << " " << val << endl;
-       } else if (fmt == ARG_U16) {
-           int val = instruction_data[3] | (instruction_data[4] << 8);
-           dbglogfile << " " << val << endl;
-       } else if (fmt == ARG_S16) {
-           int val = instruction_data[3] | (instruction_data[4] << 8);
-           if (val & 0x8000) val |= ~0x7FFF;   // sign-extend
-           dbglogfile << " " << val << endl;
-       } else if (fmt == ARG_PUSH_DATA) {
-           dbglogfile << endl;
-           int i = 0;
-           while (i < length) {
-               int     type = instruction_data[3 + i];
-               i++;
-               if (type == 0) {
-                   // string
-                   string str;
-                   while (instruction_data[3 + i]) {
-                       str += instruction_data[3 + i];
-                       i++;
-                   }
-                   i++;
-                   dbglogfile << "\t\"" << str.c_str() << "\"" << endl;
-               } else if (type == 1) {
-                   // float (little-endian)
-                   union {
-                       float   f;
-                       uint32_t        i;
-                   } u;
-                   compiler_assert(sizeof(u) == sizeof(u.i));
-                   
-                   memcpy(&u.i, instruction_data + 3 + i, 4);
-                   u.i = swap_le32(u.i);
-                   i += 4;
-                   
-                   dbglogfile << "(float) " << u.f << endl;
-               } else if (type == 2) {
-                   dbglogfile << "NULL" << endl;
-               } else if (type == 3) {
-                   dbglogfile << "undef" << endl;
-               } else if (type == 4) {
-                   // contents of register
-                   int reg = instruction_data[3 + i];
-                   i++;
-                   dbglogfile << "reg[" << reg << "]" << endl;
-               } else if (type == 5) {
-                   int bool_val = instruction_data[3 + i];
-                   i++;
-                   dbglogfile << "bool(" << bool_val << ")" << endl;
-               } else if (type == 6) {
-                   // double
-                   // wacky format: 45670123
-                   union {
-                       double  d;
-                       uint64  i;
-                       struct {
-                           uint32_t    lo;
-                           uint32_t    hi;
-                       } sub;
-                   } u;
-                   compiler_assert(sizeof(u) == sizeof(u.i));
-                   
-                   memcpy(&u.sub.hi, instruction_data + 3 + i, 4);
-                   memcpy(&u.sub.lo, instruction_data + 3 + i + 4, 4);
-                   u.i = swap_le64(u.i);
-                   i += 8;
-                   
-                   dbglogfile << "(double) " << u.d << endl;
-               } else if (type == 7) {
-                   // int32
-                   int32_t     val = instruction_data[3 + i]
-                       | (instruction_data[3 + i + 1] << 8)
-                       | (instruction_data[3 + i + 2] << 16)
-                       | (instruction_data[3 + i + 3] << 24);
-                   i += 4;
-                   dbglogfile << "(int) " << val << endl;
-               } else if (type == 8) {
-                   int id = instruction_data[3 + i];
-                   i++;
-                   dbglogfile << "dict_lookup[" << id << "]" << endl;
-               } else if (type == 9) {
-                   int id = instruction_data[3 + i] | (instruction_data[3 + i 
+ 1] << 8);
-                   i += 2;
-                   dbglogfile << "dict_lookup_lg[" << id << "]" << endl;
-               }
-           }
-       } else if (fmt == ARG_DECL_DICT) {
-           int i = 0;
-           int count = instruction_data[3 + i] | (instruction_data[3 + i + 1] 
<< 8);
-           i += 2;
-           
-           dbglogfile << " [" << count << "]" << endl;
-           
-           // Print strings.
-           for (int ct = 0; ct < count; ct++) {
-               dbglogfile << "\t" << endl;     // indent
-               
-               string str;
-               while (instruction_data[3 + i]) {
-                       // safety check.
-                   if (i >= length) {
-                       dbglogfile << "<disasm error -- length exceeded>" << 
endl;
-                       break;
-                   }
-                   str += instruction_data[3 + i];
-                   i++;
-               }
-               dbglogfile << "\"" << str.c_str() << "\"" << endl;
-               i++;
-           }
-       } else if (fmt == ARG_FUNCTION2) {
-           // Signature info for a function2 opcode.
-           int i = 0;
-           const char* function_name = (const char*) &instruction_data[3 + i];
-           i += strlen(function_name) + 1;
-           
-           int arg_count = instruction_data[3 + i] | (instruction_data[3 + i + 
1] << 8);
-           i += 2;
-           
-           int reg_count = instruction_data[3 + i];
-           i++;
-
-           dbglogfile << "\t\tname = '" << function_name << "'"
-                      << " arg_count = " << arg_count
-                      << " reg_count = " << reg_count << endl;
-           
-           uint16      flags = (instruction_data[3 + i]) | (instruction_data[3 
+ i + 1] << 8);
-           i += 2;
-           
-           // @@ What is the difference between "super" and "_parent"?
-           
-           bool        preload_global = (flags & 0x100) != 0;
-           bool        preload_parent = (flags & 0x80) != 0;
-           bool        preload_root   = (flags & 0x40) != 0;
-           bool        suppress_super = (flags & 0x20) != 0;
-           bool        preload_super  = (flags & 0x10) != 0;
-           bool        suppress_args  = (flags & 0x08) != 0;
-           bool        preload_args   = (flags & 0x04) != 0;
-           bool        suppress_this  = (flags & 0x02) != 0;
-           bool        preload_this   = (flags & 0x01) != 0;
-           
-           log_msg("\t\t        pg = %d\n"
-                   "\t\t        pp = %d\n"
-                   "\t\t        pr = %d\n"
-                   "\t\tss = %d, ps = %d\n"
-                   "\t\tsa = %d, pa = %d\n"
-                   "\t\tst = %d, pt = %d\n",
-                   int(preload_global),
-                   int(preload_parent),
-                   int(preload_root),
-                   int(suppress_super),
-                   int(preload_super),
-                   int(suppress_args),
-                   int(preload_args),
-                   int(suppress_this),
-                   int(preload_this));
-           
-           for (int argi = 0; argi < arg_count; argi++) {
-               int     arg_register = instruction_data[3 + i];
-               i++;
-               const char*     arg_name = (const char*) &instruction_data[3 + 
i];
-               i += strlen(arg_name) + 1;
-               
-               dbglogfile << "\t\targ[" << argi << "]"
-                          << " - reg[" << arg_register << "]"
-                          << " - '" << arg_name << "'" << endl;
-           }
-           
-           int function_length = instruction_data[3 + i] | (instruction_data[3 
+ i + 1] << 8);
-           i += 2;
-           
-           dbglogfile << "\t\tfunction length = " << function_length << endl;
-       }
-    } else {
-       dbglogfile << endl;
-    }
-    dbglogfile.setStamp(true);
-}
-
-// Disassemble one instruction to the log.
-void
-action_buffer::log_disasm(size_t pc) const
-{    
-       const unsigned char* instruction_data =
-               (const unsigned char *)&m_buffer[pc];
-       disasm(instruction_data);
-}
-
-
-float
-action_buffer::read_float_little(size_t pc) const
-{
-       union {
-               float   f;
-               uint32_t        i;
-       } u;
-       compiler_assert(sizeof(u) == sizeof(u.i));
-       memcpy(&u.i, &m_buffer[pc], 4);
-       u.i = swap_le32(u.i);
-       return u.f;
-}
-
-double
-action_buffer::read_double_wacky(size_t pc) const
-{
-       // double
-       // wacky format: 45670123
-       union {
-               double  d;
-               uint64  i;
-               struct {
-                       uint32_t        lo;
-                       uint32_t        hi;
-               } sub;
-       } u;
-
-       compiler_assert(sizeof(u) == sizeof(u.i));
-
-       // this works, but is pretty dirty
-       memcpy(&u.sub.hi, &m_buffer[pc], 4);
-       memcpy(&u.sub.lo, &m_buffer[pc + 4], 4);
-       u.i = swap_le64(u.i);
-
-       return u.d;
-}
-
-}
-
-
-// Local Variables:
-// mode: C++
-// indent-tabs-mode: t
-// End:

Index: server/action_buffer.h
===================================================================
RCS file: server/action_buffer.h
diff -N server/action_buffer.h
--- server/action_buffer.h      4 Aug 2006 14:45:52 -0000       1.5
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,284 +0,0 @@
-// 
-//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
-// 
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-// 
-// This program 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 General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-// Linking Gnash statically or dynamically with other modules is making a
-// combined work based on Gnash. Thus, the terms and conditions of the GNU
-// General Public License cover the whole combination.
-//
-// As a special exception, the copyright holders of Gnash give you
-// permission to combine Gnash with free software programs or libraries
-// that are released under the GNU LGPL and with code included in any
-// release of Talkback distributed by the Mozilla Foundation. You may
-// copy and distribute such a system following the terms of the GNU GPL
-// for all but the LGPL-covered parts and Talkback, and following the
-// LGPL for the LGPL-covered parts.
-//
-// Note that people who make modified versions of Gnash are not obligated
-// to grant this special exception for their modified versions; it is their
-// choice whether to do so. The GNU General Public License gives permission
-// to release a modified version without this exception; this exception
-// also makes it possible to release a modified version which carries
-// forward this exception.
-// 
-//
-//
-
-#ifndef GNASH_ACTION_BUFFER_H
-#define GNASH_ACTION_BUFFER_H
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-
-#include "gnash.h"
-//#include "as_object.h"
-#include "types.h"
-#include <wchar.h>
-
-#include "container.h"
-#include "smart_ptr.h"
-//#include "log.h"
-#include "with_stack_entry.h"
-
-// Forward declarations
-namespace gnash {
-       struct as_environment;
-       struct as_value;
-       namespace SWF {
-               class ActionHandler;
-       }
-}
-
-
-namespace gnash {
-
-class ActionExec;
-
-/// A code segment.
-//
-/// This currently holds the actions in a memory
-/// buffer, but I'm workin toward making this unneeded
-/// so to eventually use a gnash::stream directly and
-/// avoid full loads. (not before profiling!).
-//
-class action_buffer
-{
-
-public:
-
-       friend class ActionExec;
-
-       action_buffer();
-
-       /// Read action bytes from input stream
-       void    read(stream* in);
-
-       /// \brief
-       /// Interpret the actions in this action buffer, and evaluate
-       /// them in the given environment. 
-       //
-       /// Execute our whole buffer,
-       /// without any arguments passed in.
-       /// 
-       /// FIXME: obsolete this, use ActionExec instead.
-       ///
-       void    execute(as_environment* env) const;
-
-       /// Interpret the specified subset of the actions in our buffer.
-       //
-       /// Caller is responsible for cleaning up our local
-       /// stack frame (it may have passed its arguments in via the
-       /// local stack frame).
-       ///
-       /// FIXME: obsolete this, use ActionExec instead.
-       ///
-       void execute(
-               as_environment* env,
-               size_t start_pc,
-               size_t exec_bytes,
-               as_value* retval, // we should probably drop this parameter
-               const std::vector<with_stack_entry>& initial_with_stack,
-               bool is_function2) const;
-
-       bool is_null() const
-       {
-               return m_buffer.size() < 1 || m_buffer[0] == 0;
-       }
-
-       // kept for backward compatibility, should drop and see
-       // what breaks.
-       size_t get_length() const { return size(); }
-
-       size_t size() const { return m_buffer.size(); }
-
-       uint8_t operator[] (size_t off) const
-       {
-               assert(off < m_buffer.size() );
-               return m_buffer[off];
-       }
-
-       /// Disassemble instruction at given offset to the log.
-       void log_disasm(size_t pc) const;
-
-       /// Get a null-terminated string from given offset
-       //
-       /// Useful to hide complexity of underlying buffer access.
-       ///
-       const char* read_string(size_t pc) const
-       {
-               return (const char*)(&m_buffer[pc]);
-       }
-
-       /// Get an integer value from given offset
-       //
-       /// Useful to hide complexity of underlying buffer access.
-       ///
-       int16_t read_int16(size_t pc) const
-       {
-               int ret = m_buffer[pc] | (m_buffer[pc + 1] << 8);
-               return ret;
-       }
-
-       /// Read a 32-bit integer starting at given offset.
-       //
-       /// Useful to hide complexity of underlying buffer access.
-       ///
-       int32_t read_int32(size_t pc) const
-       {
-               int32_t val = m_buffer[pc]
-                     | (m_buffer[pc + 1] << 8)
-                     | (m_buffer[pc + 2] << 16)
-                     | (m_buffer[pc + 3] << 24);
-               return val;
-       }
-
-       /// Read a little-endian 32-bit float starting at given offset
-       //
-       /// Useful to hide complexity of underlying buffer access.
-       ///
-       float read_float_little(size_t pc) const;
-
-       /// Read a 64-bit double starting at given offset.
-       //
-       /// wacky format: 45670123
-       /// Useful to hide complexity of underlying buffer access.
-       ///
-       double read_double_wacky(size_t pc) const;
-
-       /// Return number of entries in the constant pool
-       size_t dictionary_size() const
-       {
-               return m_dictionary.size();
-       }
-
-       /// Return a value from the constant pool
-       const char* dictionary_get(size_t n) const
-       {
-               return m_dictionary[n];
-       }
-
-       /// \brief
-       /// Interpret the SWF::ACTION_CONSTANTPOOL opcode. 
-       //
-       /// Don't read stop_pc or later. 
-       ///
-       /// A dictionary is some static strings embedded in the
-       /// action buffer; there should only be one dictionary per
-       /// action buffer.
-       ///
-       /// NOTE: Normally the dictionary is declared as the first
-       /// action in an action buffer, but I've seen what looks like
-       /// some form of copy protection that amounts to:
-       ///
-       /// <start of action buffer>
-       ///          push true
-       ///          branch_if_true label
-       ///          decl_dict   [0]   // this is never executed, but has lots 
of orphan data declared in the opcode
-       /// label:   // (embedded inside the previous opcode; looks like an 
invalid jump)
-       ///          ... "protected" code here, including the real decl_dict 
opcode ...
-       ///          <end of the dummy decl_dict [0] opcode>
-       ///
-       /// So we just interpret the first decl_dict we come to, and
-       /// cache the results.  If we ever hit a different decl_dict in
-       /// the same action_buffer, then we log an error and ignore it.
-       ///
-       void process_decl_dict(size_t start_pc, size_t stop_pc) const;
-
-private:
-
-       // Don't put these as values in std::vector<>!  They contain
-       // internal pointers and cannot be moved or copied.
-       // If you need to keep an array of them, keep pointers
-       // to new'd instances.
-       action_buffer(const action_buffer& /*a*/) { assert(0); }
-
-       /// the code itself, as read from the SWF
-       std::vector<uint8_t> m_buffer;
-
-       /// The dictionary
-       mutable std::vector<const char*> m_dictionary;
-
-       /// FIXME: move to ActionExec
-       mutable int m_decl_dict_processed_at;
-
-#if 0
-       void doActionNew(as_environment* env, 
-               std::vector<with_stack_entry>& with_stack);
-
-       void doActionInstanceOf(as_environment* env);
-
-       void doActionCast(as_environment* env);
-
-       void doActionCallMethod(as_environment* env);
-
-       void doActionCallFunction(as_environment* env,
-               std::vector<with_stack_entry>& with_stack);
-
-       void doActionDefineFunction(as_environment* env,
-               std::vector<with_stack_entry>& with_stack,
-               size_t pc, size_t* next_pc);
-
-       void doActionDefineFunction2(as_environment* env,
-               std::vector<with_stack_entry>& with_stack,
-               size_t pc, size_t* next_pc);
-
-       void doActionGetMember(as_environment* env);
-
-       void doActionStrictEquals(as_environment* env);
-
-       void doActionEquals(as_environment* env);
-
-       void doActionDelete(as_environment* env,
-               std::vector<with_stack_entry>& with_stack);
-
-       void doActionDelete2(as_environment* env,
-               std::vector<with_stack_entry>& with_stack);
-#endif
-
-};
-
-
-}      // end namespace gnash
-
-
-#endif // GNASH_ACTION_BUFFER_H
-
-
-// Local Variables:
-// mode: C++
-// indent-tabs-mode: t
-// End:

Index: server/bitmap_character_def.h
===================================================================
RCS file: server/bitmap_character_def.h
diff -N server/bitmap_character_def.h
--- server/bitmap_character_def.h       7 May 2006 19:40:43 -0000       1.1
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,114 +0,0 @@
-// 
-//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
-// 
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-// 
-// This program 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 General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-// Linking Gnash statically or dynamically with other modules is making a
-// combined work based on Gnash. Thus, the terms and conditions of the GNU
-// General Public License cover the whole combination.
-//
-// As a special exception, the copyright holders of Gnash give you
-// permission to combine Gnash with free software programs or libraries
-// that are released under the GNU LGPL and with code included in any
-// release of Talkback distributed by the Mozilla Foundation. You may
-// copy and distribute such a system following the terms of the GNU GPL
-// for all but the LGPL-covered parts and Talkback, and following the
-// LGPL for the LGPL-covered parts.
-//
-// Note that people who make modified versions of Gnash are not obligated
-// to grant this special exception for their modified versions; it is their
-// choice whether to do so. The GNU General Public License gives permission
-// to release a modified version without this exception; this exception
-// also makes it possible to release a modified version which carries
-// forward this exception.
-// 
-//
-//
-
-#ifndef GNASH_BITMAP_CHARACTER_DEF_H
-#define GNASH_BITMAP_CHARACTER_DEF_H
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "gnash.h" // for bitmap_info definition
-#include "character_def.h" // for character_def inheritance
-#include "action.h"
-#include "types.h"
-#include "log.h"
-#include "container.h"
-#include "utility.h"
-#include "smart_ptr.h"
-//#include "movie_interface.h"
-#include <stdarg.h>
-
-#include <cassert>
-
-namespace gnash {
-
-/// What's this ? An interface ?
-struct bitmap_character_def : public character_def
-{
-    virtual gnash::bitmap_info*        get_bitmap_info() = 0;
-};
-
-#if 1
-/// Bitmap character
-struct bitmap_character : public bitmap_character_def
-{
-    bitmap_character(bitmap_info* bi)
-       :
-       m_bitmap_info(bi)
-       {
-       }
-
-//             bitmap_character(image::rgb* image)
-//             {
-//                     assert(image != 0);
-
-//                     // Create our bitmap info, from our image.
-//                     m_bitmap_info = 
gnash::render::create_bitmap_info_rgb(image);
-//             }
-
-//             bitmap_character(image::rgba* image)
-//             {
-//                     assert(image != 0);
-
-//                     // Create our bitmap info, from our image.
-//                     m_bitmap_info = 
gnash::render::create_bitmap_info_rgba(image);
-//             }
-
-    gnash::bitmap_info*        get_bitmap_info()
-       {
-           return m_bitmap_info.get_ptr();
-       }
-
-private:
-    smart_ptr<gnash::bitmap_info>      m_bitmap_info;
-};
-
-#endif
-
-
-}      // end namespace gnash
-
-
-#endif // GNASH_BITMAP_CHARACTER_DEF_H
-
-
-// Local Variables:
-// mode: C++
-// indent-tabs-mode: t
-// End:

Index: server/character_def.cpp
===================================================================
RCS file: server/character_def.cpp
diff -N server/character_def.cpp
--- server/character_def.cpp    1 Jul 2006 20:44:10 -0000       1.3
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,60 +0,0 @@
-// 
-//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
-// 
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-// 
-// This program 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 General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-// Linking Gnash statically or dynamically with other modules is making a
-// combined work based on Gnash. Thus, the terms and conditions of the GNU
-// General Public License cover the whole combination.
-//
-// As a special exception, the copyright holders of Gnash give you
-// permission to combine Gnash with free software programs or libraries
-// that are released under the GNU LGPL and with code included in any
-// release of Talkback distributed by the Mozilla Foundation. You may
-// copy and distribute such a system following the terms of the GNU GPL
-// for all but the LGPL-covered parts and Talkback, and following the
-// LGPL for the LGPL-covered parts.
-//
-// Note that people who make modified versions of Gnash are not obligated
-// to grant this special exception for their modified versions; it is their
-// choice whether to do so. The GNU General Public License gives permission
-// to release a modified version without this exception; this exception
-// also makes it possible to release a modified version which carries
-// forward this exception.
-// 
-//
-//
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <character_def.h>
-#include <generic_character.h>
-
-namespace gnash
-{
-
-character*
-character_def::create_character_instance(character* parent, int id)
-{
-       return new generic_character(this, parent, id);
-}
-
-}
-
-// Local Variables:
-// mode: C++
-// indent-tabs-mode: t
-// End:

Index: server/character_def.h
===================================================================
RCS file: server/character_def.h
diff -N server/character_def.h
--- server/character_def.h      27 Jul 2006 01:47:11 -0000      1.8
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,132 +0,0 @@
-// 
-//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
-// 
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-// 
-// This program 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 General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-// Linking Gnash statically or dynamically with other modules is making a
-// combined work based on Gnash. Thus, the terms and conditions of the GNU
-// General Public License cover the whole combination.
-//
-// As a special exception, the copyright holders of Gnash give you
-// permission to combine Gnash with free software programs or libraries
-// that are released under the GNU LGPL and with code included in any
-// release of Talkback distributed by the Mozilla Foundation. You may
-// copy and distribute such a system following the terms of the GNU GPL
-// for all but the LGPL-covered parts and Talkback, and following the
-// LGPL for the LGPL-covered parts.
-//
-// Note that people who make modified versions of Gnash are not obligated
-// to grant this special exception for their modified versions; it is their
-// choice whether to do so. The GNU General Public License gives permission
-// to release a modified version without this exception; this exception
-// also makes it possible to release a modified version which carries
-// forward this exception.
-// 
-//
-
-#ifndef GNASH_CHARACTER_DEF_H
-#define GNASH_CHARACTER_DEF_H
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "resource.h" // for inheritance from resource class
-
-// Forward declarations
-class tu_file;
-namespace gnash {
-       class character;
-       struct cache_options;
-       //class sprite_instance;
-}
-
-namespace gnash {
-
-/// Immutable data representing the template of a movie element.
-//
-/// This is not really a public interface.  It's here so it
-/// can be mixed into movie_definition and sprite_definition,
-/// without using multiple inheritance.
-///
-struct character_def : public resource
-{
-private:
-       int     m_id;
-       
-public:
-       character_def()
-               :
-               m_id(-1)
-               {
-               }
-       
-       virtual ~character_def() {}
-       
-       virtual void display(character* /*instance_info*/)
-       {
-       }
-
-       virtual bool point_test_local(float /*x*/, float /*y*/)
-       {
-               return false;
-       }
-
-       virtual float get_height_local()
-       {
-               return 0.0f;
-       }
-
-       virtual float get_width_local()
-       {
-               return 0.0f;
-       }
-       
-       /// Should stick the result in a smart_ptr immediately.
-       //
-       /// default is to make a generic_character
-       ///
-       virtual character* create_character_instance(character* parent,
-                       int id);
-       
-       // From resource interface.
-       virtual character_def*  cast_to_character_def()
-       {
-               return this;
-       }
-       
-       //
-       // Caching.
-       //
-       
-       virtual void output_cached_data(tu_file* /*out*/,
-                       const cache_options& /*options*/)
-       {
-       }
-
-       virtual void    input_cached_data(tu_file* /*in*/)
-       {
-       }
-};
-
-
-}      // namespace gnash
-
-#endif // GNASH_CHARACTER_DEF_H
-
-
-// Local Variables:
-// mode: C++
-// indent-tabs-mode: t
-// End:

Index: server/edit_text_character_def.cpp
===================================================================
RCS file: server/edit_text_character_def.cpp
diff -N server/edit_text_character_def.cpp
--- server/edit_text_character_def.cpp  13 Aug 2006 16:45:11 -0000      1.9
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,137 +0,0 @@
-// text.cpp    -- Thatcher Ulrich <address@hidden> 2003
-
-// This source code has been donated to the Public Domain.  Do
-// whatever you want with it.
-
-// Code for the text tags.
-
-
-#include "stream.h"
-#include "log.h"
-#include "movie_definition.h" // for m_root_def use
-
-#include "edit_text_character_def.h"
-#include "edit_text_character.h"
-
-namespace gnash {
-
-// Forward declarations
-struct movie_definition;
-
-void
-edit_text_character_def::read(stream* in, int tag_type,
-               movie_definition* m)
-{
-       assert(m != NULL);
-       assert(tag_type == SWF::DEFINEEDITTEXT); // 37
-
-       m_rect.read(in);
-
-       in->align();
-       bool    has_text = in->read_uint(1) ? true : false;
-       m_word_wrap = in->read_uint(1) ? true : false;
-       m_multiline = in->read_uint(1) ? true : false;
-       m_password = in->read_uint(1) ? true : false;
-       m_readonly = in->read_uint(1) ? true : false;
-       bool    has_color = in->read_uint(1) ? true : false;
-       bool    has_max_length = in->read_uint(1) ? true : false;
-       bool    has_font = in->read_uint(1) ? true : false;
-
-       in->read_uint(1);       // reserved
-       m_auto_size = in->read_uint(1) ? true : false;
-       bool    has_layout = in->read_uint(1) ? true : false;
-       m_no_select = in->read_uint(1) ? true : false;
-       m_border = in->read_uint(1) ? true : false;
-       in->read_uint(1);       // reserved
-       m_html = in->read_uint(1) ? true : false;
-       m_use_outlines = in->read_uint(1) ? true : false;
-
-       if (has_font)
-       {
-               m_font_id = in->read_u16();
-               m_text_height = in->read_u16();
-       }
-
-       if (has_color)
-       {
-               m_color.read_rgba(in);
-       }
-
-       if (has_max_length)
-       {
-               m_max_length = in->read_u16();
-       }
-
-       if (has_layout)
-       {
-               m_alignment = (alignment) in->read_u8();
-               //m_left_margin = (float) in->read_u16();
-               m_left_margin = in->read_u16();
-               //m_right_margin = (float) in->read_u16();
-               m_right_margin = in->read_u16();
-               m_indent = in->read_s16();
-               m_leading = in->read_s16();
-       }
-
-       char*   name = in->read_string();
-       m_default_name = name;
-       delete [] name;
-
-       if (has_text)
-       {
-               char*   str = in->read_string();
-               m_default_text = str;
-               delete [] str;
-       }
-
-       IF_VERBOSE_PARSE (
-               log_parse("edit_text_char:\n"
-                       " default varname = %s\n"
-                       " text = ``%s''\n"
-                       " font_id: %d\n"
-                       " text_height: %d",
-                       m_default_name.c_str(),
-                       m_default_text.c_str(),
-                       m_font_id,
-                       m_text_height);
-       );
-}
-
-const font*
-edit_text_character_def::get_font() 
-{
-       if (m_font == NULL)
-       {
-               // Resolve the font, if possible.
-               m_font = m_root_def->get_font(m_font_id);
-               if (m_font == NULL)
-               {
-                       log_error("error: text style with undefined font; 
font_id = %d\n", m_font_id);
-               }
-       }
-
-       return m_font;
-}
-
-character*
-edit_text_character_def::create_character_instance(character* parent,
-               int id)
-{
-       // Resolve the font, if possible
-       get_font();
-       edit_text_character* ch = new edit_text_character(parent, this, id);
-
-       ch->set_name(m_default_name.c_str());
-
-       return ch;
-}
-
-
-} // namespace gnash
-
-
-// Local Variables:
-// mode: C++
-// indent-tabs-mode: t
-// End:
-

Index: server/edit_text_character_def.h
===================================================================
RCS file: server/edit_text_character_def.h
diff -N server/edit_text_character_def.h
--- server/edit_text_character_def.h    10 Jul 2006 13:47:12 -0000      1.8
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,308 +0,0 @@
-// 
-//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
-// 
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-// 
-// This program 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 General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-// Linking Gnash statically or dynamically with other modules is making a
-// combined work based on Gnash. Thus, the terms and conditions of the GNU
-// General Public License cover the whole combination.
-//
-// As a special exception, the copyright holders of Gnash give you
-// permission to combine Gnash with free software programs or libraries
-// that are released under the GNU LGPL and with code included in any
-// release of Talkback distributed by the Mozilla Foundation. You may
-// copy and distribute such a system following the terms of the GNU GPL
-// for all but the LGPL-covered parts and Talkback, and following the
-// LGPL for the LGPL-covered parts.
-//
-// Note that people who make modified versions of Gnash are not obligated
-// to grant this special exception for their modified versions; it is their
-// choice whether to do so. The GNU General Public License gives permission
-// to release a modified version without this exception; this exception
-// also makes it possible to release a modified version which carries
-// forward this exception.
-// 
-//
-
-
-#ifndef _GNASH_EDIT_TEXT_CHARACTER_DEF_H_
-#define _GNASH_EDIT_TEXT_CHARACTER_DEF_H_
-
-#include "character_def.h" // for inheritance
-#include "gnash.h" // for composition (struct rect)
-#include "textformat.h" // for composition
-
-namespace gnash {
-
-// Forward declarations
-struct movie_definition;
-
-/// \brief
-/// A definition for a text display character, whose text can
-/// be changed at runtime (by script or host).
-/// This object is defined by SWF tag 37 (SWF::DEFINEEDITTEXT)
-///
-class edit_text_character_def : public character_def
-{
-
-public:
-
-       /// Text alignment values
-       enum alignment
-       {
-               ALIGN_LEFT = 0,
-               ALIGN_RIGHT,
-               ALIGN_CENTER,
-               /// probably don't need to implement...
-               ALIGN_JUSTIFY
-       };
-
-       edit_text_character_def(movie_definition* root_def)
-               :
-               m_root_def(root_def),
-               m_format(),
-               m_word_wrap(false),
-               m_multiline(false),
-               m_password(false),
-               m_readonly(false),
-               m_auto_size(false),
-               m_no_select(false),
-               m_border(false),
-               m_html(false),
-               m_use_outlines(false),
-               m_font_id(-1),
-               m_font(NULL),
-               m_text_height(1),
-               m_max_length(0),
-               m_alignment(ALIGN_LEFT),
-               m_left_margin(0),
-               m_right_margin(0),
-               m_indent(0),
-               m_leading(0)
-       {
-               assert(m_root_def);
-
-               m_color.set(0, 0, 0, 255);
-       }
-
-       /// Set the format of the text
-       void    set_format(text_format &format)
-       {
-               m_format = format;
-       }
-       
-       ~edit_text_character_def()
-       {
-       }
-
-       /// Get width of this definition (by definition)
-       float width() const { return m_rect.width(); }
-
-       /// Get height of this definition (by definition)
-       float height() const { return m_rect.height(); }
-
-       /// Create an instance of this character
-       character* create_character_instance(character* parent, int id);
-
-       /// Initialize from SWF input stream (tag 37)
-       void read(stream* in, int tag_type, movie_definition* m);
-
-       /// Return a reference to the default text associated
-       /// with this EditText definition.
-       const tu_string& get_default_text() const {
-               return m_default_text;
-       }
-
-       /// Return a reference to the default name for
-       /// instances of this EditText definition. (?)
-       const tu_string& get_default_name() const {
-               return m_default_name;
-       }
-
-       /// \brief
-       /// Return the maximum length of text this widget
-       /// can hold.
-       int get_max_length() const {
-               return m_max_length;
-       }
-
-       /// Get boundaries of this movie
-       //
-       /// Return a reference to private space, copy
-       /// it if you need it  for longer then this
-       /// object's lifetime.
-       ///
-       const rect& get_bounds() const {
-               return m_rect;
-       }
-
-       /// Get right margin in twips
-       uint16_t get_right_margin() const {
-               return m_right_margin;
-       }
-
-       /// Get left margin in twips
-       uint16_t get_left_margin() const {
-               return m_left_margin;
-       }
-
-       /// Get indentation in  twips
-       uint16_t get_indent() const {
-               return m_indent;
-       }
-
-       /// Get height of font  in twips.
-       // @@ what if has_font is false ??
-       uint16_t get_font_height() const {
-               return m_text_height;
-       }
-
-       /// Get font.
-       //
-       /// Note: use add_ref() on the return if you need to keep
-       /// it alive after this definition gets destructed.
-       ///
-       const font* get_font();
-
-       /// Get color of the text
-       const rgba& get_text_color() const {
-               return m_color;
-       }
-
-       /// \brief
-       /// Get extra space between lines (in twips).
-       //
-       /// This is in addition to default font line spacing.
-       uint16_t get_leading() const {
-               return m_leading;
-       }
-
-       /// Get text alignment
-       alignment get_alignment() const {
-               return m_alignment;
-       }
-
-       /// Is border requested ?
-       bool has_border() const {
-               return m_border;
-       }
-
-       /// Word wrap requested ?
-       bool do_word_wrap() const {
-               return m_word_wrap;
-       }
-
-       /// Get root movie definition
-       movie_definition* get_root_def() {
-               return m_root_def;
-       }
-
-       bool get_readonly() const
-       {
-               return m_readonly;
-       }
-
-private:
-
-       /// Root movie_definition
-       movie_definition*       m_root_def;
-
-       rect                    m_rect;
-       tu_string               m_default_name;
-       text_format             m_format;
-       bool                    m_word_wrap;
-       bool                    m_multiline;
-       /// show asterisks instead of actual characters
-       bool                    m_password;
-       bool                    m_readonly;
-       /// resize our bound to fit the text
-       bool                    m_auto_size;
-       bool                    m_no_select;
-
-       /// forces white background and black border.
-       /// silly, but sometimes used
-       bool                    m_border;
-
-       /// Allowed HTML (from Alexi's SWF Reference).
-       //
-       /// <a href=url target=targ>...</a> -- hyperlink
-       /// <b>...</b> -- bold
-       /// <br> -- line break
-       /// <font face=name size=[+|-][0-9]+ color=#RRGGBB>...</font>  -- font 
change; size in TWIPS
-       /// <i>...</i> -- italic
-       /// <li>...</li> -- list item
-       /// <p>...</p> -- paragraph
-       /// <tab> -- insert tab
-       /// <TEXTFORMAT>  </TEXTFORMAT>
-       ///   [ BLOCKINDENT=[0-9]+ ]
-       ///   [ INDENT=[0-9]+ ]
-       ///   [ LEADING=[0-9]+ ]
-       ///   [ LEFTMARGIN=[0-9]+ ]
-       ///   [ RIGHTMARGIN=[0-9]+ ]
-       ///   [ TABSTOPS=[0-9]+{,[0-9]+} ]
-       ///
-       /// Change the different parameters as indicated. The
-       /// sizes are all in TWIPs. There can be multiple
-       /// positions for the tab stops. These are seperated by
-       /// commas.
-       /// <U>...</U> -- underline
-       ///
-       bool                    m_html;
-
-
-
-       /// \brief
-       /// When true, use specified SWF internal font. 
-       /// Otherwise, renderer picks a default font
-       bool    m_use_outlines;
-
-       int     m_font_id;
-       font*   m_font;
-
-       /// height of font text, in twips
-       uint16_t m_text_height;
-
-       /// Text color
-       rgba    m_color;
-
-       /// Maximum length of text this widget can display (number of chars?)
-       int     m_max_length;
-
-       alignment m_alignment;
-       
-       /// extra space between box's left border and text (in twips)
-       uint16_t m_left_margin;
-       //float m_left_margin;
-
-       /// extra space between box's right border and text (in twips)
-       uint16_t m_right_margin;
-       //float m_right_margin;
-
-       /// how much to indent the first line of multiline text (in twips)
-       uint16_t        m_indent;
-       //float m_indent;
-
-       /// \brief
-       /// Extra space between lines
-       /// (in addition to default font line spacing)
-       uint16_t        m_leading;
-
-       /// The default text to be displayed
-       tu_string       m_default_text;
-
-};
-
-} // namespace gnash
-
-#endif // _GNASH_EDIT_TEXT_CHARACTER_DEF_H_

Index: server/movie_def_impl.cpp
===================================================================
RCS file: server/movie_def_impl.cpp
diff -N server/movie_def_impl.cpp
--- server/movie_def_impl.cpp   23 Aug 2006 22:22:56 -0000      1.35
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,1024 +0,0 @@
-// 
-//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
-// 
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-// 
-// This program 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 General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-// Linking Gnash statically or dynamically with other modules is making a
-// combined work based on Gnash. Thus, the terms and conditions of the GNU
-// General Public License cover the whole combination.
-//
-// As a special exception, the copyright holders of Gnash give you
-// permission to combine Gnash with free software programs or libraries
-// that are released under the GNU LGPL and with code included in any
-// release of Talkback distributed by the Mozilla Foundation. You may
-// copy and distribute such a system following the terms of the GNU GPL
-// for all but the LGPL-covered parts and Talkback, and following the
-// LGPL for the LGPL-covered parts.
-//
-// Note that people who make modified versions of Gnash are not obligated
-// to grant this special exception for their modified versions; it is their
-// choice whether to do so. The GNU General Public License gives permission
-// to release a modified version without this exception; this exception
-// also makes it possible to release a modified version which carries
-// forward this exception.
-// 
-//
-#ifdef HAVE_PTHREADS
-#include <pthread.h>
-#endif
-
-#include <iostream>
-#include <string>
-
-#include "movie_def_impl.h"
-#include "movie_definition.h" // for inheritance
-#include "movie_instance.h"
-#include "tu_file.h"
-#include "zlib_adapter.h"
-#include "stream.h"
-#include "jpeg.h"
-#include "fontlib.h"
-#include "font.h"
-#include "log.h"
-//#include "Sprite.h"
-#include "sprite_instance.h"
-#include "render.h"
-#include "bitmap_character_def.h"
-#include "smart_ptr.h"
-#include "swf/TagLoadersTable.h"
-#include "execute_tag.h"
-#include "movie_root.h"
-
-using namespace std;
-
-// Increment this when the cache data format changes.
-#define CACHE_FILE_VERSION 4
-
-// If != 0 this is the number of frames to load at each iteration
-// of the main loop. Loading in chunks greatly speeds the process up
-#define FRAMELOAD_CHUNK 0
-
-// Debug frames load
-#undef DEBUG_FRAMES_LOAD 
-
-// Define this this to load movies using a separate thread
-// (undef and it will fully load a movie before starting to play it)
-#define LOAD_MOVIES_IN_A_SEPARATE_THREAD 1
-
-// Debug threads locking
-#undef DEBUG_THREADS_LOCKING
-
-namespace gnash
-{
-
-#ifdef USE_SDL_THREADS
-
-MovieLoader::MovieLoader(movie_def_impl& md)
-       :
-       _waiting_for_frame(0),
-       _movie_def(md)
-{
-       _frame_reached_condition = SDL_CreateCond();
-       _mutex = SDL_CreateMutex();
-}
-
-MovieLoader::~MovieLoader()
-{
-       SDL_DestroyMutex(_mutex);
-       SDL_DestroyCond(_frame_reached_condition);
-}
-
-int MovieLoader::execute(void* arg)
-{
-       movie_def_impl* md = static_cast<movie_def_impl*>(arg);
-       md->read_all_swf();
-       return 0;
-}
-
-bool MovieLoader::start()
-{
-        _thread = SDL_CreateThread(execute, &_movie_def);
-        if (_thread == NULL)
-        {
-                return false;
-        }
-       return true;
-}
-
-void MovieLoader::signal_frame_loaded(size_t frameno)
-{
-       if (_waiting_for_frame &&
-               frameno >= _waiting_for_frame )
-       {
-               SDL_CondSignal(_frame_reached_condition);
-       }
-}
-
-void MovieLoader::wait_for_frame(size_t framenum)
-{
-
-       lock();
-
-       if (_movie_def.get_loading_frame() < framenum)
-       {
-               //log_msg("Waiting for frame %u to load", framenum);
-
-               assert(_waiting_for_frame == 0);
-               _waiting_for_frame = framenum;
-
-               do
-               {
-                       SDL_CondWait(_frame_reached_condition, _mutex);
-               }
-               while (_movie_def.get_loading_frame() < framenum);
-
-               _waiting_for_frame = 0;
-
-               //log_msg("Done waiting (frame %u/%u loaded)",
-               //      _movie_def.get_loading_frame(),
-               //      _movie_def.get_frame_count());
-       }
-
-       unlock();
-}
-
-void MovieLoader::lock()
-{
-       if ( -1 == SDL_mutexP(_mutex) )
-       {
-               log_error("Error unlocking MovieLoader");
-       }
-}
-
-void MovieLoader::unlock()
-{
-       if ( -1 == SDL_mutexV(_mutex) )
-       {
-               log_error("Error unlocking MovieLoader");
-       }
-}
-
-#else
-
-MovieLoader::MovieLoader(movie_def_impl& md)
-       :
-       _waiting_for_frame(0),
-       _movie_def(md)
-{
-       pthread_cond_init(&_frame_reached_condition, NULL);
-       pthread_mutex_init(&_mutex, NULL);
-}
-
-MovieLoader::~MovieLoader()
-{
-       if ( pthread_cond_destroy(&_frame_reached_condition) != 0 )
-       {
-               log_error("Error destroying MovieLoader condition");
-       }
-
-       if ( pthread_mutex_destroy(&_mutex) != 0 )
-       {
-               log_error("Error destroying MovieLoader mutex");
-       }
-}
-
-void*
-MovieLoader::execute(void* arg)
-{
-       movie_def_impl* md = static_cast<movie_def_impl*>(arg);
-       md->read_all_swf();
-       // maybe this frees all resources and that's bad !
-       //pthread_exit(NULL);
-       
-       /* Better to cancel yourself methinks: 'man 3p pthread_cancel' */
-       pthread_cancel(pthread_self());
-        pthread_testcancel();
-       return NULL;
-}
-
-bool
-MovieLoader::start()
-{
-       if ( pthread_create(&_thread, NULL, execute, &_movie_def) )
-       {
-               return false;
-       }
-
-       // should set some mutexes ?
-
-       return true;
-}
-
-void
-MovieLoader::signal_frame_loaded(size_t frameno)
-{
-       if (_waiting_for_frame &&
-               frameno >= _waiting_for_frame )
-       {
-               pthread_cond_signal(&_frame_reached_condition);
-       }
-}
-
-void
-MovieLoader::lock()
-{
-
-#ifdef DEBUG_THREADS_LOCKING
-       // debugging
-       if ( pthread_equal(pthread_self(), _thread) ) {
-               log_msg("MovieLoader locking itself");
-       } else {
-               log_msg("MovieLoader being locked by another thread");
-       }
-#endif
-
-       if ( pthread_mutex_lock(&_mutex) != 0 )
-       {
-               log_error("Error locking MovieLoader");
-       }
-
-#ifdef DEBUG_THREADS_LOCKING
-       // debugging
-       if ( pthread_equal(pthread_self(), _thread) ) {
-               log_msg("MovieLoader locked by itself");
-       } else {
-               log_msg("MovieLoader locked by another thread");
-       }
-#endif
-}
-
-void
-MovieLoader::unlock()
-{
-
-#ifdef DEBUG_THREADS_LOCKING
-       // debugging
-       if ( pthread_equal(pthread_self(), _thread) ) {
-               log_msg("MovieLoader unlocking itself");
-       } else {
-               log_msg("MovieLoader being unlocked by another thread");
-       }
-#endif
-
-       if ( pthread_mutex_unlock(&_mutex) != 0 )
-       {
-               log_error("Error unlocking MovieLoader");
-       }
-
-#ifdef DEBUG_THREADS_LOCKING
-       // debugging
-       if ( pthread_equal(pthread_self(), _thread) ) {
-               log_msg("MovieLoader unlocked itself");
-       } else {
-               log_msg("MovieLoader unlocked by another thread");
-       }
-#endif
-}
-
-void
-MovieLoader::wait_for_frame(size_t framenum)
-{
-
-       // lock the loader so we can rely on m_loading_frame
-       lock();
-
-       if ( _movie_def.get_loading_frame() < framenum )
-       {
-               assert(_waiting_for_frame == 0);
-               _waiting_for_frame = framenum;
-               pthread_cond_wait(&_frame_reached_condition, &_mutex);
-               _waiting_for_frame = 0;
-       }
-
-       unlock();
-}
-
-#endif // PTHREAD MovieLoader
-
-
-//
-// some utility stuff
-//
-
-void   dump_tag_bytes(stream* in)
-    // Log the contents of the current tag, in hex.
-{
-    static const int   ROW_BYTES = 16;
-    char       row_buf[ROW_BYTES];
-    int        row_count = 0;
-
-    while(in->get_position() < in->get_tag_end_position())
-        {
-            int        c = in->read_u8();
-            log_msg("%02X", c);
-
-            if (c < 32) c = '.';
-            if (c > 127) c = '.';
-            row_buf[row_count] = c;
-                               
-            row_count++;
-            if (row_count >= ROW_BYTES)
-                {
-                    log_msg("    ");
-                    for (int i = 0; i < ROW_BYTES; i++)
-                        {
-                            log_msg("%c", row_buf[i]);
-                        }
-
-                    log_msg("\n");
-                    row_count = 0;
-                }
-            else
-                {
-                    log_msg(" ");
-                }
-        }
-
-    if (row_count > 0)
-        {
-            log_msg("\n");
-        }
-}
-
-
-//
-// progress callback stuff (from Vitaly)
-//
-progress_callback      s_progress_function = NULL;
-
-// Host calls this to register a function for progress bar handling
-// during loading movies.
-void
-register_progress_callback(progress_callback progress_handle)
-{
-    s_progress_function = progress_handle;
-}
-
-//
-// movie_def_impl
-//
-
-movie_def_impl::movie_def_impl(create_bitmaps_flag cbf,
-               create_font_shapes_flag cfs)
-       :
-       _tag_loaders(s_tag_loaders), // FIXME: use a class-static 
TagLoadersTable for movie_def_impl
-       m_create_bitmaps(cbf),
-       m_create_font_shapes(cfs),
-       m_frame_rate(30.0f),
-       m_frame_count(0u),
-       m_version(0),
-       m_loading_frame(0u),
-       _loaded_bytes(0u),
-       m_jpeg_in(0),
-       _loader(*this)
-{
-}
-
-movie_def_impl::~movie_def_impl()
-{
-    // Release our playlist data.
-    {for (int i = 0, n = m_playlist.size(); i < n; i++)
-        {
-            for (int j = 0, m = m_playlist[i].size(); j < m; j++)
-                {
-                    delete m_playlist[i][j];
-                }
-        }}
-
-    // Release init action data.
-    {for (size_t i = 0, n = m_init_action_list.size(); i < n; i++)
-        {
-            for (size_t j = 0, m = m_init_action_list[i].size(); j < m; j++)
-                {
-                    delete m_init_action_list[i][j];
-                }
-        }}
-
-       // It's supposed to be cleaned up in read()
-       // TODO: join with loader thread instead ?
-       //assert(m_jpeg_in.get() == NULL);
-}
-
-bool movie_def_impl::in_import_table(int character_id)
-{
-    for (int i = 0, n = m_imports.size(); i < n; i++)
-        {
-            if (m_imports[i].m_character_id == character_id)
-                {
-                    return true;
-                }
-        }
-    return false;
-}
-
-void movie_def_impl::visit_imported_movies(import_visitor* visitor)
-{
-    stringi_hash<bool> visited;        // ugh!
-
-    for (int i = 0, n = m_imports.size(); i < n; i++)
-        {
-            const import_info& inf = m_imports[i];
-            if (visited.find(inf.m_source_url) == visited.end())
-                {
-                    // Call back the visitor.
-                    visitor->visit(inf.m_source_url.c_str());
-                    visited[inf.m_source_url] = true;
-                }
-        }
-}
-
-void movie_def_impl::resolve_import(const char* source_url, movie_definition* 
source_movie)
-{
-    // @@ should be safe, but how can we verify
-    // it?  Compare a member function pointer, or
-    // something?
-    movie_def_impl*    def_impl = static_cast<movie_def_impl*>(source_movie);
-    movie_definition*  def = static_cast<movie_definition*>(def_impl);
-
-    // Iterate in reverse, since we remove stuff along the way.
-    for (int i = m_imports.size() - 1; i >= 0; i--)
-        {
-            const import_info& inf = m_imports[i];
-            if (inf.m_source_url == source_url)
-                {
-                    // Do the import.
-                    smart_ptr<resource> res = 
def->get_exported_resource(inf.m_symbol);
-                    bool        imported = true;
-
-                    if (res == NULL)
-                        {
-                            log_error("import error: resource '%s' is not 
exported from movie '%s'\n",
-                                      inf.m_symbol.c_str(), source_url);
-                        }
-                    else if (font* f = res->cast_to_font())
-                        {
-                            // Add this shared font to our fonts.
-                            add_font(inf.m_character_id, f);
-                            imported = true;
-                        }
-                    else if (character_def* ch = res->cast_to_character_def())
-                        {
-                            // Add this character to our characters.
-                            add_character(inf.m_character_id, ch);
-                            imported = true;
-                        }
-                    else
-                        {
-                            log_error("import error: resource '%s' from movie 
'%s' has unknown type\n",
-                                      inf.m_symbol.c_str(), source_url);
-                        }
-
-                    if (imported)
-                        {
-                            m_imports.erase(m_imports.begin() + i);
-
-                            // Hold a ref, to keep this source 
movie_definition alive.
-                            m_import_source_movies.push_back(source_movie);
-                        }
-                }
-        }
-}
-
-void movie_def_impl::add_character(int character_id, character_def* c)
-{
-       assert(c);
-       _dictionary.add_character(character_id, c);
-}
-
-character_def*
-movie_def_impl::get_character_def(int character_id)
-{
-#ifndef NDEBUG
-    // make sure character_id is resolved
-    if (in_import_table(character_id))
-        {
-            log_error("get_character_def(): character_id %d is still waiting 
to be imported\n",
-                      character_id);
-        }
-#endif // not NDEBUG
-
-       smart_ptr<character_def> ch = _dictionary.get_character(character_id);
-       assert(ch == NULL || ch->get_ref_count() > 1);
-       return ch.get_ptr(); // mm... why don't we return the smart_ptr?
-}
-
-void movie_def_impl::add_font(int font_id, font* f)
-{
-    assert(f);
-    m_fonts.add(font_id, f);
-}
-
-font* movie_def_impl::get_font(int font_id)
-{
-#ifndef NDEBUG
-    // make sure font_id is resolved
-    if (in_import_table(font_id))
-        {
-            log_error("get_font(): font_id %d is still waiting to be 
imported\n",
-                      font_id);
-        }
-#endif // not NDEBUG
-
-    smart_ptr<font>    f;
-    m_fonts.get(font_id, &f);
-    assert(f == NULL || f->get_ref_count() > 1);
-    return f.get_ptr();
-}
-
-bitmap_character_def* movie_def_impl::get_bitmap_character(int character_id)
-{
-    smart_ptr<bitmap_character_def>    ch;
-    m_bitmap_characters.get(character_id, &ch);
-    assert(ch == NULL || ch->get_ref_count() > 1);
-    return ch.get_ptr();
-}
-
-void movie_def_impl::add_bitmap_character(int character_id, 
bitmap_character_def* ch)
-{
-    assert(ch);
-    //log_msg("Add bitmap character %d", character_id);
-    m_bitmap_characters.add(character_id, ch);
-
-    add_bitmap_info(ch->get_bitmap_info());
-}
-
-sound_sample* movie_def_impl::get_sound_sample(int character_id)
-{
-    smart_ptr<sound_sample>    ch;
-    m_sound_samples.get(character_id, &ch);
-    assert(ch == NULL || ch->get_ref_count() > 1);
-    return ch.get_ptr();
-}
-
-void movie_def_impl::add_sound_sample(int character_id, sound_sample* sam)
-{
-    assert(sam);
-       log_msg("Add sound sample %d", character_id);
-    m_sound_samples.add(character_id, sam);
-}
-
-
-// Read a .SWF movie.
-bool
-movie_def_impl::read(tu_file* in, const std::string& url)
-{
-
-       // we only read a movie once (well, headers at least)
-       assert(_str.get() == NULL);
-
-       if ( url == "" ) _url = "<anonymous>";
-       else _url = url;
-
-       uint32_t file_start_pos = in->get_position();
-       uint32_t header = in->read_le32();
-       m_file_length = in->read_le32();
-       _swf_end_pos = file_start_pos + m_file_length;
-
-       m_version = (header >> 24) & 255;
-       if ((header & 0x0FFFFFF) != 0x00535746
-               && (header & 0x0FFFFFF) != 0x00535743)
-        {
-               // ERROR
-               log_error("gnash::movie_def_impl::read() -- "
-                       "file does not start with a SWF header!\n");
-               return false;
-        }
-       bool    compressed = (header & 255) == 'C';
-    
-       IF_VERBOSE_PARSE(
-               log_parse("version = %d, file_length = %d",
-                       m_version, m_file_length);
-       );
-
-       tu_file* original_in = NULL;
-       if (compressed)
-        {
-#if TU_CONFIG_LINK_TO_ZLIB == 0
-               log_error("movie_def_impl::read(): unable to read "
-                       "zipped SWF data; TU_CONFIG_LINK_TO_ZLIB is 0\n");
-               return false;
-#endif
-
-               IF_VERBOSE_PARSE(
-                       log_parse("file is compressed.");
-               );
-
-               original_in = in;
-
-               // Uncompress the input as we read it.
-               _zlib_file.reset(zlib_adapter::make_inflater(original_in));
-               in = _zlib_file.get();
-
-               // Subtract the size of the 8-byte header, since
-               // it's not included in the compressed
-               // stream length.
-               _swf_end_pos = m_file_length - 8;
-        }
-
-       //stream str(in);
-       _str.reset(new stream(in));
-
-       m_frame_size.read(_str.get());
-       m_frame_rate = _str->read_u16() / 256.0f;
-       m_frame_count = _str->read_u16();
-
-       // hack
-       // Vitaly: I am not assured that it correctly
-       m_frame_count = (m_frame_count == 0) ? 1 : m_frame_count;
-
-       m_playlist.resize(m_frame_count);
-       m_init_action_list.resize(m_frame_count);
-
-       IF_VERBOSE_PARSE(
-               m_frame_size.print();
-               log_parse("frame rate = %f, frames = %d",
-                       m_frame_rate, m_frame_count);
-       );
-
-#ifdef LOAD_MOVIES_IN_A_SEPARATE_THREAD
-
-       // Start the loading frame
-       if ( ! _loader.start() )
-       {
-               log_error("Could not start loading thread");
-       }
-
-       // Wait until 'startup_frames' have been loaded
-#if 1
-       size_t startup_frames = 1;
-#else
-       size_t startup_frames = m_frame_count;
-#endif
-       ensure_frame_loaded(startup_frames);
-
-#else // undef LOAD_MOVIES_IN_A_SEPARATE_THREAD
-
-       read_all_swf();
-#endif
-
-// Can't delete here as we will keep reading from it while playing
-// FIXME: remove this at end of reading (or in destructor)
-#if 0
-       if (original_in)
-        {
-            // Done with the zlib_adapter.
-            delete in;
-        }
-#endif
-
-       return true;
-}
-
-
-// 1-based frame number
-bool
-movie_def_impl::ensure_frame_loaded(size_t framenum)
-{
-        //log_msg("Waiting for frame %u to be loaded", framenum);
-       _loader.wait_for_frame(framenum);
-        //log_msg("Condition reached (m_loading_frame=%u)", m_loading_frame);
-
-
-       // TODO: return false on timeout 
-       return true;
-}
-
-
-/* movie_def_impl */
-void movie_def_impl::get_owned_fonts(std::vector<font*>* fonts)
-    // Fill up *fonts with fonts that we own.
-{
-    assert(fonts);
-    fonts->resize(0);
-
-    std::vector<int>   font_ids;
-
-    for (hash<int, smart_ptr<font> >::iterator it = m_fonts.begin();
-         it != m_fonts.end();
-         ++it)
-        {
-            font*      f = it->second.get_ptr();
-            if (f->get_owning_movie() == this)
-                {
-                    // Sort by character id, so the ordering is
-                    // consistent for cache read/write.
-                    int        id = it->first;
-
-                    // Insert in correct place.
-                    unsigned int insert;
-                    for (insert = 0; insert < font_ids.size(); insert++)
-                        {
-                            if (font_ids[insert] > id)
-                                {
-                                    // We want to insert here.
-                                    break;
-                                }
-                        }
-                    fonts->insert(fonts->begin() + insert, f);
-                    font_ids.insert(font_ids.begin() + insert, id);
-                }
-        }
-}
-
-
-/* movie_def_impl */
-void movie_def_impl::generate_font_bitmaps()
-    // Generate bitmaps for our fonts, if necessary.
-{
-    // Collect list of fonts.
-    std::vector<font*> fonts;
-    get_owned_fonts(&fonts);
-    fontlib::generate_font_bitmaps(fonts, this);
-}
-
-void
-movie_def_impl::output_cached_data(tu_file* out, const cache_options& options)
-{
-    // Write a little header.
-    char       header[5];
-    strcpy(header, "gscX");
-    header[3] = CACHE_FILE_VERSION;
-    compiler_assert(CACHE_FILE_VERSION < 256);
-
-    out->write_bytes(header, 4);
-
-    // Write font data.
-    std::vector<font*> fonts;
-    get_owned_fonts(&fonts);
-    fontlib::output_cached_data(out, fonts, this, options);
-
-       // Write character data.
-       {
-
-       for ( CharacterDictionary::iterator
-               it = _dictionary.begin(), itEnd = _dictionary.end();
-               it != itEnd;
-               ++it )
-       {
-               out->write_le16(it->first);
-               it->second->output_cached_data(out, options);
-       }
-                       
-#if 0
-       for (hash<int, smart_ptr<character_def> >::iterator it = 
m_characters.begin();
-          it != m_characters.end();
-          ++it)
-        {
-            out->write_le16(it->first);
-            it->second->output_cached_data(out, options);
-        }
-#endif
-       }
-
-    out->write_le16((int16_t) -1);     // end of characters marker
-}
-
-
-void
-movie_def_impl::input_cached_data(tu_file* in)
-{
-    // Read the header & check version.
-    unsigned char      header[4];
-    in->read_bytes(header, 4);
-    if (header[0] != 'g' || header[1] != 's' || header[2] != 'c')
-        {
-            log_error("cache file does not have the correct format; 
skipping\n");
-            return;
-        }
-    else if (header[3] != CACHE_FILE_VERSION)
-        {
-            log_error(
-                "cached data is version %d, but we require version %d; 
skipping\n",
-                int(header[3]), CACHE_FILE_VERSION);
-            return;
-        }
-
-    // Read the cached font data.
-    std::vector<font*> fonts;
-    get_owned_fonts(&fonts);
-    fontlib::input_cached_data(in, fonts, this);
-
-    // Read the cached character data.
-    for (;;)
-        {
-            if (in->get_error() != TU_FILE_NO_ERROR)
-                {
-                    log_error("error reading cache file (characters); 
skipping\n");
-                    return;
-                }
-            if (in->get_eof())
-                {
-                    log_error("unexpected eof reading cache file (characters); 
skipping\n");
-                    return;
-                }
-
-            int16_t    id = in->read_le16();
-            if (id == (int16_t) -1) { break; } // done
-
-            smart_ptr<character_def> ch = _dictionary.get_character(id);
-            //m_characters.get(id, &ch);
-            if (ch != NULL)
-                {
-                    ch->input_cached_data(in);
-                }
-            else
-                {
-                    log_error("sync error in cache file (reading characters)!  
"
-                              "Skipping rest of cache data.\n");
-                    return;
-                }
-        }
-}
-
-movie_interface*
-movie_def_impl::create_instance()
-{
-    movie_root*        m = new movie_root(this);
-    assert(m);
-
-    sprite_instance* root_movie = new movie_instance(this, m, NULL);
-    assert(root_movie);
-
-    root_movie->set_name("_root");
-    m->set_root_movie(root_movie);
-
-    // @@ somewhere in here I *might* add _url variable
-    // (or is it a member?)
-
-    m->add_ref();
-
-               root_movie->execute_frame_tags(0); // create _root dlist
-
-    return m;
-}
-
-
-//
-// CharacterDictionary
-//
-
-void
-CharacterDictionary::dump_chars() const
-{
-       for ( const_iterator it=begin(), endIt=end();
-               it != endIt; ++it )
-       {
-               log_msg("Character %d @ %p", it->first, it->second.get_ptr());
-               //character_def* cdef = it->second;
-       }
-}
-
-smart_ptr<character_def>
-CharacterDictionary::get_character(int id)
-{
-       container::iterator it = _map.find(id);
-       if ( it == _map.end() )
-       {
-               log_msg("Could not find char %d, dump is:", id);
-               dump_chars();
-               return smart_ptr<character_def>();
-       }
-       else return it->second;
-}
-
-void
-CharacterDictionary::add_character(int id, smart_ptr<character_def> c)
-{
-       //log_msg("CharacterDictionary: add char %d", id);
-       _map[id] = c;
-       //dump_chars();
-}
-
-// Load next chunk of this sprite frames.
-// This is possibly better defined in movie_definition
-void
-movie_def_impl::load_next_frame_chunk()
-{
-
-       size_t framecount = get_frame_count();
-       size_t lastloaded = get_loading_frame();
-
-       // nothing to do
-       if ( lastloaded == framecount ) return;
-
-       size_t nextframe = lastloaded+1;
-
-#if FRAMELOAD_CHUNK
-       nextframe += FRAMELOAD_CHUNK; // load in chunks of 10 frames 
-       if ( nextframe > framecount ) nextframe = framecount;
-#endif
-       //log_msg("Framecount: %u, Lastloaded: %u", framecount, lastloaded);
-       if ( nextframe <= framecount )
-       {
-#ifdef DEBUG_FRAMES_LOAD // debugging
-               log_msg("Ensure load of frame %u/%u (last loaded is: %u)",
-                       nextframe, framecount, lastloaded);
-#endif
-               if ( ! ensure_frame_loaded(nextframe) )
-               {
-                       log_error("Could not advance to frame %d!",
-                               nextframe);
-                       // these kind of errors should be handled by callers
-                       assert(0);
-               }
-       }
-#ifdef DEBUG_FRAMES_LOAD
-       else
-       {
-               log_msg("No more frames to load. Framecount: %u, Lastloaded: 
%u, next to load: %u", framecount, lastloaded, nextframe);
-       }
-#endif
-}
-
-void
-movie_def_impl::read_all_swf()
-{
-       assert(_str.get() != NULL);
-
-       stream& str=*_str;
-
-       //size_t it=0;
-       while ( (uint32_t) str.get_position() < _swf_end_pos )
-       {
-               // Get exclusive lock on loader, to avoid
-               // race conditions with wait_for_frame
-               _loader.lock();
-
-               //log_msg("Loading thread iteration %u", it++);
-
-               SWF::tag_type tag_type = str.open_tag();
-
-               if (s_progress_function != NULL)
-                {
-                       s_progress_function((uint32_t)str.get_position(),
-                               _swf_end_pos);
-                }
-
-               SWF::TagLoadersTable::loader_function lf = NULL;
-               //log_parse("tag_type = %d\n", tag_type);
-               if (tag_type == SWF::SHOWFRAME)
-               {
-                       // show frame tag -- advance to the next frame.
-
-                       IF_VERBOSE_PARSE(
-                               log_parse("  show_frame\n");
-                       );
-
-                       ++m_loading_frame;
-
-                       // signal load of frame
-                       _loader.signal_frame_loaded(m_loading_frame);
-
-#if DEBUG_FRAMES_LOAD
-                       log_msg("Loaded frame %u/%u",
-                               m_loading_frame, m_frame_count);
-#endif
-               }
-               else if (_tag_loaders.get(tag_type, &lf))
-                {
-                       // call the tag loader.  The tag loader should add
-                       // characters or tags to the movie data structure.
-                       (*lf)(&str, tag_type, this);
-               }
-               else
-               {
-                       // no tag loader for this tag type.
-                               log_error("*** no tag loader for type %d 
(movie)",
-                                       tag_type);
-                               dump_tag_bytes(&str);
-               } 
-
-               str.close_tag();
-
-               if (tag_type == SWF::END)
-                {
-                       if ((unsigned int) str.get_position() != _swf_end_pos)
-                        {
-                               // Safety break, so we don't read past
-                               // the end of the  movie.
-                               log_warning("hit stream-end tag, "
-                                       "but not at the advertised SWF end; "
-                                       "stopping for safety.");
-                               _loader.unlock();
-                               break;
-                       }
-               }
-               _loader.unlock();
-
-       }
-
-}
-
-} // namespace gnash
-

Index: server/movie_def_impl.h
===================================================================
RCS file: server/movie_def_impl.h
diff -N server/movie_def_impl.h
--- server/movie_def_impl.h     22 Aug 2006 00:53:54 -0000      1.22
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,570 +0,0 @@
-// 
-//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
-// 
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-// 
-// This program 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 General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-// Linking Gnash statically or dynamically with other modules is making a
-// combined work based on Gnash. Thus, the terms and conditions of the GNU
-// General Public License cover the whole combination.
-//
-// As a special exception, the copyright holders of Gnash give you
-// permission to combine Gnash with free software programs or libraries
-// that are released under the GNU LGPL and with code included in any
-// release of Talkback distributed by the Mozilla Foundation. You may
-// copy and distribute such a system following the terms of the GNU GPL
-// for all but the LGPL-covered parts and Talkback, and following the
-// LGPL for the LGPL-covered parts.
-//
-// Note that people who make modified versions of Gnash are not obligated
-// to grant this special exception for their modified versions; it is their
-// choice whether to do so. The GNU General Public License gives permission
-// to release a modified version without this exception; this exception
-// also makes it possible to release a modified version which carries
-// forward this exception.
-// 
-//
-
-#ifndef GNASH_MOVIE_DEF_IMPL_H
-#define GNASH_MOVIE_DEF_IMPL_H
-
-#include "container.h"
-#include "smart_ptr.h"
-#include "button.h" // for mouse_button_state
-#include "timers.h" // for Timer
-#include "fontlib.h"
-#include "font.h"
-#include "jpeg.h"
-#include "tu_file.h"
-#include "movie_definition.h" // for inheritance
-#include "character_def.h" // for smart_ptr visibility of dtor
-#include "bitmap_character_def.h" // for smart_ptr visibility of dtor
-#include "resource.h" // for smart_ptr visibility of dtor
-#include "stream.h" // for get_bytes_loaded
-
-#include <map> // for CharacterDictionary
-#include <string>
-#include <memory> // for auto_ptr
-
-// We'd avoid SDL threads if possible. Please define the macro below
-// if you experience problems and report the difference on gnash-dev
-#undef REALLY_USE_SDL_THREADS
-
-#ifdef REALLY_USE_SDL_THREADS
-#ifdef HAVE_SDL_H
-# define USE_SDL_THREADS 1
-#endif
-#endif
-
-#ifdef USE_SDL_THREADS
-#      include "SDL.h"
-#      include "SDL_thread.h"
-#endif
-
-
-namespace gnash
-{
-
-// Forward declarations
-class import_info;
-class movie_def_impl;
-class movie_root;
-
-//
-// Helper for movie_def_impl
-//
-
-class import_info
-{
-    friend class movie_def_impl;
-
-    tu_string  m_source_url;
-    int                m_character_id;
-    tu_string  m_symbol;
-
-    import_info()
-       :
-       m_character_id(-1)
-       {
-       }
-
-    import_info(const char* source, int id, const char* symbol)
-       :
-       m_source_url(source),
-       m_character_id(id),
-       m_symbol(symbol)
-       {
-       }
-};
-
-/// \brief
-/// movie_def_impl helper class handling start and execution of
-/// an SWF loading thread
-///
-class MovieLoader
-{
-
-public:
-
-       MovieLoader(movie_def_impl& md);
-
-       ~MovieLoader();
-
-       /// Start loading thread.
-       //
-       /// The associated movie_def_impl instance
-       /// is expected to have already read the SWF
-       /// header and applied a zlib adapter if needed.
-       ///
-       bool start();
-
-       /// Wait for specified frame number (1-based) to be loaded
-       //
-       /// Block caller thread until frame is loaded.
-       ///
-       void wait_for_frame(size_t framenum);
-
-       /// Signal load of given frame number (if anyone waiting for it)
-       void signal_frame_loaded(size_t frameno);
-
-       void lock();
-
-       void unlock();
-
-private:
-
-       size_t _waiting_for_frame;
-       movie_def_impl& _movie_def;
-
-#ifdef USE_SDL_THREADS
-
-       static int execute(void* arg);
-
-       SDL_Thread* _thread;
-       SDL_cond* _frame_reached_condition;
-       SDL_mutex* _mutex;
-
-#else
-
-       pthread_cond_t _frame_reached_condition;
-       pthread_mutex_t _mutex;
-       pthread_t _thread;
-
-       /// Entry point for the actual thread
-       static void *execute(void* arg);
-
-#endif
-
-};
-
-/// The Characters dictionary associated with each SWF file.
-//
-/// This is a set of Characters defined by define tags and
-/// getting assigned a unique ID. 
-///
-class CharacterDictionary
-{
-
-public:
-
-       /// The container used by this dictionary
-       //
-       /// It contains pairs of 'int' and 'smart_ptr<character_def>'
-       ///
-       typedef std::map< int, smart_ptr<character_def> > container;
-       //typedef hash< int, smart_ptr<character_def> >container;
-
-       typedef container::iterator iterator;
-
-       typedef container::const_iterator const_iterator;
-
-       /// Get the Character with the given id
-       //
-       /// returns a NULL if the id is unknown.
-       ///
-       smart_ptr<character_def> get_character(int id);
-
-       /// Add a Character assigning it the given id
-       //
-       /// replaces any existing character with the same id
-       ///
-       void add_character(int id, smart_ptr<character_def> c);
-
-       /// Return an iterator to the first dictionary element
-       iterator begin() { return _map.begin(); }
-
-       /// Return a const_iterator to the first dictionary element
-       const_iterator begin() const { return _map.begin(); }
-
-       /// Return an iterator to one-past last dictionary element
-       iterator end() { return _map.end(); }
-
-       /// Return a const_iterator to one-past last dictionary element
-       const_iterator end() const { return _map.end(); }
-
-       /// Dump content of the dictionary (debugging only)
-       void dump_chars(void) const;
-private:
-
-       container _map;
-
-};
-
-
-/// Immutable definition of a movie's contents.
-//
-/// It cannot be played directly, and does not hold
-/// current state; for that you need to call create_instance()
-/// to get a movie instance (gnash::movie_interface).
-///
-class movie_def_impl : public movie_definition
-{
-       /// Characters Dictionary
-       CharacterDictionary     _dictionary;
-       //hash<int, smart_ptr<character_def> >          m_characters;
-
-       /// Tags loader table
-       SWF::TagLoadersTable& _tag_loaders;
-
-       hash<int, smart_ptr<font> >                     m_fonts;
-       hash<int, smart_ptr<bitmap_character_def> >     m_bitmap_characters;
-       hash<int, smart_ptr<sound_sample> >             m_sound_samples;
-       hash<int, smart_ptr<sound_sample> >             m_sound_streams;
-
-       /// A list of movie control events for each frame.
-       std::vector<std::vector<execute_tag*> >         m_playlist;
-
-       /// Init actions for each frame.
-       std::vector<std::vector<execute_tag*> >    m_init_action_list;
-
-       /// 0-based frame #'s
-       stringi_hash<size_t> m_named_frames;
-
-       stringi_hash<smart_ptr<resource> > m_exports;
-
-       /// Items we import.
-       std::vector<import_info> m_imports;
-
-       /// Movies we import from; hold a ref on these,
-       /// to keep them alive
-       std::vector<smart_ptr<movie_definition> > m_import_source_movies;
-
-       /// Bitmaps used in this movie; collected in one place to make
-       /// it possible for the host to manage them as textures.
-       std::vector<smart_ptr<bitmap_info> >    m_bitmap_list;
-
-       create_bitmaps_flag     m_create_bitmaps;
-       create_font_shapes_flag m_create_font_shapes;
-
-       rect    m_frame_size;
-       float   m_frame_rate;
-       size_t  m_frame_count;
-       int     m_version;
-       size_t  m_loading_frame;
-       int     m_loading_sound_stream;
-       uint32  m_file_length;
-       size_t  _loaded_bytes;
-
-       std::auto_ptr<jpeg::input> m_jpeg_in;
-
-       std::string _url;
-
-       std::auto_ptr<stream> _str;
-
-       tu_file* in;
-
-       std::auto_ptr<tu_file> _zlib_file;
-
-       /// swf end position (as read from header)
-       unsigned int _swf_end_pos;
-
-       /// asyncronous SWF loader and parser
-       MovieLoader _loader;
-
-public:
-
-       movie_def_impl(create_bitmaps_flag cbf, create_font_shapes_flag cfs);
-
-       ~movie_def_impl();
-
-       // ...
-       size_t get_frame_count() const { return m_frame_count; }
-       float   get_frame_rate() const { return m_frame_rate; }
-       const rect& get_frame_size() const { return m_frame_size; }
-
-       float   get_width_pixels() const
-       {
-               return ceilf(TWIPS_TO_PIXELS(m_frame_size.width()));
-       }
-
-       float   get_height_pixels() const
-       {
-               return ceilf(TWIPS_TO_PIXELS(m_frame_size.height()));
-       }
-
-       virtual int     get_version() const { return m_version; }
-
-       virtual size_t  get_loading_frame() const
-       {
-               return m_loading_frame;
-       }
-
-#if 0 // renamed to get_bytes_total
-       uint32  get_file_bytes() const {
-               return m_file_length;
-       }
-#endif
-
-       /// Get number of bytes loaded from input stream
-       size_t  get_bytes_loaded() const {
-#if 0 // temporarly disabled because broken
-               uint32 ret = _loaded_bytes;
-#else
-               uint32 ret = m_file_length;
-#endif
-               log_msg("get_bytes_loaded returning %u (loaded frame: %zu/%zu)",
-                       ret, m_loading_frame, m_frame_count);
-               return ret;
-       }
-
-       /// Get total number of bytes in input stream
-       size_t  get_bytes_total() const {
-               log_msg("get_bytes_total returning %u", m_file_length);
-               return m_file_length;
-       }
-
-       /// Returns DO_CREATE_BITMAPS if we're supposed to
-       /// initialize our bitmap infos, or DO_NOT_INIT_BITMAPS
-       /// if we're supposed to create blank placeholder
-       /// bitmaps (to be init'd later explicitly by the host
-       /// program).
-       virtual create_bitmaps_flag get_create_bitmaps() const
-       {
-               return m_create_bitmaps;
-       }
-
-       /// Returns DO_LOAD_FONT_SHAPES if we're supposed to
-       /// initialize our font shape info, or
-       /// DO_NOT_LOAD_FONT_SHAPES if we're supposed to not
-       /// create any (vector) font glyph shapes, and instead
-       /// rely on precached textured fonts glyphs.
-       virtual create_font_shapes_flag get_create_font_shapes() const
-       {
-           return m_create_font_shapes;
-       }
-
-       /// All bitmap_info's used by this movie should be
-       /// registered with this API.
-       virtual void    add_bitmap_info(bitmap_info* bi)
-       {
-           m_bitmap_list.push_back(bi);
-       }
-
-       virtual int get_bitmap_info_count() const
-       {
-               return m_bitmap_list.size();
-       }
-
-       virtual bitmap_info*    get_bitmap_info(int i) const
-       {
-               return m_bitmap_list[i].get_ptr();
-       }
-
-       /// Expose one of our resources under the given symbol,
-       /// for export.  Other movies can import it.
-       virtual void export_resource(const tu_string& symbol,
-                       resource* res)
-       {
-           // SWF sometimes exports the same thing more than once!
-           m_exports[symbol] = res;
-       }
-
-       /// Get the named exported resource, if we expose it.
-       /// Otherwise return NULL.
-       virtual smart_ptr<resource> get_exported_resource(const tu_string& 
symbol)
-       {
-           smart_ptr<resource> res;
-           m_exports.get(symbol, &res);
-           return res;
-       }
-
-       /// Adds an entry to a table of resources that need to
-       /// be imported from other movies.  Client code must
-       /// call resolve_import() later, when the source movie
-       /// has been loaded, so that the actual resource can be
-       /// used.
-       virtual void add_import(const char* source_url, int id, const char* 
symbol)
-       {
-           assert(in_import_table(id) == false);
-
-           m_imports.push_back(import_info(source_url, id, symbol));
-       }
-
-       /// Debug helper; returns true if the given
-       /// character_id is listed in the import table.
-       bool in_import_table(int character_id);
-
-       /// Calls back the visitor for each movie that we
-       /// import symbols from.
-       virtual void visit_imported_movies(import_visitor* visitor);
-
-       /// Grabs the stuff we want from the source movie.
-       virtual void resolve_import(const char* source_url,
-               movie_definition* source_movie);
-
-       void add_character(int character_id, character_def* c);
-
-       /// \brief
-       /// Return a character from the dictionary
-       /// NOTE: call add_ref() on the return or put in a smart_ptr<>
-       /// TODO: return a smart_ptr<> directly...
-       ///
-       character_def*  get_character_def(int character_id);
-
-       /// Returns 0-based frame #
-       bool get_labeled_frame(const char* label, size_t* frame_number)
-       {
-               return m_named_frames.get(label, frame_number);
-       }
-
-       void    add_font(int font_id, font* f);
-       font*   get_font(int font_id);
-       bitmap_character_def*   get_bitmap_character(int character_id);
-       void    add_bitmap_character(int character_id, bitmap_character_def* 
ch);
-       sound_sample*   get_sound_sample(int character_id);
-       virtual void    add_sound_sample(int character_id, sound_sample* sam);
-       virtual void    set_loading_sound_stream_id(int id) { 
m_loading_sound_stream = id; }
-       int             get_loading_sound_stream_id() { return 
m_loading_sound_stream; }
-
-       /// Add an execute_tag to this movie_definition's playlist
-       void    add_execute_tag(execute_tag* e)
-       {
-           assert(e);
-           m_playlist[m_loading_frame].push_back(e);
-       }
-
-       /// Need to execute the given tag before entering the
-       /// currently-loading frame for the first time.
-       ///
-       /// @@ AFAIK, the sprite_id is totally pointless -- correct?
-       //void  add_init_action(int sprite_id, execute_tag* e)
-       void    add_init_action(execute_tag* e)
-       {
-           assert(e);
-           m_init_action_list[m_loading_frame].push_back(e);
-       }
-
-       /// Labels the frame currently being loaded with the
-       /// given name.  A copy of the name string is made and
-       /// kept in this object.
-       void    add_frame_name(const char* name)
-       {
-           assert(m_loading_frame < m_frame_count);
-
-           tu_string   n = name;
-
-                       if (m_named_frames.get(n, NULL) == false)       // 
frame should not already have a name (?)
-                       {
-                   m_named_frames.add(n, m_loading_frame);     // stores 
0-based frame #
-                       }
-       }
-
-       /// Set an input object for later loading DefineBits
-       /// images (JPEG images without the table info).
-       void    set_jpeg_loader(std::auto_ptr<jpeg::input> j_in)
-       {
-           assert(m_jpeg_in.get() == NULL);
-           m_jpeg_in = j_in;
-       }
-
-       /// Get the jpeg input loader, to load a DefineBits
-       /// image (one without table info).
-       //
-       /// NOTE: ownership is NOT transferred
-       ///
-       jpeg::input*    get_jpeg_loader()
-       {
-           return m_jpeg_in.get();
-       }
-
-       virtual const std::vector<execute_tag*>& get_playlist(size_t 
frame_number)
-       {
-               return m_playlist[frame_number];
-       }
-
-       virtual const std::vector<execute_tag*>* get_init_actions(size_t 
frame_number)
-       {
-               assert(frame_number <= m_loading_frame);
-               //ensure_frame_loaded(frame_number);
-               return &m_init_action_list[frame_number];
-       }
-
-       /// Read (w/out playing) a Movie definition from an SWF file.
-       //
-       /// Note that the *full* SWF is read before
-       /// this function returns. We should change this
-       /// interface to both read and play a file instead.
-       ///
-       /// This function uses a private TagLoadersTable
-       /// to interpret specific tag types.
-       /// Currently the TagLoadersTable in use is the
-       /// gnash::s_tag_loaders global variable
-       ///
-       /// @param in the tu_file from which to read SWF
-       /// @param url the url associated with the input
-       /// @return false if SWF file could not be parsed
-       ///
-       bool read(tu_file *in, const std::string& url);
-
-       /// \brief
-       /// Ensure that frame number 'framenum' (1-based offset)
-       /// has been loaded (load on demand).
-       ///
-       bool ensure_frame_loaded(size_t framenum);
-
-       /// Read and parse all the SWF stream (blocking until load is finished)
-       void read_all_swf();
-
-       virtual void load_next_frame_chunk();
-
-       /// Fill up *fonts with fonts that we own.
-       void get_owned_fonts(std::vector<font*>* fonts);
-
-       /// Generate bitmaps for our fonts, if necessary.
-       void generate_font_bitmaps();
-
-       /// Dump our cached data into the given stream.
-       void output_cached_data(tu_file* out,
-               const cache_options& options);
-
-       /// \brief
-       /// Read in cached data and use it to prime our
-       /// loaded characters.
-       void    input_cached_data(tu_file* in);
-
-       /// \brief
-       /// Create a playable movie_root instance from a def.
-       //
-       /// The _root reference of the newly created instance
-       /// will be set to a newly created sprite_instace (Help!)
-       ///
-       movie_interface* create_instance();
-
-       virtual const std::string& get_url() const { return _url; }
-
-
-};
-
-} // namespace gnash
-
-#endif // GNASH_MOVIE_DEF_IMPL_H

Index: server/movie_definition.h
===================================================================
RCS file: server/movie_definition.h
diff -N server/movie_definition.h
--- server/movie_definition.h   14 Aug 2006 23:16:57 -0000      1.11
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,269 +0,0 @@
-// 
-//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
-// 
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-// 
-// This program 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 General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-// Linking Gnash statically or dynamically with other modules is making a
-// combined work based on Gnash. Thus, the terms and conditions of the GNU
-// General Public License cover the whole combination.
-//
-// As a special exception, the copyright holders of Gnash give you
-// permission to combine Gnash with free software programs or libraries
-// that are released under the GNU LGPL and with code included in any
-// release of Talkback distributed by the Mozilla Foundation. You may
-// copy and distribute such a system following the terms of the GNU GPL
-// for all but the LGPL-covered parts and Talkback, and following the
-// LGPL for the LGPL-covered parts.
-//
-// Note that people who make modified versions of Gnash are not obligated
-// to grant this special exception for their modified versions; it is their
-// choice whether to do so. The GNU General Public License gives permission
-// to release a modified version without this exception; this exception
-// also makes it possible to release a modified version which carries
-// forward this exception.
-// 
-//
-
-
-/// \page movie SWF Movies
-///
-/// SWF Movies definitions are created by reading an SWF stream.
-/// Gnash doesn't play SWF Movie definitions, but instances.
-/// So you can play the same SWF file (Movie definiton) using
-/// multiple instances.
-///
-/// A Movie definition is defined by the gnash::movie_definition class.
-/// A Movie instance is defined by the gnash::movie_interface class.
-/// 
-/// A Movie instance exposes the ActionScript
-/// Object base interface (gnash::as_object),
-/// thus it can manage gnash::as_value members.
-///
-/// The implementation of SWF parsing for a Movie definition
-/// is found in gnash::movie_def_impl::read.
-/// Note that movie_definition is also used as a base class
-/// to sprite_definition, which is a sub-movie defined in an SWF
-/// file. This seems to be the only reason to have a
-/// movie_def_impl class, being the top-level definition of
-/// a movie (the one with a CharacterDictionary in it).
-///
-
-
-#ifndef GNASH_MOVIE_DEFINITION_H
-#define GNASH_MOVIE_DEFINITION_H
-
-#include "container.h"
-#include "button.h" // for mouse_button_state
-#include "timers.h" // for Timer
-#include "fontlib.h"
-#include "font.h"
-#include "jpeg.h"
-#include "tu_file.h"
-
-#include <string>
-#include <memory> // for auto_ptr
-
-namespace gnash
-{
-
-/// Client program's interface to the definition of a movie
-//
-/// (i.e. the shared constant source info).
-///
-struct movie_definition : public character_def
-{
-       virtual int     get_version() const = 0;
-       virtual float   get_width_pixels() const = 0;
-       virtual float   get_height_pixels() const = 0;
-       virtual size_t  get_frame_count() const = 0;
-       virtual float   get_frame_rate() const = 0;
-
-       virtual size_t get_bytes_loaded() const = 0;
-       virtual size_t get_bytes_total() const = 0;
-       
-       /// Create a playable movie instance from a def.
-       //
-       /// This calls add_ref() on the movie_interface internally.
-       /// Call drop_ref() on the movie_interface when you're done with it.
-       /// Or use smart_ptr<T> from base/smart_ptr.h if you want.
-       ///
-       virtual movie_interface*        create_instance() = 0;
-       
-       virtual void    output_cached_data(tu_file* out, const cache_options& 
options) = 0;
-       virtual void    input_cached_data(tu_file* in) = 0;
-       
-       /// \brief
-       /// Causes this movie def to generate texture-mapped
-       /// versions of all the fonts it owns. 
-       //
-       /// This improves
-       /// speed and quality of text rendering.  The
-       /// texture-map data is serialized in the
-       /// output/input_cached_data() calls, so you can
-       /// preprocess this if you load cached data.
-       ///
-       virtual void    generate_font_bitmaps() = 0;
-       
-       //
-       // (optional) API to support gnash::create_movie_no_recurse().
-       //
-       
-       /// \brief
-       /// Call visit_imported_movies() to retrieve a list of
-       /// names of movies imported into this movie.
-       //
-       /// visitor->visit() will be called back with the name
-       /// of each imported movie.
-       struct import_visitor
-       {
-           virtual ~import_visitor() {}
-           virtual void        visit(const char* imported_movie_filename) = 0;
-       };
-       virtual void    visit_imported_movies(import_visitor* visitor) = 0;
-       
-       /// Call this to resolve an import of the given movie.
-       /// Replaces the dummy placeholder with the real
-       /// movie_definition* given.
-       virtual void    resolve_import(const char* name, movie_definition* def) 
= 0;
-       
-       //
-       // (optional) API to support host-driven creation of textures.
-       //
-       // Create the movie using gnash::create_movie_no_recurse(..., 
DO_NOT_LOAD_BITMAPS),
-       // and then initialize each bitmap info via get_bitmap_info_count(), 
get_bitmap_info(),
-       // and bitmap_info::init_*_image() or your own subclassed API.
-       //
-       // E.g.:
-       //
-       // // During preprocessing:
-       // // This will create bitmap_info's using the rgba, rgb, alpha 
contructors.
-       // my_def = gnash::create_movie_no_recurse("myfile.swf", 
DO_LOAD_BITMAPS);
-       // int ct = my_def->get_bitmap_info_count();
-       // for (int i = 0; i < ct; i++)
-       // {
-       //      my_bitmap_info_subclass*        bi = NULL;
-       //      my_def->get_bitmap_info(i, (bitmap_info**) &bi);
-       //      
my_precomputed_textures.push_back(bi->m_my_internal_texture_reference);
-       // }
-       // // Save out my internal data.
-       // my_precomputed_textures->write_into_some_cache_stream(...);
-       //
-       // // Later, during run-time loading:
-       // my_precomputed_textures->read_from_some_cache_stream(...);
-       // // This will create blank bitmap_info's.
-       // my_def = gnash::create_movie_no_recurse("myfile.swf", 
DO_NOT_LOAD_BITMAPS);
-       // 
-       // // Push cached texture info into the movie's bitmap_info structs.
-       // int  ct = my_def->get_bitmap_info_count();
-       // for (int i = 0; i < ct; i++)
-       // {
-       //      my_bitmap_info_subclass*        bi = (my_bitmap_info_subclass*) 
my_def->get_bitmap_info(i);
-       //      bi->set_internal_texture_reference(my_precomputed_textures[i]);
-       // }
-       virtual int     get_bitmap_info_count() const = 0;
-       virtual bitmap_info*    get_bitmap_info(int i) const = 0;
-
-       // From movie_definition_sub
-
-       virtual const std::vector<execute_tag*>& get_playlist(size_t 
frame_number) = 0;
-       virtual const std::vector<execute_tag*>* get_init_actions(size_t 
frame_number) = 0;
-       virtual smart_ptr<resource>     get_exported_resource(const tu_string& 
symbol) = 0;
-
-
-       /// \brief
-       /// Get a character from the dictionary.
-       ///
-       /// Note that only top-level movies (those belonging to a single
-       /// SWF stream) have a characters dictionary, thus our
-       /// movie_def_impl. The other derived class, sprite_definition
-       /// will seek for characters in it's base movie_def_impl.
-       ///
-       virtual character_def*  get_character_def(int id) = 0;
-
-       virtual bool get_labeled_frame(const char* label, size_t* frame_number) 
= 0;
-
-       //
-       // For use during creation.
-       //
-
-       /// Returns 1 based index. Ex: if 1 then 1st frame as been fully loaded
-       virtual size_t  get_loading_frame() const = 0;
-
-       virtual void    add_character(int id, character_def* ch) = 0;
-
-       virtual void    add_font(int id, font* ch) = 0;
-
-       virtual font*   get_font(int id) = 0;
-
-       virtual void    add_execute_tag(execute_tag* c) = 0;
-
-       // sprite_id was useless
-       //virtual void  add_init_action(int sprite_id, execute_tag* c) = 0;
-       virtual void    add_init_action(execute_tag* c) = 0;
-
-       virtual void    add_frame_name(const char* name) = 0;
-
-       virtual void    set_jpeg_loader(std::auto_ptr<jpeg::input> j_in) = 0;
-
-       virtual jpeg::input*    get_jpeg_loader() = 0;
-
-       virtual bitmap_character_def* get_bitmap_character(int character_id)=0;
-
-       virtual void add_bitmap_character(int character_id,
-                       bitmap_character_def* ch) = 0;
-
-       virtual sound_sample* get_sound_sample(int character_id) = 0;
-
-       virtual void add_sound_sample(int character_id, sound_sample* sam) = 0;
-
-       virtual void set_loading_sound_stream_id(int id) = 0;
-       
-       virtual int get_loading_sound_stream_id() = 0;
-
-
-       virtual void export_resource(const tu_string& symbol,
-                       resource* res) = 0;
-
-       virtual void add_import(const char* source_url, int id,
-                       const char* symbol_name) = 0;
-
-       virtual void add_bitmap_info(bitmap_info* ch) = 0;
-
-       // ...
-
-       virtual create_bitmaps_flag     get_create_bitmaps() const = 0;
-       virtual create_font_shapes_flag get_create_font_shapes() const = 0;
-
-       /// \brief
-       /// Return the URL of the SWF stream this definition has been read
-       /// from.
-       virtual const std::string& get_url() const = 0;
-
-       /// \brief
-       /// Ensure that frame number 'framenum' (1-based offset)
-       /// has been loaded (load on demand).
-       //
-       /// @return false on error (like not enough frames available).
-       ///
-       virtual bool ensure_frame_loaded(size_t framenum) = 0;
-
-       /// \brief
-       /// Load next chunk of this movie/sprite frames if available.
-       ///
-       virtual void load_next_frame_chunk() = 0;
-};
-
-} // namespace gnash
-
-#endif // GNASH_MOVIE_DEFINITION_H

Index: server/shape_character_def.cpp
===================================================================
RCS file: server/shape_character_def.cpp
diff -N server/shape_character_def.cpp
--- server/shape_character_def.cpp      13 Aug 2006 16:45:11 -0000      1.7
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,718 +0,0 @@
-// shape.cpp   -- Thatcher Ulrich <address@hidden> 2003
-
-// This source code has been donated to the Public Domain.  Do
-// whatever you want with it.
-
-// Quadratic bezier outline shapes, the basis for most SWF rendering.
-
-
-#include "shape_character_def.h"
-#include "shape.h" // for mesh_set
-
-#include "impl.h"
-#include "log.h"
-#include "render.h"
-#include "stream.h"
-#include "tesselate.h"
-#include "movie_definition.h" // TODO: check if really needed
-//#include "bitmap_character_def.h"
-#include "sprite_instance.h"
-
-#include "tu_file.h"
-
-#include <float.h>
-
-
-#define DEBUG_DISPLAY_SHAPE_PATHS
-#ifdef DEBUG_DISPLAY_SHAPE_PATHS
-// For debugging only!
-bool   gnash_debug_show_paths = false;
-#endif // DEBUG_DISPLAY_SHAPE_PATHS
-
-
-namespace gnash {
-
-static float   s_curve_max_pixel_error = 1.0f;
-
-
-//
-// helper functions.
-//
-
-void   set_curve_max_pixel_error(float pixel_error)
-{
-    s_curve_max_pixel_error = fclamp(pixel_error, 1e-6f, 1e6f);
-}
-
-float  get_curve_max_pixel_error()
-{
-    return s_curve_max_pixel_error;
-}
-
-
-// Read fill styles, and push them onto the given style array.
-static void
-read_fill_styles(std::vector<fill_style>& styles, stream* in,
-               int tag_type, movie_definition* m)
-{
-    //assert(styles);
-
-    // Get the count.
-    int        fill_style_count = in->read_u8();
-    if (tag_type > 2) {
-       if (fill_style_count == 0xFF)
-           {
-               fill_style_count = in->read_u16();
-           }
-    }
-
-               IF_VERBOSE_PARSE (
-    log_parse("  read_fill_styles: count = %d", fill_style_count);
-               );
-
-    // Read the styles. 
-    for (int i = 0; i < fill_style_count; i++) {
-       styles.resize(styles.size() + 1);
-       //styles[styles.size() - 1].read(in, tag_type, m);
-       styles.back().read(in, tag_type, m);
-    }
-}
-
-
-static void
-read_line_styles(std::vector<line_style>& styles, stream* in, int tag_type)
-    // Read line styles and push them onto the back of the given array.
-{
-    // Get the count.
-    int        line_style_count = in->read_u8();
-    
-               IF_VERBOSE_PARSE
-               (
-    log_parse("  read_line_styles: count = %d", line_style_count);
-               );
-
-    // @@ does the 0xFF flag apply to all tag types?
-    // if (tag_type > 2)
-    // {
-    if (line_style_count == 0xFF) {
-       line_style_count = in->read_u16();
-               IF_VERBOSE_PARSE
-               (
-       log_parse("  read_line_styles: count2 = %d", line_style_count);
-               );
-    }
-    // }
-
-    // Read the styles.
-    for (int i = 0; i < line_style_count; i++) {
-       styles.resize(styles.size() + 1);
-       //styles[styles.size() - 1].read(in, tag_type);
-       styles.back().read(in, tag_type);
-    }
-}
-
-
-shape_character_def::shape_character_def()
-{
-}
-
-
-shape_character_def::~shape_character_def()
-{
-    // Free our mesh_sets.
-    for (unsigned int i = 0; i < m_cached_meshes.size(); i++) {
-       delete m_cached_meshes[i];
-    }
-}
-
-
-void
-shape_character_def::read(stream* in, int tag_type, bool with_style,
-       movie_definition* m)
-{
-    if (with_style) {
-       m_bound.read(in);
-       read_fill_styles(m_fill_styles, in, tag_type, m);
-       read_line_styles(m_line_styles, in, tag_type);
-    }
-
-    int        num_fill_bits = in->read_uint(4);
-    int        num_line_bits = in->read_uint(4);
-
-               IF_VERBOSE_PARSE
-               (
-    log_parse("  shape_character_def read: nfillbits = %d, nlinebits = %d", 
num_fill_bits, num_line_bits);
-               );
-
-    // These are state variables that keep the
-    // current position & style of the shape
-    // outline, and vary as we read the edge data.
-    //
-    // At the moment we just store each edge with
-    // the full necessary info to render it, which
-    // is simple but not optimally efficient.
-    int        fill_base = 0;
-    int        line_base = 0;
-    float      x = 0, y = 0;
-    path       current_path;
-
-#define SHAPE_LOG 0
-    // SHAPERECORDS
-    for (;;) {
-       int     type_flag = in->read_uint(1);
-       if (type_flag == 0) {
-           // Parse the record.
-           int flags = in->read_uint(5);
-           if (flags == 0) {
-               // End of shape records.
-
-               // Store the current path if any.
-               if (! current_path.is_empty())
-                   {
-                       m_paths.push_back(current_path);
-                       current_path.m_edges.resize(0);
-                   }
-
-               break;
-           }
-           if (flags & 0x01) {
-               // move_to = 1;
-
-               // Store the current path if any, and prepare a fresh one.
-               if (! current_path.is_empty()) {
-                   m_paths.push_back(current_path);
-                   current_path.m_edges.resize(0);
-               }
-
-               int     num_move_bits = in->read_uint(5);
-               int     move_x = in->read_sint(num_move_bits);
-               int     move_y = in->read_sint(num_move_bits);
-
-               x = (float) move_x;
-               y = (float) move_y;
-
-               // Set the beginning of the path.
-               current_path.m_ax = x;
-               current_path.m_ay = y;
-
-               IF_VERBOSE_PARSE
-               (
-               if (SHAPE_LOG) 
-                   log_parse("  shape_character read: moveto %4g %4g", x, y);
-               );
-           }
-           if ((flags & 0x02) && num_fill_bits > 0) {
-               // fill_style_0_change = 1;
-               if (! current_path.is_empty()) {
-                   m_paths.push_back(current_path);
-                   current_path.m_edges.resize(0);
-                   current_path.m_ax = x;
-                   current_path.m_ay = y;
-               }
-               int     style = in->read_uint(num_fill_bits);
-               if (style > 0) {
-                   style += fill_base;
-               }
-               current_path.m_fill0 = style;
-               IF_VERBOSE_PARSE
-               (
-               if (SHAPE_LOG) {
-                   log_parse("  shape_character read: fill0 = %d", 
current_path.m_fill0);
-               }
-               );
-               
-           }
-           if ((flags & 0x04) && num_fill_bits > 0) {
-               // fill_style_1_change = 1;
-               if (! current_path.is_empty()) {
-                   m_paths.push_back(current_path);
-                   current_path.m_edges.resize(0);
-                   current_path.m_ax = x;
-                   current_path.m_ay = y;
-               }
-               int     style = in->read_uint(num_fill_bits);
-               if (style > 0) {
-                   style += fill_base;
-               }
-               current_path.m_fill1 = style;
-               IF_VERBOSE_PARSE (
-               if (SHAPE_LOG) {
-                   log_parse("  shape_character read: fill1 = %d", 
current_path.m_fill1);
-               }
-               );
-           }
-           if ((flags & 0x08) && num_line_bits > 0) {
-               // line_style_change = 1;
-               if (! current_path.is_empty()) {
-                   m_paths.push_back(current_path);
-                   current_path.m_edges.resize(0);
-                   current_path.m_ax = x;
-                   current_path.m_ay = y;
-               }
-               int     style = in->read_uint(num_line_bits);
-               if (style > 0) {
-                   style += line_base;
-               }
-               current_path.m_line = style;
-               IF_VERBOSE_PARSE (
-               if (SHAPE_LOG)
-               {
-                   log_parse("  shape_character_read: line = %d", 
current_path.m_line);
-               }
-               );
-           }
-           if (flags & 0x10) {
-               if (tag_type == 2) {
-                   tag_type+=20;
-               }
-               assert(tag_type >= 22);
-
-               IF_VERBOSE_PARSE (
-               log_parse("  shape_character read: more fill styles");
-               );
-
-               // Store the current path if any.
-               if (! current_path.is_empty()) {
-                   m_paths.push_back(current_path);
-                   current_path.m_edges.resize(0);
-
-                   // Clear styles.
-                   current_path.m_fill0 = -1;
-                   current_path.m_fill1 = -1;
-                   current_path.m_line = -1;
-               }
-               // Tack on an empty path signalling a new shape.
-               // @@ need better understanding of whether this is correct??!?!!
-               // @@ i.e., we should just start a whole new shape here, right?
-               m_paths.push_back(path());
-               m_paths.back().m_new_shape = true;
-
-               fill_base = m_fill_styles.size();
-               line_base = m_line_styles.size();
-               read_fill_styles(m_fill_styles, in, tag_type, m);
-               read_line_styles(m_line_styles, in, tag_type);
-               num_fill_bits = in->read_uint(4);
-               num_line_bits = in->read_uint(4);
-           }
-       } else {
-           // EDGERECORD
-           int edge_flag = in->read_uint(1);
-           if (edge_flag == 0) {
-               // curved edge
-               int num_bits = 2 + in->read_uint(4);
-               float   cx = x + in->read_sint(num_bits);
-               float   cy = y + in->read_sint(num_bits);
-               float   ax = cx + in->read_sint(num_bits);
-               float   ay = cy + in->read_sint(num_bits);
-
-               IF_VERBOSE_PARSE (
-               if (SHAPE_LOG)
-               {
-                   log_parse("  shape_character read: curved edge   = %4g %4g 
- %4g %4g - %4g %4g", x, y, cx, cy, ax, ay);
-               }
-               );
-
-               current_path.m_edges.push_back(edge(cx, cy, ax, ay));
-
-               x = ax;
-               y = ay;
-           } else {
-               // straight edge
-               int     num_bits = 2 + in->read_uint(4);
-               int     line_flag = in->read_uint(1);
-               float   dx = 0, dy = 0;
-               if (line_flag) {
-                   // General line.
-                   dx = (float) in->read_sint(num_bits);
-                   dy = (float) in->read_sint(num_bits);
-               } else {
-                   int vert_flag = in->read_uint(1);
-                   if (vert_flag == 0) {
-                       // Horizontal line.
-                       dx = (float) in->read_sint(num_bits);
-                   } else {
-                       // Vertical line.
-                       dy = (float) in->read_sint(num_bits);
-                   }
-               }
-
-               IF_VERBOSE_PARSE (
-               if (SHAPE_LOG)
-               {
-                   log_parse("  shape_character_read: straight edge = %4g %4g 
- %4g %4g", x, y, x + dx, y + dy);
-               }
-               );
-
-               current_path.m_edges.push_back(edge(x + dx, y + dy, x + dx, y + 
dy));
-
-               x += dx;
-               y += dy;
-           }
-       }
-    }
-}
-
-
-void   shape_character_def::display(character* inst)
-    // Draw the shape using our own inherent styles.
-{
-//    GNASH_REPORT_FUNCTION;
-
-    matrix     mat = inst->get_world_matrix();
-    cxform     cx = inst->get_world_cxform();
-
-    float      pixel_scale = inst->get_parent()->get_pixel_scale();
-    display(mat, cx, pixel_scale, m_fill_styles, m_line_styles);
-}
-
-
-#ifdef DEBUG_DISPLAY_SHAPE_PATHS
-
-#include "ogl.h"
-
-
-static void    point_normalize(point* p)
-{
-    float      mag2 = p->m_x * p->m_x + p->m_y * p->m_y;
-    if (mag2 < 1e-9f) {
-       // Very short vector.
-       // @@ log error
-
-       // Arbitrary unit vector.
-       p->m_x = 1;
-       p->m_y = 0;
-    }
-
-    float      inv_mag = 1.0f / sqrtf(mag2);
-    p->m_x *= inv_mag;
-    p->m_y *= inv_mag;
-}
-
-
-static void    show_fill_number(const point& p, int fill_number)
-{
-    // We're inside a glBegin(GL_LINES)
-
-    // Eh, let's do it in binary, least sig four bits...
-    float      x = p.m_x;
-    float      y = p.m_y;
-
-    int        mask = 8;
-    while (mask) {
-       if (mask & fill_number) {
-           // Vert line --> 1.
-           glVertex2f(x, y - 40.0f);
-           glVertex2f(x, y + 40.0f);
-       } else {
-           // Rectangle --> 0.
-           glVertex2f(x - 10.0f, y - 40.0f);
-           glVertex2f(x + 10.0f, y - 40.0f);
-
-           glVertex2f(x + 10.0f, y - 40.0f);
-           glVertex2f(x + 10.0f, y + 40.0f);
-
-           glVertex2f(x - 10.0f, y + 40.0f);
-           glVertex2f(x + 10.0f, y + 40.0f);
-
-           glVertex2f(x - 10.0f, y - 40.0f);
-           glVertex2f(x - 10.0f, y + 40.0f);
-       }
-       x += 40.0f;
-       mask >>= 1;
-    }
-}
-
-
-static void    debug_display_shape_paths(
-    const matrix& mat,
-    float /* object_space_max_error */,
-    const std::vector<path>& paths,
-    const std::vector<fill_style>& /* fill_styles */,
-    const std::vector<line_style>& /* line_styles */)
-{
-    for (unsigned int i = 0; i < paths.size(); i++) {
-//                     if (i > 0) break;//xxxxxxxx
-       const path&     p = paths[i];
-
-       if (p.m_fill0 == 0 && p.m_fill1 == 0) {
-           continue;
-       }
-
-       gnash::render::set_matrix(mat);
-
-       // Color the line according to which side has
-       // fills.
-       if (p.m_fill0 == 0) glColor4f(1, 0, 0, 0.5);
-       else if (p.m_fill1 == 0) glColor4f(0, 1, 0, 0.5);
-       else glColor4f(0, 0, 1, 0.5);
-
-       // Offset according to which loop we are.
-       float   offset_x = (i & 1) * 80.0f;
-       float   offset_y = ((i & 2) >> 1) * 80.0f;
-       glMatrixMode(GL_MODELVIEW);
-       glPushMatrix();
-       glTranslatef(offset_x, offset_y, 0.f);
-
-       point   pt;
-
-       glBegin(GL_LINE_STRIP);
-
-       mat.transform(&pt, point(p.m_ax, p.m_ay));
-       glVertex2f(pt.m_x, pt.m_y);
-
-       for (unsigned int j = 0; j < p.m_edges.size(); j++)     {
-           mat.transform(&pt, point(p.m_edges[j].m_cx, p.m_edges[j].m_cy));
-           glVertex2f(pt.m_x, pt.m_y);
-           mat.transform(&pt, point(p.m_edges[j].m_ax, p.m_edges[j].m_ay));
-           glVertex2f(pt.m_x, pt.m_y);
-       }
-
-       glEnd();
-
-       // Draw arrowheads.
-       point   dir, right, p0, p1;
-       glBegin(GL_LINES);
-       {for (unsigned int j = 0; j < p.m_edges.size(); j++)
-           {
-               mat.transform(&p0, point(p.m_edges[j].m_cx, p.m_edges[j].m_cy));
-               mat.transform(&p1, point(p.m_edges[j].m_ax, p.m_edges[j].m_ay));
-               dir = point(p1.m_x - p0.m_x, p1.m_y - p0.m_y);
-               point_normalize(&dir);
-               right = point(-dir.m_y, dir.m_x);       // perpendicular
-
-               const float     ARROW_MAG = 60.f;       // TWIPS?
-               if (p.m_fill0 != 0)
-                   {
-                       glColor4f(0, 1, 0, 0.5);
-                       glVertex2f(p0.m_x,
-                                  p0.m_y);
-                       glVertex2f(p0.m_x - dir.m_x * ARROW_MAG - right.m_x * 
ARROW_MAG,
-                                  p0.m_y - dir.m_y * ARROW_MAG - right.m_y * 
ARROW_MAG);
-
-                       show_fill_number(point(p0.m_x - right.m_x * ARROW_MAG * 
4,
-                                              p0.m_y - right.m_y * ARROW_MAG * 
4),
-                                        p.m_fill0);
-                   }
-               if (p.m_fill1 != 0)
-                   {
-                       glColor4f(1, 0, 0, 0.5);
-                       glVertex2f(p0.m_x,
-                                  p0.m_y);
-                       glVertex2f(p0.m_x - dir.m_x * ARROW_MAG + right.m_x * 
ARROW_MAG,
-                                  p0.m_y - dir.m_y * ARROW_MAG + right.m_y * 
ARROW_MAG);
-
-                       show_fill_number(point(p0.m_x + right.m_x * ARROW_MAG * 
4,
-                                              p0.m_y + right.m_y * ARROW_MAG * 
4),
-                                        p.m_fill1);
-                   }
-           }}
-       glEnd();
-
-       glPopMatrix();
-    }
-}
-#endif // DEBUG_DISPLAY_SHAPE_PATHS
-
-               
-void   shape_character_def::display(
-    const matrix& mat,
-    const cxform& cx,
-    float pixel_scale,
-    const std::vector<fill_style>& fill_styles,
-    const std::vector<line_style>& line_styles) const
-    // Display our shape.  Use the fill_styles arg to
-    // override our default set of fill styles (e.g. when
-    // rendering text).
-{
-//    GNASH_REPORT_FUNCTION;
-
-    // Compute the error tolerance in object-space.
-    float      max_scale = mat.get_max_scale();
-    if (fabsf(max_scale) < 1e-6f) {
-       // Scale is essentially zero.
-       return;
-    }
-
-    float      object_space_max_error = 20.0f / max_scale / pixel_scale * 
s_curve_max_pixel_error;
-
-#ifdef DEBUG_DISPLAY_SHAPE_PATHS
-    // Render a debug view of shape path outlines, instead
-    // of the tesselated shapes themselves.
-    if (gnash_debug_show_paths) {
-       debug_display_shape_paths(mat, object_space_max_error, m_paths, 
fill_styles, line_styles);
-
-       return;
-    }
-#endif // DEBUG_DISPLAY_SHAPE_PATHS
-
-    // See if we have an acceptable mesh available; if so then render with it.
-    for (unsigned int i = 0, n = m_cached_meshes.size(); i < n; i++) {
-       const mesh_set* candidate = m_cached_meshes[i];
-
-       if (object_space_max_error > candidate->get_error_tolerance() * 3.0f)
-           {
-               // Mesh is too high-res; the remaining meshes are higher res,
-               // so stop searching and build an appropriately scaled mesh.
-               break;
-           }
-
-       if (object_space_max_error > candidate->get_error_tolerance()) {
-           // Do it.
-           candidate->display(mat, cx, fill_styles, line_styles);
-           return;
-       }
-    }
-
-    // Construct a new mesh to handle this error tolerance.
-    mesh_set*  m = new mesh_set(this, object_space_max_error * 0.75f);
-    m_cached_meshes.push_back(m);
-    m->display(mat, cx, fill_styles, line_styles);
-               
-    sort_and_clean_meshes();
-}
-
-
-static int     sort_by_decreasing_error(const void* A, const void* B)
-{
-    const mesh_set*    a = *(const mesh_set* const *) A;
-    const mesh_set*    b = *(const mesh_set* const *) B;
-
-    if (a->get_error_tolerance() < b->get_error_tolerance()) {
-       return 1;
-    } else if (a->get_error_tolerance() > b->get_error_tolerance()) {
-       return -1;
-    } else {
-       return 0;
-    }
-}
-
-
-void   shape_character_def::sort_and_clean_meshes() const
-    // Maintain cached meshes.  Clean out mesh_sets that haven't
-    // been used recently, and make sure they're sorted from high
-    // error to low error.
-{
-    // Re-sort.
-    if (m_cached_meshes.size() > 0) {
-       qsort(
-           &m_cached_meshes[0],
-           m_cached_meshes.size(),
-           sizeof(m_cached_meshes[0]),
-           sort_by_decreasing_error);
-
-       // Check to make sure the sort worked as intended.
-#ifndef NDEBUG
-       for (unsigned int i = 0, n = m_cached_meshes.size() - 1; i < n; i++) {
-           const mesh_set*     a = m_cached_meshes[i];
-           const mesh_set*     b = m_cached_meshes[i + 1];
-
-           assert(a->get_error_tolerance() > b->get_error_tolerance());
-       }
-#endif // not NDEBUG
-    }
-}
-
-               
-void   shape_character_def::tesselate(float error_tolerance, 
tesselate::trapezoid_accepter* accepter) const
-    // Push our shape data through the tesselator.
-{
-    tesselate::begin_shape(accepter, error_tolerance);
-    for (unsigned int i = 0; i < m_paths.size(); i++) {
-       if (m_paths[i].m_new_shape == true)     {
-           // Hm; should handle separate sub-shapes in a less lame way.
-           tesselate::end_shape();
-           tesselate::begin_shape(accepter, error_tolerance);
-       } else {
-           m_paths[i].tesselate();
-       }
-    }
-    tesselate::end_shape();
-}
-
-
-bool   shape_character_def::point_test_local(float x, float y)
-    // Return true if the specified point is on the interior of our shape.
-    // Incoming coords are local coords.
-{
-    if (m_bound.point_test(x, y) == false) {
-       // Early out.
-       return false;
-    }
-
-    // Try each of the paths.
-    for (unsigned int i = 0; i < m_paths.size(); i++) {
-       if (m_paths[i].point_test(x, y))
-           {
-               return true;
-           }
-    }
-
-    return false;
-}
-
-
-float shape_character_def::get_height_local()
-{
-    return m_bound.height();
-}
-
-float shape_character_def::get_width_local()
-{
-    return m_bound.width();
-}
-
-
-void   shape_character_def::compute_bound(rect* r) const
-    // Find the bounds of this shape, and store them in
-    // the given rectangle.
-{
-    r->m_x_min = 1e10f;
-    r->m_y_min = 1e10f;
-    r->m_x_max = -1e10f;
-    r->m_y_max = -1e10f;
-
-    for (unsigned int i = 0; i < m_paths.size(); i++) {
-       const path&     p = m_paths[i];
-       r->expand_to_point(p.m_ax, p.m_ay);
-       for (unsigned int j = 0; j < p.m_edges.size(); j++)     {
-           r->expand_to_point(p.m_edges[j].m_ax, p.m_edges[j].m_ay);
-//                                     r->expand_to_point(p.m_edges[j].m_cx, 
p.m_edges[j].m_cy);
-       }
-    }
-}
-
-
-void   shape_character_def::output_cached_data(tu_file* out, const 
cache_options& /* options */)
-    // Dump our precomputed mesh data to the given stream.
-{
-    int        n = m_cached_meshes.size();
-    out->write_le32(n);
-
-    for (int i = 0; i < n; i++) {
-       m_cached_meshes[i]->output_cached_data(out);
-    }
-}
-
-
-void   shape_character_def::input_cached_data(tu_file* in)
-    // Initialize our mesh data from the given stream.
-{
-    int        n = in->read_le32();
-
-    m_cached_meshes.resize(n);
-
-    for (int i = 0; i < n; i++)        {
-       mesh_set*       ms = new mesh_set();
-       ms->input_cached_data(in);
-       m_cached_meshes[i] = ms;
-    }
-}
-
-       
-}      // end namespace gnash
-
-
-// Local Variables:
-// mode: C++
-// indent-tabs-mode: t
-// End:

Index: server/shape_character_def.h
===================================================================
RCS file: server/shape_character_def.h
diff -N server/shape_character_def.h
--- server/shape_character_def.h        25 May 2006 12:05:16 -0000      1.2
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,85 +0,0 @@
-// shape.h     -- Thatcher Ulrich <address@hidden> 2003
-
-// This source code has been donated to the Public Domain.  Do
-// whatever you want with it.
-
-// Quadratic bezier outline shapes, the basis for most SWF rendering.
-
-
-#ifndef GNASH_SHAPE_CHARACTER_DEF_H
-#define GNASH_SHAPE_CHARACTER_DEF_H
-
-
-#include "styles.h"
-#include "character_def.h" // for inheritance of shape_character_def
-#include "tesselate.h" 
-#include "shape.h" // for path
-
-
-namespace gnash {
-
-       /// \brief
-       /// Represents the outline of one or more shapes, along with
-       /// information on fill and line styles.
-       class shape_character_def : public character_def, public 
tesselate::tesselating_shape
-       {
-       public:
-               shape_character_def();
-               virtual ~shape_character_def();
-
-               virtual void    display(character* inst);
-               bool    point_test_local(float x, float y);
-
-               float   get_height_local();
-               float   get_width_local();
-
-               void    read(stream* in, int tag_type, bool with_style, 
movie_definition* m);
-               void    display(
-                       const matrix& mat,
-                       const cxform& cx,
-                       float pixel_scale,
-                       const std::vector<fill_style>& fill_styles,
-                       const std::vector<line_style>& line_styles) const;
-               virtual void    tesselate(float error_tolerance, 
tesselate::trapezoid_accepter* accepter) const;
-               const rect&     get_bound() const { return m_bound; }
-               void    compute_bound(rect* r) const;   // @@ what's the 
difference between this and get_bound?
-
-               void    output_cached_data(tu_file* out, const cache_options& 
options);
-               void    input_cached_data(tu_file* in);
-
-               const std::vector<fill_style>&  get_fill_styles() const { 
return m_fill_styles; }
-               const std::vector<line_style>&  get_line_styles() const { 
return m_line_styles; }
-               const std::vector<path>&        get_paths() const { return 
m_paths; }
-
-               // morph uses this
-               void    set_bound(const rect& r) { m_bound = r; /* should do 
some verifying */ }
-
-       protected:
-               friend class morph2_character_def;
-
-               // derived morph classes changes these
-               std::vector<fill_style> m_fill_styles;
-               std::vector<line_style> m_line_styles;
-               std::vector<path>       m_paths;
-
-       private:
-               void    sort_and_clean_meshes() const;
-               
-               rect    m_bound;
-
-               // Cached pre-tesselated meshes.
-               mutable std::vector<mesh_set*>  m_cached_meshes;
-       };
-
-}      // end namespace gnash
-
-
-#endif // GNASH_SHAPE_CHARACTER_DEF_H
-
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 8 
-// tab-width: 8
-// indent-tabs-mode: t
-// End:

Index: server/sprite_definition.cpp
===================================================================
RCS file: server/sprite_definition.cpp
diff -N server/sprite_definition.cpp
--- server/sprite_definition.cpp        13 Aug 2006 16:45:11 -0000      1.13
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,181 +0,0 @@
-// 
-//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
-// 
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-// 
-// This program 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 General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-// Linking Gnash statically or dynamically with other modules is making a
-// combined work based on Gnash. Thus, the terms and conditions of the GNU
-// General Public License cover the whole combination.
-//
-// As a special exception, the copyright holders of Gnash give you
-// permission to combine Gnash with free software programs or libraries
-// that are released under the GNU LGPL and with code included in any
-// release of Talkback distributed by the Mozilla Foundation. You may
-// copy and distribute such a system following the terms of the GNU GPL
-// for all but the LGPL-covered parts and Talkback, and following the
-// LGPL for the LGPL-covered parts.
-//
-// Note that people who make modified versions of Gnash are not obligated
-// to grant this special exception for their modified versions; it is their
-// choice whether to do so. The GNU General Public License gives permission
-// to release a modified version without this exception; this exception
-// also makes it possible to release a modified version which carries
-// forward this exception.
-// 
-//
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-// This needs to be included first for NetBSD systems or we get a weird
-// problem with pthread_t being defined too many times if we use any
-// STL containers.
-#ifdef HAVE_PTHREADS
-#include <pthread.h>
-#endif
-
-#include "sprite_instance.h"
-#include "sprite_definition.h"
-#include "execute_tag.h" // for dtor visibility
-
-#include <vector>
-#include <string>
-#include <cassert>
-
-using namespace std;
-
-namespace gnash {
-
-character*
-sprite_definition::create_character_instance(character* parent,
-               int id)
-{
-       sprite_instance* si = new sprite_instance(this,
-               parent->get_root(), parent, id);
-       return si;
-}
-
-sprite_definition::~sprite_definition()
-{
-       // Release our playlist data.
-       for (int i = 0, n = m_playlist.size(); i < n; i++)
-       {
-               for (int j = 0, m = m_playlist[i].size(); j < m; j++)
-               {
-                   delete m_playlist[i][j];
-               }
-       }
-}
-
-/*private*/
-// only called from constructors
-void
-sprite_definition::read(stream* in)
-{
-       int tag_end = in->get_tag_end_position();
-
-       m_frame_count = in->read_u16();
-
-       // ALEX: some SWF files have been seen that have 0-frame sprites.
-       // The Macromedia player behaves as if they have 1 frame.
-       if (m_frame_count < 1)
-       {
-               m_frame_count = 1;
-       }
-
-       // need a playlist for each frame
-       m_playlist.resize(m_frame_count);
-
-               IF_VERBOSE_PARSE (
-       log_parse("  frames = %u", m_frame_count);
-               );
-
-       m_loading_frame = 0;
-
-       while ((uint32_t) in->get_position() < (uint32_t) tag_end)
-       {
-               SWF::tag_type tag_type = in->open_tag();
-
-               SWF::TagLoadersTable::loader_function lf = NULL;
-
-               if (tag_type == SWF::DEFINESPRITE)
-               {
-                       log_error("DefineSprite tag inside sprite "
-                               "definition - Malformed SWF!");
-               }
-
-               if (tag_type == SWF::SHOWFRAME)
-               {
-                       // show frame tag -- advance to the next frame.
-                       IF_VERBOSE_PARSE (
-                   log_parse("  show_frame (sprite)");
-                       );
-                   m_loading_frame++;
-               }
-               else if (_tag_loaders.get(tag_type, &lf))
-               {
-                   // call the tag loader.  The tag loader should add
-                   // characters or tags to the movie data structure.
-                   (*lf)(in, tag_type, this);
-               }
-               else
-               {
-                       // no tag loader for this tag type.
-                    log_error("*** no tag loader for type %d (sprite)",
-                              tag_type);
-               }
-
-               in->close_tag();
-       }
-
-               IF_VERBOSE_PARSE (
-       log_parse("  -- sprite END --");
-               );
-}
-
-/*virtual*/
-void
-sprite_definition::add_frame_name(const char* name)
-{
-       assert((int)m_loading_frame >= 0 && m_loading_frame < m_frame_count);
-
-       tu_string n = name;
-       size_t currently_assigned = 0;
-       if (m_named_frames.get(n, &currently_assigned) == true)
-       {
-               log_error("add_frame_name(%d, '%s') -- frame name "
-                       "already assigned to frame %u; overriding\n",
-                       m_loading_frame,
-                       name, currently_assigned);
-       }
-
-       // stores 0-based frame #
-       m_named_frames[n] = m_loading_frame;
-}
-
-sprite_definition::sprite_definition(movie_definition* m, stream* in)
-       :
-       _tag_loaders(s_tag_loaders),  // FIXME: use a class-static 
TagLoadersTable for sprite_definition
-       m_movie_def(m),
-       m_frame_count(0),
-       m_loading_frame(0)
-{
-       assert(m_movie_def);
-       read(in);
-}
-
-
-
-} // namespace gnash

Index: server/sprite_definition.h
===================================================================
RCS file: server/sprite_definition.h
diff -N server/sprite_definition.h
--- server/sprite_definition.h  14 Aug 2006 23:16:57 -0000      1.16
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,369 +0,0 @@
-// 
-//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
-// 
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-// 
-// This program 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 General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-// Linking Gnash statically or dynamically with other modules is making a
-// combined work based on Gnash. Thus, the terms and conditions of the GNU
-// General Public License cover the whole combination.
-//
-// As a special exception, the copyright holders of Gnash give you
-// permission to combine Gnash with free software programs or libraries
-// that are released under the GNU LGPL and with code included in any
-// release of Talkback distributed by the Mozilla Foundation. You may
-// copy and distribute such a system following the terms of the GNU GPL
-// for all but the LGPL-covered parts and Talkback, and following the
-// LGPL for the LGPL-covered parts.
-//
-// Note that people who make modified versions of Gnash are not obligated
-// to grant this special exception for their modified versions; it is their
-// choice whether to do so. The GNU General Public License gives permission
-// to release a modified version without this exception; this exception
-// also makes it possible to release a modified version which carries
-// forward this exception.
-// 
-//
-
-#ifndef GNASH_SPRITE_DEFINITION_H
-#define GNASH_SPRITE_DEFINITION_H
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <vector>
-
-#include "movie_definition.h"
-#include "stream.h"
-#include "log.h"
-
-namespace gnash
-{
-
-
-/// \brief
-/// Holds the immutable data for a sprite, as read from
-/// as SWF stream.
-/// @@ should *not* derive from movie_definition, probably!
-///
-class sprite_definition : public movie_definition
-{
-
-public:
-
-       /// \brief
-       /// Read the sprite info from input stream.
-       //
-       /// A sprite definition consists of a series control tags.
-       ///
-       /// @param m
-       ///     the Top-Level movie_definition this sprite is read
-       ///     from (not a sprite_definition!)
-       ///
-       /// @param in
-       ///     The stream associated with the sprite. It is assumed
-       ///     to be already positioned right before the frame count
-       ///         
-       sprite_definition(movie_definition* m, stream* in);
-
-       /// Destructor, releases playlist data
-       ~sprite_definition();
-
-private:
-
-       void read(stream* in);
-
-       /// Tags loader table.
-       //
-       /// TODO: make it a static member, specific to sprite_definition
-       SWF::TagLoadersTable& _tag_loaders;
-
-       /// Top-level movie definition
-       /// (the definition read from SWF stream)
-       movie_definition* m_movie_def;
-
-       /// movie control events for each frame.
-       std::vector<std::vector<execute_tag*> > m_playlist;
-
-       // stores 0-based frame #'s
-       stringi_hash<size_t> m_named_frames;
-
-       size_t m_frame_count;
-
-       size_t m_loading_frame;
-
-       // overloads from movie_definition
-       virtual float   get_width_pixels() const { return 1; }
-       virtual float   get_height_pixels() const { return 1; }
-
-       virtual size_t  get_frame_count() const
-       {
-               return m_frame_count;
-       }
-
-       /// \brief
-       /// Return total bytes of the movie from which this sprite
-       /// has been read.
-       ///
-       virtual size_t get_bytes_total() const
-       {
-               return m_movie_def->get_bytes_total();
-       }
-
-       /// \brief
-       /// Return the number of bytes loaded from the stream of the
-       /// the movie from which this sprite is being read.
-       ///
-       virtual size_t get_bytes_loaded() const
-       {
-               return m_movie_def->get_bytes_loaded();
-       }
-
-       virtual float   get_frame_rate() const { return 
m_movie_def->get_frame_rate(); }
-
-       // Return number of frames loaded (of current sprite)
-       virtual size_t  get_loading_frame() const { return m_loading_frame; }
-
-       virtual int     get_version() const { return 
m_movie_def->get_version(); }
-
-       virtual void add_font(int /*id*/, font* /*ch*/)
-       {
-               log_error("add_font tag appears in sprite tags! "
-                       "Malformed SWF?\n");
-       }
-
-       virtual font* get_font(int id) { return m_movie_def->get_font(id); }
-
-       virtual void set_jpeg_loader(std::auto_ptr<jpeg::input> /*j_in*/)
-       {
-               assert(0);
-       }
-
-       virtual jpeg::input* get_jpeg_loader()
-       {
-               return NULL;
-       }
-
-       virtual bitmap_character_def* get_bitmap_character(int id)
-       {
-               return m_movie_def->get_bitmap_character(id);
-       }
-
-       virtual void add_bitmap_character(int /*id*/,
-                       bitmap_character_def* /*ch*/)
-       {
-               log_error("add_bc appears in sprite tags!"
-                       " Malformed SWF?");
-       }
-
-       virtual sound_sample* get_sound_sample(int id)
-       {
-               return m_movie_def->get_sound_sample(id);
-       }
-
-       virtual void add_sound_sample(int /*id*/, sound_sample* /*sam*/)
-       {
-               log_error("add sam appears in sprite tags!"
-                       " Malformed SWF?");
-       }
-
-       virtual void set_loading_sound_stream_id(int id) { 
-               return m_movie_def->set_loading_sound_stream_id(id);
-       }
-
-       virtual int get_loading_sound_stream_id() { 
-               return m_movie_def->get_loading_sound_stream_id();
-       }
-
-       
-       // @@ would be nicer to not inherit these...
-       virtual create_bitmaps_flag     get_create_bitmaps() const
-       { assert(0); return DO_LOAD_BITMAPS; }
-       virtual create_font_shapes_flag get_create_font_shapes() const
-       { assert(0); return DO_LOAD_FONT_SHAPES; }
-       virtual int     get_bitmap_info_count() const
-       { assert(0); return 0; }
-       virtual bitmap_info*    get_bitmap_info(int /*i*/) const
-       { assert(0); return NULL; }
-       virtual void    add_bitmap_info(bitmap_info* /*bi*/)
-       { assert(0); }
-
-       virtual void export_resource(const tu_string& /*symbol*/,
-                       resource* /*res*/)
-       {
-               log_error("can't export from sprite! Malformed SWF?");
-       }
-
-       virtual smart_ptr<resource> get_exported_resource(const tu_string& sym)
-       {
-               return m_movie_def->get_exported_resource(sym);
-       }
-
-       virtual void add_import(const char* /*source_url*/, int /*id*/,
-                       const char* /*symbol*/)
-       {
-               assert(0);
-       }
-
-       virtual void visit_imported_movies(import_visitor* /*v*/)
-       {
-               assert(0);
-       }
-
-       virtual void resolve_import(const char* /*source_url*/,
-                       movie_definition* /*d*/)
-       {
-               assert(0);
-       }
-
-
-       /// \brief
-       /// Get a character_def from this Sprite's parent
-       /// CharacterDictionary. NOTE that calling this
-       /// method on the leaf Sprite of a movie_definition
-       /// hierarchy will result in a recursive scan of
-       /// all parents until the top-level movie_definition
-       /// (movie_def_impl) is found.
-       ///
-       virtual character_def*  get_character_def(int id)
-       {
-           return m_movie_def->get_character_def(id);
-       }
-
-       /// Calls to this function should only be made when
-       /// an invalid SWF is being read, as it would mean
-       /// that a Definition tag is been found as part of
-       /// a Sprite definition
-       ///
-       virtual void add_character(int /*id*/, character_def* /*ch*/)
-       {
-               log_error("add_character tag appears in sprite tags!"
-                               " Maformed SWF?");
-       }
-
-
-       virtual void generate_font_bitmaps()
-       {
-               assert(0);
-       }
-
-       virtual void output_cached_data(tu_file* /*out*/,
-               const cache_options& /*options*/)
-       {
-           // Nothing to do.
-           return;
-       }
-
-       virtual void    input_cached_data(tu_file* /*in*/)
-       {
-           // Nothing to do.
-           return;
-       }
-
-       virtual movie_interface* create_instance()
-       {
-           return NULL;
-       }
-
-       // Create a (mutable) instance of our definition.  The
-       // instance is created to live (temporarily) on some level on
-       // the parent movie's display list.
-       //
-       // overloads from character_def
-       virtual character* create_character_instance(
-               character* parent, int id);
-
-
-       virtual void    add_execute_tag(execute_tag* c)
-       {
-               m_playlist[m_loading_frame].push_back(c);
-       }
-
-       //virtual void  add_init_action(int sprite_id, execute_tag* c)
-       virtual void    add_init_action(execute_tag* /*c*/)
-       {
-           // Sprite def's should not have do_init_action tags in them!  (@@ 
correct?)
-           log_error("sprite_definition::add_init_action called!  Ignored. 
(Malformed SWF?)\n");
-       }
-
-       /// \brief
-       /// Labels the frame currently being loaded with the
-       /// given name.  A copy of the name string is made and
-       /// kept in this object.
-       ///
-       virtual void    add_frame_name(const char* name);
-
-       /// Returns 0-based frame #
-       bool    get_labeled_frame(const char* label, size_t* frame_number)
-       {
-           return m_named_frames.get(label, frame_number);
-       }
-
-       /// frame_number is 0-based
-       const std::vector<execute_tag*>& get_playlist(size_t frame_number)
-       {
-               return m_playlist[frame_number];
-       }
-
-       // Sprites do not have init actions in their
-       // playlists!  Only the root movie
-       // (movie_def_impl) does (@@ correct?)
-       virtual const std::vector<execute_tag*>* get_init_actions(size_t 
/*frame_number*/)
-       {
-           return NULL;
-       }
-
-       virtual const std::string& get_url() const
-       {
-           return m_movie_def->get_url();
-       }
-
-       /// \brief
-       /// Ensure framenum frames of this sprite 
-       /// have been loaded.
-       ///
-       virtual bool ensure_frame_loaded(size_t framenum)
-       {
-               // TODO: return false on timeout 
-               while ( m_loading_frame < framenum )
-               {
-                       log_msg("sprite_definition: "
-                               "loading of frame %u requested "
-                               "(we are at %u/%u)",
-                               framenum, m_loading_frame, m_frame_count);
-                       // Could this ever happen ?
-                       assert(0);
-               }
-               return true;
-       }
-
-       virtual void load_next_frame_chunk()
-       {
-               /// We load full sprite definitions at once, so
-               /// this function is a no-op. 
-       }
-
-       /// Return the top-level movie definition
-       /// (the definition read from SWF stream)
-       movie_definition* get_movie_definition() {
-               return m_movie_def;
-       }
-
-
-};
-
-
-} // end of namespace gnash
-
-#endif // GNASH_SPRITE_H




reply via email to

[Prev in Thread] Current Thread [Next in Thread]