gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] /srv/bzr/gnash/trunk r11802: Fixes for Sun Studio compili


From: Benjamin Wolsey
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r11802: Fixes for Sun Studio compiling.
Date: Mon, 25 Jan 2010 13:10:05 +0100
User-agent: Bazaar (2.0.2)

------------------------------------------------------------
revno: 11802 [merge]
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Mon 2010-01-25 13:10:05 +0100
message:
  Fixes for Sun Studio compiling.
  
  Tests, fixes and implementation of TextField.autoSize for "center" and "right"
  values and TextFormat.getTextExtent.
  
  The tests for TextFormat.getTextExtent may be unwise because they only deal
  with device fonts, and these vary from system to system. It is probably
  correct that Gnash does not get the same result as the pp.
modified:
  libcore/DisplayObject.cpp
  libcore/Font.cpp
  libcore/Font.h
  libcore/FreetypeGlyphsProvider.cpp
  libcore/FreetypeGlyphsProvider.h
  libcore/TextField.cpp
  libcore/TextField.h
  libcore/asobj/flash/text/TextFormat_as.cpp
  libcore/asobj/flash/text/TextFormat_as.h
  testsuite/actionscript.all/TextField.as
  testsuite/actionscript.all/TextFormat.as
=== modified file 'libcore/DisplayObject.cpp'
--- a/libcore/DisplayObject.cpp 2010-01-11 06:41:38 +0000
+++ b/libcore/DisplayObject.cpp 2010-01-25 06:47:50 +0000
@@ -1549,29 +1549,29 @@
 displayObjectGetters()
 {
     static const Getters getters = boost::assign::map_list_of
-        (NSV::PROP_uX, getX)
-        (NSV::PROP_uY, getY)
-        (NSV::PROP_uXSCALE, getScaleX)
-        (NSV::PROP_uYSCALE, getScaleY)
-        (NSV::PROP_uROTATION, getRotation)
-        (NSV::PROP_uHIGHQUALITY, getHighQuality)
-        (NSV::PROP_uQUALITY, getQuality)
-        (NSV::PROP_uALPHA, getAlpha)
-        (NSV::PROP_uWIDTH, getWidth)
-        (NSV::PROP_uURL, getURL)
-        (NSV::PROP_uHEIGHT, getHeight)
-        (NSV::PROP_uNAME, getNameProperty)
-        (NSV::PROP_uVISIBLE, getVisible)
-        (NSV::PROP_uSOUNDBUFTIME, getSoundBufTime)
-        (NSV::PROP_uFOCUSRECT, getFocusRect)
-        (NSV::PROP_uDROPTARGET, getDropTarget)
-        (NSV::PROP_uCURRENTFRAME, getCurrentFrame)
-        (NSV::PROP_uFRAMESLOADED, getFramesLoaded)
-        (NSV::PROP_uTOTALFRAMES, getTotalFrames)
-        (NSV::PROP_uPARENT, getParent)
-        (NSV::PROP_uTARGET, getTarget)
-        (NSV::PROP_uXMOUSE, getMouseX)
-        (NSV::PROP_uYMOUSE, getMouseY);
+        (NSV::PROP_uX, &getX)
+        (NSV::PROP_uY, &getY)
+        (NSV::PROP_uXSCALE, &getScaleX)
+        (NSV::PROP_uYSCALE, &getScaleY)
+        (NSV::PROP_uROTATION, &getRotation)
+        (NSV::PROP_uHIGHQUALITY, &getHighQuality)
+        (NSV::PROP_uQUALITY, &getQuality)
+        (NSV::PROP_uALPHA, &getAlpha)
+        (NSV::PROP_uWIDTH, &getWidth)
+        (NSV::PROP_uURL, &getURL)
+        (NSV::PROP_uHEIGHT, &getHeight)
+        (NSV::PROP_uNAME, &getNameProperty)
+        (NSV::PROP_uVISIBLE, &getVisible)
+        (NSV::PROP_uSOUNDBUFTIME, &getSoundBufTime)
+        (NSV::PROP_uFOCUSRECT, &getFocusRect)
+        (NSV::PROP_uDROPTARGET, &getDropTarget)
+        (NSV::PROP_uCURRENTFRAME, &getCurrentFrame)
+        (NSV::PROP_uFRAMESLOADED, &getFramesLoaded)
+        (NSV::PROP_uTOTALFRAMES, &getTotalFrames)
+        (NSV::PROP_uPARENT, &getParent)
+        (NSV::PROP_uTARGET, &getTarget)
+        (NSV::PROP_uXMOUSE, &getMouseX)
+        (NSV::PROP_uYMOUSE, &getMouseY);
     return getters;
 }
 
@@ -1581,20 +1581,20 @@
     const Setter n = 0;
 
     static const Setters setters = boost::assign::map_list_of
-        (NSV::PROP_uX, setX)
-        (NSV::PROP_uY, setY)
-        (NSV::PROP_uXSCALE, setScaleX)
-        (NSV::PROP_uYSCALE, setScaleY)
-        (NSV::PROP_uROTATION, setRotation)
-        (NSV::PROP_uHIGHQUALITY, setHighQuality)
-        (NSV::PROP_uQUALITY, setQuality)
-        (NSV::PROP_uALPHA, setAlpha)
-        (NSV::PROP_uWIDTH, setWidth)
-        (NSV::PROP_uHEIGHT, setHeight)
-        (NSV::PROP_uNAME, setName)
-        (NSV::PROP_uVISIBLE, setVisible)
-        (NSV::PROP_uSOUNDBUFTIME, setSoundBufTime)
-        (NSV::PROP_uFOCUSRECT, setFocusRect)
+        (NSV::PROP_uX, &setX)
+        (NSV::PROP_uY, &setY)
+        (NSV::PROP_uXSCALE, &setScaleX)
+        (NSV::PROP_uYSCALE, &setScaleY)
+        (NSV::PROP_uROTATION, &setRotation)
+        (NSV::PROP_uHIGHQUALITY, &setHighQuality)
+        (NSV::PROP_uQUALITY, &setQuality)
+        (NSV::PROP_uALPHA, &setAlpha)
+        (NSV::PROP_uWIDTH, &setWidth)
+        (NSV::PROP_uHEIGHT, &setHeight)
+        (NSV::PROP_uNAME, &setName)
+        (NSV::PROP_uVISIBLE, &setVisible)
+        (NSV::PROP_uSOUNDBUFTIME, &setSoundBufTime)
+        (NSV::PROP_uFOCUSRECT, &setFocusRect)
         (NSV::PROP_uDROPTARGET, n)
         (NSV::PROP_uCURRENTFRAME, n)
         (NSV::PROP_uFRAMESLOADED, n)

=== modified file 'libcore/Font.cpp'
--- a/libcore/Font.cpp  2010-01-11 06:41:38 +0000
+++ b/libcore/Font.cpp  2010-01-25 09:57:03 +0000
@@ -55,21 +55,21 @@
 }
 
 Font::GlyphInfo::GlyphInfo()
-       :
-       advance(0)
+    :
+    advance(0)
 {}
 
 Font::GlyphInfo::GlyphInfo(std::auto_ptr<SWF::ShapeRecord> glyph,
         float advance)
-       :
-       glyph(glyph.release()),
-       advance(advance)
+    :
+    glyph(glyph.release()),
+    advance(advance)
 {}
 
 Font::GlyphInfo::GlyphInfo(const GlyphInfo& o)
-       :
-       glyph(o.glyph),
-       advance(o.advance)
+    :
+    glyph(o.glyph),
+    advance(o.advance)
 {}
 
 
@@ -240,7 +240,7 @@
 float
 Font::get_kerning_adjustment(int last_code, int code) const
 {
-    kerning_pair       k;
+    kerning_pair k;
     k.m_char0 = last_code;
     k.m_char1 = code;
     kernings_table::const_iterator it = m_kerning_pairs.find(k);
@@ -251,15 +251,13 @@
     return 0;
 }
 
-unsigned short int
+size_t
 Font::unitsPerEM(bool embed) const
 {
     // the EM square is 1024 x 1024 for DefineFont up to 2
     // and 20 as much for DefineFont3 up
     if (embed) {
-        // If this is not an embedded font, what should we do
-        // here?
-        if ( _fontTag && _fontTag->subpixelFont() ) return 1024 * 20;
+        if ( _fontTag && _fontTag->subpixelFont() ) return 1024 * 20.0;
         else return 1024;
     }
     
@@ -267,7 +265,7 @@
         if (!initDeviceFontProvider()) {
             log_error("Device font provider was not initialized, "
                     "can't get unitsPerEM");
-            return 0; // can't query it..
+            return 0; 
         }
     }
 
@@ -308,8 +306,6 @@
 
     _deviceGlyphTable.push_back(GlyphInfo(sh, advance));
 
-    testInvariant();
-
     return newOffset;
 }
 
@@ -333,35 +329,32 @@
 bool
 Font::matches(const std::string& name, bool bold, bool italic) const
 {
-       return (_bold == bold && _italic == italic && name ==_name);
+    return (_bold == bold && _italic == italic && name ==_name);
 }
 
-// TODO: what about device fonts?
 float
 Font::leading() const {
     return _fontTag ? _fontTag->leading() : 0.0f;
 }
 
-// TODO: what about device fonts?
-float
-Font::ascent() const {
-    return _fontTag ? _fontTag->ascent() : 0.0f;
-}
-    
-// TODO: what about device fonts?
-float
-Font::descent() const {
-    return _fontTag ? _fontTag->descent() : 0.0f;
-}
-    
-// TODO: what about device fonts?
+float
+Font::ascent(bool embedded) const {
+    return (embedded && _fontTag) ? _fontTag->ascent() : _ftProvider->ascent();
+}
+
+float
+Font::descent(bool embedded) const {
+    return (embedded && _fontTag) ? _fontTag->descent() :
+                                    _ftProvider->descent();
+}
+    
 bool
 Font::is_subpixel_font() const {
     return _fontTag ? _fontTag->subpixelFont() : false;
 }
 
 
-}      // end namespace gnash
+} // namespace gnash
 
 
 // Local Variables:

