gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] gnash/server Sprite.cpp action.cpp text.cpp tex...


From: strk
Subject: [Gnash-commit] gnash/server Sprite.cpp action.cpp text.cpp tex...
Date: Tue, 31 Jan 2006 16:45:38 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Branch:         
Changes by:     strk <address@hidden>   06/01/31 16:45:38

Modified files:
        server         : Sprite.cpp action.cpp text.cpp text.h 
                         textformat.h xml.h 

Log message:
        More doxygen-enabled dox

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/gnash/server/Sprite.cpp.diff?tr1=1.5&tr2=1.6&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/gnash/gnash/server/action.cpp.diff?tr1=1.9&tr2=1.10&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/gnash/gnash/server/text.cpp.diff?tr1=1.3&tr2=1.4&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/gnash/gnash/server/text.h.diff?tr1=1.1&tr2=1.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/gnash/gnash/server/textformat.h.diff?tr1=1.2&tr2=1.3&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/gnash/gnash/server/xml.h.diff?tr1=1.4&tr2=1.5&r1=text&r2=text

Patches:
Index: gnash/server/Sprite.cpp
diff -u gnash/server/Sprite.cpp:1.5 gnash/server/Sprite.cpp:1.6
--- gnash/server/Sprite.cpp:1.5 Mon Jan 30 10:29:28 2006
+++ gnash/server/Sprite.cpp     Tue Jan 31 16:45:38 2006
@@ -537,8 +537,9 @@
                }
                case M_PARENT:
                {
-                   
val->set_as_object_interface(static_cast<as_object_interface*>(m_parent));
-                   return true;
+                       assert(dynamic_cast<as_object_interface*>(m_parent));
+                       
val->set_as_object_interface(static_cast<as_object_interface*>(m_parent));
+                       return true;
                }
                case M_ONLOAD:
                {
Index: gnash/server/action.cpp
diff -u gnash/server/action.cpp:1.9 gnash/server/action.cpp:1.10
--- gnash/server/action.cpp:1.9 Sun Jan 29 10:19:51 2006
+++ gnash/server/action.cpp     Tue Jan 31 16:45:38 2006
@@ -3267,7 +3267,7 @@
                }
                else
                {
-                       m_string_value = "<bad type>";
+                       m_string_value = "<bad type> "+m_type;
                        assert(0);
                }
                
Index: gnash/server/text.cpp
diff -u gnash/server/text.cpp:1.3 gnash/server/text.cpp:1.4
--- gnash/server/text.cpp:1.3   Sun Jan 29 10:19:51 2006
+++ gnash/server/text.cpp       Tue Jan 31 16:45:38 2006
@@ -315,760 +315,605 @@
        // edit_text_character_def
        //
 
-
-       /// A definition for a text display character, whose text can
-       /// be changed at runtime (by script or host).
-       struct edit_text_character_def : public character_def
+       void
+       edit_text_character_def::read(stream* in, int tag_type,
+                       movie_definition_sub* m)
        {
-               movie_definition_sub*   m_root_def;
-               rect                    m_rect;
-               tu_string               m_default_name;
-               text_format             m_format;
-               bool                    m_word_wrap;
-               bool                    m_multiline;
-               bool                    m_password;     // show asterisks 
instead of actual characters
-               bool                    m_readonly;
-               bool                    m_auto_size;    // resize our bound to 
fit the text
-               bool                    m_no_select;
-               bool                    m_border;       // forces white 
background and black border -- silly, but sometimes used
-               bool                    m_html;
-
-               // Allowed HTML (from Alexi's SWF Reference):
-               //
-               // <a href=url target=targ>...</a> -- hyperlink
-               // <b>...</b> -- bold
-               // <br> -- line break
-               // <font face=name size=[+|-][0-9]+ color=#RRGGBB>...</font>  
-- font change; size in TWIPS
-               // <i>...</i> -- italic
-               // <li>...</li> -- list item
-               // <p>...</p> -- paragraph
-               // <tab> -- insert tab
-               // <TEXTFORMAT>  </TEXTFORMAT>
-               //   [ BLOCKINDENT=[0-9]+ ]
-               //   [ INDENT=[0-9]+ ]
-               //   [ LEADING=[0-9]+ ]
-               //   [ LEFTMARGIN=[0-9]+ ]
-               //   [ RIGHTMARGIN=[0-9]+ ]
-               //   [ TABSTOPS=[0-9]+{,[0-9]+} ]
-               //
-               // Change the different parameters as indicated. The
-               // sizes are all in TWIPs. There can be multiple
-               // positions for the tab stops. These are seperated by
-               // commas.
-               // <U>...</U> -- underline
-
-
-               bool    m_use_outlines; // when true, use specified SWF 
internal font.  Otherwise, renderer picks a default font
-
-               int     m_font_id;
-               font*   m_font;
-               float   m_text_height;
-
-               rgba    m_color;
-               int     m_max_length;
-
-               enum alignment
-               {
-                       ALIGN_LEFT = 0,
-                       ALIGN_RIGHT,
-                       ALIGN_CENTER,
-                       ALIGN_JUSTIFY   // probably don't need to implement...
-               };
-               alignment       m_alignment;
-               
-               float   m_left_margin;  // extra space between box border and 
text
-               float   m_right_margin;
-               float   m_indent;       // how much to indent the first line of 
multiline text
-               float   m_leading;      // extra space between lines (in 
addition to default font line spacing)
-               tu_string       m_default_text;
-
-               edit_text_character_def(movie_definition_sub* root_def)
-                       :
-                       m_root_def(root_def),
-                       m_word_wrap(false),
-                       m_multiline(false),
-                       m_password(false),
-                       m_readonly(false),
-                       m_auto_size(false),
-                       m_no_select(false),
-                       m_border(false),
-                       m_html(false),
-                       m_use_outlines(false),
-                       m_font_id(-1),
-                       m_font(NULL),
-                       m_text_height(1.0f),
-                       m_max_length(0),
-                       m_alignment(ALIGN_LEFT),
-                       m_left_margin(0.0f),
-                       m_right_margin(0.0f),
-                       m_indent(0.0f),
-                       m_leading(0.0f)
-               {
-                       assert(m_root_def);
+               assert(m != NULL);
+               assert(tag_type == 37);
 
-                       m_color.set(0, 0, 0, 255);
-               }
+               m_rect.read(in);
+
+               in->align();
+               bool    has_text = in->read_uint(1) ? true : false;
+               m_word_wrap = in->read_uint(1) ? true : false;
+               m_multiline = in->read_uint(1) ? true : false;
+               m_password = in->read_uint(1) ? true : false;
+               m_readonly = in->read_uint(1) ? true : false;
+               bool    has_color = in->read_uint(1) ? true : false;
+               bool    has_max_length = in->read_uint(1) ? true : false;
+               bool    has_font = in->read_uint(1) ? true : false;
+
+               in->read_uint(1);       // reserved
+               m_auto_size = in->read_uint(1) ? true : false;
+               bool    has_layout = in->read_uint(1) ? true : false;
+               m_no_select = in->read_uint(1) ? true : false;
+               m_border = in->read_uint(1) ? true : false;
+               in->read_uint(1);       // reserved
+               m_html = in->read_uint(1) ? true : false;
+               m_use_outlines = in->read_uint(1) ? true : false;
 
-               // Set the format of the text
-               void    set_format(text_format &format)
+               if (has_font)
                {
-                       m_format = format;
+                       m_font_id = in->read_u16();
+                       m_text_height = (float) in->read_u16();
                }
-               
-               ~edit_text_character_def()
+
+               if (has_color)
                {
+                       m_color.read_rgba(in);
                }
 
