bug 684889 pt2 - move and rename FontFamily/Entry classes from gfxFT2Fonts to gfxFT2FontList source file. r=jdaggett
authorJonathan Kew <jfkthame@gmail.com>
Fri, 23 Sep 2011 12:16:13 +0100
changeset 78723 065af81cd739ed419f936680c1b2fc61572f5357
parent 78722 6081c809fcf6ee052752e84c2ecade07e0397837
child 78724 5ddec215cf627896ba0d52b3585de652caf39af4
push id78
push userclegnitto@mozilla.com
push dateFri, 16 Dec 2011 17:32:24 +0000
treeherdermozilla-release@79d24e644fdd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdaggett
bugs684889
milestone9.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
bug 684889 pt2 - move and rename FontFamily/Entry classes from gfxFT2Fonts to gfxFT2FontList source file. r=jdaggett
gfx/thebes/gfxAndroidPlatform.h
gfx/thebes/gfxFT2FontList.cpp
gfx/thebes/gfxFT2FontList.h
gfx/thebes/gfxFT2Fonts.cpp
gfx/thebes/gfxFT2Fonts.h
--- a/gfx/thebes/gfxAndroidPlatform.h
+++ b/gfx/thebes/gfxAndroidPlatform.h
@@ -39,16 +39,23 @@
 #ifndef GFX_PLATFORM_ANDROID_H
 #define GFX_PLATFORM_ANDROID_H
 
 #include "gfxFT2Fonts.h"
 #include "gfxPlatform.h"
 #include "gfxUserFontSet.h"
 #include "nsTArray.h"
 
