gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] /srv/bzr/gnash/trunk r11037: Migrated TextSnapshot to new


From: Bob Naugle
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r11037: Migrated TextSnapshot to new file and folder, modified makefiles and dependencies accordingly.
Date: Mon, 08 Jun 2009 11:00:03 -0600
User-agent: Bazaar (1.13.1)

------------------------------------------------------------
revno: 11037
committer: Bob Naugle <address@hidden>
branch nick: trunk
timestamp: Mon 2009-06-08 11:00:03 -0600
message:
  Migrated TextSnapshot to new file and folder, modified makefiles and 
dependencies accordingly.
removed:
  libcore/asobj/TextSnapshot_as.cpp
  libcore/asobj/TextSnapshot_as.h
modified:
  libcore/ClassHierarchy.cpp
  libcore/asobj/Global.cpp
  libcore/asobj/flash.am
  libcore/asobj/flash/text/TextSnapshot_as.cpp
  libcore/asobj/flash/text/TextSnapshot_as.h
  libcore/asobj/flash/text/text.am
=== modified file 'libcore/ClassHierarchy.cpp'
--- a/libcore/ClassHierarchy.cpp        2009-06-08 16:10:02 +0000
+++ b/libcore/ClassHierarchy.cpp        2009-06-08 17:00:03 +0000
@@ -51,7 +51,7 @@
 #include "Sound_as.h"
 #include "Stage_as.h"
 #include "System_as.h"
-#include "TextSnapshot_as.h"
+#include "flash/text/TextSnapshot_as.h"
 #include "TextFormat_as.h"
 #include "Video.h"
 #include "extension.h"

=== modified file 'libcore/asobj/Global.cpp'
--- a/libcore/asobj/Global.cpp  2009-06-08 16:08:56 +0000
+++ b/libcore/asobj/Global.cpp  2009-06-08 17:00:03 +0000
@@ -54,7 +54,7 @@
 #include "Stage_as.h"
 #include "System_as.h"
 #include "TextFormat_as.h"
-#include "TextSnapshot_as.h"
+#include "flash/text/TextSnapshot_as.h"
 #include "Video.h"
 #include "extension.h"
 #include "VM.h"