=== modified file 'libcore/Font.h'
--- a/libcore/Font.h    2010-01-11 06:41:38 +0000
+++ b/libcore/Font.h    2010-01-25 09:05:21 +0000
@@ -51,153 +51,168 @@
 class kerning_pair
 {
 public:
-       boost::uint16_t m_char0, m_char1;
+    boost::uint16_t    m_char0, m_char1;
 
-       bool operator==(const kerning_pair& k) const
-       {
-               return m_char0 == k.m_char0 && m_char1 == k.m_char1;
-       }
+    bool operator==(const kerning_pair& k) const
+    {
+        return m_char0 == k.m_char0 && m_char1 == k.m_char1;
+    }
 };
 
 // for use in standard algorithms
 inline bool
 operator< (const kerning_pair& p1, const kerning_pair& p2)
 {
-       if (p1.m_char0 < p2.m_char0) return true;
-       if (p1.m_char0 == p2.m_char0) {
-               if (p1.m_char1 < p2.m_char1) return true;
+    if (p1.m_char0 < p2.m_char0) return true;
+    if (p1.m_char0 == p2.m_char0) {
+        if (p1.m_char1 < p2.m_char1) return true;
     }
     
     return false;
 }
 
-/// \brief
-/// A 'Font' definition as read from SWF::DefineFont,
-/// SWF::DefineFont2 or SWF::DefineFont3 tags.
-/// Includes definitions from SWF::DefineFontInfo tags
-///
+
+/// A Font resource.
+//
+/// All fonts used in the course of rendering a SWF are represented by this
+/// class. There are two types of Font object: device fonts and glyph fonts
+/// (also called embedded fonts). Device fonts contain no embedded glyphs,
+/// but glyph fonts may be rendered using device fonts if requested during
+/// runtime.
+//
+/// The fact that one Font object may represent an embedded and a device
+/// font simultaneously means that callers must themselves ensure they
+/// specify which font they require. Failure to do this consistently may mean
+/// callers end up with the wrong information about a font.
 class Font : public ExportableResource
 {
 public:
 
     // This table maps from Unicode DisplayObject number to glyph index.
-       typedef std::map<boost::uint16_t, int> CodeTable;
-
-       Font(std::auto_ptr<SWF::DefineFontTag> ft);
-
-       /// Create a device-font only font, using the given name to find it
-       //
-       /// @param name
-       ///     Name of the font face to look for.
-       ///
-       /// @param bold
-       ///     Whether to use the bold variant of the font.
-       ///
-       /// @param italic
-       ///     Whether to use the italic variant of the font.
-       Font(const std::string& name, bool bold=false, bool italic=false);
-
-       ~Font();
+    typedef std::map<boost::uint16_t, int> CodeTable;
+
+    Font(std::auto_ptr<SWF::DefineFontTag> ft);
+
+    /// Create a device-font only font, using the given name to find it
+    //
+    /// @param name
+    ///    Name of the font face to look for.
+    ///
+    /// @param bold
+    ///    Whether to use the bold variant of the font.
+    ///
+    /// @param italic
+    ///    Whether to use the italic variant of the font.
+    Font(const std::string& name, bool bold=false, bool italic=false);
+
+    ~Font();
 
     boost::uint16_t codeTableLookup(int glyph, bool embedded) const;
 
-       /// Return true if this font matches given name and flags
-       //
-       /// @param name
-       ///     Font name
-       ///
-       /// @param bold
-       ///     Bold flag
-       ///
-       /// @param italic
-       ///     Italic flag
-       bool matches(const std::string& name, bool bold, bool italic) const;
-
-       void testInvariant()
-       {
-       }
-
-       /// Get glyph by index.
-       //
-       /// @param glyph_index
-       ///     Index of the glyph. See get_glyph_index() to obtain by 
character code.
-       ///
-       /// @param embedded
-       ///     If true, queries the 'embedded' glyphs table, 
-       ///     otherwise, looks in the 'device' font table.
-       ///
-       /// @return
-       ///     The glyph outline, or NULL if out of range. (would be a
+    /// Return true if this font matches given name and flags
+    //
+    /// @param name
+    ///    Font name
+    ///
+    /// @param bold
+    ///    Bold flag
+    ///
+    /// @param italic
+    ///    Italic flag
+    bool matches(const std::string& name, bool bold, bool italic) const;
+
+    /// Get glyph by index.
+    //
+    /// @param glyph_index
+    ///   Index of the glyph. See get_glyph_index() to obtain by character 
code.
+    ///
+    /// @param embedded
+    ///    If true, queries the 'embedded' glyphs table, 
+    ///    otherwise, looks in the 'device' font table.
+    ///
+    /// @return
+    ///    The glyph outline, or NULL if out of range. (would be a
     /// programming error most likely). The ShapeRecord is owned by
     /// the Font class.
     SWF::ShapeRecord* get_glyph(int glyph_index, bool embedded) const;
 
-       /// Get name of this font. 
-       const std::string& name() const { return _name; }
-
-       /// Return the glyph index for a given character code
-       //
-       /// @param code
-       ///     Character code to fetch the corresponding glyph index of.
-       ///
-       /// @param embedded
-       ///     If true, queries the 'embedded' glyphs table, 
-       ///     otherwise, looks in the 'device' font table.
-       ///
-       /// Note, when querying device fonts, glyphs are created on demand,
-       /// this never happens for embedded fonts, in which case an unexistent
-       /// glyph results in a return of -1
-       ///
-       /// @return -1 if there is no glyph for the specified code or a valid
-       ///         positive index to use in subsequent calls to other 
glyph-index-based
-       ///         methods.
-       ///
-       int     get_glyph_index(boost::uint16_t code, bool embedded) const;
-
-       /// Return the advance value for the given glyph index
-       //
-       /// @param glyph_index
-       ///     Index of the glyph. See get_glyph_index() to obtain by 
character code.
-       ///
-       /// @param embedded
-       ///     If true, queries the 'embedded' glyphs table, 
-       ///     otherwise, looks in the 'device' font table.
-       ///
-       float get_advance(int glyph_index, bool embedded) const;
-
-       /// \brief
-       /// Return the adjustment in advance between the given two
-       /// DisplayObjects (makes sense for embedded glyphs only)
-       //
-       /// Normally this will be 0
-       ///
-       /// NOTE: don't call this method when willing to work with device
-       ///       fonts, or you'll end up mixing information from device fonts
-       ///       with information from embedded fonts.
-       ///
-       float get_kerning_adjustment(int last_code, int this_code) const;
-
-       /// Return height of the EM square used for glyphs definition
-       //
-       /// @param embedded
-       ///     If true, return is based on the SWF tag the font
-       ///     was read from, otherwise will query the FreeTypeGlyphsProvider
-       ///
-       unsigned short int unitsPerEM(bool embedded) const;
-
-    // TODO: what about device fonts?
-    float ascent() const;
-        
-    // TODO: what about device fonts?
-       float leading() const;
- 
-    // TODO: what about device fonts?
-    float descent() const;
-        
-       bool is_subpixel_font() const;
-
-       bool isBold() const { return _bold; }
-       bool isItalic() const { return _italic; }
+    /// Get name of this font. 
+    const std::string& name() const { return _name; }
+
+    /// Return the glyph index for a given character code
+    //
+    /// @param code
+    ///    Character code to fetch the corresponding glyph index of.
+    ///
+    /// @param embedded
+    ///    If true, queries the 'embedded' glyphs table, 
+    ///    otherwise, looks in the 'device' font table.
+    ///
+    /// Note, when querying device fonts, glyphs are created on demand,
+    /// this never happens for embedded fonts, in which case an unexistent
+    /// glyph results in a return of -1
+    ///
+    /// @return -1 if there is no glyph for the specified code or a valid
+    ///         positive index to use in subsequent calls to other
+    ///         glyph-index-based methods.
+    ///
+    int get_glyph_index(boost::uint16_t code, bool embedded) const;
+
+    /// Return the advance value for the given glyph index
+    //
+    /// Note: use unitsPerEM() to get the EM square.
+    //
+    /// @param glyph_index      Index of the glyph. See get_glyph_index()
+    ///                         to obtain by character code.
+    ///
+    /// @param embedded         If true, queries the 'embedded' glyphs table, 
+    ///                         otherwise, looks in the 'device' font table.
+    float get_advance(int glyph_index, bool embedded) const;
+
+    /// Return the adjustment in advance between the given two
+    /// DisplayObjects (makes sense for embedded glyphs only)
+    //
+    /// Normally this will be 0
+    ///
+    /// NOTE: don't call this method when willing to work with device
+    ///       fonts, or you'll end up mixing information from device fonts
+    ///      with information from embedded fonts.
+    ///
+    float get_kerning_adjustment(int last_code, int this_code) const;
+
+    /// Return height of the EM square used for glyphs definition
+    //
+    /// @param embedded     If true, return is based on the SWF tag the font
+    ///                     was read from, otherwise will query the
+    ///                     FreeTypeGlyphsProvider
+    size_t unitsPerEM(bool embedded) const;
+
+    /// Return the ascent value of the font.
+    //
+    /// Note: use unitsPerEM() to get the EM square.
+    float ascent(bool embedded) const;
+        
+    /// Return the descent value of the font in EM units.
+    //
+    /// Note: use unitsPerEM() to get the EM square.
+    float descent(bool embedded) const;
+
+    /// Return the leading value of the font.
+    //
+    /// Note: use unitsPerEM() to get the EM square.
+    float leading() const;
+        
+    bool is_subpixel_font() const;
+
+    /// Return true if the font is bold.
+    bool isBold() const {
+        return _bold;
+    }
+    
+    /// Return true if the font is italic.
+    bool isItalic() const {
+        return _italic;
+    }
 
     /// A pair of strings describing the font.
     //
@@ -226,7 +241,7 @@
         float advance;
     };
 
-       typedef std::vector<GlyphInfo> GlyphInfoRecords;
+    typedef std::vector<GlyphInfo> GlyphInfoRecords;
 
     /// Add display name and copyright name for an embedded font.
     //
@@ -256,41 +271,41 @@
 
 private:
 
-       /// Add a glyph from the os font into the device glyphs table
-       //
-       /// It is assumed that the glyph tables do NOT contain
-       /// an entry for the given code.
-       /// Initializes the rasterizer if not already done so.
-       ///
-       /// @return index of the newly added glyph, or -1 on error.
-       ///
-       int add_os_glyph(boost::uint16_t code);
+    /// Add a glyph from the os font into the device glyphs table
+    //
+    /// It is assumed that the glyph tables do NOT contain
+    /// an entry for the given code.
+    /// Initializes the rasterizer if not already done so.
+    ///
+    /// @return index of the newly added glyph, or -1 on error.
+    ///
+    int add_os_glyph(boost::uint16_t code);
 
-       /// Initialize the freetype rasterizer
-       //
-       /// NOTE: this is 'const' for lazy initialization.
-       ///
-       /// Return true on success, false on error
-       ///
-       bool initDeviceFontProvider() const;
+    /// Initialize the freetype rasterizer
+    //
+    /// NOTE: this is 'const' for lazy initialization.
+    ///
+    /// Return true on success, false on error
+    ///
+    bool initDeviceFontProvider() const;
 
     /// If we were constructed from a definition, this is not NULL.
     boost::scoped_ptr<SWF::DefineFontTag> _fontTag;
 
-       // Device glyphs
-       GlyphInfoRecords _deviceGlyphTable;
+    // Device glyphs
+    GlyphInfoRecords _deviceGlyphTable;
 
-       std::string     _name;
+    std::string    _name;
     std::string _displayName;
     std::string _copyrightName;
 
-       bool    _unicodeChars;
-       bool    _shiftJISChars;
-       bool    _ansiChars;
-       bool    _italic;
-       bool    _bold;
+    bool    _unicodeChars;
+    bool    _shiftJISChars;
+    bool    _ansiChars;
+    bool    _italic;
+    bool    _bold;
 
-       /// Code to index table for embedded glyphs
+    /// Code to index table for embedded glyphs
     //
     /// This can be NULL if an embedded font should not be
     /// substituted by a device font. This can arise with
@@ -303,18 +318,18 @@
     /// of CodeTables from a DefineFontInfo tag.
     boost::shared_ptr<const CodeTable> _embeddedCodeTable; 
 
-       /// Code to index table for device glyphs
-       CodeTable _deviceCodeTable; 
-
-       typedef std::map<kerning_pair, float> kernings_table;
-       kernings_table m_kerning_pairs;
-
-       mutable std::auto_ptr<FreetypeGlyphsProvider> _ftProvider;
+    /// Code to index table for device glyphs
+    CodeTable _deviceCodeTable; 
+
+    typedef std::map<kerning_pair, float> kernings_table;
+    kernings_table m_kerning_pairs;
+
+    mutable std::auto_ptr<FreetypeGlyphsProvider> _ftProvider;
 
 };
 
 
