[SCM] GNU Shockwave Flash (SWF) player branch, upstream, updated. upstream/0.8.9_git20110217-1-g7e47601

Tim Retout diocles at alioth.debian.org
Sun Feb 20 23:21:05 UTC 2011


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Shockwave Flash (SWF) player".

The branch, upstream has been updated
       via  7e47601c6058c9aafb9250f9ea9a05511c154ca9 (commit)
      from  f9dd484694eb30420f2f8a0da54da387f8eb45b5 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
-----------------------------------------------------------------------

Summary of changes:
 libcore/DisplayList.cpp                            |  202 ++++++--------------
 libcore/DisplayList.h                              |   30 ---
 libcore/DisplayObjectContainer.cpp                 |   45 -----
 libcore/DisplayObjectContainer.h                   |   43 ----
 libcore/Font.cpp                                   |   31 ++-
 libcore/TextField.cpp                              |   10 +-
 libcore/asobj/flash/geom/Transform_as.cpp          |    2 +-
 libcore/parser/SWFMovieDefinition.cpp              |    4 +-
 libcore/parser/SWFMovieDefinition.h                |    2 +-
 libcore/parser/movie_definition.h                  |    2 +-
 libcore/parser/sprite_definition.h                 |    2 +-
 libcore/swf/DefineFontTag.cpp                      |   67 +++----
 libcore/swf/TextRecord.cpp                         |    2 +-
 libcore/swf/TextRecord.h                           |   13 +-
 libcore/swf/VideoFrameTag.cpp                      |   28 ++-
 libcore/vm/ASHandlers.cpp                          |   25 ++-
 libmedia/gst/AudioDecoderGst.cpp                   |    1 +
 libmedia/gst/MediaParserGst.cpp                    |   26 +--
 libsound/sdl/sound_handler_sdl.cpp                 |    8 +
 libsound/sdl/sound_handler_sdl.h                   |    3 +
 macros/kde4.m4                                     |    2 +-
 plugin/npapi/plugin.cpp                            |    2 +-
 plugin/npapi/plugin.h                              |    1 -
 testsuite/actionscript.all/TextFieldHTML.as        |    6 +-
 testsuite/misc-ming.all/DragDropTestRunner.cpp     |    2 +-
 testsuite/misc-ming.all/loading/loadMovieTest.c    |   93 +++++++--
 .../misc-ming.all/loading/loadMovieTestRunner.cpp  |  136 +++++++------
 testsuite/misc-ming.all/masks_testrunner.cpp       |    2 +-
 28 files changed, 345 insertions(+), 445 deletions(-)

diff --git a/libcore/DisplayList.cpp b/libcore/DisplayList.cpp
index 6d2a14c..7c7ebb9 100644
--- a/libcore/DisplayList.cpp
+++ b/libcore/DisplayList.cpp
@@ -15,23 +15,26 @@
 //
 // 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
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
-#include "smart_ptr.h" 
 #include "DisplayList.h"
-#include "log.h"
-#include "Renderer.h"
-#include "StringPredicates.h"
-#include "MovieClip.h"
-#include "ObjectURI.h"
 
-#include <typeinfo>
 #include <ostream>
+#include <sstream>
 #include <algorithm>
 #include <stack>
 #include <cassert>
 #include <boost/bind.hpp>