-
-               character*      create_character_instance(movie* parent, int 
id);
-
-
-               void    read(stream* in, int tag_type, movie_definition_sub* m)
+               if (has_max_length)
                {
-                       assert(m != NULL);
-                       assert(tag_type == 37);
-
-                       m_rect.read(in);
-
-                       in->align();
-                       bool    has_text = in->read_uint(1) ? true : false;
-                       m_word_wrap = in->read_uint(1) ? true : false;
-                       m_multiline = in->read_uint(1) ? true : false;
-                       m_password = in->read_uint(1) ? true : false;
-                       m_readonly = in->read_uint(1) ? true : false;
-                       bool    has_color = in->read_uint(1) ? true : false;
-                       bool    has_max_length = in->read_uint(1) ? true : 
false;
-                       bool    has_font = in->read_uint(1) ? true : false;
-
-                       in->read_uint(1);       // reserved
-                       m_auto_size = in->read_uint(1) ? true : false;
-                       bool    has_layout = in->read_uint(1) ? true : false;
-                       m_no_select = in->read_uint(1) ? true : false;
-                       m_border = in->read_uint(1) ? true : false;
-                       in->read_uint(1);       // reserved
-                       m_html = in->read_uint(1) ? true : false;
-                       m_use_outlines = in->read_uint(1) ? true : false;
+                       m_max_length = in->read_u16();
+               }
 
-                       if (has_font)
-                       {
-                               m_font_id = in->read_u16();
-                               m_text_height = (float) in->read_u16();
-                       }
+               if (has_layout)
+               {
+                       m_alignment = (alignment) in->read_u8();
+                       m_left_margin = (float) in->read_u16();
+                       m_right_margin = (float) in->read_u16();
+                       m_indent = (float) in->read_s16();
+                       m_leading = (float) in->read_s16();
+               }
 
-                       if (has_color)
-                       {
-                               m_color.read_rgba(in);
-                       }
+               char*   name = in->read_string();
+               m_default_name = name;
+               delete [] name;
 
-                       if (has_max_length)
-                       {
-                               m_max_length = in->read_u16();
-                       }
-
-                       if (has_layout)
-                       {
-                               m_alignment = (alignment) in->read_u8();
-                               m_left_margin = (float) in->read_u16();
-                               m_right_margin = (float) in->read_u16();
-                               m_indent = (float) in->read_s16();
-                               m_leading = (float) in->read_s16();
-                       }
+               if (has_text)
+               {
+                       char*   str = in->read_string();
+                       m_default_text = str;
+                       delete [] str;
+               }
 
-                       char*   name = in->read_string();
-                       m_default_name = name;
-                       delete [] name;
-
-                       if (has_text)
-                       {
-                               char*   str = in->read_string();
-                               m_default_text = str;
-                               delete [] str;
-                       }
+               IF_VERBOSE_PARSE(log_msg("edit_text_char, varname = %s, text = 
%s\n",
+                                        m_default_name.c_str(), 
m_default_text.c_str()));
+       }
 
-                       IF_VERBOSE_PARSE(log_msg("edit_text_char, varname = %s, 
text = %s\n",
-                                                m_default_name.c_str(), 
m_default_text.c_str()));
-               }
-       };
 
 
        //
        // edit_text_character
        //
 
-
-       struct edit_text_character : public character
+       void
+       edit_text_character::set_text_value(const char* new_text)
        {
-               edit_text_character_def*        m_def;
-               array<text_glyph_record>        m_text_glyph_records;
-               array<fill_style>       m_dummy_style;  // used to pass a color 
on to shape_character::display()
-               array<line_style>       m_dummy_line_style;
-               rect    m_text_bounding_box;    // bounds of dynamic text, as 
laid out
-
-               tu_string       m_text;
+               if (m_text == new_text)
+               {
+                       return;
+               }
 
-               edit_text_character(movie* parent, edit_text_character_def* 
def, int id)
-                       :
-                       character(parent, id),
-                       m_def(def)
+               m_text = new_text;
+               if (m_def->m_max_length > 0
+                   && m_text.length() > m_def->m_max_length)
                {
-                       assert(parent);
-                       assert(m_def);
+                       m_text.resize(m_def->m_max_length);
+               }
+
+               format_text();
+       }
 
-                       set_text_value(m_def->m_default_text.c_str());
+       void
+       edit_text_character::set_member(const tu_stringi& name,
+                       const as_value& val)
+       {
+               // @@ TODO need to inherit basic stuff like _x, _y, _xscale, 
_yscale etc
 
-                       m_dummy_style.push_back(fill_style());
+               as_standard_member      std_member = get_standard_member(name);
+               switch (std_member)
+               {
+               default:
+               case M_INVALID_MEMBER:
+                       break;
+               case M_TEXT:
+                       //if (name == "text")
+               {
+                       int version = 
get_parent()->get_movie_definition()->get_version();
+                       set_text_value(val.to_tu_string_versioned(version));
+                       return;
+               }
+               case M_X:
+                       //else if (name == "_x")
+               {
+                       matrix  m = get_matrix();
+                       m.m_[0][2] = (float) PIXELS_TO_TWIPS(val.to_number());
+                       set_matrix(m);
+
+                       // m_accept_anim_moves = false;
+                       
+                       return;
+               }
+               case M_Y:
+                       //else if (name == "_y")
+               {
+                       matrix  m = get_matrix();
+                       m.m_[1][2] = (float) PIXELS_TO_TWIPS(val.to_number());
+                       set_matrix(m);
+
+                       // m_accept_anim_moves = false;
+                       
+                       return;
+               }
+               case M_VISIBLE:
+                       //else if (name == "_visible")
+               {
+                       set_visible(val.to_bool());
+                       return;
+               }
+               case M_ALPHA:
+                       //else if (name == "_alpha")
+               {
+                       // @@ TODO this should be generic to struct character!
+                       // Arg is in percent.
+                       cxform  cx = get_cxform();
+                       cx.m_[3][0] = fclamp(float(val.to_number()) / 100.f, 0, 
1);
+                       set_cxform(cx);
+                       return;
+               }
+               case M_TEXTCOLOR:
+                       //else if (name == "textColor")
+               {       
+                       // The arg is 0xRRGGBB format.
+                       Uint32  rgb = (Uint32) val.to_number();
+
+                       cxform  cx = get_cxform();
+                       cx.m_[0][0] = fclamp(((rgb >> 16) & 255) / 255.0f, 0, 
1);
+                       cx.m_[1][0] = fclamp(((rgb >>  8) & 255) / 255.0f, 0, 
1);
+                       cx.m_[2][0] = fclamp(((rgb      ) & 255) / 255.0f, 0, 
1);
+                       set_cxform(cx);
 
-                       reset_bounding_box(0, 0);
+                       return;
                }
+               // @@ TODO see TextField members in Flash MX docs
+               }       // end switch
+       }
 
-               ~edit_text_character()
+       bool
+       edit_text_character::get_member(const tu_stringi& name, as_value* val)
+       {
+               as_standard_member      std_member = get_standard_member(name);
+               switch (std_member)
                {
+               default:
+               case M_INVALID_MEMBER:
+                       break;
+               case M_TEXT:
+                       //if (name == "text")
+               {
+                       val->set_tu_string(m_text);
+                       return true;
+               }
+               case M_VISIBLE:
+                       //else if (name == "_visible")
+               {
+                       val->set_bool(get_visible());
+                       return true;
+               }
+               case M_ALPHA:
+                       //else if (name == "_alpha")
+               {
+                       // @@ TODO this should be generic to struct character!
+                       const cxform&   cx = get_cxform();
+                       val->set_double(cx.m_[3][0] * 100.f);
+                       return true;
+               }
+               case M_TEXTCOLOR:
+                       //else if (name == "textColor")
+               {
+                       // Return color in 0xRRGGBB format
+                       const cxform&   cx = get_cxform();
+                       int     r = iclamp(int(cx.m_[0][0] * 255), 0, 255);
+                       int     g = iclamp(int(cx.m_[0][0] * 255), 0, 255);
+                       int     b = iclamp(int(cx.m_[0][0] * 255), 0, 255);
+                       val->set_int((r << 16) + (g << 8) + b);
+                       return true;
+               }
+               case M_X:
+                       //else if (name == "_x")
+               {
+                       matrix  m = get_matrix();       // @@ 
get_world_matrix()???
+                       val->set_double(TWIPS_TO_PIXELS(m.m_[0][2]));
+                       return true;
+               }
+               case M_Y:
+                       //else if (name == "_y")
+               {
+                       matrix  m = get_matrix();       // @@ 
get_world_matrix()???
+                       val->set_double(TWIPS_TO_PIXELS(m.m_[1][2]));
+                       return true;
+               }
+               case M_WIDTH:
+                       //else if (name == "_width")
+               {
+                       // @@ TODO should implement this in
+                       // character and inherit into both here and 
sprite_instance
+                       rect    transformed_rect;
+                       
transformed_rect.enclose_transformed_rect(get_world_matrix(), m_def->m_rect);
+                       
val->set_double(TWIPS_TO_PIXELS(transformed_rect.width()));
+                       return true;
+               }
+               case M_HEIGHT:
+                       //else if (name == "_height")
+               {
+                       // @@ TODO should implement this in
+                       // character and inherit into both here and 
sprite_instance
+                       rect    transformed_rect;
+                       
transformed_rect.enclose_transformed_rect(get_world_matrix(), m_def->m_rect);
+                       
val->set_double(TWIPS_TO_PIXELS(transformed_rect.height()));
+                       return true;
+               }
+               case M_TEXTWIDTH:
+                       //else if (name == "textWidth")
+               {
+                       // 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.
+                       
val->set_double(TWIPS_TO_PIXELS(m_text_bounding_box.width()));
+
+                       return true;
                }
+               }       // end switch
+
+               return false;
+       }
+               
+       // @@ WIDTH_FUDGE is a total fudge to make it match the Flash player!  
Maybe
+       // we have a bug?
+       #define WIDTH_FUDGE 80.0f
+
 