-}      // end namespace gnash
+}    // end namespace gnash
 
 
 

=== modified file 'libcore/FreetypeGlyphsProvider.cpp'
--- a/libcore/FreetypeGlyphsProvider.cpp        2010-01-11 06:41:38 +0000
+++ b/libcore/FreetypeGlyphsProvider.cpp        2010-01-22 13:45:28 +0000
@@ -75,23 +75,23 @@
 
 public:
 
-       /// Create an outline walker drawing to the given DynamiShape
-       //
-       /// @param sh
-       ///     The DynamicShape to draw to. Externally owned.
-       ///
-       /// @param scale
-       ///     The scale to apply to coordinates.
-       ///     This is to match an arbitrary EM 
-       ///
-       OutlineWalker(SWF::ShapeRecord& sh, float scale)
-               :
-               _shape(sh),
-               _scale(scale),
+    /// Create an outline walker drawing to the given DynamiShape
+    //
+    /// @param sh
+    ///    The DynamicShape to draw to. Externally owned.
+    ///
+    /// @param scale
+    ///    The scale to apply to coordinates.
+    ///    This is to match an arbitrary EM 
+    ///
+    OutlineWalker(SWF::ShapeRecord& sh, float scale)
+        :
+        _shape(sh),
+        _scale(scale),
         _currPath(0),
         _x(0),
         _y(0)
-       {
+    {
         fill_style f;
         f.setSolid(rgba(255, 255, 255, 255));
         _shape.addFillStyle(f);
@@ -104,104 +104,104 @@
         _currPath->close();
     }
 
-       ~OutlineWalker() {}
-
-       /// Callback function for the move_to member of FT_Outline_Funcs
-       static int
-       walkMoveTo(FT_CONST FT_Vector* to, void* ptr)
-       {
-               OutlineWalker* walker = static_cast<OutlineWalker*>(ptr);
-               return walker->moveTo(to);
-       }
-
-       /// Callback function for the line_to member of FT_Outline_Funcs
-       static int
-       walkLineTo(FT_CONST FT_Vector* to, void* ptr)
-       {
-               OutlineWalker* walker = static_cast<OutlineWalker*>(ptr);
-               return walker->lineTo(to);
-       }
-
-       /// Callback function for the conic_to member of FT_Outline_Funcs
-       static int
-       walkConicTo(FT_CONST FT_Vector* ctrl, FT_CONST FT_Vector* to, void* ptr)
-       {
-               OutlineWalker* walker = static_cast<OutlineWalker*>(ptr);
-               return walker->conicTo(ctrl, to);
-       }
-
-       /// Callback function for the cubic_to member of FT_Outline_Funcs
-       //
-       /// Transform the cubic curve into a quadratic one an interpolated point
-       /// falling in the middle of the two control points.
-       ///
-       static int
-       walkCubicTo(FT_CONST FT_Vector* ctrl1, FT_CONST FT_Vector* ctrl2,
+    ~OutlineWalker() {}
+
+    /// Callback function for the move_to member of FT_Outline_Funcs
+    static int
+    walkMoveTo(FT_CONST FT_Vector* to, void* ptr)
+    {
+        OutlineWalker* walker = static_cast<OutlineWalker*>(ptr);
+        return walker->moveTo(to);
+    }
+
+    /// Callback function for the line_to member of FT_Outline_Funcs
+    static int
+    walkLineTo(FT_CONST FT_Vector* to, void* ptr)
+    {
+        OutlineWalker* walker = static_cast<OutlineWalker*>(ptr);
+        return walker->lineTo(to);
+    }
+
+    /// Callback function for the conic_to member of FT_Outline_Funcs
+    static int
+    walkConicTo(FT_CONST FT_Vector* ctrl, FT_CONST FT_Vector* to, void* ptr)
+    {
+        OutlineWalker* walker = static_cast<OutlineWalker*>(ptr);
+        return walker->conicTo(ctrl, to);
+    }
+
+    /// Callback function for the cubic_to member of FT_Outline_Funcs
+    //
+    /// Transform the cubic curve into a quadratic one an interpolated point
+    /// falling in the middle of the two control points.
+    ///
+    static int
+    walkCubicTo(FT_CONST FT_Vector* ctrl1, FT_CONST FT_Vector* ctrl2,
             FT_CONST FT_Vector* to, void* ptr)
-       {
-               OutlineWalker* walker = static_cast<OutlineWalker*>(ptr);
-               return walker->cubicTo(ctrl1, ctrl2, to);
-       }
+    {
+        OutlineWalker* walker = static_cast<OutlineWalker*>(ptr);
+        return walker->cubicTo(ctrl1, ctrl2, to);
+    }
 
 private:
-       
+    
     int moveTo(const FT_Vector* to)
-       {
+    {
 #ifdef DEBUG_OUTLINE_DECOMPOSITION 
-               log_debug("moveTo: %ld,%ld", to->x, to->y);
+        log_debug("moveTo: %ld,%ld", to->x, to->y);
 #endif
         _x = static_cast<boost::int32_t>(to->x * _scale);
         _y = - static_cast<boost::int32_t>(to->y * _scale);
         _currPath->close();
         _shape.addPath(Path(_x, _y, 1, 0, 0, false));
         _currPath = &_shape.currentPath();
-               return 0;
-       }
+        return 0;
+    }
 
-       int lineTo(const FT_Vector* to)
-       {
+    int lineTo(const FT_Vector* to)
+    {
 #ifdef DEBUG_OUTLINE_DECOMPOSITION 
-               log_debug("lineTo: %ld,%ld", to->x, to->y);
+        log_debug("lineTo: %ld,%ld", to->x, to->y);
 #endif
         _x = static_cast<boost::int32_t>(to->x * _scale);
         _y = - static_cast<boost::int32_t>(to->y * _scale);
-               _currPath->drawLineTo(_x, _y);
+        _currPath->drawLineTo(_x, _y);
         expandBounds(_x, _y);
-               return 0;
-       }
+        return 0;
+    }
 
-       int conicTo(const FT_Vector* ctrl, const FT_Vector* to)
-       {
+    int conicTo(const FT_Vector* ctrl, const FT_Vector* to)
+    {
 #ifdef DEBUG_OUTLINE_DECOMPOSITION 
-               log_debug("conicTo: %ld,%ld %ld,%ld", ctrl->x, ctrl->y, to->x, 
to->y);
+        log_debug("conicTo: %ld,%ld %ld,%ld", ctrl->x, ctrl->y, to->x, to->y);
 #endif
         boost::int32_t x1 = static_cast<boost::int32_t>(ctrl->x * _scale);
         boost::int32_t y1 = static_cast<boost::int32_t>(ctrl->y * _scale);
         _x = static_cast<boost::int32_t>(to->x * _scale);
         _y = - static_cast<boost::int32_t>(to->y * _scale);
-               _currPath->drawCurveTo(x1, -y1, _x, _y);
-               expandBounds(x1, -y1, _x, _y);
-               return 0;
-       }
+        _currPath->drawCurveTo(x1, -y1, _x, _y);
+        expandBounds(x1, -y1, _x, _y);
+        return 0;
+    }
 
-       int
-       cubicTo(const FT_Vector* ctrl1, const FT_Vector* ctrl2, const 
FT_Vector* to)
-       {
+    int
+    cubicTo(const FT_Vector* ctrl1, const FT_Vector* ctrl2, const FT_Vector* 
to)
+    {
 #ifdef DEBUG_OUTLINE_DECOMPOSITION 
-               log_debug("cubicTo: %ld,%ld %ld,%ld %ld,%ld", ctrl1->x,
+        log_debug("cubicTo: %ld,%ld %ld,%ld %ld,%ld", ctrl1->x,
                 ctrl1->y, ctrl2->x, ctrl2->y, to->x, to->y);
 #endif
-               float x = ctrl1->x + ( (ctrl2->x - ctrl1->x) * 0.5 );
-               float y = ctrl1->y + ( (ctrl2->y - ctrl1->y) * 0.5 );
+        float x = ctrl1->x + ( (ctrl2->x - ctrl1->x) * 0.5 );
+        float y = ctrl1->y + ( (ctrl2->y - ctrl1->y) * 0.5 );
         boost::int32_t x1 = static_cast<boost::int32_t>(x * _scale);
         boost::int32_t y1 = static_cast<boost::int32_t>(y * _scale);
         _x = static_cast<boost::int32_t>(to->x * _scale);
         _y = - static_cast<boost::int32_t>(to->y * _scale);
         
-               _currPath->drawCurveTo(x1, -y1, _x, _y);
-               expandBounds(x1, -y1, _x, _y);
+        _currPath->drawCurveTo(x1, -y1, _x, _y);
+        expandBounds(x1, -y1, _x, _y);
         return 0;
-       }
+    }
     
     void expandBounds(int x, int y) {
         SWFRect bounds = _shape.getBounds();
@@ -224,7 +224,7 @@
 
     SWF::ShapeRecord& _shape;
 
-       const float _scale;
+    const float _scale;
 
     Path* _currPath;
 
@@ -237,119 +237,119 @@
 boost::mutex FreetypeGlyphsProvider::m_lib_mutex;
 
 // static private
-void FreetypeGlyphsProvider::init()
+void
+FreetypeGlyphsProvider::init()
 {
-       boost::mutex::scoped_lock lock(m_lib_mutex);
-
-       if ( m_lib ) return; // nothing to do
-
-       int     error = FT_Init_FreeType(&m_lib);
-       if (error)
-       {
-               std::cerr << boost::format(_("Can't init FreeType! Error "
-                                       "= %d")) % error << std::endl;
-               exit(EXIT_FAILURE);
-       }
+    boost::mutex::scoped_lock lock(m_lib_mutex);
+
+    if (m_lib) return; 
+
+    int    error = FT_Init_FreeType(&m_lib);
+    if (error) {
+        std::cerr << boost::format(_("Can't init FreeType! Error "
+                    "= %d")) % error << std::endl;
+        exit(EXIT_FAILURE);
+    }
 }
 
 // static private
 void FreetypeGlyphsProvider::close()
 {
-       int error = FT_Done_FreeType(m_lib);
-       if (error)
-       {
-               std::cerr << boost::format(_("Can't close FreeType! Error "
-                               "= %d")) % error << std::endl;
-       }
+    int error = FT_Done_FreeType(m_lib);
+    if (error)
+    {
+        std::cerr << boost::format(_("Can't close FreeType! Error "
+                "= %d")) % error << std::endl;
+    }
 }
 
 
 // private
 bool
 FreetypeGlyphsProvider::getFontFilename(const std::string &name,
-               bool bold, bool italic, std::string& filename)
+        bool bold, bool italic, std::string& filename)
 {
 
 #ifdef HAVE_FONTCONFIG
 
-       if (!FcInit ())
-       {
-
-               log_error("Can't init fontconfig library, using hard-"
-                               "coded font filename");
-               filename = DEFAULT_FONTFILE;
-               return true;
-               //return false;
-       }
-       
-       FcResult    result;
-
-       FcPattern* pat = FcNameParse((const FcChar8*)name.c_str());
-       
-       FcConfigSubstitute (0, pat, FcMatchPattern);
-
-       if (italic) {
-               FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ITALIC);
-       }
-
-       if (bold) {
-               FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_BOLD);
-       }
-
-       FcDefaultSubstitute (pat);
-
-       FcPattern   *match;
-       match = FcFontMatch (0, pat, &result);
-       FcPatternDestroy (pat);
-
-       FcFontSet* fs = NULL;
-       if (match)
-       {
-               fs = FcFontSetCreate ();
-               FcFontSetAdd (fs, match);
-       }
-
-       if ( fs )
-       {
-#ifdef GNASH_DEBUG_DEVICEFONTS
-               log_debug("Found %d fonts matching the family %s (using "
-                               "first)", fs->nfont, name);
-#endif
-
-               for (int j = 0; j < fs->nfont; j++)
-               {
-                       FcChar8 *file;
-                       if (FcPatternGetString (fs->fonts[j], FC_FILE, 0, 
&file) != FcResultMatch)
-                       {
-#ifdef GNASH_DEBUG_DEVICEFONTS
-               log_debug("Matching font %d has unknown filename, skipping", j);
-#endif
-               continue;
-                       }
-
-                       filename = (char *)file;
-                       FcFontSetDestroy(fs);
-
-#ifdef GNASH_DEBUG_DEVICEFONTS
-                   log_debug("Loading font from file %d", filename);
-#endif
-                       return true;
-
-               }
-
-               FcFontSetDestroy(fs);
-       }
-
-       log_error("No device font matches the name '%s', using hard-coded"
-                       " font filename", name);
-       filename = DEFAULT_FONTFILE;
-       return true;
+    if (!FcInit ())
+    {
+
+        log_error("Can't init fontconfig library, using hard-"
+                "coded font filename");
+        filename = DEFAULT_FONTFILE;
+        return true;
+        //return false;
+    }
+    
+    FcResult result;
+
+    FcPattern* pat = FcNameParse((const FcChar8*)name.c_str());
+    
+    FcConfigSubstitute (0, pat, FcMatchPattern);
+
+    if (italic) {
+        FcPatternAddInteger (pat, FC_SLANT, FC_SLANT_ITALIC);
+    }
+
+    if (bold) {
+        FcPatternAddInteger (pat, FC_WEIGHT, FC_WEIGHT_BOLD);
+    }
+
+    FcDefaultSubstitute (pat);
+
+    FcPattern   *match;
+    match = FcFontMatch (0, pat, &result);
+    FcPatternDestroy (pat);
+
+    FcFontSet* fs = NULL;
+    if (match)
+    {
+        fs = FcFontSetCreate ();
+        FcFontSetAdd (fs, match);
+    }
+
+    if ( fs )
+    {
+#ifdef GNASH_DEBUG_DEVICEFONTS
+        log_debug("Found %d fonts matching the family %s (using "
+                "first)", fs->nfont, name);
+#endif
+
+        for (int j = 0; j < fs->nfont; j++)
+        {
+            FcChar8 *file;
+            if (FcPatternGetString (fs->fonts[j], FC_FILE, 0, &file) != 
FcResultMatch)
+            {
+#ifdef GNASH_DEBUG_DEVICEFONTS
+        log_debug("Matching font %d has unknown filename, skipping", j);
+#endif
+        continue;
+            }
+
+            filename = (char *)file;
+            FcFontSetDestroy(fs);
+
+#ifdef GNASH_DEBUG_DEVICEFONTS
+            log_debug("Loading font from file %d", filename);
+#endif
+            return true;
+
+        }
+
+        FcFontSetDestroy(fs);
+    }
+
+    log_error("No device font matches the name '%s', using hard-coded"
+            " font filename", name);
+    filename = DEFAULT_FONTFILE;
+    return true;
 #else
-       log_error("Font filename matching not implemented (no fontconfig"
-                       " support built-in), using hard-coded font filename",
-                       name);
-       filename = DEFAULT_FONTFILE;
-       return true;
+    log_error("Font filename matching not implemented (no fontconfig"
+            " support built-in), using hard-coded font filename",
+            name);
+    filename = DEFAULT_FONTFILE;
+    return true;
 #endif
 }
 
@@ -361,83 +361,105 @@
 FreetypeGlyphsProvider::createFace(const std::string& name, bool bold, bool 
italic)
 {
 
-       std::auto_ptr<FreetypeGlyphsProvider> ret;
-
-       try { 
-               ret.reset( new FreetypeGlyphsProvider(name, bold, italic) );
-       } catch (GnashException& ge) {
-               log_error(ge.what());
-               assert(! ret.get());
-       }
-
-       return ret;
+    std::auto_ptr<FreetypeGlyphsProvider> ret;
+
+    try { 
+        ret.reset( new FreetypeGlyphsProvider(name, bold, italic) );
+    } catch (GnashException& ge) {
+        log_error(ge.what());
+        assert(! ret.get());
+    }
+
+    return ret;
 
 }
 #else // ndef USE_FREETYPE 
 std::auto_ptr<FreetypeGlyphsProvider>
 FreetypeGlyphsProvider::createFace(const std::string&, bool, bool)
 {
-       log_error("Freetype not supported");
-       return std::auto_ptr<FreetypeGlyphsProvider>(NULL);
-}
-#endif // ndef USE_FREETYPE 
+    log_error("Freetype not supported");
+    return std::auto_ptr<FreetypeGlyphsProvider>(NULL);
+}
+#endif 
+       
+unsigned short
+FreetypeGlyphsProvider::unitsPerEM() const
+{
+    assert(_face);
+    return _face->units_per_EM;
+}
+
+float
+FreetypeGlyphsProvider::descent() const
+{
+    assert(_face);
+    return std::abs(_face->descender);
+}
+
+float
+FreetypeGlyphsProvider::ascent() const
+{
+    assert(_face);
+    return _face->ascender;
+}
 
 #ifdef USE_FREETYPE 