=== removed file 'libcore/asobj/TextSnapshot_as.cpp'
--- a/libcore/asobj/TextSnapshot_as.cpp 2009-04-22 11:55:09 +0000
+++ b/libcore/asobj/TextSnapshot_as.cpp 1970-01-01 00:00:00 +0000
@@ -1,633 +0,0 @@
-// TextSnapshot_as.cpp:  ActionScript "TextSnapshot" class, for Gnash.
-//
-//   Copyright (C) 2005, 2006, 2007, 2008, 2009 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 3 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
-//
-
-#ifdef HAVE_CONFIG_H
-#include "gnashconfig.h"
-#endif
-
-#include "TextSnapshot_as.h"
-#include "as_object.h" // for inheritance
-#include "log.h"
-#include "fn_call.h"
-#include "smart_ptr.h" // for boost intrusive_ptr
-#include "builtin_function.h" // need builtin_function
-#include "Object.h" // for getObjectInterface
-#include "StaticText.h"
-#include "DisplayList.h"
-#include "MovieClip.h"
-#include "Font.h"
-#include "swf/TextRecord.h"
-#include "Array_as.h"
-#include "RGBA.h"
-#include "GnashNumeric.h"
-
-#include <boost/algorithm/string/compare.hpp>
-#include <boost/dynamic_bitset.hpp>
-#include <algorithm>
-
-namespace gnash {
-
-// Forward declarations
-namespace {
-
-    as_value textsnapshot_findText(const fn_call& fn);
-    as_value textsnapshot_getCount(const fn_call& fn);
-    as_value textsnapshot_getSelected(const fn_call& fn);
-    as_value textsnapshot_getSelectedText(const fn_call& fn);
-    as_value textsnapshot_getTextRunInfo(const fn_call& fn);
-    as_value textsnapshot_getText(const fn_call& fn);
-    as_value textsnapshot_hitTestTextNearPos(const fn_call& fn);
-    as_value textsnapshot_setSelectColor(const fn_call& fn);
-    as_value textsnapshot_setSelected(const fn_call& fn);
-    as_value textsnapshot_ctor(const fn_call& fn);
-
-    void attachTextSnapshotInterface(as_object& o);
-    as_object* getTextSnapshotInterface();
-
-    size_t getTextFields(const MovieClip* mc,
-            TextSnapshot_as::TextFields& fields);
-
-    void setTextReachable(const TextSnapshot_as::TextFields::value_type& vt);
-
-}
-
-namespace {
-
-/// Locate static text in a DisplayObject.
-//
-/// Static text (TextRecords) are added to a vector, which should 
-/// correspond to a single DisplayObject. Also keeps count of the total number
-/// of glyphs.
-class TextFinder
-{
-public:
-    TextFinder(TextSnapshot_as::TextFields& fields)
-        :
-        _fields(fields),
-        _count(0)
-    {}
-
-    void operator()(DisplayObject* ch) {
-
-        /// This is not tested.
-        if (ch->unloaded()) return;
-
-        TextSnapshot_as::Records text;
-        StaticText* tf;
-        size_t numChars;
-
-        if ((tf = ch->getStaticText(text, numChars))) {
-            _fields.push_back(std::make_pair(tf, text));
-            _count += numChars;
-        }
-    }
-
-    size_t getCount() const { return _count; }
-
-private:
-    TextSnapshot_as::TextFields& _fields;
-    size_t _count;
-};
-
-} // anonymous namespace
-
-/// The member _textFields is initialized here unnecessarily to show
-/// that it is constructed before it is used.
-TextSnapshot_as::TextSnapshot_as(const MovieClip* mc)
-    :
-    as_object(getTextSnapshotInterface()),
-    _textFields(),
-    _valid(mc),
-    _count(getTextFields(mc, _textFields))
-{
-}
-
-void
-TextSnapshot_as::setSelected(size_t start, size_t end, bool selected)
-{
-    /// If there are no TextFields, there is nothing to do.
-    if (_textFields.empty()) return;
-
-    start = std::min(start, _count);
-    end = std::min(end, _count);
-
-    TextFields::const_iterator field = _textFields.begin();
-
-    size_t totalChars = field->first->getSelected().size();
-    size_t fieldStartIndex = 0;
-
-    for (size_t i = start; i < end; ++i) {
-
-        /// Find the field containing the start index.
-        while (totalChars <= i) {
-            fieldStartIndex = totalChars;
-            ++field;
-
-            if (field == _textFields.end()) return;
-            
-            const boost::dynamic_bitset<>& sel = field->first->getSelected();
-            totalChars += sel.size();
-            continue;
-        }
-        field->first->setSelected(i - fieldStartIndex, selected);
-    }
-}
-
-bool
-TextSnapshot_as::getSelected(size_t start, size_t end) const
-{
-
-    if (_textFields.empty()) return false;
-
-    start = std::min(start, _count);
-    end = std::min(end, _count);
-
-    TextFields::const_iterator field = _textFields.begin();
-
-    size_t totalChars = field->first->getSelected().size();
-    size_t fieldStartIndex = 0;
-
-    for (size_t i = start; i < end; ++i) {
-
-        /// Find the field containing the start index.
-        while (totalChars <= i) {
-            fieldStartIndex = totalChars;
-            ++field;
-            if (field == _textFields.end()) return false;
-
-            const boost::dynamic_bitset<>& sel = field->first->getSelected();
-            totalChars += sel.size();
-            continue;
-        }
-
-        if (field->first->getSelected().test(i - fieldStartIndex)) return true;
-    }
-    
-    return false;
-}
-
-void
-TextSnapshot_as::markReachableResources() const
-{
-    std::for_each(_textFields.begin(), _textFields.end(), setTextReachable);
-    markAsObjectReachable();
-}
-
-void
-TextSnapshot_as::getTextRunInfo(size_t start, size_t end, Array_as& ri) const
-{
-    std::string::size_type pos = 0;
-
-    std::string::size_type len = end - start;
-
-    for (TextFields::const_iterator field = _textFields.begin(),
-            e = _textFields.end(); field != e; ++field) {
-
-        const Records& rec = field->second;
-        const SWFMatrix& mat = field->first->getMatrix();
-        const boost::dynamic_bitset<>& selected = field->first->getSelected();
-
-        const std::string::size_type fieldStartIndex = pos;
-
-        for (Records::const_iterator j = rec.begin(), end = rec.end();
-                j != end; ++j) {
-        
-            const SWF::TextRecord* tr = *j;
-            assert(tr);
-
-            const SWF::TextRecord::Glyphs& glyphs = tr->glyphs();
-            const SWF::TextRecord::Glyphs::size_type numGlyphs = glyphs.size();
-
-            if (pos + numGlyphs < start) {
-                pos += numGlyphs;
-                continue;
-            }
-
-            const Font* font = tr->getFont();
-            assert(font);
-
-            double x = tr->xOffset();
-            for (SWF::TextRecord::Glyphs::const_iterator k = glyphs.begin(),
-                    e = glyphs.end(); k != e; ++k) {
-                
-                if (pos < start) {
-                    x += k->advance;
-                    ++pos;
-                    continue;
-                }
-                
-                as_object* el = new as_object;
-
-                el->init_member("indexInRun", pos);
-                el->init_member("selected",
-                        selected.test(pos - fieldStartIndex));
-                el->init_member("font", font->name());
-                el->init_member("color", tr->color().toRGBA());
-                el->init_member("height", twipsToPixels(tr->textHeight()));
-
-                const double factor = 65536.0;
-                el->init_member("matrix_a", mat.sx / factor);
-                el->init_member("matrix_b", mat.shx / factor);
-                el->init_member("matrix_c", mat.shy / factor);
-                el->init_member("matrix_d", mat.sy / factor);
-
-                const double xpos = twipsToPixels(mat.tx + x);
-                const double ypos = twipsToPixels(mat.ty + tr->yOffset());
-                el->init_member("matrix_tx", xpos);
-                el->init_member("matrix_ty", ypos);
-
-                ri.push(el);
-
-                ++pos;
-                x += k->advance;
-                if (pos - start > len) return;
-            }
-        }
-    }
-    
-}
-
-void
-TextSnapshot_as::makeString(std::string& to, bool newline, bool selectedOnly,
-        std::string::size_type start, std::string::size_type len) const
-{
-
-    std::string::size_type pos = 0;
-
-    for (TextFields::const_iterator field = _textFields.begin(),
-            e = _textFields.end(); field != e; ++field)
-    {
-        // When newlines are requested, insert one after each individual
-        // text field is processed.
-        if (newline && pos > start) to += '\n';
-
-        const Records& records = field->second;
-        const boost::dynamic_bitset<>& selected = field->first->getSelected();
-
-        /// Remember the position at the beginning of the StaticText.
-        const std::string::size_type fieldStartIndex = pos;
-
-        for (Records::const_iterator j = records.begin(), end = records.end();
-                j != end; ++j) {
-        
-            const SWF::TextRecord* tr = *j;
-            assert(tr);
-
-            const SWF::TextRecord::Glyphs& glyphs = tr->glyphs();
-            const SWF::TextRecord::Glyphs::size_type numGlyphs = glyphs.size();
-
-            if (pos + numGlyphs < start) {
-                pos += numGlyphs;
-                continue;
-            }
-
-            const Font* font = tr->getFont();
-            assert(font);
-
-            for (SWF::TextRecord::Glyphs::const_iterator k = glyphs.begin(),
-                    e = glyphs.end(); k != e; ++k) {
-                
-                if (pos < start) {
-                    ++pos;
-                    continue;
-                }
-                
-                if (!selectedOnly || selected.test(pos - fieldStartIndex)) {
-                    to += font->codeTableLookup(k->index, true);
-                }
-                ++pos;
-                if (pos - start == len) return;
-            }
-        }
-    }
-}
-
-std::string
-TextSnapshot_as::getText(boost::int32_t start, boost::int32_t end, bool nl)
-    const
-{
-
-    // Start is always moved to between 0 and len - 1.
-    start = std::max<boost::int32_t>(start, 0);
-    start = std::min<boost::int32_t>(start, _count - 1);
-
-    // End is always moved to between start and end. We don't really care
-    // about the end of the string.
-    end = std::max(start + 1, end);
-
-    std::string snapshot;
-    makeString(snapshot, nl, false, start, end - start);
-
-    return snapshot;
-
-}
-
-std::string
-TextSnapshot_as::getSelectedText(bool newline) const
-{
-    std::string sel;
-    
-    makeString(sel, newline, true);
-    return sel;
-}
-
-boost::int32_t
-TextSnapshot_as::findText(boost::int32_t start, const std::string& text,
-        bool ignoreCase) const
-{
-
-    if (start < 0 || text.empty()) return -1;
-
-    std::string snapshot;
-    makeString(snapshot);
-
-    const std::string::size_type len = snapshot.size();
-
-    // Don't try to search if start is past the end of the string.
-    if (len < static_cast<size_t>(start)) return -1;
-
-    if (ignoreCase) {
-        std::string::const_iterator it = std::search(snapshot.begin() + start,
-                snapshot.end(), text.begin(), text.end(), boost::is_iequal());
-        return (it == snapshot.end()) ? -1 : it - snapshot.begin();
-    }
-
-    std::string::size_type pos = snapshot.find(text, start);
-    return (pos == std::string::npos) ? -1 : pos;
-
-}
-
-void
-TextSnapshot_as::init(as_object& global)
-{
-       // This is going to be the global TextSnapshot "class"/"function"
-       static boost::intrusive_ptr<builtin_function> cl;
-
-       if ( cl == NULL )
-       {
-               cl=new builtin_function(&textsnapshot_ctor, 
getTextSnapshotInterface());
-       }
-
-       global.init_member("TextSnapshot", cl.get());
-}
-
-
-namespace {
-
-void
-attachTextSnapshotInterface(as_object& o)
-{
-
-    const int flags = as_prop_flags::onlySWF6Up;
-
-       o.init_member("findText", new builtin_function(textsnapshot_findText),
-            flags);
-       o.init_member("getCount", new builtin_function(textsnapshot_getCount),
-            flags);
-       o.init_member("getTextRunInfo",
-            new builtin_function(textsnapshot_getTextRunInfo), flags);
-       o.init_member("getSelected",
-            new builtin_function(textsnapshot_getSelected), flags);
-       o.init_member("getSelectedText",
-            new builtin_function(textsnapshot_getSelectedText), flags);
-       o.init_member("getText",
-            new builtin_function(textsnapshot_getText), flags);
-       o.init_member("hitTestTextNearPos",
-            new builtin_function(textsnapshot_hitTestTextNearPos), flags);
-       o.init_member("setSelectColor",
-            new builtin_function(textsnapshot_setSelectColor), flags);
-       o.init_member("setSelected",
-            new builtin_function(textsnapshot_setSelected), flags);
-}
-
-as_object*
-getTextSnapshotInterface()
-{
-       static boost::intrusive_ptr<as_object> o;
-       if ( ! o )
-       {
-               o = new as_object(getObjectInterface());
-               attachTextSnapshotInterface(*o);
-       }
-       return o.get();
-}
-
-as_value
-textsnapshot_getTextRunInfo(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextSnapshot_as> ts =
-        ensureType<TextSnapshot_as>(fn.this_ptr);
-    
-    if (!ts->valid()) return as_value();
-
-    if (fn.nargs != 2) {
-        return as_value();
-    }
-
-    size_t start = std::max<boost::int32_t>(0, fn.arg(0).to_int());
-    size_t end = std::max<boost::int32_t>(start + 1, fn.arg(1).to_int());
-
-    Array_as* ri = new Array_as;
-
-    ts->getTextRunInfo(start, end, *ri);
-    
-    return as_value(ri);
-}
-
-as_value
-textsnapshot_findText(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextSnapshot_as> ts =
-        ensureType<TextSnapshot_as>(fn.this_ptr);
-    
-    if (!ts->valid()) return as_value();
-
-    if (fn.nargs != 3) {
-        IF_VERBOSE_ASCODING_ERRORS(
-            log_aserror("TextSnapshot.findText() requires 3 arguments");
-        );
-        return as_value();
-    }
-
-    boost::int32_t start = fn.arg(0).to_int();
-    const std::string& text = fn.arg(1).to_string();
-
-    /// Yes, the pp is case-insensitive by default. We don't write
-    /// functions like that here.
-    bool ignoreCase = !fn.arg(2).to_bool();
-
-    return ts->findText(start, text, ignoreCase);
-}
-
-as_value
-textsnapshot_getCount(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextSnapshot_as> ts =
-        ensureType<TextSnapshot_as>(fn.this_ptr);
-    
-    if (!ts->valid()) return as_value();
-
-    if (fn.nargs) {
-        IF_VERBOSE_ASCODING_ERRORS(
-            log_aserror("TextSnapshot.getCount() takes no arguments");
-        );
-        return as_value();
-    }
-
-    return ts->getCount();
-}
-
-/// Returns a boolean value, or undefined if not valid.
-as_value
-textsnapshot_getSelected(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextSnapshot_as> ts =
-        ensureType<TextSnapshot_as>(fn.this_ptr);
-
-    if (!ts->valid()) return as_value();
-
-    if (fn.nargs != 2) {
-        return as_value();
-    }
-
-    size_t start = std::max<boost::int32_t>(0, fn.arg(0).to_int());
-    size_t end = std::max<boost::int32_t>(start + 1, fn.arg(1).to_int());
-
-    return as_value(ts->getSelected(start, end));
-}
-
-/// Returns a string, or undefined if not valid.
-as_value
-textsnapshot_getSelectedText(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextSnapshot_as> ts =
-        ensureType<TextSnapshot_as>(fn.this_ptr);
-
-    if (!ts->valid()) return as_value();
-
-    if (fn.nargs > 1) {
-        return as_value();
-    }
-
-    bool newlines = fn.nargs ? fn.arg(0).to_bool() : false;
-
-    return as_value(ts->getSelectedText(newlines));
-}
-
-/// Returns a string, or undefined if not valid.
-as_value
-textsnapshot_getText(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextSnapshot_as> ts =
-        ensureType<TextSnapshot_as>(fn.this_ptr);
-
-    if (!ts->valid()) return as_value();
-    
-    if (fn.nargs < 2 || fn.nargs > 3)
-    {
-        IF_VERBOSE_ASCODING_ERRORS(
-            log_aserror("TextSnapshot.getText requires exactly 2 arguments");
-        );
-        return as_value();
-    }
-
-    boost::int32_t start = fn.arg(0).to_int();
-    boost::int32_t end = fn.arg(1).to_int();
-
-    const bool newline = (fn.nargs > 2) ? fn.arg(2).to_bool() : false;
-
-    return ts->getText(start, end, newline);
-
-}
-
-
-/// Returns bool, or undefined if not valid.
-as_value
-textsnapshot_hitTestTextNearPos(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextSnapshot_as> ts =
-        ensureType<TextSnapshot_as>(fn.this_ptr);
-
-    if (!ts->valid()) return as_value();
-
-    log_unimpl (__FUNCTION__);
-    return as_value();
-}
-
-/// Returns void.
-as_value
-textsnapshot_setSelectColor(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextSnapshot_as> ts =
-        ensureType<TextSnapshot_as>(fn.this_ptr);
-
-    log_unimpl (__FUNCTION__);
-    return as_value();
-}
-
-
-/// Returns void.
-as_value
-textsnapshot_setSelected(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextSnapshot_as> ts =
-        ensureType<TextSnapshot_as>(fn.this_ptr);
-
-    if (fn.nargs < 2 || fn.nargs > 3) {
-        return as_value();
-    }
-
-    size_t start = std::max<boost::int32_t>(0, fn.arg(0).to_int());
-    size_t end = std::max<boost::int32_t>(start, fn.arg(1).to_int());
-
-    bool selected = (fn.nargs > 2) ? fn.arg(2).to_bool() : true;
-
-    ts->setSelected(start, end, selected);
-
-    return as_value();
-}
-
-as_value
-textsnapshot_ctor(const fn_call& fn)
-{
-    MovieClip* mc = (fn.nargs == 1) ? fn.arg(0).to_sprite() : 0;
-    return as_value(new TextSnapshot_as(mc));
-}
-
-size_t
-getTextFields(const MovieClip* mc, TextSnapshot_as::TextFields& fields)
-{
-    if (mc) {
-        const DisplayList& dl = mc->getDisplayList();
-
-        TextFinder finder(fields);
-        dl.visitAll(finder);
-        return finder.getCount();
-    }
-    return 0;
-}
-
-void
-setTextReachable(const TextSnapshot_as::TextFields::value_type& vt)
-{
-    vt.first->setReachable();
-}
-
-} // anonymous namespace
-} // gnash namespace

