gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] /srv/bzr/gnash/trunk r10251: Move most Font-related parsi


From: Benjamin Wolsey
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r10251: Move most Font-related parsing to libcore/swf, so that the Font class
Date: Sat, 08 Nov 2008 20:47:47 +0100
User-agent: Bazaar (1.5)

------------------------------------------------------------
revno: 10251
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Sat 2008-11-08 20:47:47 +0100
message:
  Move most Font-related parsing to libcore/swf, so that the Font class
  is either constructed with an immutable DefineFontTag or from a 
  device font. The Tag-related part of the Font (embedded glyphs and
  records) is immutable. Device-font glyphs can be added on demand
  as before. There should be no reason to change the Font externally.
added:
  libcore/swf/DefineFontTag.cpp
  libcore/swf/DefineFontTag.h
renamed:
  libcore/font.cpp => libcore/Font.cpp
  libcore/font.h => libcore/Font.h
modified:
  libcore/Makefile.am
  libcore/TextField.cpp
  libcore/TextField.h
  libcore/fontlib.cpp
  libcore/fontlib.h
  libcore/impl.cpp
  libcore/parser/SWFMovieDefinition.cpp
  libcore/parser/SWFMovieDefinition.h
  libcore/parser/movie_definition.h
  libcore/parser/sprite_definition.h
  libcore/swf/DefineEditTextTag.cpp
  libcore/swf/DefineEditTextTag.h
  libcore/swf/DefineFontAlignZonesTag.cpp
  libcore/swf/TextRecord.cpp
  libcore/swf/TextRecord.h
  libcore/swf/tag_loaders.cpp
  libcore/swf/tag_loaders.h
  libcore/Font.cpp
  libcore/Font.h
    ------------------------------------------------------------
    revno: 10244.1.2
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Sat 2008-11-08 13:27:44 +0100
    message:
      Clean up indentation, obsolete code, and rearrange font class.
    modified:
      libcore/font.cpp
      libcore/font.h
    ------------------------------------------------------------
    revno: 10244.1.3
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Sat 2008-11-08 18:30:07 +0100
    message:
      Move DefineFont and DefineFont2 parsing into 
libcore/swf/DefineFontTag.{h,cpp}.
      A font can now be constructed only as an embedded font (with a 
DefineFontTag)
      or a device font (with name, bold, italic).
    added:
      libcore/swf/DefineFontTag.cpp
      libcore/swf/DefineFontTag.h
    modified:
      libcore/Makefile.am
      libcore/font.cpp
      libcore/font.h
      libcore/impl.cpp
      libcore/swf/tag_loaders.cpp
      libcore/swf/tag_loaders.h
    ------------------------------------------------------------
    revno: 10244.1.4
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Sat 2008-11-08 19:03:33 +0100
    message:
      Rename font to Font.
    renamed:
      libcore/font.cpp => libcore/Font.cpp
      libcore/font.h => libcore/Font.h
    modified:
      libcore/Makefile.am
      libcore/TextField.cpp
      libcore/TextField.h
      libcore/fontlib.cpp
      libcore/fontlib.h
      libcore/impl.cpp
      libcore/parser/SWFMovieDefinition.cpp
      libcore/parser/SWFMovieDefinition.h
      libcore/parser/movie_definition.h
      libcore/parser/sprite_definition.h
      libcore/swf/DefineEditTextTag.cpp
      libcore/swf/DefineEditTextTag.h
      libcore/swf/DefineFontAlignZonesTag.cpp
      libcore/swf/DefineFontTag.cpp
      libcore/swf/DefineFontTag.h
      libcore/swf/TextRecord.cpp
      libcore/swf/TextRecord.h
      libcore/swf/tag_loaders.cpp
      libcore/Font.cpp
      libcore/Font.h
    ------------------------------------------------------------
    revno: 10244.1.5
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Sat 2008-11-08 19:30:00 +0100
    message:
      More renaming, and move more parsing to DefineFontTag.
    modified:
      libcore/Font.cpp
      libcore/Font.h
      libcore/swf/DefineFontTag.cpp
      libcore/swf/DefineFontTag.h
    ------------------------------------------------------------
    revno: 10244.1.6
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Sat 2008-11-08 19:45:25 +0100
    message:
      Yes, it is possible for embedded fonts to be requested when there isn't
      one, so handle it gracefully.
    modified:
      libcore/Font.cpp
      libcore/Font.h
    ------------------------------------------------------------
    revno: 10244.1.7
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Sat 2008-11-08 20:14:15 +0100
    message:
      Dox.
    modified:
      libcore/Font.h
      libcore/swf/DefineFontTag.h
=== renamed file 'libcore/font.cpp' => 'libcore/Font.cpp'
--- a/libcore/font.cpp  2008-09-04 15:32:42 +0000
+++ b/libcore/Font.cpp  2008-11-08 18:45:25 +0000
@@ -1,4 +1,4 @@
-// font.cpp:  ActionScript font handling, for Gnash.
+// Font.cpp:  ActionScript Font handling, for Gnash.
 // 
 //   Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.
 // 
@@ -21,32 +21,34 @@
 // Based on the public domain work of Thatcher Ulrich <address@hidden> 2003
 
 #include "smart_ptr.h" // GNASH_USE_GC
-#include "font.h"
+#include "Font.h"
 #include "SWFStream.h"
 #include "log.h"
 #include "movie_definition.h"
 #include "shape_character_def.h"
 #include "swf.h"
 #include "GnashException.h"