-               virtual const char*     get_text_name() const { return 
m_def->m_default_name.c_str(); }
+       void
+       edit_text_character::align_line(
+                       edit_text_character_def::alignment align,
+                       int last_line_start_record, float x)
+       {
+               float   extra_space = (m_def->m_rect.width() -
+                               m_def->m_right_margin) - x - WIDTH_FUDGE;
+               assert(extra_space >= 0.0f);
 
+               float   shift_right = 0.0f;
 
-               void    reset_bounding_box(float x, float y)
-               // Reset our text bounding box to the given point.
+               if (align == edit_text_character_def::ALIGN_LEFT)
                {
-                       m_text_bounding_box.m_x_min = x;
-                       m_text_bounding_box.m_x_max = x;
-                       m_text_bounding_box.m_y_min = y;
-                       m_text_bounding_box.m_y_max = y;
+                       // Nothing to do; already aligned left.
+                       return;
+               }
+               else if (align == edit_text_character_def::ALIGN_CENTER)
+               {
+                       // Distribute the space evenly on both sides.
+                       shift_right = extra_space / 2;
+               }
+               else if (align == edit_text_character_def::ALIGN_RIGHT)
+               {
+                       // Shift all the way to the right.
+                       shift_right = extra_space;
                }
 
-
-               virtual void    set_text_value(const char* new_text)
-               // Set our text to the given string.
+               // Shift the beginnings of the records on this line.
+               for (int i = last_line_start_record; i < 
m_text_glyph_records.size(); i++)
                {
-                       if (m_text == new_text)
-                       {
-                               return;
-                       }
+                       text_glyph_record&      rec = m_text_glyph_records[i];
 
-                       m_text = new_text;
-                       if (m_def->m_max_length > 0
-                           && m_text.length() > m_def->m_max_length)
+                       if (rec.m_style.m_has_x_offset)
                        {
-                               m_text.resize(m_def->m_max_length);
+                               rec.m_style.m_x_offset += shift_right;
                        }
-
-                       format_text();
                }
+       }
 
-               virtual const char*     get_text_value() const
+       void
+       edit_text_character::format_text()
+       {
+               m_text_glyph_records.resize(0);
+
+               if (m_def->m_font == NULL)
                {
-                       return m_text.c_str();
+                       return;
                }
 
-
-               void    set_member(const tu_stringi& name, const as_value& val)
-               // We have a "text" member.
+               // @@ mostly for debugging
+               // Font substitution -- if the font has no
+               // glyphs, try some other defined font!
+               if (m_def->m_font->get_glyph_count() == 0)
                {
-                       // @@ TODO need to inherit basic stuff like _x, _y, 
_xscale, _yscale etc
-
-                       as_standard_member      std_member = 
get_standard_member(name);
-                       switch (std_member)
-                       {
-                       default:
-                       case M_INVALID_MEMBER:
-                               break;
-                       case M_TEXT:
-                               //if (name == "text")
+                       // Find a better font.
+                       font*   newfont = m_def->m_font;
+                       for (int i = 0, n = fontlib::get_font_count(); i < n; 
i++)
                        {
-                               int version = 
get_parent()->get_movie_definition()->get_version();
-                               
set_text_value(val.to_tu_string_versioned(version));
-                               return;
-                       }
-                       case M_X:
-                               //else if (name == "_x")
-                       {
-                               matrix  m = get_matrix();
-                               m.m_[0][2] = (float) 
PIXELS_TO_TWIPS(val.to_number());
-                               set_matrix(m);
+                               font*   f = fontlib::get_font(i);
+                               assert(f);
 
-                               // m_accept_anim_moves = false;
-                               
-                               return;
+                               if (f->get_glyph_count() > 0)
+                               {
+                                       // This one looks good.
+                                       newfont = f;
+                                       break;
+                               }
                        }
-                       case M_Y:
-                               //else if (name == "_y")
-                       {
-                               matrix  m = get_matrix();
-                               m.m_[1][2] = (float) 
PIXELS_TO_TWIPS(val.to_number());
-                               set_matrix(m);
 
-                               // m_accept_anim_moves = false;
-                               
-                               return;
-                       }
-                       case M_VISIBLE:
-                               //else if (name == "_visible")
-                       {
-                               set_visible(val.to_bool());
-                               return;
-                       }
-                       case M_ALPHA:
-                               //else if (name == "_alpha")
+                       if (m_def->m_font != newfont)
                        {
-                               // @@ TODO this should be generic to struct 
character!
-                               // Arg is in percent.
-                               cxform  cx = get_cxform();
-                               cx.m_[3][0] = fclamp(float(val.to_number()) / 
100.f, 0, 1);
-                               set_cxform(cx);
-                               return;
-                       }
-                       case M_TEXTCOLOR:
-                               //else if (name == "textColor")
-                       {       
-                               // The arg is 0xRRGGBB format.
-                               Uint32  rgb = (Uint32) val.to_number();
-
-                               cxform  cx = get_cxform();
-                               cx.m_[0][0] = fclamp(((rgb >> 16) & 255) / 
255.0f, 0, 1);
-                               cx.m_[1][0] = fclamp(((rgb >>  8) & 255) / 
255.0f, 0, 1);
-                               cx.m_[2][0] = fclamp(((rgb      ) & 255) / 
255.0f, 0, 1);
-                               set_cxform(cx);
+                               log_error("error: substituting font!  font '%s' 
has no glyphs, using font '%s'\n",
+                                         fontlib::get_font_name(m_def->m_font),
+                                         fontlib::get_font_name(newfont));
 
-                               return;
+                               m_def->m_font = newfont;
                        }
-                       // @@ TODO see TextField members in Flash MX docs
-                       }       // end switch
                }
 
 
-               bool    get_member(const tu_stringi& name, as_value* val)
-               {
-                       as_standard_member      std_member = 
get_standard_member(name);
-                       switch (std_member)
-                       {
-                       default:
-                       case M_INVALID_MEMBER:
-                               break;
-                       case M_TEXT:
-                               //if (name == "text")
-                       {
-                               val->set_tu_string(m_text);
-                               return true;
-                       }
-                       case M_VISIBLE:
-                               //else if (name == "_visible")
-                       {
-                               val->set_bool(get_visible());
-                               return true;
-                       }
-                       case M_ALPHA:
-                               //else if (name == "_alpha")
-                       {
-                               // @@ TODO this should be generic to struct 
character!
-                               const cxform&   cx = get_cxform();
-                               val->set_double(cx.m_[3][0] * 100.f);
-                               return true;
-                       }
-                       case M_TEXTCOLOR:
-                               //else if (name == "textColor")
-                       {
-                               // Return color in 0xRRGGBB format
-                               const cxform&   cx = get_cxform();
-                               int     r = iclamp(int(cx.m_[0][0] * 255), 0, 
255);
-                               int     g = iclamp(int(cx.m_[0][0] * 255), 0, 
255);
-                               int     b = iclamp(int(cx.m_[0][0] * 255), 0, 
255);
-                               val->set_int((r << 16) + (g << 8) + b);
-                               return true;
-                       }
-                       case M_X:
-                               //else if (name == "_x")
-                       {
-                               matrix  m = get_matrix();       // @@ 
get_world_matrix()???
-                               val->set_double(TWIPS_TO_PIXELS(m.m_[0][2]));
-                               return true;
-                       }
-                       case M_Y:
-                               //else if (name == "_y")
-                       {
-                               matrix  m = get_matrix();       // @@ 
get_world_matrix()???
-                               val->set_double(TWIPS_TO_PIXELS(m.m_[1][2]));
-                               return true;
-                       }
-                       case M_WIDTH:
-                               //else if (name == "_width")
-                       {
-                               // @@ TODO should implement this in
-                               // character and inherit into both here and 
sprite_instance
-                               rect    transformed_rect;
-                               
transformed_rect.enclose_transformed_rect(get_world_matrix(), m_def->m_rect);
-                               
val->set_double(TWIPS_TO_PIXELS(transformed_rect.width()));
-                               return true;
-                       }
-                       case M_HEIGHT:
-                               //else if (name == "_height")
-                       {
-                               // @@ TODO should implement this in
-                               // character and inherit into both here and 
sprite_instance
-                               rect    transformed_rect;
-                               
transformed_rect.enclose_transformed_rect(get_world_matrix(), m_def->m_rect);
-                               
val->set_double(TWIPS_TO_PIXELS(transformed_rect.height()));
-                               return true;
-                       }
-                       case M_TEXTWIDTH:
-                               //else if (name == "textWidth")
-                       {
-                               // 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.
-                               
val->set_double(TWIPS_TO_PIXELS(m_text_bounding_box.width()));
+               float   scale = m_def->m_text_height / 1024.0f; // the EM 
square is 1024 x 1024
 
-                               return true;
-                       }
-                       }       // end switch
-
-                       return false;
-               }
+               text_glyph_record       rec;    // one to work on
+               rec.m_style.m_font = m_def->m_font;
+               rec.m_style.m_color = m_def->m_color;
+               rec.m_style.m_x_offset = fmax(0, m_def->m_left_margin + 
m_def->m_indent);
+               rec.m_style.m_y_offset = m_def->m_text_height
+                       + (m_def->m_font->get_leading() - 
m_def->m_font->get_descent()) * scale;
+               rec.m_style.m_text_height = m_def->m_text_height;
+               rec.m_style.m_has_x_offset = true;
+               rec.m_style.m_has_y_offset = true;
 
-               
-               // @@ WIDTH_FUDGE is a total fudge to make it match the Flash 
player!  Maybe
-               // we have a bug?
-               #define WIDTH_FUDGE 80.0f
+               float   x = rec.m_style.m_x_offset;
+               float   y = rec.m_style.m_y_offset;
 
+               // Start the bbox at the upper-left corner of the first glyph.
+               reset_bounding_box(x, y - m_def->m_font->get_descent() * scale 
+ m_def->m_text_height);
 
-               void    align_line(edit_text_character_def::alignment align, 
int last_line_start_record, float x)
-               // 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   extra_space = (m_def->m_rect.width() - 
m_def->m_right_margin) - x - WIDTH_FUDGE;
-                       assert(extra_space >= 0.0f);
+               float   leading = m_def->m_leading;
+               leading += m_def->m_font->get_leading() * scale;
 