=== removed file 'libcore/asobj/TextSnapshot_as.h'
--- a/libcore/asobj/TextSnapshot_as.h   2009-04-03 09:18:40 +0000
+++ b/libcore/asobj/TextSnapshot_as.h   1970-01-01 00:00:00 +0000
@@ -1,114 +0,0 @@
-//
-//   Copyright (C) 2005, 2006, 2007, 2008, 2009 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 3 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
-//
-
-#ifndef GNASH_ASOBJ_TEXTSNAPSHOT_H
-#define GNASH_ASOBJ_TEXTSNAPSHOT_H
-
-#include "as_object.h"
-
-
-// Forward declarations.
-namespace gnash {
-    class StaticText;
-    class Array_as;
-    namespace SWF {
-        class TextRecord;
-    }
-}
-
-namespace gnash {
-
-class TextSnapshot_as: public as_object
-{
-
-public:
-
-    typedef std::vector<const SWF::TextRecord*> Records;
-
-    /// Should remain in the order of insertion
-    /// We should only ever iterate from begin to end, so there's no
-    /// performance issue.
-    typedef std::vector<std::pair<StaticText*, Records> > TextFields;
-
-    /// Construct a TextSnapshot_as from a MovieClip.
-    //
-    /// @param mc       The MovieClip to search for static text. If 0, the
-    ///                 TextSnapshot is invalid, which should be reflected in
-    ///                 AS return values.
-    TextSnapshot_as(const MovieClip* mc);
-
-    static void init(as_object& global);
-
-    std::string getText(boost::int32_t start, boost::int32_t end,
-            bool nl) const;
-
-    boost::int32_t findText(boost::int32_t start, const std::string& text,
-            bool ignoreCase) const;
-
-    bool valid() const { return _valid; }
-
-    size_t getCount() const { return _count; }
-
-    void setSelected(size_t start, size_t end, bool selected);
-    
-    bool getSelected(size_t start, size_t end) const;
-
-    std::string getSelectedText(bool newlines) const;
-
-    void getTextRunInfo(size_t start, size_t end, Array_as& ri) const;
-
-protected:
-
-    void markReachableResources() const;
-
-private:
-
-    /// Generate a string from the TextRecords in this TextSnapshot.
-    //
-    /// @param to           The string to write to
-    /// @param newline      If true, newlines are written after every
-    ///                     StaticText in this TextSnapshot
-    /// @param selectedOnly Only write DisplayObject that are selected to.
-    /// @param start        The start index
-    /// @param len          The number of StaticText DisplayObjects to 
traverse.
-    ///                     This includes non-selected DisplayObjects.
-    void makeString(std::string& to, bool newline = false,
-            bool selectedOnly = false,
-            std::string::size_type start = 0,
-            std::string::size_type len = std::string::npos) const;
-
-    TextFields _textFields;
-
-    /// Whether the object is valid, i.e. it was constructed with a MovieClip.
-    //
-    /// This should be deducible from another member, but since there seems
-    /// to be no point in storing the MovieClip this bool will do instead.
-    const bool _valid;
-
-    /// The number of DisplayObjects
-    //
-    /// There is no need to store this, but it is quicker than counting
-    /// afresh every time.
-    const size_t _count;
-
-};
-
-} // end of gnash namespace
-
-#endif
-