+#include <boost/format.hpp>
+
+#include "smart_ptr.h" 
+#include "log.h"
+#include "Renderer.h"
+#include "StringPredicates.h"
+#include "MovieClip.h"
+#include "ObjectURI.h"
+#include "utility.h"
 
 namespace gnash {
 
@@ -56,50 +59,30 @@ namespace {
 /// Anonymous namespace for generic algorithm functors.
 namespace {
 
-class DepthEquals
+struct DepthEquals : std::binary_function<const DisplayObject*, int, bool>
 {
-public:
-
-    DepthEquals(int depth) : _depth(depth) {}
-
-    bool operator() (const DisplayObject* item) const {
+    bool operator()(const DisplayObject* item, int depth) const {
         if (!item) return false;
-        return item->get_depth() == _depth;
-    }
-
-private:
-    const int _depth;
-};
-
-struct DepthGreaterThan
-{
-    bool operator()(const DisplayObject* a, const DisplayObject* b) const {
-        return a->get_depth() > b->get_depth();
+        return item->get_depth() == depth;
     }
 };
 
-struct DepthLessThan
+struct DepthLessThan : std::binary_function<const DisplayObject*, int, bool>
 {
-    bool operator()(const DisplayObject* a, const DisplayObject* b) const {
-        return a->get_depth() < b->get_depth();
+    bool operator()(const DisplayObject* item, int depth) const {
+        if (!item) return false;
+        return item->get_depth() < depth;
     }
 };
 
-class DepthGreaterOrEqual
+struct DepthGreaterThan : std::binary_function<const DisplayObject*, int, bool>
 {
-public:
-
-    DepthGreaterOrEqual(int depth) : _depth(depth) {}
-
-    bool operator() (const DisplayObject* item) const {
+    bool operator()(const DisplayObject* item, int depth) const {
         if (!item) return false;
-        return item->get_depth() >= _depth;
+        return item->get_depth() > depth;
     }
-private:
-    const int _depth;
 };
 
-
 class NameEquals
 {
 public:
@@ -199,7 +182,7 @@ DisplayList::placeDisplayObject(DisplayObject* ch, int depth)
 
     container_type::iterator it =
         std::find_if( _charsByDepth.begin(), _charsByDepth.end(),
-                DepthGreaterOrEqual(depth));
+                boost::bind(std::not2(DepthLessThan()), _1, depth));
 
     if (it == _charsByDepth.end() || (*it)->get_depth() != depth) {
         // add the new char
@@ -236,7 +219,7 @@ DisplayList::add(DisplayObject* ch, bool replace)
 
     container_type::iterator it =
         std::find_if(_charsByDepth.begin(), _charsByDepth.end(),
-                DepthGreaterOrEqual(depth));
+                boost::bind(std::not2(DepthLessThan()), _1, depth));
 
     if (it == _charsByDepth.end() || (*it)->get_depth() != depth) {
         _charsByDepth.insert(it, ch);
@@ -260,7 +243,7 @@ DisplayList::replaceDisplayObject(DisplayObject* ch, int depth,
 
     container_type::iterator it =
         std::find_if(_charsByDepth.begin(), _charsByDepth.end(),
-            DepthGreaterOrEqual(depth));
+            boost::bind(std::not2(DepthLessThan()), _1, depth));
 
     if (it == _charsByDepth.end() || (*it)->get_depth() != depth) {
         _charsByDepth.insert(it, ch);
@@ -361,7 +344,7 @@ DisplayList::removeDisplayObject(int depth)
     // TODO: optimize to take by-depth order into account
     container_type::iterator it = 
         std::find_if( _charsByDepth.begin(), _charsByDepth.end(),
-            DepthEquals(depth));
+            boost::bind(DepthEquals(), _1, depth));
 
     if (it != _charsByDepth.end()) {
         // Make a copy (before erasing)
@@ -416,7 +399,7 @@ DisplayList::swapDepths(DisplayObject* ch1, int newdepth)
     // upper bound ...
     container_type::iterator it2 =
         std::find_if(_charsByDepth.begin(), _charsByDepth.end(),
-            DepthGreaterOrEqual(newdepth));
+            boost::bind(std::not2(DepthLessThan()), _1, newdepth));
 
     if (it1 == _charsByDepth.end()) {
         log_error("First argument to DisplayList::swapDepth() "
@@ -462,32 +445,6 @@ DisplayList::swapDepths(DisplayObject* ch1, int newdepth)
 
     testInvariant();
 }
-
-DisplayObject*
-DisplayList::removeDisplayObjectAt(int index)
-{
-    container_type::iterator it =
-        std::find_if(_charsByDepth.begin(), _charsByDepth.end(),
-                DepthEquals(index));
-
-    if (it == _charsByDepth.end()) return 0;
-   
-    DisplayObject* obj = *it;
-    _charsByDepth.erase(it);
-    return obj;
-}
-
-void
-DisplayList::removeDisplayObject(DisplayObject* obj)
-{
-    container_type::iterator it = std::find(_charsByDepth.begin(),
-            _charsByDepth.end(), obj);
-    
-    if (it != _charsByDepth.end()) {
-        _charsByDepth.erase(it);
-    }
-}
-
 void
 DisplayList::insertDisplayObject(DisplayObject* obj, int index)
 {
@@ -501,7 +458,7 @@ DisplayList::insertDisplayObject(DisplayObject* obj, int index)
     // Find the first index greater than or equal to the required index
     container_type::iterator it =
         std::find_if(_charsByDepth.begin(), _charsByDepth.end(),
-            DepthGreaterOrEqual(index));
+            boost::bind(std::not2(DepthLessThan()), _1, index));
         
     // Insert the DisplayObject before that position
     _charsByDepth.insert(it, obj);
@@ -516,28 +473,6 @@ DisplayList::insertDisplayObject(DisplayObject* obj, int index)
     testInvariant();
 }
 
-void
-DisplayList::addDisplayObject(DisplayObject* obj)
-{
-    testInvariant();
-
-    assert(!obj->unloaded());
-
-    obj->set_invalidated();
-    if (_charsByDepth.empty()) {
-        obj->set_depth(0);
-    }
-    else {
-        container_type::const_reverse_iterator it = _charsByDepth.rbegin();
-        obj->set_depth((*it)->get_depth() + 1);
-    }
-
-    // Insert the DisplayObject at the end
-    _charsByDepth.insert(_charsByDepth.end(), obj);
-
-    testInvariant();
-}
-
 
 bool
 DisplayList::unload()
@@ -608,6 +543,8 @@ DisplayList::display(Renderer& renderer, const Transform& base)
 {
     testInvariant();
 
+    //log_debug("Displaying list: %s", *this);
+
     std::stack<int> clipDepthStack;
     
     // We only display DisplayObjects which are out of the "removed" zone
@@ -681,28 +618,6 @@ DisplayList::omit_display()
     }
 }
 
-void
-DisplayList::dump() const
-{
-    if (_charsByDepth.empty()) return;
-
-    string_table& st = getStringTable(*getObject(_charsByDepth.front()));
-    ObjectURI::Logger l(st);
-
-    int num=0;
-    for (const_iterator it = _charsByDepth.begin(),
-            endIt = _charsByDepth.end(); it != endIt; ++it) {
-
-        const DisplayObject* dobj = *it;
-        log_debug(_("Item %d(%s) at depth %d (char name %s, type %s)"
-                    "Destroyed: %s, unloaded: %s"),
-            num, dobj, dobj->get_depth(), l.debug(dobj->get_name()), typeName(*dobj),
-            dobj->isDestroyed(), dobj->unloaded());
-        num++;
-    }
-}
-
-
 void 
 DisplayList::add_invalidated_bounds(InvalidatedRanges& ranges, bool force)
 {
@@ -825,12 +740,7 @@ DisplayList::mergeDisplayList(DisplayList& newList)
     iterator itNew = beginNonRemoved(newList._charsByDepth);
 
     iterator itOldEnd = dlistTagsEffectiveZoneEnd(_charsByDepth);
-
-    // There used to be an assertion here that no character in the new list
-    // is at depth 65535 or higher. There's no reason why the tags executed
-    // on the new list shouldn't do this though. Bug #29282 does this.
-    // TODO: check whether we should be ignoring that character.
-    iterator itNewEnd = dlistTagsEffectiveZoneEnd(newList._charsByDepth); 
+    iterator itNewEnd = dlistTagsEffectiveZoneEnd(newList._charsByDepth);
 
     // step1. 
     // starting scanning both lists.
@@ -839,13 +749,13 @@ DisplayList::mergeDisplayList(DisplayList& newList)
         iterator itOldBackup = itOld;
         
         DisplayObject* chOld = *itOldBackup;
-        int depthOld = chOld->get_depth();
+        const int depthOld = chOld->get_depth();
 
         while (itNew != itNewEnd) {
             iterator itNewBackup = itNew;
             
             DisplayObject* chNew = *itNewBackup;
-            int depthNew = chNew->get_depth();
+            const int depthNew = chNew->get_depth();
             
             // depth in old list is occupied, and empty in new list.
             if (depthOld < depthNew) {
@@ -867,7 +777,7 @@ DisplayList::mergeDisplayList(DisplayList& newList)
                 ++itOld;
                 ++itNew;
                 
-                bool is_ratio_compatible = 
+                const bool is_ratio_compatible = 
                     (chOld->get_ratio() == chNew->get_ratio());
 
                 if (!is_ratio_compatible || chOld->isDynamic() ||
@@ -898,9 +808,9 @@ DisplayList::mergeDisplayList(DisplayList& newList)
             }
 
             // depth in old list is empty, but occupied in new list.
-            ++ itNew;
+            ++itNew;
             // add the new DisplayObject to the old list.
-            _charsByDepth.insert(itOldBackup, *itNewBackup );
+            _charsByDepth.insert(itOldBackup, *itNewBackup);
         }
 
         // break if finish scanning the new list
@@ -910,7 +820,7 @@ DisplayList::mergeDisplayList(DisplayList& newList)
     // step2(only required if scanning of new list finished earlier in step1).
     // continue to scan the static zone of the old list.
     // unload remaining DisplayObjects directly.
-    while((itOld != itOldEnd) && ((*itOld)->get_depth() < 0)) {
+    while ((itOld != itOldEnd) && ((*itOld)->get_depth() < 0)) {
 
         DisplayObject* chOld = *itOld;
         itOld = _charsByDepth.erase(itOld);
@@ -930,12 +840,12 @@ DisplayList::mergeDisplayList(DisplayList& newList)
     for (itNew = newList._charsByDepth.begin(); itNew != itNewEnd; ++itNew) {
 
         DisplayObject* chNew = *itNew;
-        int depthNew = chNew->get_depth();
+        const int depthNew = chNew->get_depth();
 
         if (chNew->unloaded()) {
             iterator it =
                 std::find_if(_charsByDepth.begin(), _charsByDepth.end(),
-                    DepthGreaterOrEqual(depthNew));
+                    boost::bind(std::not2(DepthLessThan()), _1, depthNew));
             
             _charsByDepth.insert(it, *itNew);
         }
@@ -989,7 +899,7 @@ DisplayList::reinsertRemovedCharacter(DisplayObject* ch)
     // TODO: optimize this by searching from the end(lowest depth).
     container_type::iterator it =
         std::find_if(_charsByDepth.begin(), _charsByDepth.end(),
-                DepthGreaterOrEqual(newDepth));
+                boost::bind(std::not2(DepthLessThan()), _1, newDepth));
 
     _charsByDepth.insert(it, ch);
 
@@ -1023,7 +933,7 @@ beginNonRemoved(DisplayList::container_type& c)
     const int depth = DisplayObject::removedDepthOffset -
         DisplayObject::staticDepthOffset;
     
-    return std::find_if(c.begin(), c.end(), DepthGreaterOrEqual(depth));
+    return std::find_if(c.begin(), c.end(), boost::bind(std::not2(DepthLessThan()), _1, depth));
 }
 
 DisplayList::const_iterator
@@ -1032,14 +942,16 @@ beginNonRemoved(const DisplayList::container_type& c)
     const int depth = DisplayObject::removedDepthOffset -
         DisplayObject::staticDepthOffset;
 
-    return std::find_if(c.begin(), c.end(), DepthGreaterOrEqual(depth));
+    return std::find_if(c.begin(), c.end(), 
+            boost::bind(std::not2(DepthLessThan()), _1, depth));
 }
 
 DisplayList::iterator
 dlistTagsEffectiveZoneEnd(DisplayList::container_type& c)
 {
     return std::find_if(c.begin(), c.end(), 
-             DepthGreaterOrEqual(0xffff + DisplayObject::staticDepthOffset));
+            boost::bind(DepthGreaterThan(), _1,
+                0xffff + DisplayObject::staticDepthOffset));
 }
 
 } // anonymous namespace
@@ -1048,20 +960,28 @@ dlistTagsEffectiveZoneEnd(DisplayList::container_type& c)
 std::ostream&
 operator<<(std::ostream& os, const DisplayList& dl)
 {
-    os << "By depth: ";
+    if (dl._charsByDepth.empty()) return os << "Empty DisplayList";
 
-    if (dl._charsByDepth.empty()) return os;
+    os << "DisplayList size " << dl._charsByDepth.size() << "\n";
 
-    string_table& st = getStringTable(*getObject(dl._charsByDepth.front()));
-    ObjectURI::Logger l(st);
+    size_t count = 0;
 
     for (DisplayList::const_iterator it = dl._charsByDepth.begin(),
-            itEnd = dl._charsByDepth.end(); it != itEnd; ++it) {
+            itEnd = dl._charsByDepth.end(); it != itEnd; ++it, ++count) {
+
+        const DisplayObject* dobj = *it;
 
-        const DisplayObject* item = *it; 
-        if (it != dl._charsByDepth.begin()) os << " | ";
-        os << " name:" << l.debug(item->get_name())
-           << " depth:" << item->get_depth();
+        boost::format fmt = boost::format(
+            "Item %1% (%2%) at depth %3% (type %4%) "
+            "Destroyed: %5%, unloaded: %6%")
+            % count 
+            % dobj 
+            % dobj->get_depth() 
+            % typeName(*dobj)
+            % boost::io::group(std::boolalpha, dobj->isDestroyed())
+            % boost::io::group(std::boolalpha, dobj->unloaded());
+
+        os << fmt.str() << std::endl;
     }
 
     return os;
diff --git a/libcore/DisplayList.h b/libcore/DisplayList.h
index 3cdfe77..78f68b4 100644
--- a/libcore/DisplayList.h
+++ b/libcore/DisplayList.h
@@ -195,23 +195,6 @@ public:
 	///	pre-existing DisplayObject at the same depth.
 	void add(DisplayObject* ch, bool replace);
 
-    /// Removes the specified DisplayObject
-    //
-    /// Other DisplayObjects are left untouched.
-    /// This implements AS3 DisplayObjectContainer.removeChild().
-    //
-    /// @param obj      The DisplayObject to remove.
-    void removeDisplayObject(DisplayObject* obj);
-
-    /// Removes the DisplayObject at the specified index
-    //
-    /// Other DisplayObjects are left untouched.
-    /// This implements AS3 DisplayObjectContainer.removeChildAt().
-    //
-    /// @param index    The index from which to remove the DisplayObject.
-    /// @return         The DisplayObject removed, or 0 if none was removed.
-    DisplayObject* removeDisplayObjectAt(int index);
-
     /// Inserts a DisplayObject at the specified index (depth)
     //
     /// If a DisplayObject is already at that index, it is moved up.
@@ -224,16 +207,6 @@ public:
     /// @param index    The index at which to insert the DisplayObject.
     void insertDisplayObject(DisplayObject* obj, int index);
 
-    /// Adds a DisplayObject at the top of the DisplayList.
-    //
-    /// This implements AS3 DisplayObjectContainer.addChild().
-    //
-    /// @param obj      The DisplayObject to insert. This should already be
-    ///                 removed from any other DisplayLists. It should not be
-    ///                 the owner of this DisplayList or any parent of that
-    ///                 owner.
-    void addDisplayObject(DisplayObject* obj);
-
 	/// Display the list's DisplayObjects.
     //
 	/// Lower depths are obscured by higher depths.
@@ -288,9 +261,6 @@ public:
 	template <class V> inline void visitAll(V& visitor);
 	template <class V> inline void visitAll(V& visitor) const;
 
-	/// dump list to logfile/stderr
-	void dump() const;
-
     /// Like DisplayObject_instance::add_invalidated_bounds() this method calls the
     /// method with the same name of all childs.	
 	void add_invalidated_bounds(InvalidatedRanges& ranges, bool force);	
diff --git a/libcore/DisplayObjectContainer.cpp b/libcore/DisplayObjectContainer.cpp
index d851b5d..17157f5 100644
--- a/libcore/DisplayObjectContainer.cpp
+++ b/libcore/DisplayObjectContainer.cpp
@@ -37,51 +37,6 @@ DisplayObjectContainer::~DisplayObjectContainer()
 {
 }
 
-DisplayObject*
-DisplayObjectContainer::removeChild(DisplayObject* obj)
-{
-    _displayList.removeDisplayObject(obj);
-    obj->set_parent(0);
-    return obj;
-}
-
-DisplayObject*
-DisplayObjectContainer::removeChildAt(int index)
-{
-    DisplayObject* obj = _displayList.removeDisplayObjectAt(index);
-    if (obj) obj->set_parent(0);
-
-    return obj;
-}
-
-DisplayObject*
-DisplayObjectContainer::addChild(DisplayObject* obj)
-{
-    // TODO: parent should be a DisplayObjectContainer; remove dynamic_cast.
-    DisplayObjectContainer* parent =
-        dynamic_cast<DisplayObjectContainer*>(obj->parent());
-    if (parent) parent->removeChild(obj);
-
-    _displayList.addDisplayObject(obj);
-    obj->set_parent(this);
-    return obj;
-}
-
-
-DisplayObject*
-DisplayObjectContainer::addChildAt(DisplayObject* obj, int index)
-{
-    // TODO: parent should be a DisplayObjectContainer; remove dynamic_cast.
-    DisplayObjectContainer* parent =
-        dynamic_cast<DisplayObjectContainer*>(obj->parent());
-    if (parent) parent->removeChild(obj);
-    
-    _displayList.insertDisplayObject(obj, index);
-    obj->set_parent(this);
-    return obj;
-}
-
-
 #ifdef USE_SWFTREE
 
 namespace {
diff --git a/libcore/DisplayObjectContainer.h b/libcore/DisplayObjectContainer.h
index 62087f3..f5dd164 100644
--- a/libcore/DisplayObjectContainer.h
+++ b/libcore/DisplayObjectContainer.h
@@ -53,49 +53,6 @@ public:
 
     virtual ~DisplayObjectContainer();
 
-    /// Remove the DisplayObject at the specified depth.
-    //
-    /// This is the implementation of the AS3-only method
-    /// DisplayObjectContainer.removeChildAt().
-    //
-    /// @param index    The depth from which to remove a DisplayObject.
-    /// @return         The removed DisplayObject (reflects the AS return)
-    DisplayObject* removeChildAt(int index);
-    
-    /// Remove the specified child DisplayObject.
-    //
-    /// TODO: should be a function of DisplayObjectContainer
-    /// This is the implementation of the AS3-only method
-    /// DisplayObjectContainer.removeChild(), but can also be used for
-    /// AS2.
-    //
-    /// @param obj      The DisplayObject to remove.
-    /// @return         The removed DisplayObject (reflects the AS return)
-    DisplayObject* removeChild(DisplayObject* obj);
-    
-    /// Add a child DisplayObject at the next suitable index (AS2: depth).
-    //
-    /// TODO: should be a function of DisplayObjectContainer
-    /// This is the implementation of the AS3-only method
-    /// DisplayObjectContainer.addChild(), but can also be used for
-    /// AS2.
-    //
-    /// @param obj      The DisplayObject to add.
-    /// @return         The added DisplayObject (reflects the AS return)
-    DisplayObject* addChild(DisplayObject* obj);
-
-    /// Add a child DisplayObject at the specified index (AS2: depth).
-    //
-    /// TODO: should be a function of DisplayObjectContainer
-    /// This is the implementation of the AS3-only method
-    /// DisplayObjectContainer.addChild(), but can also be used for
-    /// AS2.
-    //
-    /// @param obj      The DisplayObject to add.
-    /// @param index    The index (depth) at which to add the DisplayObject.
-    /// @return         The added DisplayObject (reflects the AS return)
-    DisplayObject* addChildAt(DisplayObject* obj, int index);
-
     size_t numChildren() const {
         return _displayList.size();
     }
diff --git a/libcore/Font.cpp b/libcore/Font.cpp
index fd55ac8..1be16a5 100644
--- a/libcore/Font.cpp
+++ b/libcore/Font.cpp
@@ -21,16 +21,17 @@
 
 // Based on the public domain work of Thatcher Ulrich <tu at tulrich.com> 2003
 
-#include "smart_ptr.h" 
 #include "Font.h"
+
+#include <utility> 
+#include <memory>
+
+#include "smart_ptr.h" 
 #include "log.h"
 #include "ShapeRecord.h"
 #include "DefineFontTag.h"
 #include "FreetypeGlyphsProvider.h"
 
-#include <utility> // for std::make_pair
-#include <memory>
-
 namespace gnash {
 
 namespace {
@@ -44,12 +45,12 @@ class CodeLookup
 public:
     CodeLookup(const int glyph) : _glyph(glyph) {}
 
-    bool operator()(const std::pair<const boost::uint16_t, int>& p) {
+    bool operator()(const std::pair<const boost::uint16_t, int>& p) const {
         return p.second == _glyph;
     }
 
 private:
-    int _glyph;
+    const int _glyph;
 };
 
 }
@@ -83,7 +84,9 @@ Font::Font(std::auto_ptr<SWF::DefineFontTag> ft)
     _italic(_fontTag->italic()),
     _bold(_fontTag->bold())
 {
-    if (_fontTag->hasCodeTable()) _embeddedCodeTable = _fontTag->getCodeTable();
+    if (_fontTag->hasCodeTable()) {
+        _embeddedCodeTable = _fontTag->getCodeTable();
+    }
 }
 
 Font::Font(const std::string& name, bool bold, bool italic)
@@ -160,8 +163,7 @@ Font::setFlags(boost::uint8_t flags)
 void
 Font::setCodeTable(std::auto_ptr<CodeTable> table)
 {
-    if (_embeddedCodeTable)
-    {
+    if (_embeddedCodeTable) {
         IF_VERBOSE_MALFORMED_SWF(
             log_swferror(_("Attempt to add an embedded glyph CodeTable to "
                     "a font that already has one. This should mean there "
@@ -191,7 +193,16 @@ Font::codeTableLookup(int glyph, bool embedded) const
     
     CodeTable::const_iterator it = std::find_if(ctable.begin(), ctable.end(),
             CodeLookup(glyph));
-    assert (it != ctable.end());
+
+    if (it == ctable.end()) {
+        // NB: this occurs with a long and complex SWF (bug #32537)
+        // that defines the same font twice and ends up with a glyph
+        // table shorter than the number of glyphs. We don't know
+        // whether it's a SWF or a Gnash bug.
+        log_error("Failed to find glyph %s in %s font %s",
+                glyph, embedded ? "embedded" : "device", _name);
+        return 0;
+    }
     return it->first;
 }
 
diff --git a/libcore/TextField.cpp b/libcore/TextField.cpp
index c51d482..b4a2b2b 100644
--- a/libcore/TextField.cpp
+++ b/libcore/TextField.cpp
@@ -1426,7 +1426,7 @@ TextField::handleChar(std::wstring::const_iterator& it,
                         }
                         else if (s == "B") {
                             //bold
-                            Font* boldfont = new Font(rec.getFont()->name(),
+                            boost::intrusive_ptr<Font> boldfont = new Font(rec.getFont()->name(),
                                     true, rec.getFont()->isItalic());
                             newrec.setFont(boldfont);
                             handleChar(it, e, x, y, newrec, last_code,
@@ -1457,10 +1457,12 @@ TextField::handleChar(std::wstring::const_iterator& it,
                             attloc = attributes.find("FACE");
                             if (attloc != attributes.end()) {
                                 if (attloc->second.empty()) {
-                                    log_error("Expected a font name in FACE attribute.");
+                                    IF_VERBOSE_ASCODING_ERRORS(
+                                         log_aserror(_("Expected a font name in FACE attribute."))
+                                    );
                                 } else {
                                     //font FACE attribute
-                                    Font* newfont = new Font(attloc->second,
+                                    boost::intrusive_ptr<Font> newfont = new Font(attloc->second,
                                         rec.getFont()->isBold(), rec.getFont()->isItalic());
                                     newrec.setFont(newfont);
                                 }
@@ -1514,7 +1516,7 @@ TextField::handleChar(std::wstring::const_iterator& it,
                         }
                         else if (s == "I") {
                             //italic
-                            Font* italicfont = new Font(rec.getFont()->name(),
+                            boost::intrusive_ptr<Font> italicfont = new Font(rec.getFont()->name(),
                                     rec.getFont()->isBold(), true);
                             newrec.setFont(italicfont);
                             handleChar(it, e, x, y, newrec, last_code,
diff --git a/libcore/asobj/flash/geom/Transform_as.cpp b/libcore/asobj/flash/geom/Transform_as.cpp
index 48c8eb8..44799d6 100644
--- a/libcore/asobj/flash/geom/Transform_as.cpp
+++ b/libcore/asobj/flash/geom/Transform_as.cpp
@@ -79,7 +79,7 @@ public:
 
 protected:
 
-    virtual void markReachableResources() const {
+    virtual void setReachable() {
         _movieClip.setReachable();
     }
 
diff --git a/libcore/parser/SWFMovieDefinition.cpp b/libcore/parser/SWFMovieDefinition.cpp
index 52e65e7..376b772 100644
--- a/libcore/parser/SWFMovieDefinition.cpp
+++ b/libcore/parser/SWFMovieDefinition.cpp
@@ -190,10 +190,10 @@ SWFMovieDefinition::getDefinitionTag(boost::uint16_t id) const
 }
 
 void
-SWFMovieDefinition::add_font(int font_id, Font* f)
+SWFMovieDefinition::add_font(int font_id, boost::intrusive_ptr<Font> f)
 {
     assert(f);
-    m_fonts.insert(std::make_pair(font_id, boost::intrusive_ptr<Font>(f)));
+    m_fonts.insert(std::make_pair(font_id, f));
 }
 
 Font*
diff --git a/libcore/parser/SWFMovieDefinition.h b/libcore/parser/SWFMovieDefinition.h
index 6e6e40f..8c47c1d 100644
--- a/libcore/parser/SWFMovieDefinition.h
+++ b/libcore/parser/SWFMovieDefinition.h
@@ -252,7 +252,7 @@ public:
     bool get_labeled_frame(const std::string& label, size_t& frame_number)
         const;
 
-    void add_font(int font_id, Font* f);
+    void add_font(int font_id, boost::intrusive_ptr<Font> f);
 
     Font* get_font(int font_id) const;
 
diff --git a/libcore/parser/movie_definition.h b/libcore/parser/movie_definition.h
index 50d720e..c829c6e 100644
--- a/libcore/parser/movie_definition.h
+++ b/libcore/parser/movie_definition.h
@@ -251,7 +251,7 @@ public:
 	/// This method is here to be called by DEFINEFONT tags loaders.
 	/// The default implementation does nothing.
 	///
-	virtual void add_font(int /*id*/, Font* /*ch*/)
+	virtual void add_font(int /*id*/, boost::intrusive_ptr<Font> /*ch*/)
 	{
 	}
 
diff --git a/libcore/parser/sprite_definition.h b/libcore/parser/sprite_definition.h
index eaf40d4..8be5d3a 100644
--- a/libcore/parser/sprite_definition.h
+++ b/libcore/parser/sprite_definition.h
@@ -140,7 +140,7 @@ public:
 	}
 
 	/// Overridden just for complaining  about malformed SWF
-	virtual void add_font(int /*id*/, Font* /*ch*/)
+	virtual void add_font(int /*id*/, boost::intrusive_ptr<Font> /*ch*/)
 	{
 		IF_VERBOSE_MALFORMED_SWF (
 		log_swferror(_("add_font tag appears in sprite tags"));
diff --git a/libcore/swf/DefineFontTag.cpp b/libcore/swf/DefineFontTag.cpp
index dd097b8..ec670e2 100644
--- a/libcore/swf/DefineFontTag.cpp
+++ b/libcore/swf/DefineFontTag.cpp
@@ -48,11 +48,9 @@ DefineFontTag::loader(SWFStream& in, TagType tag, movie_definition& m,
     const boost::uint16_t fontID = in.read_u16();
 
     std::auto_ptr<DefineFontTag> ft(new DefineFontTag(in, m, tag, r));
-
-    Font* f = new Font(ft);
+    boost::intrusive_ptr<Font> f(new Font(ft));
 
     m.add_font(fontID, f);
-
 }
 
 void
@@ -60,7 +58,8 @@ DefineFontTag::readCodeTable(SWFStream& in, Font::CodeTable& table,
         bool wideCodes, size_t glyphCount)
 {
     IF_VERBOSE_PARSE(
-        log_parse(_("reading code table at offset %lu"), in.tell());
+        log_parse(_("reading code table at offset %1%, "
+                "%2% glyphs"), in.tell(), glyphCount);
     );
 
     // Good. We can only do this once.
@@ -70,7 +69,7 @@ DefineFontTag::readCodeTable(SWFStream& in, Font::CodeTable& table,
         in.ensureBytes(2 * glyphCount);
         // Code table is made of boost::uint16_t's.
         for (size_t i=0; i < glyphCount; ++i) {
-            boost::uint16_t code = in.read_u16();
+            const boost::uint16_t code = in.read_u16();
             table.insert(std::make_pair(code, i));
         }
     }
@@ -78,7 +77,7 @@ DefineFontTag::readCodeTable(SWFStream& in, Font::CodeTable& table,
         // Code table is made of bytes.
         in.ensureBytes(1 * glyphCount);
         for (size_t i = 0; i < glyphCount; ++i) {
-            boost::uint8_t code = in.read_u8();
+            const boost::uint8_t code = in.read_u8();
             table.insert(std::make_pair(code, i));
         }
     }
@@ -132,32 +131,25 @@ DefineFontTag::readDefineFont(SWFStream& in, movie_definition& m,
     offsets.push_back(in.read_u16());
 
     IF_VERBOSE_PARSE (
-    log_parse("offset[0] = %d", offsets[0]);
+        log_parse("offset[0] = %d", offsets[0]);
     );
 
-    int	count = offsets[0] >> 1;
-    if ( count > 0 )
-    {
+    const size_t count = offsets[0] >> 1;
+    if (count > 0) {
         in.ensureBytes(count*2);
-        for (int i = 1; i < count; i++)
-        {
+        for (size_t i = 1; i < count; ++i) {
             offsets.push_back(in.read_u16());
 
             IF_VERBOSE_PARSE (
-            log_parse("offset[%d] = %d", i, offsets[i]);
+                log_parse("offset[%d] = %d", i, offsets[i]);
             );
         }
     }
-    else
-    {
-        log_error("Negative embedded glyph table size: %d", count);
-    }
 
     _glyphTable.resize(count);
 
     // Read the glyph shapes.
-    for (int i = 0; i < count; i++)
-    {
+    for (size_t i = 0; i < count; ++i) {
         // Seek to the start of the shape data.
         unsigned long new_pos = table_base + offsets[i];
 
@@ -177,23 +169,23 @@ void
 DefineFontTag::readDefineFont2Or3(SWFStream& in, movie_definition& m,
         const RunResources& r)
 {
-    IF_VERBOSE_PARSE (
-    log_parse(_("reading DefineFont2 or DefineFont3"));
+    IF_VERBOSE_PARSE(
+        log_parse(_("reading DefineFont2 or DefineFont3"));
     );
 
     in.ensureBytes(2); // 1 for the flags, 1 unknown
-    int flags = in.read_u8();
-    bool has_layout = flags & (1 << 7);
+    const int flags = in.read_u8();
+    const bool has_layout = flags & (1 << 7);
     _shiftJISChars = flags & (1 << 6);
     _unicodeChars = flags & (1 << 5);
     _ansiChars = flags & (1 << 4);
-    bool wide_offsets = flags & (1 << 3);
-    bool wideCodes = flags & (1 << 2);
+    const bool wide_offsets = flags & (1 << 3);
+    const bool wideCodes = flags & (1 << 2);
     _italic = flags & (1 << 1);
     _bold = flags & (1 << 0);
 
     // Next is language code, always 0 for SWF5 or previous
-    int languageCode = in.read_u8();
+    const int languageCode = in.read_u8();
     if (languageCode) {
         LOG_ONCE(log_unimpl("LanguageCode (%d) in DefineFont tag",
                     languageCode));
@@ -202,7 +194,7 @@ DefineFontTag::readDefineFont2Or3(SWFStream& in, movie_definition& m,
     in.read_string_with_length(_name);
 
     in.ensureBytes(2); 
-    boost::uint16_t glyph_count = in.read_u16();
+    const boost::uint16_t glyph_count = in.read_u16();
 
     IF_VERBOSE_PARSE (
         log_parse(" has_layout = %d", has_layout);
@@ -217,7 +209,7 @@ DefineFontTag::readDefineFont2Or3(SWFStream& in, movie_definition& m,
         log_parse(" glyphs count = %d", glyph_count);
     );
     
-    unsigned long table_base = in.tell();
+    const unsigned long table_base = in.tell();
 
     // Read the glyph offsets.  Offsets
     // are measured from the start of the
@@ -228,14 +220,11 @@ DefineFontTag::readDefineFont2Or3(SWFStream& in, movie_definition& m,
     if (wide_offsets) {
         // 32-bit offsets.
         in.ensureBytes(4*glyph_count + 4); 
-        for (size_t i = 0; i < glyph_count; ++i)
-        {
+        for (size_t i = 0; i < glyph_count; ++i) {
             const boost::uint32_t off = in.read_u32();	
-
             IF_VERBOSE_PARSE (
                 log_parse(_("Glyph %d at offset %u"), i, off);
             );
-
             offsets.push_back(off);
         }
         font_code_offset = in.read_u32();
@@ -244,13 +233,10 @@ DefineFontTag::readDefineFont2Or3(SWFStream& in, movie_definition& m,
         // 16-bit offsets.
         in.ensureBytes(2*glyph_count + 2); 
         for (size_t i = 0; i < glyph_count; ++i) {
-
             const boost::uint16_t off = in.read_u16();	
-
-            IF_VERBOSE_PARSE (
+            IF_VERBOSE_PARSE(
                 log_parse(_("Glyph %d at offset %u"), i, off);
             );
-
             offsets.push_back(off);
         }
         font_code_offset = in.read_u16();
@@ -274,9 +260,8 @@ DefineFontTag::readDefineFont2Or3(SWFStream& in, movie_definition& m,
         _glyphTable[i].glyph.reset(new ShapeRecord(in, SWF::DEFINEFONT2, m, r));
     }
 
-    unsigned long current_position = in.tell();
-    if (font_code_offset + table_base != current_position)
-    {
+    const unsigned long current_position = in.tell();
+    if (font_code_offset + table_base != current_position) {
         // Bad offset!  Don't try to read any more.
         IF_VERBOSE_MALFORMED_SWF(
             log_swferror(_("Bad offset in DefineFont2"));
@@ -297,7 +282,7 @@ DefineFontTag::readDefineFont2Or3(SWFStream& in, movie_definition& m,
         _leading = in.read_s16();
         
         // Advance table; i.e. how wide each DisplayObject is.
-        size_t nGlyphs = _glyphTable.size();
+        const size_t nGlyphs = _glyphTable.size();
         in.ensureBytes(nGlyphs*2);
 
         for (size_t i = 0; i < nGlyphs; i++) {
@@ -307,7 +292,6 @@ DefineFontTag::readDefineFont2Or3(SWFStream& in, movie_definition& m,
             _glyphTable[i].advance = static_cast<float>(in.read_u16());
         }
 
-        // TODO: shouldn't we log_unimpl here ??
         for (size_t i = 0; i < nGlyphs; i++) {
             LOG_ONCE(log_unimpl("Bounds table in DefineFont2Tag"));
             readRect(in);
@@ -342,7 +326,6 @@ DefineFontTag::readDefineFont2Or3(SWFStream& in, movie_definition& m,
                     log_swferror(_("Repeated kerning pair found - ignoring"));
                 );
             }
-
         }
     }
 }
diff --git a/libcore/swf/TextRecord.cpp b/libcore/swf/TextRecord.cpp
index d4cdd18..ca85dee 100644
--- a/libcore/swf/TextRecord.cpp
+++ b/libcore/swf/TextRecord.cpp
@@ -77,7 +77,7 @@ TextRecord::read(SWFStream& in, movie_definition& m, int glyphBits,
         {
             IF_VERBOSE_PARSE(
                 log_parse(_("  has_font: font id = %d (%p)"), fontID,
-                    (void*)_font);
+                    _font.get());
             );
         } 
     }
diff --git a/libcore/swf/TextRecord.h b/libcore/swf/TextRecord.h
index 730a21a..89d07ec 100644
--- a/libcore/swf/TextRecord.h
+++ b/libcore/swf/TextRecord.h
@@ -19,10 +19,13 @@
 #ifndef GNASH_SWF_TEXTRECORD_H
 #define GNASH_SWF_TEXTRECORD_H
 
-#include "RGBA.h"
-#include "SWF.h"
 #include <string>
 #include <vector>
+#include <boost/intrusive_ptr.hpp>
+
+#include "RGBA.h"
+#include "SWF.h"
+#include "Font.h"
 
 namespace gnash {
     class movie_definition;
@@ -107,7 +110,7 @@ public:
     }
 
     // TODO: check font properly.
-    void setFont(const Font* f) {
+    void setFont(boost::intrusive_ptr<const Font> f) {
         _font = f;
     }
 
@@ -128,7 +131,7 @@ public:
 	}
 	
     const Font* getFont() const {
-        return _font;
+        return _font.get();
     }
 
     void setTextHeight(boost::uint16_t height) {
@@ -213,7 +216,7 @@ private:
     float _yOffset;
 
     /// The font associated with the TextRecord. Can be NULL.
-    const Font* _font;
+    boost::intrusive_ptr<const Font> _font;
 
 	std::string _htmlURL;
 	std::string _htmlTarget;
diff --git a/libcore/swf/VideoFrameTag.cpp b/libcore/swf/VideoFrameTag.cpp
index 0f10556..de433d8 100644
--- a/libcore/swf/VideoFrameTag.cpp
+++ b/libcore/swf/VideoFrameTag.cpp
@@ -61,20 +61,30 @@ VideoFrameTag::loader(SWFStream& in, SWF::TagType tag, movie_definition& m,
         return;
     }
 
-	// TODO: skip if there's no MediaHandler registered ?
+    // TODO: skip if there's no MediaHandler registered ?
 
     const unsigned short padding = 8;
 
-	in.ensureBytes(2);
-	unsigned int frameNum = in.read_u16(); 
+    in.ensureBytes(3);
+    unsigned int frameNum = in.read_u16();
+
+    const media::VideoInfo* info = vs->getVideoInfo();
+
+    if (info && info->codec == media::VIDEO_CODEC_SCREENVIDEO) {
+        // According to swfdec, every SV frame comes with keyframe
+        // and format identifiers (4 bits each), but these are not
+        // part of the codec bitstream and break the decoder.
+        (void) in.read_u8();
+    }
+
 	
-	const unsigned int dataLength = in.get_tag_end_position() - in.tell();
+    const unsigned int dataLength = in.get_tag_end_position() - in.tell();
 
     // FIXME: catch bad_alloc
-	boost::uint8_t* buffer = new boost::uint8_t[dataLength + padding]; 
+    boost::uint8_t* buffer = new boost::uint8_t[dataLength + padding]; 
 
-	const size_t bytesRead = in.read(reinterpret_cast<char*>(buffer),
-            dataLength);
+    const size_t bytesRead = in.read(reinterpret_cast<char*>(buffer),
+                                     dataLength);
 
     if (bytesRead < dataLength)
     {
@@ -85,12 +95,12 @@ VideoFrameTag::loader(SWFStream& in, SWF::TagType tag, movie_definition& m,
 	
     std::fill_n(buffer + bytesRead, padding, 0);
 
-	using namespace media;
+    using namespace media;
 
     std::auto_ptr<EncodedVideoFrame> frame(
             new EncodedVideoFrame(buffer, dataLength, frameNum));
 
-	vs->addVideoFrameTag(frame);
+    vs->addVideoFrameTag(frame);
 }
 
 } // namespace SWF
diff --git a/libcore/vm/ASHandlers.cpp b/libcore/vm/ASHandlers.cpp
index 805ff20..1815f5e 100644
--- a/libcore/vm/ASHandlers.cpp
+++ b/libcore/vm/ASHandlers.cpp
@@ -3546,7 +3546,7 @@ commonGetURL(as_environment& env, as_value target,
             target_string, url, static_cast<int>(method),
             sendVarsMethod, loadTargetFlag, loadVariableFlag);
 
-    DisplayObject* target_ch = findTarget(env, target.to_string());
+    DisplayObject* target_ch = findTarget(env, target_string);
     MovieClip* target_movie = target_ch ? target_ch->to_movie() : 0;
 
     if (loadVariableFlag) {
@@ -3618,13 +3618,28 @@ commonGetURL(as_environment& env, as_value target,
 
         const std::string s = target_movie->getTarget(); // or getOrigTarget ?
         if (s != target_movie->getOrigTarget()) {
-            log_debug(_("TESTME: target of a loadMovie changed its target "
-                        "path"));
+            log_debug("TESTME: target of a loadMovie changed its target path");
         }
         
-        // TODO: try to trigger this !
-        assert(m.findCharacterByTarget(s) == target_movie);
+        // To trigger: https://savannah.gnu.org/bugs/?32506
+        if ( m.findCharacterByTarget(s) != target_movie ) {
+            log_error("FIXME: "
+                "getURL target %1% is resolved by findTarget(env) "
+                "to sprite %2%. Sprite %2% has "
+                "target %3%. Target %3% will be resolved "
+                "by movie_root::findCharacterByTarget() to %4%",
+                target_string, target_movie, s,
+                m.findCharacterByTarget(s));
+        }
 
+        // We might probably use target_string here rather than
+        // ``s'' (which is the _official_ target) but at time   
+        // of writing the MovieLoader will use
+        // movie_root::findCharacterByTarget to resolve paths,
+        // and that one, in turn, won't support /slash/notation
+        // which may be found in target_string (see also loadMovieTest.swf
+        // under misc-ming.all)
+        //
         m.loadMovie(url, s, varsToSend, sendVarsMethod); 
         return;
     }
diff --git a/libmedia/gst/AudioDecoderGst.cpp b/libmedia/gst/AudioDecoderGst.cpp
index 25f52c2..110a33d 100644
--- a/libmedia/gst/AudioDecoderGst.cpp
+++ b/libmedia/gst/AudioDecoderGst.cpp
@@ -113,6 +113,7 @@ AudioDecoderGst::AudioDecoderGst(const AudioInfo& info)
         throw MediaException(err.str());
     }
 
+    gst_caps_ref(extraaudioinfo->caps);
     setup(extraaudioinfo->caps);
 }
 
diff --git a/libmedia/gst/MediaParserGst.cpp b/libmedia/gst/MediaParserGst.cpp
index ce6441a..2778ae2 100644
--- a/libmedia/gst/MediaParserGst.cpp
+++ b/libmedia/gst/MediaParserGst.cpp
@@ -74,7 +74,7 @@ MediaParserGst::MediaParserGst(std::auto_ptr<IOChannel> stream)
     SimpleTimer timer;
 
     size_t counter = 0;
-    while (!probingConditionsMet(timer)) {
+    while (!probingConditionsMet(timer) && !_stream->eof() && !_stream->bad()) {
 
         if (!pushGstBuffer()) {
             ++counter;
@@ -141,7 +141,7 @@ MediaParserGst::parseNextChunk()
 
     // FIXME: our caller check for _parsingComplete prior
     //        to call parseNextChunk
-    if (_stream->eof()) {
+    if (_stream->eof() || _stream->bad()) {
         //log_debug (_("Stream EOF, emitting!"));
         _parsingComplete = true;
         return false;
@@ -174,24 +174,18 @@ MediaParserGst::pushGstBuffer()
 
     std::streamoff ret = _stream->read(GST_BUFFER_DATA(buffer), PUSHBUF_SIZE);
 
-    if (ret == 0) {
-        if (!_stream->eof()) {
-            log_error(_("MediaParserGst failed to read the stream, but did not "
-                      "reach EOF!"));
+    if (ret < PUSHBUF_SIZE) {
+        if (!_stream->eof() && !_stream->bad()) {
+            log_error(_("MediaParserGst failed to read the stream, but it did"
+                      " not reach EOF or enter a bad state."));
         } else {
             _parsingComplete = true;
         }
-        gst_buffer_unref(buffer);
-        return false;
-    }
 
-    if (ret < PUSHBUF_SIZE) {
-        if (!_stream->eof()) {
-            log_error(_("MediaParserGst failed to read the stream, but did not "
-                      "reach EOF!"));
-        } else {
-            _parsingComplete = true;
-        }       
+        if (!ret) {
+            gst_buffer_unref(buffer);
+            return false;
+        }
 
         GST_BUFFER_SIZE(buffer) = ret;
     }
diff --git a/libsound/sdl/sound_handler_sdl.cpp b/libsound/sdl/sound_handler_sdl.cpp
index 80af7d6..5081467 100644
--- a/libsound/sdl/sound_handler_sdl.cpp
+++ b/libsound/sdl/sound_handler_sdl.cpp
@@ -338,6 +338,14 @@ SDL_sound_handler::unpause()
     sound_handler::unpause();
 }
 
+void
+SDL_sound_handler::unplugInputStream(InputStream* id)
+{
+    boost::mutex::scoped_lock lock(_mutex);
+
+    sound_handler::unplugInputStream(id);
+}
+
 } // gnash.sound namespace 
 } // namespace gnash
 
diff --git a/libsound/sdl/sound_handler_sdl.h b/libsound/sdl/sound_handler_sdl.h
index b0f060b..b7bf867 100644
--- a/libsound/sdl/sound_handler_sdl.h
+++ b/libsound/sdl/sound_handler_sdl.h
@@ -153,6 +153,9 @@ public:
     // Overridden to unpause SDL audio
     void plugInputStream(std::auto_ptr<InputStream> in);
 
+    // Overidden to provide thread safety.
+    void unplugInputStream(InputStream* id);
+
     // See dox in sound_handler.h
     void fetchSamples(boost::int16_t* to, unsigned int nSamples);
 };
diff --git a/macros/kde4.m4 b/macros/kde4.m4
index 8b16768..b12be17 100644
--- a/macros/kde4.m4
+++ b/macros/kde4.m4
@@ -194,7 +194,7 @@ AC_DEFUN([GNASH_PATH_KDE4],
     if test x"${with_kde4_plugindir}" != x ; then 
       KDE4_PLUGINDIR="${with_kde4_plugindir}"
     else
-      if test -d ${KDE4_PREFIX}/lib64 -a ! -h ${KDE4_PREFIX}/lib64; then
+      if test -d ${KDE4_PREFIX}/lib64 -a -f /etc/redhat-release; then
         KDE4_PLUGINDIR="${KDE4_PREFIX}/lib64/kde4"
       else
         KDE4_PLUGINDIR="${KDE4_PREFIX}/lib/kde4"
diff --git a/plugin/npapi/plugin.cpp b/plugin/npapi/plugin.cpp
index f615163..693c36f 100644
--- a/plugin/npapi/plugin.cpp
+++ b/plugin/npapi/plugin.cpp
@@ -393,7 +393,6 @@ nsPluginInstance::nsPluginInstance(nsPluginCreateData* data)
     _width(0),
     _height(0),
     _streamfd(-1),
-    _ichan(0),
     _ichanWatchId(0),
     _controlfd(-1),
     _childpid(0),
@@ -1290,6 +1289,7 @@ nsPluginInstance::startProc()
                                        (GIOCondition)(G_IO_IN|G_IO_HUP), 
                                        (GIOFunc)handlePlayerRequestsWrapper,
                                        this);
+        g_io_channel_unref(ichan);
         return;
     }
     
diff --git a/plugin/npapi/plugin.h b/plugin/npapi/plugin.h
index 007df68..6666128 100644
--- a/plugin/npapi/plugin.h
+++ b/plugin/npapi/plugin.h
@@ -125,7 +125,6 @@ private:
     unsigned int                       _height;
     std::map<std::string, std::string> _options;
     int                                _streamfd;
-    GIOChannel*                        _ichan;
     int                                _ichanWatchId;
     int                                _controlfd;
     pid_t                              _childpid;
diff --git a/testsuite/actionscript.all/TextFieldHTML.as b/testsuite/actionscript.all/TextFieldHTML.as
index ae81f6f..f88b8f2 100644
--- a/testsuite/actionscript.all/TextFieldHTML.as
+++ b/testsuite/actionscript.all/TextFieldHTML.as
@@ -129,6 +129,10 @@
  format = tf.getTextFormat(1, 4);
  xcheck_equals(format.color, 0x00ff00);
 
- totals(30);
+ // Check empty face value (bug #32508)
+ tf.htmlText = '<font face="">#32508</font>';
+ xcheck_equals(tf.text, "#32508");
+
+ totals(31);
 
 #endif
diff --git a/testsuite/misc-ming.all/DragDropTestRunner.cpp b/testsuite/misc-ming.all/DragDropTestRunner.cpp
index 7ae1646..24eed04 100644
--- a/testsuite/misc-ming.all/DragDropTestRunner.cpp
+++ b/testsuite/misc-ming.all/DragDropTestRunner.cpp
@@ -111,7 +111,7 @@ main(int /*argc*/, char** /*argv*/)
 		{
 			check(!"loadTarget was never loaded");
 			cerr << "Root display list is: " << endl;
-			root->getDisplayList().dump();
+            std::cerr << root->getDisplayList();
 			exit(EXIT_FAILURE);
 		}
 
diff --git a/testsuite/misc-ming.all/loading/loadMovieTest.c b/testsuite/misc-ming.all/loading/loadMovieTest.c
index 3e7f043..e18224e 100644
--- a/testsuite/misc-ming.all/loading/loadMovieTest.c
+++ b/testsuite/misc-ming.all/loading/loadMovieTest.c
@@ -1,6 +1,6 @@
 /***********************************************************************
  *
- *   Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc.
+ *   Copyright (C) 2007, 2009, 2010, 2011 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
@@ -87,10 +87,33 @@ add_clip(SWFMovie mo, char* file, char* name,
 	/* "Click" handler */
 	snprintf(action,  1023,
 		"%s.onPress = function () { "
-		"	coverart.loadMovie('%s');"
-		"	_level0.expectLoaded = '%s';" 
+		"  if ( _root.clicks < 3 ) {"
+		"    coverart.loadMovie('%s');"
+		"    _level0.loadMethod = 'MovieClip.loadMovie';" 
+		"  } else if ( _root.clicks < 6 ) {"
+		"    loadMovie('%s', '_level0.cont.coverart');" /* Uses GETURL */
+		"    _level0.loadMethod = 'GETURL, target:_level0.cont.coverart';"
+		"  } else if ( _root.clicks < 9 ) {"
+		"    loadMovie('%s', '/cont/coverart');" /* Uses GETURL tag */
+		"    _level0.loadMethod = 'GETURL, target:/cont/coverart';"
+#define SKIP_FAILING 1
+#ifndef SKIP_FAILING
+// This is disabled as gnash fails
+		"  } else if ( _root.clicks < 12 ) {"
+		"    loadMovie('%s', '_level0.coverart');" /* Uses GETURL */
+		"    _level0.loadMethod = 'GETURL, target:_level0.coverart';"
+#endif
+		"  } else {"
+		"    _root.note('You are not supposed to be clicking anymore');"
+		"    return;"
+		"  }"
+		" _level0.expectLoaded = '%s';" 
 		"};"
-		,name, url, fname);
+		, name, url, url, url,
+#ifndef SKIP_FAILING
+		url,
+#endif
+		fname);
 
 	ac = compileSWFActionCode(action);
 
@@ -102,9 +125,10 @@ add_coverart(SWFMovie mo, int x, int y)
 {
 	SWFShape sh_coverart;
 	SWFFillStyle fstyle;
+	SWFMovieClip mc_coverart_cont;
 	SWFMovieClip mc_coverart;
 	SWFDisplayItem it;
-#define BUFSIZE 1024
+#define BUFSIZE 2048
 	char buf[BUFSIZE];
 
 	sh_coverart = newSWFShape();
@@ -124,10 +148,13 @@ add_coverart(SWFMovie mo, int x, int y)
 	));
 	SWFMovieClip_nextFrame(mc_coverart); /* showFrame */
 
-	it = SWFMovie_add(mo, (SWFBlock)mc_coverart);
+	mc_coverart_cont = newSWFMovieClip();
+	it = SWFMovieClip_add(mc_coverart_cont, (SWFBlock)mc_coverart);
+	SWFDisplayItem_setDepth(it, 8);
 	SWFDisplayItem_setName(it, "coverart"); 
 	SWFDisplayItem_moveTo(it, x, y);
 
+
 	snprintf(buf, BUFSIZE,
 		//"_root.note(this+'.on(RollOver) ... ');"
 		//"_level0.coverart.onUnload = function() {"
@@ -143,15 +170,34 @@ add_coverart(SWFMovie mo, int x, int y)
 		"  _root.check_equals(lastUrlComponent, _level0.expectLoaded, '%s:%d');"
 		"  _root.check_equals(this.getDepth(), -16376);"
 		"  _root.check_equals(this.getBytesLoaded(), this.getBytesTotal());"
-		"  _root.check(this.getBytesLoaded() > 0);" /* assuming something was loaded here */
-		"  _root.note('bytesLoaded: '+this.getBytesLoaded());"
-		"  if ( Key.isDown(Key.SHIFT) ) { "
-		"	trace('SHIFT-click on coverart...');"
-		//"	_root.note('SHIFT-click on coverart...');"
-		"	_root.totals(26, '"__FILE__"');"
-		"	_root.END_OF_TEST = true;"
-		" }"
-		"  else _root.note('2 tests run');"
+		/* assuming something was loaded here */
+		"  _root.check(this.getBytesLoaded() > 0);"
+		"  _root.clicks++;"
+
+		"  if ( _root.clicks < 4 ) {"
+		"    _root.check_equals(_root.loadMethod, "
+		"       'MovieClip.loadMovie');" 
+		"  } else if ( _root.clicks < 7 ) {"
+		"    _root.check_equals(_root.loadMethod, "
+		"         'GETURL, target:_level0.cont.coverart');" 
+		"  } else if ( _root.clicks < 10 ) {"
+		"    _root.check_equals(_root.loadMethod, "
+		"         'GETURL, target:/cont/coverart');" 
+		"  } else if ( _root.clicks < 13 ) {"
+		"    _root.check_equals(_root.loadMethod, "
+		"         'GETURL, target:_level0.coverart');" 
+		"  }"
+
+		"  if ( _root.clicks < 9 ) {"
+		"    _root.note(Math.floor(_root.clicks/3)+'.'+"
+		"    _root.clicks%%3+': Click on the '+"
+		"      _root.imagenames[_root.clicks%%3]+' image.' +"
+		"      ' Wait for it to appear on the right, then click on it.');"
+		"  } else {"
+		"    _root.note('The test is over');"
+		"    _root.totals(67, '"__FILE__"');"
+		"    _root.END_OF_TEST = true;"
+		"  }"
 		"};"
 		, __FILE__, __LINE__);
 
@@ -165,6 +211,11 @@ add_coverart(SWFMovie mo, int x, int y)
 		),
 		SWFACTION_ROLLOUT);
 
+
+	SWFMovieClip_nextFrame(mc_coverart_cont); /* showFrame */
+	it = SWFMovie_add(mo, (SWFBlock)mc_coverart_cont);
+	SWFDisplayItem_setName(it, "cont"); 
+
 }
 
 SWFTextField
@@ -296,7 +347,7 @@ main(int argc, char** argv)
 	add_button(mo, 50, 220, "Clear", newSWFAction(
 				" art=_root.coverart;"
 				" for (i=0; i<art.lastdepth; ++i) {"
-				"  removeMovieClip('_root.coverart.child'+i);" 
+				"  removeMovieClip('_root.cont.coverart.child'+i);" 
 				" }"
 				" art.lastdepth=0;"
 				" art.clear(); "
@@ -320,9 +371,13 @@ main(int argc, char** argv)
 	add_coverart(mo, 600, 100);
 
 	add_actions(mo,
-		"note('Click on each image to load it into the container on the right.');"
-		"note('After each load, click on the container.');"
-		"note('Finally, shift-click on the container to get results printed.');"
+		"_root.imagenames = ['first','second','third'];"
+		"_root.clicks = 0;"
+		"_root.check_equals(typeof(_level0.cont), 'movieclip');"
+		"_root.check_equals(typeof(_level0.cont.coverart), 'movieclip');"
+		"_root.coverart = _level0.cont.coverart;"
+		"note('0.0: Click on the '+_root.imagenames[_root.clicks]+' image.'+"
+		"      ' Wait for it to appear on the right, then click on it.');"
 		"_level0.expectLoaded = 'loadMovieTest.swf';" 
 		// TODO: add self-contained tests after each load
 		//       like for the DragAndDropTest.as movie
diff --git a/testsuite/misc-ming.all/loading/loadMovieTestRunner.cpp b/testsuite/misc-ming.all/loading/loadMovieTestRunner.cpp
index 488a507..dfa3aff 100644
--- a/testsuite/misc-ming.all/loading/loadMovieTestRunner.cpp
+++ b/testsuite/misc-ming.all/loading/loadMovieTestRunner.cpp
@@ -43,8 +43,11 @@ MovieClip* root;
 MovieClip*
 getCoverArt()
 {
-	DisplayObject* coverartch = const_cast<DisplayObject*>(tester->findDisplayItemByName(*root, "coverart"));
-	MovieClip* coverart = coverartch->to_movie();
+    const DisplayObject* coverartch = tester->findDisplayItemByTarget(
+        "_level0.cont.coverart"
+    );
+    if ( ! coverartch ) return 0;
+	MovieClip* coverart = const_cast<DisplayObject*>(coverartch)->to_movie();
 
 	//log_debug("Coverart is %p, displaylist is:", coverart);
 	//coverart->getDisplayList().dump();
@@ -72,60 +75,41 @@ checkScribbling()
 	check_equals(coverart->getDisplayList().size(), initial_child_count);
 }
 
-int
-main(int /*argc*/, char** /*argv*/)
+/* Wait until the coverart character is different from the given character */
+MovieClip*
+waitForLoad(MovieClip* from)
 {
-	gnash::LogFile& dbglogfile = gnash::LogFile::getDefaultInstance();
-	dbglogfile.setVerbosity(1);
+    MovieClip* coverart;
 
-	string filename = string(TGTDIR) + string("/") + string(INPUT_FILENAME);
-	tester.reset(new MovieTester(filename));
+    // Wait for the movie to load
+    // TODO: drop this test and use a self-containment instead
+    do {
+	    usleep(500); // give it some time... 
+	    tester->advance(); // loads (should) happen on next advance
+	    coverart = getCoverArt();
+    } while (coverart == from);
+
+    return coverart;
+}
+
+void
+clickCycle(MovieClip* coverart)
+{
 
-	URL baseURL(filename);
 	URL mediaURL(MEDIADIR"/");
 	URL lynchURL("lynch.swf", mediaURL);
 	URL greenURL("green.jpg", mediaURL);
 	URL offspringURL("offspring.swf", mediaURL);
-	std::string url;
-
-	gnash::RcInitFile& rc = gnash::RcInitFile::getDefaultInstance();
-	rc.addLocalSandboxPath(MEDIADIR);
-
-
 
-	root = tester->getRootMovie();
-	assert(root);
-
-	check_equals(root->get_frame_count(), 2);
-	check_equals(root->get_current_frame(), 0);
-
-	tester->advance();
-	check_equals(root->get_current_frame(), 1);
-
-	// Verify that 'coverart' exists and is empty
-	DisplayObject* coverartch = const_cast<DisplayObject*>(tester->findDisplayItemByName(*root, "coverart"));
-	MovieClip* coverart = coverartch->to_movie();
-	check(coverart);
-	url = coverart->get_root()->url();
-	check_equals(coverart->get_root()->url(), baseURL.str());
-
-	// Check scribbling on the empty canvas
-	checkScribbling();
+	/*------------------------------------- */
 
 	// Click on the first (lynch)
 	tester->movePointerTo(80, 80);
 	check(tester->isMouseOverMouseEntity());
-	tester->pressMouseButton();
 
-    // Wait for the movie to load
-    // TODO: drop this test and use a self-containment instead
-    do {
-	    usleep(500); // give it some time...
-	    tester->advance(); // loads (should) happen on next advance
-	    coverartch = const_cast<DisplayObject*>(tester->findDisplayItemByName(*root, "coverart"));
-    } while (coverartch->to_movie() == coverart);
+	tester->pressMouseButton();
 
-	coverart = coverartch->to_movie();
+	coverart = waitForLoad(coverart);
 	check_equals(coverart->get_root()->url(), lynchURL.str());
 
 	tester->depressMouseButton();
@@ -137,23 +121,20 @@ main(int /*argc*/, char** /*argv*/)
 	tester->movePointerTo(640,180);
 	tester->click(); tester->advance();
 
+	/*------------------------------------- */
+
 	// Click on the second (green)
 	tester->movePointerTo(280, 80);
 	check(tester->isMouseOverMouseEntity());
+
 	tester->click();
 
-    // Wait for the movie to load
-    // TODO: drop this test and use a self-containment instead
-    do {
-	    usleep(500); // give it some time... 
-	    tester->advance(); // loads (should) happen on next advance
-	    coverartch = const_cast<DisplayObject*>(tester->findDisplayItemByName(*root, "coverart"));
-    } while (coverartch->to_movie() == coverart);
+	coverart = waitForLoad(coverart);
 
-	coverart = coverartch->to_movie();
 	check_equals(coverart->get_root()->url(), greenURL.str());
 	// TODO: find a way to test if the jpeg is really displayed
-	//       (like turn it into a mouse-event-handling char and use isMouseOverActiveEntity ?)
+	//       (like turn it into a mouse-event-handling char and
+	//        use isMouseOverActiveEntity ?)
 
 	// Check scribbling on the jpeg
 	checkScribbling();
@@ -162,20 +143,16 @@ main(int /*argc*/, char** /*argv*/)
 	tester->movePointerTo(640,180);
 	tester->click(); tester->advance();
 
+	/*------------------------------------- */
+
 	// Click on the third (offspring)
 	tester->movePointerTo(480, 80);
 	check(tester->isMouseOverMouseEntity());
+
 	tester->click();
 
-    // Wait for the movie to load
-    // TODO: drop this test and use a self-containment instead
-    do {
-	    usleep(500); // give it some time... 
-	    tester->advance(); // loads (should) happen on next advance
-	    coverartch = const_cast<DisplayObject*>(tester->findDisplayItemByName(*root, "coverart"));
-    } while (coverartch->to_movie() == coverart);
+	coverart = waitForLoad(coverart);
 
-	coverart = coverartch->to_movie();
 	check_equals(coverart->get_root()->url(), offspringURL.str());
 
 	// Check scribbling on the offspring
@@ -184,11 +161,44 @@ main(int /*argc*/, char** /*argv*/)
 	// Run 'coverart' tests..
 	tester->movePointerTo(640,180);
 	tester->click(); tester->advance();
+}
 
-	// Get summary ...
-	tester->pressKey(key::SHIFT);
-	tester->click(); tester->advance();
-	tester->releaseKey(key::SHIFT);
+int
+main(int /*argc*/, char** /*argv*/)
+{
+	gnash::LogFile& dbglogfile = gnash::LogFile::getDefaultInstance();
+	dbglogfile.setVerbosity(1);
+
+	string filename = string(TGTDIR) + string("/") + string(INPUT_FILENAME);
+	tester.reset(new MovieTester(filename));
+
+	URL baseURL(filename);
+
+	gnash::RcInitFile& rc = gnash::RcInitFile::getDefaultInstance();
+	rc.addLocalSandboxPath(MEDIADIR);
+
+	root = tester->getRootMovie();
+	assert(root);
+
+	check_equals(root->get_frame_count(), 2);
+	check_equals(root->get_current_frame(), 0);
+
+	tester->advance();
+	check_equals(root->get_current_frame(), 1);
+
+	// Verify that 'coverart' exists and is empty
+	MovieClip* coverart = getCoverArt();
+	check(coverart);
+	std::string url = coverart->get_root()->url();
+	check_equals(coverart->get_root()->url(), baseURL.str());
+
+	// Check scribbling on the empty canvas
+	checkScribbling();
+
+	clickCycle(coverart); // MovieClip::loadMovie
+	clickCycle(coverart); // GETURL _level0.cont.coverart 
+	clickCycle(coverart); // GETURL /cont/coverart
+	//clickCycle(coverart); // GETURL _level0.coverart
 
 	// Consistency checking
 	VM& vm = getVM(*getObject(root));
diff --git a/testsuite/misc-ming.all/masks_testrunner.cpp b/testsuite/misc-ming.all/masks_testrunner.cpp
index 4d5b9e8..cb9f43a 100644
--- a/testsuite/misc-ming.all/masks_testrunner.cpp
+++ b/testsuite/misc-ming.all/masks_testrunner.cpp
@@ -64,7 +64,7 @@ main(int /*argc*/, char** /*argv*/)
 	check_equals(root->getPlayState(), MovieClip::PLAYSTATE_STOP);
 	check_equals(root->get_current_frame(), 1); // 0-based
 	check_equals(root->getDisplayList().size(), 9);
-	root->getDisplayList().dump();
+    std::cout << root->getDisplayList() << "\n";
 	check( tester.findDisplayItemByName(*root, "staticmc2") );
 	check( tester.findDisplayItemByName(*root, "staticmc3") );
 	check( tester.findDisplayItemByName(*root, "staticmc4") );


hooks/post-receive
-- 
GNU Shockwave Flash (SWF) player



More information about the pkg-flash-devel mailing list