-                       float   shift_right = 0.0f;
+               int     last_code = -1;
+               int     last_space_glyph = -1;
+               int     last_line_start_record = 0;
 
-                       if (align == edit_text_character_def::ALIGN_LEFT)
-                       {
-                               // Nothing to do; already aligned left.
-                               return;
-                       }
-                       else if (align == edit_text_character_def::ALIGN_CENTER)
-                       {
-                               // Distribute the space evenly on both sides.
-                               shift_right = extra_space / 2;
-                       }
-                       else if (align == edit_text_character_def::ALIGN_RIGHT)
+               const char*     text = &m_text[0];
+               while (Uint32 code = utf8::decode_next_unicode_character(&text))
+               {
+// @@ try to truncate overflow text??
+#if 0
+                       if (y + m_def->m_font->get_descent() * scale > 
m_def->m_rect.height())
                        {
-                               // Shift all the way to the right.
-                               shift_right = extra_space;
+                               // Text goes below the bottom of our bounding 
box.
+                               rec.m_glyphs.resize(0);
+                               break;
                        }
+#endif // 0
 
-                       // Shift the beginnings of the records on this line.
-                       for (int i = last_line_start_record; i < 
m_text_glyph_records.size(); i++)
-                       {
-                               text_glyph_record&      rec = 
m_text_glyph_records[i];
+                       //Uint16        code = m_text[j];
 
-                               if (rec.m_style.m_has_x_offset)
-                               {
-                                       rec.m_style.m_x_offset += shift_right;
-                               }
-                       }
-               }
+                       x += m_def->m_font->get_kerning_adjustment(last_code, 
(int) code) * scale;
+                       last_code = (int) code;
 
-               // Convert the characters in m_text into a series of
-               // text_glyph_records to be rendered.
-               void    format_text()
-               {
-                       m_text_glyph_records.resize(0);
+                       // 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 + 
m_def->m_font->get_descent() * scale);
 
-                       if (m_def->m_font == NULL)
+                       if (code == 13 || code == 10)
                        {
-                               return;
-                       }
+                               // newline.
 
-                       // @@ mostly for debugging
-                       // Font substitution -- if the font has no
-                       // glyphs, try some other defined font!
-                       if (m_def->m_font->get_glyph_count() == 0)
-                       {
-                               // Find a better font.
-                               font*   newfont = m_def->m_font;
-                               for (int i = 0, n = fontlib::get_font_count(); 
i < n; i++)
-                               {
-                                       font*   f = fontlib::get_font(i);
-                                       assert(f);
+                               // Frigging Flash seems to use '\r' (13) as its
+                               // default newline character.  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.
 
-                                       if (f->get_glyph_count() > 0)
-                                       {
-                                               // This one looks good.
-                                               newfont = f;
-                                               break;
-                                       }
-                               }
+                               // Close out this stretch of glyphs.
+                               m_text_glyph_records.push_back(rec);
+                               align_line(m_def->m_alignment, 
last_line_start_record, x);
 
-                               if (m_def->m_font != newfont)
-                               {
-                                       log_error("error: substituting font!  
font '%s' has no glyphs, using font '%s'\n",
-                                                 
fontlib::get_font_name(m_def->m_font),
-                                                 
fontlib::get_font_name(newfont));
-
-                                       m_def->m_font = newfont;
-                               }
-                       }
+                               x = fmax(0, m_def->m_left_margin + 
m_def->m_indent);    // new paragraphs get the indent.
+                               y += m_def->m_text_height + leading;
 
+                               // Start a new record on the next line.
+                               rec.m_glyphs.resize(0);
+                               rec.m_style.m_font = m_def->m_font;
+                               rec.m_style.m_color = m_def->m_color;
+                               rec.m_style.m_x_offset = x;
+                               rec.m_style.m_y_offset = y;
+                               rec.m_style.m_text_height = 
m_def->m_text_height;
+                               rec.m_style.m_has_x_offset = true;
+                               rec.m_style.m_has_y_offset = true;
 
-                       float   scale = m_def->m_text_height / 1024.0f; // the 
EM square is 1024 x 1024
+                               last_space_glyph = -1;
+                               last_line_start_record = 
m_text_glyph_records.size();
 