=== modified file 'libcore/asobj/flash.am'
--- a/libcore/asobj/flash.am    2009-06-07 18:12:15 +0000
+++ b/libcore/asobj/flash.am    2009-06-08 17:00:03 +0000
@@ -53,7 +53,6 @@
        asobj/Stage_as.cpp \
        asobj/System_as.cpp \
        asobj/TextFormat_as.cpp \
-       asobj/TextSnapshot_as.cpp \
        asobj/MovieClipLoader.cpp\
        asobj/String_as.cpp \
        asobj/XML_as.cpp \
@@ -88,7 +87,6 @@
        asobj/Stage_as.h        \
        asobj/System_as.h \
        asobj/TextFormat_as.h \
-       asobj/TextSnapshot_as.h \
        asobj/String_as.h \
        asobj/XML_as.h \
        asobj/XMLSocket_as.h \

=== modified file 'libcore/asobj/flash/text/TextSnapshot_as.cpp'
--- a/libcore/asobj/flash/text/TextSnapshot_as.cpp      2009-05-28 17:11:27 
+0000
+++ b/libcore/asobj/flash/text/TextSnapshot_as.cpp      2009-06-08 17:00:03 
+0000
@@ -22,43 +22,56 @@
 #endif
 
 #include "text/TextSnapshot_as.h"