-FreetypeGlyphsProvider::FreetypeGlyphsProvider(const std::string& name, bool 
bold, bool italic)
-       :
-       m_face(NULL)
+FreetypeGlyphsProvider::FreetypeGlyphsProvider(const std::string& name,
+        bool bold, bool italic)
+    :
+    _face(NULL)
 {
 
-       if (m_lib == NULL)
-       {
-               init();
-       }
-
-       std::string filename;
-       if (getFontFilename(name, bold, italic, filename) == false)
-       {
-               boost::format msg = boost::format(_("Can't find font file "
-                                      "for font '%s'")) % name;
-               throw GnashException(msg.str());
-       }
-
-       int error = FT_New_Face(m_lib, filename.c_str(), 0, &m_face);
-       switch (error)
-       {
-               case 0:
-                       break;
-
-               case FT_Err_Unknown_File_Format:
-               {
-                       boost::format msg = boost::format(_("Font file '%s' "
-                                               "has bad format")) % filename;
-                       throw GnashException(msg.str());
-                       break;
-               }
-
-               default:
-               {
-                       // TODO: return a better error message !
-                       boost::format msg = boost::format(_("Some error "
-                                               "opening font '%s'"))
-                                               % filename;
-                       throw GnashException(msg.str());
-                       break;
-               }
-       }
-
-       // We want an EM of unitsPerEM, so if units_per_EM is different
-       // we will scale 
-       scale = (float)unitsPerEM()/m_face->units_per_EM;
+    if (m_lib == NULL)
+    {
+        init();
+    }
+
+    std::string filename;
+    if (getFontFilename(name, bold, italic, filename) == false)
+    {
+        boost::format msg = boost::format(_("Can't find font file "
+                       "for font '%s'")) % name;
+        throw GnashException(msg.str());
+    }
+
+    int error = FT_New_Face(m_lib, filename.c_str(), 0, &_face);
+    switch (error)
+    {
+        case 0:
+            break;
+
+        case FT_Err_Unknown_File_Format:
+        {
+            boost::format msg = boost::format(_("Font file '%s' "
+                        "has bad format")) % filename;
+            throw GnashException(msg.str());
+            break;
+        }
+
+        default:
+        {
+            // TODO: return a better error message !
+            boost::format msg = boost::format(_("Some error "
+                        "opening font '%s'"))
+                               % filename;
+            throw GnashException(msg.str());
+            break;
+        }
+    }
+
+    // We want an EM of unitsPerEM, so if units_per_EM is different
+    // we will scale 
+    scale = (float)unitsPerEM()/_face->units_per_EM;
 
 #ifdef GNASH_DEBUG_DEVICEFONTS
-       log_debug("EM square for font '%s' is %d, scale is thus %g", name, 
m_face->units_per_EM, scale);
+    log_debug("EM square for font '%s' is %d, scale is thus %g", name, 
_face->units_per_EM, scale);
 #endif
 }
 #else // ndef(USE_FREETYPE)
 FreetypeGlyphsProvider::FreetypeGlyphsProvider(const std::string&, bool, bool)
 {
-       abort(); // should never be called
+    abort(); // should never be called
 }
 #endif // ndef USE_FREETYPE 
 