-                       text_glyph_record       rec;    // one to work on
-                       rec.m_style.m_font = m_def->m_font;
-                       rec.m_style.m_color = m_def->m_color;
-                       rec.m_style.m_x_offset = fmax(0, m_def->m_left_margin + 
m_def->m_indent);
-                       rec.m_style.m_y_offset = m_def->m_text_height
-                               + (m_def->m_font->get_leading() - 
m_def->m_font->get_descent()) * scale;
-                       rec.m_style.m_text_height = m_def->m_text_height;
-                       rec.m_style.m_has_x_offset = true;
-                       rec.m_style.m_has_y_offset = true;
-
-                       float   x = rec.m_style.m_x_offset;
-                       float   y = rec.m_style.m_y_offset;
-
-                       // Start the bbox at the upper-left corner of the first 
glyph.
-                       reset_bounding_box(x, y - m_def->m_font->get_descent() 
* scale + m_def->m_text_height);
-
-                       float   leading = m_def->m_leading;
-                       leading += m_def->m_font->get_leading() * scale;
-
-                       int     last_code = -1;
-                       int     last_space_glyph = -1;
-                       int     last_line_start_record = 0;
+                               continue;
+                       }
 
-                       const char*     text = &m_text[0];
-                       while (Uint32 code = 
utf8::decode_next_unicode_character(&text))
+                       if (code == 8)
                        {
-// @@ try to truncate overflow text??
-#if 0
-                               if (y + m_def->m_font->get_descent() * scale > 
m_def->m_rect.height())
-                               {
-                                       // Text goes below the bottom of our 
bounding box.
-                                       rec.m_glyphs.resize(0);
-                                       break;
-                               }
-#endif // 0
+                               // backspace (ASCII BS).
 
-                               //Uint16        code = m_text[j];
+                               // This is a limited hack to enable overstrike 
effects.
+                               // It backs the cursor up by one character 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 character.
+                               //
+                               // ONLY WORKS FOR BACKSPACING OVER ONE 
CHARACTER, WON'T BS
+                               // OVER NEWLINES, ETC.
 
-                               x += 
m_def->m_font->get_kerning_adjustment(last_code, (int) code) * scale;
-                               last_code = (int) code;
+                               if (rec.m_glyphs.size() > 0)
+                               {
+                                       // Peek at the previous glyph, and zero 
out its advance
+                                       // value, so the next char overwrites 
it.
+                                       float   advance = 
rec.m_glyphs.back().m_glyph_advance;
+                                       x -= advance;   // maintain formatting
+                                       rec.m_glyphs.back().m_glyph_advance = 
0;        // do the BS effect
+                               }
+                               continue;
+                       }
 
-                               // 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 + 
m_def->m_font->get_descent() * scale);
+                       // Remember where word breaks occur.
+                       if (code == 32)
+                       {
+                               last_space_glyph = rec.m_glyphs.size();
+                       }
 
-                               if (code == 13 || code == 10)
+                       int     index = m_def->m_font->get_glyph_index((Uint16) 
code);
+                       if (index == -1)
+                       {
+                               // error -- missing glyph!
+                               
+                               // Log an error, but don't log too many times.
+                               static int      s_log_count = 0;
+                               if (s_log_count < 10)
                                {
-                                       // newline.
+                                       s_log_count++;
+                                       
log_error("edit_text_character::display() -- missing glyph for char %d "
+                                                 "-- make sure character 
shapes for font %s are being exported "
+                                                 "into your SWF file!\n",
+                                                 code,
+                                                 m_def->m_font->get_name());
+                               }
 
-                                       // Frigging Flash seems to use '\r' 
(13) as its
-                                       // default newline character.  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.
-                                       m_text_glyph_records.push_back(rec);
-                                       align_line(m_def->m_alignment, 
last_line_start_record, x);
-
-                                       x = fmax(0, m_def->m_left_margin + 
m_def->m_indent);    // new paragraphs get the indent.
-                                       y += m_def->m_text_height + leading;
-
-                                       // Start a new record on the next line.
-                                       rec.m_glyphs.resize(0);
-                                       rec.m_style.m_font = m_def->m_font;
-                                       rec.m_style.m_color = m_def->m_color;
-                                       rec.m_style.m_x_offset = x;
-                                       rec.m_style.m_y_offset = y;
-                                       rec.m_style.m_text_height = 
m_def->m_text_height;
-                                       rec.m_style.m_has_x_offset = true;
-                                       rec.m_style.m_has_y_offset = true;
+                               // Drop through and use index == -1; this will 
display
+                               // using the empty-box glyph
+                       }
+                       text_glyph_record::glyph_entry  ge;
+                       ge.m_glyph_index = index;
+                       ge.m_glyph_advance = scale * 
m_def->m_font->get_advance(index);
 
-                                       last_space_glyph = -1;
-                                       last_line_start_record = 
m_text_glyph_records.size();
+                       rec.m_glyphs.push_back(ge);
 
-                                       continue;
-                               }
+                       x += ge.m_glyph_advance;
 
-                               if (code == 8)
-                               {
-                                       // backspace (ASCII BS).
+                       
+                       if (x >= m_def->m_rect.width() - m_def->m_right_margin 
- WIDTH_FUDGE)
+                       {
+                               // Whoops, we just exceeded the box width.  Do 
word-wrap.
 
-                                       // This is a limited hack to enable 
overstrike effects.
-                                       // It backs the cursor up by one 
character 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 character.
-                                       //
-                                       // ONLY WORKS FOR BACKSPACING OVER ONE 
CHARACTER, WON'T BS
-                                       // OVER NEWLINES, ETC.
+                               // Insert newline.
 
-                                       if (rec.m_glyphs.size() > 0)
-                                       {
-                                               // Peek at the previous glyph, 
and zero out its advance
-                                               // value, so the next char 
overwrites it.
-                                               float   advance = 
rec.m_glyphs.back().m_glyph_advance;
-                                               x -= advance;   // maintain 
formatting
-                                               
rec.m_glyphs.back().m_glyph_advance = 0;        // do the BS effect
-                                       }
-                                       continue;
-                               }
+                               // Close out this stretch of glyphs.
+                               m_text_glyph_records.push_back(rec);
+                               float   previous_x = x;
 
-                               // Remember where word breaks occur.
-                               if (code == 32)
-                               {
-                                       last_space_glyph = rec.m_glyphs.size();
-                               }
+                               x = m_def->m_left_margin;
+                               y += m_def->m_text_height + leading;
 
-                               int     index = 
m_def->m_font->get_glyph_index((Uint16) code);
-                               if (index == -1)
+                               // Start a new record on the next line.
+                               rec.m_glyphs.resize(0);
+                               rec.m_style.m_font = m_def->m_font;
+                               rec.m_style.m_color = m_def->m_color;
+                               rec.m_style.m_x_offset = x;
+                               rec.m_style.m_y_offset = y;
+                               rec.m_style.m_text_height = 
m_def->m_text_height;
+                               rec.m_style.m_has_x_offset = true;
+                               rec.m_style.m_has_y_offset = true;
+                               
+                               text_glyph_record&      last_line = 
m_text_glyph_records.back();
+                               if (last_space_glyph == -1)
                                {
-                                       // error -- missing glyph!
-                                       
-                                       // Log an error, but don't log too many 
times.
-                                       static int      s_log_count = 0;
-                                       if (s_log_count < 10)
+                                       // Pull the previous glyph down onto the
+                                       // new line.
+                                       if (last_line.m_glyphs.size() > 0)
                                        {
-                                               s_log_count++;
-                                               
log_error("edit_text_character::display() -- missing glyph for char %d "
-                                                         "-- make sure 
character shapes for font %s are being exported "
-                                                         "into your SWF 
file!\n",
-                                                         code,
-                                                         
m_def->m_font->get_name());
+                                               
rec.m_glyphs.push_back(last_line.m_glyphs.back());
+                                               x += 
last_line.m_glyphs.back().m_glyph_advance;
+                                               previous_x -= 
last_line.m_glyphs.back().m_glyph_advance;
+                                               
last_line.m_glyphs.resize(last_line.m_glyphs.size() - 1);
                                        }
-
-                                       // Drop through and use index == -1; 
this will display
-                                       // using the empty-box glyph
                                }
-                               text_glyph_record::glyph_entry  ge;
-                               ge.m_glyph_index = index;
-                               ge.m_glyph_advance = scale * 
m_def->m_font->get_advance(index);
-
-                               rec.m_glyphs.push_back(ge);
-
-                               x += ge.m_glyph_advance;
-
-                               
-                               if (x >= m_def->m_rect.width() - 
m_def->m_right_margin - WIDTH_FUDGE)
+                               else
                                {
-                                       // Whoops, we just exceeded the box 
width.  Do word-wrap.
+                                       // Move the previous word down onto the 
next line.
 
-                                       // Insert newline.
+                                       previous_x -= 
last_line.m_glyphs[last_space_glyph].m_glyph_advance;
 
-                                       // Close out this stretch of glyphs.
-                                       m_text_glyph_records.push_back(rec);
-                                       float   previous_x = x;
-
-                                       x = m_def->m_left_margin;
-                                       y += m_def->m_text_height + leading;
-
-                                       // Start a new record on the next line.
-                                       rec.m_glyphs.resize(0);
-                                       rec.m_style.m_font = m_def->m_font;
-                                       rec.m_style.m_color = m_def->m_color;
-                                       rec.m_style.m_x_offset = x;
-                                       rec.m_style.m_y_offset = y;
-                                       rec.m_style.m_text_height = 
m_def->m_text_height;
-                                       rec.m_style.m_has_x_offset = true;
-                                       rec.m_style.m_has_y_offset = true;
-                                       
-                                       text_glyph_record&      last_line = 
m_text_glyph_records.back();
-                                       if (last_space_glyph == -1)
+                                       for (int i = last_space_glyph + 1; i < 
last_line.m_glyphs.size(); i++)
                                        {
-                                               // Pull the previous glyph down 
onto the
-                                               // new line.
-                                               if (last_line.m_glyphs.size() > 
0)
-                                               {
-                                                       
rec.m_glyphs.push_back(last_line.m_glyphs.back());
-                                                       x += 
last_line.m_glyphs.back().m_glyph_advance;
-                                                       previous_x -= 
last_line.m_glyphs.back().m_glyph_advance;
-                                                       
last_line.m_glyphs.resize(last_line.m_glyphs.size() - 1);
-                                               }
+                                               
rec.m_glyphs.push_back(last_line.m_glyphs[i]);
+                                               x += 
last_line.m_glyphs[i].m_glyph_advance;
+                                               previous_x -= 
last_line.m_glyphs[i].m_glyph_advance;
                                        }
-                                       else
-                                       {
-                                               // Move the previous word down 
onto the next line.
-
-                                               previous_x -= 
last_line.m_glyphs[last_space_glyph].m_glyph_advance;
-
-                                               for (int i = last_space_glyph + 
1; i < last_line.m_glyphs.size(); i++)
-                                               {
-                                                       
rec.m_glyphs.push_back(last_line.m_glyphs[i]);
-                                                       x += 
last_line.m_glyphs[i].m_glyph_advance;
-                                                       previous_x -= 
last_line.m_glyphs[i].m_glyph_advance;
-                                               }
-                                               
last_line.m_glyphs.resize(last_space_glyph);
-                                       }
-
-                                       align_line(m_def->m_alignment, 
last_line_start_record, previous_x);
-
-                                       last_space_glyph = -1;
-                                       last_line_start_record = 
m_text_glyph_records.size();
+                                       
last_line.m_glyphs.resize(last_space_glyph);
                                }
 
-                               // TODO: HTML markup
+                               align_line(m_def->m_alignment, 
last_line_start_record, previous_x);
+
+                               last_space_glyph = -1;
+                               last_line_start_record = 
m_text_glyph_records.size();
                        }
 