+#include "GnashException.h" // for ActionException
+
+#include "as_object.h" // for inheritance
 #include "log.h"
 #include "fn_call.h"
 #include "smart_ptr.h" // for boost intrusive_ptr
 #include "builtin_function.h" // need builtin_function
-#include "GnashException.h" // for ActionException
+#include "Object.h" // for getObjectInterface
+#include "StaticText.h"
+#include "DisplayList.h"
+#include "MovieClip.h"
+#include "Font.h"
+#include "swf/TextRecord.h"
+#include "Array_as.h"
+#include "RGBA.h"
+#include "GnashNumeric.h"
+
+#include <boost/algorithm/string/compare.hpp>
+#include <boost/dynamic_bitset.hpp>
+#include <algorithm>
 
 namespace gnash {
 
 // Forward declarations
 namespace {
+    void attachTextSnapshotStaticInterface(as_object& o);
+    
+    as_value textsnapshot_findText(const fn_call& fn);
+    as_value textsnapshot_getCount(const fn_call& fn);
     as_value textsnapshot_getSelected(const fn_call& fn);
     as_value textsnapshot_getSelectedText(const fn_call& fn);
+    as_value textsnapshot_getTextRunInfo(const fn_call& fn);
     as_value textsnapshot_getText(const fn_call& fn);
-    as_value textsnapshot_getTextRunInfo(const fn_call& fn);
     as_value textsnapshot_hitTestTextNearPos(const fn_call& fn);
     as_value textsnapshot_setSelectColor(const fn_call& fn);
     as_value textsnapshot_setSelected(const fn_call& fn);
     as_value textsnapshot_ctor(const fn_call& fn);
+
     void attachTextSnapshotInterface(as_object& o);
-    void attachTextSnapshotStaticInterface(as_object& o);
     as_object* getTextSnapshotInterface();
 
+    size_t getTextFields(const MovieClip* mc,
+            TextSnapshot_as::TextFields& fields);
+
+    void setTextReachable(const TextSnapshot_as::TextFields::value_type& vt);
+
 }
 
-class TextSnapshot_as : public as_object
-{
-
-public:
-
-    TextSnapshot_as()
-        :
-        as_object(getTextSnapshotInterface())
-    {}
-};
-
 // extern (used by Global.cpp)
-void textsnapshot_class_init(as_object& global)
+void TextSnapshot_as::init(as_object& global)
 {
     static boost::intrusive_ptr<builtin_function> cl;
 
@@ -71,113 +84,548 @@
     global.init_member("TextSnapshot", cl.get());
 }
 
+/// The member _textFields is initialized here unnecessarily to show
+/// that it is constructed before it is used.
+TextSnapshot_as::TextSnapshot_as(const MovieClip* mc)
+    :
+    as_object(getTextSnapshotInterface()),
+    _textFields(),
+    _valid(mc),
+    _count(getTextFields(mc, _textFields))
+{
+}
+
+void
+TextSnapshot_as::setSelected(size_t start, size_t end, bool selected)
+{
+    /// If there are no TextFields, there is nothing to do.
+    if (_textFields.empty()) return;
+
+    start = std::min(start, _count);
+    end = std::min(end, _count);
+
+    TextFields::const_iterator field = _textFields.begin();
+
+    size_t totalChars = field->first->getSelected().size();
+    size_t fieldStartIndex = 0;
+
+    for (size_t i = start; i < end; ++i) {
+
+        /// Find the field containing the start index.
+        while (totalChars <= i) {
+            fieldStartIndex = totalChars;
+            ++field;
+
+            if (field == _textFields.end()) return;
+            
+            const boost::dynamic_bitset<>& sel = field->first->getSelected();
+            totalChars += sel.size();
+            continue;
+        }
+        field->first->setSelected(i - fieldStartIndex, selected);
+    }
+}
+
+bool
+TextSnapshot_as::getSelected(size_t start, size_t end) const
+{
+
+    if (_textFields.empty()) return false;
+
+    start = std::min(start, _count);
+    end = std::min(end, _count);
+
+    TextFields::const_iterator field = _textFields.begin();
+
+    size_t totalChars = field->first->getSelected().size();
+    size_t fieldStartIndex = 0;
+
+    for (size_t i = start; i < end; ++i) {
+
+        /// Find the field containing the start index.
+        while (totalChars <= i) {
+            fieldStartIndex = totalChars;
+            ++field;
+            if (field == _textFields.end()) return false;
+
+            const boost::dynamic_bitset<>& sel = field->first->getSelected();
+            totalChars += sel.size();
+            continue;
+        }
+
+        if (field->first->getSelected().test(i - fieldStartIndex)) return true;
+    }
+    
+    return false;
+}
+
+void
+TextSnapshot_as::markReachableResources() const
+{
+    std::for_each(_textFields.begin(), _textFields.end(), setTextReachable);
+    markAsObjectReachable();
+}
+
+void
+TextSnapshot_as::getTextRunInfo(size_t start, size_t end, Array_as& ri) const
+{
+    std::string::size_type pos = 0;
+
+    std::string::size_type len = end - start;
+
+    for (TextFields::const_iterator field = _textFields.begin(),
+            e = _textFields.end(); field != e; ++field) {
+
+        const Records& rec = field->second;
+        const SWFMatrix& mat = field->first->getMatrix();
+        const boost::dynamic_bitset<>& selected = field->first->getSelected();
+
+        const std::string::size_type fieldStartIndex = pos;
+
+        for (Records::const_iterator j = rec.begin(), end = rec.end();
+                j != end; ++j) {
+        
+            const SWF::TextRecord* tr = *j;
+            assert(tr);
+
+            const SWF::TextRecord::Glyphs& glyphs = tr->glyphs();
+            const SWF::TextRecord::Glyphs::size_type numGlyphs = glyphs.size();
+
+            if (pos + numGlyphs < start) {
+                pos += numGlyphs;
+                continue;
+            }
+
+            const Font* font = tr->getFont();
+            assert(font);
+
+            double x = tr->xOffset();
+            for (SWF::TextRecord::Glyphs::const_iterator k = glyphs.begin(),
+                    e = glyphs.end(); k != e; ++k) {
+                
+                if (pos < start) {
+                    x += k->advance;
+                    ++pos;
+                    continue;
+                }
+                
+                as_object* el = new as_object;
+
+                el->init_member("indexInRun", pos);
+                el->init_member("selected",
+                        selected.test(pos - fieldStartIndex));
+                el->init_member("font", font->name());
+                el->init_member("color", tr->color().toRGBA());
+                el->init_member("height", twipsToPixels(tr->textHeight()));
+
+                const double factor = 65536.0;
+                el->init_member("matrix_a", mat.sx / factor);
+                el->init_member("matrix_b", mat.shx / factor);
+                el->init_member("matrix_c", mat.shy / factor);
+                el->init_member("matrix_d", mat.sy / factor);
+
+                const double xpos = twipsToPixels(mat.tx + x);
+                const double ypos = twipsToPixels(mat.ty + tr->yOffset());
+                el->init_member("matrix_tx", xpos);
+                el->init_member("matrix_ty", ypos);
+
+                ri.push(el);
+
+                ++pos;
+                x += k->advance;
+                if (pos - start > len) return;
+            }
+        }
+    }
+    
+}
+
+void
+TextSnapshot_as::makeString(std::string& to, bool newline, bool selectedOnly,
+        std::string::size_type start, std::string::size_type len) const
+{
+
+    std::string::size_type pos = 0;
+
+    for (TextFields::const_iterator field = _textFields.begin(),
+            e = _textFields.end(); field != e; ++field)
+    {
+        // When newlines are requested, insert one after each individual
+        // text field is processed.
+        if (newline && pos > start) to += '\n';
+
+        const Records& records = field->second;
+        const boost::dynamic_bitset<>& selected = field->first->getSelected();
+
+        /// Remember the position at the beginning of the StaticText.
+        const std::string::size_type fieldStartIndex = pos;
+
+        for (Records::const_iterator j = records.begin(), end = records.end();
+                j != end; ++j) {
+        
+            const SWF::TextRecord* tr = *j;
+            assert(tr);
+
+            const SWF::TextRecord::Glyphs& glyphs = tr->glyphs();
+            const SWF::TextRecord::Glyphs::size_type numGlyphs = glyphs.size();
+
+            if (pos + numGlyphs < start) {
+                pos += numGlyphs;
+                continue;
+            }
+
+            const Font* font = tr->getFont();
+            assert(font);
+
+            for (SWF::TextRecord::Glyphs::const_iterator k = glyphs.begin(),
+                    e = glyphs.end(); k != e; ++k) {
+                
+                if (pos < start) {
+                    ++pos;
+                    continue;
+                }
+                
+                if (!selectedOnly || selected.test(pos - fieldStartIndex)) {
+                    to += font->codeTableLookup(k->index, true);
+                }
+                ++pos;
+                if (pos - start == len) return;
+            }
+        }
+    }
+}
+
+std::string
+TextSnapshot_as::getText(boost::int32_t start, boost::int32_t end, bool nl)
+    const
+{
+
+    // Start is always moved to between 0 and len - 1.
+    start = std::max<boost::int32_t>(start, 0);
+    start = std::min<boost::int32_t>(start, _count - 1);
+
+    // End is always moved to between start and end. We don't really care
+    // about the end of the string.
+    end = std::max(start + 1, end);
+
+    std::string snapshot;
+    makeString(snapshot, nl, false, start, end - start);
+
+    return snapshot;
+
+}
+
+std::string
+TextSnapshot_as::getSelectedText(bool newline) const
+{
+    std::string sel;
+    
+    makeString(sel, newline, true);
+    return sel;
+}
+
+boost::int32_t
+TextSnapshot_as::findText(boost::int32_t start, const std::string& text,
+        bool ignoreCase) const
+{
+
+    if (start < 0 || text.empty()) return -1;
+
+    std::string snapshot;
+    makeString(snapshot);
+
+    const std::string::size_type len = snapshot.size();
+
+    // Don't try to search if start is past the end of the string.
+    if (len < static_cast<size_t>(start)) return -1;
+
+    if (ignoreCase) {
+        std::string::const_iterator it = std::search(snapshot.begin() + start,
+                snapshot.end(), text.begin(), text.end(), boost::is_iequal());
+        return (it == snapshot.end()) ? -1 : it - snapshot.begin();
+    }
+
+    std::string::size_type pos = snapshot.find(text, start);
+    return (pos == std::string::npos) ? -1 : pos;
+
+}
+
 namespace {
 
+class TextFinder
+{
+public:
+    TextFinder(TextSnapshot_as::TextFields& fields)
+        :
+        _fields(fields),
+        _count(0)
+    {}
+
+    void operator()(DisplayObject* ch) {
+
+        /// This is not tested.
+        if (ch->unloaded()) return;
+
+        TextSnapshot_as::Records text;
+        StaticText* tf;
+        size_t numChars;
+
+        if ((tf = ch->getStaticText(text, numChars))) {
+            _fields.push_back(std::make_pair(tf, text));
+            _count += numChars;
+        }
+    }
+
+    size_t getCount() const { return _count; }
+
+private:
+    TextSnapshot_as::TextFields& _fields;
+    size_t _count;
+};
+
+void
+attachTextSnapshotStaticInterface(as_object& o)
+{
+
+}
+
 void
 attachTextSnapshotInterface(as_object& o)
 {
-    o.init_member("getSelected", new 
builtin_function(textsnapshot_getSelected));
-    o.init_member("getSelectedText", new 
builtin_function(textsnapshot_getSelectedText));
-    o.init_member("getText", new builtin_function(textsnapshot_getText));
-    o.init_member("getTextRunInfo", new 
builtin_function(textsnapshot_getTextRunInfo));
-    o.init_member("hitTestTextNearPos", new 
builtin_function(textsnapshot_hitTestTextNearPos));
-    o.init_member("setSelectColor", new 
builtin_function(textsnapshot_setSelectColor));
-    o.init_member("setSelected", new 
builtin_function(textsnapshot_setSelected));
-}
-
-void
-attachTextSnapshotStaticInterface(as_object& o)
-{
-
+
+    const int flags = as_prop_flags::onlySWF6Up;
+
+       o.init_member("findText", new builtin_function(textsnapshot_findText),
+            flags);
+       o.init_member("getCount", new builtin_function(textsnapshot_getCount),
+            flags);
+       o.init_member("getTextRunInfo",
+            new builtin_function(textsnapshot_getTextRunInfo), flags);
+       o.init_member("getSelected",
+            new builtin_function(textsnapshot_getSelected), flags);
+       o.init_member("getSelectedText",
+            new builtin_function(textsnapshot_getSelectedText), flags);
+       o.init_member("getText",
+            new builtin_function(textsnapshot_getText), flags);
+       o.init_member("hitTestTextNearPos",
+            new builtin_function(textsnapshot_hitTestTextNearPos), flags);
+       o.init_member("setSelectColor",
+            new builtin_function(textsnapshot_setSelectColor), flags);
+       o.init_member("setSelected",
+            new builtin_function(textsnapshot_setSelected), flags);
 }
 
 as_object*
 getTextSnapshotInterface()
 {
-    static boost::intrusive_ptr<as_object> o;
-    if ( ! o ) {
-        o = new as_object();
-        attachTextSnapshotInterface(*o);
-    }
-    return o.get();
-}
-
+       static boost::intrusive_ptr<as_object> o;
+       if ( ! o )
+       {
+               o = new as_object(getObjectInterface());
+               attachTextSnapshotInterface(*o);
+       }
+       return o.get();
+}
+
+as_value
+textsnapshot_getTextRunInfo(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextSnapshot_as> ts =
+        ensureType<TextSnapshot_as>(fn.this_ptr);
+    
+    if (!ts->valid()) return as_value();
+
+    if (fn.nargs != 2) {
+        return as_value();
+    }
+
+    size_t start = std::max<boost::int32_t>(0, fn.arg(0).to_int());
+    size_t end = std::max<boost::int32_t>(start + 1, fn.arg(1).to_int());
+
+    Array_as* ri = new Array_as;
+
+    ts->getTextRunInfo(start, end, *ri);
+    
+    return as_value(ri);
+}
+
+as_value
+textsnapshot_findText(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextSnapshot_as> ts =
+        ensureType<TextSnapshot_as>(fn.this_ptr);
+    
+    if (!ts->valid()) return as_value();
+
+    if (fn.nargs != 3) {
+        IF_VERBOSE_ASCODING_ERRORS(
+            log_aserror("TextSnapshot.findText() requires 3 arguments");
+        );
+        return as_value();
+    }
+
+    boost::int32_t start = fn.arg(0).to_int();
+    const std::string& text = fn.arg(1).to_string();
+
+    /// Yes, the pp is case-insensitive by default. We don't write
+    /// functions like that here.
+    bool ignoreCase = !fn.arg(2).to_bool();
+
+    return ts->findText(start, text, ignoreCase);
+}
+
+as_value
+textsnapshot_getCount(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextSnapshot_as> ts =
+        ensureType<TextSnapshot_as>(fn.this_ptr);
+    
+    if (!ts->valid()) return as_value();
+
+    if (fn.nargs) {
+        IF_VERBOSE_ASCODING_ERRORS(
+            log_aserror("TextSnapshot.getCount() takes no arguments");
+        );
+        return as_value();
+    }
+
+    return ts->getCount();
+}
+
+/// Returns a boolean value, or undefined if not valid.
 as_value
 textsnapshot_getSelected(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextSnapshot_as> ptr =
+    boost::intrusive_ptr<TextSnapshot_as> ts =
         ensureType<TextSnapshot_as>(fn.this_ptr);
-    UNUSED(ptr);
-    log_unimpl (__FUNCTION__);
-    return as_value();
+
+    if (!ts->valid()) return as_value();
+
+    if (fn.nargs != 2) {
+        return as_value();
+    }
+
+    size_t start = std::max<boost::int32_t>(0, fn.arg(0).to_int());
+    size_t end = std::max<boost::int32_t>(start + 1, fn.arg(1).to_int());
+
+    return as_value(ts->getSelected(start, end));
 }
 
+/// Returns a string, or undefined if not valid.
 as_value
 textsnapshot_getSelectedText(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextSnapshot_as> ptr =
+    boost::intrusive_ptr<TextSnapshot_as> ts =
         ensureType<TextSnapshot_as>(fn.this_ptr);
-    UNUSED(ptr);
-    log_unimpl (__FUNCTION__);
-    return as_value();
+
+    if (!ts->valid()) return as_value();
+
+    if (fn.nargs > 1) {
+        return as_value();
+    }
+
+    bool newlines = fn.nargs ? fn.arg(0).to_bool() : false;
+
+    return as_value(ts->getSelectedText(newlines));
 }
 
+/// Returns a string, or undefined if not valid.
 as_value
 textsnapshot_getText(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextSnapshot_as> ptr =
-        ensureType<TextSnapshot_as>(fn.this_ptr);
-    UNUSED(ptr);
-    log_unimpl (__FUNCTION__);
-    return as_value();
-}
-
-as_value
-textsnapshot_getTextRunInfo(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextSnapshot_as> ptr =
-        ensureType<TextSnapshot_as>(fn.this_ptr);
-    UNUSED(ptr);
-    log_unimpl (__FUNCTION__);
-    return as_value();
-}
-
+    boost::intrusive_ptr<TextSnapshot_as> ts =
+        ensureType<TextSnapshot_as>(fn.this_ptr);
+
+    if (!ts->valid()) return as_value();
+    
+    if (fn.nargs < 2 || fn.nargs > 3)
+    {
+        IF_VERBOSE_ASCODING_ERRORS(
+            log_aserror("TextSnapshot.getText requires exactly 2 arguments");
+        );
+        return as_value();
+    }
+
+    boost::int32_t start = fn.arg(0).to_int();
+    boost::int32_t end = fn.arg(1).to_int();
+
+    const bool newline = (fn.nargs > 2) ? fn.arg(2).to_bool() : false;
+
+    return ts->getText(start, end, newline);
+
+}
+
+
+/// Returns bool, or undefined if not valid.
 as_value
 textsnapshot_hitTestTextNearPos(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextSnapshot_as> ptr =
+    boost::intrusive_ptr<TextSnapshot_as> ts =
         ensureType<TextSnapshot_as>(fn.this_ptr);
-    UNUSED(ptr);
+
+    if (!ts->valid()) return as_value();
+
     log_unimpl (__FUNCTION__);
     return as_value();
 }
 
