gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] /srv/bzr/gnash/trunk r11284: Changes to TextField:


From: Bob Naugle
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r11284: Changes to TextField:
Date: Mon, 20 Jul 2009 10:26:43 -0600
User-agent: Bazaar (1.13.1)

------------------------------------------------------------
revno: 11284
committer: Bob Naugle <address@hidden>
branch nick: trunk
timestamp: Mon 2009-07-20 10:26:43 -0600
message:
  Changes to TextField:
        - New recursive method for inserting text will allow for HTML tags
        - Early code for HTML
modified:
  libcore/TextField.cpp
  libcore/TextField.h
=== modified file 'libcore/TextField.cpp'
--- a/libcore/TextField.cpp     2009-07-16 09:02:35 +0000
+++ b/libcore/TextField.cpp     2009-07-20 16:26:43 +0000
@@ -1075,7 +1075,7 @@
     float leading = getLeading();
     leading += fontLeading * scale; // not sure this is correct...
        
-    int    last_code = -1; // only used if _embedFonts
+       int    last_code = -1; // only used if _embedFonts
     int    last_space_glyph = -1;
     int    last_line_start_record = 0;
        _line_starts.push_back(0);
@@ -1084,8 +1084,6 @@
     m_xcursor = x;
     m_ycursor = y;
     
-    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
@@ -1094,301 +1092,9 @@
     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();