-                       // Add this line to our output.
-                       m_text_glyph_records.push_back(rec);
-                       align_line(m_def->m_alignment, last_line_start_record, 
x);
+                       // TODO: HTML markup
                }
 
+               // Add this line to our output.
+               m_text_glyph_records.push_back(rec);
+               align_line(m_def->m_alignment, last_line_start_record, x);
+       }
 
-               void    display()
-               // Draw the dynamic string.
+       void
+       edit_text_character::display()
+       {
+               if (m_def->m_border)
                {
-                       if (m_def->m_border)
-                       {
-                               matrix  mat = get_world_matrix();
-                               
-                               // @@ hm, should we apply the color xform?  It 
seems logical; need to test.
-                               // cxform       cx = get_world_cxform();
+                       matrix  mat = get_world_matrix();
+                       
+                       // @@ hm, should we apply the color xform?  It seems 
logical; need to test.
+                       // cxform       cx = get_world_cxform();
+
+                       // Show white background + black bounding box.
+                       render::set_matrix(mat);
+
+                       point   coords[4];
+                       coords[0] = m_def->m_rect.get_corner(0);
+                       coords[1] = m_def->m_rect.get_corner(1);
+                       coords[2] = m_def->m_rect.get_corner(3);
+                       coords[3] = m_def->m_rect.get_corner(2);
+
+                       Sint16  icoords[18] = 
+                       {
+                               // strip (fill in)
+                               (Sint16) coords[0].m_x, (Sint16) coords[0].m_y,
+                               (Sint16) coords[1].m_x, (Sint16) coords[1].m_y,
+                               (Sint16) coords[2].m_x, (Sint16) coords[2].m_y,
+                               (Sint16) coords[3].m_x, (Sint16) coords[3].m_y,
+
+                               // outline
+                               (Sint16) coords[0].m_x, (Sint16) coords[0].m_y,
+                               (Sint16) coords[1].m_x, (Sint16) coords[1].m_y,
+                               (Sint16) coords[3].m_x, (Sint16) coords[3].m_y,
+                               (Sint16) coords[2].m_x, (Sint16) coords[2].m_y,
+                               (Sint16) coords[0].m_x, (Sint16) coords[0].m_y,
+                       };
+                       
+                       render::fill_style_color(0, rgba(255, 255, 255, 255));
+                       render::draw_mesh_strip(&icoords[0], 4);
 
-                               // Show white background + black bounding box.
-                               render::set_matrix(mat);
-
-                               point   coords[4];
-                               coords[0] = m_def->m_rect.get_corner(0);
-                               coords[1] = m_def->m_rect.get_corner(1);
-                               coords[2] = m_def->m_rect.get_corner(3);
-                               coords[3] = m_def->m_rect.get_corner(2);
-
-                               Sint16  icoords[18] = 
-                               {
-                                       // strip (fill in)
-                                       (Sint16) coords[0].m_x, (Sint16) 
coords[0].m_y,
-                                       (Sint16) coords[1].m_x, (Sint16) 
coords[1].m_y,
-                                       (Sint16) coords[2].m_x, (Sint16) 
coords[2].m_y,
-                                       (Sint16) coords[3].m_x, (Sint16) 
coords[3].m_y,
-
-                                       // outline
-                                       (Sint16) coords[0].m_x, (Sint16) 
coords[0].m_y,
-                                       (Sint16) coords[1].m_x, (Sint16) 
coords[1].m_y,
-                                       (Sint16) coords[3].m_x, (Sint16) 
coords[3].m_y,
-                                       (Sint16) coords[2].m_x, (Sint16) 
coords[2].m_y,
-                                       (Sint16) coords[0].m_x, (Sint16) 
coords[0].m_y,
-                               };
-                               
-                               render::fill_style_color(0, rgba(255, 255, 255, 
255));
-                               render::draw_mesh_strip(&icoords[0], 4);
-
-                               render::line_style_color(rgba(0,0,0,255));
-                               render::draw_line_strip(&icoords[8], 5);
-                       }
+                       render::line_style_color(rgba(0,0,0,255));
+                       render::draw_line_strip(&icoords[8], 5);
+               }
 
-                       // Draw our actual text.
-                       display_glyph_records(matrix::identity, this, 
m_text_glyph_records, m_def->m_root_def);
+               // Draw our actual text.
+               display_glyph_records(matrix::identity, this, 
m_text_glyph_records, m_def->m_root_def);
 
-                       do_display_callback();
-               }
-       };
+               do_display_callback();
+       }
 
+       //
+       // edit_text_character_def
+       //
 
        character*      