+/// Returns void.
 as_value
 textsnapshot_setSelectColor(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextSnapshot_as> ptr =
+    boost::intrusive_ptr<TextSnapshot_as> ts =
         ensureType<TextSnapshot_as>(fn.this_ptr);
-    UNUSED(ptr);
+
     log_unimpl (__FUNCTION__);
     return as_value();
 }
 
+
+/// Returns void.
 as_value
 textsnapshot_setSelected(const fn_call& fn)
 {
-    boost::intrusive_ptr<TextSnapshot_as> ptr =
+    boost::intrusive_ptr<TextSnapshot_as> ts =
         ensureType<TextSnapshot_as>(fn.this_ptr);
-    UNUSED(ptr);
-    log_unimpl (__FUNCTION__);
+
+    if (fn.nargs < 2 || fn.nargs > 3) {
+        return as_value();
+    }
+
+    size_t start = std::max<boost::int32_t>(0, fn.arg(0).to_int());
+    size_t end = std::max<boost::int32_t>(start, fn.arg(1).to_int());
+
+    bool selected = (fn.nargs > 2) ? fn.arg(2).to_bool() : true;
+
+    ts->setSelected(start, end, selected);
+
     return as_value();
 }
 
 as_value
 textsnapshot_ctor(const fn_call& fn)
 {
-    boost::intrusive_ptr<as_object> obj = new TextSnapshot_as;
-
-    return as_value(obj.get()); // will keep alive
+    MovieClip* mc = (fn.nargs == 1) ? fn.arg(0).to_sprite() : 0;
+    return as_value(new TextSnapshot_as(mc));
+}
+
+size_t
+getTextFields(const MovieClip* mc, TextSnapshot_as::TextFields& fields)
+{
+    if (mc) {
+        const DisplayList& dl = mc->getDisplayList();
+
+        TextFinder finder(fields);
+        dl.visitAll(finder);
+        return finder.getCount();
+    }
+    return 0;
+}
+
+void
+setTextReachable(const TextSnapshot_as::TextFields::value_type& vt)
+{
+    vt.first->setReachable();
 }
 
 } // anonymous namespace 

