gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] /srv/bzr/gnash/trunk r11043: Merge from branch


From: Bob Naugle
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r11043: Merge from branch
Date: Mon, 08 Jun 2009 16:26:31 -0600
User-agent: Bazaar (1.13.1)

------------------------------------------------------------
revno: 11043
committer: Bob Naugle <address@hidden>
branch nick: trunk
timestamp: Mon 2009-06-08 16:26:31 -0600
message:
  Merge from branch
removed:
  libcore/TextField.cpp
  libcore/TextField.h
modified:
  libcore/ClassHierarchy.cpp
  libcore/Makefile.am
  libcore/MovieClip.cpp
  libcore/MovieClip.h
  libcore/asobj/Global.cpp
  libcore/asobj/Selection_as.cpp
  libcore/asobj/flash/text/TextField_as.cpp
  libcore/asobj/flash/text/TextField_as.h
  libcore/asobj/flash/text/TextFormat_as.cpp
  libcore/asobj/flash/text/TextFormat_as.h
  libcore/asobj/flash/text/text.am
  libcore/swf/DefineEditTextTag.cpp
  libcore/swf/DefineEditTextTag.h
  testsuite/as3/classes.all/text/TextField_as.hx
    ------------------------------------------------------------
    revno: 11042.1.1
    committer: Bob Naugle <address@hidden>
    branch nick: development
    timestamp: Mon 2009-06-08 16:24:55 -0600
    message:
      Migrated TextField to new file and directory. Modified makefiles, 
dependencies, and test cases accordingly.
    removed:
      libcore/TextField.cpp
      libcore/TextField.h
    modified:
      libcore/ClassHierarchy.cpp
      libcore/Makefile.am
      libcore/MovieClip.cpp
      libcore/MovieClip.h
      libcore/asobj/Global.cpp
      libcore/asobj/Selection_as.cpp
      libcore/asobj/flash/text/TextField_as.cpp
      libcore/asobj/flash/text/TextField_as.h
      libcore/asobj/flash/text/TextFormat_as.cpp
      libcore/asobj/flash/text/TextFormat_as.h
      libcore/asobj/flash/text/text.am
      libcore/swf/DefineEditTextTag.cpp
      libcore/swf/DefineEditTextTag.h
      testsuite/as3/classes.all/text/TextField_as.hx
=== modified file 'libcore/ClassHierarchy.cpp'
--- a/libcore/ClassHierarchy.cpp        2009-06-08 22:15:34 +0000
+++ b/libcore/ClassHierarchy.cpp        2009-06-08 22:24:55 +0000
@@ -58,7 +58,7 @@
 #include "VM.h"
 #include "URL.h" // for URL::encode and URL::decode (escape/unescape)
 #include "builtin_function.h"
-#include "TextField.h"
+#include "flash/text/TextField_as.h"
 #include "namedStrings.h"
 #include "ClassHierarchy.h"
 #include "builtin_function.h"
@@ -292,7 +292,7 @@
        { system_class_init, NSV::CLASS_SYSTEM, 0, NSV::NS_FLASH_SYSTEM, 1 },
        { stage_class_init, NSV::CLASS_STAGE, 0, NSV::NS_FLASH_DISPLAY, 1 },
        { movieclip_class_init, NSV::CLASS_MOVIE_CLIP, 0, 
NSV::NS_FLASH_DISPLAY, 3 },
-       { textfield_class_init, NSV::CLASS_TEXT_FIELD, 0, NSV::NS_FLASH_TEXT, 3 
},
+       { TextField_as::init, NSV::CLASS_TEXT_FIELD, 0, NSV::NS_FLASH_TEXT, 3 },
        { math_class_init, NSV::CLASS_MATH, 0, NS_GLOBAL, 4 },
        { boolean_class_init, NSV::CLASS_BOOLEAN, NSV::CLASS_OBJECT, NS_GLOBAL, 
5 },
        { Button::init, NSV::CLASS_BUTTON, NSV::CLASS_OBJECT, NS_GLOBAL, 5 },

=== modified file 'libcore/Makefile.am'
--- a/libcore/Makefile.am       2009-06-06 23:27:19 +0000
+++ b/libcore/Makefile.am       2009-06-08 22:24:55 +0000
@@ -70,16 +70,15 @@
        Shape.cpp \
        MorphShape.cpp \
        StaticText.cpp \
-       TextField.cpp \
-        BlurFilter.cpp \
-        GlowFilter.cpp \
-        DropShadowFilter.cpp \
-        ConvolutionFilter.cpp \
-        ColorMatrixFilter.cpp \
-        GradientGlowFilter.cpp \
-        BevelFilter.cpp \
-        GradientBevelFilter.cpp \
-        parser/filter_factory.cpp \
+    BlurFilter.cpp \
+    GlowFilter.cpp \
+    DropShadowFilter.cpp \
+    ConvolutionFilter.cpp \
+    ColorMatrixFilter.cpp \
+    GradientGlowFilter.cpp \
+    BevelFilter.cpp \
+    GradientBevelFilter.cpp \
+    parser/filter_factory.cpp \
        InteractiveObject.cpp \
        SWFMatrix.cpp \
        SWFMovie.cpp \
@@ -146,17 +145,16 @@
        BitmapMovie.h \
        Button.h \
        debugger.h \
-       TextField.h \
-        BitmapFilter.h \
-        BlurFilter.h \
-        BevelFilter.h \
-        GradientBevelFilter.h \
-        GlowFilter.h \
-        GradientGlowFilter.h \
-        DropShadowFilter.h \
-        ConvolutionFilter.h \
-        ColorMatrixFilter.h \
-        parser/filter_factory.h \
+    BitmapFilter.h \
+    BlurFilter.h \
+    BevelFilter.h \
+    GradientBevelFilter.h \
+    GlowFilter.h \
+    GradientGlowFilter.h \
+    DropShadowFilter.h \
+    ConvolutionFilter.h \
+    ColorMatrixFilter.h \
+    parser/filter_factory.h \
        Font.h \
        fontlib.h \
        Shape.h \

=== modified file 'libcore/MovieClip.cpp'
--- a/libcore/MovieClip.cpp     2009-06-08 21:40:22 +0000
+++ b/libcore/MovieClip.cpp     2009-06-08 22:24:55 +0000
@@ -28,7 +28,7 @@
 #include "as_value.h"
 #include "as_function.h"
 #include "Bitmap.h"
-#include "TextField.h"
+#include "text/TextField_as.h"
 #include "ControlTag.h"
 #include "fn_call.h"
 #include "flash/ui/Keyboard_as.h"