edit_text_character_def::create_character_instance(movie* parent, int id)
        {
Index: gnash/server/text.h
diff -u gnash/server/text.h:1.1 gnash/server/text.h:1.2
--- gnash/server/text.h:1.1     Sun Jan 29 10:19:51 2006
+++ gnash/server/text.h Tue Jan 31 16:45:38 2006
@@ -22,6 +22,9 @@
 #ifndef GNASH_TEXT_H
 #define GNASH_TEXT_H
 
+#include "textformat.h" // maybe we should include it here
+#include "styles.h" 
+
 namespace gnash {
 
        // Forward declarations
@@ -100,6 +103,220 @@
 
        };
 
+       /// \brief
+       /// A definition for a text display character, whose text can
+       /// be changed at runtime (by script or host).
+       /// This object is defined by SWF tag 37.
+       ///
+       struct edit_text_character_def : public character_def
+       {
+               movie_definition_sub*   m_root_def;
+               rect                    m_rect;
+               tu_string               m_default_name;
+               text_format             m_format;
+               bool                    m_word_wrap;
+               bool                    m_multiline;
+               /// show asterisks instead of actual characters
+               bool                    m_password;
+               bool                    m_readonly;
+               /// resize our bound to fit the text
+               bool                    m_auto_size;
+               bool                    m_no_select;
+
+               /// forces white background and black border.
+               /// silly, but sometimes used
+               bool                    m_border;
+
+               /// Allowed HTML (from Alexi's SWF Reference).
+               //
+               /// <a href=url target=targ>...</a> -- hyperlink
+               /// <b>...</b> -- bold
+               /// <br> -- line break
+               /// <font face=name size=[+|-][0-9]+ color=#RRGGBB>...</font>  
-- font change; size in TWIPS
+               /// <i>...</i> -- italic
+               /// <li>...</li> -- list item
+               /// <p>...</p> -- paragraph
+               /// <tab> -- insert tab
+               /// <TEXTFORMAT>  </TEXTFORMAT>
+               ///   [ BLOCKINDENT=[0-9]+ ]
+               ///   [ INDENT=[0-9]+ ]
+               ///   [ LEADING=[0-9]+ ]
+               ///   [ LEFTMARGIN=[0-9]+ ]
+               ///   [ RIGHTMARGIN=[0-9]+ ]
+               ///   [ TABSTOPS=[0-9]+{,[0-9]+} ]
+               ///
+               /// Change the different parameters as indicated. The
+               /// sizes are all in TWIPs. There can be multiple
+               /// positions for the tab stops. These are seperated by
+               /// commas.
+               /// <U>...</U> -- underline
+               ///
+               bool                    m_html;
+
+
+
+               /// \brief
+               /// When true, use specified SWF internal font. 
+               /// Otherwise, renderer picks a default font
+               bool    m_use_outlines;
+
+               int     m_font_id;
+               font*   m_font;
+               float   m_text_height;
+
+               rgba    m_color;
+               int     m_max_length;
+
+               enum alignment
+               {
+                       ALIGN_LEFT = 0,
+                       ALIGN_RIGHT,
+                       ALIGN_CENTER,
+                       /// probably don't need to implement...
+                       ALIGN_JUSTIFY
+               };
+               alignment       m_alignment;
+               
+               /// extra space between box border and text
+               float   m_left_margin;
+
+               float   m_right_margin;
+
+               /// how much to indent the first line of multiline text
+               float   m_indent;
+
+               /// \brief
+               /// Extra space between lines
+               /// (in addition to default font line spacing)
+               float   m_leading;
+               tu_string       m_default_text;
+
+               edit_text_character_def(movie_definition_sub* root_def)
+                       :
+                       m_root_def(root_def),
+                       m_word_wrap(false),
+                       m_multiline(false),
+                       m_password(false),
+                       m_readonly(false),
+                       m_auto_size(false),
+                       m_no_select(false),
+                       m_border(false),
+                       m_html(false),
+                       m_use_outlines(false),
+                       m_font_id(-1),
+                       m_font(NULL),
+                       m_text_height(1.0f),
+                       m_max_length(0),
+                       m_alignment(ALIGN_LEFT),
+                       m_left_margin(0.0f),
+                       m_right_margin(0.0f),
+                       m_indent(0.0f),
+                       m_leading(0.0f)
+               {
+                       assert(m_root_def);
+
+                       m_color.set(0, 0, 0, 255);
+               }
+
+               /// Set the format of the text
+               void    set_format(text_format &format)
+               {
+                       m_format = format;
+               }
+               
+               ~edit_text_character_def()
+               {
+               }
+
+
+               character* create_character_instance(movie* parent, int id);
+
+
+               /// Initialize from SWF input stream (tag 37)
+               void read(stream* in, int tag_type, movie_definition_sub* m);
+       };
+
+       /// ...
+       struct edit_text_character : public character
+       {
+               edit_text_character_def*        m_def;
+               array<text_glyph_record>        m_text_glyph_records;
+
+               /// used to pass a color on to shape_character::display()
+               array<fill_style>       m_dummy_style;
+
+               array<line_style>       m_dummy_line_style;
+
+               /// bounds of dynamic text, as laid out
+               rect    m_text_bounding_box;
+
+               tu_string       m_text;
+
+               edit_text_character(movie* parent, edit_text_character_def* 
def, int id)
+                       :
+                       character(parent, id),
+                       m_def(def)
+               {
+                       assert(parent);
+                       assert(m_def);
+
+                       set_text_value(m_def->m_default_text.c_str());
+
+                       m_dummy_style.push_back(fill_style());
+
+                       reset_bounding_box(0, 0);
+               }
+
+               ~edit_text_character()
+               {
+               }
+
+               virtual const char* get_text_name() const { return 
m_def->m_default_name.c_str(); }
+
+
+               /// Reset our text bounding box to the given point.
+               void    reset_bounding_box(float x, float y)
+               {
+                       m_text_bounding_box.m_x_min = x;
+                       m_text_bounding_box.m_x_max = x;
+                       m_text_bounding_box.m_y_min = y;
+                       m_text_bounding_box.m_y_max = y;
+               }
+
+
+               /// Set our text to the given string.
+               virtual void    set_text_value(const char* new_text);
+
+               virtual const char*     get_text_value() const
+               {
+                       return m_text.c_str();
+               }
+
+
+               /// We have a "text" member.
+               void set_member(const tu_stringi& name, const as_value& val);
+
+
+               bool get_member(const tu_stringi& name, as_value* val);
+
+
+               /// 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.
+               void align_line(edit_text_character_def::alignment align,
+                               int last_line_start_record, float x);
+
+
+               /// Convert the characters in m_text into a series of
+               /// text_glyph_records to be rendered.
+               void    format_text();
+
+
+               /// Draw the dynamic string.
+               void    display();
+       };
+
 } // namespace gnash
 
 #endif // GNASH_TEXT_H