@@ -447,84 +469,82 @@
 {
     std::auto_ptr<SWF::ShapeRecord> glyph;
 
-       FT_Error error = FT_Load_Char(m_face, code, FT_LOAD_NO_BITMAP | 
+    FT_Error error = FT_Load_Char(_face, code, FT_LOAD_NO_BITMAP | 
                                                 FT_LOAD_NO_SCALE);
 
-       if (error) {
-               log_error("Error loading freetype outline glyph for char '%c' "
+    if (error) {
+        log_error("Error loading freetype outline glyph for char '%c' "
                 "(error: %d)", code, error);
-               return glyph;
-       }
+        return glyph;
+    }
 
-       // Scale advance by current scale, to match expected output coordinate 
space
-       advance = m_face->glyph->metrics.horiAdvance * scale;
+    // Scale advance by current scale, to match expected output coordinate 
space
+    advance = _face->glyph->metrics.horiAdvance * scale;
 #ifdef GNASH_DEBUG_DEVICEFONTS 
-       log_debug("Advance value for glyph '%c' is %g (horiAdvance:%ld, "
-                       "scale:%g)", code, advance, 
-                       m_face->glyph->metrics.horiAdvance, scale);
+    log_debug("Advance value for glyph '%c' is %g (horiAdvance:%ld, "
+            "scale:%g)", code, advance, 
+            _face->glyph->metrics.horiAdvance, scale);
 #endif
 
-       if ( m_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE )
-       {
-               unsigned long gf = m_face->glyph->format;
-               log_unimpl("FT_Load_Char() returned a glyph format != "
-                       "FT_GLYPH_FORMAT_OUTLINE (%c%c%c%c)",
-                       static_cast<char>((gf>>24)&0xff),
-                       static_cast<char>((gf>>16)&0xff),
-                       static_cast<char>((gf>>8)&0xff),
-                       static_cast<char>(gf&0xff));
-               return glyph;
-       }
-
-       FT_Outline* outline = &(m_face->glyph->outline);
-
-       FT_Outline_Funcs walk;
+    if ( _face->glyph->format != FT_GLYPH_FORMAT_OUTLINE )
+    {
+        unsigned long gf = _face->glyph->format;
+        log_unimpl("FT_Load_Char() returned a glyph format != "
+            "FT_GLYPH_FORMAT_OUTLINE (%c%c%c%c)",
+            static_cast<char>((gf>>24)&0xff),
+            static_cast<char>((gf>>16)&0xff),
+            static_cast<char>((gf>>8)&0xff),
+            static_cast<char>(gf&0xff));
+        return glyph;
+    }
+
+    FT_Outline* outline = &(_face->glyph->outline);
+
+    FT_Outline_Funcs walk;
     walk.move_to = OutlineWalker::walkMoveTo;
-       walk.line_to = OutlineWalker::walkLineTo;
-       walk.conic_to = OutlineWalker::walkConicTo;
-       walk.cubic_to = OutlineWalker::walkCubicTo;
-       walk.shift = 0; // ?
-       walk.delta = 0; // ?
+    walk.line_to = OutlineWalker::walkLineTo;
+    walk.conic_to = OutlineWalker::walkConicTo;
+    walk.cubic_to = OutlineWalker::walkCubicTo;
+    walk.shift = 0; // ?
+    walk.delta = 0; // ?
 
 #ifdef DEBUG_OUTLINE_DECOMPOSITION 
-       log_debug("Decomposing glyph outline for DisplayObject %u", code);
+    log_debug("Decomposing glyph outline for DisplayObject %u", code);
 #endif
     
     glyph.reset(new SWF::ShapeRecord);
 
-       OutlineWalker walker(*glyph, scale);
+    OutlineWalker walker(*glyph, scale);
 
-       FT_Outline_Decompose(outline, &walk, &walker);
+    FT_Outline_Decompose(outline, &walk, &walker);
 #ifdef DEBUG_OUTLINE_DECOMPOSITION 
-       SWFRect bound; sh->compute_bound(&bound, VM::get().getSWFVersion());
-       log_debug("Decomposed glyph for DisplayObject '%c' has bounds %s",
-                       code, bound.toString());
+    SWFRect bound; sh->compute_bound(&bound, VM::get().getSWFVersion());
+    log_debug("Decomposed glyph for DisplayObject '%c' has bounds %s",
+            code, bound.toString());
 #endif
 
     walker.finish();
 
-       return glyph;
+    return glyph;
 }
 #else // ndef(USE_FREETYPE)
 
 std::auto_ptr<SWF::ShapeRecord>
 FreetypeGlyphsProvider::getGlyph(boost::uint16_t, float& advance)
 {
-       abort(); // should never be called... 
+    abort(); // should never be called... 
 }
-#endif // ndef(USE_FREETYPE)
+#endif
 
 FreetypeGlyphsProvider::~FreetypeGlyphsProvider()
 {
 #ifdef USE_FREETYPE 
-       if ( m_face )
-       {
-               if ( FT_Done_Face(m_face) != 0 )
-               {
-                       log_error("Could not release FT face resources");
-               }
-       }
-#endif // ndef(USE_FREETYPE)
+    if (_face) {
+        if (FT_Done_Face(_face) != 0) {
+            log_error("Could not release FT face resources");
+        }
+    }
+#endif
 }
 
 } // namespace gnash

=== modified file 'libcore/FreetypeGlyphsProvider.h'
--- a/libcore/FreetypeGlyphsProvider.h  2010-01-11 06:41:38 +0000
+++ b/libcore/FreetypeGlyphsProvider.h  2010-01-22 13:45:28 +0000
@@ -61,108 +61,115 @@
 
 public:
 
-       /// Named constructor for a face-bound rasterizer.
-       //
-       /// @param name
-       ///     Name of the font to get glyphs info from
-       ///
-       /// @param bold
-       ///     Whether to use a bold version of the font
-       ///
-       /// @param italic
-       ///     Whether to use an italic version of the font
-       ///
-       /// @return a rasterizer bound to the given font name,
-       ///         or a NULL auto_ptr if the given truetype font
-       ///         could not be found.
-       ///
-       static std::auto_ptr<FreetypeGlyphsProvider> createFace(const 
std::string& name, bool bold, bool italic);
-
-       /// Destructor
-       //
-       /// Release face resources
-       ///
-       ~FreetypeGlyphsProvider();
-
-
-       /// \brief
-       /// Return the given DisplayObject glyph as a shape DisplayObject 
definition
-       /// in unitsPerEM() coordinates.
-       //
-       ///
-       /// TODO: allow using a custom EM square ?
-       ///
-       /// @param code
-       ///     Character code.
-       ///
-       /// @param advance
-       ///     Output parameter... units to advance horizontally from this
-       ///     glyph to the next, in unitsPerEM() units.
-       ///
-       /// @return A DefineShapeTag in unitsPerEM() coordinates,
-       ///         or a NULL pointer if the given DisplayObject code
-       ///         doesn't exist in this font.
-       ///
+    /// Named constructor for a face-bound rasterizer.
+    //
+    /// @param name
+    ///    Name of the font to get glyphs info from
+    ///
+    /// @param bold
+    ///    Whether to use a bold version of the font
+    ///
+    /// @param italic
+    ///    Whether to use an italic version of the font
+    ///
+    /// @return a rasterizer bound to the given font name,
+    ///         or a NULL auto_ptr if the given truetype font
+    ///         could not be found.
+    ///
+    static std::auto_ptr<FreetypeGlyphsProvider> createFace(
+            const std::string& name, bool bold, bool italic);
+
+    /// Destructor
+    //
+    /// Release face resources
+    ///
+    ~FreetypeGlyphsProvider();
+
+
+    /// \brief
+    /// Return the given DisplayObject glyph as a shape DisplayObject 
definition
+    /// in unitsPerEM() coordinates.
+    //
+    ///
+    /// TODO: allow using a custom EM square ?
+    ///
+    /// @param code
+    ///     Character code.
+    ///
+    /// @param advance
+    ///    Output parameter... units to advance horizontally from this
+    ///     glyph to the next, in unitsPerEM() units.
+    ///
+    /// @return A DefineShapeTag in unitsPerEM() coordinates,
+    ///         or a NULL pointer if the given DisplayObject code
+    ///         doesn't exist in this font.
+    ///
     std::auto_ptr<SWF::ShapeRecord> getGlyph(boost::uint16_t code,
             float& advance);
 
-       /// Return the number of units of glyphs EM
-       //
-       /// This is currently hard-coded to 1024, but could in future depend
-       /// on actual font file being used.
-       ///
-       unsigned short unitsPerEM() const { return 1024; }
+    /// Return the font's ascender in terms of its EM own square.
+    float ascent() const;
+    
+    /// Return the font's descender in terms of its own EM square.
+    float descent() const;
+
+    /// Return the number of units of glyphs EM
+    //
+    /// This is currently hard-coded to 1024, but could in future depend
+    /// on actual font file being used.
+    ///
+    unsigned short unitsPerEM() const;
 
 private:
 
-       /// Use the named constructor to create an instance
-       //
-       /// throw a GnashException on error (unkonwn font name or similar).
-       ///
-       FreetypeGlyphsProvider(const std::string& fontname, bool bold, bool 
italic);
+    /// Use the named constructor to create an instance
+    //
+    /// throw a GnashException on error (unkonwn font name or similar).
+    ///
+    FreetypeGlyphsProvider(const std::string& fontname, bool bold, bool 
italic);
 
 #ifdef USE_FREETYPE 
 
-       /// Scale factor to make the freetype glyph metrix match our 
unitsPerEM()
-       /// coordinate space. Not all font faces have am EM square of 
unitsPerEM(), so we
-       /// use this value to scale both coordinates and advance values
-       /// The value is computed by the costructor, as soon as a face is 
initialized.
-       float scale;
-
-       /// Get filename containing given font
-       //
-       /// @param name
-       ///     Font name
-       ///
-       /// @param bold
-       ///     Want bold version
-       ///
-       /// @param italic
-       ///     Want italic version
-       ///
-       /// @param filename
-       ///     Where to return the filename to
-       ///
-       /// @return true if the font was found, false otherwise.
-       ///     Actually, this function should return a default
-       ///     filename in any case, so false should only be
-       ///     returned if not even a default font was found.
-       ///
-       bool getFontFilename(const std::string& name, bool bold, bool italic,
-                       std::string& filename);
-
-       /// Initialize the FreeType library if not done so yet
-       static void init();
-
-       static void close();
-
-       /// Mutex protecting FreeType library (for initialization basically)
-       static boost::mutex     m_lib_mutex;
-
-       /// FreeType library
-       static FT_Library       m_lib;
-
-       FT_Face m_face;
+    /// Scale factor to make the freetype glyph metrix match our unitsPerEM()
+    /// coordinate space. Not all font faces have am EM square of 
unitsPerEM(), so we
+    /// use this value to scale both coordinates and advance values
+    /// The value is computed by the costructor, as soon as a face is 
initialized.
+    float scale;
+
+    /// Get filename containing given font
+    //
+    /// @param name
+    ///    Font name
+    ///
+    /// @param bold
+    ///    Want bold version
+    ///
+    /// @param italic
+    ///    Want italic version
+    ///
+    /// @param filename
+    ///    Where to return the filename to
+    ///
+    /// @return true if the font was found, false otherwise.
+    ///    Actually, this function should return a default
+    ///    filename in any case, so false should only be
+    ///    returned if not even a default font was found.
+    ///
+    bool getFontFilename(const std::string& name, bool bold, bool italic,
+            std::string& filename);
+
+    /// Initialize the FreeType library if not done so yet
+    static void init();
+
+    static void close();
+
+    /// Mutex protecting FreeType library (for initialization basically)
+    static boost::mutex    m_lib_mutex;
+
+    /// FreeType library
+    static FT_Library    m_lib;
+
+    FT_Face    _face;
 
 #endif // USE_FREETYPE
 
@@ -171,4 +178,4 @@
 } // namespace gnash
 
 
-#endif // GNASH_FREETYPE_H
+#endif    // GNASH_FREETYPE_H

=== modified file 'libcore/TextField.cpp'
--- a/libcore/TextField.cpp     2010-01-19 15:02:37 +0000
+++ b/libcore/TextField.cpp     2010-01-25 11:37:17 +0000
@@ -82,6 +82,9 @@
 
 // Forward declarations
 namespace {
+    const char* autoSizeValueName(TextField::AutoSize val);
+    TextField::AutoSize parseAutoSize(const std::string& val);
+
     void attachPrototypeProperties(as_object& proto);
     void attachTextFieldStaticMembers(as_object& o);
     void attachTextFieldInterface(as_object& o);
@@ -183,7 +186,7 @@
     _wordWrap(def.wordWrap()),
     _html(def.html()),
     _selectable(!def.noSelect()),
-    _autoSize(def.autoSize() ? autoSizeLeft : autoSizeNone),
+    _autoSize(def.autoSize() ? AUTOSIZE_LEFT : AUTOSIZE_NONE),
     _type(def.readOnly() ? typeDynamic : typeInput),
     _bounds(def.bounds()),
     _selection(0, 0)
@@ -253,7 +256,7 @@
     _wordWrap(false),
     _html(false),
     _selectable(true),
-    _autoSize(autoSizeNone),
+    _autoSize(AUTOSIZE_NONE),
     _type(typeDynamic),
     _bounds(bounds),
     _selection(0, 0)
@@ -411,7 +414,7 @@
 
     _displayRecords.clear();
     float scale = getFontHeight() /
-    static_cast<float>(_font->unitsPerEM(_embedFonts));
+        static_cast<float>(_font->unitsPerEM(_embedFonts));
     float fontLeading = _font->leading() * scale;
 
     //offset the lines
@@ -1015,8 +1018,7 @@
 }
 
 float