-                                
-                linestartit = _line_starts.begin();
-                               linestartend = _line_starts.end();
-                               //Fit a line_start in the correct place
-                               while ( linestartit < linestartend && 
*linestartit < it-_text.begin())
-                               {
-                                       linestartit++;
-                               }
-                               _line_starts.insert(linestartit, 
it-_text.begin());
-                               break;
-            }
-            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();
-                               
-                               linestartit = _line_starts.begin();
-                               linestartend = _line_starts.end();
-                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);
-                                               //record the new line start
-                                               while ( linestartit != 
linestartend && *linestartit <= (it-_text.begin())-1)
-                                               {
-                                                       linestartit++;
-                                               }
-                                               
_line_starts.insert(linestartit, (it-_text.begin()));
-                    }
-                } 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);
-                                       
-                                       //record the position at the start of 
this line as a line_start
-                                       int linestartpos = 
(it-_text.begin())-rec.glyphs().size();
-                                       while ( linestartit < linestartend && 
*linestartit < linestartpos)
-                                       {
-                                               linestartit++;
-                                       }
-                                       _line_starts.insert(linestartit, 
linestartpos);
-                }
-
-                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 
-            }
-        }
-
-        // TODO: HTML markup
-               
-    }
+    ///handleChar takes care of placing the glyphs
+       handleChar(it, e, x, y, rec, last_code, last_space_glyph, 
last_line_start_record);
+       
     // Expand bounding box to include the whole text (if autoSize)
     if ( _autoSize != autoSizeNone )
     {
@@ -1407,7 +1113,7 @@
        int manylines = _line_starts.size();
        int manyrecords = _textRecords.size();
        SWF::TextRecord cursorposition_line;
-       while(linestartit != linestartend && *linestartit <= m_cursor) {
+       while (linestartit != linestartend && *linestartit <= m_cursor) {
                linestart = *linestartit++;
        }
        current_line = linestartit - _line_starts.begin();
@@ -1416,7 +1122,7 @@
 
        ///ASSIGN THE VISIBLE LINES TO _displayRecord
        int yoffset = _top_visible_line*(fontHeight + leading) + PADDING_TWIPS;
-       for(unsigned int i = 0; i < manyrecords; ++i) {
+       for (unsigned int i = 0; i < manyrecords; ++i) {
                //if the record is in the section we want to show
                if(_textRecords[i].yOffset() - yoffset < defBounds.height() && 
                        _textRecords[i].yOffset() - yoffset > 0) {
@@ -1425,16 +1131,21 @@
                }
        }
        ///POSITION THE CURSOR IN X-DIRECTION
-       if ( current_line <= manyrecords && current_line >= 1) {
-               cursorposition_line = _textRecords[current_line-1];
+       if ( current_line <= manylines && current_line >= 1) {
+               float lineposition = (current_line * (fontHeight + leading)) + 
PADDING_TWIPS;
+               for (unsigned int i = current_line - 1; i < manyrecords && 
_textRecords[i].yOffset() == lineposition; ++i) {
+                       cursorposition_line = _textRecords[i];
+                       linestart += _textRecords[i].glyphs().size();
+               }
+               m_xcursor = cursorposition_line.xOffset();
                //extra checks keep MemCheck happy!
-               for ( unsigned int i = linestart; i < m_cursor && i < 
cursorposition_line.glyphs().size(); ++i ) {
+               for (unsigned int i = linestart; i < m_cursor && i-linestart < 
cursorposition_line.glyphs().size(); ++i) {
                        m_xcursor += 
cursorposition_line.glyphs()[i-linestart].advance;
                }
        }
        ///POSITION THE CURSOR IN Y-DIRECTION
        m_ycursor = PADDING_TWIPS - _top_visible_line*(fontHeight + leading);
-       if(current_line >= 0) {
+       if (current_line >= 0) {
                for(unsigned int i = 0; i < current_line-1; ++i) {
                        m_ycursor += (fontHeight+leading);
                }
@@ -1468,6 +1179,387 @@
        }
 }
 
+void
+TextField::handleChar(std::wstring::const_iterator& it, const 
std::wstring::const_iterator& e,
+       boost::int32_t& x, boost::int32_t& y, SWF::TextRecord& rec, int& 
last_code, int& last_space_glyph,
+       int& last_line_start_record)
+{
+       std::vector<int>::iterator linestartit = _line_starts.begin();
+       std::vector<int>::const_iterator linestartend = _line_starts.end();
+       
+       float scale = _fontHeight / (float)_font->unitsPerEM(_embedFonts); 
+    float fontDescent = _font->descent() * scale; 
+    float fontLeading = _font->leading() * scale;
+       float leading = getLeading();
+    leading += fontLeading * scale; // not sure this is correct...
+       
+       boost::uint32_t code = 0;
+       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);
+                               ///THIS IS WHERE SHARAD'S TABSTOBS WILL GO
+                               break;
+                       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 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(getTextAlignment(), 
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, getLeftMargin() + getIndent()) 
+ PADDING_TWIPS;
+                               y += getFontHeight() + 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();
+                                
+                               linestartit = _line_starts.begin();
+                               linestartend = _line_starts.end();
+                               //Fit a line_start in the correct place
+                               while ( linestartit < linestartend && 
*linestartit < it-_text.begin())
+                               {
+                                       linestartit++;
+                               }
+                               _line_starts.insert(linestartit, 
it-_text.begin());
+                               break;
+                       }
+                       case '<':
+                               if (doHtml())
+                               {
+                                       //close out this stretch of glyphs
+                                       _textRecords.push_back(rec);
+                                       if (*it == '\\') {
+                                               while (it != e && *it != '>') {
+                                                       ++it;
+                                               }
+                                               ++it;
+                                               return;
+                                       }
+                                       rec.clearGlyphs();
+                                       LOG_ONCE(log_debug(_("HTML in a text 
field is unsupported, "
+                                                                               
 "gnash will just ignore the tags and "
+                                                                               
 "print their content")));
+                
+                                       std::wstring discard;
+                                       SWF::TextRecord newrec;
+                                       newrec.setFont(rec.getFont());
+                                       newrec.setUnderline(rec.underline());
+                                       newrec.setColor(rec.color()); 
+                                       newrec.setTextHeight(rec.textHeight());
+                                       newrec.setXOffset(x);
+                                       newrec.setYOffset(y);
+                                       bool complete = parseHTML(discard, it, 
e);
+                                       std::string s(discard.begin(), 
discard.end());
+                                       s.assign(discard.begin(), 
discard.end());
+                                       if (!complete) continue;
+                                       else {
+                                               log_debug("No TextField html 
tags are currently implemented in Gnash");
+                                               //Don't think this is the best 
way to match with tags...
+                                               if (strcmp(s.c_str(), "u") == 
0) {
+                                                       
//newrec.setUnderline(true); This works
+                                                       log_unimpl("<u> html 
tag in TextField");
+                                                       handleChar(it, e, x, y, 
newrec, last_code, last_space_glyph, last_line_start_record);
+                                               } else if (strcmp(s.c_str(), 
"a") == 0) {
+                                                       //anchor
+                                                       log_unimpl("<a> html 
tag in TextField");
+                                                       handleChar(it, e, x, y, 
newrec, last_code, last_space_glyph, last_line_start_record);
+                                               } else if (strcmp(s.c_str(), 
"b") == 0) {
+                                                       //bold
+                                                       log_unimpl("<b> html 
tag in TextField");
+                                                       handleChar(it, e, x, y, 
newrec, last_code, last_space_glyph, last_line_start_record);
+                                               } else if (strcmp(s.c_str(), 
"font") == 0) {
+                                                       //font
+                                                       log_unimpl("<font> html 
tag in TextField");
+                                                       handleChar(it, e, x, y, 
newrec, last_code, last_space_glyph, last_line_start_record);
+                                               } else if (strcmp(s.c_str(), 
"img") == 0) {
+                                                       //image
+                                                       log_unimpl("<img> html 
tag in TextField");
+                                                       handleChar(it, e, x, y, 
newrec, last_code, last_space_glyph, last_line_start_record);
+                                               } else if (strcmp(s.c_str(), 
"i") == 0) {
+                                                       //italic
+                                                       log_unimpl("<i> html 
tag in TextField");
+                                                       handleChar(it, e, x, y, 
newrec, last_code, last_space_glyph, last_line_start_record);
+                                               } else if (strcmp(s.c_str(), 
"li") == 0) {
+                                                       //list item
+                                                       log_unimpl("<li> html 
tag in TextField");
+                                                       handleChar(it, e, x, y, 
newrec, last_code, last_space_glyph, last_line_start_record);
+                                               } else if (strcmp(s.c_str(), 
"span") == 0) {
+                                                       //span
+                                                       log_unimpl("<span> html 
tag in TextField");
+                                                       handleChar(it, e, x, y, 
newrec, last_code, last_space_glyph, last_line_start_record);
+                                               } else if (strcmp(s.c_str(), 
"textformat") == 0) {
+                                                       //text format
+                                                       
log_unimpl("<textformat> html tag in TextField");
+                                                       handleChar(it, e, x, y, 
newrec, last_code, last_space_glyph, last_line_start_record);
+                                               } else if (strcmp(s.c_str(), 
"p") == 0) { 
+                                                       //paragraph
+                                                       log_unimpl("<p> html 
tag in TextField");
+                                                       handleChar(it, e, x, y, 
newrec, last_code, last_space_glyph, last_line_start_record);
+                                               } else if (strcmp(s.c_str(), 
"br") == 0) {
+                                                       //line break
+                                                       log_unimpl("<br> html 
tag in TextField");
+                                               } else {
+                                                       log_debug("<%s> tag is 
unsupported", s);
+                                                       handleChar(it, e, x, y, 
newrec, last_code, last_space_glyph, last_line_start_record);
+                                               }
+                                       }
+                                       rec.setXOffset(x);
+                                       rec.setYOffset(y);
+                                       continue;
+                               }
+                               // 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 = _bounds.width();
+               if (x >= width - getRightMargin() - 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() && getAutoSize() == 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 = getLeftMargin() + getBlockIndent() + 
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();
+                               
+                               linestartit = _line_starts.begin();
+                               linestartend = _line_starts.end();
+                               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);
+                                               //record the new line start
+                                               while ( linestartit != 
linestartend && *linestartit <= (it-_text.begin())-1)
+                                               {
+                                                       linestartit++;
+                                               }
+                                               
_line_starts.insert(linestartit, (it-_text.begin()));
+                                       }
+                               } 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);
+                                       
+                                       //record the position at the start of 
this line as a line_start
+                                       int linestartpos = 
(it-_text.begin())-rec.glyphs().size();
+                                       while ( linestartit < linestartend && 
*linestartit < linestartpos)
+                                       {
+                                               linestartit++;
+                                       }
+                                       _line_starts.insert(linestartit, 
linestartpos);
+                               }
+
+                               align_line(getTextAlignment(), 
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 
+                       }
+               }
+
+                       // TODO: HTML markup
+                       
+       }
+}
+
 TextField::VariableRef
 TextField::parseTextVariableRef(const std::string& variableName) const
 {
@@ -1645,7 +1737,8 @@
         // Check for NULL DisplayObject
         if (*it == 0) break;
 
-        tag.push_back(*it++);
+        tag.push_back(*it);
+               ++it;
     }
     
 #ifdef GNASH_DEBUG_TEXTFIELDS
@@ -1717,7 +1810,7 @@
     }
 
     // Register _global.TextField
-    global.init_member(getName(uri), cl.get(), as_object::DefaultFlags,
+    global.init_member("TextField", cl.get(), as_object::DefaultFlags,
             getNamespace(uri));
 }
 

=== modified file 'libcore/TextField.h'
--- a/libcore/TextField.h       2009-07-16 08:30:06 +0000
+++ b/libcore/TextField.h       2009-07-20 16:26:43 +0000
@@ -355,6 +355,7 @@
        ///     If true HTML tags in the text will be parsed and rendered
        void setHtml(bool on) {
                _html = on;
+               format_text();
        }
 
        /// Return true if the TextField text is selectable
@@ -512,6 +513,11 @@
        /// Move viewable lines based on m_cursor
        void changeTopVisibleLine(int current_line);
        
+       /// De-reference and do appropriate action for character iterator
+       void handleChar(std::wstring::const_iterator& it, const 
std::wstring::const_iterator& e,
+               boost::int32_t& x, boost::int32_t& y, SWF::TextRecord& rec, 
int& last_code,
+               int& last_space_glyph, int& last_line_start_record);
+       
        /// Extracts an HTML tag.
        ///
        /// @param tag  This string is filled with the extracted HTML tag.
@@ -666,6 +672,7 @@
     /// 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


reply via email to

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