+namespace mozilla {
+    namespace dom {
+        class FontListEntry;
+    };
+};
+using mozilla::dom::FontListEntry;
+
 typedef struct FT_LibraryRec_ *FT_Library;
 
 class THEBES_API gfxAndroidPlatform : public gfxPlatform {
 public:
     gfxAndroidPlatform();
     virtual ~gfxAndroidPlatform();
 
     static gfxAndroidPlatform *GetPlatform() {
--- a/gfx/thebes/gfxFT2FontList.cpp
+++ b/gfx/thebes/gfxFT2FontList.cpp
@@ -34,34 +34,50 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+#if defined(MOZ_WIDGET_GTK2)
+#include "gfxPlatformGtk.h"
+#define gfxToolkitPlatform gfxPlatformGtk
+#elif defined(MOZ_WIDGET_QT)
+#include <qfontinfo.h>
+#include "gfxQtPlatform.h"
+#define gfxToolkitPlatform gfxQtPlatform
+#elif defined(XP_WIN)
+#include "gfxWindowsPlatform.h"
+#define gfxToolkitPlatform gfxWindowsPlatform
+#elif defined(ANDROID)
+#include "mozilla/dom/ContentChild.h"
+#include "gfxAndroidPlatform.h"
+#define gfxToolkitPlatform gfxAndroidPlatform
+#endif
+
 #ifdef ANDROID
-#include "mozilla/dom/ContentChild.h"
 #include "nsXULAppAPI.h"
-
-#include "gfxAndroidPlatform.h"
 #include <dirent.h>
 #include <android/log.h>
 #define ALOG(args...)  __android_log_print(ANDROID_LOG_INFO, "Gecko" , ## args)
 #endif
 
+#include "ft2build.h"
+#include FT_FREETYPE_H
+#include FT_TRUETYPE_TAGS_H
+#include FT_TRUETYPE_TABLES_H
+#include "cairo-ft.h"
+
 #include "gfxFT2FontList.h"
+#include "gfxFT2Fonts.h"
 #include "gfxUserFontSet.h"
 #include "gfxFontUtils.h"
 
-#include "ft2build.h"
-#include FT_FREETYPE_H
-#include "gfxFT2Fonts.h"
-
 #include "nsServiceManagerUtils.h"
 #include "nsTArray.h"
 #include "nsUnicharUtils.h"
 
 #include "nsDirectoryServiceUtils.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsISimpleEnumerator.h"
@@ -73,29 +89,342 @@
 #include "nsIWindowsRegKey.h"
 #include <windows.h>
 #endif
 
 #ifdef PR_LOGGING
 static PRLogModuleInfo *gFontInfoLog = PR_NewLogModule("fontInfoLog");
 #endif /* PR_LOGGING */
 
+#undef LOG
 #define LOG(args) PR_LOG(gFontInfoLog, PR_LOG_DEBUG, args)
 #define LOG_ENABLED() PR_LOG_TEST(gFontInfoLog, PR_LOG_DEBUG)
 
 static __inline void
 BuildKeyNameFromFontName(nsAString &aName)
 {
 #ifdef XP_WIN
     if (aName.Length() >= LF_FACESIZE)
         aName.Truncate(LF_FACESIZE - 1);
 #endif
     ToLowerCase(aName);
 }
 
+/*
+ * FT2FontEntry
+ * gfxFontEntry subclass corresponding to a specific face that can be
+ * rendered by freetype. This is associated with a face index in a
+ * file (normally a .ttf/.otf file holding a single face, but in principle
+ * there could be .ttc files with multiple faces).
+ * The FT2FontEntry can create the necessary FT_Face on demand, and can
+ * then create a Cairo font_face and scaled_font for drawing.
+ */
+
+cairo_scaled_font_t *
+FT2FontEntry::CreateScaledFont(const gfxFontStyle *aStyle)
+{
+    cairo_scaled_font_t *scaledFont = NULL;
+
+    cairo_matrix_t sizeMatrix;
+    cairo_matrix_t identityMatrix;
+
+    // XXX deal with adjusted size
+    cairo_matrix_init_scale(&sizeMatrix, aStyle->size, aStyle->size);
+    cairo_matrix_init_identity(&identityMatrix);
+
+    // synthetic oblique by skewing via the font matrix
+    PRBool needsOblique = !IsItalic() &&
+            (aStyle->style & (FONT_STYLE_ITALIC | FONT_STYLE_OBLIQUE));
+
+    if (needsOblique) {
+        const double kSkewFactor = 0.25;
+
+        cairo_matrix_t style;
+        cairo_matrix_init(&style,
+                          1,                //xx
+                          0,                //yx
+                          -1 * kSkewFactor,  //xy
+                          1,                //yy
+                          0,                //x0
+                          0);               //y0
+        cairo_matrix_multiply(&sizeMatrix, &sizeMatrix, &style);
+    }
+
+    cairo_font_options_t *fontOptions = cairo_font_options_create();
+
+#ifdef MOZ_GFX_OPTIMIZE_MOBILE
+    cairo_font_options_set_hint_metrics(fontOptions, CAIRO_HINT_METRICS_OFF);
+#endif
+
+    scaledFont = cairo_scaled_font_create(CairoFontFace(),
+                                          &sizeMatrix,
+                                          &identityMatrix, fontOptions);
+    cairo_font_options_destroy(fontOptions);
+
+    NS_ASSERTION(cairo_scaled_font_status(scaledFont) == CAIRO_STATUS_SUCCESS,
+                 "Failed to make scaled font");
+
+    return scaledFont;
+}
+
+FT2FontEntry::~FT2FontEntry()
+{
+    // Do nothing for mFTFace here since FTFontDestroyFunc is called by cairo.
+    mFTFace = nsnull;
+
+#ifndef ANDROID
+    if (mFontFace) {
+        cairo_font_face_destroy(mFontFace);
+        mFontFace = nsnull;
+    }
+#endif
+}
+
+gfxFont*
+FT2FontEntry::CreateFontInstance(const gfxFontStyle *aFontStyle, PRBool aNeedsBold)
+{
+    cairo_scaled_font_t *scaledFont = CreateScaledFont(aFontStyle);
+    gfxFont *font = new gfxFT2Font(scaledFont, this, aFontStyle, aNeedsBold);
+    cairo_scaled_font_destroy(scaledFont);
+    return font;
+}
+
+/* static */
+FT2FontEntry*
+FT2FontEntry::CreateFontEntry(const gfxProxyFontEntry &aProxyEntry,
+                              const PRUint8 *aFontData,
+                              PRUint32 aLength)
+{
+    // Ownership of aFontData is passed in here; the fontEntry must
+    // retain it as long as the FT_Face needs it, and ensure it is
+    // eventually deleted.
+    FT_Face face;
+    FT_Error error =
+        FT_New_Memory_Face(gfxToolkitPlatform::GetPlatform()->GetFTLibrary(),
+                           aFontData, aLength, 0, &face);
+    if (error != FT_Err_Ok) {
+        NS_Free((void*)aFontData);
+        return nsnull;
+    }
+    FT2FontEntry* fe = FT2FontEntry::CreateFontEntry(face, nsnull, 0, aFontData);
+    if (fe) {
+        fe->mItalic = aProxyEntry.mItalic;
+        fe->mWeight = aProxyEntry.mWeight;
+        fe->mStretch = aProxyEntry.mStretch;
+    }
+    return fe;
+}
+
+class FTUserFontData {
+public:
+    FTUserFontData(FT_Face aFace, const PRUint8* aData)
+        : mFace(aFace), mFontData(aData)
+    {
+    }
+
+    ~FTUserFontData()
+    {
+        FT_Done_Face(mFace);
+        if (mFontData) {
+            NS_Free((void*)mFontData);
+        }
+    }
+
+private:
+    FT_Face        mFace;
+    const PRUint8 *mFontData;
+};
+
+static void
+FTFontDestroyFunc(void *data)
+{
+    FTUserFontData *userFontData = static_cast<FTUserFontData*>(data);
+    delete userFontData;
+}
+
+/* static */
+FT2FontEntry*
+FT2FontEntry::CreateFontEntry(const FontListEntry& aFLE)
+{
+    FT2FontEntry *fe = new FT2FontEntry(aFLE.faceName());
+    fe->mFilename = aFLE.filepath();
+    fe->mFTFontIndex = aFLE.index();
+    fe->mWeight = aFLE.weight();
+    fe->mStretch = aFLE.stretch();
+    fe->mItalic = aFLE.italic();
+    return fe;
+}
+
+/* static */
+FT2FontEntry*
+FT2FontEntry::CreateFontEntry(FT_Face aFace,
+                              const char* aFilename, PRUint8 aIndex,
+                              const PRUint8 *aFontData)
+{
+    static cairo_user_data_key_t key;
+
+    if (!aFace->family_name) {
+        FT_Done_Face(aFace);
+        return nsnull;
+    }
+    // Construct font name from family name and style name, regular fonts
+    // do not have the modifier by convention.
+    NS_ConvertUTF8toUTF16 fontName(aFace->family_name);
+    if (aFace->style_name && strcmp("Regular", aFace->style_name)) {
+        fontName.AppendLiteral(" ");
+        AppendUTF8toUTF16(aFace->style_name, fontName);
+    }
+    FT2FontEntry *fe = new FT2FontEntry(fontName);
+    fe->mItalic = aFace->style_flags & FT_STYLE_FLAG_ITALIC;
+    fe->mFTFace = aFace;
+#ifdef MOZ_GFX_OPTIMIZE_MOBILE
+    fe->mFontFace = cairo_ft_font_face_create_for_ft_face(aFace, FT_LOAD_NO_AUTOHINT | FT_LOAD_NO_HINTING);
+#else
+    fe->mFontFace = cairo_ft_font_face_create_for_ft_face(aFace, 0);
+#endif
+    fe->mFilename = aFilename;
+    fe->mFTFontIndex = aIndex;
+    FTUserFontData *userFontData = new FTUserFontData(aFace, aFontData);
+    cairo_font_face_set_user_data(fe->mFontFace, &key,
+                                  userFontData, FTFontDestroyFunc);
+
+    TT_OS2 *os2 = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(aFace, ft_sfnt_os2));
+    PRUint16 os2weight = 0;
+    if (os2 && os2->version != 0xffff) {
+        // Technically, only 100 to 900 are valid, but some fonts
+        // have this set wrong -- e.g. "Microsoft Logo Bold Italic" has
+        // it set to 6 instead of 600.  We try to be nice and handle that
+        // as well.
+        if (os2->usWeightClass >= 100 && os2->usWeightClass <= 900)
+            os2weight = os2->usWeightClass;
+        else if (os2->usWeightClass >= 1 && os2->usWeightClass <= 9)
+            os2weight = os2->usWeightClass * 100;
+    }
+
+    if (os2weight != 0)
+        fe->mWeight = os2weight;
+    else if (aFace->style_flags & FT_STYLE_FLAG_BOLD)
+        fe->mWeight = 700;
+    else
+        fe->mWeight = 400;
+
+    NS_ASSERTION(fe->mWeight >= 100 && fe->mWeight <= 900, "Invalid final weight in font!");
+
+    return fe;
+}
+
+FT2FontEntry*
+gfxFT2Font::GetFontEntry()
+{
+    return static_cast<FT2FontEntry*> (mFontEntry.get());
+}
+
+cairo_font_face_t *
+FT2FontEntry::CairoFontFace()
+{
+    static cairo_user_data_key_t key;
+
+    if (!mFontFace) {
+        FT_Face face;
+        FT_New_Face(gfxToolkitPlatform::GetPlatform()->GetFTLibrary(), mFilename.get(), mFTFontIndex, &face);
+        mFTFace = face;
+#ifdef MOZ_GFX_OPTIMIZE_MOBILE
+        mFontFace = cairo_ft_font_face_create_for_ft_face(face, FT_LOAD_NO_AUTOHINT | FT_LOAD_NO_HINTING);
+#else
+        mFontFace = cairo_ft_font_face_create_for_ft_face(face, 0);
+#endif
+        FTUserFontData *userFontData = new FTUserFontData(face, nsnull);
+        cairo_font_face_set_user_data(mFontFace, &key,
+                                      userFontData, FTFontDestroyFunc);
+    }
+    return mFontFace;
+}
+
+nsresult
+FT2FontEntry::ReadCMAP()
+{
+    if (mCmapInitialized) {
+        return NS_OK;
+    }
+
+    // attempt this once, if errors occur leave a blank cmap
+    mCmapInitialized = PR_TRUE;
+
+    AutoFallibleTArray<PRUint8,16384> buffer;
+    nsresult rv = GetFontTable(TTAG_cmap, buffer);
+    
+    if (NS_SUCCEEDED(rv)) {
+        PRPackedBool unicodeFont;
+        PRPackedBool symbolFont;
+        rv = gfxFontUtils::ReadCMAP(buffer.Elements(), buffer.Length(),
+                                    mCharacterMap, mUVSOffset,
+                                    unicodeFont, symbolFont);
+    }
+
+    mHasCmapTable = NS_SUCCEEDED(rv);
+    return rv;
+}
+
+nsresult
+FT2FontEntry::GetFontTable(PRUint32 aTableTag,
+                           FallibleTArray<PRUint8>& aBuffer)
+{
+    // Ensure existence of mFTFace
+    CairoFontFace();
+    NS_ENSURE_TRUE(mFTFace, NS_ERROR_FAILURE);
+
+    FT_Error status;
+    FT_ULong len = 0;
+    status = FT_Load_Sfnt_Table(mFTFace, aTableTag, 0, nsnull, &len);
+    NS_ENSURE_TRUE(status == 0, NS_ERROR_FAILURE);
+    NS_ENSURE_TRUE(len != 0, NS_ERROR_FAILURE);
+
+    if (!aBuffer.SetLength(len)) {
+        return NS_ERROR_OUT_OF_MEMORY;
+    }
+    PRUint8 *buf = aBuffer.Elements();
+    status = FT_Load_Sfnt_Table(mFTFace, aTableTag, 0, buf, &len);
+    NS_ENSURE_TRUE(status == 0, NS_ERROR_FAILURE);
+
+    return NS_OK;
+}
+
+/*
+ * FT2FontFamily
+ * A standard gfxFontFamily; just adds a method used to support sending
+ * the font list from chrome to content via IPC.
+ */
+
+void
+FT2FontFamily::AddFacesToFontList(InfallibleTArray<FontListEntry>* aFontList)
+{
+    for (int i = 0, n = mAvailableFonts.Length(); i < n; ++i) {
+        const FT2FontEntry *fe =
+            static_cast<const FT2FontEntry*>(mAvailableFonts[i].get());
+        if (!fe) {
+            continue;
+        }
+        
+        aFontList->AppendElement(FontListEntry(Name(), fe->Name(),
+                                               fe->mFilename,
+                                               fe->Weight(), fe->Stretch(),
+                                               fe->IsItalic(),
+                                               fe->mFTFontIndex));
+    }
+}
+
+/*
+ * Startup cache support for the font list:
+ * We store the list of families and faces, with their style attributes and the
+ * corresponding font files, in the startup cache.
+ * This allows us to recreate the gfxFT2FontList collection of families and
+ * faces without instantiating Freetype faces for each font file (in order to
+ * find their attributes), leading to significantly quicker startup.
+ */
+
 #define CACHE_KEY "font.cached-list"
 
 class FontNameCache {
 public:
     FontNameCache()
         : mWriteNeeded(PR_FALSE)
     {
         mOps = (PLDHashTableOps) {
@@ -304,21 +633,16 @@ private:
 /***************************************************************
  *
  * gfxFT2FontList
  *
  */
 
 // For Mobile, we use gfxFT2Fonts, and we build the font list by directly
 // scanning the system's Fonts directory for OpenType and TrueType files.
-//
-// FontEntry is currently defined in gfxFT2Fonts.h, but should probably be
-// moved here for consistency with other platform implementations, and
-// because it logically "belongs" to the fontlist that manages the families
-// and entries.
 
 gfxFT2FontList::gfxFT2FontList()
 {
 }
 
 void
 gfxFT2FontList::AppendFacesFromCachedFaceList(nsCString& aFileName,
                                               PRBool aStdFile,
@@ -363,17 +687,17 @@ gfxFT2FontList::AppendFacesFromCachedFac
 
         beginning = end + 1;
         end = strchr(beginning, ',');
     }
 }
 
 static void
 AppendToFaceList(nsCString& aFaceList,
-                 nsAString& aFamilyName, FontEntry* aFontEntry)
+                 nsAString& aFamilyName, FT2FontEntry* aFontEntry)
 {
     aFaceList.Append(NS_ConvertUTF16toUTF8(aFamilyName));
     aFaceList.Append(',');
     aFaceList.Append(NS_ConvertUTF16toUTF8(aFontEntry->Name()));
     aFaceList.Append(',');
     aFaceList.AppendInt(aFontEntry->mFTFontIndex);
     aFaceList.Append(',');
     aFaceList.Append(aFontEntry->IsItalic() ? '1' : '0');
@@ -417,23 +741,24 @@ gfxFT2FontList::AppendFacesFromFontFile(
         timestamp = s.st_mtime;
         filesize = s.st_size;
         for (FT_Long i = 0; i < dummy->num_faces; i++) {
             FT_Face face;
             if (FT_Err_Ok != FT_New_Face(ftLibrary, aFileName.get(), i, &face)) {
                 continue;
             }
 
-            FontEntry* fe = FontEntry::CreateFontEntry(face, aFileName.get(), i);
+            FT2FontEntry* fe =
+                FT2FontEntry::CreateFontEntry(face, aFileName.get(), i);
             if (fe) {
                 NS_ConvertUTF8toUTF16 name(face->family_name);
                 BuildKeyNameFromFontName(name);       
                 gfxFontFamily *family = mFontFamilies.GetWeak(name);
                 if (!family) {
-                    family = new gfxFontFamily(name);
+                    family = new FT2FontFamily(name);
                     mFontFamilies.Put(name, family);
                     if (mBadUnderlineFamilyNames.Contains(name)) {
                         family->SetBadUnderlineFamily();
                     }
                 }
                 fe->mStandardFace = aStdFile;
                 family->AddFontEntry(fe);
                 if (family->IsBadUnderlineFamily()) {
@@ -627,23 +952,23 @@ gfxFT2FontList::FindFonts()
     mFontFamilies.Enumerate(FinalizeFamilyMemberList, this);
 #endif // XP_WIN && ANDROID
 }
 
 void
 gfxFT2FontList::AppendFaceFromFontListEntry(const FontListEntry& aFLE,
                                             PRBool aStdFile)
 {
-    FontEntry* fe = FontEntry::CreateFontEntry(aFLE);
+    FT2FontEntry* fe = FT2FontEntry::CreateFontEntry(aFLE);
     if (fe) {
         fe->mStandardFace = aStdFile;
         nsAutoString name(aFLE.familyName());
         gfxFontFamily *family = mFontFamilies.GetWeak(name);
         if (!family) {
-            family = new gfxFontFamily(name);
+            family = new FT2FontFamily(name);
             mFontFamilies.Put(name, family);
             if (mBadUnderlineFamilyNames.Contains(name)) {
                 family->SetBadUnderlineFamily();
             }
         }
         family->AddFontEntry(fe);
         if (family->IsBadUnderlineFamily()) {
             fe->mIsBadUnderlineFont = PR_TRUE;
@@ -654,17 +979,17 @@ gfxFT2FontList::AppendFaceFromFontListEn
 static PLDHashOperator
 AddFamilyToFontList(nsStringHashKey::KeyType aKey,
                     nsRefPtr<gfxFontFamily>& aFamily,
                     void* aUserArg)
 {
     InfallibleTArray<FontListEntry>* fontlist =
         reinterpret_cast<InfallibleTArray<FontListEntry>*>(aUserArg);
 
-    FontFamily *family = static_cast<FontFamily*>(aFamily.get());
+    FT2FontFamily *family = static_cast<FT2FontFamily*>(aFamily.get());
     family->AddFacesToFontList(fontlist);
 
     return PL_DHASH_NEXT;
 }
 
 void
 gfxFT2FontList::GetFontList(InfallibleTArray<FontListEntry>* retValue)
 {
@@ -718,17 +1043,17 @@ FindFullName(nsStringHashKey::KeyType aK
         }
     }
 
     return PL_DHASH_NEXT;
 }
 
 gfxFontEntry* 
 gfxFT2FontList::LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
-                                       const nsAString& aFontName)
+                                const nsAString& aFontName)
 {
     // walk over list of names
     FullFontNameSearch data(aFontName);
 
     mFontFamilies.Enumerate(FindFullName, &data);
 
     return data.mFontEntry;
 }
@@ -757,10 +1082,11 @@ gfxFT2FontList::GetDefaultFont(const gfx
 gfxFontEntry*
 gfxFT2FontList::MakePlatformFont(const gfxProxyFontEntry *aProxyEntry,
                                  const PRUint8 *aFontData,
                                  PRUint32 aLength)
 {
     // The FT2 font needs the font data to persist, so we do NOT free it here
     // but instead pass ownership to the font entry.
     // Deallocation will happen later, when the font face is destroyed.
-    return FontEntry::CreateFontEntry(*aProxyEntry, aFontData, aLength);
+    return FT2FontEntry::CreateFontEntry(*aProxyEntry, aFontData, aLength);
 }
+
--- a/gfx/thebes/gfxFT2FontList.h
+++ b/gfx/thebes/gfxFT2FontList.h
@@ -50,16 +50,79 @@
 namespace mozilla {
     namespace dom {
         class FontListEntry;
     };
 };
 using mozilla::dom::FontListEntry;
 
 class FontNameCache;
+typedef struct FT_FaceRec_* FT_Face;
+
+class FT2FontEntry : public gfxFontEntry
+{
+public:
+    FT2FontEntry(const nsAString& aFaceName) :
+        gfxFontEntry(aFaceName)
+    {
+        mFTFace = nsnull;
+        mFontFace = nsnull;
+        mFTFontIndex = 0;
+    }
+
+    ~FT2FontEntry();
+
+    const nsString& GetName() const {
+        return Name();
+    }
+
+    // create a font entry for a downloaded font
+    static FT2FontEntry* 
+    CreateFontEntry(const gfxProxyFontEntry &aProxyEntry,
+                    const PRUint8 *aFontData, PRUint32 aLength);
+
+    // create a font entry representing an installed font, identified by
+    // a FontListEntry; the freetype and cairo faces will not be instantiated
+    // until actually needed
+    static FT2FontEntry*
+    CreateFontEntry(const FontListEntry& aFLE);
+
+    // create a font entry for a given freetype face; if it is an installed font,
+    // also record the filename and index
+    static FT2FontEntry* 
+    CreateFontEntry(FT_Face aFace, const char *aFilename, PRUint8 aIndex,
+                    const PRUint8 *aFontData = nsnull);
+        // aFontData is NS_Malloc'ed data that aFace depends on, to be freed
+        // after the face is destroyed; null if there is no such buffer
+
+    virtual gfxFont *CreateFontInstance(const gfxFontStyle *aFontStyle,
+                                        PRBool aNeedsBold);
+
+    cairo_font_face_t *CairoFontFace();
+    cairo_scaled_font_t *CreateScaledFont(const gfxFontStyle *aStyle);
+
+    nsresult ReadCMAP();
+    nsresult GetFontTable(PRUint32 aTableTag, FallibleTArray<PRUint8>& aBuffer);
+
+    FT_Face mFTFace;
+    cairo_font_face_t *mFontFace;
+
+    nsCString mFilename;
+    PRUint8 mFTFontIndex;
+};
+
+class FT2FontFamily : public gfxFontFamily
+{
+public:
+    FT2FontFamily(const nsAString& aName) :
+        gfxFontFamily(aName) { }
+
+    // Append this family's faces to the IPC fontlist
+    void AddFacesToFontList(InfallibleTArray<FontListEntry>* aFontList);
+};
 
 class gfxFT2FontList : public gfxPlatformFontList
 {
 public:
     gfxFT2FontList();
 
     virtual gfxFontEntry* GetDefaultFont(const gfxFontStyle* aStyle,
                                          PRBool& aNeedsBold);
--- a/gfx/thebes/gfxFT2Fonts.cpp
+++ b/gfx/thebes/gfxFT2Fonts.cpp
@@ -40,31 +40,26 @@
 #elif defined(MOZ_WIDGET_QT)
 #include <qfontinfo.h>
 #include "gfxQtPlatform.h"
 #define gfxToolkitPlatform gfxQtPlatform
 #elif defined(XP_WIN)
 #include "gfxWindowsPlatform.h"
 #define gfxToolkitPlatform gfxWindowsPlatform
 #elif defined(ANDROID)
-#include "mozilla/dom/ContentChild.h"
 #include "gfxAndroidPlatform.h"
 #define gfxToolkitPlatform gfxAndroidPlatform
 #endif
 
 #include "gfxTypes.h"
 #include "gfxFT2Fonts.h"
 #include "gfxFT2FontBase.h"
 #include "gfxFT2Utils.h"
 #include "gfxFT2FontList.h"
 #include <locale.h>
-#include "cairo-ft.h"
-#include FT_TRUETYPE_TAGS_H
-#include FT_TRUETYPE_TABLES_H
-#include "gfxFontUtils.h"
 #include "gfxHarfBuzzShaper.h"
 #include "gfxUnicodeProperties.h"
 #include "gfxAtoms.h"
 #include "nsTArray.h"
 #include "nsUnicodeRange.h"
 #include "nsCRT.h"
 
 #include "prlog.h"
@@ -77,312 +72,16 @@ static PRLogModuleInfo *gFontLog = PR_Ne
 // rounding and truncation functions for a Freetype floating point number
 // (FT26Dot6) stored in a 32bit integer with high 26 bits for the integer
 // part and low 6 bits for the fractional part.
 #define MOZ_FT_ROUND(x) (((x) + 32) & ~63) // 63 = 2^6 - 1
 #define MOZ_FT_TRUNC(x) ((x) >> 6)
 #define CONVERT_DESIGN_UNITS_TO_PIXELS(v, s) \
         MOZ_FT_TRUNC(MOZ_FT_ROUND(FT_MulFix((v) , (s))))
 
-static cairo_scaled_font_t *
-CreateScaledFont(FontEntry *aFontEntry, const gfxFontStyle *aStyle)
-{
-    cairo_scaled_font_t *scaledFont = NULL;
-
-    cairo_matrix_t sizeMatrix;
-    cairo_matrix_t identityMatrix;
-
-    // XXX deal with adjusted size
-    cairo_matrix_init_scale(&sizeMatrix, aStyle->size, aStyle->size);
-    cairo_matrix_init_identity(&identityMatrix);
-
-    // synthetic oblique by skewing via the font matrix
-    PRBool needsOblique =
-        !aFontEntry->mItalic &&
-            (aStyle->style & (FONT_STYLE_ITALIC | FONT_STYLE_OBLIQUE));
-
-    if (needsOblique) {
-        const double kSkewFactor = 0.25;
-
-        cairo_matrix_t style;
-        cairo_matrix_init(&style,
-                          1,                //xx
-                          0,                //yx
-                          -1 * kSkewFactor,  //xy
-                          1,                //yy
-                          0,                //x0
-                          0);               //y0
-        cairo_matrix_multiply(&sizeMatrix, &sizeMatrix, &style);
-    }
-
-    cairo_font_options_t *fontOptions = cairo_font_options_create();
-
-#ifdef MOZ_GFX_OPTIMIZE_MOBILE
-    cairo_font_options_set_hint_metrics(fontOptions, CAIRO_HINT_METRICS_OFF);
-#endif
-
-    scaledFont = cairo_scaled_font_create(aFontEntry->CairoFontFace(),
-                                          &sizeMatrix,
-                                          &identityMatrix, fontOptions);
-    cairo_font_options_destroy(fontOptions);
-
-    NS_ASSERTION(cairo_scaled_font_status(scaledFont) == CAIRO_STATUS_SUCCESS,
-                 "Failed to make scaled font");
-
-    return scaledFont;
-}
-
-/**
- * FontEntry
- */
-
-FontEntry::~FontEntry()
-{
-    // Do nothing for mFTFace here since FTFontDestroyFunc is called by cairo.
-    mFTFace = nsnull;
-
-#ifndef ANDROID
-    if (mFontFace) {
-        cairo_font_face_destroy(mFontFace);
-        mFontFace = nsnull;
-    }
-#endif
-}
-
-gfxFont*
-FontEntry::CreateFontInstance(const gfxFontStyle *aFontStyle, PRBool aNeedsBold)
-{
-    cairo_scaled_font_t *scaledFont = CreateScaledFont(this, aFontStyle);
-    gfxFont *font = new gfxFT2Font(scaledFont, this, aFontStyle, aNeedsBold);
-    cairo_scaled_font_destroy(scaledFont);
-    return font;
-}
-
-/* static */
-FontEntry*
-FontEntry::CreateFontEntry(const gfxProxyFontEntry &aProxyEntry,
-                           const PRUint8 *aFontData,
-                           PRUint32 aLength)
-{
-    // Ownership of aFontData is passed in here; the fontEntry must
-    // retain it as long as the FT_Face needs it, and ensure it is
-    // eventually deleted.
-    FT_Face face;
-    FT_Error error =
-        FT_New_Memory_Face(gfxToolkitPlatform::GetPlatform()->GetFTLibrary(),
-                           aFontData, aLength, 0, &face);
-    if (error != FT_Err_Ok) {
-        NS_Free((void*)aFontData);
-        return nsnull;
-    }
-    FontEntry* fe = FontEntry::CreateFontEntry(face, nsnull, 0, aFontData);
-    if (fe) {
-        fe->mItalic = aProxyEntry.mItalic;
-        fe->mWeight = aProxyEntry.mWeight;
-        fe->mStretch = aProxyEntry.mStretch;
-    }
-    return fe;
-}
-
-class FTUserFontData {
-public:
-    FTUserFontData(FT_Face aFace, const PRUint8* aData)
-        : mFace(aFace), mFontData(aData)
-    {
-    }
-
-    ~FTUserFontData()
-    {
-        FT_Done_Face(mFace);
-        if (mFontData) {
-            NS_Free((void*)mFontData);
-        }
-    }
-
-private:
-    FT_Face        mFace;
-    const PRUint8 *mFontData;
-};
-
-static void
-FTFontDestroyFunc(void *data)
-{
-    FTUserFontData *userFontData = static_cast<FTUserFontData*>(data);
-    delete userFontData;
-}
-
-/* static */ FontEntry*
-FontEntry::CreateFontEntry(const FontListEntry& aFLE)
-{
-    FontEntry *fe = new FontEntry(aFLE.faceName());
-    fe->mFilename = aFLE.filepath();
-    fe->mFTFontIndex = aFLE.index();
-    fe->mWeight = aFLE.weight();
-    fe->mStretch = aFLE.stretch();
-    fe->mItalic = aFLE.italic();
-    return fe;
-}
-
-/* static */ FontEntry*
-FontEntry::CreateFontEntry(FT_Face aFace,
-                           const char* aFilename, PRUint8 aIndex,
-                           const PRUint8 *aFontData)
-{
-    static cairo_user_data_key_t key;
-
-    if (!aFace->family_name) {
-        FT_Done_Face(aFace);
-        return nsnull;
-    }
-    // Construct font name from family name and style name, regular fonts
-    // do not have the modifier by convention.
-    NS_ConvertUTF8toUTF16 fontName(aFace->family_name);
-    if (aFace->style_name && strcmp("Regular", aFace->style_name)) {
-        fontName.AppendLiteral(" ");
-        AppendUTF8toUTF16(aFace->style_name, fontName);
-    }
-    FontEntry *fe = new FontEntry(fontName);
-    fe->mItalic = aFace->style_flags & FT_STYLE_FLAG_ITALIC;
-    fe->mFTFace = aFace;
-#ifdef MOZ_GFX_OPTIMIZE_MOBILE
-    fe->mFontFace = cairo_ft_font_face_create_for_ft_face(aFace, FT_LOAD_NO_AUTOHINT | FT_LOAD_NO_HINTING);
-#else
-    fe->mFontFace = cairo_ft_font_face_create_for_ft_face(aFace, 0);
-#endif
-    fe->mFilename = aFilename;
-    fe->mFTFontIndex = aIndex;
-    FTUserFontData *userFontData = new FTUserFontData(aFace, aFontData);
-    cairo_font_face_set_user_data(fe->mFontFace, &key,
-                                  userFontData, FTFontDestroyFunc);
-
-    TT_OS2 *os2 = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(aFace, ft_sfnt_os2));
-    PRUint16 os2weight = 0;
-    if (os2 && os2->version != 0xffff) {
-        // Technically, only 100 to 900 are valid, but some fonts
-        // have this set wrong -- e.g. "Microsoft Logo Bold Italic" has
-        // it set to 6 instead of 600.  We try to be nice and handle that
-        // as well.
-        if (os2->usWeightClass >= 100 && os2->usWeightClass <= 900)
-            os2weight = os2->usWeightClass;
-        else if (os2->usWeightClass >= 1 && os2->usWeightClass <= 9)
-            os2weight = os2->usWeightClass * 100;
-    }
-
-    if (os2weight != 0)
-        fe->mWeight = os2weight;
-    else if (aFace->style_flags & FT_STYLE_FLAG_BOLD)
-        fe->mWeight = 700;
-    else
-        fe->mWeight = 400;
-
-    NS_ASSERTION(fe->mWeight >= 100 && fe->mWeight <= 900, "Invalid final weight in font!");
-
-    return fe;
-}
-
-FontEntry*
-gfxFT2Font::GetFontEntry()
-{
-    return static_cast<FontEntry*> (mFontEntry.get());
-}
-
-cairo_font_face_t *
-FontEntry::CairoFontFace()
-{
-    static cairo_user_data_key_t key;
-
-    if (!mFontFace) {
-        FT_Face face;
-        FT_New_Face(gfxToolkitPlatform::GetPlatform()->GetFTLibrary(), mFilename.get(), mFTFontIndex, &face);
-        mFTFace = face;
-#ifdef MOZ_GFX_OPTIMIZE_MOBILE
-        mFontFace = cairo_ft_font_face_create_for_ft_face(face, FT_LOAD_NO_AUTOHINT | FT_LOAD_NO_HINTING);
-#else
-        mFontFace = cairo_ft_font_face_create_for_ft_face(face, 0);
-#endif
-        FTUserFontData *userFontData = new FTUserFontData(face, nsnull);
-        cairo_font_face_set_user_data(mFontFace, &key,
-                                      userFontData, FTFontDestroyFunc);
-    }
-    return mFontFace;
-}
-
-nsresult
-FontEntry::ReadCMAP()
-{
-    if (mCmapInitialized) {
-        return NS_OK;
-    }
-
-    // attempt this once, if errors occur leave a blank cmap
-    mCmapInitialized = PR_TRUE;
-
-    AutoFallibleTArray<PRUint8,16384> buffer;
-    nsresult rv = GetFontTable(TTAG_cmap, buffer);
-    
-    if (NS_SUCCEEDED(rv)) {
-        PRPackedBool unicodeFont;
-        PRPackedBool symbolFont;
-        rv = gfxFontUtils::ReadCMAP(buffer.Elements(), buffer.Length(),
-                                    mCharacterMap, mUVSOffset,
-                                    unicodeFont, symbolFont);
-    }
-
-    mHasCmapTable = NS_SUCCEEDED(rv);
-    return rv;
-}
-
-nsresult
-FontEntry::GetFontTable(PRUint32 aTableTag, FallibleTArray<PRUint8>& aBuffer)
-{
-    // Ensure existence of mFTFace
-    CairoFontFace();
-    NS_ENSURE_TRUE(mFTFace, NS_ERROR_FAILURE);
-
-    FT_Error status;
-    FT_ULong len = 0;
-    status = FT_Load_Sfnt_Table(mFTFace, aTableTag, 0, nsnull, &len);
-    NS_ENSURE_TRUE(status == 0, NS_ERROR_FAILURE);
-    NS_ENSURE_TRUE(len != 0, NS_ERROR_FAILURE);
-
-    if (!aBuffer.SetLength(len)) {
-        return NS_ERROR_OUT_OF_MEMORY;
-    }
-    PRUint8 *buf = aBuffer.Elements();
-    status = FT_Load_Sfnt_Table(mFTFace, aTableTag, 0, buf, &len);
-    NS_ENSURE_TRUE(status == 0, NS_ERROR_FAILURE);
-
-    return NS_OK;
-}
-
-FontEntry *
-FontFamily::FindFontEntry(const gfxFontStyle& aFontStyle)
-{
-    PRBool needsBold = PR_FALSE;
-    return static_cast<FontEntry*>(FindFontForStyle(aFontStyle, needsBold));
-}
-
-void
-FontFamily::AddFacesToFontList(InfallibleTArray<FontListEntry>* aFontList)
-{
-    for (int i = 0, n = mAvailableFonts.Length(); i < n; ++i) {
-        const FontEntry *fe =
-            static_cast<const FontEntry*>(mAvailableFonts[i].get());
-        if (!fe) {
-            continue;
-        }
-        
-        aFontList->AppendElement(FontListEntry(Name(), fe->Name(),
-                                               fe->mFilename,
-                                               fe->Weight(), fe->Stretch(),
-                                               fe->IsItalic(),
-                                               fe->mFTFontIndex));
-    }
-}
-
 #ifndef ANDROID // not needed on Android, we use the generic gfxFontGroup
 /**
  * gfxFT2FontGroup
  */
 
 PRBool
 gfxFT2FontGroup::FontCallback(const nsAString& fontName,
                               const nsACString& genericName,
@@ -847,17 +546,17 @@ gfxFT2Font::AddRange(gfxTextRun *aTextRu
             details.mYOffset = 0;
             g.SetComplex(aTextRun->IsClusterStart(offset + i), PR_TRUE, 1);
             aTextRun->SetGlyphs(offset + i, g, &details);
         }
     }
 }
 
 gfxFT2Font::gfxFT2Font(cairo_scaled_font_t *aCairoFont,
-                       FontEntry *aFontEntry,
+                       FT2FontEntry *aFontEntry,
                        const gfxFontStyle *aFontStyle,
                        PRBool aNeedsBold)
     : gfxFT2FontBase(aCairoFont, aFontEntry, aFontStyle)
 {
     NS_ASSERTION(mFontEntry, "Unable to find font entry for font.  Something is whack.");
     mApplySyntheticBold = aNeedsBold;
     mCharGlyphCache.Init(64);
 }
@@ -877,38 +576,39 @@ gfxFT2Font::CairoFontFace()
  * In either case, add a ref, append it to the aFonts array, and return it ---
  * except for OOM in which case we do nothing and return null.
  */
 already_AddRefed<gfxFT2Font>
 gfxFT2Font::GetOrMakeFont(const nsAString& aName, const gfxFontStyle *aStyle,
                           PRBool aNeedsBold)
 {
 #ifdef ANDROID
-    FontEntry *fe = static_cast<FontEntry*>
+    FT2FontEntry *fe = static_cast<FT2FontEntry*>
         (gfxPlatformFontList::PlatformFontList()->
             FindFontForFamily(aName, aStyle, aNeedsBold));
 #else
-    FontEntry *fe = static_cast<FontEntry*>
+    FT2FontEntry *fe = static_cast<FT2FontEntry*>
         (gfxToolkitPlatform::GetPlatform()->FindFontEntry(aName, *aStyle));
 #endif
     if (!fe) {
         NS_WARNING("Failed to find font entry for font!");
         return nsnull;
     }
 
     nsRefPtr<gfxFT2Font> font = GetOrMakeFont(fe, aStyle, aNeedsBold);
     return font.forget();
 }
 
 already_AddRefed<gfxFT2Font>
-gfxFT2Font::GetOrMakeFont(FontEntry *aFontEntry, const gfxFontStyle *aStyle, PRBool aNeedsBold)
+gfxFT2Font::GetOrMakeFont(FT2FontEntry *aFontEntry, const gfxFontStyle *aStyle,
+                          PRBool aNeedsBold)
 {
     nsRefPtr<gfxFont> font = gfxFontCache::GetCache()->Lookup(aFontEntry, aStyle);
     if (!font) {
-        cairo_scaled_font_t *scaledFont = CreateScaledFont(aFontEntry, aStyle);
+        cairo_scaled_font_t *scaledFont = aFontEntry->CreateScaledFont(aStyle);
         font = new gfxFT2Font(scaledFont, aFontEntry, aStyle, aNeedsBold);
         cairo_scaled_font_destroy(scaledFont);
         if (!font)
             return nsnull;
         gfxFontCache::GetCache()->AddNew(font);
     }
     gfxFont *f = nsnull;
     font.swap(f);
--- a/gfx/thebes/gfxFT2Fonts.h
+++ b/gfx/thebes/gfxFT2Fonts.h
@@ -42,112 +42,36 @@
 #include "cairo.h"
 #include "gfxTypes.h"
 #include "gfxFont.h"
 #include "gfxFT2FontBase.h"
 #include "gfxContext.h"
 #include "gfxFontUtils.h"
 #include "gfxUserFontSet.h"
 
-namespace mozilla {
-    namespace dom {
-        class FontListEntry;
-    };
-};
-using mozilla::dom::FontListEntry;
-
-typedef struct FT_FaceRec_* FT_Face;
-
-/**
- * FontFamily is a class that describes one of the fonts on the users system.  It holds
- * each FontEntry (maps more directly to a font face) which holds font type, charset info
- * and character map info.
- */
-class FontEntry;
-class FontFamily : public gfxFontFamily
-{
-public:
-    FontFamily(const nsAString& aName) :
-        gfxFontFamily(aName) { }
-
-    FontEntry *FindFontEntry(const gfxFontStyle& aFontStyle);
-
-    // Append this family's faces to the IPC fontlist
-    void AddFacesToFontList(InfallibleTArray<FontListEntry>* aFontList);
-};
-
-class FontEntry : public gfxFontEntry
-{
-public:
-    FontEntry(const nsAString& aFaceName) :
-        gfxFontEntry(aFaceName)
-    {
-        mFTFace = nsnull;
-        mFontFace = nsnull;
-        mFTFontIndex = 0;
-    }
-
-    ~FontEntry();
-
-    const nsString& GetName() const {
-        return Name();
-    }
-
-    // create a font entry for a downloaded font
-    static FontEntry* 
-    CreateFontEntry(const gfxProxyFontEntry &aProxyEntry,
-                    const PRUint8 *aFontData, PRUint32 aLength);
-
-    // create a font entry representing an installed font, identified by
-    // a FontListEntry; the freetype and cairo faces will not be instantiated
-    // until actually needed
-    static FontEntry*
-    CreateFontEntry(const FontListEntry& aFLE);
-
-    // create a font entry for a given freetype face; if it is an installed font,
-    // also record the filename and index
-    static FontEntry* 
-    CreateFontEntry(FT_Face aFace, const char *aFilename, PRUint8 aIndex,
-                    const PRUint8 *aFontData = nsnull);
-        // aFontData is NS_Malloc'ed data that aFace depends on, to be freed
-        // after the face is destroyed; null if there is no such buffer
-
-    virtual gfxFont *CreateFontInstance(const gfxFontStyle *aFontStyle, PRBool aNeedsBold);
-
-    cairo_font_face_t *CairoFontFace();
-    nsresult ReadCMAP();
-
-    nsresult GetFontTable(PRUint32 aTableTag, FallibleTArray<PRUint8>& aBuffer);
-
-    FT_Face mFTFace;
-    cairo_font_face_t *mFontFace;
-
-    nsCString mFilename;
-    PRUint8 mFTFontIndex;
-};
-
+class FT2FontEntry;
 
 class gfxFT2Font : public gfxFT2FontBase {
 public: // new functions
     gfxFT2Font(cairo_scaled_font_t *aCairoFont,
-               FontEntry *aFontEntry,
+               FT2FontEntry *aFontEntry,
                const gfxFontStyle *aFontStyle,
                PRBool aNeedsBold);
     virtual ~gfxFT2Font ();
 
     cairo_font_face_t *CairoFontFace();
 
-    FontEntry *GetFontEntry();
+    FT2FontEntry *GetFontEntry();
 
     static already_AddRefed<gfxFT2Font>
     GetOrMakeFont(const nsAString& aName, const gfxFontStyle *aStyle,
                   PRBool aNeedsBold = PR_FALSE);
 
     static already_AddRefed<gfxFT2Font>
-    GetOrMakeFont(FontEntry *aFontEntry, const gfxFontStyle *aStyle,
+    GetOrMakeFont(FT2FontEntry *aFontEntry, const gfxFontStyle *aStyle,
                   PRBool aNeedsBold = PR_FALSE);
 
     struct CachedGlyphData {
         CachedGlyphData()
             : glyphIndex(0xffffffffU) { }
 
         CachedGlyphData(PRUint32 gid)
             : glyphIndex(gid) { }