-TextField::align_line(TextAlignment align,
-        int last_line_start_record, float x)
+TextField::align_line(TextAlignment align, int last_line_start_record, float x)
 {
 
     float width = _bounds.width(); 
@@ -1151,7 +1153,7 @@
     // nothing more to do if text is empty
     if ( _text.empty() )
     {
-        // TODO: should we still reset _bounds if autoSize != autoSizeNone ?
+        // TODO: should we still reset _bounds if autoSize != AUTOSIZE_NONE ?
         //       not sure we should...
         reset_bounding_box(0, 0);
         return;
@@ -1160,16 +1162,11 @@
     LineStarts::iterator linestartit = _line_starts.begin();
     LineStarts::const_iterator linestartend = _line_starts.end();
 
-    AutoSizeValue autoSize = getAutoSize();
-    if ( autoSize != autoSizeNone )
-    {
-        // define GNASH_DEBUG_TEXT_FORMATTING on top to get useful info
-        //LOG_ONCE( log_debug(_("TextField.autoSize != 'none' TESTING")) );
-
+    AutoSize autoSize = getAutoSize();
+    if (autoSize != AUTOSIZE_NONE) {
         // When doing WordWrap we don't want to change
         // the boundaries. See bug #24348
-        if (!  doWordWrap() )
-        {
+        if (!doWordWrap()) {
             _bounds.set_to_rect(0, 0, 0, 0); // this is correct for 'true'
         }
     }
@@ -1178,24 +1175,22 @@
     // to find the appropriate font to use, as ActionScript
     // code should be able to change the font of a TextField
     //
-    if (!_font)
-    {
+    if (!_font) {
         log_error(_("No font for TextField!"));
         return;
     }
 
     boost::uint16_t fontHeight = getFontHeight();
     float scale = fontHeight /
-    static_cast<float>(_font->unitsPerEM(_embedFonts)); 
-    float fontDescent = _font->descent() * scale; 
-    float fontLeading = _font->leading() * scale;
-    boost::uint16_t leftMargin = getLeftMargin();
-    boost::uint16_t indent = getIndent();
-    boost::uint16_t blockIndent = getBlockIndent();
-    bool underlined = getUnderlined();
+        static_cast<float>(_font->unitsPerEM(_embedFonts)); 
+    const float fontLeading = _font->leading() * scale;
+    const boost::uint16_t leftMargin = getLeftMargin();
+    const boost::uint16_t indent = getIndent();
+    const boost::uint16_t blockIndent = getBlockIndent();
+    const bool underlined = getUnderlined();
 
-    //log_debug("%s: fontDescent:%g, fontLeading:%g, fontHeight:%g, scale:%g",
-    //  getTarget(), fontDescent, fontLeading, fontHeight, scale);
+    /// Remember the current bounds for autosize.
+    SWFRect oldBounds(_bounds);
 
     SWF::TextRecord rec;    // one to work on
     rec.setFont(_font.get());
@@ -1203,7 +1198,7 @@
     rec.setColor(getTextColor()); 
     rec.setXOffset(PADDING_TWIPS + 
             std::max(0, leftMargin + indent + blockIndent));
-    rec.setYOffset(PADDING_TWIPS + fontHeight + (fontLeading - fontDescent));
+    rec.setYOffset(PADDING_TWIPS + fontHeight + fontLeading);
     rec.setTextHeight(fontHeight);
        
        // create in textrecord.h
@@ -1243,7 +1238,7 @@
     boost::int32_t y = static_cast<boost::int32_t>(rec.yOffset());
 
     // Start the bbox at the upper-left corner of the first glyph.
-    reset_bounding_box(x, y - fontDescent + fontHeight); 
+    //reset_bounding_box(x, y + fontHeight); 
     
     int last_code = -1; // only used if _embedFonts
     int last_space_glyph = -1;
@@ -1266,10 +1261,28 @@
     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)
+    // Expand bounding box to include the whole text (if autoSize and wordWrap
+    // is not in operation.
+    if (_autoSize != AUTOSIZE_NONE && !doWordWrap())
     {
         _bounds.expand_to_point(x + PADDING_TWIPS, y + PADDING_TWIPS);
+
+        if (_autoSize == AUTOSIZE_RIGHT) {
+            /// Autosize right expands from the previous right margin.
+            SWFMatrix m;
+
+            m.tx = oldBounds.get_x_max() - _bounds.width();
+            m.transform(_bounds);
+        }
+        else if (_autoSize == AUTOSIZE_CENTER) {
+            // Autosize center expands from the previous center.
+            SWFMatrix m;
+            log_debug("_bounds.width() before: %s", _bounds.width());
+            m.tx = oldBounds.get_x_min() + oldBounds.width() / 2.0 - 
+                _bounds.width() / 2.0;
+            m.transform(_bounds);
+            log_debug("_bounds.width() after: %s", _bounds.width());
+        }
     }
 
     // Add the last line to our output.
@@ -1290,7 +1303,7 @@
 {
     boost::uint16_t fontHeight = getFontHeight();
     float scale = fontHeight /
-    static_cast<float>(_font->unitsPerEM(_embedFonts));
+        static_cast<float>(_font->unitsPerEM(_embedFonts));
     float fontLeading = _font->leading() * scale;
     _linesindisplay = _bounds.height() / (fontHeight + fontLeading + 
PADDING_TWIPS);
     if (_linesindisplay > 0) { //no need to place lines if we can't fit any
@@ -1338,7 +1351,7 @@
     LineStarts::const_iterator linestartend = _line_starts.end();
     
     float scale = _fontHeight /
-    static_cast<float>(_font->unitsPerEM(_embedFonts)); 
+        static_cast<float>(_font->unitsPerEM(_embedFonts)); 
     float fontLeading = _font->leading() * scale;
     float leading = getLeading();
     leading += fontLeading * scale; // not sure this is correct...
@@ -1350,13 +1363,13 @@
     align_line(getTextAlignment(), last_line_start_record, x);
 
     // Expand bounding box to include last column of text ...
-    if ( _autoSize != autoSizeNone ) 
-    {
+    if (!doWordWrap() && _autoSize != AUTOSIZE_NONE) {
         _bounds.expand_to_point(x + PADDING_TWIPS, y + PADDING_TWIPS);
     }
 
     // new paragraphs get the indent.
-    x = std::max(0, getLeftMargin() + getIndent() + getBlockIndent()) + 
PADDING_TWIPS;
+    x = std::max(0, getLeftMargin() + getIndent() + getBlockIndent()) +
+        PADDING_TWIPS;
     y += div * (getFontHeight() + leading);
     if (y >= _bounds.height()) {
         ++_maxScroll;
@@ -1424,8 +1437,8 @@
     LineStarts::const_iterator linestartend = _line_starts.end();
     
     float scale = _fontHeight /
-    static_cast<float>(_font->unitsPerEM(_embedFonts)); 
-    float fontDescent = _font->descent() * scale; 
+        static_cast<float>(_font->unitsPerEM(_embedFonts)); 
+    float fontDescent = _font->descent(_embedFonts) * scale; 
     float fontLeading = _font->leading() * scale;
     float leading = getLeading();
     leading += fontLeading * scale; // not sure this is correct...
@@ -1850,7 +1863,7 @@
 #endif
 
             // No wrap and no resize: truncate
-            if (!doWordWrap() && getAutoSize() == autoSizeNone)
+            if (!doWordWrap() && getAutoSize() == AUTOSIZE_NONE)
             {
 #ifdef GNASH_DEBUG_TEXT_FORMATTING
                 log_debug(" wordWrap=false, autoSize=none");
@@ -2615,47 +2628,6 @@
 }
 
 
-TextField::AutoSizeValue
-TextField::parseAutoSizeValue(const std::string& val)
-{
-    StringNoCaseEqual cmp;
-
-    if ( cmp(val, "left") )
-    {
-        return autoSizeLeft;
-    }
-    if ( cmp(val, "right") )
-    {
-        return autoSizeRight;
-    }
-    if ( cmp(val, "center") )
-    {
-        return autoSizeCenter;
-    }
-    return autoSizeNone;
-
-}
-
-
-const char*
-TextField::autoSizeValueName(AutoSizeValue val)
-{
-    switch (val)
-    {
-        case autoSizeLeft:
-            return "left";
-        case autoSizeRight:
-            return "right";
-        case autoSizeCenter:
-            return "center";
-        case autoSizeNone:
-        default:
-            return "none";
-    }
-
-}
-
-
 TextField::TypeValue
 TextField::parseTypeValue(const std::string& val)
 {
@@ -2687,7 +2659,7 @@
 }
 
 void
-TextField::setAutoSize(AutoSizeValue val)
+TextField::setAutoSize(AutoSize val)
 {
     if ( val == _autoSize ) return;
 
@@ -2701,9 +2673,21 @@
 TextField::getTextAlignment()
 {
     TextAlignment textAlignment = getAlignment(); 
-    if ( _autoSize == autoSizeCenter ) textAlignment = ALIGN_CENTER;
-    else if ( _autoSize == autoSizeLeft ) textAlignment = ALIGN_LEFT;
-    else if ( _autoSize == autoSizeRight ) textAlignment = ALIGN_RIGHT;
+
+    switch (_autoSize) {
+        case AUTOSIZE_CENTER:
+            textAlignment = ALIGN_CENTER;
+            break;
+        case AUTOSIZE_LEFT:
+            textAlignment = ALIGN_LEFT;
+            break;
+        case AUTOSIZE_RIGHT:
+            textAlignment = ALIGN_RIGHT;
+            break;
+        default:
+            // Leave it as it was.
+            break;
+    }
 
     return textAlignment;
 }
@@ -3147,27 +3131,24 @@
 
     if ( fn.nargs == 0 ) // getter
     {
-        return ptr->autoSizeValueName(ptr->getAutoSize());
+        return autoSizeValueName(ptr->getAutoSize());
     }
     else // setter
     {
         const as_value& arg = fn.arg(0);
-        if ( arg.is_bool() )
-        {
-            if ( arg.to_bool() ) // true == left
-            {
-                ptr->setAutoSize( TextField::autoSizeLeft );
+        if (arg.is_bool()) {
+            if (arg.to_bool()) {
+                // True equates to left, every other bool to none.
+                ptr->setAutoSize(TextField::AUTOSIZE_LEFT);
             }
-            else
-            {
-                ptr->setAutoSize( TextField::autoSizeNone );
+            else {
+                ptr->setAutoSize(TextField::AUTOSIZE_NONE);
             }
         }
-        else
-        {
+        else {
             std::string strval = arg.to_string();
-            TextField::AutoSizeValue val = ptr->parseAutoSizeValue(strval);
-            ptr->setAutoSize( val );
+            TextField::AutoSize val = parseAutoSize(strval);
+            ptr->setAutoSize(val);
         }
     }
 
@@ -3179,8 +3160,7 @@
 {
     TextField* ptr = ensure<IsDisplayObject<TextField> >(fn);
 
-    if (!fn.nargs)
-    {
+    if (!fn.nargs) {
         // getter
         return ptr->typeValueName(ptr->getType());
     }
@@ -3191,8 +3171,7 @@
     TextField::TypeValue val = ptr->parseTypeValue(strval);
 
     IF_VERBOSE_ASCODING_ERRORS(
-        if ( val == TextField::typeInvalid )
-        {
+        if (val == TextField::typeInvalid) {
             log_aserror(_("Invalid value given to TextField.type: %s"), 
strval);
         }
     );
@@ -3804,6 +3783,47 @@
     o.init_member("getFontList", vm.getNative(104, 201), swf6Flags);
 }
 
+
+/// Return autoSize value as a string
+//
+/// @param val      AutoSize value 
+/// @return         a C-string representation of the autoSize value.
+///                    The return is *never* NULL.
+const char*
+autoSizeValueName(TextField::AutoSize val)
+{
+    switch (val) {
+        case TextField::AUTOSIZE_LEFT:
+            return "left";
+        case TextField::AUTOSIZE_RIGHT:
+            return "right";
+        case TextField::AUTOSIZE_CENTER:
+            return "center";
+        case TextField::AUTOSIZE_NONE:
+        default:
+            return "none";
+    }
+
+}
+
+TextField::AutoSize
+parseAutoSize(const std::string& val)
+{
+    StringNoCaseEqual cmp;
+
+    if (cmp(val, "left")) {
+        return TextField::AUTOSIZE_LEFT;
+    }
+    if (cmp(val, "right")) {
+        return TextField::AUTOSIZE_RIGHT;
+    }
+    if (cmp(val, "center")) {
+        return TextField::AUTOSIZE_CENTER;
+    }
+    return TextField::AUTOSIZE_NONE;
+}
+
+
 } // anonymous namespace
 
 } // namespace gnash

=== modified file 'libcore/TextField.h'
--- a/libcore/TextField.h       2010-01-14 12:03:17 +0000
+++ b/libcore/TextField.h       2010-01-25 11:13:55 +0000
@@ -63,19 +63,19 @@
        };
        
        /// Possible autoSize values
-       enum AutoSizeValue {
+       enum AutoSize {
 
                /// Do not automatically resize TextField as text grow/shrink
-               autoSizeNone,
+               AUTOSIZE_NONE,
 
                /// Expand TextField, anchor the top-left side
-               autoSizeLeft,
+               AUTOSIZE_LEFT,
 
                /// Expand TextField, anchor the horizontal center
-               autoSizeCenter,
+               AUTOSIZE_CENTER,
 
                /// Expand TextField, anchor the top-right side
-               autoSizeRight
+               AUTOSIZE_RIGHT
        };
 
        /// Possible type values
@@ -307,7 +307,7 @@
        void setEmbedFonts(bool use);
 
        /// Get autoSize value 
-       AutoSizeValue getAutoSize() const
+       AutoSize getAutoSize() const
        {
                return _autoSize;
        }
@@ -318,28 +318,9 @@
        /// Set autoSize value 
        //
        /// @param val
-       ///     The AutoSizeValue to use
-       ///
-       void setAutoSize(AutoSizeValue val);
-
-       /// Parse autoSize string value
-       //
-       /// @param val
-       ///     Auto size value as a string (one of none, left, center, right)
-       ///
-       /// @return an AutoSizeValue identifier. autoSizeNone if invalid
-       ///
-       static AutoSizeValue parseAutoSizeValue(const std::string& val);
-
-       /// Return autoSize value as a string
-       //
-       /// @param val
-       ///     Auto size value 
-       ///
-       /// @return a C-string representation of the autoSize value.
-       ///     The returns is *never* NULL.
-       ///
-       static const char* autoSizeValueName(AutoSizeValue val);
+       ///     The AutoSize to use
+       ///
+       void setAutoSize(AutoSize val);
 
        /// Set type (input or dynamic)
        //
@@ -839,7 +820,7 @@
 
        bool _selectable;
 
-       AutoSizeValue _autoSize;
+       AutoSize _autoSize;
 
        TypeValue _type;
 

=== modified file 'libcore/asobj/flash/text/TextFormat_as.cpp'
--- a/libcore/asobj/flash/text/TextFormat_as.cpp        2010-01-19 15:44:18 
+0000
+++ b/libcore/asobj/flash/text/TextFormat_as.cpp        2010-01-25 11:37:17 
+0000
@@ -31,6 +31,7 @@
 #include "smart_ptr.h" 
 #include "GnashNumeric.h"
 #include "Array_as.h"
+#include "fontlib.h"
 
 
 namespace gnash {
@@ -54,6 +55,13 @@
     }
 };
 
+struct
+PixelsToTwips
+{
+    boost::int32_t operator()(const as_value& val) const {
+        return pixelsToTwips(val.to_number());
+    }
+};
 
 struct
 ToBool
@@ -110,7 +118,7 @@
 /// @tparam F       The function to call to retrieve the value.
 /// @tparam P       A function object to be applied to the argument before
 ///                 returning the value.
-template<typename T, typename U, const Optional<U>&(T::*F)(),
+template<typename T, typename U, const Optional<U>&(T::*F)() const,
     typename P = Nothing>
 struct Get
 {
@@ -150,16 +158,12 @@
        TextField::TextAlignment parseAlignString(const std::string& align);
        TextField::TextFormatDisplay parseDisplayString(const std::string& 
display);
 
+    as_value textformat_align(const fn_call& fn);
        as_value textformat_display(const fn_call& fn);
        as_value textformat_tabStops(const fn_call& fn);
-       as_value textformat_blockIndent(const fn_call& fn);
-       as_value textformat_leading(const fn_call& fn);
-       as_value textformat_indent(const fn_call& fn);
-       as_value textformat_align(const fn_call& fn);
        as_value textformat_target(const fn_call& fn);
        as_value textformat_url(const fn_call& fn);
        as_value textformat_color(const fn_call& fn);
-       as_value textformat_size(const fn_call& fn);
        as_value textformat_font(const fn_call& fn);
        as_value textformat_getTextExtent(const fn_call& fn);
 
@@ -202,8 +206,14 @@
     vm.registerNative(textformat_font, 110, 1);
     vm.registerNative(textformat_font, 110, 2);
     
-    vm.registerNative(textformat_size, 110, 3);
-    vm.registerNative(textformat_size, 110, 4);
+    vm.registerNative(
+            Get<const TextFormat_as, boost::uint16_t,
+            &TextFormat_as::size, TwipsToPixels>::get,
+            110, 3);
+    vm.registerNative(
+            Set<TextFormat_as, boost::uint16_t, &TextFormat_as::sizeSet,
+            PixelsToTwips>::set, 
+            110, 4);
     
     vm.registerNative(textformat_color, 110, 5);
     vm.registerNative(textformat_color, 110, 6);
@@ -259,22 +269,28 @@
             PositiveTwips>::set, 
             110, 22);
 
-    vm.registerNative(textformat_indent, 110, 23);
+    vm.registerNative(
+            Get<const TextFormat_as, boost::uint16_t,
+            &TextFormat_as::indent,
+            TwipsToPixels>::get, 110, 23);
     vm.registerNative(
             Set<TextFormat_as, boost::uint16_t, &TextFormat_as::indentSet,
             PositiveTwips>::set, 
             110, 24);
     
-    vm.registerNative(textformat_leading, 110, 25);
+    vm.registerNative(
+            Get<const TextFormat_as, boost::uint16_t,
+            &TextFormat_as::leading,
+            TwipsToPixels>::get, 110, 25);
     vm.registerNative(
             Set<TextFormat_as, boost::uint16_t, &TextFormat_as::leadingSet,
             PositiveTwips>::set, 
             110, 26);
 
-    vm.registerNative(textformat_blockIndent, 110, 27);
-
-    // Note: this behaves differently in SWF8, so perhaps best not to use
-    // the template.
+    vm.registerNative(
+            Get<const TextFormat_as, boost::uint32_t,
+            &TextFormat_as::blockIndent,
+            TwipsToPixels>::get, 110, 27);
     vm.registerNative(
             Set<TextFormat_as, boost::uint32_t, &TextFormat_as::blockIndentSet,
             PositiveTwips>::set,
@@ -427,82 +443,6 @@
 }
 
 as_value
-textformat_blockIndent(const fn_call& fn)
-{
-    TextFormat_as* relay = ensure<ThisIsNative<TextFormat_as> >(fn);
-
-       as_value ret;
-
-       if (fn.nargs == 0) 
-       {
-               if (relay->blockIndent()) {
-            ret.set_double(twipsToPixels(*relay->blockIndent()));
-        }
-               else ret.set_null();
-       }
-
-       return ret;
-}
-
-as_value
-textformat_leading(const fn_call& fn)
-{
-    TextFormat_as* relay = ensure<ThisIsNative<TextFormat_as> >(fn);
-
-       as_value ret;
-
-       if ( fn.nargs == 0 ) // getter
-       {
-               if (relay->leading()) 
ret.set_double(twipsToPixels(*relay->leading()));
-               else ret.set_null();
-       }
-       else // setter
-       {
-               relay->leadingSet(pixelsToTwips(toInt(fn.arg(0))));
-       }
-
-       return ret;
-}
-
-as_value
-textformat_indent(const fn_call& fn)
-{
-    TextFormat_as* relay = ensure<ThisIsNative<TextFormat_as> >(fn);
-
-       as_value ret;
-
-       if ( fn.nargs == 0 ) // getter
-       {
-               if (relay->indent()) 
ret.set_double(twipsToPixels(*relay->indent()));
-               else ret.set_null();
-       }
-
-       return ret;
-}
-
-as_value
-textformat_align(const fn_call& fn)
-{
-    TextFormat_as* relay = ensure<ThisIsNative<TextFormat_as> >(fn);
-
-       as_value ret;
-
-       if ( fn.nargs == 0 ) // getter
-       {
-               if (relay->align()) {
-            ret.set_string(getAlignString(*relay->align()));
-        }
-        else ret.set_null();
-       }
-       else // setter
-       {
-               relay->alignSet(fn.arg(0).to_string());
-       }
-
-       return ret;
-}
-
-as_value
 textformat_target(const fn_call& fn)
 {
     TextFormat_as* relay = ensure<ThisIsNative<TextFormat_as> >(fn);
@@ -565,26 +505,6 @@
 }
 
 as_value
-textformat_size(const fn_call& fn)
-{
-    TextFormat_as* relay = ensure<ThisIsNative<TextFormat_as> >(fn);
-
-       as_value ret;
-
-       if ( fn.nargs == 0 ) // getter
-       {
-               if (relay->size()) 
ret.set_double(twipsToPixels(*relay->size()));
-               else ret.set_null();
-       }
-       else // setter
-       {
-               relay->sizeSet(pixelsToTwips(toInt(fn.arg(0))));
-       }
-
-       return ret;
-}
-
-as_value
 textformat_font(const fn_call& fn)
 {
     TextFormat_as* relay = ensure<ThisIsNative<TextFormat_as> >(fn);
@@ -604,14 +524,121 @@
        return ret;
 }
 
-
+as_value
+textformat_align(const fn_call& fn)
+{
+    TextFormat_as* relay = ensure<ThisIsNative<TextFormat_as> >(fn);
+
+   as_value ret;
+
+   if ( fn.nargs == 0 ) // getter
+   {
+       if (relay->align()) {
+            ret.set_string(getAlignString(*relay->align()));
+        }
+        else ret.set_null();
+   }
+   else // setter
+   {
+       relay->alignSet(fn.arg(0).to_string());
+   }
+
+   return ret;
+}
+
+
+/// Return various dimensions of a theoretical run of text
+//
+/// The TextFormat's format values are used to calculate what the dimensions
+/// of a TextField would be if it contained the given text.
+//
+/// This may never apply to embedded fonts. There is no way to instruct the
+/// function to use embedded fonts, so it makes sense if it always chooses
+/// the device font.
+//
+/// TODO: this duplicates other functionality in TextField; ideally both
+/// should be fixed, tested, and merged.
 as_value
 textformat_getTextExtent(const fn_call& fn)
 {
+
     TextFormat_as* relay = ensure<ThisIsNative<TextFormat_as> >(fn);
-    UNUSED(relay);
-       LOG_ONCE( log_unimpl("TextFormat.getTextExtent") );
-       return as_value();
+    
+    if (!fn.nargs) {
+        IF_VERBOSE_ASCODING_ERRORS(
+            log_aserror("TextFormat.getTextExtent requires at least one"
+                "argument");
+        );
+        return as_value();
+    }
+
+    const int version = getSWFVersion(fn);
+    const std::string& s = fn.arg(0).to_string(version);
+
+    // Everything must be in twips here.
+
+    double tfw;
+    bool limitWidth = false;
+    if (fn.nargs > 1) {
+        limitWidth = true;
+        tfw = pixelsToTwips(fn.arg(1).to_number());       
+    }
+    else {
+        tfw = 0;
+    }
+
+    const bool bold = relay->bold() ? *relay->bold() : false;
+    const bool italic = relay->italic() ? *relay->italic() : false;
+    const double size = relay->size() ? *relay->size() : 240;
+
+    // Note: currently leading is never defined for device fonts, and since
+    // getTextExtent currently only takes account of device fonts we don't
+    // need it.
+
+    Font* f = relay->font() ?
+        fontlib::get_font(*relay->font(), bold, italic) :
+        fontlib::get_default_font().get();
+    
+    /// Advance, descent, ascent given according to square of 1024.
+    //
+    /// An ascent of 1024 is equal to the whole size of the character, so
+    /// 240 twips for a size 12.
+    const double scale = size / static_cast<double>(f->unitsPerEM(false));
+
+    double height = size;
+    double width = 0;
+    double curr = 0;
+    
+    const double ascent = f->ascent(false) * scale;
+    const double descent = f->descent(false) * scale;
+
+    for (std::string::const_iterator it = s.begin(), e = s.end();
+            it != e; ++it) {
+
+        int index = f->get_glyph_index(*it, false);
+        const double advance = f->get_advance(index, false) * scale;
+        if (limitWidth && (curr + advance > width)) {
+            curr = 0;
+            height += size;
+        }
+        curr += advance;
+        width = std::max(width, curr);
+
+    }
+
+    Global_as& gl = getGlobal(fn);
+    as_object* obj = new as_object(gl);
+
+    obj->init_member("textFieldHeight", twipsToPixels(height) + 4);
+    obj->init_member("textFieldWidth",
+            limitWidth ? twipsToPixels(tfw) : twipsToPixels(width) + 4);
+    obj->init_member("width", twipsToPixels(width));
+    obj->init_member("height", twipsToPixels(height));
+    obj->init_member("ascent", twipsToPixels(ascent));
+    obj->init_member("descent", twipsToPixels(descent));
+
+    return as_value(obj);
+
 }
 
 

=== modified file 'libcore/asobj/flash/text/TextFormat_as.h'
--- a/libcore/asobj/flash/text/TextFormat_as.h  2010-01-19 15:44:18 +0000
+++ b/libcore/asobj/flash/text/TextFormat_as.h  2010-01-22 08:25:47 +0000
@@ -148,7 +148,9 @@
     const Optional<std::string>& url() const { return _url; }
 
     /// The block indent.
-    const Optional<boost::uint32_t>& blockIndent() { return _blockIndent; }
+    const Optional<boost::uint32_t>& blockIndent() const {
+        return _blockIndent;
+    }
 
     /// Return a number that indicates the amount of leading vertical
     /// space between lines.

=== modified file 'testsuite/actionscript.all/TextField.as'
--- a/testsuite/actionscript.all/TextField.as   2010-01-01 17:48:26 +0000
+++ b/testsuite/actionscript.all/TextField.as   2010-01-25 10:47:59 +0000
@@ -961,9 +961,18 @@
 // test that adding a newline doesn't change the bounds width
 // see bug #22216
 tf.autoSize = 'center';
+
+// Word wrap is still true, so nothing should happen!
+check_equals(tf._width, 10);
 tf.text = "single line";
+
+// Changing text should also not change width.
+check_equals(tf._width, 10);
+
 linewidth = tf._width;
 tf.text = "single line\n";
+
+check_equals(tf._width, 10);
 check_equals(tf._width, linewidth); 
 
 // Test that setting autoSize = none
@@ -1278,11 +1287,11 @@
 //------------------------------------------------------------
 
 #if OUTPUT_VERSION == 6
-     check_totals(522);
+     check_totals(525);
 #elif OUTPUT_VERSION == 7
- check_totals(546);
+ check_totals(549);
 #elif OUTPUT_VERSION == 8
- check_totals(547);
+ check_totals(550);
 #endif
 
 #endif

=== modified file 'testsuite/actionscript.all/TextFormat.as'
--- a/testsuite/actionscript.all/TextFormat.as  2010-01-19 17:38:27 +0000
+++ b/testsuite/actionscript.all/TextFormat.as  2010-01-25 07:23:53 +0000
@@ -252,6 +252,33 @@
 tf.indent = undefined;
 check_equals(tf.indent, null);
 
+// size
+tf = new TextFormat();
+check_equals(tf.size, null);
+tf.size = 10;
+check_equals(tf.size, 10);
+
+tf.size = -10;
+xcheck_equals(tf.size, -10);
+
+tf.size = "string";
+#if OUTPUT_VERSION < 8
+check_equals(tf.size, 0);
+#else
+xcheck_equals(tf.size, -2147483648);
+#endif
+
+tf.size = null;
+check_equals(tf.size, null);
+
+tf.size = "string";
+#if OUTPUT_VERSION < 8
+check_equals(tf.size, 0);
+#else
+xcheck_equals(tf.size, -2147483648);
+#endif
+tf.size = undefined;
+check_equals(tf.size, null);
 
 // Check tabStops property.
 // The passed array is processed before assignment, not simply stored.
@@ -269,23 +296,28 @@
 
 tf2 = new TextFormat("Arial", 12);
 
-// Different behaviour.
+// getTextExtent has different behaviour for SWF6.
 #if OUTPUT_VERSION > 6
 
+// I don't know how to test this properly, as we can only test device fonts
+// here, and the pp uses a different font from Gnash.
+
 te = tf2.getTextExtent("Hello");
 
 // The object is a bare object
 te.hasOwnProperty = Object.prototype.hasOwnProperty;
 
-xcheck(te.hasOwnProperty("ascent"));
-xcheck(te.hasOwnProperty("descent"));
-xcheck(te.hasOwnProperty("textFieldWidth"));
-xcheck(te.hasOwnProperty("textFieldHeight"));
-xcheck(te.hasOwnProperty("width"));
-xcheck(te.hasOwnProperty("height"));
+check(te.hasOwnProperty("ascent"));
+check(te.hasOwnProperty("descent"));
+check(te.hasOwnProperty("textFieldWidth"));
+check(te.hasOwnProperty("textFieldHeight"));
+check(te.hasOwnProperty("width"));
+check(te.hasOwnProperty("height"));
 
 xcheck_equals(Math.round(te.textFieldHeight), 18);
 xcheck_equals(Math.round(te.textFieldWidth), 33);
+check_equals(Math.round(te.ascent), 11);
+check_equals(Math.round(te.descent), 3);
 
 te = tf2.getTextExtent("Hello", 10);
 #if OUTPUT_VERSION > 7
@@ -294,10 +326,10 @@
 xcheck_equals(Math.round(te.textFieldHeight), 18);
 #endif
 
-xcheck_equals(te.textFieldWidth, 10);
+check_equals(te.textFieldWidth, 10);
 
 #if OUTPUT_VERSION > 7
-xcheck_equals(Math.round(te.width), 9);
+check_equals(Math.round(te.width), 9);
 #else
 xcheck_equals(Math.round(te.width), 29);
 #endif
@@ -309,26 +341,53 @@
 #else
 xcheck_equals(Math.round(te.textFieldHeight), 18);
 #endif
-xcheck_equals(te.textFieldWidth, 5);
-
+check_equals(te.textFieldWidth, 5);
+check_equals(Math.round(te.ascent), 11);
+check_equals(Math.round(te.descent), 3);
 
 #if OUTPUT_VERSION > 7
 // Width of largest character in version 8?
-xcheck_equals(Math.round(te.width), 9);
+check_equals(Math.round(te.width), 9);
 #else
 xcheck_equals(Math.round(te.width), 29);
 #endif
 
+
 te = tf2.getTextExtent("Longer sentence with more words.", 30);
-xcheck_equals(te.textFieldWidth, 30);
+check_equals(te.textFieldWidth, 30);
 xcheck_equals(Math.round(te.width), 25);
 
+te = tf2.getTextExtent("o");
+xcheck_equals(Math.round(te.textFieldHeight), 18);
+check_equals(Math.round(te.textFieldWidth), 11);
+check_equals(Math.round(te.ascent), 11);
+check_equals(Math.round(te.descent), 3);
+
+te = tf2.getTextExtent("oo");
+xcheck_equals(Math.round(te.textFieldHeight), 18);
+xcheck_equals(Math.round(te.textFieldWidth), 18);
+check_equals(Math.round(te.ascent), 11);
+check_equals(Math.round(te.descent), 3);
+
+te = tf2.getTextExtent("ool");
+xcheck_equals(Math.round(te.textFieldHeight), 18);
+xcheck_equals(Math.round(te.textFieldWidth), 21);
+check_equals(Math.round(te.ascent), 11);
+check_equals(Math.round(te.descent), 3);
+
+tf2.size = 20;
+te = tf2.getTextExtent("ool");
+xcheck_equals(Math.round(te.textFieldHeight), 28);
+xcheck_equals(Math.round(te.textFieldWidth), 32);
+xcheck_equals(Math.round(te.ascent), 19);
+xcheck_equals(Math.round(te.descent), 5);
+
 #endif
 
 #if OUTPUT_VERSION < 7
-    check_totals(107);
+    check_totals(114);
 #elif OUTPUT_VERSION == 7
-    check_totals(123);
+    check_totals(150);
 #else 
-    check_totals(123);
+    check_totals(150);
 #endif


reply via email to

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