Index: gnash/server/textformat.h
diff -u gnash/server/textformat.h:1.2 gnash/server/textformat.h:1.3
--- gnash/server/textformat.h:1.2       Thu Jan 19 23:50:11 2006
+++ gnash/server/textformat.h   Tue Jan 31 16:45:38 2006
@@ -27,87 +27,156 @@
 
 namespace gnash {  
 
+/// new text_format([font, [size, [color, [bold, [italic, [underline, [url, 
[target, [align,[leftMargin, [rightMargin, [indent, [leading]]]]]]]]]]]]])
 class text_format
 {
 public:
-  // new text_format([font, [size, [color, [bold, [italic, [underline, [url, 
[target, [align,
-  //                [leftMargin, [rightMargin, [indent, [leading]]]]]]]]]]]]])
   
-  text_format();
-  // tulrich: TODO need to take const ref!
-  text_format(tu_string font);
-  text_format(tu_string font, int size);
-  text_format(tu_string font, int size, int color);
-  ~text_format();
+       text_format();
+       // tulrich: TODO need to take const ref!
+       text_format(tu_string font);
+       text_format(tu_string font, int size);
+       text_format(tu_string font, int size, int color);
+       ~text_format();
   
-  bool underlined()  { return _underline; }
-  bool italiced()    { return _italic; }
-  bool bold()        { return _bold; }
-  bool bullet()      { return _bullet; }
-  uint32 color() const { return _color; }
-  float indent() const { return _indent; }
-  const tu_string& align() const { return _align; }
-  float blockIndent() { return _block_indent; }
-  float leading()     { return _leading; }
-  float leftMargin()  { return _left_margin; }
-  float RightMargin() { return _right_margin; }
-  float size()        { return _point_size; }
-
-  void underlinedSet(bool x)   { _underline = x; }
-  void italicedSet(bool x)     { _italic = x; }
-  void boldSet(bool x)         { _bold = x; }
-  void bulletSet(bool x)       { _bullet = x; }
-  void colorSet(uint32 x)      { _color = x; }
-  void indentSet(float x)      { _indent = x; }
-  void alignSet(tu_string x)  { _align = x; }
-  void blockIndentSet(float x)   { _block_indent = x; }
-  void leadingSet(float x)     { _leading = x; }
-  void leftMarginSet(float x)  { _left_margin = x; }
-  void rightMarginSet(float x) { _right_margin = x; }
-  void sizeSet(float x)        { _point_size = x; }
-
-  // In a paragraph, change the format of a range of characters.
-  void setTextFormat (text_format &format);
-  void setTextFormat (int index, text_format &format);
-  void setTextFormat (int start, int end, text_format &format);
-
-  text_format &getTextFormat ();
-  text_format &getTextFormat (int index);
-  text_format &getTextFormat (int start, int end);
+       /// Return a Boolean value that indicates whether the text is 
underlined.
+       bool underlined()  { return _underline; }
 
-  int getTextExtant();
-  text_format *operator = (text_format &format);
+       /// Return a Boolean value that indicates whether the text is 
italicized.
+       bool italiced()    { return _italic; }
+
+       /// Return a Boolean value that indicates whether the text is boldface.
+       bool bold()        { return _bold; }
+
+       bool bullet()      { return _bullet; }
+
+       /// Return the color of text using this text format.
+       //
+       /// A number containing three 8-bit RGB components; for example,
+        /// 0xFF0000 is red, 0x00FF00 is green.
+       uint32 color() const { return _color; }
+
+       /// \brief
+       /// Return ann integer that indicates the indentation from the left
+        /// margin to the first character in the paragraph
+       float indent() const { return _indent; }
+
+       /// Return the alignment of the paragraph, represented as a string.
+       //
+       /// If "left", the paragraph is left-aligned. If "center", the
+       /// paragraph is centered. If "right", the paragraph is
+       /// right-aligned.
+       ///
+       const tu_string& align() const { return _align; }
+
+       /// Return the name of a font for text as a string.
+       const tu_string& font() const { return _font; }
+
+       ///
+       float blockIndent() { return _block_indent; }
+
+       /// Return a number that indicates the amount of leading vertical
+       /// space between lines.
+       float leading()     { return _leading; }
+
+       /// Indicates the left margin of the paragraph, in points.
+       float leftMargin()  { return _left_margin; }
+
+       /// Indicates the right margin of the paragraph, in points.
+       float RightMargin() { return _right_margin; }
+
+       /// Return a float that indicates the point size.
+       float size()        { return _point_size; }
+
+       void underlinedSet(bool x)   { _underline = x; }
+       void italicedSet(bool x)     { _italic = x; }
+       void boldSet(bool x)         { _bold = x; }
+       void bulletSet(bool x)       { _bullet = x; }
+       void colorSet(uint32 x)      { _color = x; }
+       void indentSet(float x)      { _indent = x; }
+       void alignSet(tu_string x)  { _align = x; }
+       void blockIndentSet(float x)   { _block_indent = x; }
+       void leadingSet(float x)     { _leading = x; }
+       void leftMarginSet(float x)  { _left_margin = x; }
+       void rightMarginSet(float x) { _right_margin = x; }
+       void sizeSet(float x)        { _point_size = x; }
+
+       // In a paragraph, change the format of a range of characters.
+       void setTextFormat (text_format &format);
+       void setTextFormat (int index, text_format &format);
+       void setTextFormat (int start, int end, text_format &format);
+
+       text_format &getTextFormat ();
+       text_format &getTextFormat (int index);
+       text_format &getTextFormat (int start, int end);
+
+       int getTextExtant();
+       text_format *operator = (text_format &format);
   
  private:
-  bool          _underline;    // A Boolean value that indicates whether the 
text is underlined.
-  bool          _bold;         // A Boolean value that indicates whether the 
text is boldface.
-  bool          _italic;       // A Boolean value that indicates whether the 
text is italicized.
-  bool          _bullet;       // 
+       /// A Boolean value that indicates whether the text is underlined.
+       bool          _underline;
+
+       /// A Boolean value that indicates whether the text is boldface.
+       bool          _bold;    
+
+       /// A Boolean value that indicates whether the text is italicized.
+       bool          _italic;
+
+       // 
+       bool          _bullet;
   
-  tu_string     _align;        // The alignment of the paragraph, represented 
as a string.
-                                // If "left", the paragraph is left-aligned. 
If "center", the
-                                // paragraph is centered. If "right", the 
paragraph is
-                                // right-aligned.
-  float                _block_indent;  // 
-  uint32       _color;         // The color of text using this text format. A 
number
-                                // containing three 8-bit RGB components; for 
example,
-                                // 0xFF0000 is red, 0x00FF00 is green.
-  tu_string _font;             // The name of a font for text as a string.
-  float                _indent;        // An integer that indicates the 
indentation from the left
-                                // margin to the first character in the 
paragraph
-  float                _leading;       // A number that indicates the amount 
of leading vertical
-                                // space between lines.
-  float                _left_margin;   // Indicates the left margin of the 
paragraph, in points.
-  float                _right_margin;  // Indicates the right margin of the 
paragraph, in points.
-  float                _point_size;    // An integer that indicates the point 
size.
-  int          _tab_stops;     // 
-  int          _target;        // The target window where the hyperlink is 
displayed. If the
-                                // target window is an empty string, the text 
is displayed in
-                                // the default target window _self. If the url 
parameter is
-                                // set to an empty string or to the value 
null, you can get
-                                // or set this property, but the property will 
have no effect.
-  tu_string     _url;          // The URL to which the text in this text 
format hyperlinks.
-                                // If url is an empty string, the text does 
not have a hyperlink
+       /// The alignment of the paragraph, represented as a string.
+       //
+       /// If "left", the paragraph is left-aligned. If "center", the
+       /// paragraph is centered. If "right", the paragraph is
+       /// right-aligned.
+       ///
+       tu_string        _align;
+
+       // 
+       float           _block_indent;
+
+       /// The color of text using this text format.
+       //
+       /// A number containing three 8-bit RGB components; for example,
+        /// 0xFF0000 is red, 0x00FF00 is green.
+       uint32  _color; 
+
+       // The name of a font for text as a string.
+       tu_string _font;        
+
+       /// An integer that indicates the indentation from the left
+        /// margin to the first character in the paragraph
+       float           _indent;
+
+       /// A number that indicates the amount of leading vertical
+       /// space between lines.
+       float           _leading;
+
+       /// Indicates the left margin of the paragraph, in points.
+       float           _left_margin;
+
+       /// Indicates the right margin of the paragraph, in points.
+       float           _right_margin;
+
+       /// An float that indicates the point size.
+       float           _point_size;
+
+       ///
+       int             _tab_stops;
+
+       /// The target window where the hyperlink is displayed. 
+        /// If the target window is an empty string, the text is displayed in
+        /// the default target window _self. If the url parameter is
+        /// set to an empty string or to the value null, you can get
+        /// or set this property, but the property will have no effect.
+       int             _target;
+
+       /// The URL to which the text in this text format hyperlinks.
+       /// If url is an empty string, the text does not have a hyperlink
+       tu_string        _url;  
+
 };
  
 struct textformat_as_object : public gnash::as_object
Index: gnash/server/xml.h
diff -u gnash/server/xml.h:1.4 gnash/server/xml.h:1.5
--- gnash/server/xml.h:1.4      Mon Jan 30 17:07:08 2006
+++ gnash/server/xml.h  Tue Jan 31 16:45:38 2006
@@ -382,7 +382,7 @@
     }
     
 #if 1
-       printf("%s(%d): ERROR: as_member::get() unimplemented!", 
__PRETTY_FUNCTION__, __LINE__);
+       printf("%s(%s:%d): ERROR: as_member::get() unimplemented!", 
__PRETTY_FUNCTION__, __FILE__, __LINE__);
 #else
     if (m_members.get(name, val) == false) {
       if (m_prototype != NULL) {




reply via email to

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