=== modified file 'libcore/asobj/flash/text/TextSnapshot_as.h'
--- a/libcore/asobj/flash/text/TextSnapshot_as.h        2009-05-28 17:29:17 
+0000
+++ b/libcore/asobj/flash/text/TextSnapshot_as.h        2009-06-08 17:00:03 
+0000
@@ -24,14 +24,92 @@
 #include "gnashconfig.h"
 #endif
 
+#include "as_object.h"
+
 
 namespace gnash {
 
+       class StaticText;
+    class Array_as;
+    namespace SWF {
+        class TextRecord;
+    }
+
 // Forward declarations
-class as_object;
-
-/// Initialize the global TextSnapshot class
-void textsnapshot_class_init(as_object& global);
+class TextSnapshot_as: public as_object
+{
+
+public:
+
+    typedef std::vector<const SWF::TextRecord*> Records;
+
+    /// Should remain in the order of insertion
+    /// We should only ever iterate from begin to end, so there's no
+    /// performance issue.
+    typedef std::vector<std::pair<StaticText*, Records> > TextFields;
+
+    /// Construct a TextSnapshot_as from a MovieClip.
+    //
+    /// @param mc       The MovieClip to search for static text. If 0, the
+    ///                 TextSnapshot is invalid, which should be reflected in
+    ///                 AS return values.
+    TextSnapshot_as(const MovieClip* mc);
+
+    static void init(as_object& global);
+
+    std::string getText(boost::int32_t start, boost::int32_t end,
+            bool nl) const;
+
+    boost::int32_t findText(boost::int32_t start, const std::string& text,
+            bool ignoreCase) const;
+
+    bool valid() const { return _valid; }
+
+    size_t getCount() const { return _count; }
+
+    void setSelected(size_t start, size_t end, bool selected);
+    
+    bool getSelected(size_t start, size_t end) const;
+
+    std::string getSelectedText(bool newlines) const;
+
+    void getTextRunInfo(size_t start, size_t end, Array_as& ri) const;
+
+protected:
+
+    void markReachableResources() const;
+
+private:
+
+    /// Generate a string from the TextRecords in this TextSnapshot.
+    //
+    /// @param to           The string to write to
+    /// @param newline      If true, newlines are written after every
+    ///                     StaticText in this TextSnapshot
+    /// @param selectedOnly Only write DisplayObject that are selected to.
+    /// @param start        The start index
+    /// @param len          The number of StaticText DisplayObjects to 
traverse.
+    ///                     This includes non-selected DisplayObjects.
+    void makeString(std::string& to, bool newline = false,
+            bool selectedOnly = false,
+            std::string::size_type start = 0,
+            std::string::size_type len = std::string::npos) const;
+
+    TextFields _textFields;
+
+    /// Whether the object is valid, i.e. it was constructed with a MovieClip.
+    //
+    /// This should be deducible from another member, but since there seems
+    /// to be no point in storing the MovieClip this bool will do instead.
+    const bool _valid;
+
+    /// The number of DisplayObjects
+    //
+    /// There is no need to store this, but it is quicker than counting
+    /// afresh every time.
+    const size_t _count;
+
+};
 
 } // gnash namespace
 

=== modified file 'libcore/asobj/flash/text/text.am'
--- a/libcore/asobj/flash/text/text.am  2009-06-07 18:12:15 +0000
+++ b/libcore/asobj/flash/text/text.am  2009-06-08 17:00:03 +0000
@@ -112,7 +112,7 @@
 
 # FIXME: already exists
 if BUILD_TEXTSNAPSHOT_AS3
-# TEXT_SOURCES += asobj/flash/text/TextSnapshot_as.cpp
+TEXT_SOURCES += asobj/flash/text/TextSnapshot_as.cpp
 TEXT_HEADERS += asobj/flash/text/TextSnapshot_as.h
 endif
 


reply via email to

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