-#include "utility.h" // for UNUSED
+#include "DefineFontTag.h"
 
 #include <utility> // for std::make_pair
 
 namespace gnash {
 
-GlyphInfo::GlyphInfo()
+
+Font::GlyphInfo::GlyphInfo()
        :
        glyph(),
        advance(0)
 {}
 
-GlyphInfo::GlyphInfo(boost::intrusive_ptr<shape_character_def> nGlyph, float 
nAdvance)
+Font::GlyphInfo::GlyphInfo(boost::intrusive_ptr<shape_character_def> glyph,
+        float advance)
        :
-       glyph(nGlyph.get()),
-       advance(nAdvance)
+       glyph(glyph.get()),
+       advance(advance)
 {}
 
-GlyphInfo::GlyphInfo(const GlyphInfo& o)
+Font::GlyphInfo::GlyphInfo(const GlyphInfo& o)
        :
        glyph(o.glyph.get()),
        advance(o.advance)
@@ -54,584 +56,287 @@
 
 #ifdef GNASH_USE_GC
 void
-GlyphInfo::markReachableResources() const
+Font::GlyphInfo::markReachableResources() const
 {
        if ( glyph ) glyph->setReachable();
 }
 #endif
 
-       font::font()
-               :
-               m_name(),
-                m_display_name(),
-                m_copyright_name(),
-               m_unicode_chars(false),
-               m_shift_jis_chars(false),
-               m_ansi_chars(true),
-               m_is_italic(false),
-               m_is_bold(false),
-               m_wide_codes(false),
-               m_subpixel_font(false),
-               m_ascent(0.0f),
-               m_descent(0.0f),
-               m_leading(0.0f)
-       {
-       }
-
-       font::font(const std::string& name, bool bold, bool italic)
-               :
-               m_name(name),
-                m_display_name(),
-                m_copyright_name(),
-               m_unicode_chars(false),
-               m_shift_jis_chars(false),
-               m_ansi_chars(true),
-               m_is_italic(italic),
-               m_is_bold(bold),
-               m_wide_codes(false),
-               m_subpixel_font(false),
-               m_ascent(0.0f),
-               m_descent(0.0f),
-               m_leading(0.0f)
-       {
-               assert(!m_name.empty());
-
-#if 0 // will be initialized when needed, hopefully only by main thread
-               if ( ! initDeviceFontProvider() )
-               {
-                       log_error(_("Could not initialize device font face 
'%s'"), m_name.c_str());
-               }
-               else
-               {
-                       log_debug("Initialized device font face '%s'%s%s", 
m_name, bold ? " bold" : "", italic ? " italic" : "");
-               }
-#endif
-       }
-
-       font::~font()
-       {
-               //m_glyphs.resize(0); // there's no need for this !
-       }
-
-       shape_character_def*    font::get_glyph(int index, bool embedded) const
-       {
-               const GlyphInfoVect& lookup = embedded ? _embedGlyphTable : 
_deviceGlyphTable;
-
-               if (index >= 0 && (size_t)index < lookup.size())
-               {
-                       return lookup[index].glyph.get();
-               }
-               else
-               {
-                       // TODO: should we log an error here ?
-                       return NULL;
-               }
-       }
-
-
-       void    font::read(SWFStream& in, SWF::tag_type tag, movie_definition& 
m)
-       {
-               if (tag == SWF::DEFINEFONT)
-               {
-                       readDefineFont(in, m);
-               }
-               else
-               {
-                       assert (tag == SWF::DEFINEFONT2 || tag == 
SWF::DEFINEFONT3);
-                       readDefineFont2_or_3(in, m);
-                       if (tag == SWF::DEFINEFONT3)
-                       {
-                               m_subpixel_font = true;
-                       }
-               }
-
-#if 0 // initialize the deviceFontProvider only when needed !
-               if ( ! m_name.empty() && ! initDeviceFontProvider() )
-               {
-                       log_error("Could not initialize device font face '%s'", 
m_name.c_str());
-               }
-#endif
-       }
-
-       // Read a DefineFont tag
-       void font::readDefineFont(SWFStream& in, movie_definition& m)
-       {
-               IF_VERBOSE_PARSE (
-               log_parse(_("reading DefineFont"));
-               );
-
-               unsigned long table_base = in.tell();
-
-               // Read the glyph offsets.  Offsets
-               // are measured from the start of the
-               // offset table.
-               std::vector<unsigned>   offsets;
-               in.ensureBytes(2);
-               offsets.push_back(in.read_u16());
-
-               IF_VERBOSE_PARSE (
-               log_parse("offset[0] = %d", offsets[0]);
-               );
-
-               int     count = offsets[0] >> 1;
-               if ( count > 0 )
-               {
-                       in.ensureBytes(count*2);
-                       for (int i = 1; i < count; i++)
-                       {
-                               offsets.push_back(in.read_u16());
-
-                               IF_VERBOSE_PARSE (
-                               log_parse("offset[%d] = %d", i, offsets[i]);
-                               );
-                       }
-               }
-               else
-               {
-                       log_error("Negative embedded glyph table size: %d", 
count);
-               }
-
-               _embedGlyphTable.resize(count);
-
-               // Read the glyph shapes.
-               for (int i = 0; i < count; i++)
-               {
-                       // Seek to the start of the shape data.
-                       unsigned long new_pos = table_base + offsets[i];
-
-                       if ( ! in.seek(new_pos) )
-                       {
-                               throw ParserException(_("Glyphs offset table 
corrupted in DefineFont tag"));
-                       }
-
-                       // Create & read the shape.
-                       shape_character_def* s = new shape_character_def;
-                       s->read(in, SWF::DEFINEFONT, false, m); 
-
-                       _embedGlyphTable[i].glyph = s;
-               }
-       }
-
-       // Read a DefineFont2 or DefineFont3 tag
-       void font::readDefineFont2_or_3(SWFStream& in, movie_definition& m)
-       {
-               IF_VERBOSE_PARSE (
-               log_parse(_("reading DefineFont2 or DefineFont3"));
-               );
-
-               in.ensureBytes(2); // 1 for the flags, 1 unknown
-               int flags = in.read_u8();
-               bool  has_layout   = flags & (1 << 7);
-               m_shift_jis_chars  = flags & (1 << 6);
-               m_unicode_chars    = flags & (1 << 5);
-               m_ansi_chars       = flags & (1 << 4);
-               bool  wide_offsets = flags & (1 << 3);
-               m_wide_codes       = flags & (1 << 2);
-               m_is_italic        = flags & (1 << 1);
-               m_is_bold          = flags & (1 << 0);
-
-               // Next is language code, always 0 for SWF5 or previous
-               int languageCode = in.read_u8();
-               LOG_ONCE( if (languageCode) { log_unimpl("LanguageCode in 
DefineFont (2 or 3)"); } );
-
-               in.read_string_with_length(m_name);
-
-               in.ensureBytes(2); 
-               boost::uint16_t glyph_count = in.read_u16();
-
-               IF_VERBOSE_PARSE (
-            log_parse(" has_layout = %d", has_layout);
-           log_parse(" shift_jis_chars = %d", m_shift_jis_chars);
-            log_parse(" m_unicode_chars = %d", m_unicode_chars);
-            log_parse(" m_ansi_chars = %d", m_ansi_chars);
-            log_parse(" wide_offsets = %d", wide_offsets);
-            log_parse(" wide_codes = %d", m_wide_codes);
-            log_parse(" is_italic = %d", m_is_italic);
-            log_parse(" is_bold = %d", m_is_bold);
-            log_parse(" name = %s", m_name);
-            log_parse(" glyphs count = %d", glyph_count);
-               );
-
-               
-               unsigned long table_base = in.tell();
-
-               // Read the glyph offsets.  Offsets
-               // are measured from the start of the
-               // offset table. Make sure wide offsets fit into elements
-               std::vector<boost::uint32_t>    offsets;
-               int     font_code_offset;
-               if (wide_offsets)
-               {
-                       // 32-bit offsets.
-                       in.ensureBytes(4*glyph_count + 4); 
-                       for (unsigned int i = 0; i < glyph_count; i++)
-                       {
-                               boost::uint32_t off = in.read_u32();    
-
-                               IF_VERBOSE_PARSE (
-                               log_parse(_("Glyph %d at offset %u"), i, off);
-                               );
-
-                               offsets.push_back(off);
-                       }
-                       font_code_offset = in.read_u32();
-               }
-               else
-               {
-                       // 16-bit offsets.
-                       in.ensureBytes(2*glyph_count + 2); 
-                       for (unsigned int i = 0; i < glyph_count; i++)
-                       {
-                               boost::uint16_t off = in.read_u16();    
-
-                               IF_VERBOSE_PARSE (
-                               log_parse(_("Glyph %d at offset %u"), i, off);
-                               );
-
-                               offsets.push_back(off);
-                       }
-                       font_code_offset = in.read_u16();
-               }
-
-               _embedGlyphTable.resize(glyph_count);
-
-               // Read the glyph shapes.
-               for (int i = 0; i < glyph_count; i++)
-               {
-                       // Seek to the start of the shape data.
-                       unsigned long new_pos = table_base + offsets[i];
-
-                       // It seems completely possible to
-                       // have such seeks-back, see bug #16311
-                       //assert(new_pos >= in.tell());
-
-                       if ( ! in.seek(new_pos) )
-                       {
-                               throw ParserException(_("Glyphs offset table 
corrupted in DefineFont2/3 tag"));
-                       }
-
-                       // Create & read the shape.
-                       shape_character_def* s = new shape_character_def;
-                       s->read(in, SWF::DEFINEFONT2, false, m); // .. or 
DEFINEFONT3 actually..
-
-                       _embedGlyphTable[i].glyph = s;
-               }
-
-               unsigned long current_position = in.tell();
-               if (font_code_offset + table_base != current_position)
-               {
-                       // Bad offset!  Don't try to read any more.
-                       IF_VERBOSE_MALFORMED_SWF(
-                       log_swferror(_("Bad offset in DefineFont2"));
-                       );
-                       return;
-               }
-
-               read_code_table(in);
-
-               // Read layout info for the glyphs.
-               if (has_layout)
-               {
-                       in.ensureBytes(6);
-                       m_ascent = (float) in.read_s16();
-                       m_descent = (float) in.read_s16();
-                       m_leading = (float) in.read_s16();
-                       
-                       // Advance table; i.e. how wide each character is.
-                       size_t nGlyphs = _embedGlyphTable.size();
-                       in.ensureBytes(nGlyphs*2);
-                       for (size_t i = 0; i < nGlyphs; i++)
-                       {
-                               _embedGlyphTable[i].advance = (float) 
in.read_s16();
-                       }
-
-                       // Bounds table.
-                       {
-                               rect    dummy_rect;
-                               // TODO: shouldn't we log_unimpl here ??
-                               for (size_t i = 0; i < nGlyphs; i++) 
dummy_rect.read(in);
-                       }
-
-                       // Kerning pairs.
-                       in.ensureBytes(2);
-                       int     kerning_count = in.read_u16();
-                       if ( m_wide_codes )
-                       {
-                               in.ensureBytes(6*kerning_count); // includes 
the adjustment 
-                       }
-                       else
-                       {
-                               in.ensureBytes(4*kerning_count); // includes 
the adjustment 
-                       }
-
-                       for (int i = 0; i < kerning_count; i++)
-                       {
-                               boost::uint16_t char0, char1;
-                               if (m_wide_codes)
-                               {
-                                       char0 = in.read_u16();
-                                       char1 = in.read_u16();
-                               }
-                               else
-                               {
-                                       char0 = in.read_u8();
-                                       char1 = in.read_u8();
-                               }
-                               float   adjustment = (float) in.read_s16();
-
-                               kerning_pair    k;
-                               k.m_char0 = char0;
-                               k.m_char1 = char1;
-
-       // Remember this adjustment; we can look it up quickly
-       // later using the character pair as the key.
-       if ( ! m_kerning_pairs.insert(std::make_pair(k, adjustment)).second )
-       {
-               IF_VERBOSE_MALFORMED_SWF(
-               log_swferror(_("Repeated kerning pair found - ignoring"));
-               );
-       }
-
-                       }
-               }
-       }
-
-        // Read the font name, display and legal, from a DefineFontName tag.
-        void font::read_font_name(SWFStream& in, SWF::tag_type tag,
-            movie_definition& /*m*/) 
-        {
-            assert(tag == SWF::DEFINEFONTNAME);
-            in.read_string(m_display_name);
-            in.read_string(m_copyright_name);
-        }
-
-       // Read additional information about this font, from a
-       // DefineFontInfo tag.  The caller has already read the tag
-       // type and font id.
-       void    font::read_font_info(SWFStream& in, SWF::tag_type tag,
-                       movie_definition& /*m*/)
-       {
-               assert(tag == SWF::DEFINEFONTINFO || tag == 
SWF::DEFINEFONTINFO2); 
-
-               if ( tag == SWF::DEFINEFONTINFO2 )
-               {
-                       // See: SWFalexref/SWFalexref.html#tag_definefont2
-                       static bool warned = false;
-                       if ( ! warned ) {
-                               log_unimpl(_("DefineFontInfo2 partially 
implemented"));
-                               warned = true;
-                       }
-               }
-
-               in.read_string_with_length(m_name);
-#if 0 // initialize the deviceFontProvider only when needed !
-               if ( ! m_name.empty() && ! initDeviceFontProvider() )
-               {
-                       log_error(_("Could not initialize device font face 
'%s'"), m_name.c_str());
-               }
-#endif
-
-               in.ensureBytes(1);
-               int     flags = in.read_u8();
-        // highest two bits are reserved.
-               m_unicode_chars   = flags & (1 << 5); //???
-               m_shift_jis_chars = flags & (1 << 4);
-               m_ansi_chars      = flags & (1 << 3);
-               m_is_italic       = flags & (1 << 2);
-               m_is_bold         = flags & (1 << 1);
-               m_wide_codes      = flags & (1 << 0);
-
-               read_code_table(in);
-       }
-
-       void    font::read_code_table(SWFStream& in)
-       {
-               IF_VERBOSE_PARSE (
-               log_parse(_("reading code table at offset %lu"), in.tell());
-               );
-
-               assert(_embedded_code_table.empty());
-
-               size_t nGlyphs = _embedGlyphTable.size();
-               if (m_wide_codes)
-               {
-                       in.ensureBytes(2*nGlyphs);
-                       // Code table is made of boost::uint16_t's.
-                       for (size_t i=0; i<nGlyphs; ++i)
-                       {
-                               boost::uint16_t code = in.read_u16();
-                               
_embedded_code_table.insert(std::make_pair(code, i));
-                       }
-               }
-               else
-               {
-                       // Code table is made of bytes.
-                       in.ensureBytes(1*nGlyphs);
-                       for (size_t i=0; i<nGlyphs; ++i)
-                       {
-                               boost::uint8_t code = in.read_u8();
-                               
_embedded_code_table.insert(std::make_pair(code, i));
-                       }
-               }
-       }
-
-       int     font::get_glyph_index(boost::uint16_t code, bool embedded) const
-       {
-               const code_table& ctable = embedded ? _embedded_code_table : 
_device_code_table;
-
-               int glyph_index = -1;
-               code_table::const_iterator it = ctable.find(code);
-               if ( it != ctable.end() )
-               {
-                       glyph_index = it->second;
-#if 0
-                       log_debug(_("get_glyph_index(%u) returning %d"),
-                               code, glyph_index);
-#endif
-                       return glyph_index;
-               }
-
-               // Try adding an os font, of possible
-               if ( ! embedded )
-               {
-                       glyph_index = 
const_cast<font*>(this)->add_os_glyph(code);
-               }
-#if 0
-               log_debug(_("get_glyph_index(%u) returning -1"), code);
-#endif
-               return glyph_index;
-       }
-
-       float   font::get_advance(int glyph_index, bool embedded) const
-       {
-               const GlyphInfoVect& lookup = embedded ? _embedGlyphTable : 
_deviceGlyphTable;
-
-               if (glyph_index <= -1)
-               {
-                       // Default advance.
-                       return 512.0f;
-               }
-
-               if ((size_t)glyph_index < lookup.size())
-               {
-                       assert(glyph_index >= 0);
-                       return lookup[glyph_index].advance;
-               }
-               else
-               {
-                       // Bad glyph index.  Due to bad data file?
-                       abort();
-                       return 0;
-               }
-       }
-
-
-       // Return the adjustment in advance between the given two
-       // characters.  Normally this will be 0; i.e. the 
-       float   font::get_kerning_adjustment(int last_code, int code) const
-       {
-               kerning_pair    k;
-               k.m_char0 = last_code;
-               k.m_char1 = code;
-               kernings_table::const_iterator it = m_kerning_pairs.find(k);
-               if ( it != m_kerning_pairs.end() )
-               {
-                       float   adjustment = it->second;
-                       return adjustment;
-               }
-               return 0;
-       }
-
-       unsigned short int 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 ( m_subpixel_font ) return 1024*20;
-                       else return 1024;
-               }
-               else
-               {
-                       if ( ! _ftProvider.get() )
-                       {
-                               if ( ! initDeviceFontProvider() )
-                               {
-                                       log_error("Device font provider was not 
initialized, can't get unitsPerEM");
-                                       return 0; // can't query it..
-                               }
-                       }
-                       return _ftProvider->unitsPerEM();
-               }
-       }
-
-       int
-       font::add_os_glyph(boost::uint16_t code)
-       {
-               if ( ! _ftProvider.get() )
-               {
-                       if ( ! initDeviceFontProvider() )
-                       {
-                               log_error("Device font provider was not 
initialized, can't get unitsPerEM");
-                               return -1; // can't provide it...
-                       }
-               }
-
-               assert(_device_code_table.find(code) == 
_device_code_table.end());
-
-               float advance;
-
-               // Get the vectorial glyph
-               boost::intrusive_ptr<shape_character_def> sh = 
_ftProvider->getGlyph(code, advance);
-
-               if ( ! sh )
-               {
-                       log_error("Could not create shape "
-                                       "glyph for character code %u (%c) with "
-                                       "device font %s (%p)", code, code, 
m_name.c_str(),
-                                       _ftProvider.get());
-                       return -1;
-               }
-
-               // Find new glyph offset
-               int newOffset = _deviceGlyphTable.size();
-
-               // Add the new glyph id
-               _device_code_table[code] = newOffset;
-
-               _deviceGlyphTable.push_back(GlyphInfo(sh, advance));
-
-               testInvariant();
-
-               return newOffset;
-       }
-
-       bool
-       font::initDeviceFontProvider() const
-       {
-               if ( m_name.empty() )
-               {
-                       log_error("No name associated with this font, can't use 
device fonts (should I use a default one?)");
-                       return false;
-               }
-
-               _ftProvider = 
FreetypeGlyphsProvider::createFace(m_name.c_str(), m_is_bold, m_is_italic);
-               if ( ! _ftProvider.get() )
-               {
-                       log_error("Could not create a freetype face %s", 
m_name.c_str());
-                       return false;
-               }
-               return true;
-       }
-
-bool
-font::matches(const std::string& name, bool bold, bool italic) const
-{
-       if ( bold != isBold() ) return false;
-       if ( italic != isItalic() ) return false;
-       if ( name != get_name() ) return false;
-
-       return true;
+Font::Font(std::auto_ptr<SWF::DefineFontTag> ft)
+    :
+    _fontTag(ft.release()),
+    _name(_fontTag->name()),
+    m_display_name(),
+    m_copyright_name(),
+    m_unicode_chars(_fontTag->unicodeChars()),
+    m_shift_jis_chars(_fontTag->shiftJISChars()),
+    m_ansi_chars(_fontTag->ansiChars()),
+    _italic(_fontTag->italic()),
+    _bold(_fontTag->bold()),
+    m_wide_codes(_fontTag->wideCodes())
+{
+    if (_fontTag->hasCodeTable()) _embeddedCodeTable = 
_fontTag->getCodeTable();
+}
+
+Font::Font(const std::string& name, bool bold, bool italic)
+    :
+    _fontTag(0),
+    _name(name),
+    m_display_name(),
+    m_copyright_name(),
+    m_unicode_chars(false),
+    m_shift_jis_chars(false),
+    m_ansi_chars(true),
+    _italic(italic),
+    _bold(bold),
+    m_wide_codes(false)
+{
+    assert(!_name.empty());
+}
+
+Font::~Font()
+{
+}
+
+shape_character_def*
+Font::get_glyph(int index, bool embedded) const
+{
+    // What to do if embedded is true and this is a
+    // device-only font?
+    const GlyphInfoRecords& lookup = (embedded && _fontTag) ? 
+            _fontTag->glyphTable() : _deviceGlyphTable;
+
+    if (index >= 0 && (size_t)index < lookup.size())
+    {
+        return lookup[index].glyph.get();
+    }
+    else
+    {
+        // TODO: should we log an error here ?
+        return NULL;
+    }
+}
+
+
+// Read the font name, display and legal, from a DefineFontName tag.
+void Font::read_font_name(SWFStream& in, SWF::tag_type tag,
+    movie_definition& /*m*/) 
+{
+    assert(tag == SWF::DEFINEFONTNAME);
+    in.read_string(m_display_name);
+    in.read_string(m_copyright_name);
+}
+
+// TODO: move libcore/swf
+// Read additional information about this font, from a
+// DefineFontInfo tag.  The caller has already read the tag
+// type and font id.
+void   Font::read_font_info(SWFStream& in, SWF::tag_type tag,
+        movie_definition& /*m*/)
+{
+    assert(tag == SWF::DEFINEFONTINFO || tag == SWF::DEFINEFONTINFO2); 
+
+    if ( tag == SWF::DEFINEFONTINFO2 )
+    {
+        // See: SWFalexref/SWFalexref.html#tag_definefont2
+        LOG_ONCE(log_unimpl(_("DefineFontInfo2 partially implemented")));
+    }
+
+    // Can a DefineFontInfo or DefineFontInfo2 tag possibly be called on
+    // a device-only font? Otherwise the font won't exist.
+    assert(_fontTag.get());
+
+    in.read_string_with_length(_name);
+
+    in.ensureBytes(1);
+    int        flags = in.read_u8();
+    // highest two bits are reserved.
+    m_unicode_chars   = flags & (1 << 5); //???
+    m_shift_jis_chars = flags & (1 << 4);
+    m_ansi_chars      = flags & (1 << 3);
+    _italic       = flags & (1 << 2);
+    _bold         = flags & (1 << 1);
+    m_wide_codes      = flags & (1 << 0);
+
+    std::auto_ptr<CodeTable> table(new CodeTable);
+    SWF::DefineFontTag::readCodeTable(in, *table, m_wide_codes,
+            _fontTag->glyphTable().size());
+
+    _embeddedCodeTable.reset(table.release());
+}
+
+int    Font::get_glyph_index(boost::uint16_t code, bool embedded) const
+{
+    const CodeTable& ctable = (embedded && _embeddedCodeTable) ? 
+        *_embeddedCodeTable : _deviceCodeTable;
+
+    int glyph_index = -1;
+    CodeTable::const_iterator it = ctable.find(code);
+    if ( it != ctable.end() )
+    {
+        glyph_index = it->second;
+        return glyph_index;
+    }
+
+    // Try adding an os font, of possible
+    if ( ! embedded )
+    {
+        glyph_index = const_cast<Font*>(this)->add_os_glyph(code);
+    }
+    return glyph_index;
+}
+
+float Font::get_advance(int glyph_index, bool embedded) const
+{
+    // What to do if embedded is true and this is a
+    // device-only font?
+    const GlyphInfoRecords& lookup = (embedded && _fontTag) ? 
+            _fontTag->glyphTable() : _deviceGlyphTable;
+
+    if (glyph_index < 0)
+    {
+        // Default advance.
+        return 512.0f;
+    }
+
+    if (static_cast<size_t>(glyph_index) < lookup.size())
+    {
+        assert(glyph_index >= 0);
+        return lookup[glyph_index].advance;
+    }
+    else
+    {
+        // Bad glyph index.  Due to bad data file?
+        abort();
+        return 0;
+    }
+}
+
+
+// Return the adjustment in advance between the given two
+// characters.  Normally this will be 0; i.e. the 
+float  Font::get_kerning_adjustment(int last_code, int code) const
+{
+    kerning_pair       k;
+    k.m_char0 = last_code;
+    k.m_char1 = code;
+    kernings_table::const_iterator it = m_kerning_pairs.find(k);
+    if ( it != m_kerning_pairs.end() )
+    {
+        float adjustment = it->second;
+        return adjustment;
+    }
+    return 0;
+}
+
+unsigned short int 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;
+        else return 1024;
+    }
+    else
+    {
+        if ( ! _ftProvider.get() )
+        {
+            if ( ! initDeviceFontProvider() )
+            {
+                log_error("Device font provider was not initialized, "
+                        "can't get unitsPerEM");
+                return 0; // can't query it..
+            }
+        }
+        return _ftProvider->unitsPerEM();
+    }
+}
+
+int
+Font::add_os_glyph(boost::uint16_t code)
+{
+    if ( ! _ftProvider.get() )
+    {
+        if ( ! initDeviceFontProvider() )
+        {
+            log_error("Device font provider was not initialized, can't "
+                    "get unitsPerEM");
+            return -1; // can't provide it...
+        }
+    }
+
+    assert(_deviceCodeTable.find(code) == _deviceCodeTable.end());
+
+    float advance;
+
+    // Get the vectorial glyph
+    boost::intrusive_ptr<shape_character_def> sh = _ftProvider->getGlyph(code, 
advance);
+
+    if ( ! sh )
+    {
+        log_error("Could not create shape "
+                "glyph for character code %u (%c) with "
+                "device font %s (%p)", code, code, _name,
+                _ftProvider.get());
+        return -1;
+    }
+
+    // Find new glyph offset
+    int newOffset = _deviceGlyphTable.size();
+
+    // Add the new glyph id
+    _deviceCodeTable[code] = newOffset;
+
+    _deviceGlyphTable.push_back(GlyphInfo(sh, advance));
+
+    testInvariant();
+
+    return newOffset;
+}
+
+bool
+Font::initDeviceFontProvider() const
+{
+    if ( _name.empty() )
+    {
+        log_error("No name associated with this font, can't use device fonts 
(should I use a default one?)");
+        return false;
+    }
+
+    _ftProvider = FreetypeGlyphsProvider::createFace(_name, _bold, _italic);
+    if ( ! _ftProvider.get() )
+    {
+        log_error("Could not create a freetype face %s", _name);
+        return false;
+    }
+    return true;
+}
+
+bool
+Font::matches(const std::string& name, bool bold, bool italic) const
+{
+       return (_bold == bold && _italic == italic && name ==_name);
+}
+
+// TODO: what about device fonts?
+float
+Font::get_leading() const {
+    return _fontTag ? _fontTag->leading() : 0.0f;
+}
+
+// TODO: what about device fonts?
+float
+Font::get_descent() const { 
+    return _fontTag ? _fontTag->leading() : 0.0f;
+}
+    
+// TODO: what about device fonts?
+bool
+Font::is_subpixel_font() const {
+    return _fontTag ? _fontTag->subpixelFont() : false;
 }
 
 #ifdef GNASH_USE_GC
@@ -641,16 +346,11 @@
 ///    - shape_character_defs (vector glyphs, devide and embeded)
 ///
 void
-font::markReachableResources() const
+Font::markReachableResources() const
 {
-       // Mark embed glyphs (textured and vector)
-       for (GlyphInfoVect::const_iterator i=_embedGlyphTable.begin(), 
e=_embedGlyphTable.end(); i!=e; ++i)
-       {
-               i->markReachableResources();
-       }
-
        // Mark device glyphs (textured and vector)
-       for (GlyphInfoVect::const_iterator i=_deviceGlyphTable.begin(), 
e=_deviceGlyphTable.end(); i!=e; ++i)
+       for (GlyphInfoRecords::const_iterator i = _deviceGlyphTable.begin(),
+            e=_deviceGlyphTable.end(); i != e; ++i)
        {
                i->markReachableResources();
        }

=== renamed file 'libcore/font.h' => 'libcore/Font.h'
--- a/libcore/font.h    2008-11-07 18:07:45 +0000
+++ b/libcore/Font.h    2008-11-08 19:14:15 +0000
@@ -1,4 +1,4 @@
-// font.h -- font class, for Gnash
+// Font.h -- Font class, for Gnash
 //
 //   Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 // 
@@ -30,18 +30,21 @@
 #include "bitmap_info.h" // for dtor visibility by smart pointer
 #include "FreetypeGlyphsProvider.h" // for device fonts support
 #include "log.h"
-#ifdef GNASH_USE_GC
-# include "GC.h"
-#endif
 
+#include <boost/scoped_ptr.hpp>
 #include <map>
 
-
-namespace gnash {
-
-class movie_definition;
-class shape_character_def;
-class SWFStream;
+namespace gnash {
+    class movie_definition;
+    class shape_character_def;
+    class SWFStream;
+    namespace SWF {
+        class DefineFontTag;
+    }
+}
+
+namespace gnash {
+
 
 
 // @@ replace this with a flat hash, or else a sorted array
@@ -77,36 +80,19 @@
        }
 }
 
-/// Glyph info structure
-struct GlyphInfo
-{
-       // no glyph, default textured glyph, 0 advance
-       GlyphInfo();
-
-       // given glyph and advance, default textured glyph
-       GlyphInfo(boost::intrusive_ptr<shape_character_def> nGlyph, float 
nAdvance);
-
-       GlyphInfo(const GlyphInfo&);
-
-#ifdef GNASH_USE_GC
-       /// Mark any glyph and texture glyph resources as reachable
-       void markReachableResources() const;
-#endif
-
-       boost::intrusive_ptr<shape_character_def> glyph;
-
-       float advance;
-};
-
 /// \brief
-/// A 'font' definition as read from SWF::DefineFont,
+/// A 'Font' definition as read from SWF::DefineFont,
 /// SWF::DefineFont2 or SWF::DefineFont3 tags.
 /// Includes definitions from SWF::DefineFontInfo tags
 ///
-class font : public ExportableResource
+class Font : public ExportableResource
 {
 public:
-       font();
+
+    // This table maps from Unicode character 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
        //
@@ -119,9 +105,9 @@
        /// @param italic
        ///     Whether to use the italic variant of the font.
        ///
-       font(const std::string& name, bool bold=false, bool italic=false);
+       Font(const std::string& name, bool bold=false, bool italic=false);
 
-       ~font();
+       ~Font();
 
        /// Return true if this font matches given name and flags
        //
@@ -156,15 +142,6 @@
        ///
        shape_character_def*    get_glyph(int glyph_index, bool embedded) const;
 
-       /// Read a DefineFont or DefineFont2 tag from an SWF stream 
-       //
-       /// @param in is the SWF stream
-       /// @param tag is the tag type either DefineFont or DefineFont2
-       /// @param m is the movie_definition containing this definition
-       ///          (used to resolve dictionary simbols referred to by glyphs, 
if any)
-       ///
-       void    read(SWFStream& in, SWF::tag_type tag, movie_definition& m);
-
        /// \brief
        /// Read additional information about this font, from a
        /// DefineFontInfo or DefineFontInfo2 tag. 
@@ -173,7 +150,7 @@
        ///
        /// @see SWF::define_font_info_loader
        ///
-       void    read_font_info(SWFStream& in, SWF::tag_type tag, 
movie_definition& m);
+       void read_font_info(SWFStream& in, SWF::tag_type tag, movie_definition& 
m);
 
     /// \brief
     /// Read the name of this font, from a DEFINEFONTNAME tag.
@@ -185,7 +162,7 @@
     void read_font_name(SWFStream& in, SWF::tag_type tag, movie_definition& m);
 
        /// Get name of this font. Warning: can be NULL.
-       const std::string& get_name() const { return m_name; }
+       const std::string& get_name() const { return _name; }
 
        /// Return the glyph index for a given character code
        //
@@ -215,7 +192,7 @@
        ///     If true, queries the 'embedded' glyphs table, 
        ///     otherwise, looks in the 'device' font table.
        ///
-       float   get_advance(int glyph_index, bool embedded) const;
+       float get_advance(int glyph_index, bool embedded) const;
 
        /// \brief
        /// Return the adjustment in advance between the given two
@@ -227,7 +204,7 @@
        ///       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;
+       float get_kerning_adjustment(int last_code, int this_code) const;
 
        /// Return height of the EM square used for glyphs definition
        //
@@ -237,25 +214,43 @@
        ///
        unsigned short int unitsPerEM(bool embedded) const;
 
-       float   get_leading() const { return m_leading; }
-       float   get_descent() const { return m_descent; }
-
-       bool    is_subpixel_font() const { return m_subpixel_font; }
-       void    set_subpixel_font(bool isit) { m_subpixel_font = isit; }
-
-       bool    isBold() const { return m_is_bold; }
-       bool    isItalic() const { return m_is_italic; }
+    // TODO: what about device fonts?
+       float get_leading() const;
+ 
+    // TODO: what about device fonts?
+    float get_descent() const;
+        
+       bool is_subpixel_font() const;
+
+       bool isBold() const { return _bold; }
+       bool isItalic() const { return _italic; }
+
+    /// Glyph info structure
+    struct GlyphInfo
+    {
+        // no glyph, default textured glyph, 0 advance
+        GlyphInfo();
+
+        // given glyph and advance, default textured glyph
+        GlyphInfo(boost::intrusive_ptr<shape_character_def> glyph,
+                float advance);
+
+        GlyphInfo(const GlyphInfo&);
+
+#ifdef GNASH_USE_GC
+        /// Mark any glyph and texture glyph resources as reachable
+        void markReachableResources() const;
+#endif
+
+        boost::intrusive_ptr<shape_character_def> glyph;
+
+        float advance;
+    };
+
+       typedef std::vector<GlyphInfo> GlyphInfoRecords;
+
 private:
 
-       /// Read the table that maps from glyph indices to character codes.
-       void    read_code_table(SWFStream& in);
-
-       /// Read a DefineFont2 or DefineFont3 tag
-       void readDefineFont2_or_3(SWFStream& in, movie_definition& m);
-
-       /// Read a DefineFont tag
-       void readDefineFont(SWFStream& in, movie_definition& m);
-
        /// Add a glyph from the os font into the device glyphs table
        //
        /// It is assumed that the glyph tables do NOT contain
@@ -274,41 +269,45 @@
        ///
        bool initDeviceFontProvider() const;
 
-       typedef std::vector< GlyphInfo > GlyphInfoVect;
-
-       // Embedded glyphs
-       GlyphInfoVect _embedGlyphTable;
+    /// If we were constructed from a definition, this is not NULL.
+    boost::scoped_ptr<SWF::DefineFontTag> _fontTag;
 
        // Device glyphs
-       GlyphInfoVect _deviceGlyphTable;
+       GlyphInfoRecords _deviceGlyphTable;
 
-       std::string     m_name;
-        std::string     m_display_name;
-        std::string     m_copyright_name;
+       std::string     _name;
+    std::string m_display_name;
+    std::string m_copyright_name;
 
        bool    m_has_layout;
        bool    m_unicode_chars;
        bool    m_shift_jis_chars;
        bool    m_ansi_chars;
-       bool    m_is_italic;
-       bool    m_is_bold;
+       bool    _italic;
+       bool    _bold;
        bool    m_wide_codes;
        bool    m_subpixel_font;
 
-       // This table maps from Unicode character number to glyph index.
-       typedef std::map<boost::uint16_t, int> code_table;
-
        /// Code to index table for embedded glyphs
-       code_table _embedded_code_table; 
+    //
+    /// This can be NULL if an embedded font should not be
+    /// substituted by a device font. This can arise with
+    /// a) a DefineFont tag without a corresponding DefineFontInfo
+    ///    or DefineFontInfo2, or
+    /// b) a DefineFont2 or DefineFont3 tag with no CodeTable.
+    ///
+    /// It is a shared_ptr to avoid changing an original
+    /// DefineFont2Tag, while allowing this class to take ownership
+    /// of CodeTables from a DefineFontInfo tag.
+    boost::shared_ptr<const CodeTable> _embeddedCodeTable; 
 
        /// Code to index table for device glyphs
-       code_table _device_code_table; 
+       CodeTable _deviceCodeTable; 
 
        // Layout stuff.
-       float   m_ascent;
-       float   m_descent;
-       float   m_leading;
-       //std::vector<float>    m_advance_table;
+       float m_ascent;
+       float m_descent;
+       float m_leading;
 
        typedef std::map<kerning_pair, float> kernings_table;
        kernings_table m_kerning_pairs;

=== modified file 'libcore/Makefile.am'
--- a/libcore/Makefile.am       2008-11-08 10:04:43 +0000
+++ b/libcore/Makefile.am       2008-11-08 18:03:33 +0000
@@ -87,6 +87,7 @@
        swf/DefineButtonSoundTag.cpp \
        swf/DefineButtonCxformTag.cpp \
        swf/DefineButtonTag.cpp \
+       swf/DefineFontTag.cpp \
        swf/VideoFrameTag.cpp \
        swf/SoundInfoRecord.cpp \
        swf/TextRecord.cpp \
@@ -105,7 +106,7 @@
        Button.cpp \
        DisplayList.cpp \
        fill_style.cpp \
-       font.cpp \
+       Font.cpp \
        fontlib.cpp \
        impl.cpp \
        LoadVariablesThread.cpp \
@@ -160,7 +161,7 @@
         ConvolutionFilter.h \
         ColorMatrixFilter.h \
         parser/filter_factory.h \
-       font.h \
+       Font.h \
        fontlib.h \
        generic_character.h \
        gnash.h \
@@ -195,6 +196,7 @@
        swf/DefineEditTextTag.h \
        swf/DefineButtonCxformTag.h \
        swf/PlaceObject2Tag.h \
+       swf/DefineFontTag.h \
        swf/RemoveObjectTag.h \
        swf/DisplayListTag.h \
        swf/DoActionTag.h \

=== modified file 'libcore/TextField.cpp'
--- a/libcore/TextField.cpp     2008-11-08 10:04:43 +0000
+++ b/libcore/TextField.cpp     2008-11-08 18:03:33 +0000
@@ -34,7 +34,7 @@
 #include "action.h" // for as_standard_member enum
 #include "VM.h"
 #include "builtin_function.h" // for getter/setter properties
-#include "font.h" // for using the _font member
+#include "Font.h" // for using the _font member
 #include "fontlib.h" // for searching or adding fonts the _font member
 #include "Object.h" // for getObjectInterface
 #include "namedStrings.h"
@@ -189,7 +189,7 @@
     tf->colorSet(text->getTextColor());
     tf->underlinedSet(text->getUnderlined());
 
-    const font* font = text->getFont();
+    const Font* font = text->getFont();
     if (font)
     {
         tf->fontSet(font->get_name());
@@ -274,7 +274,7 @@
             assert(mi);
             movie_definition* md = mi->get_movie_definition();
             assert(md);
-            font* f = md->get_font(fontName, bold, italic);
+            Font* f = md->get_font(fontName, bold, italic);
             if ( ! f ) f = fontlib::get_font(fontName, bold, italic);
             text->setFont( f );
         }
@@ -743,7 +743,7 @@
 {
 
     // WARNING! remember to set the font *before* setting text value!
-    boost::intrusive_ptr<const font> f = def.getFont();
+    boost::intrusive_ptr<const Font> f = def.getFont();
     if (!f) f = fontlib::get_default_font(); 
     setFont(f);
 
@@ -799,7 +799,7 @@
 {
     // Use the default font (Times New Roman for Windows, Times for Mac
     // according to docs. They don't say what it is for Linux.
-    boost::intrusive_ptr<const font> f = fontlib::get_default_font(); 
+    boost::intrusive_ptr<const Font> f = fontlib::get_default_font(); 
     setFont(f);
 
     init();
@@ -1441,12 +1441,12 @@
     return shift_right;
 }
 
-boost::intrusive_ptr<const font>
-TextField::setFont(boost::intrusive_ptr<const font> newfont)
+boost::intrusive_ptr<const Font>
+TextField::setFont(boost::intrusive_ptr<const Font> newfont)
 {
     if ( newfont == _font ) return _font;
 
-    boost::intrusive_ptr<const font> oldfont = _font;
+    boost::intrusive_ptr<const Font> oldfont = _font;
     set_invalidated();
     _font = newfont; 
     format_text();

=== modified file 'libcore/TextField.h'
--- a/libcore/TextField.h       2008-11-07 22:19:58 +0000
+++ b/libcore/TextField.h       2008-11-08 18:03:33 +0000
@@ -22,7 +22,7 @@
 #include "styles.h" // for fill_style and line_style
 #include "Range2d.h"
 #include "rect.h" // for inlines
-#include "font.h" // for visibility of font add_ref/drop_ref
+#include "Font.h" // for visibility of font add_ref/drop_ref
 
 // Forward declarations
 namespace gnash {
@@ -377,9 +377,9 @@
        /// @param newfont
        ///     Will be stored in an intrusive_ptr
        ///
-       boost::intrusive_ptr<const font> setFont(boost::intrusive_ptr<const 
font> newfont);
+       boost::intrusive_ptr<const Font> setFont(boost::intrusive_ptr<const 
Font> newfont);
 
-       const font* getFont() { return _font.get(); }
+       const Font* getFont() { return _font.get(); }
 
        boost::uint16_t getFontHeight() const
        {
@@ -552,7 +552,7 @@
 
        boost::uint16_t _fontHeight;
 
-       boost::intrusive_ptr<const font> _font;
+       boost::intrusive_ptr<const Font> _font;
 
        bool m_has_focus;
        size_t m_cursor;

=== modified file 'libcore/fontlib.cpp'
--- a/libcore/fontlib.cpp       2008-08-22 15:11:39 +0000
+++ b/libcore/fontlib.cpp       2008-11-08 18:03:33 +0000
@@ -13,7 +13,7 @@
 #include <pthread.h>
 #endif
 
-#include "font.h"
+#include "Font.h"
 #include "impl.h"
 #include "log.h"
 #include "render.h"
@@ -28,8 +28,8 @@
 namespace fontlib {
 
 namespace {
-       std::vector< boost::intrusive_ptr<font> >       s_fonts;
-       boost::intrusive_ptr<font> _defaultFont;
+       std::vector< boost::intrusive_ptr<Font> >       s_fonts;
+       boost::intrusive_ptr<Font> _defaultFont;
 }
 
 
@@ -44,11 +44,11 @@
                s_fonts.clear();
        }
 
-boost::intrusive_ptr<font>
+boost::intrusive_ptr<Font>
 get_default_font()
 {
        if ( _defaultFont ) return _defaultFont;
-       _defaultFont = new font(DEFAULT_FONT_NAME);
+       _defaultFont = new Font(DEFAULT_FONT_NAME);
        return _defaultFont;
 }
 
@@ -59,7 +59,7 @@
        }
 
 
-       font*   get_font(int index)
+       Font*   get_font(int index)
        // Retrieve one of our fonts, by index.
        {
                if (index < 0 || index >= (int) s_fonts.size())
@@ -71,24 +71,24 @@
        }
 
 
-       font*   get_font(const std::string& name, bool bold, bool italic)
+       Font*   get_font(const std::string& name, bool bold, bool italic)
        {
                // Dumb linear search.
                for (unsigned int i = 0; i < s_fonts.size(); i++)
                {
-                       font*   f = s_fonts[i].get();
+                       Font*   f = s_fonts[i].get();
                        assert(f);
                        if ( f->matches(name, bold, italic) )
                        {
                                return f;
                        }
                }
-               font* f = new font(name, bold, italic);
+               Font* f = new Font(name, bold, italic);
                s_fonts.push_back(f);
                return f;
        }
 
-       void    add_font(font* f)
+       void    add_font(Font* f)
        // Add the given font to our library.
        {
                assert(f);

=== modified file 'libcore/fontlib.h'
--- a/libcore/fontlib.h 2008-06-04 12:52:51 +0000
+++ b/libcore/fontlib.h 2008-11-08 18:03:33 +0000
@@ -22,7 +22,7 @@
 
 // Forward declarations
 namespace gnash {
-       class font;
+       class Font;
 }
 
 namespace gnash {
@@ -41,21 +41,21 @@
 namespace fontlib {
 
        // For adding fonts.
-       void add_font(font* f);
+       void add_font(Font* f);
 
        /// Clean up the font library
        void clear();
 
        int     get_font_count();
 
-       font* get_font(int index);
+       Font* get_font(int index);
 
-       font* get_font(const std::string& name, bool bold, bool italic);
+       Font* get_font(const std::string& name, bool bold, bool italic);
 
        /// Return a default device font.
-       boost::intrusive_ptr<font> get_default_font();
+       boost::intrusive_ptr<Font> get_default_font();
 
-       const char*     get_font_name(const font* f);
+       const char*     get_font_name(const Font* f);
 
        
 }      // end namespace fontlib

=== modified file 'libcore/impl.cpp'
--- a/libcore/impl.cpp  2008-11-07 18:07:45 +0000
+++ b/libcore/impl.cpp  2008-11-08 18:03:33 +0000
@@ -22,7 +22,6 @@
 #include "IOChannel.h"
 #include "utility.h"
 #include "impl.h"
-#include "font.h"
 #include "fontlib.h"
 #include "log.h"
 #include "GnashImage.h"
@@ -39,6 +38,7 @@
 #include "DefineFontAlignZonesTag.h"
 #include "DefineButtonCxformTag.h"
 #include "CSMTextSettingsTag.h"
+#include "DefineFontTag.h"
 #include "DefineButtonTag.h"
 #include "DefineTextTag.h"
 #include "PlaceObject2Tag.h"
@@ -105,7 +105,7 @@
     register_tag_loader(SWF::DEFINEBUTTON, DefineButtonTag::loader);
     register_tag_loader(SWF::JPEGTABLES, jpeg_tables_loader);
     register_tag_loader(SWF::SETBACKGROUNDCOLOR, 
SetBackgroundColorTag::loader);
-    register_tag_loader(SWF::DEFINEFONT,  define_font_loader);
+    register_tag_loader(SWF::DEFINEFONT, DefineFontTag::loader);
     register_tag_loader(SWF::DEFINETEXT, DefineTextTag::loader);
     register_tag_loader(SWF::DOACTION,  DoActionTag::doActionLoader);
     register_tag_loader(SWF::DEFINEFONTINFO, define_font_info_loader);
@@ -158,7 +158,8 @@
     register_tag_loader(SWF::SOUNDSTREAMHEAD2, sound_stream_head_loader); // 45
     register_tag_loader(SWF::DEFINEMORPHSHAPE, define_shape_morph_loader);
     register_tag_loader(SWF::FRAMETAG,  fixme_loader); // 47
-    register_tag_loader(SWF::DEFINEFONT2, define_font_loader); // 48
+    // 48
+    register_tag_loader(SWF::DEFINEFONT2, DefineFontTag::loader);
     register_tag_loader(SWF::GENCOMMAND,  fixme_loader); // 49
     register_tag_loader(SWF::DEFINECOMMANDOBJ, fixme_loader); // 50
     register_tag_loader(SWF::CHARACTERSET,  fixme_loader); // 51
@@ -208,7 +209,8 @@
     register_tag_loader(SWF::DEFINEALIGNZONES, 
DefineFontAlignZonesTag::loader); // 73
 
     register_tag_loader(SWF::CSMTEXTSETTINGS, CSMTextSettingsTag::loader); // 
74
-    register_tag_loader(SWF::DEFINEFONT3, define_font_loader); // 75
+    // 75
+    register_tag_loader(SWF::DEFINEFONT3, DefineFontTag::loader);
     register_tag_loader(SWF::SYMBOLCLASS, fixme_loader); // 76 
     register_tag_loader(SWF::METADATA, metadata_loader); // 77
     register_tag_loader(SWF::DEFINESCALINGGRID, fixme_loader); // 78

=== modified file 'libcore/parser/SWFMovieDefinition.cpp'
--- a/libcore/parser/SWFMovieDefinition.cpp     2008-10-30 21:35:10 +0000
+++ b/libcore/parser/SWFMovieDefinition.cpp     2008-11-08 18:03:33 +0000
@@ -30,7 +30,7 @@
 #include "SWFStream.h"
 #include "GnashImageJpeg.h"
 #include "RunInfo.h"
-#include "font.h"
+#include "Font.h"
 #include "log.h"
 #include "MovieClip.h"
 #include "movie_instance.h"
@@ -251,29 +251,29 @@
        return ch.get(); // mm... why don't we return the boost::intrusive_ptr?
 }
 
-void SWFMovieDefinition::add_font(int font_id, font* f)
+void SWFMovieDefinition::add_font(int font_id, Font* f)
 {
     assert(f);
-    m_fonts.insert(std::make_pair(font_id, boost::intrusive_ptr<font>(f)));
+    m_fonts.insert(std::make_pair(font_id, boost::intrusive_ptr<Font>(f)));
 }
 
-font* SWFMovieDefinition::get_font(int font_id) const
+Font* SWFMovieDefinition::get_font(int font_id) const
 {
 
     FontMap::const_iterator it = m_fonts.find(font_id);
     if ( it == m_fonts.end() ) return NULL;
-    boost::intrusive_ptr<font> f = it->second;
+    boost::intrusive_ptr<Font> f = it->second;
     assert(f->get_ref_count() > 1);
     return f.get();
 }
 
-font*
+Font*
 SWFMovieDefinition::get_font(const std::string& name, bool bold, bool italic) 
const
 {
 
     for (FontMap::const_iterator it=m_fonts.begin(), itEnd=m_fonts.end(); it 
!= itEnd; ++it)
     {
-       font* f = it->second.get();
+       Font* f = it->second.get();
        if ( f->matches(name, bold, italic) ) return f;
     }
     return 0;
@@ -935,7 +935,7 @@
                         "movie '%s'"), symbolName, source->get_url());
                        continue;
         }
-        else if (font* f = dynamic_cast<font*>(res.get()))
+        else if (Font* f = dynamic_cast<Font*>(res.get()))
                {
                        // Add this shared font to the currently-loading movie.
                        add_font(id, f);

=== modified file 'libcore/parser/SWFMovieDefinition.h'
--- a/libcore/parser/SWFMovieDefinition.h       2008-10-30 21:35:10 +0000
+++ b/libcore/parser/SWFMovieDefinition.h       2008-11-08 18:03:33 +0000
@@ -28,7 +28,6 @@
 
 #include "smart_ptr.h" // GNASH_USE_GC
 #include "fontlib.h"
-#include "font.h"
 #include "GnashImageJpeg.h"
 #include "IOChannel.h"
 #include "movie_definition.h" // for inheritance
@@ -37,6 +36,7 @@
 #include "SWFStream.h" // for get_bytes_loaded and visitbility of dtor 
(composition)
 #include "StringPredicates.h" // for case-insensitive string comparision 
(ExportMap)
 #include "utility.h" // for TWIPS_TO_PIXELS 
+#include "rect.h"
 
 #include <map> // for CharacterDictionary
 #include <set> // for _importSources
@@ -57,6 +57,7 @@
                class TagLoadersTable;
        }
     class RunInfo;
+    class Font;
 }
 
 namespace gnash
@@ -277,11 +278,11 @@
        //
        bool get_labeled_frame(const std::string& label, size_t& frame_number);
 
-       void    add_font(int font_id, font* f);
-
-       font*   get_font(int font_id) const;
-
-       font* get_font(const std::string& name, bool bold, bool italic) const;
+       void    add_font(int font_id, Font* f);
+
+       Font*   get_font(int font_id) const;
+
+       Font* get_font(const std::string& name, bool bold, bool italic) const;
 
        // See dox in movie_definition.h
        bitmap_character_def*   get_bitmap_character_def(int character_id);
@@ -446,7 +447,7 @@
        /// Tags loader table
        SWF::TagLoadersTable& _tag_loaders;
 
-       typedef std::map<int, boost::intrusive_ptr<font> > FontMap;
+       typedef std::map<int, boost::intrusive_ptr<Font> > FontMap;
        FontMap m_fonts;
 
        typedef std::map<int, boost::intrusive_ptr<bitmap_character_def> >

=== modified file 'libcore/parser/movie_definition.h'
--- a/libcore/parser/movie_definition.h 2008-10-30 21:35:10 +0000
+++ b/libcore/parser/movie_definition.h 2008-11-08 18:03:33 +0000
@@ -66,7 +66,7 @@
        class movie_instance;
        class MovieClip;
        class ControlTag;
-    class font;
+    class Font;
     class ExportableResource;
     class sound_sample;
 }
@@ -246,7 +246,7 @@
        /// This method is here to be called by DEFINEFONT tags loaders.
        /// The default implementation does nothing.
        ///
-       virtual void add_font(int /*id*/, font* /*ch*/)
+       virtual void add_font(int /*id*/, Font* /*ch*/)
        {
        }
 
@@ -257,13 +257,13 @@
        ///
        /// @see add_font
        ///
-       virtual font* get_font(int /*id*/) const
+       virtual Font* get_font(int /*id*/) const
        {
                return NULL;
        }
 
        /// Find a font from the movie (not shared) lib
-       virtual font* get_font(const std::string& /*name*/, 
+       virtual Font* get_font(const std::string& /*name*/, 
             bool /*bold*/, bool /*italic*/) const
        {
                return 0;

=== modified file 'libcore/parser/sprite_definition.h'
--- a/libcore/parser/sprite_definition.h        2008-10-30 21:35:10 +0000
+++ b/libcore/parser/sprite_definition.h        2008-11-08 18:03:33 +0000
@@ -146,7 +146,7 @@
        }
 
        /// Overridden just for complaining  about malformed SWF
-       virtual void add_font(int /*id*/, font* /*ch*/)
+       virtual void add_font(int /*id*/, Font* /*ch*/)
        {
                IF_VERBOSE_MALFORMED_SWF (
                log_swferror(_("add_font tag appears in sprite tags"));
@@ -154,7 +154,7 @@
        }
 
        /// Delegate call to associated root movie
-       virtual font* get_font(int id) const
+       virtual Font* get_font(int id) const
        {
                return m_movie_def.get_font(id);
        }

=== modified file 'libcore/swf/DefineEditTextTag.cpp'
--- a/libcore/swf/DefineEditTextTag.cpp 2008-11-06 13:56:00 +0000
+++ b/libcore/swf/DefineEditTextTag.cpp 2008-11-08 18:03:33 +0000
@@ -18,7 +18,7 @@
 #include "DefineEditTextTag.h"
 #include "TextField.h"
 #include "movie_definition.h"
-#include "font.h"
+#include "Font.h"
 #include "SWFStream.h"
 
 namespace gnash {

=== modified file 'libcore/swf/DefineEditTextTag.h'
--- a/libcore/swf/DefineEditTextTag.h   2008-11-08 10:04:43 +0000
+++ b/libcore/swf/DefineEditTextTag.h   2008-11-08 18:03:33 +0000
@@ -27,8 +27,6 @@
 #include "swf.h" // for tag_type definition
 #include "RGBA.h"
 #include "TextField.h"
-// Move to cpp:
-#include "font.h"
 
 #include <boost/cstdint.hpp> // for boost::uint16_t and friends
  
@@ -38,7 +36,7 @@
        class SWFStream;
        class movie_definition;
        class RunInfo;
-    class font;
+    class Font;
 }
 
 namespace gnash {
@@ -209,7 +207,7 @@
                return _useOutlines;
        }
 
-    boost::intrusive_ptr<font> getFont() const
+    boost::intrusive_ptr<Font> getFont() const
     {
         return _font;
     }
@@ -293,7 +291,7 @@
        bool _useOutlines;
 
        int     _fontID;
-       boost::intrusive_ptr<font> _font;
+       boost::intrusive_ptr<Font> _font;
 
        /// height of font text, in twips
     // TODO: initialize to a meaningful value (see MovieClip::add_textfield)

=== modified file 'libcore/swf/DefineFontAlignZonesTag.cpp'
--- a/libcore/swf/DefineFontAlignZonesTag.cpp   2008-11-08 10:04:43 +0000
+++ b/libcore/swf/DefineFontAlignZonesTag.cpp   2008-11-08 18:03:33 +0000
@@ -18,7 +18,7 @@
 //
 
 
-#include "font.h"
+#include "Font.h"
 #include "log.h"
 #include "shape.h"
 #include "SWFStream.h"
@@ -44,7 +44,7 @@
 
     in.ensureBytes(1);
        unsigned short ref = in.read_u8(); // must reference a valid 
DEFINEFONT3 tag
-       font* referencedFont = m.get_font(ref);
+       Font* referencedFont = m.get_font(ref);
        if ( ! referencedFont )
        {
                IF_VERBOSE_MALFORMED_SWF(

=== added file 'libcore/swf/DefineFontTag.cpp'
--- a/libcore/swf/DefineFontTag.cpp     1970-01-01 00:00:00 +0000
+++ b/libcore/swf/DefineFontTag.cpp     2008-11-08 18:30:00 +0000
@@ -0,0 +1,377 @@
+// DefineFontTag.cpp: read DefineFont2 and DefineFont tags.
+// 
+//   Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#include "DefineFontTag.h"
+#include "SWFStream.h"
+#include "Font.h"
+#include "RunInfo.h"
+#include "swf.h"
+#include "movie_definition.h"
+#include "shape_character_def.h"
+
+// Based on the public domain work of Thatcher Ulrich <address@hidden> 2003
+
+namespace gnash {
+namespace SWF {
+
+void
+DefineFontTag::loader(SWFStream& in, tag_type tag, movie_definition& m,
+            const RunInfo& /*r*/)
+{
+    assert(tag == DEFINEFONT || tag == DEFINEFONT2 || tag == DEFINEFONT3);
+
+    in.ensureBytes(2);
+    boost::uint16_t fontID = in.read_u16();
+
+    std::auto_ptr<DefineFontTag> ft(new DefineFontTag(in, m, tag));
+
+    Font* f = new Font(ft);
+
+    m.add_font(fontID, f);
+
+}
+
+void
+DefineFontTag::readCodeTable(SWFStream& in, Font::CodeTable& table,
+        bool wideCodes, size_t glyphCount)
+{
+    IF_VERBOSE_PARSE (
+    log_parse(_("reading code table at offset %lu"), in.tell());
+    );
+
+    // Good. We can only do this once.
+    assert(table.empty());
+
+    if (wideCodes)
+    {
+        in.ensureBytes(2 * glyphCount);
+        // Code table is made of boost::uint16_t's.
+        for (size_t i=0; i < glyphCount; ++i)
+        {
+            boost::uint16_t code = in.read_u16();
+            table.insert(std::make_pair(code, i));
+        }
+    }
+    else
+    {
+        // Code table is made of bytes.
+        in.ensureBytes(1 * glyphCount);
+        for (size_t i=0; i < glyphCount; ++i)
+        {
+            boost::uint8_t code = in.read_u8();
+            table.insert(std::make_pair(code, i));
+        }
+    }
+}
+
+#ifdef GNASH_USE_GC
+void
+DefineFontTag::markReachableResources() const
+{
+       // Mark glyphs
+       for (Font::GlyphInfoRecords::const_iterator i = _glyphTable.begin(),
+            e = _glyphTable.end(); i != e; ++i)
+       {
+               i->markReachableResources();
+       }
+}
+#endif
+
+
+DefineFontTag::DefineFontTag(SWFStream& in, movie_definition& m, tag_type tag)
+    :
+    _subpixelFont(tag == DEFINEFONT3 ? true : false),
+    _unicodeChars(false),
+    _shiftJISChars(false),
+    _ansiChars(true),
+    _italic(false),
+    _bold(false),
+    _wideCodes(false),
+    _ascent(0.0f),
+    _descent(0.0f),
+    _leading(0.0f)
+{
+    switch (tag)
+    {
+        default:
+            std::abort();
+            break;
+        case DEFINEFONT:
+            readDefineFont(in, m);
+            break;
+        case DEFINEFONT2:
+        case DEFINEFONT3:
+            readDefineFont2Or3(in, m);
+            break;
+    }
+}
+
+void
+DefineFontTag::readDefineFont(SWFStream& in, movie_definition& m)
+{
+    IF_VERBOSE_PARSE(
+        log_parse(_("reading DefineFont"));
+    );
+
+    unsigned long table_base = in.tell();
+
+    // Read the glyph offsets.  Offsets
+    // are measured from the start of the
+    // offset table.
+    std::vector<unsigned> offsets;
+    in.ensureBytes(2);
+    offsets.push_back(in.read_u16());
+
+    IF_VERBOSE_PARSE (
+    log_parse("offset[0] = %d", offsets[0]);
+    );
+
+    int        count = offsets[0] >> 1;
+    if ( count > 0 )
+    {
+        in.ensureBytes(count*2);
+        for (int i = 1; i < count; i++)
+        {
+            offsets.push_back(in.read_u16());
+
+            IF_VERBOSE_PARSE (
+            log_parse("offset[%d] = %d", i, offsets[i]);
+            );
+        }
+    }
+    else
+    {
+        log_error("Negative embedded glyph table size: %d", count);
+    }
+
+    _glyphTable.resize(count);
+
+    // Read the glyph shapes.
+    for (int i = 0; i < count; i++)
+    {
+        // Seek to the start of the shape data.
+        unsigned long new_pos = table_base + offsets[i];
+
+        if ( ! in.seek(new_pos) )
+        {
+            throw ParserException(_("Glyphs offset table corrupted "
+                        "in DefineFont tag"));
+        }
+
+        // Create & read the shape.
+        shape_character_def* s = new shape_character_def;
+        s->read(in, SWF::DEFINEFONT, false, m); 
+
+        _glyphTable[i].glyph = s;
+    }
+}
+
+// Read a DefineFont2 or DefineFont3 tag
+void
+DefineFontTag::readDefineFont2Or3(SWFStream& in, movie_definition& m)
+{
+    IF_VERBOSE_PARSE (
+    log_parse(_("reading DefineFont2 or DefineFont3"));
+    );
+
+    in.ensureBytes(2); // 1 for the flags, 1 unknown
+    int flags = in.read_u8();
+    bool has_layout = flags & (1 << 7);
+    _shiftJISChars = flags & (1 << 6);
+    _unicodeChars = flags & (1 << 5);
+    _ansiChars = flags & (1 << 4);
+    bool wide_offsets = flags & (1 << 3);
+    _wideCodes = flags & (1 << 2);
+    _italic = flags & (1 << 1);
+    _bold = flags & (1 << 0);
+
+    // Next is language code, always 0 for SWF5 or previous
+    int languageCode = in.read_u8();
+    if (languageCode) {
+        LOG_ONCE(log_unimpl("LanguageCode in DefineFont (2 or 3)"));
+    }
+
+    in.read_string_with_length(_name);
+
+    in.ensureBytes(2); 
+    boost::uint16_t glyph_count = in.read_u16();
+
+    IF_VERBOSE_PARSE (
+        log_parse(" has_layout = %d", has_layout);
+        log_parse(" shift_jis_chars = %d", _shiftJISChars);
+        log_parse(" m_unicode_chars = %d", _unicodeChars);
+        log_parse(" m_ansi_chars = %d", _ansiChars);
+        log_parse(" wide_offsets = %d", wide_offsets);
+        log_parse(" wide_codes = %d", _wideCodes);
+        log_parse(" is_italic = %d", _italic);
+        log_parse(" is_bold = %d", _bold);
+        log_parse(" name = %s", _name);
+        log_parse(" glyphs count = %d", glyph_count);
+    );
+    
+    unsigned long table_base = in.tell();
+
+    // Read the glyph offsets.  Offsets
+    // are measured from the start of the
+    // offset table. Make sure wide offsets fit into elements
+    std::vector<boost::uint32_t> offsets;
+    int        font_code_offset;
+    if (wide_offsets)
+    {
+        // 32-bit offsets.
+        in.ensureBytes(4*glyph_count + 4); 
+        for (unsigned int i = 0; i < glyph_count; i++)
+        {
+            boost::uint32_t off = in.read_u32();       
+
+            IF_VERBOSE_PARSE (
+            log_parse(_("Glyph %d at offset %u"), i, off);
+            );
+
+            offsets.push_back(off);
+        }
+        font_code_offset = in.read_u32();
+    }
+    else
+    {
+        // 16-bit offsets.
+        in.ensureBytes(2*glyph_count + 2); 
+        for (unsigned int i = 0; i < glyph_count; i++)
+        {
+            boost::uint16_t off = in.read_u16();       
+
+            IF_VERBOSE_PARSE (
+            log_parse(_("Glyph %d at offset %u"), i, off);
+            );
+
+            offsets.push_back(off);
+        }
+        font_code_offset = in.read_u16();
+    }
+
+    _glyphTable.resize(glyph_count);
+
+    // Read the glyph shapes.
+    for (int i = 0; i < glyph_count; i++)
+    {
+        // Seek to the start of the shape data.
+        unsigned long new_pos = table_base + offsets[i];
+
+        // It seems completely possible to
+        // have such seeks-back, see bug #16311
+        //assert(new_pos >= in.tell());
+
+        if ( ! in.seek(new_pos) )
+        {
+            throw ParserException(_("Glyphs offset table corrupted in 
DefineFont2/3 tag"));
+        }
+
+        // Create & read the shape.
+        shape_character_def* s = new shape_character_def;
+        s->read(in, SWF::DEFINEFONT2, false, m); // .. or DEFINEFONT3 
actually..
+
+        _glyphTable[i].glyph = s;
+    }
+
+    unsigned long current_position = in.tell();
+    if (font_code_offset + table_base != current_position)
+    {
+        // Bad offset!  Don't try to read any more.
+        IF_VERBOSE_MALFORMED_SWF(
+        log_swferror(_("Bad offset in DefineFont2"));
+        );
+        return;
+    }
+
+    std::auto_ptr<Font::CodeTable> table(new Font::CodeTable);
+
+    readCodeTable(in, *table, _wideCodes, _glyphTable.size());
+    _codeTable.reset(table.release());
+
+    // Read layout info for the glyphs.
+    if (has_layout)
+    {
+        in.ensureBytes(6);
+        _ascent = static_cast<float>(in.read_s16());
+        _descent = static_cast<float>(in.read_s16());
+        _leading = static_cast<float>(in.read_s16());
+        
+        // Advance table; i.e. how wide each character is.
+        size_t nGlyphs = _glyphTable.size();
+        in.ensureBytes(nGlyphs*2);
+        for (size_t i = 0; i < nGlyphs; i++)
+        {
+            _glyphTable[i].advance = (float) in.read_s16();
+        }
+
+        // Bounds table.
+        {
+            rect       dummy_rect;
+            // TODO: shouldn't we log_unimpl here ??
+            for (size_t i = 0; i < nGlyphs; i++) dummy_rect.read(in);
+        }
+
+        // Kerning pairs.
+        in.ensureBytes(2);
+        int    kerning_count = in.read_u16();
+        if ( _wideCodes )
+        {
+            in.ensureBytes(6*kerning_count); // includes the adjustment 
+        }
+        else
+        {
+            in.ensureBytes(4*kerning_count); // includes the adjustment 
+        }
+
+        for (int i = 0; i < kerning_count; i++)
+        {
+            boost::uint16_t    char0, char1;
+            if (_wideCodes)
+            {
+                char0 = in.read_u16();
+                char1 = in.read_u16();
+            }
+            else
+            {
+                char0 = in.read_u8();
+                char1 = in.read_u8();
+            }
+            float      adjustment = (float) in.read_s16();
+
+            kerning_pair       k;
+            k.m_char0 = char0;
+            k.m_char1 = char1;
+
+            // Remember this adjustment; we can look it up quickly
+            // later using the character pair as the key.
+            if ( ! m_kerning_pairs.insert(std::make_pair(k, 
adjustment)).second )
+            {
+                IF_VERBOSE_MALFORMED_SWF(
+                log_swferror(_("Repeated kerning pair found - ignoring"));
+                );
+            }
+
+        }
+    }
+}
+
+
+}
+}
+

=== added file 'libcore/swf/DefineFontTag.h'
--- a/libcore/swf/DefineFontTag.h       1970-01-01 00:00:00 +0000
+++ b/libcore/swf/DefineFontTag.h       2008-11-08 19:14:15 +0000
@@ -0,0 +1,134 @@
+// DefineFontTag.h   Read DefineFont and DefineFont2 tags
+//
+//   Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+// Based on the public domain work of Thatcher Ulrich <address@hidden> 2003
+
+
+#ifndef GNASH_SWF_DEFINEFONTTAG_H
+#define GNASH_SWF_DEFINEFONTTAG_H
+
+#include "smart_ptr.h" // GC
+#include "swf.h"
+#include "Font.h"
+#include <vector>
+
+// Forward declarations
+namespace gnash {
+    class SWFStream;
+    class movie_definition;
+    class RunInfo;
+}
+
+namespace gnash {
+namespace SWF {
+
+/// Read and store DefineFont and DefineFont2 tag.
+class DefineFontTag
+{
+public:
+
+    /// Load a DefineFont tag.
+    //
+    /// A corresponding Font is created and added to the movie_definition.
+    static void loader(SWFStream& in, tag_type tag, movie_definition& m,
+            const RunInfo& r);
+
+    /// Return the glyphs read from the DefineFont tag.
+    const Font::GlyphInfoRecords& glyphTable() const {
+        return _glyphTable;
+    }
+
+    /// Check for the existence of a Font::CodeTable.
+    //
+    /// @return     True if the tag has a Font::CodeTable.
+    //
+    /// This can only be true for a DefineFont2 tag.
+    bool hasCodeTable() const {
+        return _codeTable.get();
+    }
+    
+    /// Retrieve the tag's Font::CodeTable.
+    //
+    /// This DefineFontTag always retains ownership, and the CodeTable
+    /// may not be altered.
+    //
+    /// @return     shared ownership of the tag's Font::CodeTable. This
+    ///             may be NULL, which can be checked first with
+    ///             hasCodeTable().
+    boost::shared_ptr<const Font::CodeTable> getCodeTable() const {
+        return _codeTable;
+    }
+
+    bool ansiChars() const { return _ansiChars; }
+    bool shiftJISChars() const { return _shiftJISChars; }
+    bool unicodeChars() const { return _unicodeChars; }
+    bool italic() const { return _italic; }
+    bool bold() const { return _bold; }
+    bool wideCodes() const { return _wideCodes; }
+    bool subpixelFont() const { return _subpixelFont; }
+    bool leading() const { return _leading; }
+    bool ascent() const { return _ascent; }
+    bool descent() const { return _descent; }
+    const std::string& name() const { return _name; }
+
+#ifdef GNASH_USE_GC
+        /// Mark glyph resources as reachable
+        void markReachableResources() const;
+#endif
+
+    /// Read Font::CodeTable, which maps glyph indices to character codes.
+       static void readCodeTable(SWFStream& in, Font::CodeTable& table,
+            bool wideCodes, size_t glyphCount);
+
+private:
+
+    DefineFontTag(SWFStream& in, movie_definition& m, tag_type tag);
+
+    /// Read a DefineFont tag.
+    void readDefineFont(SWFStream& in, movie_definition & m);
+
+    /// Read a DefineFont2 or DefineFont3 tag.
+    void readDefineFont2Or3(SWFStream& in, movie_definition& m);
+
+    /// The GlyphInfo records contained in the tag.
+    Font::GlyphInfoRecords _glyphTable;
+
+    std::string _name;
+    bool _subpixelFont;
+       bool _hasLayout;
+       bool _unicodeChars;
+       bool _shiftJISChars;
+       bool _ansiChars;
+       bool _italic;
+       bool _bold;
+       bool _wideCodes;
+    float _ascent;
+    float _descent;
+    float _leading;
+
+       typedef std::map<kerning_pair, float> kernings_table;
+       kernings_table m_kerning_pairs;
+
+    boost::shared_ptr<const Font::CodeTable> _codeTable;
+};
+
+}
+}
+
+#endif

=== modified file 'libcore/swf/TextRecord.cpp'
--- a/libcore/swf/TextRecord.cpp        2008-11-08 11:02:43 +0000
+++ b/libcore/swf/TextRecord.cpp        2008-11-08 18:03:33 +0000
@@ -24,7 +24,7 @@
 #include "swf.h"
 #include "log.h"
 #include "render.h"
-#include "font.h"
+#include "Font.h"
 
 #include <vector>
 
@@ -168,7 +168,7 @@
         static std::vector<fill_style> s_dummy_style(1, fill_style());    
         static std::vector<line_style> s_dummy_line_style;
 
-        const font*    fnt = rec.getFont();
+        const Font* fnt = rec.getFont();
         if (!fnt) {
             IF_VERBOSE_MALFORMED_SWF(
                 log_swferror("No font in style of TextRecord");

=== modified file 'libcore/swf/TextRecord.h'
--- a/libcore/swf/TextRecord.h  2008-11-08 10:04:43 +0000
+++ b/libcore/swf/TextRecord.h  2008-11-08 18:03:33 +0000
@@ -27,7 +27,7 @@
     class movie_definition;
     class SWFStream;
     class SWFMatrix;
-    class font;
+    class Font;
 }
 
 namespace gnash {
@@ -94,11 +94,11 @@
     }
 
     // TODO: check font properly.
-    void setFont(const font* f) {
+    void setFont(const Font* f) {
         _font = f;
     }
 
-    const font* getFont() const {
+    const Font* getFont() const {
         return _font;
     }
 
@@ -173,7 +173,7 @@
     float _yOffset;
 
     /// The font associated with the TextRecord. Can be NULL.
-    const font* _font;
+    const Font* _font;
 
     /// Whether the text should be underlined.
     bool _underline;

=== modified file 'libcore/swf/tag_loaders.cpp'
--- a/libcore/swf/tag_loaders.cpp       2008-11-07 18:07:45 +0000
+++ b/libcore/swf/tag_loaders.cpp       2008-11-08 18:03:33 +0000
@@ -30,7 +30,7 @@
 #include "utility.h"
 #include "action.h"
 #include "action_buffer.h"
-#include "font.h"
+#include "Font.h"
 #include "fontlib.h"
 #include "log.h"
 #include "morph2_character_def.h"
@@ -825,29 +825,6 @@
 //
 
 
-void define_font_loader(SWFStream& in, tag_type tag, movie_definition& m,
-               const RunInfo& /*r*/)
-    // Load a DefineFont or DefineFont2 tag.
-{
-    assert(tag == SWF::DEFINEFONT
-       || tag == SWF::DEFINEFONT2
-       || tag == SWF::DEFINEFONT3 ); // 10 || 48 || 75
-
-    in.ensureBytes(2);
-    boost::uint16_t font_id = in.read_u16();
-
-    font* f = new font;
-    f->read(in, tag, m);
-
-    m.add_font(font_id, f);
-
-    // Automatically keeping fonts in fontlib is
-    // problematic.  The app should be responsible for
-    // optionally adding fonts to fontlib.
-    // //fontlib::add_font(f);
-}
-
-
 // See description in header
 void define_font_info_loader(SWFStream& in, tag_type tag, movie_definition& m,
                const RunInfo& /*r*/)
@@ -857,7 +834,7 @@
     in.ensureBytes(2);
     boost::uint16_t font_id = in.read_u16();
 
-    font* f = m.get_font(font_id);
+    Font* f = m.get_font(font_id);
     if (f)
     {
         f->read_font_info(in, tag, m);
@@ -880,7 +857,7 @@
     in.ensureBytes(2);
     boost::uint16_t font_id = in.read_u16();
 
-    font* f = m.get_font(font_id);
+    Font* f = m.get_font(font_id);
     if (f)
     {
         f->read_font_name(in, tag, m);
@@ -987,7 +964,7 @@
             log_parse(_("  export: id = %d, name = %s"), id, symbolName);
         );
 
-        if (font* f = m.get_font(id))
+        if (Font* f = m.get_font(id))
         {
             // Expose this font for export.
             m.export_resource(symbolName, f);

=== modified file 'libcore/swf/tag_loaders.h'
--- a/libcore/swf/tag_loaders.h 2008-11-07 18:07:45 +0000
+++ b/libcore/swf/tag_loaders.h 2008-11-08 17:30:07 +0000
@@ -69,13 +69,6 @@
 void define_shape_morph_loader(SWFStream&, tag_type, movie_definition&,
                const RunInfo&);
 
-/// SWF Tags DefineFont (10), DefineFont2 (48) and DefineFont3 (75)
-//
-/// Load a font and adds it the the movie definition.
-///
-void define_font_loader(SWFStream&, tag_type, movie_definition&,
-               const RunInfo&);
-
 /// SWF Tags Reflex (777)
 //
 void reflex_loader(SWFStream&, tag_type, movie_definition&,


reply via email to

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