@@ -638,7 +638,7 @@
         for (TextFields::const_iterator i=etc->begin(), e=etc->end();
                 i!=e; ++i)
         {
-            boost::intrusive_ptr<TextField> tf = i->get();
+            boost::intrusive_ptr<TextField_as> tf = i->get();
             if ( tf->getTextDefined() )
             {
                 val->set_string(tf->get_text_value());
@@ -767,7 +767,7 @@
     rect bounds(0, 0, pixelsToTwips(width), pixelsToTwips(height));
 
     // Create an instance
-    boost::intrusive_ptr<DisplayObject> txt_char = new TextField(this, bounds);
+    boost::intrusive_ptr<DisplayObject> txt_char = new TextField_as(this, 
bounds);
 
     // Give name and mark as dynamic
     txt_char->set_name(name);
@@ -1970,7 +1970,7 @@
 
 
 void
-MovieClip::set_textfield_variable(const std::string& name, TextField* ch)
+MovieClip::set_textfield_variable(const std::string& name, TextField_as* ch)
 {
     assert(ch);
 

=== modified file 'libcore/MovieClip.h'
--- a/libcore/MovieClip.h       2009-06-03 13:34:35 +0000
+++ b/libcore/MovieClip.h       2009-06-08 22:24:55 +0000
@@ -46,7 +46,7 @@
     class drag_state;
     class LoadVariablesThread;
     class gradient_record;
-    class TextField;
+    class TextField_as;
     class BitmapData_as;
     class BitmapInfo;
     namespace SWF {
@@ -588,7 +588,7 @@
     /// A TextField variable is a variable that acts
     /// as a setter/getter for a TextField 'text' member.
     ///
-    void set_textfield_variable(const std::string& name, TextField* ch);
+    void set_textfield_variable(const std::string& name, TextField_as* ch);
 
     void add_invalidated_bounds(InvalidatedRanges& ranges, bool force);
     
@@ -809,7 +809,7 @@
 
 private:
 
-    typedef std::vector<boost::intrusive_ptr<TextField> > TextFields;
+    typedef std::vector<boost::intrusive_ptr<TextField_as> > TextFields;
 
     /// A container for textfields, indexed by their variable name
     typedef std::map<std::string, TextFields> TextFieldIndex;

=== removed file 'libcore/TextField.cpp'
--- a/libcore/TextField.cpp     2009-06-08 22:15:34 +0000
+++ b/libcore/TextField.cpp     1970-01-01 00:00:00 +0000
@@ -1,2845 +0,0 @@
-// TextField.cpp:  User-editable text regions, 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 "utf8.h"
-#include "log.h"
-#include "swf/DefineEditTextTag.h"
-#include "render.h"
-#include "movie_definition.h" // to extract version info
-#include "MovieClip.h"
-#include "TextField.h"
-#include "flash/ui/Keyboard_as.h" // for keyboard events
-#include "movie_root.h"     // for killing focus
-#include "as_environment.h" // for parse_path
-#include "action.h" // for as_standard_member enum
-#include "VM.h"
-#include "builtin_function.h" // for getter/setter properties
-#include "Font.h" // for using the _font member
-#include "fontlib.h" // for searching or adding fonts the _font member
-#include "Object.h" // for getObjectInterface
-#include "namedStrings.h"
-#include "Array_as.h" // for _listeners construction
-#include "AsBroadcaster.h" // for initializing self as a broadcaster
-#include "StringPredicates.h"
-#include "text/TextFormat_as.h" // for getTextFormat/setTextFormat
-#include "GnashKey.h" // key::code
-#include "TextRecord.h"
-#include "Point2d.h"
-#include "GnashNumeric.h"
-
-#include <algorithm> // std::min
-#include <string>
-#include <boost/algorithm/string/case_conv.hpp>
-#include <boost/assign/list_of.hpp>
-#include <boost/bind.hpp>
-
-// Text fields have a fixed 2 pixel padding for each side (regardless of 
border)
-#define PADDING_TWIPS 40 
-
-// Define the following to get detailed log information about
-// textfield bounds and HTML tags:
-//#define GNASH_DEBUG_TEXTFIELDS 1
-
-// Define this to get debugging info about text formatting
-//#define GNASH_DEBUG_TEXT_FORMATTING 1
-
-namespace gnash {
-
-// Forward declarations
-namespace {
-    as_object* getTextFieldInterface(VM& vm);
-    void attachPrototypeProperties(as_object& proto);
-    void attachTextFieldStaticMembers(as_object& o);
-
-    as_value textfield_variable(const fn_call& fn);
-    as_value textfield_setTextFormat(const fn_call& fn);
-    as_value textfield_getTextFormat(const fn_call& fn);
-    as_value textfield_setNewTextFormat(const fn_call& fn);
-    as_value textfield_getNewTextFormat(const fn_call& fn);
-    as_value textfield_getDepth(const fn_call& fn);
-    as_value textfield_getFontList(const fn_call& fn);
-    as_value textfield_removeTextField(const fn_call& fn);
-    as_value textfield_replaceSel(const fn_call& fn);
-    as_value textfield_replaceText(const fn_call& fn);
-
-    as_value textfield_password(const fn_call& fn);
-    as_value textfield_ctor(const fn_call& fn);
-    as_value textfield_multiline(const fn_call& fn);
-    as_value textfield_scroll(const fn_call& fn);
-    as_value textfield_maxscroll(const fn_call& fn);
-    as_value textfield_maxhscroll(const fn_call& fn);
-    as_value textfield_maxChars(const fn_call& fn);
-    as_value textfield_bottomScroll(const fn_call& fn);
-    as_value textfield_hscroll(const fn_call& fn);
-    as_value textfield_htmlText(const fn_call& fn);
-    as_value textfield_restrict(const fn_call& fn);
-    as_value textfield_background(const fn_call& fn);
-    as_value textfield_border(const fn_call& fn);
-    as_value textfield_backgroundColor(const fn_call& fn);
-    as_value textfield_borderColor(const fn_call& fn);
-    as_value textfield_text(const fn_call& fn);
-    as_value textfield_textColor(const fn_call& fn);
-    as_value textfield_embedFonts(const fn_call& fn);
-    as_value textfield_autoSize(const fn_call& fn);
-    as_value textfield_type(const fn_call& fn);
-    as_value textfield_wordWrap(const fn_call& fn);
-    as_value textfield_html(const fn_call& fn);
-    as_value textfield_selectable(const fn_call& fn);
-    as_value textfield_length(const fn_call& fn);
-    as_value textfield_textWidth(const fn_call& fn);
-    as_value textfield_textHeight(const fn_call& fn);
-}
-
-TextField::TextField(DisplayObject* parent, const SWF::DefineEditTextTag& def,
-        int id)
-    :
-    InteractiveObject(parent, id),
-    _tag(&def),
-    _textDefined(def.hasText()),
-    _underlined(false),
-    _leading(def.leading()),
-    _alignment(def.alignment()),
-    _indent(def.indent()), 
-    _blockIndent(0),
-    _leftMargin(def.leftMargin()), 
-    _rightMargin(def.rightMargin()), 
-    _fontHeight(def.textHeight()), 
-    _font(0),
-    m_has_focus(false),
-    m_cursor(0u),
-    m_xcursor(0.0f),
-    m_ycursor(0.0f),
-    _multiline(def.multiline()),
-    _password(def.password()),
-    _maxChars(def.maxChars()),
-    _text_variable_registered(false),
-    _variable_name(def.variableName()),
-    _drawBackground(def.border()),
-    _backgroundColor(255,255,255,255),
-    _drawBorder(def.border()),
-    _borderColor(0,0,0,255),
-    _textColor(def.color()),
-    _embedFonts(def.getUseEmbeddedGlyphs()),
-    _wordWrap(def.wordWrap()),
-    _html(def.html()),
-    _selectable(!def.noSelect()),
-    _autoSize(autoSizeNone),
-    _type(def.readOnly() ? typeDynamic : typeInput),
-    _bounds(def.bounds()),
-    _selection(0, 0)
-{
-
-    // WARNING! remember to set the font *before* setting text value!
-    boost::intrusive_ptr<const Font> f = def.getFont();
-    if (!f) f = fontlib::get_default_font(); 
-    setFont(f);
-
-    int version = parent->getVM().getSWFVersion();
-    
-    // set default text *before* calling registerTextVariable
-    // (if the textvariable already exist and has a value
-    // the text will be replaced with it)
-    if (_textDefined) 
-    {
-        setTextValue(utf8::decodeCanonicalString(def.defaultText(), version));
-    }
-
-    init();
-
-}
-
-TextField::TextField(DisplayObject* parent, const rect& bounds)
-    :
-    // the id trick is to fool assertions in DisplayObject ctor
-    InteractiveObject(parent, parent ? 0 : -1),
-    _textDefined(false),
-    _underlined(false),
-    _leading(0),
-    _alignment(ALIGN_LEFT),
-    _indent(0), 
-    _blockIndent(0),
-    _leftMargin(0), 
-    _rightMargin(0), 
-    _fontHeight(12 * 20), 
-    _font(0),
-    m_has_focus(false),
-    m_cursor(0u),
-    m_xcursor(0.0f),
-    m_ycursor(0.0f),
-    _multiline(false),
-    _password(false),
-    _maxChars(0),
-    _text_variable_registered(false),
-    _drawBackground(false),
-    _backgroundColor(255,255,255,255),
-    _drawBorder(false),
-    _borderColor(0, 0, 0, 255),
-    _textColor(0, 0, 0, 255),
-    _embedFonts(false), // ?
-    _wordWrap(false),
-    _html(false),
-    _selectable(true),
-    _autoSize(autoSizeNone),
-    _type(typeDynamic),
-    _bounds(bounds),
-    _selection(0, 0)
-{
-    // Use the default font (Times New Roman for Windows, Times for Mac
-    // according to docs. They don't say what it is for Linux.
-    boost::intrusive_ptr<const Font> f = fontlib::get_default_font(); 
-    setFont(f);
-
-    init();
-}
-
-void
-TextField::init()
-{
-
-    as_object* proto = getTextFieldInterface(_vm);
- 
-    // This is an instantiation, so attach properties to the
-    // prototype.
-    // TODO: is it correct to do it here, or can some TextFields
-    // be constructed without attaching these?
-    attachPrototypeProperties(*proto);
-
-    set_prototype(proto);
-
-    Array_as* ar = new Array_as();
-    ar->push(this);
-    set_member(NSV::PROP_uLISTENERS, ar);
-    
-    registerTextVariable();
-
-    reset_bounding_box(0, 0);
-}
-
-
-TextField::~TextField()
-{
-}
-
-void
-TextField::removeTextField()
-{
-    int depth = get_depth();
-    if ( depth < 0 || depth > 1048575 )
-    {
-        //IF_VERBOSE_ASCODING_ERRORS(
-        log_debug(_("CHECKME: removeTextField(%s): TextField depth (%d) "
-            "out of the 'dynamic' zone [0..1048575], won't remove"),
-            getTarget(), depth);
-        //);
-        return;
-    }
-
-    DisplayObject* parent = get_parent();
-    assert(parent); // every TextField must have a parent, right ?
-
-    MovieClip* parentSprite = parent->to_movie();
-
-    if (!parentSprite)
-    {
-        log_error("FIXME: attempt to remove a TextField being a child of a %s",
-                typeName(*parent));
-        return;
-    }
-
-    // second argument is arbitrary, see comments above
-    // the function declaration in MovieClip.h
-    parentSprite->remove_display_object(depth, 0);
-}
-
-void
-TextField::show_cursor(const SWFMatrix& mat)
-{
-    boost::uint16_t x = static_cast<boost::uint16_t>(m_xcursor);
-    boost::uint16_t y = static_cast<boost::uint16_t>(m_ycursor);
-    boost::uint16_t h = getFontHeight();
-
-    const std::vector<point> box = boost::assign::list_of
-        (point(x, y))
-        (point(x, y + h));
-    
-    render::drawLine(box, rgba(0,0,0,255), mat);
-}
-
-void
-TextField::display()
-{
-
-    registerTextVariable();
-
-    const bool drawBorder = getDrawBorder();
-    const bool drawBackground = getDrawBackground();
-
-    const SWFMatrix& wmat = getWorldMatrix();
-
-    if ((drawBorder || drawBackground) && !_bounds.is_null())
-    {
-
-        std::vector<point> coords(4);
-
-        boost::int32_t xmin = _bounds.get_x_min();
-        boost::int32_t xmax = _bounds.get_x_max();
-        boost::int32_t ymin = _bounds.get_y_min();
-        boost::int32_t ymax = _bounds.get_y_max();
-
-        coords[0].setTo(xmin, ymin); 
-        coords[1].setTo(xmax, ymin); 
-        coords[2].setTo(xmax, ymax); 
-        coords[3].setTo(xmin, ymax); 
-
-        rgba borderColor = drawBorder ? getBorderColor() : rgba(0,0,0,0);
-        rgba backgroundColor = drawBackground ? getBackgroundColor() :
-                                                rgba(0,0,0,0);
-
-        cxform cx = get_world_cxform();
-            
-        if (drawBorder) borderColor = cx.transform(borderColor);
-         
-        if (drawBackground) backgroundColor = cx.transform(backgroundColor);
-        
-#ifdef GNASH_DEBUG_TEXTFIELDS
-    log_debug("rendering a Pol composed by corners %s", _bounds);
-#endif
-
-        render::draw_poly(&coords.front(), 4, backgroundColor, 
-                borderColor, wmat, true);
-        
-    }
-
-    // Draw our actual text.
-    // Using a SWFMatrix to translate to def bounds seems an hack to me.
-    // A cleaner implementation is likely correctly setting the
-    // _xOffset and _yOffset memebers in glyph records.
-    // Anyway, see bug #17954 for a testcase.
-    SWFMatrix m = getWorldMatrix();
-
-    if (!_bounds.is_null()) {
-        m.concatenate_translation(_bounds.get_x_min(), _bounds.get_y_min()); 
-    }
-    
-    SWF::TextRecord::displayRecords(m, get_world_cxform(), _textRecords,
-            _embedFonts);
-
-    if (m_has_focus) show_cursor(wmat);
-    
-    clear_invalidated();
-}
-
-
-void
-TextField::add_invalidated_bounds(InvalidatedRanges& ranges, 
-    bool force)
-{
-    if (!force && !m_invalidated) return; // no need to redraw
-    
-    ranges.add(m_old_invalidated_ranges);
-
-    const SWFMatrix& wm = getWorldMatrix();
-
-    rect bounds = getBounds();
-    bounds.expand_to_rect(m_text_bounding_box); 
-    wm.transform(bounds);
-    ranges.add(bounds.getRange());            
-}
-
-void
-TextField::replaceSelection(const std::string& replace)
-{
-
-    const int version = _vm.getSWFVersion();
-    const std::wstring& wstr = utf8::decodeCanonicalString(replace, version);
-    
-    const size_t start = _selection.first;
-    const size_t replaceLength = wstr.size();
-
-    _text.replace(start, _selection.second - start, wstr);
-    _selection = std::make_pair(start + replaceLength, start + replaceLength);
-}
-
-void
-TextField::setSelection(int start, int end)
-{
-
-    if (_text.empty()) {
-        _selection = std::make_pair(0, 0);
-        return;
-    }
-
-    const size_t textLength = _text.size();
-
-    if (start < 0) start = 0;
-    else start = std::min<size_t>(start, textLength);
-
-    if (end < 0) end = 0;
-    else end = std::min<size_t>(end, textLength);
-
-    // The cursor position is always set to the end value, even if the
-    // two values are swapped to obtain the selection. Equal values are
-    // fine.
-    m_cursor = end;
-    if (start > end) std::swap(start, end);
-
-    _selection = std::make_pair(start, end);
-}
-bool
-TextField::on_event(const event_id& ev)
-{
-    if (isReadOnly()) return false;
-
-    switch (ev.id())
-    {
-        case event_id::KEY_PRESS:
-        {
-            if ( getType() != typeInput ) break; // not an input field
-            std::wstring s = _text;
-
-            // id.keyCode is the unique gnash::key::code for a 
DisplayObject/key.
-            // The maximum value is about 265, including function keys.
-            // It seems that typing in DisplayObjects outside the Latin-1 set
-            // (256 DisplayObject codes, identical to the first 256 of UTF-8)
-            // is not supported, though a much greater number UTF-8 codes can 
be
-            // stored and displayed. See utf.h for more information.
-            // This is a limit on the number of key codes, not on the
-            // capacity of strings.
-            gnash::key::code c = ev.keyCode();
-
-            // maybe _text is changed in ActionScript
-            m_cursor = std::min<size_t>(m_cursor, _text.size());
-
-            switch (c)
-            {
-                case key::BACKSPACE:
-                    if (m_cursor > 0)
-                    {
-                        s.erase(m_cursor - 1, 1);
-                        m_cursor--;
-                        setTextValue(s);
-                    }
-                    break;
-
-                case key::DELETEKEY:
-                    if (s.size() > m_cursor)
-                    {
-                        s.erase(m_cursor, 1);
-                        setTextValue(s);
-                    }
-                    break;
-
-                case key::INSERT:        // TODO
-                    break;
-
-                case key::HOME:
-                case key::PGUP:
-                case key::UP:
-                    m_cursor = 0;
-                    format_text();
-                    break;
-
-                case key::END:
-                case key::PGDN:
-                case key::DOWN:
-                    m_cursor = _text.size();
-                    format_text();
-                    break;
-
-                case key::LEFT:
-                    m_cursor = m_cursor > 0 ? m_cursor - 1 : 0;
-                    format_text();
-                    break;
-
-                case key::RIGHT:
-                    m_cursor = m_cursor < _text.size() ? m_cursor + 1 :
-                                                        _text.size();
-                    format_text();
-                    break;
-
-                default:
-                    wchar_t t = static_cast<wchar_t>(
-                            gnash::key::codeMap[c][key::ASCII]);
-                    if (t != 0)
-                    {
-                        // Insert one copy of the DisplayObject
-                        // at the cursor position.
-                          s.insert(m_cursor, 1, t);
-                        m_cursor++;
-                    }
-                    setTextValue(s);
-                    break;
-            }
-            onChanged();
-        }
-
-        default:
-            return false;
-    }
-    return true;
-}
-
-InteractiveObject*
-TextField::topmostMouseEntity(boost::int32_t x, boost::int32_t y)
-{
-
-    if (!visible()) return 0;
-    
-    // shouldn't this be !can_handle_mouse_event() instead ?
-    // not selectable, so don't catch mouse events!
-    if (!_selectable) return 0;
-
-    SWFMatrix m = getMatrix();
-    point p(x, y);
-    m.invert().transform(p);
-
-    if (_bounds.point_test(p.x, p.y)) return this;
-
-    return 0;
-}
-
-void
-TextField::updateText(const std::string& str)
-{
-    int version = _vm.getSWFVersion();
-    const std::wstring& wstr = utf8::decodeCanonicalString(str, version);
-    updateText(wstr);
-}
-
-void
-TextField::updateText(const std::wstring& wstr)
-{
-    _textDefined = true;
-
-    if (_text == wstr) return;
-
-    set_invalidated();
-
-    _text = wstr;
-    format_text();
-}
-
-void
-TextField::setTextValue(const std::wstring& wstr)
-{
-
-    updateText(wstr);
-
-    if ( ! _variable_name.empty() && _text_variable_registered )
-    {
-        // TODO: notify MovieClip if we have a variable name !
-        VariableRef ref = parseTextVariableRef(_variable_name);
-        as_object* tgt = ref.first;
-        if ( tgt )
-        {
-            int version = _vm.getSWFVersion();
-            // we shouldn't truncate, right?
-            tgt->set_member(ref.second, utf8::encodeCanonicalString(wstr,
-                        version)); 
-        }
-        else    
-        {
-            // nothing to do (too early ?)
-            log_debug("setTextValue: variable name %s points to a non-existent"
-                    " target, I guess we would not be registered if this was "
-                    "true, or the sprite we've registered our variable name "
-                    "has been unloaded", _variable_name);
-        }
-    }
-}
-
-std::string
-TextField::get_text_value() const
-{
-    // we need the const_cast here because registerTextVariable
-    // *might* change our text value, calling the non-const
-    // setTextValue().
-    // This happens if the TextVariable has not been already registered
-    // and during registration comes out to name an existing variable
-    // with a pre-existing value.
-    const_cast<TextField*>(this)->registerTextVariable();
-
-    int version = _vm.getSWFVersion();
-
-    return utf8::encodeCanonicalString(_text, version);
-}
-
-bool
-TextField::set_member(string_table::key name,
-        const as_value& val, string_table::key nsname, bool ifFound)
-{
-
-    // FIXME: Turn all standard members into getter/setter properties
-    //        of the TextField class. See attachTextFieldInterface()
-    // @@ TODO need to inherit basic stuff like _x, _y, _xscale, _yscale etc ?
-
-    switch (name)
-    {
-    default:
-        break;
-    case NSV::PROP_uX:
-    {
-        SWFMatrix m = getMatrix();
-        double x = infinite_to_zero( val.to_number() );
-        m.tx = pixelsToTwips(x);    
-        setMatrix(m); // no need to update caches when only changing 
translation
-
-        // m_accept_anim_moves = false;
-        return true;
-    }
-    case NSV::PROP_uY:
-    {
-        SWFMatrix m = getMatrix();
-        double y = infinite_to_zero( val.to_number() );
-        m.ty = pixelsToTwips(y);
-        setMatrix(m); // no need to update caches when only changing 
translation
-
-        // m_accept_anim_moves = false; 
-        return true;
-    }
-    case NSV::PROP_uWIDTH:
-    {
-        double nw = val.to_number(); 
-        if (!isFinite(nw) )
-        {
-            // might be our fault, see the TODO above 
-            // (missing to pass as_environment out..)
-            IF_VERBOSE_ASCODING_ERRORS(
-            log_aserror(_("Attempt to set TextField._width to %g"), nw);
-            );
-            return true;
-        }
-
-        if ( nw < 0 )
-        {
-            IF_VERBOSE_ASCODING_ERRORS(
-            log_aserror(_("Attempt to set TextField._width to a "
-                    "negative number: %g, toggling sign"), nw);
-            );
-            nw = -nw;
-        }
-
-        if ( _bounds.width() == pixelsToTwips(nw) )
-        {
-#ifdef GNASH_DEBUG_TEXTFIELDS
-            log_debug("TextField width already == %g, nothing to do to "
-                    "change it", nw);
-#endif
-            return true; // nothing to do
-        }
-        if ( _bounds.is_null() )
-        {
-#ifdef GNASH_DEBUG_TEXTFIELDS
-            log_debug("NULL TextField bounds : %s", _bounds);
-#endif
-            return true;
-        }
-
-#ifdef GNASH_DEBUG_TEXTFIELDS
-        log_debug("Chaging TextField width to %g", nw);
-#endif
-
-        set_invalidated();
-
-        // Modify TextField drawing rectangle
-        // TODO: check which anchor point we should use !
-        boost::int32_t xmin = _bounds.get_x_min();
-        boost::int32_t ymin = _bounds.get_y_min();
-        boost::int32_t ymax = _bounds.get_y_max();
-        boost::int32_t xmax = xmin + pixelsToTwips(nw);
-
-        assert(xmin <= xmax);
-        _bounds.set_to_rect(xmin, ymin, xmax, ymax);
-        assert( _bounds.width() == pixelsToTwips(nw) );
-
-        // previously truncated text might get visible now
-        // TODO: if nested masks were implemented we would 
-        // not need to reformat text here
-        format_text();
-
-        return true;
-    }
-    case NSV::PROP_uHEIGHT:
-    {
-        double nh = val.to_number(); 
-        if (!isFinite(nh) )
-        {
-            // might be our fault, see the TODO above (missing to pass
-            // as_environment out..)
-            IF_VERBOSE_ASCODING_ERRORS(
-            log_aserror(_("Attempt to set TextField._height to %g"), nh);
-            );
-            return true;
-        }
-
-        if ( nh < 0.0f )
-        {
-            IF_VERBOSE_ASCODING_ERRORS(
-            log_aserror(_("Attempt to set TextField._height to a negative "
-                    "number: %g, toggling sign"), nh);
-            );
-            nh = -nh;
-        }
-
-        if ( _bounds.height() == pixelsToTwips(nh) )
-        {
-#ifdef GNASH_DEBUG_TEXTFIELDS
-            log_debug("TextField height already == %g, nothing to do to "
-                    "change it", nh);
-#endif // GNASH_DEBUG_TEXTFIELDS
-            return true; // nothing to do
-        }
-        if ( _bounds.is_null() )
-        {
-            return true;
-        }
-
-#ifdef GNASH_DEBUG_TEXTFIELDS
-        log_debug("Changing TextField height to %g", nh);
-#endif // GNASH_DEBUG_TEXTFIELDS
-        set_invalidated();
-
-        // Modify TextField drawing rectangle
-        // TODO: check which anchor point we should use !
-        boost::int32_t xmin = _bounds.get_x_min();
-        boost::int32_t xmax = _bounds.get_x_max();
-        boost::int32_t ymin = _bounds.get_y_min();
-        _bounds.set_to_rect(xmin, ymin, xmax, ymin + pixelsToTwips(nh) );
-
-        assert(_bounds.height() == pixelsToTwips(nh));
-
-        // previously truncated text might get visible now
-        // TODO: if nested masks were implemented we would 
-        // not need to reformat text here
-        format_text();
-
-        return true;
-    }
-    case NSV::PROP_uVISIBLE:
-    {
-        set_visible(val.to_bool());
-        return true;
-    }
-    case NSV::PROP_uALPHA:
-    {
-        // @@ TODO this should be generic to class DisplayObject!
-        // Arg is in percent.
-        cxform    cx = get_cxform();
-        cx.aa = (boost::int16_t)(val.to_number() * 2.56);
-        set_cxform(cx);
-        return true;
-    }
-    // @@ TODO see TextField members in Flash MX docs
-    }    // end switch
-
-
-    return as_object::set_member(name, val, nsname, ifFound);
-}
-
-bool
-TextField::get_member(string_table::key name, as_value* val,
-    string_table::key nsname)
-{
-    //log_debug("TextField.get_member(%s)", name);
-
-    // FIXME: Turn all standard members into getter/setter properties
-    //        of the TextField class. See attachTextFieldInterface()
-
-    switch (name)
-    {
-    default:
-        break;
-    case NSV::PROP_uVISIBLE:
-    {
-        val->set_bool(visible());
-        return true;
-    }
-    case NSV::PROP_uALPHA:
-    {
-        // @@ TODO this should be generic to class DisplayObject!
-        const cxform&    cx = get_cxform();
-        val->set_double(cx.aa / 2.56);
-        return true;
-    }
-    case NSV::PROP_uX:
-    {
-        SWFMatrix    m = getMatrix();    
-        val->set_double(twipsToPixels(m.tx));
-        return true;
-    }
-    case NSV::PROP_uY:
-    {
-        SWFMatrix    m = getMatrix();    
-        val->set_double(twipsToPixels(m.ty));
-        return true;
-    }
-    case NSV::PROP_uWIDTH:
-    {
-        val->set_double(twipsToPixels(get_width()));
-#ifdef GNASH_DEBUG_TEXTFIELDS
-        log_debug("Got TextField width == %s", *val);
-#endif // GNASH_DEBUG_TEXTFIELDS
-        return true;
-    }
-    case NSV::PROP_uHEIGHT:
-    {
-        val->set_double(twipsToPixels(get_height()));
-#ifdef GNASH_DEBUG_TEXTFIELDS
-        log_debug("Got TextField height == %s", *val);
-#endif // GNASH_DEBUG_TEXTFIELDS
-        return true;
-    }
-    }    // end switch
-
-    return as_object::get_member(name, val, nsname);
-    
-}
-    
-
-float
-TextField::align_line(TextAlignment align,
-        int last_line_start_record, float x)
-{
-
-    float width = _bounds.width(); 
-    float right_margin = getRightMargin();
-
-    float extra_space = (width - right_margin) - x - PADDING_TWIPS;
-
-    //assert(extra_space >= 0.0f);
-    if (extra_space <= 0.0f)
-    {
-#ifdef GNASH_DEBUG_TEXTFIELDS
-        log_debug(_("TextField text doesn't fit in its boundaries: "
-                "width %g, margin %g - nothing to align"),
-                width, right_margin);
-#endif
-        return 0.0f;
-    }
-
-    float shift_right = 0.0f;
-
-    if (align == ALIGN_LEFT)
-    {
-        // Nothing to do; already aligned left.
-        return 0.0f;
-    }
-    else if (align == ALIGN_CENTER)
-    {
-        // Distribute the space evenly on both sides.
-        shift_right = extra_space / 2;
-    }
-    else if (align == ALIGN_RIGHT)
-    {
-        // Shift all the way to the right.
-        shift_right = extra_space;
-    }
-
-    // Shift the beginnings of the records on this line.
-    for (unsigned int i = last_line_start_record; i < _textRecords.size(); ++i)
-    {
-        SWF::TextRecord& rec = _textRecords[i];
-
-        //if ( rec.hasXOffset() ) // why?
-            rec.setXOffset(rec.xOffset() + shift_right); 
-    }
-    return shift_right;
-}
-
-boost::intrusive_ptr<const Font>
-TextField::setFont(boost::intrusive_ptr<const Font> newfont)
-{
-    if ( newfont == _font ) return _font;
-
-    boost::intrusive_ptr<const Font> oldfont = _font;
-    set_invalidated();
-    _font = newfont; 
-    format_text();
-    return oldfont;  
-}
-
-
-void
-TextField::insertTab(SWF::TextRecord& rec, boost::int32_t& x, float scale)
-{
-    // tab (ASCII HT)
-    const int space = 32;
-    int index = rec.getFont()->get_glyph_index(space, _embedFonts); 
-    if ( index == -1 )
-    {
-        IF_VERBOSE_MALFORMED_SWF (
-          log_error(_("TextField: missing glyph for space char (needed "
-                  "for TAB). Make sure DisplayObject shapes for font "
-                  "%s are being exported into your SWF file."),
-                rec.getFont()->name());
-        );
-    }
-    else
-    {
-        SWF::TextRecord::GlyphEntry ge;
-        ge.index = index;
-        ge.advance = scale * rec.getFont()->get_advance(index, 
-                _embedFonts);
-
-        const int tabstop = 8;
-        rec.addGlyph(ge, tabstop);
-        x += ge.advance * tabstop;
-    }
-}
-
-void
-TextField::format_text()
-{
-    _textRecords.clear();
-
-    // nothing more to do if text is empty
-    if ( _text.empty() )
-    {
-        // TODO: should we still reset _bounds if autoSize != autoSizeNone ?
-        //       not sure we should...
-        reset_bounding_box(0, 0);
-        return;
-    }
-
-    // See bug #24266
-    const rect& defBounds = _bounds;
-
-    AutoSizeValue autoSize = getAutoSize();
-    if ( autoSize != autoSizeNone )
-    {
-        // define GNASH_DEBUG_TEXT_FORMATTING on top to get useful info
-        //LOG_ONCE( log_debug(_("TextField.autoSize != 'none' TESTING")) );
-
-        // When doing WordWrap we don't want to change
-        // the boundaries. See bug #24348
-        if (!  doWordWrap() )
-        {
-            _bounds.set_to_rect(0, 0, 0, 0); // this is correct for 'true'
-        }
-    }
-
-    // Should get info from autoSize too maybe ?
-    TextAlignment textAlignment = getTextAlignment();
-
-    // FIXME: I don't think we should query the definition
-    // to find the appropriate font to use, as ActionScript
-    // code should be able to change the font of a TextField
-    //
-    if (!_font)
-    {
-        log_error(_("No font for TextField!"));
-        return;
-    }
-
-    boost::uint16_t fontHeight = getFontHeight();
-    float scale = fontHeight / (float)_font->unitsPerEM(_embedFonts); 
-    float fontDescent = _font->descent() * scale; 
-    float fontLeading = _font->leading() * scale;
-    boost::uint16_t leftMargin = getLeftMargin();
-    boost::uint16_t rightMargin = getRightMargin();
-    boost::uint16_t indent = getIndent();
-    boost::uint16_t blockIndent = getBlockIndent();
-    bool underlined = getUnderlined();
-
-    //log_debug("%s: fontDescent:%g, fontLeading:%g, fontHeight:%g, scale:%g",
-    //  getTarget(), fontDescent, fontLeading, fontHeight, scale);
-
-    SWF::TextRecord rec;    // one to work on
-    rec.setFont(_font.get());
-    rec.setUnderline(underlined);
-    rec.setColor(getTextColor()); 
-    rec.setXOffset(PADDING_TWIPS + 
-            std::max(0, leftMargin + indent + blockIndent));
-    rec.setYOffset(PADDING_TWIPS + fontHeight + (fontLeading - fontDescent));
-    rec.setTextHeight(fontHeight);
-
-    boost::int32_t x = static_cast<boost::int32_t>(rec.xOffset());
-    boost::int32_t y = static_cast<boost::int32_t>(rec.yOffset());
-
-    // Start the bbox at the upper-left corner of the first glyph.
-    reset_bounding_box(x, y - fontDescent + fontHeight); 
-
-    float leading = getLeading();
-    leading += fontLeading * scale; // not sure this is correct...
-
-    int    last_code = -1; // only used if _embedFonts
-    int    last_space_glyph = -1;
-    int    last_line_start_record = 0;
-
-    unsigned int idx = 0;
-    m_xcursor = x;
-    m_ycursor = y;
-
-    assert(! _text.empty() );
-    
-    boost::uint32_t code = 0;
-    
-    // String iterators are very sensitive to 
-    // potential changes to the string (to allow for copy-on-write).
-    // So there must be no external changes to the string or
-    // calls to most non-const member functions during this loop.
-    // Especially not c_str() or data().
-    std::wstring::const_iterator it = _text.begin();
-    const std::wstring::const_iterator e = _text.end();
-
-    while (it != e)
-    {
-        code = *it++;
-        if (!code) break;
-
-        if ( _embedFonts )
-        {
-            x += rec.getFont()->get_kerning_adjustment(last_code, 
-                    static_cast<int>(code)) * scale;
-            last_code = static_cast<int>(code);
-        }
-
-        // Expand the bounding-box to the lower-right corner of each glyph as
-        // we generate it.
-        m_text_bounding_box.expand_to_point(x, y + fontDescent);
-
-        switch (code)
-        {
-            case 27:
-                // Ignore escape
-                break;
-            case 9:
-                insertTab(rec, x, scale);
-                break;
-            case 13:
-            case 10:
-            {
-                // newline.
-
-                // Frigging Flash seems to use '\r' (13) as its
-                // default newline DisplayObject.  If we get DOS-style \r\n
-                // sequences, it'll show up as double newlines, so maybe we
-                // need to detect \r\n and treat it as one newline.
-
-                // Close out this stretch of glyphs.
-                _textRecords.push_back(rec);
-                align_line(textAlignment, last_line_start_record, x);
-
-                // Expand bounding box to include last column of text ...
-                if ( _autoSize != autoSizeNone ) {
-                    _bounds.expand_to_point(x + PADDING_TWIPS,
-                            y + PADDING_TWIPS);
-                }
-
-                // new paragraphs get the indent.
-                x = std::max(0, leftMargin + indent) + PADDING_TWIPS;
-                y += fontHeight + leading; 
-
-                // Start a new record on the next line. Other properties of the
-                // TextRecord should be left unchanged.
-                rec.clearGlyphs();
-                rec.setXOffset(x);
-                rec.setYOffset(y);
-
-                last_space_glyph = -1;
-                last_line_start_record = _textRecords.size();
-
-                continue;
-            }
-            case 8:
-                // Backspace 
-
-                // This is a limited hack to enable overstrike effects.
-                // It backs the cursor up by one DisplayObject and then 
continues
-                // the layout.  E.g. you can use this to display an underline
-                // cursor inside a simulated text-entry box.
-                //
-                // ActionScript understands the '\b' escape sequence
-                // for inserting a BS DisplayObject.
-                //
-                // ONLY WORKS FOR BACKSPACING OVER ONE CHARACTER, WON'T BS
-                // OVER NEWLINES, ETC.
-
-                if (!rec.glyphs().empty())
-                {
-                    // Peek at the previous glyph, and zero out its advance
-                    // value, so the next char overwrites it.
-                    float advance = rec.glyphs().back().advance;
-                    x -= advance; 
-                    // Remove one glyph
-                    rec.clearGlyphs(1);
-                }
-                continue;
-            case '<':
-                if (_html)
-                {
-                    LOG_ONCE(log_debug(_("HTML in a text field is unsupported, 
"
-                                         "gnash will just ignore the tags and "
-                                         "print their content")));
-         
-                    std::wstring discard;
-                    bool complete = parseHTML(discard, it, e);
-                    
-                    if (!complete) continue;
-                    else break;
-
-                }
-                // If HTML isn't enabled, carry on and insert the glyph.
-
-            case 32:
-                last_space_glyph = rec.glyphs().size();
-                // Don't break, as we still need to insert the space glyph.
-
-            default:
-            {
-
-                // The font table holds up to 65535 glyphs. Casting
-                // from uint32_t would, in the event that the code
-                // is higher than 65535, result in the wrong DisplayObject
-                // being chosen. Flash can currently only handle 16-bit
-                // values.
-                int index = rec.getFont()->get_glyph_index(
-                        static_cast<boost::uint16_t>(code), _embedFonts);
-
-                IF_VERBOSE_MALFORMED_SWF (
-                    if (index == -1)
-                    {
-                        // Missing glyph! Log the first few errors.
-                        static int s_log_count = 0;
-                        if (s_log_count < 10)
-                        {
-                            s_log_count++;
-                            if (_embedFonts)
-                            {
-                                log_swferror(_("TextField: missing embedded "
-                                    "glyph for char %d. Make sure 
DisplayObject "
-                                    "shapes for font %s are being exported "
-                                    "into your SWF file"),
-                                    code, _font->name());
-                            }
-                            else
-                            {
-                                log_swferror(_("TextField: missing device "
-                                    "glyph for char %d. Maybe you don't have "
-                                    "font '%s' installed in your system."),
-                                    code, _font->name());
-                            }
-                        }
-
-                        // Drop through and use index == -1; this will display
-                        // using the empty-box glyph
-                    }
-                );
-
-                SWF::TextRecord::GlyphEntry ge;
-                ge.index = index;
-                ge.advance = scale * rec.getFont()->get_advance(index, 
-                        _embedFonts);
-
-                rec.addGlyph(ge);
-
-                x += ge.advance;
-            }
-        }
-
-        float width = defBounds.width();
-        if (x >= width - rightMargin - PADDING_TWIPS)
-        {
-#ifdef GNASH_DEBUG_TEXT_FORMATTING
-            log_debug("Text in TextField %s exceeds width [ _bounds %s ]", 
-                    getTarget(), _bounds);
-#endif
-
-            // No wrap and no resize: truncate
-            if (!doWordWrap() && autoSize == autoSizeNone)
-            {
-#ifdef GNASH_DEBUG_TEXT_FORMATTING
-                log_debug(" wordWrap=false, autoSize=none");
-#endif 
-                // Truncate long line, but keep expanding text box
-                bool newlinefound = false;
-                while (it != e)
-                {
-                    code = *it++;
-                    if (_embedFonts)
-                    {
-                        x += rec.getFont()->get_kerning_adjustment(last_code,
-                                static_cast<int>(code)) * scale;
-                        last_code = code;
-                    }
-                    // Expand the bounding-box to the lower-right corner
-                    // of each glyph, even if we don't display it 
-                    m_text_bounding_box.expand_to_point(x, y + fontDescent);
-#ifdef GNASH_DEBUG_TEXT_FORMATTING
-                    log_debug("Text bbox expanded to %s (width: %f)",
-                            m_text_bounding_box, m_text_bounding_box.width());
-#endif
-
-                    if (code == 13 || code == 10)
-                    {
-                        newlinefound = true;
-                        break;
-                    }
-
-                    int index = rec.getFont()->get_glyph_index(
-                            static_cast<boost::uint16_t>(code), _embedFonts);
-                    x += scale * rec.getFont()->get_advance(index, 
_embedFonts);
-
-                }
-                if (!newlinefound) break;
-            }
-            else if ( doWordWrap() )
-            {
-#ifdef GNASH_DEBUG_TEXT_FORMATTING
-                log_debug(" wordWrap=true");
-#endif 
-
-                // Insert newline if there's space or autosize != none
-
-                // Close out this stretch of glyphs.
-                _textRecords.push_back(rec);
-
-                float previous_x = x;
-                x = leftMargin + blockIndent + PADDING_TWIPS;
-                y += fontHeight + leading;
-
-                // Start a new record on the next line.
-                rec.clearGlyphs();
-                rec.setXOffset(x);
-                rec.setYOffset(y);
-
-                // TODO : what if m_text_glyph_records is empty ?
-                // Is it possible ?
-                assert(!_textRecords.empty());
-                SWF::TextRecord& last_line = _textRecords.back();
-                if (last_space_glyph == -1)
-                {
-                    // Pull the previous glyph down onto the
-                    // new line.
-                    if (!last_line.glyphs().empty())
-                    {
-                        rec.addGlyph(last_line.glyphs().back());
-                        x += last_line.glyphs().back().advance;
-                        previous_x -= last_line.glyphs().back().advance;
-                        last_line.clearGlyphs(1);
-                    }
-                }
-                else
-                {
-                    // Move the previous word down onto the next line.
-
-                    previous_x -= last_line.glyphs()[last_space_glyph].advance;
-
-                    const SWF::TextRecord::Glyphs::size_type lineSize =
-                        last_line.glyphs().size();
-                    for (unsigned int i = last_space_glyph + 1; i < lineSize;
-                            ++i)
-                    {
-                        rec.addGlyph(last_line.glyphs()[i]);
-                        x += last_line.glyphs()[i].advance;
-                        previous_x -= last_line.glyphs()[i].advance;
-                    }
-                    last_line.clearGlyphs(lineSize - last_space_glyph);
-                }
-
-                align_line(textAlignment, last_line_start_record, previous_x);
-
-                last_space_glyph = -1;
-                last_line_start_record = _textRecords.size();
-                
-            }
-            else
-            {
-#ifdef GNASH_DEBUG_TEXT_FORMATTING
-                log_debug(" wordWrap=%d, autoSize=%d", _wordWrap, _autoSize);
-#endif 
-            }
-        }
-
-        if (y > (defBounds.height() - PADDING_TWIPS) && 
-                autoSize == autoSizeNone )
-        {
-#ifdef GNASH_DEBUG_TEXT_FORMATTING
-            log_debug("Text with wordWrap exceeds height of box");
-#endif
-            rec.clearGlyphs();
-            // TODO: should still compute m_text_bounds !
-            LOG_ONCE(log_unimpl("Computing text bounds of a TextField "
-                        "containing text that doesn't fit the box 
vertically"));
-            break;
-        }
-
-        if (m_cursor > idx)
-        {
-            m_xcursor = x;
-            m_ycursor = y;
-        }
-        idx++;
-
-        // TODO: HTML markup
-    }
-
-    // Expand bounding box to include the whole text (if autoSize)
-    if ( _autoSize != autoSizeNone )
-    {
-        _bounds.expand_to_point(x+PADDING_TWIPS, y+PADDING_TWIPS);
-    }
-
-    // Add this line to our output.
-    if (!rec.glyphs().empty()) _textRecords.push_back(rec);
-
-    float extra_space = align_line(textAlignment, last_line_start_record, x);
-
-    m_xcursor += static_cast<int>(extra_space);
-    m_ycursor -= fontHeight + (fontLeading - fontDescent);
-}
-
-TextField::VariableRef
-TextField::parseTextVariableRef(const std::string& variableName) const
-{
-    VariableRef ret;
-    ret.first = 0;
-
-#ifdef DEBUG_DYNTEXT_VARIABLES
-    log_debug(_("VariableName: %s"), variableName);
-#endif
-
-    /// Why isn't get_environment const again ?
-    as_environment& env = const_cast<TextField*>(this)->get_environment();
-
-    as_object* target = env.get_target();
-    if ( ! target )
-    {
-        IF_VERBOSE_MALFORMED_SWF(
-            log_swferror(_("Current environment has no target, "
-                "can't bind VariableName (%s) associated to "
-                "text field. Gnash will try to register "
-                "again on next access."), variableName);
-        );
-        return ret;
-    }
-
-    // If the variable string contains a path, we extract
-    // the appropriate target from it and update the variable
-    // name. We copy the string so we can assign to it if necessary.
-    std::string parsedName = variableName;
-    std::string path, var;
-    if (as_environment::parse_path(variableName, path, var))
-    {
-#ifdef DEBUG_DYNTEXT_VARIABLES
-        log_debug(_("Variable text Path: %s, Var: %s"), path, var);
-#endif
-        // find target for the path component
-        // we use our parent's environment for this
-        target = env.find_object(path);
-
-        parsedName = var;
-    }
-
-    if ( ! target )
-    {
-        IF_VERBOSE_MALFORMED_SWF(
-            log_swferror(_("VariableName associated to text field refers "
-                    "to an unknown target (%s). It is possible that the "
-                    "DisplayObject will be instantiated later in the SWF "
-                    "stream. Gnash will try to register again on next "
-                    "access."), path);
-        );
-        return ret;
-    }
-
-    ret.first = target;
-    ret.second = _vm.getStringTable().find(parsedName);
-
-    return ret;
-}
-
-void
-TextField::registerTextVariable() 
-{
-//#define DEBUG_DYNTEXT_VARIABLES 1
-
-#ifdef DEBUG_DYNTEXT_VARIABLES
-    log_debug(_("registerTextVariable() called"));
-#endif
-
-    if ( _text_variable_registered )
-    {
-#ifdef DEBUG_DYNTEXT_VARIABLES
-        log_debug(_("registerTextVariable() no-op call (already registered)"));
-#endif
-        return;
-    }
-
-    if ( _variable_name.empty() )
-    {
-#ifdef DEBUG_DYNTEXT_VARIABLES
-        log_debug(_("string is empty, consider as registered"));
-#endif
-        _text_variable_registered=true;
-        return;
-    }
-
-    VariableRef varRef = parseTextVariableRef(_variable_name);
-    as_object* target = varRef.first;
-    if ( ! target )
-    {
-        log_debug(_("VariableName associated to text field (%s) refer to "
-                    "an unknown target. It is possible that the DisplayObject "
-                    "will be instantiated later in the SWF stream. "
-                    "Gnash will try to register again on next access."),
-                _variable_name);
-        return;
-    }
-
-    string_table::key key = varRef.second;
-
-    // check if the VariableName already has a value,
-    // in that case update text value
-    as_value val;
-    
-    int version = _vm.getSWFVersion();
-    
-    if (target->get_member(key, &val) )
-    {
-#ifdef DEBUG_DYNTEXT_VARIABLES
-        log_debug(_("target object (%s @ %p) does have a member named %s"),
-            typeName(*target), (void*)target, _vm.getStringTable().value(key));
-#endif
-        // TODO: pass environment to to_string ?
-        // as_environment& env = get_environment();
-        setTextValue(utf8::decodeCanonicalString(val.to_string(), version));
-    }
-    else if ( _textDefined )
-    {
-        as_value newVal = as_value(utf8::encodeCanonicalString(_text, 
version));
-#ifdef DEBUG_DYNTEXT_VARIABLES
-        log_debug(_("target sprite (%s @ %p) does NOT have a member "
-                    "named %s (no problem, we'll add it with value %s)"),
-                    typeName(*target), (void*)target,
-                    _vm.getStringTable().value(key), newVal);
-#endif
-        target->set_member(key, newVal);
-    }
-    else
-    {
-#ifdef DEBUG_DYNTEXT_VARIABLES
-        log_debug(_("target sprite (%s @ %p) does NOT have a member "
-                    "named %s, and we don't have text defined"),
-                    typeName(*target), (void*)target,
-                    _vm.getStringTable().value(key));
-#endif
-    }
-
-    MovieClip* sprite = target->to_movie();
-
-    if ( sprite )
-    {
-        // add the textfield variable to the target sprite
-        // TODO: have set_textfield_variable take a string_table::key instead ?
-#ifdef DEBUG_DYNTEXT_VARIABLES
-        log_debug("Calling set_textfield_variable(%s) against sprite %s",
-                _vm.getStringTable().value(key), sprite->getTarget());
-#endif
-        sprite->set_textfield_variable(_vm.getStringTable().value(key), this);
-
-    }
-    _text_variable_registered=true;
-
-}
-
-/// Parses an HTML tag (between < and >) and puts
-/// the contents into tag. Returns false if the
-/// tag was incomplete. The iterator is moved to after
-/// the closing tag or the end of the string.
-bool
-TextField::parseHTML(std::wstring& tag, std::wstring::const_iterator& it,
-                               const std::wstring::const_iterator& e) const
-{
-
-    bool complete = false;
-
-    while (it != e)
-    {
-        if (*it == '>')
-        {
-            ++it;
-            complete = true;
-            break;
-        }
-
-        // Check for NULL DisplayObject
-        if (*it == 0) break;
-
-        tag.push_back(*it++);
-    }
-    
-#ifdef GNASH_DEBUG_TEXTFIELDS
-    log_debug ("HTML tag: %s", utf8::encodeCanonicalString(tag, 7));
-#endif
-    
-    return complete;
-}
-
-void
-TextField::set_variable_name(const std::string& newname)
-{
-    if ( newname != _variable_name )
-    {
-        _variable_name = newname;
-
-        // The name was empty or undefined, so there's nothing more to do.
-        if (_variable_name.empty()) return;
-
-        _text_variable_registered = false;
-
-#ifdef DEBUG_DYNTEXT_VARIABLES
-        log_debug("Calling updateText after change of variable name");
-#endif
-
-        // Use the original definition text if this isn't dynamically
-        // created.
-        if (_tag) updateText(_tag->defaultText());
-
-#ifdef DEBUG_DYNTEXT_VARIABLES
-        log_debug("Calling registerTextVariable after change of variable "
-                "name and updateText call");
-#endif
-        registerTextVariable();
-    }
-}
-
-/// This provides the prototype and static methods for TextField.
-//
-/// For SWF5 there is initially no prototype, for SWF6+ there is a 
-/// limited prototype. This is changed later on instantiation of a
-/// TextField.
-void
-textfield_class_init(as_object& global)
-{
-    static boost::intrusive_ptr<builtin_function> cl = NULL;
-
-    if (!cl)
-    {
-        VM& vm = global.getVM();
-
-        if (vm.getSWFVersion() < 6) {
-            /// Version 5 or less: no initial prototype
-            cl = new builtin_function(&textfield_ctor, 0);
-        }
-        else {
-            /// Version 6 upward: limited initial prototype
-            as_object* iface = getTextFieldInterface(vm);
-            cl = new builtin_function(&textfield_ctor, iface);
-        }
-
-        vm.addStatic(cl.get());
-
-        // replicate static members to class, to be able to access
-        // all methods as static functions
-        attachTextFieldStaticMembers(*cl);
-             
-    }
-
-    // Register _global.TextField
-    global.init_member("TextField", cl.get());
-}
-
-bool
-TextField::pointInShape(boost::int32_t x, boost::int32_t y) const
-{
-    SWFMatrix wm = getWorldMatrix();
-    point lp(x, y);
-    wm.invert().transform(lp);
-    return _bounds.point_test(lp.x, lp.y);
-}
-
-bool
-TextField::getDrawBorder() const
-{
-    return _drawBorder;
-}
-
-void
-TextField::setDrawBorder(bool val) 
-{
-    if ( _drawBorder != val )
-    {
-        set_invalidated();
-        _drawBorder = val;
-    }
-}
-
-rgba
-TextField::getBorderColor() const
-{
-    return _borderColor;
-}
-
-void
-TextField::setBorderColor(const rgba& col)
-{
-    if ( _borderColor != col )
-    {
-        set_invalidated();
-        _borderColor = col;
-    }
-}
-
-bool
-TextField::getDrawBackground() const
-{
-    return _drawBackground;
-}
-
-void
-TextField::setDrawBackground(bool val) 
-{
-    if ( _drawBackground != val )
-    {
-        set_invalidated();
-        _drawBackground = val;
-    }
-}
-
-rgba
-TextField::getBackgroundColor() const
-{
-    return _backgroundColor;
-}
-
-void
-TextField::setBackgroundColor(const rgba& col)
-{
-    if ( _backgroundColor != col )
-    {
-        set_invalidated();
-        _backgroundColor = col;
-    }
-}
-
-void
-TextField::setTextColor(const rgba& col)
-{
-    if (_textColor != col) {
-
-        set_invalidated();
-        _textColor = col;
-        std::for_each(_textRecords.begin(), _textRecords.end(),
-                boost::bind(&SWF::TextRecord::setColor, _1, _textColor));
-    }
-}
-
-void
-TextField::setEmbedFonts(bool use)
-{
-    if ( _embedFonts != use )
-    {
-        set_invalidated();
-        _embedFonts=use;
-        format_text();
-    }
-}
-
-void
-TextField::setWordWrap(bool on)
-{
-    if ( _wordWrap != on )
-    {
-        set_invalidated();
-        _wordWrap=on;
-        format_text();
-    }
-}
-
-cxform    
-TextField::get_world_cxform() const
-{
-    // This is not automatically tested. See testsuite/samples/input-fields.swf
-    // for a manual check.
-
-    // If using a device font (PP compatibility), do not take parent cxform
-    // into account.
-    if (!getEmbedFonts()) return cxform();
-
-    return DisplayObject::get_world_cxform();
-}
-
-void
-TextField::setLeading(boost::uint16_t h)
-{
-    if ( _leading != h )
-    {
-        set_invalidated();
-        _leading = h;
-        format_text();
-    }
-}
-
-void
-TextField::setUnderlined(bool v)
-{
-    if ( _underlined != v )
-    {
-        set_invalidated();
-        _underlined = v;
-        format_text();
-    }
-}
-
-void
-TextField::setAlignment(TextAlignment h)
-{
-    if ( _alignment != h )
-    {
-        set_invalidated();
-        _alignment = h;
-        format_text();
-    }
-}
-
-void
-TextField::setIndent(boost::uint16_t h)
-{
-    if ( _indent != h )
-    {
-        set_invalidated();
-        _indent = h;
-        format_text();
-    }
-}
-
-void
-TextField::setBlockIndent(boost::uint16_t h)
-{
-    if ( _blockIndent != h )
-    {
-        set_invalidated();
-        _blockIndent = h;
-        format_text();
-    }
-}
-
-void
-TextField::setRightMargin(boost::uint16_t h)
-{
-    if ( _rightMargin != h )
-    {
-        set_invalidated();
-        _rightMargin = h;
-        format_text();
-    }
-}
-
-void
-TextField::setLeftMargin(boost::uint16_t h)
-{
-    if (_leftMargin != h)
-    {
-        set_invalidated();
-        _leftMargin = h;
-        format_text();
-    }
-}
-
-void
-TextField::setFontHeight(boost::uint16_t h)
-{
-    if ( _fontHeight != h )
-    {
-        set_invalidated();
-        _fontHeight = h;
-        format_text();
-    }
-}
-
-
-TextField::AutoSizeValue
-TextField::parseAutoSizeValue(const std::string& val)
-{
-    StringNoCaseEqual cmp;
-
-    if ( cmp(val, "left") )
-    {
-        return autoSizeLeft;
-    }
-    if ( cmp(val, "right") )
-    {
-        return autoSizeRight;
-    }
-    if ( cmp(val, "center") )
-    {
-        return autoSizeCenter;
-    }
-    return autoSizeNone;
-
-}
-
-
-const char*
-TextField::autoSizeValueName(AutoSizeValue val)
-{
-    switch (val)
-    {
-        case autoSizeLeft:
-            return "left";
-        case autoSizeRight:
-            return "right";
-        case autoSizeCenter:
-            return "center";
-        case autoSizeNone:
-        default:
-            return "none";
-    }
-
-}
-
-
-TextField::TypeValue
-TextField::parseTypeValue(const std::string& val)
-{
-    StringNoCaseEqual cmp;
-
-    if (cmp(val, "input")) return typeInput;
-    if (cmp(val, "dynamic")) return typeDynamic;
-    return typeInvalid;
-
-}
-
-
-const char*
-TextField::typeValueName(TypeValue val)
-{
-    switch (val)
-    {
-        case typeInput:
-            //log_debug("typeInput returned as 'input'");
-            return "input";
-        case typeDynamic:
-            //log_debug("typeDynamic returned as 'dynamic'");
-            return "dynamic";
-        default:
-            //log_debug("invalid type %d returned as 'invalid'", (int)val);
-            return "invalid";
-    }
-
-}
-
-void
-TextField::setAutoSize(AutoSizeValue val)
-{
-    if ( val == _autoSize ) return;
-
-    set_invalidated();
-
-    _autoSize = val; 
-    format_text();
-}
-
-TextField::TextAlignment
-TextField::getTextAlignment()
-{
-    TextAlignment textAlignment = getAlignment(); 
-    if ( _autoSize == autoSizeCenter ) textAlignment = ALIGN_CENTER;
-    else if ( _autoSize == autoSizeLeft ) textAlignment = ALIGN_LEFT;
-    else if ( _autoSize == autoSizeRight ) textAlignment = ALIGN_RIGHT;
-    return textAlignment;
-}
-
-void
-TextField::onChanged()
-{
-    as_value met(PROPNAME("onChanged"));
-    as_value targetVal(this);
-    callMethod(NSV::PROP_BROADCAST_MESSAGE, met, targetVal);
-}
-
-/// This is called by movie_root when focus is applied to this TextField.
-//
-/// The return value is true if the TextField can recieve focus.
-bool
-TextField::handleFocus()
-{
-
-    set_invalidated();
-
-    /// Select the entire text on focus.
-    setSelection(0, _text.length());
-
-    m_has_focus = true;
-
-    // why should we add to the key listener list every time
-    // we call setFocus()???
-    _vm.getRoot().add_key_listener(this);
-
-    m_cursor = _text.size();
-    format_text();
-    return true;
-}
-
-/// This is called by movie_root when focus is removed from the
-/// current TextField.
-void
-TextField::killFocus()
-{
-    if ( ! m_has_focus ) return; // nothing to do
-
-    set_invalidated();
-    m_has_focus = false;
-
-    movie_root& root = _vm.getRoot();
-    root.remove_key_listener(this);
-    format_text(); // is this needed ?
-
-}
-
-void
-TextField::markReachableResources() const
-{
-
-    if (_tag) _tag->setReachable();
-
-    if (_font) _font->setReachable();
-
-    // recurse to parent...
-    markDisplayObjectReachable();
-}
-
-/// TextField interface functions
-
-namespace {
-
-void
-attachPrototypeProperties(as_object& o)
-{
-    // Standard flags.
-    const int flags = as_prop_flags::dontDelete
-        |as_prop_flags::dontEnum;
-
-    // SWF6 or higher
-    const int swf6Flags = flags | as_prop_flags::onlySWF6Up;
-
-    boost::intrusive_ptr<builtin_function> getset;
-
-    // The following properties should only be attached to the prototype
-    // on first textfield creation.
-    o.init_property(NSV::PROP_TEXT_WIDTH,
-            textfield_textWidth, textfield_textWidth);
-    o.init_property(NSV::PROP_TEXT_HEIGHT,
-            textfield_textHeight, textfield_textHeight);
-
-    getset = new builtin_function(textfield_variable);
-    o.init_property("variable", *getset, *getset, swf6Flags);
-    getset = new builtin_function(textfield_background);
-    o.init_property("background", *getset, *getset, swf6Flags);
-    getset = new builtin_function(textfield_text);
-    o.init_property("text", *getset, *getset, swf6Flags);
-    getset = new builtin_function(textfield_backgroundColor);
-    o.init_property("backgroundColor", *getset, *getset, swf6Flags);
-    getset = new builtin_function(textfield_border);
-    o.init_property("border", *getset, *getset, swf6Flags);
-    getset = new builtin_function(textfield_borderColor);
-    o.init_property("borderColor", *getset, *getset, swf6Flags);
-    getset = new builtin_function(textfield_textColor);
-    o.init_property("textColor", *getset, *getset, swf6Flags);
-    getset = new builtin_function(textfield_embedFonts);
-    o.init_property("embedFonts", *getset, *getset, swf6Flags);
-    getset = new builtin_function(textfield_autoSize);
-    o.init_property("autoSize", *getset, *getset, swf6Flags);
-    getset = new builtin_function(textfield_type);
-    o.init_property("type", *getset, *getset, swf6Flags);
-    getset = new builtin_function(textfield_wordWrap);
-    o.init_property("wordWrap", *getset, *getset, swf6Flags);
-    getset = new builtin_function(textfield_html);
-    o.init_property("html", *getset, *getset, swf6Flags);
-    getset = new builtin_function(textfield_selectable);
-    o.init_property("selectable", *getset, *getset, swf6Flags);
-    getset = new builtin_function(textfield_length);
-    o.init_property("length", *getset, *getset, swf6Flags);
-    getset = new builtin_function(textfield_maxscroll);
-    o.init_property("maxscroll", *getset, *getset, swf6Flags);
-    getset = new builtin_function(textfield_maxhscroll);
-    o.init_property("maxhscroll", *getset, *getset, swf6Flags);
-    getset = new builtin_function(textfield_maxChars);
-    o.init_property("maxChars", *getset, *getset, swf6Flags);
-    getset = new builtin_function(textfield_bottomScroll);
-    o.init_property("bottomScroll", *getset, *getset, swf6Flags);
-    getset = new builtin_function(textfield_scroll);
-    o.init_property("scroll", *getset, *getset, swf6Flags);
-    getset = new builtin_function(textfield_hscroll);
-    o.init_property("hscroll", *getset, *getset, swf6Flags);
-    getset = new builtin_function(textfield_restrict);
-    o.init_property("restrict", *getset, *getset, swf6Flags);
-    getset = new builtin_function(textfield_multiline);
-    o.init_property("multiline", *getset, *getset, swf6Flags);
-    getset = new builtin_function(textfield_password);
-    o.init_property("password", *getset, *getset, swf6Flags);
-    getset = new builtin_function(textfield_htmlText);
-    o.init_property("htmlText", *getset, *getset, swf6Flags);
-}
-
-
-as_value
-textfield_background(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField> ptr = ensureType<TextField>(fn.this_ptr);
-
-    if (fn.nargs == 0) {
-        return as_value(ptr->getDrawBackground());
-    }
-    else {
-        ptr->setDrawBackground(fn.arg(0).to_bool());
-    }
-
-    return as_value();
-}
-
-as_value
-textfield_border(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField> ptr = ensureType<TextField>(fn.this_ptr);
-
-    if (fn.nargs == 0) {
-        return as_value(ptr->getDrawBorder());
-    }
-    else {
-        ptr->setDrawBorder(fn.arg(0).to_bool());
-    }
-
-    return as_value();
-}
-
-as_value
-textfield_backgroundColor(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField> ptr = ensureType<TextField>(fn.this_ptr);
-
-    if (fn.nargs == 0) {
-        return as_value(ptr->getBackgroundColor().toRGB());
-    }
-    else {
-        rgba newColor;
-        newColor.parseRGB(static_cast<boost::uint32_t>(fn.arg(0).to_int()));
-        ptr->setBackgroundColor(newColor);
-    }
-
-    return as_value();
-}
-
-as_value
-textfield_borderColor(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField> ptr = ensureType<TextField>(fn.this_ptr);
-
-    if (fn.nargs == 0) {
-        return as_value(ptr->getBorderColor().toRGB());
-    }
-    else {
-        rgba newColor;
-        newColor.parseRGB(static_cast<boost::uint32_t>(fn.arg(0).to_number()));
-        ptr->setBorderColor(newColor);
-    }
-
-    return as_value();
-}
-
-    
-as_value
-textfield_textColor(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField> ptr = ensureType<TextField>(fn.this_ptr);
-
-    if (!fn.nargs) {
-        // Getter
-        return as_value(ptr->getTextColor().toRGB());
-    }
-
-    // Setter
-    rgba newColor;
-    newColor.parseRGB(static_cast<boost::uint32_t>(fn.arg(0).to_number()));
-    ptr->setTextColor(newColor);
-
-    return as_value();
-}
-
-as_value
-textfield_embedFonts(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField> ptr = ensureType<TextField>(fn.this_ptr);
-
-    if (!fn.nargs) {
-        // Getter
-        return as_value(ptr->getEmbedFonts());
-    }
-
-    // Setter
-    ptr->setEmbedFonts(fn.arg(0).to_bool());
-    return as_value();
-}
-
-as_value
-textfield_wordWrap(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField> ptr = ensureType<TextField>(fn.this_ptr);
-
-    if (fn.nargs == 0) {
-        return as_value(ptr->doWordWrap());
-    }
-    else {
-        ptr->setWordWrap(fn.arg(0).to_bool());
-    }
-
-    return as_value();
-}
-
-as_value
-textfield_html(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField> ptr = ensureType<TextField>(fn.this_ptr);
-
-    if (fn.nargs == 0) {
-        return as_value(ptr->doHtml());
-    }
-    else {
-        ptr->setHtml( fn.arg(0).to_bool() );
-    }
-
-    return as_value();
-}
-
-as_value
-textfield_selectable(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField> ptr = ensureType<TextField>(fn.this_ptr);
-
-    if ( fn.nargs == 0 ) // getter
-    {
-        return as_value(ptr->isSelectable());
-    }
-    else // setter
-    {
-        ptr->setSelectable( fn.arg(0).to_bool() );
-    }
-
-    return as_value();
-}
-
-as_value
-textfield_length(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField> ptr = ensureType<TextField>(fn.this_ptr);
-
-    if ( fn.nargs == 0 ) // getter
-    {
-        const std::string& s = ptr->get_text_value();
-        return as_value(s.length()); // TOCHECK: utf-8 ?
-    }
-    else // setter
-    {
-        IF_VERBOSE_ASCODING_ERRORS(
-        log_aserror(_("Attempt to set length property of TextField %s"),
-            ptr->getTarget());
-        );
-    }
-
-    return as_value();
-}
-
-as_value
-textfield_textHeight(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField> ptr = ensureType<TextField>(fn.this_ptr);
-
-    if ( fn.nargs == 0 ) // getter
-    {
-        // Return the height, in pixels, of the text as laid out.
-        // (I.e. the actual text content, not our defined
-        // bounding box.)
-        //
-        // In local coords.  Verified against Macromedia Flash.
-        return as_value(twipsToPixels(ptr->getTextBoundingBox().height()));
-
-    }
-    else // setter
-    {
-        IF_VERBOSE_ASCODING_ERRORS(
-        log_aserror(_("Attempt to set read-only %s property of TextField "
-                "%s"), "textHeight", ptr->getTarget());
-        );
-    }
-
-    return as_value();
-}
-
-as_value
-textfield_textWidth(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField> ptr = ensureType<TextField>(fn.this_ptr);
-
-    if ( fn.nargs == 0 ) // getter
-    {
-        // Return the width, in pixels, of the text as laid out.
-        // (I.e. the actual text content, not our defined
-        // bounding box.)
-        //
-        // In local coords.  Verified against Macromedia Flash.
-        return as_value(twipsToPixels(ptr->getTextBoundingBox().width()));
-
-    }
-    else // setter
-    {
-        IF_VERBOSE_ASCODING_ERRORS(
-        log_aserror(_("Attempt to set read-only %s property of TextField %s"),
-            "textWidth", ptr->getTarget());
-        );
-    }
-
-    return as_value();
-}
-
-as_value
-textfield_autoSize(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField> ptr = ensureType<TextField>(fn.this_ptr);
-
-    if ( fn.nargs == 0 ) // getter
-    {
-        return ptr->autoSizeValueName(ptr->getAutoSize());
-    }
-    else // setter
-    {
-        const as_value& arg = fn.arg(0);
-        if ( arg.is_bool() )
-        {
-            if ( arg.to_bool() ) // true == left
-            {
-                ptr->setAutoSize( TextField::autoSizeLeft );
-            }
-            else
-            {
-                ptr->setAutoSize( TextField::autoSizeNone );
-            }
-        }
-        else
-        {
-            std::string strval = arg.to_string();
-            TextField::AutoSizeValue val = ptr->parseAutoSizeValue(strval);
-            ptr->setAutoSize( val );
-        }
-    }
-
-    return as_value();
-}
-
-as_value
-textfield_type(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField> ptr = ensureType<TextField>(fn.this_ptr);
-
-    if (!fn.nargs)
-    {
-        // getter
-        return ptr->typeValueName(ptr->getType());
-    }
-
-    // setter
-    const as_value& arg = fn.arg(0);
-    std::string strval = arg.to_string();
-    TextField::TypeValue val = ptr->parseTypeValue(strval);
-
-    IF_VERBOSE_ASCODING_ERRORS(
-        if ( val == TextField::typeInvalid )
-        {
-            log_aserror(_("Invalid value given to TextField.type: %s"), 
strval);
-        }
-    );
-    ptr->setType(val);
-    return as_value();
-}
-
-
-as_value
-textfield_variable(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField> text = ensureType<TextField>(fn.this_ptr);
-
-    if (!fn.nargs)
-    {
-        // Getter
-        const std::string& varName = text->getVariableName();
-        // An empty variable name returns null.
-        if (varName.empty()) {
-            as_value null;
-            null.set_null();
-            return null;
-        }
-        return as_value(varName);
-    }
-
-    // Setter
-    const as_value& varName = fn.arg(0);
-    if (varName.is_undefined() || varName.is_null()) {
-        text->set_variable_name("");
-    }
-    else text->set_variable_name(varName.to_string());
-
-    return as_value();
-
-}
-
-
-as_value
-textfield_getDepth(const fn_call& fn)
-{
-    // TODO: make this a DisplayObject::getDepth_method function...
-    boost::intrusive_ptr<TextField> text = ensureType<TextField>(fn.this_ptr);
-
-    int n = text->get_depth();
-
-    return as_value(n);
-
-}
-
-as_value
-textfield_getFontList(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField> text = ensureType<TextField>(fn.this_ptr);
-    UNUSED(text);
-
-    LOG_ONCE(log_unimpl("TextField.getFontList()"));
-
-    return as_value();
-}
-
-as_value
-textfield_getNewTextFormat(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField> text = ensureType<TextField>(fn.this_ptr);
-    UNUSED(text);
-
-    LOG_ONCE(log_unimpl("TextField.getNewTextFormat()"));
-
-    return as_value();
-}
-
-as_value
-textfield_getTextFormat(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField> text = ensureType<TextField>(fn.this_ptr);
-
-    boost::intrusive_ptr<TextFormat_as> tf = new TextFormat_as;
-    tf->alignSet(text->getTextAlignment());
-    tf->sizeSet(text->getFontHeight());
-    tf->indentSet(text->getIndent());
-    tf->blockIndentSet(text->getBlockIndent());
-    tf->leadingSet(text->getLeading());
-    tf->leftMarginSet(text->getLeftMargin());
-    tf->rightMarginSet(text->getRightMargin());
-    tf->colorSet(text->getTextColor());
-    tf->underlinedSet(text->getUnderlined());
-
-    const Font* font = text->getFont();
-    if (font)
-    {
-        tf->fontSet(font->name());
-        tf->italicedSet(font->isItalic());
-        tf->boldSet(font->isBold());
-    }
-
-    // TODO: add font color and some more
-
-    LOG_ONCE(
-        log_unimpl("TextField.getTextFormat() discards url, target, "
-            "tabStops, bullet and display")
-    );
-
-    return as_value(tf.get());
-}
-
-as_value
-textfield_setTextFormat(const fn_call& fn)
-{
-
-    boost::intrusive_ptr<TextField> text = ensureType<TextField>(fn.this_ptr);
-
-    if ( ! fn.nargs )
-    {
-        IF_VERBOSE_ASCODING_ERRORS(
-        std::stringstream ss; fn.dump_args(ss);
-        log_aserror("TextField.setTextFormat(%s) : %s", ss.str(),
-            _("missing arg"))
-        );
-        return as_value();
-    }
-    else if ( fn.nargs > 2 )
-    {
-        std::stringstream ss; fn.dump_args(ss);
-        log_debug("TextField.setTextFormat(%s) : args past the first are "
-                "unhandled by Gnash", ss.str());
-    }
-
-    as_object* obj = fn.arg(0).to_object().get();
-    if ( ! obj )
-    {
-        IF_VERBOSE_ASCODING_ERRORS(
-        std::stringstream ss; fn.dump_args(ss);
-        log_aserror("TextField.setTextFormat(%s) : %s", ss.str(), 
-            _("first argument is not an object"))
-        );
-        return as_value();
-    }
-
-    TextFormat_as* tf = dynamic_cast<TextFormat_as*>(obj);
-    if ( ! tf )
-    {
-        IF_VERBOSE_ASCODING_ERRORS(
-        std::stringstream ss; fn.dump_args(ss);
-        log_aserror("TextField.setTextFormat(%s) : %s", ss.str(),
-            _("first argument is not a TextFormat"))
-        );
-        return as_value();
-    }
-
-    if ( tf->alignDefined() ) text->setAlignment(tf->align());
-    if ( tf->sizeDefined() ) text->setFontHeight(tf->size()); // keep twips
-    if ( tf->indentDefined() ) text->setIndent(tf->indent());
-    if ( tf->blockIndentDefined() ) text->setBlockIndent(tf->blockIndent());
-    if ( tf->leadingDefined() ) text->setLeading(tf->leading());
-    if ( tf->leftMarginDefined() ) text->setLeftMargin(tf->leftMargin());
-    if ( tf->rightMarginDefined() ) text->setRightMargin(tf->rightMargin());
-    if ( tf->colorDefined() ) text->setTextColor(tf->color());
-    if ( tf->underlinedDefined() ) text->setUnderlined(tf->underlined());
-
-    if ( tf->fontDefined() )
-    {
-        const std::string& fontName = tf->font();
-        if ( ! fontName.empty() )
-        {
-            bool bold = tf->bold();
-            bool italic = tf->italiced();
-
-            // NOTE: should query movie-private font lib, not global-shared one
-            Movie* mi = text->get_root();
-            assert(mi);
-            const movie_definition* md = mi->definition();
-            assert(md);
-            Font* f = md->get_font(fontName, bold, italic);
-            if ( ! f ) f = fontlib::get_font(fontName, bold, italic);
-            text->setFont( f );
-        }
-    }
-
-    // TODO: add font color and some more
-
-    LOG_ONCE( log_unimpl("TextField.setTextFormat() discards url, target, "
-                "tabStops, bullet and display") );
-
-    return as_value();
-
-}
-
-as_value
-textfield_setNewTextFormat(const fn_call& fn)
-{
-    //boost::intrusive_ptr<TextField> text = 
ensureType<TextField>(fn.this_ptr);
-    //UNUSED(text);
-
-    LOG_ONCE( log_unimpl("TextField.setNewTextFormat(), we'll delegate "
-                "to setTextFormat") );
-    return textfield_setTextFormat(fn);
-
-    //return as_value();
-}
-
-as_value
-textfield_password(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField> text = ensureType<TextField>(fn.this_ptr);
-
-    LOG_ONCE(log_unimpl("TextField.password"));
-
-    if (!fn.nargs)
-    {
-        // Getter
-        return as_value(text->password());
-    }
-    // Setter
-    text->password(fn.arg(0).to_bool());
-    return as_value();
-}
-
-as_value
-textfield_multiline(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField> text = ensureType<TextField>(fn.this_ptr);
-
-    LOG_ONCE(log_unimpl("TextField.multiline"));
-
-    if (!fn.nargs) {
-        // Getter
-        return as_value(text->multiline());
-    }
-    // Setter
-    text->multiline(fn.arg(0).to_bool());
-    return as_value();
-}
-
-as_value
-textfield_restrict(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField> text = ensureType<TextField>(fn.this_ptr);
-    UNUSED(text);
-
-    LOG_ONCE (log_unimpl("TextField.restrict"));
-
-    return as_value();
-}
-
-as_value
-textfield_bottomScroll(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField> text = ensureType<TextField>(fn.this_ptr);
-    UNUSED(text);
-
-    LOG_ONCE (log_unimpl("TextField.bottomScroll"));
-
-    return as_value();
-}
-
-as_value
-textfield_maxhscroll(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField> text = ensureType<TextField>(fn.this_ptr);
-    UNUSED(text);
-
-    LOG_ONCE (log_unimpl("TextField.maxhscroll"));
-
-    return as_value();
-}
-
-/// TextField.maxChars().
-//
-/// This does not limit the length of the text, but rather the
-/// number of DisplayObjects that can be entered in the TextField.
-//
-/// Returns null when the value is 0.
-as_value
-textfield_maxChars(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField> text = ensureType<TextField>(fn.this_ptr);
-
-    LOG_ONCE(log_unimpl("TextField.maxChars"));
-
-    if (!fn.nargs)
-    {
-        boost::int32_t maxChars = text->maxChars();
-        if (maxChars == 0)
-        {
-            as_value null;
-            null.set_null();
-            return null;
-        }
-        return as_value(maxChars);
-    }
-    // Setter
-    text->maxChars(fn.arg(0).to_int());
-    return as_value();
-}
-
-as_value
-textfield_text(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField> ptr = ensureType<TextField>(fn.this_ptr);
-    if (!fn.nargs)
-    {
-        // Getter
-        //
-        // FIXME: should return text without HTML tags.
-        return as_value(ptr->get_text_value());
-    }
-
-    // Setter
-    int version = ptr->getVM().getSWFVersion();
-    ptr->setTextValue(
-            utf8::decodeCanonicalString(fn.arg(0).to_string(), version));
-
-    return as_value();
-}
-
-as_value
-textfield_htmlText(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField> ptr = ensureType<TextField>(fn.this_ptr);
-    if (!fn.nargs)
-    {
-        // Getter
-        return as_value(ptr->get_text_value());
-    }
-
-    // Setter
-    int version = ptr->getVM().getSWFVersion();
-    ptr->setTextValue(
-            utf8::decodeCanonicalString(fn.arg(0).to_string(), version));
-
-    return as_value();
-}
-
-/// TextField.replaceSel(newText)
-//
-/// Replaces the current selection with the new text, setting both
-/// begin and end of the selection to one after the inserted text.
-/// If an empty string is passed, SWF8 erases the selection; SWF7 and below
-/// is a no-op.
-/// If no argument is passed, this is a no-op.
-as_value
-textfield_replaceSel(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField> text = ensureType<TextField>(fn.this_ptr);
-
-    if (!fn.nargs) {
-        IF_VERBOSE_ASCODING_ERRORS(
-            std::ostringstream os;
-            fn.dump_args(os);
-            log_aserror("TextField.replaceSel(%s) requires exactly one "
-                "argument", os.str());
-        );
-        return as_value();
-    }
-
-    const std::string& replace = fn.arg(0).to_string();
-
-    /// Do nothing if text is empty and version less than 8.
-    const int version = text->getVM().getSWFVersion();
-    if (version < 8 && replace.empty()) return as_value();
-
-    text->replaceSelection(replace);
-
-    return as_value();
-}
-
-as_value
-textfield_scroll(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField> text = ensureType<TextField>(fn.this_ptr);
-    UNUSED(text);
-
-    LOG_ONCE (log_unimpl("TextField.scroll()"));
-
-    return as_value();
-}
-
-as_value
-textfield_hscroll(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField> text = ensureType<TextField>(fn.this_ptr);
-    UNUSED(text);
-
-    LOG_ONCE (log_unimpl("TextField.hscroll()"));
-
-    return as_value();
-}
-
-as_value
-textfield_maxscroll(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField> text = ensureType<TextField>(fn.this_ptr);
-    UNUSED(text);
-
-    LOG_ONCE (log_unimpl("TextField.maxscroll"));
-
-    return as_value();
-}
-
-as_value
-textfield_replaceText(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField> text = ensureType<TextField>(fn.this_ptr);
-    UNUSED(text);
-
-    LOG_ONCE(log_unimpl("TextField.replaceText()"));
-
-    return as_value();
-}
-
-as_value
-textfield_removeTextField(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField> text = ensureType<TextField>(fn.this_ptr);
-
-    text->removeTextField();
-
-    LOG_ONCE(log_debug("TextField.removeTextField() TESTING"));
-
-    return as_value();
-}
-
-
-/// This is called for 'new TextField()' only
-as_value
-textfield_ctor(const fn_call& fn)
-{
-
-    VM& vm = fn.getVM();
-
-    as_object* proto = getTextFieldInterface(vm);
-
-    as_object* obj = 0;
-
-    if ( vm.getSWFVersion() < 9 )
-    {
-        // We should attach more properties to the prototype on first
-        // instantiation.
-        // TODO: this also attaches properties to the SWF5 prototype but makes
-        // them invisible with prop flags. Is this correct?
-        attachPrototypeProperties(*proto);
-
-        obj = new as_object(proto);
-    }
-    else
-    {
-        rect nullRect;
-        obj = new TextField(0, nullRect);
-    }
-
-    return as_value(obj);
-}
-
-
-void
-attachTextFieldInterface(as_object& o)
-{
-    boost::intrusive_ptr<builtin_function> getset;
-
-    // TextField is an AsBroadcaster
-    AsBroadcaster::initialize(o);
-
-    int propFlags = as_prop_flags::dontDelete
-        |as_prop_flags::dontEnum
-        |as_prop_flags::readOnly
-        |as_prop_flags::isProtected;
-
-    // Parent seems to not be a normal property
-    getset = new builtin_function(&DisplayObject::parent_getset, NULL);
-    o.init_property(NSV::PROP_uPARENT, *getset, *getset);
-
-    // Target seems to not be a normal property
-    getset = new builtin_function(&DisplayObject::target_getset, NULL);
-    o.init_property(NSV::PROP_uTARGET, *getset, *getset);
-
-    // _name should be a property of the instance, not the prototype
-    getset = new builtin_function(&DisplayObject::name_getset, NULL);
-    o.init_property(NSV::PROP_uNAME, *getset, *getset);
-
-    o.init_property(NSV::PROP_uXMOUSE,
-            DisplayObject::xmouse_get, DisplayObject::xmouse_get, propFlags);
-    o.init_property(NSV::PROP_uYMOUSE,
-            DisplayObject::ymouse_get, DisplayObject::ymouse_get, propFlags);
-    o.init_property(NSV::PROP_uHIGHQUALITY,
-            DisplayObject::highquality, DisplayObject::highquality);
-    o.init_property(NSV::PROP_uQUALITY,
-            DisplayObject::quality, DisplayObject::quality);
-    o.init_property(NSV::PROP_uXSCALE,
-            DisplayObject::xscale_getset, DisplayObject::xscale_getset);
-    o.init_property(NSV::PROP_uYSCALE,
-            DisplayObject::yscale_getset, DisplayObject::yscale_getset);
- 
-    // Standard flags.
-    const int flags = as_prop_flags::dontDelete
-        |as_prop_flags::dontEnum;
-
-    // SWF6 or higher
-    const int swf6Flags = flags | as_prop_flags::onlySWF6Up;
-
-    o.init_member("setTextFormat", 
-            new builtin_function(textfield_setTextFormat), swf6Flags);
-    o.init_member("getTextFormat", 
-            new builtin_function(textfield_getTextFormat), swf6Flags);
-    o.init_member("setNewTextFormat",
-            new builtin_function(textfield_setNewTextFormat), swf6Flags);
-    o.init_member("getNewTextFormat",
-            new builtin_function(textfield_getNewTextFormat), swf6Flags);
-    o.init_member("getNewTextFormat",
-            new builtin_function(textfield_getNewTextFormat), swf6Flags);
-    o.init_member("getDepth",
-            new builtin_function(textfield_getDepth), swf6Flags);
-    o.init_member("removeTextField",
-            new builtin_function(textfield_removeTextField), swf6Flags);
-    o.init_member("replaceSel",
-            new builtin_function(textfield_replaceSel), swf6Flags);
-
-    // SWF7 or higher
-    const int swf7Flags = flags | as_prop_flags::onlySWF7Up;
-
-    o.init_member("replaceText",
-            new builtin_function(textfield_replaceText), swf7Flags);
-
-}
-
-void
-attachTextFieldStaticMembers(as_object& o)
-{
-    // Standard flags.
-    const int flags = as_prop_flags::dontDelete
-        |as_prop_flags::dontEnum;
-
-    // SWF6 or higher
-    const int swf6Flags = flags | as_prop_flags::onlySWF6Up;
-
-    o.init_member("getFontList",
-            new builtin_function(textfield_getFontList), swf6Flags);
-
-}
-
-/// This is called when a prototype should be added
-//
-/// @note   This is called at different times, depending on the version.
-///         For SWF5 it is called only on first instantiation. For SWF6 it
-///         is called at the registration of _global.TextField.
-as_object*
-getTextFieldInterface(VM& vm)
-{
-    static boost::intrusive_ptr<as_object> proto;
-
-    if ( proto == NULL )
-    {
-        if (vm.getSWFVersion() < 6) {
-            /// The prototype for SWF5 is a simple as_object without
-            /// toString() or valueOf().
-            proto = new as_object();
-            vm.addStatic(proto.get());
-        }
-        else {
-            proto = new as_object(getObjectInterface());
-            vm.addStatic(proto.get());
-            attachTextFieldInterface(*proto);
-        }
-
-    }
-    return proto.get();
-}
-
-} // anonymous namespace
-
-} // namespace gnash
-
-
-// Local Variables:
-// mode: C++
-// indent-tabs-mode: t
-// End:
-

=== removed file 'libcore/TextField.h'
--- a/libcore/TextField.h       2009-04-14 11:26:23 +0000
+++ b/libcore/TextField.h       1970-01-01 00:00:00 +0000
@@ -1,670 +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_TEXTFIELD_H
-#define GNASH_TEXTFIELD_H
-
-#include "InteractiveObject.h" // for inheritance
-#include "styles.h" // for line_style
-#include "fill_style.h"
-#include "Range2d.h"
-#include "rect.h" // for inlines
-#include "Font.h" // for visibility of font add_ref/drop_ref
-
-// Forward declarations
-namespace gnash {
-    namespace SWF {
-        class DefineEditTextTag;
-        class TextRecord;
-    }
-}
-
-namespace gnash {
-
-/// An instance of a DefineEditTextTag 
-class TextField : public InteractiveObject
-{
-
-public:
-
-    /// Text alignment values
-       enum TextAlignment
-       {
-               ALIGN_LEFT = 0,
-               ALIGN_RIGHT,
-               ALIGN_CENTER,
-               ALIGN_JUSTIFY
-       };
-
-       /// Possible autoSize values
-       enum AutoSizeValue {
-
-               /// Do not automatically resize TextField as text grow/shrink
-               autoSizeNone,
-
-               /// Expand TextField, anchor the top-left side
-               autoSizeLeft,
-
-               /// Expand TextField, anchor the horizontal center
-               autoSizeCenter,
-
-               /// Expand TextField, anchor the top-right side
-               autoSizeRight
-       };
-
-       /// Possible type values
-       enum TypeValue {
-
-               /// Invalid value
-               typeInvalid,
-
-               /// Do not accept input, text is only changed by variable name
-               /// or assigning to the .text member
-               typeDynamic,
-
-               /// Accept user input
-               typeInput
-       };
-
-    /// Constructs a TextField as specified in a DefineEditText tag.
-       TextField(DisplayObject* parent, const SWF::DefineEditTextTag& def, int 
id);
-
-    /// Constructs a TextField with default values and the specified bounds.
-    //
-    /// Notably, the default textHeight is 12pt (240 twips).
-    TextField(DisplayObject* parent, const rect& bounds);
-
-       ~TextField();
-
-       // TODO: should this return isSelectable() ?
-       bool mouseEnabled() const { return true; }
-
-       InteractiveObject* topmostMouseEntity(boost::int32_t x,
-            boost::int32_t y);
-
-       // Text fields need to handle cxform specially 
-       virtual cxform get_world_cxform() const;
-       
-    bool wantsInstanceName() const
-       {
-               return true; // text fields can be referenced 
-       }       
-               
-       bool on_event(const event_id& id);      
-
-       const std::string& getVariableName() const
-       {
-               return _variable_name;
-       }
-
-       /// Set the name of a variable associated to this
-       /// TextField's displayed text.
-       //
-       /// Calling this function will override any previous
-       /// setting for the variable name.
-       /// 
-       void set_variable_name(const std::string& newname);
-       
-       /// \brief Set our text to the given string by effect of an update of a
-    /// registered variable name
-       //
-       /// This call only updates the text and is only meant to be called
-    /// by ourselves or by MovieClip when a registered TextVariable is
-    /// updated.
-       void updateText(const std::string& s);
-
-       /// Return value of our text.
-       std::string get_text_value() const;
-
-       /// Return true if text is defined
-       bool getTextDefined() const { return _textDefined; }
-
-    size_t getCaretIndex() const {
-        return m_cursor;
-    }
-
-    const std::pair<size_t, size_t>& getSelection() const {
-        return _selection;
-    }
-
-    /// Replace the current selection with the new text.
-    void replaceSelection(const std::string& replace);
-
-    /// Set the current selection
-    //
-    /// @param start    The index of the beginning of the selection.
-    /// @param end      The index of the end of the selection.
-    //
-    /// If start is greater than end, the values are swapped, ensuring
-    /// end is never less than start.
-    void setSelection(int start, int end);
-
-       /// We have a "text" member.
-       bool set_member(string_table::key name, const as_value& val, 
-               string_table::key nsname = 0, bool ifFound=false);
-
-       bool get_member(string_table::key name, as_value* val, 
-               string_table::key nsname = 0);
-
-       /// Draw the dynamic string.
-       void    display();
-
-       void add_invalidated_bounds(InvalidatedRanges& ranges, bool force);
-
-       virtual rect getBounds() const
-       {
-               return _bounds;
-       }
-
-       // See dox in DisplayObject.h
-       bool pointInShape(boost::int32_t x, boost::int32_t y) const;
-
-       /// Return true if the 'background' should be drawn
-       bool getDrawBackground() const;
-
-       /// Specify wheter to draw the background
-       void setDrawBackground(bool draw);
-
-       /// Return color of the background
-       rgba getBackgroundColor() const;
-
-       /// Set color of the background
-       //
-       /// Use setDrawBackground to actually use this value.
-       ///
-       void setBackgroundColor(const rgba& col);
-
-       /// Return true if this TextField should have it's border visible
-       bool getDrawBorder() const;
-
-       /// Specify wheter to draw the border
-       void setDrawBorder(bool draw);
-
-       /// Return color of the border
-       rgba getBorderColor() const;
-
-       /// Set color of the border
-       //
-       /// Use setDrawBorder to actually use this value.
-       ///
-       void setBorderColor(const rgba& col);
-
-       /// Return color of the text
-       const rgba& getTextColor() const 
-       {
-               return _textColor;
-       }
-
-       /// Set color of the text
-       void setTextColor(const rgba& col);
-
-       /// \brief
-       /// Return true if this TextField should use embedded font glyphs,
-       /// false if it should use device font glyphs
-       bool getEmbedFonts() const {
-               return _embedFonts;
-       }
-
-    /// Get the current maxChars setting of the TextField
-    boost::int32_t maxChars() const {
-        return _maxChars;
-    }
-
-    /// Set the current maxChars setting of the TextField
-    void maxChars(boost::int32_t max) {
-        _maxChars = max;
-    }
-
-    /// Get the current multiline setting of the TextField
-    bool multiline() const {
-        return _multiline;
-    }
-
-    /// Set the current multiline setting of the TextField
-    void multiline(bool b) {
-        _multiline = b;
-    }
-
-    /// Get the current password setting of the TextField
-    bool password() const {
-        return _password;
-    }
-
-    /// Set the current password setting of the TextField
-    void password(bool b) {
-        _password = b;
-    }
-       /// \brief
-       /// Set whether this TextField should use embedded font glyphs,
-       /// or use device font glyphs
-       //
-       /// @param use
-       void setEmbedFonts(bool use);
-
-       /// Get autoSize value 
-       AutoSizeValue getAutoSize() const
-       {
-               return _autoSize;
-       }
-
-       /// Return text TextAlignment
-    TextAlignment getTextAlignment();
-
-       /// Set autoSize value 
-       //
-       /// @param val
-       ///     The AutoSizeValue to use
-       ///
-       void setAutoSize(AutoSizeValue val);
-
-       /// Parse autoSize string value
-       //
-       /// @param val
-       ///     Auto size value as a string (one of none, left, center, right)
-       ///
-       /// @return an AutoSizeValue identifier. autoSizeNone if invalid
-       ///
-       static AutoSizeValue parseAutoSizeValue(const std::string& val);
-
-       /// Return autoSize value as a string
-       //
-       /// @param val
-       ///     Auto size value 
-       ///
-       /// @return a C-string representation of the autoSize value.
-       ///     The returns is *never* NULL.
-       ///
-       static const char* autoSizeValueName(AutoSizeValue val);
-
-       /// Set type (input or dynamic)
-       //
-       /// @param val
-       ///     The TypeValue to use, no-op if typeInvalid.
-       ///
-       void setType(TypeValue val) { if (val != typeInvalid) _type=val; }
-
-       /// Get type (input, dynamic or invalid)
-       TypeValue getType() const
-       {
-               return _type;
-       }
-
-       /// Return true if this TextField is read-only
-       bool isReadOnly() const { return _type != typeInput; }
-
-       /// Parse type string value
-       //
-       /// @param val
-       ///     Type value as a string (one of input or dynamic)
-       ///
-       /// @return an TypeValue identifier. typeInvalid if invalid.
-       ///
-       static TypeValue parseTypeValue(const std::string& val);
-
-       /// Return type value as a string
-       //
-       /// @param val
-       ///     Type value  (enum)
-       ///
-       /// @return a C-string representation of the type value.
-       ///     The returns is *never* NULL.
-       ///
-       static const char* typeValueName(TypeValue val);
-
-       /// \brief
-       /// Return true if text should continue to next available line
-       /// when hitting end of bounding box.
-       ///
-       bool doWordWrap() const {
-               return _wordWrap;
-       }
-
-       /// Set wordWrap parameter 
-       //
-       /// @param on
-       ///     If true text hitting bounding box limits will continue
-       ///     to next line.
-       ///     If false, either text will be truncated or bounding box
-       ///     expanded, depending on autoSize (see getAutoSize)
-       ///
-       void setWordWrap(bool on);
-
-       /// \brief
-       /// Return true if HTML markup in text should be rendered.
-       ///
-       bool doHtml() const {
-               return _html;
-       }
-
-       /// Set html parameter
-       //
-       /// @param on
-       ///     If true HTML tags in the text will be parsed and rendered
-       void setHtml(bool on) {
-               _html = on;
-       }
-
-       /// Return true if the TextField text is selectable
-       bool isSelectable() const
-       {
-               return _selectable;
-       }
-
-       /// Set 'selectable' parameter
-       void setSelectable(bool v) 
-       {
-               _selectable = v;
-       }
-
-       // See DisplayObject::isActiveTextField
-       virtual bool isSelectableTextField() const
-       {
-               return isSelectable();
-       }
-
-       /// Remove this textfield from the stage
-       //
-       /// This is to implement TextField.removeTextField, will
-       /// basically forward the request to its parent.
-       /// Eventually this and MovieClip::removeMovieClip
-       /// will be merged in a single function to be later used
-       /// also for AS3 removeChild().
-       ///
-       void removeTextField();
-
-       /// Set our font, return previously set one.
-       //
-       /// @param newfont
-       ///     Will be stored in an intrusive_ptr
-       ///
-       boost::intrusive_ptr<const Font> setFont(
-            boost::intrusive_ptr<const Font> newfont);
-
-       const Font* getFont() { return _font.get(); }
-
-       boost::uint16_t getFontHeight() const
-       {
-               return _fontHeight;
-       }
-
-       void setFontHeight(boost::uint16_t h);
-
-       boost::uint16_t getLeftMargin() const
-       {
-               return _leftMargin;
-       }
-
-       void setLeftMargin(boost::uint16_t h);
-
-       boost::uint16_t getRightMargin() const
-       {
-               return _rightMargin;
-       }
-
-       void setRightMargin(boost::uint16_t h);
-
-       boost::uint16_t getIndent() const
-       {
-               return _indent;
-       }
-
-       void setIndent(boost::uint16_t h);
-
-       boost::uint16_t getBlockIndent() const
-       {
-               return _blockIndent;
-       }
-
-       void setBlockIndent(boost::uint16_t h);
-
-       TextAlignment getAlignment() const
-       {
-               return _alignment;
-       }
-
-       void setAlignment(TextAlignment h);
-
-       boost::uint16_t getLeading() const
-       {
-               return _leading;
-       }
-
-       void setLeading(boost::uint16_t h);
-
-       bool getUnderlined() const
-       {
-               return _underlined;
-       }
-
-       void setUnderlined(bool v);
-
-       const rect& getTextBoundingBox() const
-       {
-               return m_text_bounding_box;
-       }
-
-       /// Set our text to the given string.
-       //
-       /// This function will also update any registered variable
-       ///
-       void setTextValue(const std::wstring& wstr);
-
-protected:
-
-       /// Mark reachable reosurces (for GC)
-       //
-       /// Reachable resources are:
-       ///  - The font being used (m_font) 
-       ///  - Our definition
-       ///  - Common DisplayObject resources
-       ///
-       void markReachableResources() const;
-
-private:
-
-    void init();
-
-       /// \brief Set our text to the given string by effect of an update of a
-    /// registered variable name
-       //
-       /// This call only updates the text and is only meant to be called
-    /// by ourselves or by MovieClip when a registered TextVariable is
-    /// updated.
-       void updateText(const std::wstring& s);
-
-    void insertTab(SWF::TextRecord& rec, boost::int32_t& x, float scale);
-
-       /// What happens when setFocus() is called on this TextField.
-    //
-    /// @return true if focus was set. A TextField can always receive focus,
-    /// so this always returns true.
-       virtual bool handleFocus();
-
-       /// Kill focus 
-       virtual void killFocus();
-
-       /// Call this function when willing to invoke the onChanged event 
handler
-       void onChanged();
-
-       /// Reset our text bounding box to the given point.
-       void reset_bounding_box(boost::int32_t x, boost::int32_t y)
-       {
-               m_text_bounding_box.set_to_point(x, y);
-       }
-
-       /// Convert the DisplayObjects in _text into a series of
-       /// text_glyph_records to be rendered.
-       void format_text();
-       
-       /// Extracts an HTML tag.
-       ///
-       /// @param tag  This string is filled with the extracted HTML tag.
-       /// @param it   An iterator pointing to the first DisplayObject of the
-       ///             HTML tag. It is left pointing to the DisplayObject 
after the
-       ///             closing tag or the end of the string.
-       /// @param e    An iterator pointing to the end of the string.
-       /// @return     Whether the tag is complete or not (i.e. whether a '>'
-       ///             was found).
-       bool parseHTML(std::wstring& tag, std::wstring::const_iterator& it,
-                             const std::wstring::const_iterator& e) const;
-
-       /// Does LEFT/CENTER/RIGHT alignment on the records in
-       /// m_text_glyph_records[], starting with
-       /// last_line_start_record and going through the end of
-       /// m_text_glyph_records.
-       float align_line(TextAlignment align, int last_line_start_record, float 
x);
-
-       /// Associate a variable to the text of this DisplayObject
-       //
-       /// Setting the associated variable actually changes the
-       /// displayed text. Getting the variable would return the
-       /// displayed text.
-       ///
-       /// If the given variable already exist use it to set
-       /// current text before overriding it.
-       ///
-       /// Since the variable target may be undefined at time
-       /// of instantiation of this EditText DisplayObject, the
-       /// class keeps track of wheter it succeeded registering
-       /// the variable and this function will do nothing in this
-       /// case. Thus it is safe to call it multiple time, using
-       /// an as-needed policy (will be called from get_text_value and
-       /// display)
-       ///
-       void registerTextVariable();
-
-       typedef std::pair<as_object*, string_table::key> VariableRef;
-
-       /// \brief
-       /// Parse the given variable name
-       /// into sprite and a string_table::key components
-       ///
-       VariableRef parseTextVariableRef(const std::string& variableName) const;
-
-    /// The immutable definition of our TextField
-    //
-    /// This is NULL for dynamic TextFields.
-    boost::intrusive_ptr<const SWF::DefineEditTextTag> _tag;
-
-       /// The actual text.
-    //
-    /// Because we have to deal with non-ascii DisplayObjects (129-255), this
-    /// is a wide string; the cursor position and the position within the
-    /// string are then the same, which makes manipulating the string much
-    /// easier.
-       std::wstring _text;
-
-       /// This flag will be true as soon as the TextField
-       /// is assigned a text value. Only way to be false is
-       /// when definition has the hasText flag set to false
-       /// and no actionscript added text.
-       bool _textDefined;
-
-       /// bounds of dynamic text, as laid out
-       rect m_text_bounding_box;
-
-       typedef std::vector<SWF::TextRecord> TextRecords;
-       TextRecords _textRecords;
-       bool _underlined;
-
-       boost::uint16_t _leading;
-
-       TextAlignment _alignment;
-
-       boost::uint16_t _indent;
-
-       /// Indentation for every line (including the ones created by
-       /// effect of a word-wrap.
-       boost::uint16_t _blockIndent;
-
-       boost::uint16_t _leftMargin;
-
-       boost::uint16_t _rightMargin;
-
-       boost::uint16_t _fontHeight;
-
-       boost::intrusive_ptr<const Font> _font;
-
-       bool m_has_focus;
-       size_t m_cursor;
-       void show_cursor(const SWFMatrix& mat);
-       float m_xcursor;
-       float m_ycursor;
-
-    /// Corresponds to the multiline property.
-    bool _multiline;
-
-    /// Corresponds to the password property.
-    bool _password;
-
-    /// Corresponds to the maxChars property.
-    boost::int32_t _maxChars;
-       /// The flag keeping status of TextVariable registration
-       //
-       /// It will be set to true if there's no need to register
-       /// a text variable (ie. non-specified in the SWF)
-       ///
-       bool _text_variable_registered;
-
-       /// The text variable name
-       //
-       /// This is stored here, and not just in the definition,
-       /// because it can be changed programmatically, by setting
-       /// 'TextFields.variable'
-       std::string _variable_name;
-
-       bool _drawBackground;
-
-       rgba _backgroundColor;
-
-       bool _drawBorder;
-
-       rgba _borderColor;
-
-       rgba _textColor;
-
-       bool _embedFonts;
-
-       bool _wordWrap;
-
-       bool _html;
-
-       bool _selectable;
-
-       AutoSizeValue _autoSize;
-
-       TypeValue _type;
-
-       /// Area in which the text is drawn. 
-       //
-       /// This area encloses all the text, can be automatically
-       /// extended to fit text or hide text overflowing it.
-       /// See the setAutoSize() method to change that.
-       ///
-       rect _bounds;
-
-    /// Represents the selected part of the text. The second element must
-    /// never be less than the first.
-    std::pair<size_t, size_t> _selection;
-};
-
-/// Initialize the global TextField class
-void textfield_class_init(as_object& global);
-
-} // namespace gnash
-
-#endif 

=== modified file 'libcore/asobj/Global.cpp'
--- a/libcore/asobj/Global.cpp  2009-06-08 22:15:34 +0000
+++ b/libcore/asobj/Global.cpp  2009-06-08 22:24:55 +0000
@@ -61,7 +61,7 @@
 #include "Timers.h"
 #include "URL.h" // for URL::encode and URL::decode (escape/unescape)
 #include "builtin_function.h"
-#include "TextField.h"
+#include "flash/text/TextField_as.h"
 #include "rc.h"
 #include "ClassHierarchy.h"
 #include "namedStrings.h"

=== modified file 'libcore/asobj/Selection_as.cpp'
--- a/libcore/asobj/Selection_as.cpp    2009-04-03 09:18:40 +0000
+++ b/libcore/asobj/Selection_as.cpp    2009-06-08 22:24:55 +0000
@@ -29,7 +29,7 @@
 #include "builtin_function.h" // need builtin_function
 #include "Object.h" // for getObjectInterface
 #include "AsBroadcaster.h"
-#include "TextField.h"
+#include "text/TextField_as.h"
 
 // For getting and setting focus
 #include "VM.h"
@@ -120,7 +120,7 @@
     movie_root& mr = ptr->getVM().getRoot();
     DisplayObject* focus = mr.getFocus().get();
 
-    TextField* tf = dynamic_cast<TextField*>(focus);
+    TextField_as* tf = dynamic_cast<TextField_as*>(focus);
 
     if (!tf) return as_value(-1);
 
@@ -142,7 +142,7 @@
     movie_root& mr = ptr->getVM().getRoot();
     DisplayObject* focus = mr.getFocus().get();
 
-    TextField* tf = dynamic_cast<TextField*>(focus);
+    TextField_as* tf = dynamic_cast<TextField_as*>(focus);
 
     if (!tf) return as_value(-1);
 
@@ -158,7 +158,7 @@
     movie_root& mr = ptr->getVM().getRoot();
     DisplayObject* focus = mr.getFocus().get();
 
-    TextField* tf = dynamic_cast<TextField*>(focus);
+    TextField_as* tf = dynamic_cast<TextField_as*>(focus);
 
     if (!tf) return as_value(-1);
 
@@ -257,7 +257,7 @@
     movie_root& mr = ptr->getVM().getRoot();
     DisplayObject* focus = mr.getFocus().get();
 
-    TextField* tf = dynamic_cast<TextField*>(focus);
+    TextField_as* tf = dynamic_cast<TextField_as*>(focus);
 
     if (!tf) return as_value();
 

=== modified file 'libcore/asobj/flash/text/TextField_as.cpp'
--- a/libcore/asobj/flash/text/TextField_as.cpp 2009-05-28 17:11:27 +0000
+++ b/libcore/asobj/flash/text/TextField_as.cpp 2009-06-08 22:24:55 +0000
@@ -22,16 +22,94 @@
 #endif
 
 #include "text/TextField_as.h"
-#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 "utf8.h"
+#include "log.h"
+#include "swf/DefineEditTextTag.h"
+#include "render.h"
+#include "movie_definition.h" // to extract version info
+#include "MovieClip.h"
+#include "ui/Keyboard_as.h" // for keyboard events
+#include "movie_root.h"     // for killing focus
+#include "as_environment.h" // for parse_path
+#include "action.h" // for as_standard_member enum
+#include "VM.h"
+#include "builtin_function.h" // for getter/setter properties
+#include "Font.h" // for using the _font member
+#include "fontlib.h" // for searching or adding fonts the _font member
+#include "Object.h" // for getObjectInterface
+#include "namedStrings.h"
+#include "Array_as.h" // for _listeners construction
+#include "AsBroadcaster.h" // for initializing self as a broadcaster
+#include "StringPredicates.h"
+#include "text/TextFormat_as.h" // for getTextFormat/setTextFormat
+#include "GnashKey.h" // key::code
+#include "TextRecord.h"
+#include "Point2d.h"
+#include "GnashNumeric.h"
+
+#include <algorithm> // std::min
+#include <string>
+#include <boost/algorithm/string/case_conv.hpp>
+#include <boost/assign/list_of.hpp>
+#include <boost/bind.hpp>
+
+#define PADDING_TWIPS 40
 
 namespace gnash {
 
 // Forward declarations
 namespace {
+       as_object* getTextFieldInterface(VM& vm);
+       void attachPrototypeProperties(as_object& proto);
+       void attachTextFieldStaticMembers(as_object& o);
+       
+       as_value textfield_password(const fn_call& fn);
+    as_value textfield_ctor(const fn_call& fn);
+    as_value textfield_multiline(const fn_call& fn);
+    as_value textfield_scroll(const fn_call& fn);
+    as_value textfield_maxscroll(const fn_call& fn);
+    as_value textfield_maxhscroll(const fn_call& fn);
+    as_value textfield_maxChars(const fn_call& fn);
+    as_value textfield_bottomScroll(const fn_call& fn);
+    as_value textfield_hscroll(const fn_call& fn);
+    as_value textfield_htmlText(const fn_call& fn);
+    as_value textfield_restrict(const fn_call& fn);
+    as_value textfield_background(const fn_call& fn);
+    as_value textfield_border(const fn_call& fn);
+    as_value textfield_backgroundColor(const fn_call& fn);
+    as_value textfield_borderColor(const fn_call& fn);
+    as_value textfield_text(const fn_call& fn);
+    as_value textfield_textColor(const fn_call& fn);
+    as_value textfield_embedFonts(const fn_call& fn);
+    as_value textfield_autoSize(const fn_call& fn);
+    as_value textfield_type(const fn_call& fn);
+    as_value textfield_wordWrap(const fn_call& fn);
+    as_value textfield_html(const fn_call& fn);
+    as_value textfield_selectable(const fn_call& fn);
+    as_value textfield_length(const fn_call& fn);
+    as_value textfield_textWidth(const fn_call& fn);
+    as_value textfield_textHeight(const fn_call& fn);
+       as_value textfield_variable(const fn_call& fn);
+    as_value textfield_setTextFormat(const fn_call& fn);
+    as_value textfield_getTextFormat(const fn_call& fn);
+    as_value textfield_setNewTextFormat(const fn_call& fn);
+    as_value textfield_getNewTextFormat(const fn_call& fn);
+    as_value textfield_getDepth(const fn_call& fn);
+    as_value textfield_getFontList(const fn_call& fn);
+    as_value textfield_removeTextField(const fn_call& fn);
+    as_value textfield_replaceSel(const fn_call& fn);
+    as_value textfield_replaceText(const fn_call& fn);
+       
+       //AS3 methods
+       as_value textfield_antiAliasType(const fn_call& fn);
+    as_value textfield_sharpness(const fn_call& fn);
+    as_value textfield_gridFitType(const fn_call& fn);
+    as_value textfield_thickness(const fn_call& fn);
+    as_value textfield_condenseWhite(const fn_call& fn);
+    as_value textfield_bottomScrollV(const fn_call& fn);
     as_value textfield_getCharBoundaries(const fn_call& fn);
     as_value textfield_getCharIndexAtPoint(const fn_call& fn);
     as_value textfield_getFirstCharInParagraph(const fn_call& fn);
@@ -45,48 +123,2855 @@
     as_value textfield_getParagraphLength(const fn_call& fn);
     as_value textfield_getTextFormat(const fn_call& fn);
     as_value textfield_replaceSelectedText(const fn_call& fn);
-    as_value textfield_replaceText(const fn_call& fn);
     as_value textfield_setSelection(const fn_call& fn);
-    as_value textfield_setTextFormat(const fn_call& fn);
+    as_value textfield_mouseWheelEnabled(const fn_call& fn);
+    //AS3 events
     as_value textfield_change(const fn_call& fn);
     as_value textfield_link(const fn_call& fn);
     as_value textfield_scroll(const fn_call& fn);
     as_value textfield_textInput(const fn_call& fn);
-    as_value textfield_ctor(const fn_call& fn);
     void attachTextFieldInterface(as_object& o);
     void attachTextFieldStaticInterface(as_object& o);
-    as_object* getTextFieldInterface();
-
-}
-
-class TextField_as : public as_object
-{
-
-public:
-
-    TextField_as()
-        :
-        as_object(getTextFieldInterface())
-    {}
-};
-
-// extern (used by Global.cpp)
-void textfield_class_init(as_object& global)
-{
-    static boost::intrusive_ptr<builtin_function> cl;
-
-    if (!cl) {
-        cl = new builtin_function(&textfield_ctor, getTextFieldInterface());
-        attachTextFieldStaticInterface(*cl);
+}
+
+TextField_as::TextField_as(DisplayObject* parent, const 
SWF::DefineEditTextTag& def,
+        int id)
+    :
+    InteractiveObject(parent, id),
+    _tag(&def),
+    _textDefined(def.hasText()),
+    _underlined(false),
+    _leading(def.leading()),
+    _alignment(def.alignment()),
+    _indent(def.indent()), 
+    _blockIndent(0),
+    _leftMargin(def.leftMargin()), 
+    _rightMargin(def.rightMargin()), 
+    _fontHeight(def.textHeight()), 
+    _font(0),
+    m_has_focus(false),
+    m_cursor(0u),
+    m_xcursor(0.0f),
+    m_ycursor(0.0f),
+    _multiline(def.multiline()),
+    _password(def.password()),
+    _maxChars(def.maxChars()),
+    _text_variable_registered(false),
+    _variable_name(def.variableName()),
+    _drawBackground(def.border()),
+    _backgroundColor(255,255,255,255),
+    _drawBorder(def.border()),
+    _borderColor(0,0,0,255),
+    _textColor(def.color()),
+    _embedFonts(def.getUseEmbeddedGlyphs()),
+    _wordWrap(def.wordWrap()),
+    _html(def.html()),
+    _selectable(!def.noSelect()),
+    _autoSize(autoSizeNone),
+    _type(def.readOnly() ? typeDynamic : typeInput),
+    _bounds(def.bounds()),
+    _selection(0, 0)
+{
+
+    // WARNING! remember to set the font *before* setting text value!
+    boost::intrusive_ptr<const Font> f = def.getFont();
+    if (!f) f = fontlib::get_default_font(); 
+    setFont(f);
+
+    int version = parent->getVM().getSWFVersion();
+    
+    // set default text *before* calling registerTextVariable
+    // (if the textvariable already exist and has a value
+    // the text will be replaced with it)
+    if (_textDefined) 
+    {
+        setTextValue(utf8::decodeCanonicalString(def.defaultText(), version));
+    }
+}
+
+TextField_as::TextField_as(DisplayObject* parent, const rect& bounds)
+    :
+    // the id trick is to fool assertions in DisplayObject ctor
+    InteractiveObject(parent, parent ? 0 : -1),
+    _textDefined(false),
+    _underlined(false),
+    _leading(0),
+    _alignment(ALIGN_LEFT),
+    _indent(0), 
+    _blockIndent(0),
+    _leftMargin(0), 
+    _rightMargin(0), 
+    _fontHeight(12 * 20), 
+    _font(0),
+    m_has_focus(false),
+    m_cursor(0u),
+    m_xcursor(0.0f),
+    m_ycursor(0.0f),
+    _multiline(false),
+    _password(false),
+    _maxChars(0),
+    _text_variable_registered(false),
+    _drawBackground(false),
+    _backgroundColor(255,255,255,255),
+    _drawBorder(false),
+    _borderColor(0, 0, 0, 255),
+    _textColor(0, 0, 0, 255),
+    _embedFonts(false), // ?
+    _wordWrap(false),
+    _html(false),
+    _selectable(true),
+    _autoSize(autoSizeNone),
+    _type(typeDynamic),
+    _bounds(bounds),
+    _selection(0, 0)
+{
+    // Use the default font (Times New Roman for Windows, Times for Mac
+    // according to docs. They don't say what it is for Linux.
+    boost::intrusive_ptr<const Font> f = fontlib::get_default_font(); 
+    setFont(f);
+}
+
+TextField_as::~TextField_as()
+{
+}
+
+/// This provides the prototype and static methods for TextField.
+//
+/// For SWF5 there is initially no prototype, for SWF6+ there is a 
+/// limited prototype. This is changed later on instantiation of a
+/// TextField.
+void
+TextField_as::init(as_object& global)
+{
+    static boost::intrusive_ptr<builtin_function> cl = NULL;
+
+    if (!cl)
+    {
+        VM& vm = global.getVM();
+
+        if (vm.getSWFVersion() < 6) {
+            /// Version 5 or less: no initial prototype
+            cl = new builtin_function(&textfield_ctor, 0);
+        }
+        else {
+            /// Version 6 upward: limited initial prototype
+            as_object* iface = getTextFieldInterface(vm);
+            cl = new builtin_function(&textfield_ctor, iface);
+        }
+
+        vm.addStatic(cl.get());
+
+        // replicate static members to class, to be able to access
+        // all methods as static functions
+        attachTextFieldStaticMembers(*cl);
+             
     }
 
     // Register _global.TextField
     global.init_member("TextField", cl.get());
 }
 
+void
+TextField_as::removeTextField()
+{
+    int depth = get_depth();
+    if ( depth < 0 || depth > 1048575 )
+    {
+        //IF_VERBOSE_ASCODING_ERRORS(
+        log_debug(_("CHECKME: removeTextField(%s): TextField depth (%d) "
+            "out of the 'dynamic' zone [0..1048575], won't remove"),
+            getTarget(), depth);
+        //);
+        return;
+    }
+
+    DisplayObject* parent = get_parent();
+    assert(parent); // every TextField must have a parent, right ?
+
+    MovieClip* parentSprite = parent->to_movie();
+
+    if (!parentSprite)
+    {
+        log_error("FIXME: attempt to remove a TextField being a child of a %s",
+                typeName(*parent));
+        return;
+    }
+
+    // second argument is arbitrary, see comments above
+    // the function declaration in MovieClip.h
+    parentSprite->remove_display_object(depth, 0);
+}
+
+void
+TextField_as::show_cursor(const SWFMatrix& mat)
+{
+    boost::uint16_t x = static_cast<boost::uint16_t>(m_xcursor);
+    boost::uint16_t y = static_cast<boost::uint16_t>(m_ycursor);
+    boost::uint16_t h = getFontHeight();
+
+    const std::vector<point> box = boost::assign::list_of
+        (point(x, y))
+        (point(x, y + h));
+    
+    render::drawLine(box, rgba(0,0,0,255), mat);
+}
+
+void
+TextField_as::display()
+{
+
+    registerTextVariable();
+
+    const bool drawBorder = getDrawBorder();
+    const bool drawBackground = getDrawBackground();
+
+    const SWFMatrix& wmat = getWorldMatrix();
+
+    if ((drawBorder || drawBackground) && !_bounds.is_null())
+    {
+
+        std::vector<point> coords(4);
+
+        boost::int32_t xmin = _bounds.get_x_min();
+        boost::int32_t xmax = _bounds.get_x_max();
+        boost::int32_t ymin = _bounds.get_y_min();
+        boost::int32_t ymax = _bounds.get_y_max();
+
+        coords[0].setTo(xmin, ymin); 
+        coords[1].setTo(xmax, ymin); 
+        coords[2].setTo(xmax, ymax); 
+        coords[3].setTo(xmin, ymax); 
+
+        rgba borderColor = drawBorder ? getBorderColor() : rgba(0,0,0,0);
+        rgba backgroundColor = drawBackground ? getBackgroundColor() :
+                                                rgba(0,0,0,0);
+
+        cxform cx = get_world_cxform();
+            
+        if (drawBorder) borderColor = cx.transform(borderColor);
+         
+        if (drawBackground) backgroundColor = cx.transform(backgroundColor);
+        
+#ifdef GNASH_DEBUG_TEXTFIELDS
+    log_debug("rendering a Pol composed by corners %s", _bounds);
+#endif
+
+        render::draw_poly(&coords.front(), 4, backgroundColor, 
+                borderColor, wmat, true);
+        
+    }
+
+    // Draw our actual text.
+    // Using a SWFMatrix to translate to def bounds seems an hack to me.
+    // A cleaner implementation is likely correctly setting the
+    // _xOffset and _yOffset memebers in glyph records.
+    // Anyway, see bug #17954 for a testcase.
+    SWFMatrix m = getWorldMatrix();
+
+    if (!_bounds.is_null()) {
+        m.concatenate_translation(_bounds.get_x_min(), _bounds.get_y_min()); 
+    }
+    
+    SWF::TextRecord::displayRecords(m, get_world_cxform(), _textRecords,
+            _embedFonts);
+
+    if (m_has_focus) show_cursor(wmat);
+    
+    clear_invalidated();
+}
+
+void
+TextField_as::add_invalidated_bounds(InvalidatedRanges& ranges, 
+    bool force)
+{
+    if (!force && !m_invalidated) return; // no need to redraw
+    
+    ranges.add(m_old_invalidated_ranges);
+
+    const SWFMatrix& wm = getWorldMatrix();
+
+    rect bounds = getBounds();
+    bounds.expand_to_rect(m_text_bounding_box); 
+    wm.transform(bounds);
+    ranges.add(bounds.getRange());            
+}
+
+void
+TextField_as::replaceSelection(const std::string& replace)
+{
+
+    const int version = _vm.getSWFVersion();
+    const std::wstring& wstr = utf8::decodeCanonicalString(replace, version);
+    
+    const size_t start = _selection.first;
+    const size_t replaceLength = wstr.size();
+
+    _text.replace(start, _selection.second - start, wstr);
+    _selection = std::make_pair(start + replaceLength, start + replaceLength);
+}
+
+void
+TextField_as::setSelection(int start, int end)
+{
+
+    if (_text.empty()) {
+        _selection = std::make_pair(0, 0);
+        return;
+    }
+
+    const size_t textLength = _text.size();
+
+    if (start < 0) start = 0;
+    else start = std::min<size_t>(start, textLength);
+
+    if (end < 0) end = 0;
+    else end = std::min<size_t>(end, textLength);
+
+    // The cursor position is always set to the end value, even if the
+    // two values are swapped to obtain the selection. Equal values are
+    // fine.
+    m_cursor = end;
+    if (start > end) std::swap(start, end);
+
+    _selection = std::make_pair(start, end);
+}
+
+bool
+TextField_as::on_event(const event_id& ev)
+{
+    if (isReadOnly()) return false;
+
+    switch (ev.id())
+    {
+        case event_id::KEY_PRESS:
+        {
+            if ( getType() != typeInput ) break; // not an input field
+            std::wstring s = _text;
+
+            // id.keyCode is the unique gnash::key::code for a 
DisplayObject/key.
+            // The maximum value is about 265, including function keys.
+            // It seems that typing in DisplayObjects outside the Latin-1 set
+            // (256 DisplayObject codes, identical to the first 256 of UTF-8)
+            // is not supported, though a much greater number UTF-8 codes can 
be
+            // stored and displayed. See utf.h for more information.
+            // This is a limit on the number of key codes, not on the
+            // capacity of strings.
+            gnash::key::code c = ev.keyCode();
+
+            // maybe _text is changed in ActionScript
+            m_cursor = std::min<size_t>(m_cursor, _text.size());
+
+            switch (c)
+            {
+                case key::BACKSPACE:
+                    if (m_cursor > 0)
+                    {
+                        s.erase(m_cursor - 1, 1);
+                        m_cursor--;
+                        setTextValue(s);
+                    }
+                    break;
+
+                case key::DELETEKEY:
+                    if (s.size() > m_cursor)
+                    {
+                        s.erase(m_cursor, 1);
+                        setTextValue(s);
+                    }
+                    break;
+
+                case key::INSERT:        // TODO
+                    break;
+
+                case key::HOME:
+                case key::PGUP:
+                case key::UP:
+                    m_cursor = 0;
+                    format_text();
+                    break;
+
+                case key::END:
+                case key::PGDN:
+                case key::DOWN:
+                    m_cursor = _text.size();
+                    format_text();
+                    break;
+
+                case key::LEFT:
+                    m_cursor = m_cursor > 0 ? m_cursor - 1 : 0;
+                    format_text();
+                    break;
+
+                case key::RIGHT:
+                    m_cursor = m_cursor < _text.size() ? m_cursor + 1 :
+                                                        _text.size();
+                    format_text();
+                    break;
+
+                default:
+                    wchar_t t = static_cast<wchar_t>(
+                            gnash::key::codeMap[c][key::ASCII]);
+                    if (t != 0)
+                    {
+                        // Insert one copy of the DisplayObject
+                        // at the cursor position.
+                          s.insert(m_cursor, 1, t);
+                        m_cursor++;
+                    }
+                    setTextValue(s);
+                    break;
+            }
+            onChanged();
+        }
+
+        default:
+            return false;
+    }
+    return true;
+}
+
+InteractiveObject*
+TextField_as::topmostMouseEntity(boost::int32_t x, boost::int32_t y)
+{
+
+    if (!visible()) return 0;
+    
+    // shouldn't this be !can_handle_mouse_event() instead ?
+    // not selectable, so don't catch mouse events!
+    if (!_selectable) return 0;
+
+    SWFMatrix m = getMatrix();
+    point p(x, y);
+    m.invert().transform(p);
+
+    if (_bounds.point_test(p.x, p.y)) return this;
+
+    return 0;
+}
+
+void
+TextField_as::updateText(const std::string& str)
+{
+    int version = _vm.getSWFVersion();
+    const std::wstring& wstr = utf8::decodeCanonicalString(str, version);
+    updateText(wstr);
+}
+
+void
+TextField_as::updateText(const std::wstring& wstr)
+{
+    _textDefined = true;
+
+    if (_text == wstr) return;
+
+    set_invalidated();
+
+    _text = wstr;
+    format_text();
+}
+
+void
+TextField_as::setTextValue(const std::wstring& wstr)
+{
+
+    updateText(wstr);
+
+    if ( ! _variable_name.empty() && _text_variable_registered )
+    {
+        // TODO: notify MovieClip if we have a variable name !
+        VariableRef ref = parseTextVariableRef(_variable_name);
+        as_object* tgt = ref.first;
+        if ( tgt )
+        {
+            int version = _vm.getSWFVersion();
+            // we shouldn't truncate, right?
+            tgt->set_member(ref.second, utf8::encodeCanonicalString(wstr,
+                        version)); 
+        }
+        else    
+        {
+            // nothing to do (too early ?)
+            log_debug("setTextValue: variable name %s points to a non-existent"
+                    " target, I guess we would not be registered if this was "
+                    "true, or the sprite we've registered our variable name "
+                    "has been unloaded", _variable_name);
+        }
+    }
+}
+
+std::string
+TextField_as::get_text_value() const
+{
+    // we need the const_cast here because registerTextVariable
+    // *might* change our text value, calling the non-const
+    // setTextValue().
+    // This happens if the TextVariable has not been already registered
+    // and during registration comes out to name an existing variable
+    // with a pre-existing value.
+    const_cast<TextField_as*>(this)->registerTextVariable();
+
+    int version = _vm.getSWFVersion();
+
+    return utf8::encodeCanonicalString(_text, version);
+}
+
+bool
+TextField_as::set_member(string_table::key name,
+        const as_value& val, string_table::key nsname, bool ifFound)
+{
+
+    // FIXME: Turn all standard members into getter/setter properties
+    //        of the TextField class. See attachTextFieldInterface()
+    // @@ TODO need to inherit basic stuff like _x, _y, _xscale, _yscale etc ?
+
+    switch (name)
+    {
+    default:
+        break;
+    case NSV::PROP_uX:
+    {
+        SWFMatrix m = getMatrix();
+        double x = infinite_to_zero( val.to_number() );
+        m.tx = pixelsToTwips(x);    
+        setMatrix(m); // no need to update caches when only changing 
translation
+
+        // m_accept_anim_moves = false;
+        return true;
+    }
+    case NSV::PROP_uY:
+    {
+        SWFMatrix m = getMatrix();
+        double y = infinite_to_zero( val.to_number() );
+        m.ty = pixelsToTwips(y);
+        setMatrix(m); // no need to update caches when only changing 
translation
+
+        // m_accept_anim_moves = false; 
+        return true;
+    }
+    case NSV::PROP_uWIDTH:
+    {
+        double nw = val.to_number(); 
+        if (!isFinite(nw) )
+        {
+            // might be our fault, see the TODO above 
+            // (missing to pass as_environment out..)
+            IF_VERBOSE_ASCODING_ERRORS(
+            log_aserror(_("Attempt to set TextField._width to %g"), nw);
+            );
+            return true;
+        }
+
+        if ( nw < 0 )
+        {
+            IF_VERBOSE_ASCODING_ERRORS(
+            log_aserror(_("Attempt to set TextField._width to a "
+                    "negative number: %g, toggling sign"), nw);
+            );
+            nw = -nw;
+        }
+
+        if ( _bounds.width() == pixelsToTwips(nw) )
+        {
+#ifdef GNASH_DEBUG_TEXTFIELDS
+            log_debug("TextField width already == %g, nothing to do to "
+                    "change it", nw);
+#endif
+            return true; // nothing to do
+        }
+        if ( _bounds.is_null() )
+        {
+#ifdef GNASH_DEBUG_TEXTFIELDS
+            log_debug("NULL TextField bounds : %s", _bounds);
+#endif
+            return true;
+        }
+
+#ifdef GNASH_DEBUG_TEXTFIELDS
+        log_debug("Chaging TextField width to %g", nw);
+#endif
+
+        set_invalidated();
+
+        // Modify TextField drawing rectangle
+        // TODO: check which anchor point we should use !
+        boost::int32_t xmin = _bounds.get_x_min();
+        boost::int32_t ymin = _bounds.get_y_min();
+        boost::int32_t ymax = _bounds.get_y_max();
+        boost::int32_t xmax = xmin + pixelsToTwips(nw);
+
+        assert(xmin <= xmax);
+        _bounds.set_to_rect(xmin, ymin, xmax, ymax);
+        assert( _bounds.width() == pixelsToTwips(nw) );
+
+        // previously truncated text might get visible now
+        // TODO: if nested masks were implemented we would 
+        // not need to reformat text here
+        format_text();
+
+        return true;
+    }
+    case NSV::PROP_uHEIGHT:
+    {
+        double nh = val.to_number(); 
+        if (!isFinite(nh) )
+        {
+            // might be our fault, see the TODO above (missing to pass
+            // as_environment out..)
+            IF_VERBOSE_ASCODING_ERRORS(
+            log_aserror(_("Attempt to set TextField._height to %g"), nh);
+            );
+            return true;
+        }
+
+        if ( nh < 0.0f )
+        {
+            IF_VERBOSE_ASCODING_ERRORS(
+            log_aserror(_("Attempt to set TextField._height to a negative "
+                    "number: %g, toggling sign"), nh);
+            );
+            nh = -nh;
+        }
+
+        if ( _bounds.height() == pixelsToTwips(nh) )
+        {
+#ifdef GNASH_DEBUG_TEXTFIELDS
+            log_debug("TextField height already == %g, nothing to do to "
+                    "change it", nh);
+#endif // GNASH_DEBUG_TEXTFIELDS
+            return true; // nothing to do
+        }
+        if ( _bounds.is_null() )
+        {
+            return true;
+        }
+
+#ifdef GNASH_DEBUG_TEXTFIELDS
+        log_debug("Changing TextField height to %g", nh);
+#endif // GNASH_DEBUG_TEXTFIELDS
+        set_invalidated();
+
+        // Modify TextField drawing rectangle
+        // TODO: check which anchor point we should use !
+        boost::int32_t xmin = _bounds.get_x_min();
+        boost::int32_t xmax = _bounds.get_x_max();
+        boost::int32_t ymin = _bounds.get_y_min();
+        _bounds.set_to_rect(xmin, ymin, xmax, ymin + pixelsToTwips(nh) );
+
+        assert(_bounds.height() == pixelsToTwips(nh));
+
+        // previously truncated text might get visible now
+        // TODO: if nested masks were implemented we would 
+        // not need to reformat text here
+        format_text();
+
+        return true;
+    }
+    case NSV::PROP_uVISIBLE:
+    {
+        set_visible(val.to_bool());
+        return true;
+    }
+    case NSV::PROP_uALPHA:
+    {
+        // @@ TODO this should be generic to class DisplayObject!
+        // Arg is in percent.
+        cxform    cx = get_cxform();
+        cx.aa = (boost::int16_t)(val.to_number() * 2.56);
+        set_cxform(cx);
+        return true;
+    }
+    // @@ TODO see TextField members in Flash MX docs
+    }    // end switch
+
+
+    return as_object::set_member(name, val, nsname, ifFound);
+}
+
+bool
+TextField_as::get_member(string_table::key name, as_value* val,
+    string_table::key nsname)
+{
+    //log_debug("TextField.get_member(%s)", name);
+
+    // FIXME: Turn all standard members into getter/setter properties
+    //        of the TextField class. See attachTextFieldInterface()
+
+    switch (name)
+    {
+    default:
+        break;
+    case NSV::PROP_uVISIBLE:
+    {
+        val->set_bool(visible());
+        return true;
+    }
+    case NSV::PROP_uALPHA:
+    {
+        // @@ TODO this should be generic to class DisplayObject!
+        const cxform&    cx = get_cxform();
+        val->set_double(cx.aa / 2.56);
+        return true;
+    }
+    case NSV::PROP_uX:
+    {
+        SWFMatrix    m = getMatrix();    
+        val->set_double(twipsToPixels(m.tx));
+        return true;
+    }
+    case NSV::PROP_uY:
+    {
+        SWFMatrix    m = getMatrix();    
+        val->set_double(twipsToPixels(m.ty));
+        return true;
+    }
+    case NSV::PROP_uWIDTH:
+    {
+        val->set_double(twipsToPixels(get_width()));
+#ifdef GNASH_DEBUG_TEXTFIELDS
+        log_debug("Got TextField width == %s", *val);
+#endif // GNASH_DEBUG_TEXTFIELDS
+        return true;
+    }
+    case NSV::PROP_uHEIGHT:
+    {
+        val->set_double(twipsToPixels(get_height()));
+#ifdef GNASH_DEBUG_TEXTFIELDS
+        log_debug("Got TextField height == %s", *val);
+#endif // GNASH_DEBUG_TEXTFIELDS
+        return true;
+    }
+    }    // end switch
+
+    return as_object::get_member(name, val, nsname);
+    
+}
+
+float
+TextField_as::align_line(TextAlignment align,
+        int last_line_start_record, float x)
+{
+
+    float width = _bounds.width(); 
+    float right_margin = getRightMargin();
+
+    float extra_space = (width - right_margin) - x - PADDING_TWIPS;
+
+    //assert(extra_space >= 0.0f);
+    if (extra_space <= 0.0f)
+    {
+#ifdef GNASH_DEBUG_TEXTFIELDS
+        log_debug(_("TextField text doesn't fit in its boundaries: "
+                "width %g, margin %g - nothing to align"),
+                width, right_margin);
+#endif
+        return 0.0f;
+    }
+
+    float shift_right = 0.0f;
+
+    if (align == ALIGN_LEFT)
+    {
+        // Nothing to do; already aligned left.
+        return 0.0f;
+    }
+    else if (align == ALIGN_CENTER)
+    {
+        // Distribute the space evenly on both sides.
+        shift_right = extra_space / 2;
+    }
+    else if (align == ALIGN_RIGHT)
+    {
+        // Shift all the way to the right.
+        shift_right = extra_space;
+    }
+
+    // Shift the beginnings of the records on this line.
+    for (unsigned int i = last_line_start_record; i < _textRecords.size(); ++i)
+    {
+        SWF::TextRecord& rec = _textRecords[i];
+
+        //if ( rec.hasXOffset() ) // why?
+            rec.setXOffset(rec.xOffset() + shift_right); 
+    }
+    return shift_right;
+}
+
+boost::intrusive_ptr<const Font>
+TextField_as::setFont(boost::intrusive_ptr<const Font> newfont)
+{
+    if ( newfont == _font ) return _font;
+
+    boost::intrusive_ptr<const Font> oldfont = _font;
+    set_invalidated();
+    _font = newfont; 
+    format_text();
+    return oldfont;  
+}
+
+void
+TextField_as::insertTab(SWF::TextRecord& rec, boost::int32_t& x, float scale)
+{
+    // tab (ASCII HT)
+    const int space = 32;
+    int index = rec.getFont()->get_glyph_index(space, _embedFonts); 
+    if ( index == -1 )
+    {
+        IF_VERBOSE_MALFORMED_SWF (
+          log_error(_("TextField: missing glyph for space char (needed "
+                  "for TAB). Make sure DisplayObject shapes for font "
+                  "%s are being exported into your SWF file."),
+                rec.getFont()->name());
+        );
+    }
+    else
+    {
+        SWF::TextRecord::GlyphEntry ge;
+        ge.index = index;
+        ge.advance = scale * rec.getFont()->get_advance(index, 
+                _embedFonts);
+
+        const int tabstop = 8;
+        rec.addGlyph(ge, tabstop);
+        x += ge.advance * tabstop;
+    }
+}
+
+void
+TextField_as::format_text()
+{
+    _textRecords.clear();
+
+    // nothing more to do if text is empty
+    if ( _text.empty() )
+    {
+        // TODO: should we still reset _bounds if autoSize != autoSizeNone ?
+        //       not sure we should...
+        reset_bounding_box(0, 0);
+        return;
+    }
+
+    // See bug #24266
+    const rect& defBounds = _bounds;
+
+    AutoSizeValue autoSize = getAutoSize();
+    if ( autoSize != autoSizeNone )
+    {
+        // define GNASH_DEBUG_TEXT_FORMATTING on top to get useful info
+        //LOG_ONCE( log_debug(_("TextField.autoSize != 'none' TESTING")) );
+
+        // When doing WordWrap we don't want to change
+        // the boundaries. See bug #24348
+        if (!  doWordWrap() )
+        {
+            _bounds.set_to_rect(0, 0, 0, 0); // this is correct for 'true'
+        }
+    }
+
+    // Should get info from autoSize too maybe ?
+    TextAlignment textAlignment = getTextAlignment();
+
+    // FIXME: I don't think we should query the definition
+    // to find the appropriate font to use, as ActionScript
+    // code should be able to change the font of a TextField
+    //
+    if (!_font)
+    {
+        log_error(_("No font for TextField!"));
+        return;
+    }
+
+    boost::uint16_t fontHeight = getFontHeight();
+    float scale = fontHeight / (float)_font->unitsPerEM(_embedFonts); 
+    float fontDescent = _font->descent() * scale; 
+    float fontLeading = _font->leading() * scale;
+    boost::uint16_t leftMargin = getLeftMargin();
+    boost::uint16_t rightMargin = getRightMargin();
+    boost::uint16_t indent = getIndent();
+    boost::uint16_t blockIndent = getBlockIndent();
+    bool underlined = getUnderlined();
+
+    //log_debug("%s: fontDescent:%g, fontLeading:%g, fontHeight:%g, scale:%g",
+    //  getTarget(), fontDescent, fontLeading, fontHeight, scale);
+
+    SWF::TextRecord rec;    // one to work on
+    rec.setFont(_font.get());
+    rec.setUnderline(underlined);
+    rec.setColor(getTextColor()); 
+    rec.setXOffset(PADDING_TWIPS + 
+            std::max(0, leftMargin + indent + blockIndent));
+    rec.setYOffset(PADDING_TWIPS + fontHeight + (fontLeading - fontDescent));
+    rec.setTextHeight(fontHeight);
+
+    boost::int32_t x = static_cast<boost::int32_t>(rec.xOffset());
+    boost::int32_t y = static_cast<boost::int32_t>(rec.yOffset());
+
+    // Start the bbox at the upper-left corner of the first glyph.
+    reset_bounding_box(x, y - fontDescent + fontHeight); 
+
+    float leading = getLeading();
+    leading += fontLeading * scale; // not sure this is correct...
+
+    int    last_code = -1; // only used if _embedFonts
+    int    last_space_glyph = -1;
+    int    last_line_start_record = 0;
+
+    unsigned int idx = 0;
+    m_xcursor = x;
+    m_ycursor = y;
+
+    assert(! _text.empty() );
+    
+    boost::uint32_t code = 0;
+    
+    // String iterators are very sensitive to 
+    // potential changes to the string (to allow for copy-on-write).
+    // So there must be no external changes to the string or
+    // calls to most non-const member functions during this loop.
+    // Especially not c_str() or data().
+    std::wstring::const_iterator it = _text.begin();
+    const std::wstring::const_iterator e = _text.end();
+
+    while (it != e)
+    {
+        code = *it++;
+        if (!code) break;
+
+        if ( _embedFonts )
+        {
+            x += rec.getFont()->get_kerning_adjustment(last_code, 
+                    static_cast<int>(code)) * scale;
+            last_code = static_cast<int>(code);
+        }
+
+        // Expand the bounding-box to the lower-right corner of each glyph as
+        // we generate it.
+        m_text_bounding_box.expand_to_point(x, y + fontDescent);
+
+        switch (code)
+        {
+            case 27:
+                // Ignore escape
+                break;
+            case 9:
+                insertTab(rec, x, scale);
+                break;
+            case 13:
+            case 10:
+            {
+                // newline.
+
+                // Frigging Flash seems to use '\r' (13) as its
+                // default newline DisplayObject.  If we get DOS-style \r\n
+                // sequences, it'll show up as double newlines, so maybe we
+                // need to detect \r\n and treat it as one newline.
+
+                // Close out this stretch of glyphs.
+                _textRecords.push_back(rec);
+                align_line(textAlignment, last_line_start_record, x);
+
+                // Expand bounding box to include last column of text ...
+                if ( _autoSize != autoSizeNone ) {
+                    _bounds.expand_to_point(x + PADDING_TWIPS,
+                            y + PADDING_TWIPS);
+                }
+
+                // new paragraphs get the indent.
+                x = std::max(0, leftMargin + indent) + PADDING_TWIPS;
+                y += fontHeight + leading; 
+
+                // Start a new record on the next line. Other properties of the
+                // TextRecord should be left unchanged.
+                rec.clearGlyphs();
+                rec.setXOffset(x);
+                rec.setYOffset(y);
+
+                last_space_glyph = -1;
+                last_line_start_record = _textRecords.size();
+
+                continue;
+            }
+            case 8:
+                // Backspace 
+
+                // This is a limited hack to enable overstrike effects.
+                // It backs the cursor up by one DisplayObject and then 
continues
+                // the layout.  E.g. you can use this to display an underline
+                // cursor inside a simulated text-entry box.
+                //
+                // ActionScript understands the '\b' escape sequence
+                // for inserting a BS DisplayObject.
+                //
+                // ONLY WORKS FOR BACKSPACING OVER ONE CHARACTER, WON'T BS
+                // OVER NEWLINES, ETC.
+
+                if (!rec.glyphs().empty())
+                {
+                    // Peek at the previous glyph, and zero out its advance
+                    // value, so the next char overwrites it.
+                    float advance = rec.glyphs().back().advance;
+                    x -= advance; 
+                    // Remove one glyph
+                    rec.clearGlyphs(1);
+                }
+                continue;
+            case '<':
+                if (_html)
+                {
+                    LOG_ONCE(log_debug(_("HTML in a text field is unsupported, 
"
+                                         "gnash will just ignore the tags and "
+                                         "print their content")));
+         
+                    std::wstring discard;
+                    bool complete = parseHTML(discard, it, e);
+                    
+                    if (!complete) continue;
+                    else break;
+
+                }
+                // If HTML isn't enabled, carry on and insert the glyph.
+
+            case 32:
+                last_space_glyph = rec.glyphs().size();
+                // Don't break, as we still need to insert the space glyph.
+
+            default:
+            {
+
+                // The font table holds up to 65535 glyphs. Casting
+                // from uint32_t would, in the event that the code
+                // is higher than 65535, result in the wrong DisplayObject
+                // being chosen. Flash can currently only handle 16-bit
+                // values.
+                int index = rec.getFont()->get_glyph_index(
+                        static_cast<boost::uint16_t>(code), _embedFonts);
+
+                IF_VERBOSE_MALFORMED_SWF (
+                    if (index == -1)
+                    {
+                        // Missing glyph! Log the first few errors.
+                        static int s_log_count = 0;
+                        if (s_log_count < 10)
+                        {
+                            s_log_count++;
+                            if (_embedFonts)
+                            {
+                                log_swferror(_("TextField: missing embedded "
+                                    "glyph for char %d. Make sure 
DisplayObject "
+                                    "shapes for font %s are being exported "
+                                    "into your SWF file"),
+                                    code, _font->name());
+                            }
+                            else
+                            {
+                                log_swferror(_("TextField: missing device "
+                                    "glyph for char %d. Maybe you don't have "
+                                    "font '%s' installed in your system."),
+                                    code, _font->name());
+                            }
+                        }
+
+                        // Drop through and use index == -1; this will display
+                        // using the empty-box glyph
+                    }
+                );
+
+                SWF::TextRecord::GlyphEntry ge;
+                ge.index = index;
+                ge.advance = scale * rec.getFont()->get_advance(index, 
+                        _embedFonts);
+
+                rec.addGlyph(ge);
+
+                x += ge.advance;
+            }
+        }
+
+        float width = defBounds.width();
+        if (x >= width - rightMargin - PADDING_TWIPS)
+        {
+#ifdef GNASH_DEBUG_TEXT_FORMATTING
+            log_debug("Text in TextField %s exceeds width [ _bounds %s ]", 
+                    getTarget(), _bounds);
+#endif
+
+            // No wrap and no resize: truncate
+            if (!doWordWrap() && autoSize == autoSizeNone)
+            {
+#ifdef GNASH_DEBUG_TEXT_FORMATTING
+                log_debug(" wordWrap=false, autoSize=none");
+#endif 
+                // Truncate long line, but keep expanding text box
+                bool newlinefound = false;
+                while (it != e)
+                {
+                    code = *it++;
+                    if (_embedFonts)
+                    {
+                        x += rec.getFont()->get_kerning_adjustment(last_code,
+                                static_cast<int>(code)) * scale;
+                        last_code = code;
+                    }
+                    // Expand the bounding-box to the lower-right corner
+                    // of each glyph, even if we don't display it 
+                    m_text_bounding_box.expand_to_point(x, y + fontDescent);
+#ifdef GNASH_DEBUG_TEXT_FORMATTING
+                    log_debug("Text bbox expanded to %s (width: %f)",
+                            m_text_bounding_box, m_text_bounding_box.width());
+#endif
+
+                    if (code == 13 || code == 10)
+                    {
+                        newlinefound = true;
+                        break;
+                    }
+
+                    int index = rec.getFont()->get_glyph_index(
+                            static_cast<boost::uint16_t>(code), _embedFonts);
+                    x += scale * rec.getFont()->get_advance(index, 
_embedFonts);
+
+                }
+                if (!newlinefound) break;
+            }
+            else if ( doWordWrap() )
+            {
+#ifdef GNASH_DEBUG_TEXT_FORMATTING
+                log_debug(" wordWrap=true");
+#endif 
+
+                // Insert newline if there's space or autosize != none
+
+                // Close out this stretch of glyphs.
+                _textRecords.push_back(rec);
+
+                float previous_x = x;
+                x = leftMargin + blockIndent + PADDING_TWIPS;
+                y += fontHeight + leading;
+
+                // Start a new record on the next line.
+                rec.clearGlyphs();
+                rec.setXOffset(x);
+                rec.setYOffset(y);
+
+                // TODO : what if m_text_glyph_records is empty ?
+                // Is it possible ?
+                assert(!_textRecords.empty());
+                SWF::TextRecord& last_line = _textRecords.back();
+                if (last_space_glyph == -1)
+                {
+                    // Pull the previous glyph down onto the
+                    // new line.
+                    if (!last_line.glyphs().empty())
+                    {
+                        rec.addGlyph(last_line.glyphs().back());
+                        x += last_line.glyphs().back().advance;
+                        previous_x -= last_line.glyphs().back().advance;
+                        last_line.clearGlyphs(1);
+                    }
+                }
+                else
+                {
+                    // Move the previous word down onto the next line.
+
+                    previous_x -= last_line.glyphs()[last_space_glyph].advance;
+
+                    const SWF::TextRecord::Glyphs::size_type lineSize =
+                        last_line.glyphs().size();
+                    for (unsigned int i = last_space_glyph + 1; i < lineSize;
+                            ++i)
+                    {
+                        rec.addGlyph(last_line.glyphs()[i]);
+                        x += last_line.glyphs()[i].advance;
+                        previous_x -= last_line.glyphs()[i].advance;
+                    }
+                    last_line.clearGlyphs(lineSize - last_space_glyph);
+                }
+
+                align_line(textAlignment, last_line_start_record, previous_x);
+
+                last_space_glyph = -1;
+                last_line_start_record = _textRecords.size();
+                
+            }
+            else
+            {
+#ifdef GNASH_DEBUG_TEXT_FORMATTING
+                log_debug(" wordWrap=%d, autoSize=%d", _wordWrap, _autoSize);
+#endif 
+            }
+        }
+
+        if (y > (defBounds.height() - PADDING_TWIPS) && 
+                autoSize == autoSizeNone )
+        {
+#ifdef GNASH_DEBUG_TEXT_FORMATTING
+            log_debug("Text with wordWrap exceeds height of box");
+#endif
+            rec.clearGlyphs();
+            // TODO: should still compute m_text_bounds !
+            LOG_ONCE(log_unimpl("Computing text bounds of a TextField "
+                        "containing text that doesn't fit the box 
vertically"));
+            break;
+        }
+
+        if (m_cursor > idx)
+        {
+            m_xcursor = x;
+            m_ycursor = y;
+        }
+        idx++;
+
+        // TODO: HTML markup
+    }
+
+    // Expand bounding box to include the whole text (if autoSize)
+    if ( _autoSize != autoSizeNone )
+    {
+        _bounds.expand_to_point(x+PADDING_TWIPS, y+PADDING_TWIPS);
+    }
+
+    // Add this line to our output.
+    if (!rec.glyphs().empty()) _textRecords.push_back(rec);
+
+    float extra_space = align_line(textAlignment, last_line_start_record, x);
+
+    m_xcursor += static_cast<int>(extra_space);
+    m_ycursor -= fontHeight + (fontLeading - fontDescent);
+}
+
+TextField_as::VariableRef
+TextField_as::parseTextVariableRef(const std::string& variableName) const
+{
+    VariableRef ret;
+    ret.first = 0;
+
+#ifdef DEBUG_DYNTEXT_VARIABLES
+    log_debug(_("VariableName: %s"), variableName);
+#endif
+
+    /// Why isn't get_environment const again ?
+    as_environment& env = const_cast<TextField_as*>(this)->get_environment();
+
+    as_object* target = env.get_target();
+    if ( ! target )
+    {
+        IF_VERBOSE_MALFORMED_SWF(
+            log_swferror(_("Current environment has no target, "
+                "can't bind VariableName (%s) associated to "
+                "text field. Gnash will try to register "
+                "again on next access."), variableName);
+        );
+        return ret;
+    }
+
+    // If the variable string contains a path, we extract
+    // the appropriate target from it and update the variable
+    // name. We copy the string so we can assign to it if necessary.
+    std::string parsedName = variableName;
+    std::string path, var;
+    if (as_environment::parse_path(variableName, path, var))
+    {
+#ifdef DEBUG_DYNTEXT_VARIABLES
+        log_debug(_("Variable text Path: %s, Var: %s"), path, var);
+#endif
+        // find target for the path component
+        // we use our parent's environment for this
+        target = env.find_object(path);
+
+        parsedName = var;
+    }
+
+    if ( ! target )
+    {
+        IF_VERBOSE_MALFORMED_SWF(
+            log_swferror(_("VariableName associated to text field refers "
+                    "to an unknown target (%s). It is possible that the "
+                    "DisplayObject will be instantiated later in the SWF "
+                    "stream. Gnash will try to register again on next "
+                    "access."), path);
+        );
+        return ret;
+    }
+
+    ret.first = target;
+    ret.second = _vm.getStringTable().find(parsedName);
+
+    return ret;
+}
+
+void
+TextField_as::registerTextVariable() 
+{
+//#define DEBUG_DYNTEXT_VARIABLES 1
+
+#ifdef DEBUG_DYNTEXT_VARIABLES
+    log_debug(_("registerTextVariable() called"));
+#endif
+
+    if ( _text_variable_registered )
+    {
+#ifdef DEBUG_DYNTEXT_VARIABLES
+        log_debug(_("registerTextVariable() no-op call (already registered)"));
+#endif
+        return;
+    }
+
+    if ( _variable_name.empty() )
+    {
+#ifdef DEBUG_DYNTEXT_VARIABLES
+        log_debug(_("string is empty, consider as registered"));
+#endif
+        _text_variable_registered=true;
+        return;
+    }
+
+    VariableRef varRef = parseTextVariableRef(_variable_name);
+    as_object* target = varRef.first;
+    if ( ! target )
+    {
+        log_debug(_("VariableName associated to text field (%s) refer to "
+                    "an unknown target. It is possible that the DisplayObject "
+                    "will be instantiated later in the SWF stream. "
+                    "Gnash will try to register again on next access."),
+                _variable_name);
+        return;
+    }
+
+    string_table::key key = varRef.second;
+
+    // check if the VariableName already has a value,
+    // in that case update text value
+    as_value val;
+    
+    int version = _vm.getSWFVersion();
+    
+    if (target->get_member(key, &val) )
+    {
+#ifdef DEBUG_DYNTEXT_VARIABLES
+        log_debug(_("target object (%s @ %p) does have a member named %s"),
+            typeName(*target), (void*)target, _vm.getStringTable().value(key));
+#endif
+        // TODO: pass environment to to_string ?
+        // as_environment& env = get_environment();
+        setTextValue(utf8::decodeCanonicalString(val.to_string(), version));
+    }
+    else if ( _textDefined )
+    {
+        as_value newVal = as_value(utf8::encodeCanonicalString(_text, 
version));
+#ifdef DEBUG_DYNTEXT_VARIABLES
+        log_debug(_("target sprite (%s @ %p) does NOT have a member "
+                    "named %s (no problem, we'll add it with value %s)"),
+                    typeName(*target), (void*)target,
+                    _vm.getStringTable().value(key), newVal);
+#endif
+        target->set_member(key, newVal);
+    }
+    else
+    {
+#ifdef DEBUG_DYNTEXT_VARIABLES
+        log_debug(_("target sprite (%s @ %p) does NOT have a member "
+                    "named %s, and we don't have text defined"),
+                    typeName(*target), (void*)target,
+                    _vm.getStringTable().value(key));
+#endif
+    }
+
+    MovieClip* sprite = target->to_movie();
+
+    if ( sprite )
+    {
+        // add the textfield variable to the target sprite
+        // TODO: have set_textfield_variable take a string_table::key instead ?
+#ifdef DEBUG_DYNTEXT_VARIABLES
+        log_debug("Calling set_textfield_variable(%s) against sprite %s",
+                _vm.getStringTable().value(key), sprite->getTarget());
+#endif
+        sprite->set_textfield_variable(_vm.getStringTable().value(key), this);
+
+    }
+    _text_variable_registered=true;
+
+}
+
+/// Parses an HTML tag (between < and >) and puts
+/// the contents into tag. Returns false if the
+/// tag was incomplete. The iterator is moved to after
+/// the closing tag or the end of the string.
+bool
+TextField_as::parseHTML(std::wstring& tag, std::wstring::const_iterator& it,
+                               const std::wstring::const_iterator& e) const
+{
+
+    bool complete = false;
+
+    while (it != e)
+    {
+        if (*it == '>')
+        {
+            ++it;
+            complete = true;
+            break;
+        }
+
+        // Check for NULL DisplayObject
+        if (*it == 0) break;
+
+        tag.push_back(*it++);
+    }
+    
+#ifdef GNASH_DEBUG_TEXTFIELDS
+    log_debug ("HTML tag: %s", utf8::encodeCanonicalString(tag, 7));
+#endif
+    
+    return complete;
+}
+
+void
+TextField_as::set_variable_name(const std::string& newname)
+{
+    if ( newname != _variable_name )
+    {
+        _variable_name = newname;
+
+        // The name was empty or undefined, so there's nothing more to do.
+        if (_variable_name.empty()) return;
+
+        _text_variable_registered = false;
+
+#ifdef DEBUG_DYNTEXT_VARIABLES
+        log_debug("Calling updateText after change of variable name");
+#endif
+
+        // Use the original definition text if this isn't dynamically
+        // created.
+        if (_tag) updateText(_tag->defaultText());
+
+#ifdef DEBUG_DYNTEXT_VARIABLES
+        log_debug("Calling registerTextVariable after change of variable "
+                "name and updateText call");
+#endif
+        registerTextVariable();
+    }
+}
+
+bool
+TextField_as::pointInShape(boost::int32_t x, boost::int32_t y) const
+{
+    SWFMatrix wm = getWorldMatrix();
+    point lp(x, y);
+    wm.invert().transform(lp);
+    return _bounds.point_test(lp.x, lp.y);
+}
+
+bool
+TextField_as::getDrawBorder() const
+{
+    return _drawBorder;
+}
+
+void
+TextField_as::setDrawBorder(bool val) 
+{
+    if ( _drawBorder != val )
+    {
+        set_invalidated();
+        _drawBorder = val;
+    }
+}
+
+rgba
+TextField_as::getBorderColor() const
+{
+    return _borderColor;
+}
+
+void
+TextField_as::setBorderColor(const rgba& col)
+{
+    if ( _borderColor != col )
+    {
+        set_invalidated();
+        _borderColor = col;
+    }
+}
+
+bool
+TextField_as::getDrawBackground() const
+{
+    return _drawBackground;
+}
+
+void
+TextField_as::setDrawBackground(bool val) 
+{
+    if ( _drawBackground != val )
+    {
+        set_invalidated();
+        _drawBackground = val;
+    }
+}
+
+rgba
+TextField_as::getBackgroundColor() const
+{
+    return _backgroundColor;
+}
+
+void
+TextField_as::setBackgroundColor(const rgba& col)
+{
+    if ( _backgroundColor != col )
+    {
+        set_invalidated();
+        _backgroundColor = col;
+    }
+}
+
+void
+TextField_as::setTextColor(const rgba& col)
+{
+    if (_textColor != col) {
+
+        set_invalidated();
+        _textColor = col;
+        std::for_each(_textRecords.begin(), _textRecords.end(),
+                boost::bind(&SWF::TextRecord::setColor, _1, _textColor));
+    }
+}
+
+void
+TextField_as::setEmbedFonts(bool use)
+{
+    if ( _embedFonts != use )
+    {
+        set_invalidated();
+        _embedFonts=use;
+        format_text();
+    }
+}
+
+void
+TextField_as::setWordWrap(bool on)
+{
+    if ( _wordWrap != on )
+    {
+        set_invalidated();
+        _wordWrap=on;
+        format_text();
+    }
+}
+
+cxform    
+TextField_as::get_world_cxform() const
+{
+    // This is not automatically tested. See testsuite/samples/input-fields.swf
+    // for a manual check.
+
+    // If using a device font (PP compatibility), do not take parent cxform
+    // into account.
+    if (!getEmbedFonts()) return cxform();
+
+    return DisplayObject::get_world_cxform();
+}
+
+void
+TextField_as::setLeading(boost::uint16_t h)
+{
+    if ( _leading != h )
+    {
+        set_invalidated();
+        _leading = h;
+        format_text();
+    }
+}
+
+void
+TextField_as::setUnderlined(bool v)
+{
+    if ( _underlined != v )
+    {
+        set_invalidated();
+        _underlined = v;
+        format_text();
+    }
+}
+
+void
+TextField_as::setAlignment(TextAlignment h)
+{
+    if ( _alignment != h )
+    {
+        set_invalidated();
+        _alignment = h;
+        format_text();
+    }
+}
+
+void
+TextField_as::setIndent(boost::uint16_t h)
+{
+    if ( _indent != h )
+    {
+        set_invalidated();
+        _indent = h;
+        format_text();
+    }
+}
+
+void
+TextField_as::setBlockIndent(boost::uint16_t h)
+{
+    if ( _blockIndent != h )
+    {
+        set_invalidated();
+        _blockIndent = h;
+        format_text();
+    }
+}
+
+void
+TextField_as::setRightMargin(boost::uint16_t h)
+{
+    if ( _rightMargin != h )
+    {
+        set_invalidated();
+        _rightMargin = h;
+        format_text();
+    }
+}
+
+void
+TextField_as::setLeftMargin(boost::uint16_t h)
+{
+    if (_leftMargin != h)
+    {
+        set_invalidated();
+        _leftMargin = h;
+        format_text();
+    }
+}
+
+void
+TextField_as::setFontHeight(boost::uint16_t h)
+{
+    if ( _fontHeight != h )
+    {
+        set_invalidated();
+        _fontHeight = h;
+        format_text();
+    }
+}
+
+TextField_as::AutoSizeValue
+TextField_as::parseAutoSizeValue(const std::string& val)
+{
+    StringNoCaseEqual cmp;
+
+    if ( cmp(val, "left") )
+    {
+        return autoSizeLeft;
+    }
+    if ( cmp(val, "right") )
+    {
+        return autoSizeRight;
+    }
+    if ( cmp(val, "center") )
+    {
+        return autoSizeCenter;
+    }
+    return autoSizeNone;
+
+}
+
+const char*
+TextField_as::autoSizeValueName(AutoSizeValue val)
+{
+    switch (val)
+    {
+        case autoSizeLeft:
+            return "left";
+        case autoSizeRight:
+            return "right";
+        case autoSizeCenter:
+            return "center";
+        case autoSizeNone:
+        default:
+            return "none";
+    }
+
+}
+
+TextField_as::TypeValue
+TextField_as::parseTypeValue(const std::string& val)
+{
+    StringNoCaseEqual cmp;
+
+    if (cmp(val, "input")) return typeInput;
+    if (cmp(val, "dynamic")) return typeDynamic;
+    return typeInvalid;
+
+}
+
+const char*
+TextField_as::typeValueName(TypeValue val)
+{
+    switch (val)
+    {
+        case typeInput:
+            //log_debug("typeInput returned as 'input'");
+            return "input";
+        case typeDynamic:
+            //log_debug("typeDynamic returned as 'dynamic'");
+            return "dynamic";
+        default:
+            //log_debug("invalid type %d returned as 'invalid'", (int)val);
+            return "invalid";
+    }
+
+}
+
+void
+TextField_as::setAutoSize(AutoSizeValue val)
+{
+    if ( val == _autoSize ) return;
+
+    set_invalidated();
+
+    _autoSize = val; 
+    format_text();
+}
+
+TextField_as::TextAlignment
+TextField_as::getTextAlignment()
+{
+    TextAlignment textAlignment = getAlignment(); 
+    if ( _autoSize == autoSizeCenter ) textAlignment = ALIGN_CENTER;
+    else if ( _autoSize == autoSizeLeft ) textAlignment = ALIGN_LEFT;
+    else if ( _autoSize == autoSizeRight ) textAlignment = ALIGN_RIGHT;
+    return textAlignment;
+}
+
+void
+TextField_as::onChanged()
+{
+    as_value met(PROPNAME("onChanged"));
+    as_value targetVal(this);
+    callMethod(NSV::PROP_BROADCAST_MESSAGE, met, targetVal);
+}
+
+/// This is called by movie_root when focus is applied to this TextField_as.
+//
+/// The return value is true if the TextField can recieve focus.
+bool
+TextField_as::handleFocus()
+{
+
+    set_invalidated();
+
+    /// Select the entire text on focus.
+    setSelection(0, _text.length());
+
+    m_has_focus = true;
+
+    // why should we add to the key listener list every time
+    // we call setFocus()???
+    _vm.getRoot().add_key_listener(this);
+
+    m_cursor = _text.size();
+    format_text();
+    return true;
+}
+
+/// This is called by movie_root when focus is removed from the
+/// current TextField.
+void
+TextField_as::killFocus()
+{
+    if ( ! m_has_focus ) return; // nothing to do
+
+    set_invalidated();
+    m_has_focus = false;
+
+    movie_root& root = _vm.getRoot();
+    root.remove_key_listener(this);
+    format_text(); // is this needed ?
+
+}
+
+void
+TextField_as::markReachableResources() const
+{
+
+    if (_tag) _tag->setReachable();
+
+    if (_font) _font->setReachable();
+
+    // recurse to parent...
+    markDisplayObjectReachable();
+}
+
+/// TextField interface functions
+
 namespace {
 
 void
+attachTextFieldStaticMembers(as_object& o)
+{
+    // Standard flags.
+    const int flags = as_prop_flags::dontDelete
+        |as_prop_flags::dontEnum;
+
+    // SWF6 or higher
+    const int swf6Flags = flags | as_prop_flags::onlySWF6Up;
+
+    o.init_member("getFontList",
+            new builtin_function(textfield_getFontList), swf6Flags);
+
+}
+
+void
+attachPrototypeProperties(as_object& o)
+{
+    // Standard flags.
+    const int flags = as_prop_flags::dontDelete
+        |as_prop_flags::dontEnum;
+
+    // SWF6 or higher
+    const int swf6Flags = flags | as_prop_flags::onlySWF6Up;
+
+    boost::intrusive_ptr<builtin_function> getset;
+
+    // The following properties should only be attached to the prototype
+    // on first textfield creation.
+    o.init_property(NSV::PROP_TEXT_WIDTH,
+            textfield_textWidth, textfield_textWidth);
+    o.init_property(NSV::PROP_TEXT_HEIGHT,
+            textfield_textHeight, textfield_textHeight);
+
+    getset = new builtin_function(textfield_variable);
+    o.init_property("variable", *getset, *getset, swf6Flags);
+    getset = new builtin_function(textfield_background);
+    o.init_property("background", *getset, *getset, swf6Flags);
+    getset = new builtin_function(textfield_text);
+    o.init_property("text", *getset, *getset, swf6Flags);
+    getset = new builtin_function(textfield_backgroundColor);
+    o.init_property("backgroundColor", *getset, *getset, swf6Flags);
+    getset = new builtin_function(textfield_border);
+    o.init_property("border", *getset, *getset, swf6Flags);
+    getset = new builtin_function(textfield_borderColor);
+    o.init_property("borderColor", *getset, *getset, swf6Flags);
+    getset = new builtin_function(textfield_textColor);
+    o.init_property("textColor", *getset, *getset, swf6Flags);
+    getset = new builtin_function(textfield_embedFonts);
+    o.init_property("embedFonts", *getset, *getset, swf6Flags);
+    getset = new builtin_function(textfield_autoSize);
+    o.init_property("autoSize", *getset, *getset, swf6Flags);
+    getset = new builtin_function(textfield_type);
+    o.init_property("type", *getset, *getset, swf6Flags);
+    getset = new builtin_function(textfield_wordWrap);
+    o.init_property("wordWrap", *getset, *getset, swf6Flags);
+    getset = new builtin_function(textfield_html);
+    o.init_property("html", *getset, *getset, swf6Flags);
+    getset = new builtin_function(textfield_selectable);
+    o.init_property("selectable", *getset, *getset, swf6Flags);
+    getset = new builtin_function(textfield_length);
+    o.init_property("length", *getset, *getset, swf6Flags);
+    getset = new builtin_function(textfield_maxscroll);
+    o.init_property("maxscroll", *getset, *getset, swf6Flags);
+    getset = new builtin_function(textfield_maxhscroll);
+    o.init_property("maxhscroll", *getset, *getset, swf6Flags);
+    getset = new builtin_function(textfield_maxChars);
+    o.init_property("maxChars", *getset, *getset, swf6Flags);
+    getset = new builtin_function(textfield_bottomScroll);
+    o.init_property("bottomScroll", *getset, *getset, swf6Flags);
+    getset = new builtin_function(textfield_scroll);
+    o.init_property("scroll", *getset, *getset, swf6Flags);
+    getset = new builtin_function(textfield_hscroll);
+    o.init_property("hscroll", *getset, *getset, swf6Flags);
+    getset = new builtin_function(textfield_restrict);
+    o.init_property("restrict", *getset, *getset, swf6Flags);
+    getset = new builtin_function(textfield_multiline);
+    o.init_property("multiline", *getset, *getset, swf6Flags);
+    getset = new builtin_function(textfield_password);
+    o.init_property("password", *getset, *getset, swf6Flags);
+    getset = new builtin_function(textfield_htmlText);
+    o.init_property("htmlText", *getset, *getset, swf6Flags);
+}
+
+
+as_value
+textfield_background(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextField_as> ptr = 
ensureType<TextField_as>(fn.this_ptr);
+
+    if (fn.nargs == 0) {
+        return as_value(ptr->getDrawBackground());
+    }
+    else {
+        ptr->setDrawBackground(fn.arg(0).to_bool());
+    }
+
+    return as_value();
+}
+
+as_value
+textfield_border(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextField_as> ptr = 
ensureType<TextField_as>(fn.this_ptr);
+
+    if (fn.nargs == 0) {
+        return as_value(ptr->getDrawBorder());
+    }
+    else {
+        ptr->setDrawBorder(fn.arg(0).to_bool());
+    }
+
+    return as_value();
+}
+
+as_value
+textfield_backgroundColor(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextField_as> ptr = 
ensureType<TextField_as>(fn.this_ptr);
+
+    if (fn.nargs == 0) {
+        return as_value(ptr->getBackgroundColor().toRGB());
+    }
+    else {
+        rgba newColor;
+        newColor.parseRGB(static_cast<boost::uint32_t>(fn.arg(0).to_int()));
+        ptr->setBackgroundColor(newColor);
+    }
+
+    return as_value();
+}
+
+as_value
+textfield_borderColor(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextField_as> ptr = 
ensureType<TextField_as>(fn.this_ptr);
+
+    if (fn.nargs == 0) {
+        return as_value(ptr->getBorderColor().toRGB());
+    }
+    else {
+        rgba newColor;
+        newColor.parseRGB(static_cast<boost::uint32_t>(fn.arg(0).to_number()));
+        ptr->setBorderColor(newColor);
+    }
+
+    return as_value();
+}
+
+    
+as_value
+textfield_textColor(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextField_as> ptr = 
ensureType<TextField_as>(fn.this_ptr);
+
+    if (!fn.nargs) {
+        // Getter
+        return as_value(ptr->getTextColor().toRGB());
+    }
+
+    // Setter
+    rgba newColor;
+    newColor.parseRGB(static_cast<boost::uint32_t>(fn.arg(0).to_number()));
+    ptr->setTextColor(newColor);
+
+    return as_value();
+}
+
+as_value
+textfield_embedFonts(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextField_as> ptr = 
ensureType<TextField_as>(fn.this_ptr);
+
+    if (!fn.nargs) {
+        // Getter
+        return as_value(ptr->getEmbedFonts());
+    }
+
+    // Setter
+    ptr->setEmbedFonts(fn.arg(0).to_bool());
+    return as_value();
+}
+
+as_value
+textfield_wordWrap(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextField_as> ptr = 
ensureType<TextField_as>(fn.this_ptr);
+
+    if (fn.nargs == 0) {
+        return as_value(ptr->doWordWrap());
+    }
+    else {
+        ptr->setWordWrap(fn.arg(0).to_bool());
+    }
+
+    return as_value();
+}
+
+as_value
+textfield_html(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextField_as> ptr = 
ensureType<TextField_as>(fn.this_ptr);
+
+    if (fn.nargs == 0) {
+        return as_value(ptr->doHtml());
+    }
+    else {
+        ptr->setHtml( fn.arg(0).to_bool() );
+    }
+
+    return as_value();
+}
+
+as_value
+textfield_selectable(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextField_as> ptr = 
ensureType<TextField_as>(fn.this_ptr);
+
+    if ( fn.nargs == 0 ) // getter
+    {
+        return as_value(ptr->isSelectable());
+    }
+    else // setter
+    {
+        ptr->setSelectable( fn.arg(0).to_bool() );
+    }
+
+    return as_value();
+}
+
+as_value
+textfield_length(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextField_as> ptr = 
ensureType<TextField_as>(fn.this_ptr);
+
+    if ( fn.nargs == 0 ) // getter
+    {
+        const std::string& s = ptr->get_text_value();
+        return as_value(s.length()); // TOCHECK: utf-8 ?
+    }
+    else // setter
+    {
+        IF_VERBOSE_ASCODING_ERRORS(
+        log_aserror(_("Attempt to set length property of TextField %s"),
+            ptr->getTarget());
+        );
+    }
+
+    return as_value();
+}
+
+as_value
+textfield_textHeight(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextField_as> ptr = 
ensureType<TextField_as>(fn.this_ptr);
+
+    if ( fn.nargs == 0 ) // getter
+    {
+        // Return the height, in pixels, of the text as laid out.
+        // (I.e. the actual text content, not our defined
+        // bounding box.)
+        //
+        // In local coords.  Verified against Macromedia Flash.
+        return as_value(twipsToPixels(ptr->getTextBoundingBox().height()));
+
+    }
+    else // setter
+    {
+        IF_VERBOSE_ASCODING_ERRORS(
+        log_aserror(_("Attempt to set read-only %s property of TextField "
+                "%s"), "textHeight", ptr->getTarget());
+        );
+    }
+
+    return as_value();
+}
+
+as_value
+textfield_textWidth(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextField_as> ptr = 
ensureType<TextField_as>(fn.this_ptr);
+
+    if ( fn.nargs == 0 ) // getter
+    {
+        // Return the width, in pixels, of the text as laid out.
+        // (I.e. the actual text content, not our defined
+        // bounding box.)
+        //
+        // In local coords.  Verified against Macromedia Flash.
+        return as_value(twipsToPixels(ptr->getTextBoundingBox().width()));
+
+    }
+    else // setter
+    {
+        IF_VERBOSE_ASCODING_ERRORS(
+        log_aserror(_("Attempt to set read-only %s property of TextField %s"),
+            "textWidth", ptr->getTarget());
+        );
+    }
+
+    return as_value();
+}
+
+as_value
+textfield_autoSize(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextField_as> ptr = 
ensureType<TextField_as>(fn.this_ptr);
+
+    if ( fn.nargs == 0 ) // getter
+    {
+        return ptr->autoSizeValueName(ptr->getAutoSize());
+    }
+    else // setter
+    {
+        const as_value& arg = fn.arg(0);
+        if ( arg.is_bool() )
+        {
+            if ( arg.to_bool() ) // true == left
+            {
+                ptr->setAutoSize( TextField_as::autoSizeLeft );
+            }
+            else
+            {
+                ptr->setAutoSize( TextField_as::autoSizeNone );
+            }
+        }
+        else
+        {
+            std::string strval = arg.to_string();
+            TextField_as::AutoSizeValue val = ptr->parseAutoSizeValue(strval);
+            ptr->setAutoSize( val );
+        }
+    }
+
+    return as_value();
+}
+
+as_value
+textfield_type(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextField_as> ptr = 
ensureType<TextField_as>(fn.this_ptr);
+
+    if (!fn.nargs)
+    {
+        // getter
+        return ptr->typeValueName(ptr->getType());
+    }
+
+    // setter
+    const as_value& arg = fn.arg(0);
+    std::string strval = arg.to_string();
+    TextField_as::TypeValue val = ptr->parseTypeValue(strval);
+
+    IF_VERBOSE_ASCODING_ERRORS(
+        if ( val == TextField_as::typeInvalid )
+        {
+            log_aserror(_("Invalid value given to TextField.type: %s"), 
strval);
+        }
+    );
+    ptr->setType(val);
+    return as_value();
+}
+
+as_value
+textfield_variable(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextField_as> text = 
ensureType<TextField_as>(fn.this_ptr);
+
+    if (!fn.nargs)
+    {
+        // Getter
+        const std::string& varName = text->getVariableName();
+        // An empty variable name returns null.
+        if (varName.empty()) {
+            as_value null;
+            null.set_null();
+            return null;
+        }
+        return as_value(varName);
+    }
+
+    // Setter
+    const as_value& varName = fn.arg(0);
+    if (varName.is_undefined() || varName.is_null()) {
+        text->set_variable_name("");
+    }
+    else text->set_variable_name(varName.to_string());
+
+    return as_value();
+
+}
+
+
+as_value
+textfield_getDepth(const fn_call& fn)
+{
+    // TODO: make this a DisplayObject::getDepth_method function...
+    boost::intrusive_ptr<TextField_as> text = 
ensureType<TextField_as>(fn.this_ptr);
+
+    int n = text->get_depth();
+
+    return as_value(n);
+
+}
+
+as_value
+textfield_getFontList(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextField_as> text = 
ensureType<TextField_as>(fn.this_ptr);
+    UNUSED(text);
+
+    LOG_ONCE(log_unimpl("TextField.getFontList()"));
+
+    return as_value();
+}
+
+as_value
+textfield_getNewTextFormat(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextField_as> text = 
ensureType<TextField_as>(fn.this_ptr);
+    UNUSED(text);
+
+    LOG_ONCE(log_unimpl("TextField.getNewTextFormat()"));
+
+    return as_value();
+}
+
+as_value
+textfield_setNewTextFormat(const fn_call& fn)
+{
+    //boost::intrusive_ptr<TextField> text = 
ensureType<TextField>(fn.this_ptr);
+    //UNUSED(text);
+
+    LOG_ONCE( log_unimpl("TextField.setNewTextFormat(), we'll delegate "
+                "to setTextFormat") );
+    return textfield_setTextFormat(fn);
+
+    //return as_value();
+}
+
+as_value
+textfield_password(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextField_as> text = 
ensureType<TextField_as>(fn.this_ptr);
+
+    LOG_ONCE(log_unimpl("TextField.password"));
+
+    if (!fn.nargs)
+    {
+        // Getter
+        return as_value(text->password());
+    }
+    // Setter
+    text->password(fn.arg(0).to_bool());
+    return as_value();
+}
+
+as_value
+textfield_multiline(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextField_as> text = 
ensureType<TextField_as>(fn.this_ptr);
+
+    LOG_ONCE(log_unimpl("TextField.multiline"));
+
+    if (!fn.nargs) {
+        // Getter
+        return as_value(text->multiline());
+    }
+    // Setter
+    text->multiline(fn.arg(0).to_bool());
+    return as_value();
+}
+
+as_value
+textfield_restrict(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextField_as> text = 
ensureType<TextField_as>(fn.this_ptr);
+    UNUSED(text);
+
+    LOG_ONCE (log_unimpl("TextField.restrict"));
+
+    return as_value();
+}
+
+as_value
+textfield_bottomScroll(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextField_as> text = 
ensureType<TextField_as>(fn.this_ptr);
+    UNUSED(text);
+
+    LOG_ONCE (log_unimpl("TextField.bottomScroll"));
+
+    return as_value();
+}
+
+as_value
+textfield_bottomScrollV(const fn_call& fn)
+{
+//TODO: AS3 Method
+    boost::intrusive_ptr<TextField_as> text = 
ensureType<TextField_as>(fn.this_ptr);
+    UNUSED(text);
+
+    LOG_ONCE (log_unimpl("TextField.bottomScroll"));
+
+    return as_value();
+}
+
+as_value
+textfield_maxhscroll(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextField_as> text = 
ensureType<TextField_as>(fn.this_ptr);
+    UNUSED(text);
+
+    LOG_ONCE (log_unimpl("TextField.maxhscroll"));
+
+    return as_value();
+}
+
+/// TextField.maxChars().
+//
+/// This does not limit the length of the text, but rather the
+/// number of DisplayObjects that can be entered in the TextField.
+//
+/// Returns null when the value is 0.
+as_value
+textfield_maxChars(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextField_as> text = 
ensureType<TextField_as>(fn.this_ptr);
+
+    LOG_ONCE(log_unimpl("TextField.maxChars"));
+
+    if (!fn.nargs)
+    {
+        boost::int32_t maxChars = text->maxChars();
+        if (maxChars == 0)
+        {
+            as_value null;
+            null.set_null();
+            return null;
+        }
+        return as_value(maxChars);
+    }
+    // Setter
+    text->maxChars(fn.arg(0).to_int());
+    return as_value();
+}
+
+as_value
+textfield_text(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextField_as> ptr = 
ensureType<TextField_as>(fn.this_ptr);
+    if (!fn.nargs)
+    {
+        // Getter
+        //
+        // FIXME: should return text without HTML tags.
+        return as_value(ptr->get_text_value());
+    }
+
+    // Setter
+    int version = ptr->getVM().getSWFVersion();
+    ptr->setTextValue(
+            utf8::decodeCanonicalString(fn.arg(0).to_string(), version));
+
+    return as_value();
+}
+
+as_value
+textfield_htmlText(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextField_as> ptr = 
ensureType<TextField_as>(fn.this_ptr);
+    if (!fn.nargs)
+    {
+        // Getter
+        return as_value(ptr->get_text_value());
+    }
+
+    // Setter
+    int version = ptr->getVM().getSWFVersion();
+    ptr->setTextValue(
+            utf8::decodeCanonicalString(fn.arg(0).to_string(), version));
+
+    return as_value();
+}
+
+/// TextField.replaceSel(newText)
+//
+/// Replaces the current selection with the new text, setting both
+/// begin and end of the selection to one after the inserted text.
+/// If an empty string is passed, SWF8 erases the selection; SWF7 and below
+/// is a no-op.
+/// If no argument is passed, this is a no-op.
+as_value
+textfield_replaceSel(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextField_as> text = 
ensureType<TextField_as>(fn.this_ptr);
+
+    if (!fn.nargs) {
+        IF_VERBOSE_ASCODING_ERRORS(
+            std::ostringstream os;
+            fn.dump_args(os);
+            log_aserror("TextField.replaceSel(%s) requires exactly one "
+                "argument", os.str());
+        );
+        return as_value();
+    }
+
+    const std::string& replace = fn.arg(0).to_string();
+
+    /// Do nothing if text is empty and version less than 8.
+    const int version = text->getVM().getSWFVersion();
+    if (version < 8 && replace.empty()) return as_value();
+
+    text->replaceSelection(replace);
+
+    return as_value();
+}
+
+as_value
+textfield_scroll(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextField_as> text = 
ensureType<TextField_as>(fn.this_ptr);
+    UNUSED(text);
+
+    LOG_ONCE (log_unimpl("TextField.scroll()"));
+
+    return as_value();
+}
+
+as_value
+textfield_hscroll(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextField_as> text = 
ensureType<TextField_as>(fn.this_ptr);
+    UNUSED(text);
+
+    LOG_ONCE (log_unimpl("TextField.hscroll()"));
+
+    return as_value();
+}
+
+as_value
+textfield_maxscroll(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextField_as> text = 
ensureType<TextField_as>(fn.this_ptr);
+    UNUSED(text);
+
+    LOG_ONCE (log_unimpl("TextField.maxscroll"));
+
+    return as_value();
+}
+
+as_value
+textfield_getCharBoundaries(const fn_call& fn)
+{
+//TODO: AS3 method
+//    boost::intrusive_ptr<TextField_as> ptr =
+//        ensureType<TextField_as>(fn.this_ptr);
+//    UNUSED(ptr);
+//    log_unimpl (__FUNCTION__);
+    return as_value();
+}
+
+as_value
+textfield_antiAliasType(const fn_call& fn)
+{
+//TODO: AS3 method
+//    boost::intrusive_ptr<TextField_as> ptr =
+//        ensureType<TextField_as>(fn.this_ptr);
+//    UNUSED(ptr);
+//    log_unimpl (__FUNCTION__);
+    return as_value();
+}
+
+as_value
+textfield_sharpness(const fn_call& fn)
+{
+//TODO: AS3 method
+//    boost::intrusive_ptr<TextField_as> ptr =
+//        ensureType<TextField_as>(fn.this_ptr);
+//    UNUSED(ptr);
+//    log_unimpl (__FUNCTION__);
+    return as_value();
+}
+
+as_value
+textfield_gridFitType(const fn_call& fn)
+{
+//TODO: AS3 method
+//    boost::intrusive_ptr<TextField_as> ptr =
+//        ensureType<TextField_as>(fn.this_ptr);
+//    UNUSED(ptr);
+//    log_unimpl (__FUNCTION__);
+    return as_value();
+}
+
+as_value
+textfield_condenseWhite(const fn_call& fn)
+{
+//TODO:
+//    boost::intrusive_ptr<TextField_as> ptr =
+//        ensureType<TextField_as>(fn.this_ptr);
+//    UNUSED(ptr);
+//    log_unimpl (__FUNCTION__);
+    return as_value();
+}
+
+as_value
+textfield_getCharIndexAtPoint(const fn_call& fn)
+{
+//TODO: AS3 method
+//    boost::intrusive_ptr<TextField_as> ptr =
+//        ensureType<TextField_as>(fn.this_ptr);
+//    UNUSED(ptr);
+//    log_unimpl (__FUNCTION__);
+    return as_value();
+}
+
+as_value
+textfield_getFirstCharInParagraph(const fn_call& fn)
+{
+//TODO: AS3 method
+//    boost::intrusive_ptr<TextField_as> ptr =
+//        ensureType<TextField_as>(fn.this_ptr);
+//    UNUSED(ptr);
+//    log_unimpl (__FUNCTION__);
+    return as_value();
+}
+
+as_value
+textfield_getImageReference(const fn_call& fn)
+{
+//TODO: AS3 method
+//    boost::intrusive_ptr<TextField_as> ptr =
+//        ensureType<TextField_as>(fn.this_ptr);
+//    UNUSED(ptr);
+//    log_unimpl (__FUNCTION__);
+    return as_value();
+}
+
+as_value
+textfield_getLineIndexAtPoint(const fn_call& fn)
+{
+//TODO: AS3 method
+//    boost::intrusive_ptr<TextField_as> ptr =
+//        ensureType<TextField_as>(fn.this_ptr);
+//    UNUSED(ptr);
+//    log_unimpl (__FUNCTION__);
+    return as_value();
+}
+
+as_value
+textfield_getLineIndexOfChar(const fn_call& fn)
+{
+//TODO: AS3 method
+//    boost::intrusive_ptr<TextField_as> ptr =
+//        ensureType<TextField_as>(fn.this_ptr);
+//    UNUSED(ptr);
+//    log_unimpl (__FUNCTION__);
+    return as_value();
+}
+
+as_value
+textfield_getLineLength(const fn_call& fn)
+{
+//TODO: AS3 method
+//    boost::intrusive_ptr<TextField_as> ptr =
+//        ensureType<TextField_as>(fn.this_ptr);
+//    UNUSED(ptr);
+//    log_unimpl (__FUNCTION__);
+    return as_value();
+}
+
+as_value
+textfield_getLineMetrics(const fn_call& fn)
+{
+//TODO: AS3 method
+//    boost::intrusive_ptr<TextField_as> ptr =
+//        ensureType<TextField_as>(fn.this_ptr);
+//    UNUSED(ptr);
+//    log_unimpl (__FUNCTION__);
+    return as_value();
+}
+
+as_value
+textfield_getLineOffset(const fn_call& fn)
+{
+//TODO: AS3 method
+//    boost::intrusive_ptr<TextField_as> ptr =
+//        ensureType<TextField_as>(fn.this_ptr);
+//    UNUSED(ptr);
+//    log_unimpl (__FUNCTION__);
+    return as_value();
+}
+
+as_value
+textfield_getLineText(const fn_call& fn)
+{
+//TODO: AS3 method
+//    boost::intrusive_ptr<TextField_as> ptr =
+//        ensureType<TextField_as>(fn.this_ptr);
+//    UNUSED(ptr);
+//    log_unimpl (__FUNCTION__);
+    return as_value();
+}
+
+as_value
+textfield_mouseWheelEnabled(const fn_call& fn)
+{
+//TODO:
+//    boost::intrusive_ptr<TextField_as> ptr =
+//        ensureType<TextField_as>(fn.this_ptr);
+//    UNUSED(ptr);
+//    log_unimpl (__FUNCTION__);
+    return as_value();
+}
+
+as_value
+textfield_styleSheet(const fn_call& fn)
+{
+//TODO:
+//    boost::intrusive_ptr<TextField_as> ptr =
+//        ensureType<TextField_as>(fn.this_ptr);
+//    UNUSED(ptr);
+//    log_unimpl (__FUNCTION__);
+    return as_value();
+}
+
+as_value
+textfield_getParagraphLength(const fn_call& fn)
+{
+//TODO: AS3 method
+//    boost::intrusive_ptr<TextField_as> ptr =
+//        ensureType<TextField_as>(fn.this_ptr);
+//    UNUSED(ptr);
+//    log_unimpl (__FUNCTION__);
+    return as_value();
+}
+
+as_value
+textfield_getTextFormat(const fn_call& fn)
+{
+        boost::intrusive_ptr<TextField_as> text = 
ensureType<TextField_as>(fn.this_ptr);
+
+    boost::intrusive_ptr<TextFormat_as> tf = new TextFormat_as;
+    tf->alignSet(text->getTextAlignment());
+    tf->sizeSet(text->getFontHeight());
+    tf->indentSet(text->getIndent());
+    tf->blockIndentSet(text->getBlockIndent());
+    tf->leadingSet(text->getLeading());
+    tf->leftMarginSet(text->getLeftMargin());
+    tf->rightMarginSet(text->getRightMargin());
+    tf->colorSet(text->getTextColor());
+    tf->underlinedSet(text->getUnderlined());
+
+    const Font* font = text->getFont();
+    if (font)
+    {
+        tf->fontSet(font->name());
+        tf->italicedSet(font->isItalic());
+        tf->boldSet(font->isBold());
+    }
+
+    // TODO: add font color and some more
+
+    LOG_ONCE(
+        log_unimpl("TextField.getTextFormat() discards url, target, "
+            "tabStops, bullet and display")
+    );
+
+    return as_value(tf.get());
+}
+
+as_value
+textfield_replaceSelectedText(const fn_call& fn)
+{
+//TODO: AS3 method
+//    boost::intrusive_ptr<TextField_as> ptr =
+//        ensureType<TextField_as>(fn.this_ptr);
+//    UNUSED(ptr);
+//    log_unimpl (__FUNCTION__);
+    return as_value();
+}
+
+as_value
+textfield_replaceText(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextField_as> text = 
ensureType<TextField_as>(fn.this_ptr);
+    UNUSED(text);
+
+    LOG_ONCE(log_unimpl("TextField.replaceText()"));
+
+    return as_value();
+}
+
+as_value
+textfield_removeTextField(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextField_as> text = 
ensureType<TextField_as>(fn.this_ptr);
+
+    text->removeTextField();
+
+    LOG_ONCE(log_debug("TextField.removeTextField() TESTING"));
+
+    return as_value();
+}
+
+as_value
+textfield_setSelection(const fn_call& fn)
+{
+//TODO: AS3 method
+//    boost::intrusive_ptr<TextField_as> ptr =
+//        ensureType<TextField_as>(fn.this_ptr);
+//    UNUSED(ptr);
+//    log_unimpl (__FUNCTION__);
+    return as_value();
+}
+
+as_value
+textfield_setTextFormat(const fn_call& fn)
+{
+    boost::intrusive_ptr<TextField_as> text = 
ensureType<TextField_as>(fn.this_ptr);
+
+    if ( ! fn.nargs )
+    {
+        IF_VERBOSE_ASCODING_ERRORS(
+        std::stringstream ss; fn.dump_args(ss);
+        log_aserror("TextField.setTextFormat(%s) : %s", ss.str(),
+            _("missing arg"))
+        );
+        return as_value();
+    }
+    else if ( fn.nargs > 2 )
+    {
+        std::stringstream ss; fn.dump_args(ss);
+        log_debug("TextField.setTextFormat(%s) : args past the first are "
+                "unhandled by Gnash", ss.str());
+    }
+
+    as_object* obj = fn.arg(0).to_object().get();
+    if ( ! obj )
+    {
+        IF_VERBOSE_ASCODING_ERRORS(
+        std::stringstream ss; fn.dump_args(ss);
+        log_aserror("TextField.setTextFormat(%s) : %s", ss.str(), 
+            _("first argument is not an object"))
+        );
+        return as_value();
+    }
+
+    TextFormat_as* tf = dynamic_cast<TextFormat_as*>(obj);
+    if ( ! tf )
+    {
+        IF_VERBOSE_ASCODING_ERRORS(
+        std::stringstream ss; fn.dump_args(ss);
+        log_aserror("TextField.setTextFormat(%s) : %s", ss.str(),
+            _("first argument is not a TextFormat"))
+        );
+        return as_value();
+    }
+
+    if ( tf->alignDefined() ) text->setAlignment(tf->align());
+    if ( tf->sizeDefined() ) text->setFontHeight(tf->size()); // keep twips
+    if ( tf->indentDefined() ) text->setIndent(tf->indent());
+    if ( tf->blockIndentDefined() ) text->setBlockIndent(tf->blockIndent());
+    if ( tf->leadingDefined() ) text->setLeading(tf->leading());
+    if ( tf->leftMarginDefined() ) text->setLeftMargin(tf->leftMargin());
+    if ( tf->rightMarginDefined() ) text->setRightMargin(tf->rightMargin());
+    if ( tf->colorDefined() ) text->setTextColor(tf->color());
+    if ( tf->underlinedDefined() ) text->setUnderlined(tf->underlined());
+
+    if ( tf->fontDefined() )
+    {
+        const std::string& fontName = tf->font();
+        if ( ! fontName.empty() )
+        {
+            bool bold = tf->bold();
+            bool italic = tf->italiced();
+
+            // NOTE: should query movie-private font lib, not global-shared one
+            Movie* mi = text->get_root();
+            assert(mi);
+            const movie_definition* md = mi->definition();
+            assert(md);
+            Font* f = md->get_font(fontName, bold, italic);
+            if ( ! f ) f = fontlib::get_font(fontName, bold, italic);
+            text->setFont( f );
+        }
+    }
+
+    // TODO: add font color and some more
+
+    LOG_ONCE( log_unimpl("TextField.setTextFormat() discards url, target, "
+                "tabStops, bullet and display") );
+
+    return as_value();
+}
+
+as_value
+textfield_change(const fn_call& fn)
+{
+//FIXME: This is an AS3 event.
+//    boost::intrusive_ptr<TextField_as> ptr =
+//        ensureType<TextField_as>(fn.this_ptr);
+//    UNUSED(ptr);
+//    log_unimpl (__FUNCTION__);
+    return as_value();
+}
+
+as_value
+textfield_link(const fn_call& fn)
+{
+//FIXME: This is an AS3 event
+//    boost::intrusive_ptr<TextField_as> ptr =
+//        ensureType<TextField_as>(fn.this_ptr);
+//    UNUSED(ptr);
+//    log_unimpl (__FUNCTION__);
+    return as_value();
+}
+
+as_value
+textfield_textInput(const fn_call& fn)
+{
+//FIXME: This is an AS3 event
+//    boost::intrusive_ptr<TextField_as> ptr =
+//        ensureType<TextField_as>(fn.this_ptr);
+//    UNUSED(ptr);
+//    log_unimpl (__FUNCTION__);
+    return as_value();
+}
+
+as_value
+textfield_ctor(const fn_call& fn)
+{
+    VM& vm = fn.getVM();
+
+    as_object* proto = getTextFieldInterface(vm);
+
+    as_object* obj = 0;
+
+    if ( vm.getSWFVersion() < 9 )
+    {
+        // We should attach more properties to the prototype on first
+        // instantiation.
+        // TODO: this also attaches properties to the SWF5 prototype but makes
+        // them invisible with prop flags. Is this correct?
+        attachPrototypeProperties(*proto);
+
+        obj = new as_object(proto);
+    }
+    else
+    {
+        rect nullRect;
+        obj = new TextField_as(0, nullRect);
+    }
+
+    return as_value(obj);
+}
+
+void
 attachTextFieldInterface(as_object& o)
 {
     o.init_member("getCharBoundaries", new 
builtin_function(textfield_getCharBoundaries));
@@ -118,222 +3003,26 @@
 }
 
 as_object*
-getTextFieldInterface()
+getTextFieldInterface(VM& vm)
 {
-    static boost::intrusive_ptr<as_object> o;
-    if ( ! o ) {
-        o = new as_object();
-        attachTextFieldInterface(*o);
+    static boost::intrusive_ptr<as_object> proto;
+
+    if ( proto == NULL )
+    {
+        if (vm.getSWFVersion() < 6) {
+            /// The prototype for SWF5 is a simple as_object without
+            /// toString() or valueOf().
+            proto = new as_object();
+            vm.addStatic(proto.get());
+        }
+        else {
+            proto = new as_object(getObjectInterface());
+            vm.addStatic(proto.get());
+            attachTextFieldInterface(*proto);
+        }
+
     }
-    return o.get();
-}
-
-as_value
-textfield_getCharBoundaries(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField_as> ptr =
-        ensureType<TextField_as>(fn.this_ptr);
-    UNUSED(ptr);
-    log_unimpl (__FUNCTION__);
-    return as_value();
-}
-
-as_value
-textfield_getCharIndexAtPoint(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField_as> ptr =
-        ensureType<TextField_as>(fn.this_ptr);
-    UNUSED(ptr);
-    log_unimpl (__FUNCTION__);
-    return as_value();
-}
-
-as_value
-textfield_getFirstCharInParagraph(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField_as> ptr =
-        ensureType<TextField_as>(fn.this_ptr);
-    UNUSED(ptr);
-    log_unimpl (__FUNCTION__);
-    return as_value();
-}
-
-as_value
-textfield_getImageReference(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField_as> ptr =
-        ensureType<TextField_as>(fn.this_ptr);
-    UNUSED(ptr);
-    log_unimpl (__FUNCTION__);
-    return as_value();
-}
-
-as_value
-textfield_getLineIndexAtPoint(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField_as> ptr =
-        ensureType<TextField_as>(fn.this_ptr);
-    UNUSED(ptr);
-    log_unimpl (__FUNCTION__);
-    return as_value();
-}
-
-as_value
-textfield_getLineIndexOfChar(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField_as> ptr =
-        ensureType<TextField_as>(fn.this_ptr);
-    UNUSED(ptr);
-    log_unimpl (__FUNCTION__);
-    return as_value();
-}
-
-as_value
-textfield_getLineLength(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField_as> ptr =
-        ensureType<TextField_as>(fn.this_ptr);
-    UNUSED(ptr);
-    log_unimpl (__FUNCTION__);
-    return as_value();
-}
-
-as_value
-textfield_getLineMetrics(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField_as> ptr =
-        ensureType<TextField_as>(fn.this_ptr);
-    UNUSED(ptr);
-    log_unimpl (__FUNCTION__);
-    return as_value();
-}
-
-as_value
-textfield_getLineOffset(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField_as> ptr =
-        ensureType<TextField_as>(fn.this_ptr);
-    UNUSED(ptr);
-    log_unimpl (__FUNCTION__);
-    return as_value();
-}
-
-as_value
-textfield_getLineText(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField_as> ptr =
-        ensureType<TextField_as>(fn.this_ptr);
-    UNUSED(ptr);
-    log_unimpl (__FUNCTION__);
-    return as_value();
-}
-
-as_value
-textfield_getParagraphLength(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField_as> ptr =
-        ensureType<TextField_as>(fn.this_ptr);
-    UNUSED(ptr);
-    log_unimpl (__FUNCTION__);
-    return as_value();
-}
-
-as_value
-textfield_getTextFormat(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField_as> ptr =
-        ensureType<TextField_as>(fn.this_ptr);
-    UNUSED(ptr);
-    log_unimpl (__FUNCTION__);
-    return as_value();
-}
-
-as_value
-textfield_replaceSelectedText(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField_as> ptr =
-        ensureType<TextField_as>(fn.this_ptr);
-    UNUSED(ptr);
-    log_unimpl (__FUNCTION__);
-    return as_value();
-}
-
-as_value
-textfield_replaceText(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField_as> ptr =
-        ensureType<TextField_as>(fn.this_ptr);
-    UNUSED(ptr);
-    log_unimpl (__FUNCTION__);
-    return as_value();
-}
-
-as_value
-textfield_setSelection(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField_as> ptr =
-        ensureType<TextField_as>(fn.this_ptr);
-    UNUSED(ptr);
-    log_unimpl (__FUNCTION__);
-    return as_value();
-}
-
-as_value
-textfield_setTextFormat(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField_as> ptr =
-        ensureType<TextField_as>(fn.this_ptr);
-    UNUSED(ptr);
-    log_unimpl (__FUNCTION__);
-    return as_value();
-}
-
-as_value
-textfield_change(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField_as> ptr =
-        ensureType<TextField_as>(fn.this_ptr);
-    UNUSED(ptr);
-    log_unimpl (__FUNCTION__);
-    return as_value();
-}
-
-as_value
-textfield_link(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField_as> ptr =
-        ensureType<TextField_as>(fn.this_ptr);
-    UNUSED(ptr);
-    log_unimpl (__FUNCTION__);
-    return as_value();
-}
-
-as_value
-textfield_scroll(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField_as> ptr =
-        ensureType<TextField_as>(fn.this_ptr);
-    UNUSED(ptr);
-    log_unimpl (__FUNCTION__);
-    return as_value();
-}
-
-as_value
-textfield_textInput(const fn_call& fn)
-{
-    boost::intrusive_ptr<TextField_as> ptr =
-        ensureType<TextField_as>(fn.this_ptr);
-    UNUSED(ptr);
-    log_unimpl (__FUNCTION__);
-    return as_value();
-}
-
-as_value
-textfield_ctor(const fn_call& fn)
-{
-    boost::intrusive_ptr<as_object> obj = new TextField_as;
-
-    return as_value(obj.get()); // will keep alive
+    return proto.get();
 }
 
 } // anonymous namespace 

=== modified file 'libcore/asobj/flash/text/TextField_as.h'
--- a/libcore/asobj/flash/text/TextField_as.h   2009-05-28 17:29:17 +0000
+++ b/libcore/asobj/flash/text/TextField_as.h   2009-06-08 22:24:55 +0000
@@ -22,16 +22,647 @@
 
 #ifdef HAVE_CONFIG_H
 #include "gnashconfig.h"
+#include "InteractiveObject.h" // for inheritance
+#include "styles.h" // for line_style
+#include "fill_style.h"
+#include "Range2d.h"
+#include "rect.h" // for inlines
+#include "Font.h" // for visibility of font add_ref/drop_ref
 #endif
 
 
 namespace gnash {
+       namespace SWF {
+        class DefineEditTextTag;
+        class TextRecord;
+    }
 
 // Forward declarations
-class as_object;
-
-/// Initialize the global TextField class
-void textfield_class_init(as_object& global);
+class TextField_as : public InteractiveObject
+{
+
+public:
+
+    /// Text alignment values
+       enum TextAlignment
+       {
+               ALIGN_LEFT = 0,
+               ALIGN_RIGHT,
+               ALIGN_CENTER,
+               ALIGN_JUSTIFY
+       };
+
+       /// Possible autoSize values
+       enum AutoSizeValue {
+
+               /// Do not automatically resize TextField as text grow/shrink
+               autoSizeNone,
+
+               /// Expand TextField, anchor the top-left side
+               autoSizeLeft,
+
+               /// Expand TextField, anchor the horizontal center
+               autoSizeCenter,
+
+               /// Expand TextField, anchor the top-right side
+               autoSizeRight
+       };
+
+       /// Possible type values
+       enum TypeValue {
+
+               /// Invalid value
+               typeInvalid,
+
+               /// Do not accept input, text is only changed by variable name
+               /// or assigning to the .text member
+               typeDynamic,
+
+               /// Accept user input
+               typeInput
+       };
+
+    /// Constructs a TextField as specified in a DefineEditText tag.
+       TextField_as(DisplayObject* parent, const SWF::DefineEditTextTag& def, 
int id);
+
+    /// Constructs a TextField with default values and the specified bounds.
+    //
+    /// Notably, the default textHeight is 12pt (240 twips).
+    TextField_as(DisplayObject* parent, const rect& bounds);
+
+       ~TextField_as();
+
+       // TODO: should this return isSelectable() ?
+       bool mouseEnabled() const { return true; }
+
+       InteractiveObject* topmostMouseEntity(boost::int32_t x,
+            boost::int32_t y);
+
+       // Text fields need to handle cxform specially 
+       virtual cxform get_world_cxform() const;
+       
+    bool wantsInstanceName() const
+       {
+               return true; // text fields can be referenced 
+       }       
+               
+       bool on_event(const event_id& id);      
+
+       const std::string& getVariableName() const
+       {
+               return _variable_name;
+       }
+
+       /// Set the name of a variable associated to this
+       /// TextField's displayed text.
+       //
+       /// Calling this function will override any previous
+       /// setting for the variable name.
+       /// 
+       void set_variable_name(const std::string& newname);
+       
+       /// \brief Set our text to the given string by effect of an update of a
+    /// registered variable name
+       //
+       /// This call only updates the text and is only meant to be called
+    /// by ourselves or by MovieClip when a registered TextVariable is
+    /// updated.
+       void updateText(const std::string& s);
+
+       /// Return value of our text.
+       std::string get_text_value() const;
+
+       /// Return true if text is defined
+       bool getTextDefined() const { return _textDefined; }
+
+    size_t getCaretIndex() const {
+        return m_cursor;
+    }
+
+    const std::pair<size_t, size_t>& getSelection() const {
+        return _selection;
+    }
+
+    /// Replace the current selection with the new text.
+    void replaceSelection(const std::string& replace);
+
+    /// Set the current selection
+    //
+    /// @param start    The index of the beginning of the selection.
+    /// @param end      The index of the end of the selection.
+    //
+    /// If start is greater than end, the values are swapped, ensuring
+    /// end is never less than start.
+    void setSelection(int start, int end);
+
+       /// We have a "text" member.
+       bool set_member(string_table::key name, const as_value& val, 
+               string_table::key nsname = 0, bool ifFound=false);
+
+       bool get_member(string_table::key name, as_value* val, 
+               string_table::key nsname = 0);
+
+       /// Draw the dynamic string.
+       void    display();
+
+       void add_invalidated_bounds(InvalidatedRanges& ranges, bool force);
+
+       virtual rect getBounds() const
+       {
+               return _bounds;
+       }
+
+       // See dox in DisplayObject.h
+       bool pointInShape(boost::int32_t x, boost::int32_t y) const;
+
+       /// Return true if the 'background' should be drawn
+       bool getDrawBackground() const;
+
+       /// Specify wheter to draw the background
+       void setDrawBackground(bool draw);
+
+       /// Return color of the background
+       rgba getBackgroundColor() const;
+
+       /// Set color of the background
+       //
+       /// Use setDrawBackground to actually use this value.
+       ///
+       void setBackgroundColor(const rgba& col);
+
+       /// Return true if this TextField should have it's border visible
+       bool getDrawBorder() const;
+
+       /// Specify wheter to draw the border
+       void setDrawBorder(bool draw);
+
+       /// Return color of the border
+       rgba getBorderColor() const;
+
+       /// Set color of the border
+       //
+       /// Use setDrawBorder to actually use this value.
+       ///
+       void setBorderColor(const rgba& col);
+
+       /// Return color of the text
+       const rgba& getTextColor() const 
+       {
+               return _textColor;
+       }
+
+       /// Set color of the text
+       void setTextColor(const rgba& col);
+
+       /// \brief
+       /// Return true if this TextField should use embedded font glyphs,
+       /// false if it should use device font glyphs
+       bool getEmbedFonts() const {
+               return _embedFonts;
+       }
+
+    /// Get the current maxChars setting of the TextField
+    boost::int32_t maxChars() const {
+        return _maxChars;
+    }
+
+    /// Set the current maxChars setting of the TextField
+    void maxChars(boost::int32_t max) {
+        _maxChars = max;
+    }
+
+    /// Get the current multiline setting of the TextField
+    bool multiline() const {
+        return _multiline;
+    }
+
+    /// Set the current multiline setting of the TextField
+    void multiline(bool b) {
+        _multiline = b;
+    }
+
+    /// Get the current password setting of the TextField
+    bool password() const {
+        return _password;
+    }
+
+    /// Set the current password setting of the TextField
+    void password(bool b) {
+        _password = b;
+    }
+       /// \brief
+       /// Set whether this TextField should use embedded font glyphs,
+       /// or use device font glyphs
+       //
+       /// @param use
+       void setEmbedFonts(bool use);
+
+       /// Get autoSize value 
+       AutoSizeValue getAutoSize() const
+       {
+               return _autoSize;
+       }
+
+       /// Return text TextAlignment
+    TextAlignment getTextAlignment();
+
+       /// Set autoSize value 
+       //
+       /// @param val
+       ///     The AutoSizeValue to use
+       ///
+       void setAutoSize(AutoSizeValue val);
+
+       /// Parse autoSize string value
+       //
+       /// @param val
+       ///     Auto size value as a string (one of none, left, center, right)
+       ///
+       /// @return an AutoSizeValue identifier. autoSizeNone if invalid
+       ///
+       static AutoSizeValue parseAutoSizeValue(const std::string& val);
+
+       /// Return autoSize value as a string
+       //
+       /// @param val
+       ///     Auto size value 
+       ///
+       /// @return a C-string representation of the autoSize value.
+       ///     The returns is *never* NULL.
+       ///
+       static const char* autoSizeValueName(AutoSizeValue val);
+
+       /// Set type (input or dynamic)
+       //
+       /// @param val
+       ///     The TypeValue to use, no-op if typeInvalid.
+       ///
+       void setType(TypeValue val) { if (val != typeInvalid) _type=val; }
+
+       /// Get type (input, dynamic or invalid)
+       TypeValue getType() const
+       {
+               return _type;
+       }
+
+       /// Return true if this TextField is read-only
+       bool isReadOnly() const { return _type != typeInput; }
+
+       /// Parse type string value
+       //
+       /// @param val
+       ///     Type value as a string (one of input or dynamic)
+       ///
+       /// @return an TypeValue identifier. typeInvalid if invalid.
+       ///
+       static TypeValue parseTypeValue(const std::string& val);
+
+       /// Return type value as a string
+       //
+       /// @param val
+       ///     Type value  (enum)
+       ///
+       /// @return a C-string representation of the type value.
+       ///     The returns is *never* NULL.
+       ///
+       static const char* typeValueName(TypeValue val);
+
+       /// \brief
+       /// Return true if text should continue to next available line
+       /// when hitting end of bounding box.
+       ///
+       bool doWordWrap() const {
+               return _wordWrap;
+       }
+
+       /// Set wordWrap parameter 
+       //
+       /// @param on
+       ///     If true text hitting bounding box limits will continue
+       ///     to next line.
+       ///     If false, either text will be truncated or bounding box
+       ///     expanded, depending on autoSize (see getAutoSize)
+       ///
+       void setWordWrap(bool on);
+
+       /// \brief
+       /// Return true if HTML markup in text should be rendered.
+       ///
+       bool doHtml() const {
+               return _html;
+       }
+
+       /// Set html parameter
+       //
+       /// @param on
+       ///     If true HTML tags in the text will be parsed and rendered
+       void setHtml(bool on) {
+               _html = on;
+       }
+
+       /// Return true if the TextField text is selectable
+       bool isSelectable() const
+       {
+               return _selectable;
+       }
+
+       /// Set 'selectable' parameter
+       void setSelectable(bool v) 
+       {
+               _selectable = v;
+       }
+
+       // See DisplayObject::isActiveTextField
+       virtual bool isSelectableTextField() const
+       {
+               return isSelectable();
+       }
+
+       /// Remove this textfield from the stage
+       //
+       /// This is to implement TextField.removeTextField, will
+       /// basically forward the request to its parent.
+       /// Eventually this and MovieClip::removeMovieClip
+       /// will be merged in a single function to be later used
+       /// also for AS3 removeChild().
+       ///
+       void removeTextField();
+
+       /// Set our font, return previously set one.
+       //
+       /// @param newfont
+       ///     Will be stored in an intrusive_ptr
+       ///
+       boost::intrusive_ptr<const Font> setFont(
+            boost::intrusive_ptr<const Font> newfont);
+
+       const Font* getFont() { return _font.get(); }
+
+       boost::uint16_t getFontHeight() const
+       {
+               return _fontHeight;
+       }
+
+       void setFontHeight(boost::uint16_t h);
+
+       boost::uint16_t getLeftMargin() const
+       {
+               return _leftMargin;
+       }
+
+       void setLeftMargin(boost::uint16_t h);
+
+       boost::uint16_t getRightMargin() const
+       {
+               return _rightMargin;
+       }
+
+       void setRightMargin(boost::uint16_t h);
+
+       boost::uint16_t getIndent() const
+       {
+               return _indent;
+       }
+
+       void setIndent(boost::uint16_t h);
+
+       boost::uint16_t getBlockIndent() const
+       {
+               return _blockIndent;
+       }
+
+       void setBlockIndent(boost::uint16_t h);
+
+       TextAlignment getAlignment() const
+       {
+               return _alignment;
+       }
+
+       void setAlignment(TextAlignment h);
+
+       boost::uint16_t getLeading() const
+       {
+               return _leading;
+       }
+
+       void setLeading(boost::uint16_t h);
+
+       bool getUnderlined() const
+       {
+               return _underlined;
+       }
+
+       void setUnderlined(bool v);
+
+       const rect& getTextBoundingBox() const
+       {
+               return m_text_bounding_box;
+       }
+
+       /// Set our text to the given string.
+       //
+       /// This function will also update any registered variable
+       ///
+       void setTextValue(const std::wstring& wstr);
+       
+       static void init(as_object& global);
+
+protected:
+
+       /// Mark reachable reosurces (for GC)
+       //
+       /// Reachable resources are:
+       ///  - The font being used (m_font) 
+       ///  - Our definition
+       ///  - Common DisplayObject resources
+       ///
+       void markReachableResources() const;
+
+private:
+
+       /// \brief Set our text to the given string by effect of an update of a
+    /// registered variable name
+       //
+       /// This call only updates the text and is only meant to be called
+    /// by ourselves or by MovieClip when a registered TextVariable is
+    /// updated.
+       void updateText(const std::wstring& s);
+
+    void insertTab(SWF::TextRecord& rec, boost::int32_t& x, float scale);
+
+       /// What happens when setFocus() is called on this TextField.
+    //
+    /// @return true if focus was set. A TextField can always receive focus,
+    /// so this always returns true.
+       virtual bool handleFocus();
+
+       /// Kill focus 
+       virtual void killFocus();
+
+       /// Call this function when willing to invoke the onChanged event 
handler
+       void onChanged();
+
+       /// Reset our text bounding box to the given point.
+       void reset_bounding_box(boost::int32_t x, boost::int32_t y)
+       {
+               m_text_bounding_box.set_to_point(x, y);
+       }
+
+       /// Convert the DisplayObjects in _text into a series of
+       /// text_glyph_records to be rendered.
+       void format_text();
+       
+       /// Extracts an HTML tag.
+       ///
+       /// @param tag  This string is filled with the extracted HTML tag.
+       /// @param it   An iterator pointing to the first DisplayObject of the
+       ///             HTML tag. It is left pointing to the DisplayObject 
after the
+       ///             closing tag or the end of the string.
+       /// @param e    An iterator pointing to the end of the string.
+       /// @return     Whether the tag is complete or not (i.e. whether a '>'
+       ///             was found).
+       bool parseHTML(std::wstring& tag, std::wstring::const_iterator& it,
+                             const std::wstring::const_iterator& e) const;
+
+       /// Does LEFT/CENTER/RIGHT alignment on the records in
+       /// m_text_glyph_records[], starting with
+       /// last_line_start_record and going through the end of
+       /// m_text_glyph_records.
+       float align_line(TextAlignment align, int last_line_start_record, float 
x);
+
+       /// Associate a variable to the text of this DisplayObject
+       //
+       /// Setting the associated variable actually changes the
+       /// displayed text. Getting the variable would return the
+       /// displayed text.
+       ///
+       /// If the given variable already exist use it to set
+       /// current text before overriding it.
+       ///
+       /// Since the variable target may be undefined at time
+       /// of instantiation of this EditText DisplayObject, the
+       /// class keeps track of wheter it succeeded registering
+       /// the variable and this function will do nothing in this
+       /// case. Thus it is safe to call it multiple time, using
+       /// an as-needed policy (will be called from get_text_value and
+       /// display)
+       ///
+       void registerTextVariable();
+
+       typedef std::pair<as_object*, string_table::key> VariableRef;
+
+       /// \brief
+       /// Parse the given variable name
+       /// into sprite and a string_table::key components
+       ///
+       VariableRef parseTextVariableRef(const std::string& variableName) const;
+
+    /// The immutable definition of our TextField
+    //
+    /// This is NULL for dynamic TextFields.
+    boost::intrusive_ptr<const SWF::DefineEditTextTag> _tag;
+
+       /// The actual text.
+    //
+    /// Because we have to deal with non-ascii DisplayObjects (129-255), this
+    /// is a wide string; the cursor position and the position within the
+    /// string are then the same, which makes manipulating the string much
+    /// easier.
+       std::wstring _text;
+
+       /// This flag will be true as soon as the TextField
+       /// is assigned a text value. Only way to be false is
+       /// when definition has the hasText flag set to false
+       /// and no actionscript added text.
+       bool _textDefined;
+
+       /// bounds of dynamic text, as laid out
+       rect m_text_bounding_box;
+
+       typedef std::vector<SWF::TextRecord> TextRecords;
+       TextRecords _textRecords;
+       bool _underlined;
+
+       boost::uint16_t _leading;
+
+       TextAlignment _alignment;
+
+       boost::uint16_t _indent;
+
+       /// Indentation for every line (including the ones created by
+       /// effect of a word-wrap.
+       boost::uint16_t _blockIndent;
+
+       boost::uint16_t _leftMargin;
+
+       boost::uint16_t _rightMargin;
+
+       boost::uint16_t _fontHeight;
+
+       boost::intrusive_ptr<const Font> _font;
+
+       bool m_has_focus;
+       size_t m_cursor;
+       void show_cursor(const SWFMatrix& mat);
+       float m_xcursor;
+       float m_ycursor;
+
+    /// Corresponds to the multiline property.
+    bool _multiline;
+
+    /// Corresponds to the password property.
+    bool _password;
+
+    /// Corresponds to the maxChars property.
+    boost::int32_t _maxChars;
+       /// The flag keeping status of TextVariable registration
+       //
+       /// It will be set to true if there's no need to register
+       /// a text variable (ie. non-specified in the SWF)
+       ///
+       bool _text_variable_registered;
+
+       /// The text variable name
+       //
+       /// This is stored here, and not just in the definition,
+       /// because it can be changed programmatically, by setting
+       /// 'TextFields.variable'
+       std::string _variable_name;
+
+       bool _drawBackground;
+
+       rgba _backgroundColor;
+
+       bool _drawBorder;
+
+       rgba _borderColor;
+
+       rgba _textColor;
+
+       bool _embedFonts;
+
+       bool _wordWrap;
+
+       bool _html;
+
+       bool _selectable;
+
+       AutoSizeValue _autoSize;
+
+       TypeValue _type;
+
+       /// Area in which the text is drawn. 
+       //
+       /// This area encloses all the text, can be automatically
+       /// extended to fit text or hide text overflowing it.
+       /// See the setAutoSize() method to change that.
+       ///
+       rect _bounds;
+
+    /// Represents the selected part of the text. The second element must
+    /// never be less than the first.
+    std::pair<size_t, size_t> _selection;
+};
 
 } // gnash namespace
 

=== modified file 'libcore/asobj/flash/text/TextFormat_as.cpp'
--- a/libcore/asobj/flash/text/TextFormat_as.cpp        2009-06-08 18:31:05 
+0000
+++ b/libcore/asobj/flash/text/TextFormat_as.cpp        2009-06-08 22:24:55 
+0000
@@ -27,7 +27,7 @@
 #include "smart_ptr.h" // for boost intrusive_ptr
 #include "builtin_function.h" // need builtin_function
 #include "GnashException.h" // for ActionException
-#include "TextField.h"
+#include "text/TextField_as.h"
 #include "VM.h"
 #include "RGBA.h" // for rgba type
 #include "namedStrings.h"
@@ -41,8 +41,8 @@
     void attachTextFormatInterface(as_object& o);
     void attachTextFormatStaticInterface(as_object& o);
     as_object* getTextFormatInterface();
-    const char* getAlignString(TextField::TextAlignment a);
-       TextField::TextAlignment parseAlignString(const std::string& align);
+    const char* getAlignString(TextField_as::TextAlignment a);
+       TextField_as::TextAlignment parseAlignString(const std::string& align);
     
        as_value textformat_display(const fn_call& fn);
        as_value textformat_bullet(const fn_call& fn);
@@ -135,7 +135,7 @@
        _bold(false),
        _italic(false),
        _bullet(false),
-       _align(TextField::ALIGN_LEFT),
+       _align(TextField_as::ALIGN_LEFT),
        _blockIndent(-1),
        _color(),
        _indent(-1),
@@ -520,31 +520,31 @@
        return as_value();
 }
 
-TextField::TextAlignment
+TextField_as::TextAlignment
 parseAlignString(const std::string& align)
 {
        StringNoCaseEqual cmp;
-       if ( cmp(align, "left") ) return TextField::ALIGN_LEFT;
-    if ( cmp(align, "center") ) return TextField::ALIGN_CENTER;
-       if ( cmp(align, "right") ) return TextField::ALIGN_RIGHT;
-       if ( cmp(align, "justify") ) return TextField::ALIGN_JUSTIFY;
+       if ( cmp(align, "left") ) return TextField_as::ALIGN_LEFT;
+    if ( cmp(align, "center") ) return TextField_as::ALIGN_CENTER;
+       if ( cmp(align, "right") ) return TextField_as::ALIGN_RIGHT;
+       if ( cmp(align, "justify") ) return TextField_as::ALIGN_JUSTIFY;
        
        log_debug("Invalid align string %s, taking as left", align);
-       return TextField::ALIGN_LEFT;
+       return TextField_as::ALIGN_LEFT;
 }
 
 const char* 
-getAlignString(TextField::TextAlignment a)
+getAlignString(TextField_as::TextAlignment a)
 {
        switch (a)
        {
-               case TextField::ALIGN_LEFT:
+               case TextField_as::ALIGN_LEFT:
                        return "left";
-               case TextField::ALIGN_CENTER:
+               case TextField_as::ALIGN_CENTER:
                        return "center";
-               case TextField::ALIGN_RIGHT:
+               case TextField_as::ALIGN_RIGHT:
                        return "right";
-               case TextField::ALIGN_JUSTIFY:
+               case TextField_as::ALIGN_JUSTIFY:
                        return "justify";
                default:
                        log_error("Uknown alignment value: %d, take as left", 
a);

=== modified file 'libcore/asobj/flash/text/TextFormat_as.h'
--- a/libcore/asobj/flash/text/TextFormat_as.h  2009-06-08 18:31:05 +0000
+++ b/libcore/asobj/flash/text/TextFormat_as.h  2009-06-08 22:24:55 +0000
@@ -23,7 +23,7 @@
 #ifdef HAVE_CONFIG_H
 #include "as_object.h" // for inheritance of TextFormat
 #include "gnashconfig.h"
-#include "TextField.h" // for TextAlignment enum
+#include "text/TextField_as.h" // for TextAlignment enum
 #include "RGBA.h" // for rgba
 #include <boost/cstdint.hpp> // for boost::uint32_t
 #include <string>
@@ -72,7 +72,7 @@
        bool indentDefined() const { return _flags&DEFindent; }
 
        /// Return the alignment of the paragraph.
-       TextField::TextAlignment align() const { return _align; }
+       TextField_as::TextAlignment align() const { return _align; }
        bool alignDefined() const { return _flags&DEFalign; }
 
        /// Return the name of a font for text as a string.
@@ -122,7 +122,7 @@
        void indentSet(boost::uint16_t x)      { _indent = x; _flags |= 
DEFindent; }
        void fontSet(const std::string& font) { _font=font; _flags |= DEFfont; }
        
-    void alignSet(TextField::TextAlignment x) {
+    void alignSet(TextField_as::TextAlignment x) {
         _align = x;
         _flags |= DEFalign;
     }
@@ -198,7 +198,7 @@
        /// paragraph is centered. If "right", the paragraph is
        /// right-aligned. If "justify", the paragraph is justified.
        ///
-       TextField::TextAlignment _align;
+       TextField_as::TextAlignment _align;
 
        // 
        boost::uint16_t _blockIndent;

=== modified file 'libcore/asobj/flash/text/text.am'
--- a/libcore/asobj/flash/text/text.am  2009-06-08 18:31:05 +0000
+++ b/libcore/asobj/flash/text/text.am  2009-06-08 22:24:55 +0000
@@ -85,7 +85,7 @@
 
 # FIXME: already exists
 if BUILD_TEXTFIELD_AS3
-# TEXT_SOURCES += asobj/flash/text/TextField_as.cpp
+TEXT_SOURCES += asobj/flash/text/TextField_as.cpp
 TEXT_HEADERS += asobj/flash/text/TextField_as.h
 endif
 

=== modified file 'libcore/swf/DefineEditTextTag.cpp'
--- a/libcore/swf/DefineEditTextTag.cpp 2009-04-15 09:08:37 +0000
+++ b/libcore/swf/DefineEditTextTag.cpp 2009-06-08 22:24:55 +0000
@@ -16,7 +16,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
 #include "DefineEditTextTag.h"
-#include "TextField.h"
+#include "text/TextField_as.h"
 #include "movie_definition.h"
 #include "Font.h"
 #include "SWFStream.h"
@@ -43,7 +43,7 @@
 {
        // Resolve the font, if possible
        getFont();
-       TextField* ch = new TextField(parent, *this, id);
+       TextField_as* ch = new TextField_as(parent, *this, id);
 
        // This gives an "instance name" to the TextField, but
        // it is not really what we need.
@@ -152,7 +152,7 @@
        if (hasLayout)
        {
                in.ensureBytes(9); //1 + 2 + 2 + 2 + 2
-               _alignment = 
static_cast<TextField::TextAlignment>(in.read_u8());
+               _alignment = 
static_cast<TextField_as::TextAlignment>(in.read_u8());
                _leftMargin = in.read_u16();
                _rightMargin = in.read_u16();
                _indent = in.read_s16();
@@ -191,7 +191,7 @@
        _fontID(-1),
        _textHeight(1),
        _maxChars(0),
-       _alignment(TextField::ALIGN_LEFT),
+       _alignment(TextField_as::ALIGN_LEFT),
        _leftMargin(0),
        _rightMargin(0),
        _indent(0),

=== modified file 'libcore/swf/DefineEditTextTag.h'
--- a/libcore/swf/DefineEditTextTag.h   2009-04-15 09:08:37 +0000
+++ b/libcore/swf/DefineEditTextTag.h   2009-06-08 22:24:55 +0000
@@ -26,7 +26,7 @@
 #include "DefinitionTag.h"
 #include "swf.h" // for TagType definition
 #include "RGBA.h"
-#include "TextField.h"
+#include "text/TextField_as.h"
 
 #include <boost/cstdint.hpp> // for boost::uint16_t and friends
  
@@ -135,7 +135,7 @@
     }
 
        /// Get text alignment
-    TextField::TextAlignment alignment() const {
+    TextField_as::TextAlignment alignment() const {
                return _alignment;
        }
 
@@ -277,7 +277,7 @@
        ///
        unsigned int _maxChars;
 
-    TextField::TextAlignment _alignment;
+    TextField_as::TextAlignment _alignment;
        
        /// extra space between box's left border and text (in twips)
        boost::uint16_t _leftMargin;

=== modified file 'testsuite/as3/classes.all/text/TextField_as.hx'
--- a/testsuite/as3/classes.all/text/TextField_as.hx    2009-06-02 22:39:40 
+0000
+++ b/testsuite/as3/classes.all/text/TextField_as.hx    2009-06-08 22:24:55 
+0000
@@ -1,6 +1,6 @@
 // TextField_as.hx:  ActionScript 3 "TextField" class, for Gnash.
 //
-// Generated by gen-as3.sh on: 20090515 by "rob". Remove this
+// Generated on: 20090608 by "bnaugle". Remove this
 // after any hand editing loosing changes.
 //
 //   Copyright (C) 2009 Free Software Foundation, Inc.
@@ -32,6 +32,7 @@
 #else
 import flash.TextField;
 import flash.MovieClip;
+import flash.text.StyleSheet;
 #end
 import flash.Lib;
 import Type;
@@ -43,16 +44,14 @@
 // Class must be named with the _as suffix, as that's the same name as the 
file.
 class TextField_as {
     static function main() {
-
+#if !(flash6 || flash7)
 #if flash9
         var x1:TextField = new TextField();
 #else
-       var x1:TextField;
+               var x1:TextField = 
flash.Lib.current.createTextField("",10,0,0,300,300);
 #end
-
-#if flash9
         // Make sure we actually get a valid class        
-        if (Type.typeof(TextField)==TObject && x1 != null) {
+        if (Std.is(x1, TextField)) {
             DejaGnu.pass("TextField class exists");
         } else {
             DejaGnu.fail("TextField class doesn't exist");
@@ -60,22 +59,13 @@
 // Tests to see if all the properties exist. All these do is test for
 // existance of a property, and don't test the functionality at all. This
 // is primarily useful only to test completeness of the API implementation.
-
+#if flash9
        if (Type.typeof(x1.alwaysShowSelection) == TBool) {
            DejaGnu.pass("TextField.alwaysShowSelection property exists");
        } else {
            DejaGnu.fail("TextField.alwaysShowSelection property doesn't 
exist");
        }
-       if (Std.is(x1.antiAliasType,String) ) {
-           DejaGnu.pass("TextField.antiAliasType property exists");
-       } else {
-           DejaGnu.fail("TextField.antiAliasType property doesn't exist");
-       }
-       if (Std.is(x1.antiAliasType,String) ) {
-           DejaGnu.pass("TextField.antiAliasType property exists");
-       } else {
-           DejaGnu.fail("TextField.antiAliasType property doesn't exist");
-       }
+#end
        if (Std.is(x1.autoSize,String) ) {
            DejaGnu.pass("TextField.autoSize property exists");
        } else {
@@ -86,7 +76,7 @@
        } else {
            DejaGnu.fail("TextField.background property doesn't exist");
        }
-       if (Std.is(x1.backgroundColor,Float) ) {
+       if (Std.is(x1.backgroundColor,Int) ) {
            DejaGnu.pass("TextField.backgroundColor property exists");
        } else {
            DejaGnu.fail("TextField.backgroundColor property doesn't exist");
@@ -101,6 +91,7 @@
        } else {
            DejaGnu.fail("TextField.borderColor property doesn't exist");
        }
+#if flash9
        if (Std.is(x1.bottomScrollV,Float) ) {
            DejaGnu.pass("TextField.bottomScrollV property exists");
        } else {
@@ -111,11 +102,6 @@
        } else {
            DejaGnu.fail("TextField.caretIndex property doesn't exist");
        }
-       if (Type.typeof(x1.condenseWhite)== TBool) {
-           DejaGnu.pass("TextField.condenseWhite property exists");
-       } else {
-           DejaGnu.fail("TextField.condenseWhite property doesn't exist");
-       }
        if (Std.is(x1.defaultTextFormat,TextFormat) ) {
            DejaGnu.pass("TextField.defaultTextFormat property exists");
        } else {
@@ -126,31 +112,11 @@
        } else {
            DejaGnu.fail("TextField.displayAsPassword property doesn't exist");
        }
-       if (Type.typeof(x1.embedFonts) == TBool) {
-           DejaGnu.pass("TextField.embedFonts property exists");
-       } else {
-           DejaGnu.fail("TextField.embedFonts property doesn't exist");
-       }
-       if (Std.is(x1.gridFitType,String) ) {
-           DejaGnu.pass("TextField.gridFitType property exists");
-       } else {
-           DejaGnu.fail("TextField.gridFitType property doesn't exist");
-       }
        if (Std.is(x1.htmlText,String) ) {
            DejaGnu.pass("TextField.htmlText property exists");
        } else {
            DejaGnu.fail("TextField.htmlText property doesn't exist");
        }
-       if (Std.is(x1.length,Int) ) {
-           DejaGnu.pass("TextField.length property exists");
-       } else {
-           DejaGnu.fail("TextField.length property doesn't exist");
-       }
-       if (Std.is(x1.maxChars,Int) ) {
-           DejaGnu.pass("TextField.maxChars property exists");
-       } else {
-           DejaGnu.fail("TextField.maxChars property doesn't exist");
-       }
        if (Std.is(x1.maxScrollH,Int) ) {
            DejaGnu.pass("TextField.maxScrollH property exists");
        } else {
@@ -161,27 +127,6 @@
        } else {
            DejaGnu.fail("TextField.maxScrollV property doesn't exist");
        }
-       if (Type.typeof(x1.mouseWheelEnabled) == TBool) {
-           DejaGnu.pass("TextField.mouseWheelEnabled property exists");
-       } else {
-           DejaGnu.fail("TextField.mouseWheelEnabled property doesn't exist");
-       }
-       if (Type.typeof(x1.multiline)==TBool ) {
-           DejaGnu.pass("TextField.multiline property exists");
-       } else {
-           DejaGnu.fail("TextField.multiline property doesn't exist");
-       }
-       if (Std.is(x1.numLines,Int) ) {
-           DejaGnu.pass("TextField.numLines property exists");
-       } else {
-           DejaGnu.fail("TextField.numLines property doesn't exist");
-       }
-//     if (Std.is(x1.restrict,String) ) {
-//         DejaGnu.pass("TextField.restrict property exists");
-//     } else {
-//         DejaGnu.fail("TextField.restrict property doesn't exist");
-//     }
-
        if (Std.is(x1.scrollH,Int) ) {
            DejaGnu.pass("TextField.scrollH property exists");
        } else {
@@ -192,10 +137,10 @@
        } else {
            DejaGnu.fail("TextField.scrollV property doesn't exist");
        }
-       if (Type.typeof(x1.selectable)==TBool ) {
-           DejaGnu.pass("TextField.selectable property exists");
+       if (Std.is(x1.numLines,Int) ) {
+           DejaGnu.pass("TextField.numLines property exists");
        } else {
-           DejaGnu.fail("TextField.selectable property doesn't exist");
+           DejaGnu.fail("TextField.numLines property doesn't exist");
        }
        if (Std.is(x1.selectionBeginIndex,Int) ) {
            DejaGnu.pass("TextField.selectionBeginIndex property exists");
@@ -206,12 +151,108 @@
            DejaGnu.pass("TextField.selectionEndIndex property exists");
        } else {
            DejaGnu.fail("TextField.selectionEndIndex property doesn't exist");
-       }       
+       }
+       if (Type.typeof(x1.useRichTextClipboard) == TBool) {
+           DejaGnu.pass("TextField.useRichTextClipboard property exists");
+       } else {
+           DejaGnu.fail("TextField.useRichTextClipboard property doesn't 
exist");
+       }
+#else
+       if (Type.typeof(x1.password) == TBool) {
+           DejaGnu.pass("TextField.password property exists");
+       } else {
+           DejaGnu.fail("TextField.password property doesn't exist");
+       }
+       if (Std.is(x1.bottomScroll,Float) ) {
+           DejaGnu.pass("TextField.bottomScroll property exists");
+       } else {
+           DejaGnu.fail("TextField.bottomScroll property doesn't exist");
+       }
+       if (Std.is(x1.maxhscroll,Int) ) {
+           DejaGnu.pass("TextField.maxhscroll property exists");
+       } else {
+           DejaGnu.fail("TextField.maxhscroll property doesn't exist");
+       }
+       if (Std.is(x1.maxscroll,Int) ) {
+           DejaGnu.pass("TextField.maxscroll property exists");
+       } else {
+           DejaGnu.fail("TextField.maxscroll property doesn't exist");
+       }
+       if (Std.is(x1.scroll,Int) ) {
+           DejaGnu.pass("TextField.scroll property exists");
+       } else {
+           DejaGnu.fail("TextField.scroll property doesn't exist");
+       }
+       if (Std.is(x1.html,Bool) ) {
+           DejaGnu.pass("TextField.html property exists");
+       } else {
+           DejaGnu.fail("TextField.html property doesn't exist");
+       }
+#end
+#if (flash9 || flash8)
+       if (Std.is(x1.antiAliasType,String) ) {
+           DejaGnu.pass("TextField.antiAliasType property exists");
+       } else {
+           DejaGnu.fail("TextField.antiAliasType property doesn't exist");
+       }
        if (Std.is(x1.sharpness,Float) ) {
            DejaGnu.pass("TextField.sharpness property exists");
        } else {
            DejaGnu.fail("TextField.sharpness property doesn't exist");
        }
+       if (Std.is(x1.gridFitType,String) ) {
+           DejaGnu.pass("TextField.gridFitType property exists");
+       } else {
+           DejaGnu.fail("TextField.gridFitType property doesn't exist");
+       }
+       if (Std.is(x1.thickness,Float) ){
+           DejaGnu.pass("TextField.thickness property exists");
+       } else {
+           DejaGnu.fail("TextField.thickness property doesn't exist");
+       }
+#end
+       if (Type.typeof(x1.condenseWhite)== TBool) {
+           DejaGnu.pass("TextField.condenseWhite property exists");
+       } else {
+           DejaGnu.fail("TextField.condenseWhite property doesn't exist");
+       }
+       if (Type.typeof(x1.embedFonts) == TBool) {
+           DejaGnu.pass("TextField.embedFonts property exists");
+       } else {
+           DejaGnu.fail("TextField.embedFonts property doesn't exist");
+       }
+       if (Std.is(x1.length,Int) ) {
+           DejaGnu.pass("TextField.length property exists");
+       } else {
+           DejaGnu.fail("TextField.length property doesn't exist");
+       }
+       if (Std.is(x1.maxChars,Int) ) {
+           DejaGnu.pass("TextField.maxChars property exists");
+       } else {
+           DejaGnu.fail("TextField.maxChars property doesn't exist");
+       }
+       if (Type.typeof(x1.mouseWheelEnabled) == TBool) {
+           DejaGnu.pass("TextField.mouseWheelEnabled property exists");
+       } else {
+           DejaGnu.fail("TextField.mouseWheelEnabled property doesn't exist");
+       }
+       if (Type.typeof(x1.multiline)==TBool ) {
+           DejaGnu.pass("TextField.multiline property exists");
+       } else {
+           DejaGnu.fail("TextField.multiline property doesn't exist");
+       }
+//     if (Std.is(x1.restrict,String) ) {
+//         DejaGnu.pass("TextField.restrict property exists");
+//     } else {
+//         DejaGnu.fail("TextField.restrict property doesn't exist");
+//     }
+
+       
+       if (Type.typeof(x1.selectable)==TBool ) {
+           DejaGnu.pass("TextField.selectable property exists");
+       } else {
+           DejaGnu.fail("TextField.selectable property doesn't exist");
+       }
 
 //Si:
 //I initialized the StylsSheet at first
@@ -245,29 +286,16 @@
        } else {
            DejaGnu.fail("TextField.textWidth property doesn't exist");
        }
-       if (Std.is(x1.thickness,Float) ){
-           DejaGnu.pass("TextField.thickness property exists");
-       } else {
-           DejaGnu.fail("TextField.thickness property doesn't exist");
-       }
        if (Std.is(x1.type,String) ) {
            DejaGnu.pass("TextField.type property exists");
        } else {
            DejaGnu.fail("TextField.type property doesn't exist");
        }
-       if (Type.typeof(x1.useRichTextClipboard) == TBool) {
-           DejaGnu.pass("TextField.useRichTextClipboard property exists");
-       } else {
-           DejaGnu.fail("TextField.useRichTextClipboard property doesn't 
exist");
-       }
        if (Type.typeof(x1.wordWrap)== TBool) {
            DejaGnu.pass("TextField.wordWrap property exists");
        } else {
            DejaGnu.fail("TextField.wordWrap property doesn't exist");
        }
-#else
-#end
-
 
 //Si:
 //This one is not defined in Haxe
@@ -282,11 +310,6 @@
 // existance of a method, and don't test the functionality at all. This
 // is primarily useful only to test completeness of the API implementation.
 #if flash9
-//     if (Type.typeof(x1.TextField)==TFunction) {
-//         DejaGnu.pass("TextField::TextField() method exists");
-//     } else {
-//         DejaGnu.fail("TextField::TextField() method doesn't exist");
-//     }
        if (Type.typeof(x1.appendText)==TFunction) {
            DejaGnu.pass("TextField::appendText() method exists");
        } else {
@@ -362,7 +385,6 @@
        } else {
            DejaGnu.fail("TextField::getTexRuns() method doesn't exist");
        }
-
        if (Type.typeof(x1.getXMLText )==TFunction) {
            DejaGnu.pass("TextField::getXMLText() method exists");
        } else {
@@ -373,31 +395,30 @@
        } else {
            DejaGnu.fail("TextField::insertXMLText() method doesn't exist");
        }       
-
-
        if (Type.typeof(x1.replaceSelectedText )==TFunction) {
            DejaGnu.pass("TextField::replaceSelectedText() method exists");
        } else {
            DejaGnu.fail("TextField::replaceSelectedText() method doesn't 
exist");
        }
+       if (Type.typeof(x1.setSelection )==TFunction) {
+           DejaGnu.pass("TextField::setSelection() method exists");
+       } else {
+           DejaGnu.fail("TextField::setSelection() method doesn't exist");
+       }
+#else
+       
+#end
        if (Type.typeof(x1.replaceText)==TFunction) {
            DejaGnu.pass("TextField::replaceText() method exists");
        } else {
            DejaGnu.fail("TextField::replaceText() method doesn't exist");
        }
-       if (Type.typeof(x1.setSelection )==TFunction) {
-           DejaGnu.pass("TextField::setSelection() method exists");
-       } else {
-           DejaGnu.fail("TextField::setSelection() method doesn't exist");
-       }
        if (Type.typeof(x1.setTextFormat )==TFunction) {
            DejaGnu.pass("TextField::setTextFormat() method exists");
        } else {
            DejaGnu.fail("TextField::setTextFormat() method doesn't exist");
        }
-#else
 #end
-
         // Call this after finishing all tests. It prints out the totals.
         DejaGnu.done();
     }


reply via email to

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