bug 462908 - Implement Freetype font backend for windows ce r=karlt, jdagget sr=stuart, vlad
authorBrad Lassey <blassey@mozilla.com>
Fri, 23 Jan 2009 01:24:29 -0500
changeset 24104 aa27de3b85637bed160aa6419f4b99333bea69fd
parent 24103 7fdc9ed7396804cac517f4131dad0e3425a816b0
child 24105 13e903f17346aca3d2e193b8f89a18ff546aaa5d
push idunknown
push userunknown
push dateunknown
reviewerskarlt, jdagget, stuart, vlad
bugs462908
milestone1.9.2a1pre
bug 462908 - Implement Freetype font backend for windows ce r=karlt, jdagget sr=stuart, vlad
config/autoconf.mk.in
configure.in
gfx/cairo/cairo/src/Makefile.in
gfx/cairo/cairo/src/cairo-features.h.in
gfx/cairo/cairo/src/cairo-ft-font.c
gfx/cairo/cairo/src/cairo-ft.h
gfx/src/thebes/nsThebesFontMetrics.cpp
gfx/thebes/public/Makefile.in
gfx/thebes/public/gfxFT2Fonts.h
gfx/thebes/public/gfxFont.h
gfx/thebes/public/gfxFontUtils.h
gfx/thebes/public/gfxWindowsFonts.h
gfx/thebes/public/gfxWindowsPlatform.h
gfx/thebes/src/Makefile.in
gfx/thebes/src/gfxFT2Fonts.cpp
gfx/thebes/src/gfxWindowsFonts.cpp
gfx/thebes/src/gfxWindowsPlatform.cpp
toolkit/library/Makefile.in
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -490,16 +490,17 @@ QT_CONFIG	= @QT_CONFIG@
 TK_CFLAGS	= @TK_CFLAGS@
 TK_LIBS		= @TK_LIBS@
 
 MOZ_TOOLKIT_REGISTRY_CFLAGS = \
 	$(TK_CFLAGS)
 
 CAIRO_FT_CFLAGS		= @CAIRO_FT_CFLAGS@
 
+MOZ_TREE_FREETYPE		= @MOZ_TREE_FREETYPE@
 MOZ_ENABLE_CAIRO_FT	= @MOZ_ENABLE_CAIRO_FT@
 MOZ_ENABLE_GTK2		= @MOZ_ENABLE_GTK2@
 MOZ_ENABLE_QT		= @MOZ_ENABLE_QT@
 MOZ_ENABLE_PHOTON	= @MOZ_ENABLE_PHOTON@
 MOZ_ENABLE_COCOA	= @MOZ_ENABLE_COCOA@
 MOZ_ENABLE_XREMOTE	= @MOZ_ENABLE_XREMOTE@
 
 MOZ_GTK2_CFLAGS		= @MOZ_GTK2_CFLAGS@
--- a/configure.in
+++ b/configure.in
@@ -1962,16 +1962,17 @@ case "$target" in
     TARGET_NSPR_MDCPUCFG='\"md/_wince.cfg\"'
     UNZIP=unzip
     XARGS=xargs
     XPCOM_FROZEN_LDOPTS='$(LIBXUL_DIST)/lib/xpcom.lib'
     ZIP=zip
     LIBIDL_CFLAGS="-I$MOZ_TOOLS_DIR/include ${GLIB_CFLAGS}"
     LIBIDL_LIBS="$MOZ_TOOLS_DIR/lib/libidl-0.6_s.lib $MOZ_TOOLS_DIR/lib/glib-1.2_s.lib"
     STATIC_LIBIDL=1
+    MOZ_TREE_FREETYPE=1
 
     AC_DEFINE(HAVE_SNPRINTF)
     AC_DEFINE(_WINDOWS)
     AC_DEFINE(_WIN32)
     AC_DEFINE(WIN32)
     AC_DEFINE(XP_WIN)
     AC_DEFINE(XP_WIN32)
     AC_DEFINE(HW_THREADS)
@@ -5756,16 +5757,40 @@ MOZ_ARG_ENABLE_BOOL(smil,
 [  --enable-smil            Enable SMIL animation support],
     MOZ_SMIL=1,
     MOZ_SMIL= )
 if test -n "$MOZ_SMIL"; then
   AC_DEFINE(MOZ_SMIL)
 fi
 
 dnl ========================================================
+dnl Build Freetype in the tree
+dnl ========================================================
+MOZ_ARG_ENABLE_BOOL(tree-freetype,
+[  --enable-tree-freetype         Enable Tree FreeType],
+    MOZ_TREE_FREETYPE=1,
+    MOZ_TREE_FREETYPE= )
+if test -n "$MOZ_TREE_FREETYPE"; then
+   AC_DEFINE(MOZ_TREE_FREETYPE)
+   AC_SUBST(MOZ_TREE_FREETYPE)
+   MOZ_ENABLE_CAIRO_FT=1       
+   FT_FONT_FEATURE="#define CAIRO_HAS_FT_FONT 1"
+   FC_FONT_FEATURE="#define CAIRO_DISABLE_FONTCONFIG 1"
+   FT2_CFLAGS="-I${topsrcdir}/modules/freetype2/include"
+   CAIRO_FT_CFLAGS="-I${topsrcdir}/modules/freetype2/include"
+   FT2_LIBS="${LIBXUL_DIST}/lib/freetype2.lib"
+   CAIRO_FT_LIBS = "${LIBXUL_DIST}/lib/freetype2.lib"
+   AC_DEFINE(HAVE_FT_BITMAP_SIZE_Y_PPEM)
+   AC_DEFINE(HAVE_FT_GLYPHSLOT_EMBOLDEN)
+   AC_DEFINE(HAVE_FT_LOAD_SFNT_TABLE)
+   AC_SUBST(CAIRO_FT_CFLAGS)
+fi
+
+
+dnl ========================================================
 dnl Installer
 dnl ========================================================
 case "$target_os" in
     aix*|solaris*|linux*|msvc*|mks*|cygwin*|mingw*|os2*|wince*)
         MOZ_INSTALLER=1
         ;;
 esac
 
@@ -7397,17 +7422,21 @@ if test "$MOZ_TREE_CAIRO"; then
     fi
     if test "$MOZ_WIDGET_TOOLKIT" = "mac" -o "$MOZ_WIDGET_TOOLKIT" = "cocoa"; then
         QUARTZ_SURFACE_FEATURE="#define CAIRO_HAS_QUARTZ_SURFACE 1"
         QUARTZ_IMAGE_SURFACE_FEATURE="#define CAIRO_HAS_QUARTZ_IMAGE_SURFACE 1"
         QUARTZ_FONT_FEATURE="#define CAIRO_HAS_QUARTZ_FONT 1"
     fi
     if test "$MOZ_WIDGET_TOOLKIT" = "windows"; then
         WIN32_SURFACE_FEATURE="#define CAIRO_HAS_WIN32_SURFACE 1"
-        WIN32_FONT_FEATURE="#define CAIRO_HAS_WIN32_FONT 1"
+        if test -z "$WINCE"; then
+           WIN32_FONT_FEATURE="#define CAIRO_HAS_WIN32_FONT 1"
+        else
+           WIN32_FONT_FEATURE=
+        fi  
         PDF_SURFACE_FEATURE="#define CAIRO_HAS_PDF_SURFACE 1"
     fi
     if test "$MOZ_WIDGET_TOOLKIT" = "os2"; then
         OS2_SURFACE_FEATURE="#define CAIRO_HAS_OS2_SURFACE 1"
         FT_FONT_FEATURE="#define CAIRO_HAS_FT_FONT 1"
         PDF_SURFACE_FEATURE="#define CAIRO_HAS_PDF_SURFACE 1"
         MOZ_ENABLE_CAIRO_FT=1
         CAIRO_FT_CFLAGS="-I${MZFTCFGFT2}/include"
@@ -7438,16 +7467,17 @@ if test "$MOZ_TREE_CAIRO"; then
     AC_SUBST(QUARTZ_SURFACE_FEATURE)
     AC_SUBST(QUARTZ_IMAGE_SURFACE_FEATURE)
     AC_SUBST(XCB_SURFACE_FEATURE)
     AC_SUBST(WIN32_SURFACE_FEATURE)
     AC_SUBST(OS2_SURFACE_FEATURE)
     AC_SUBST(BEOS_SURFACE_FEATURE)
     AC_SUBST(DIRECTFB_SURFACE_FEATURE)
     AC_SUBST(FT_FONT_FEATURE)
+    AC_SUBST(FC_FONT_FEATURE)
     AC_SUBST(WIN32_FONT_FEATURE)
     AC_SUBST(QUARTZ_FONT_FEATURE)
     AC_SUBST(PNG_FUNCTIONS_FEATURE)
     AC_SUBST(QPAINTER_SURFACE_FEATURE)
 
     if test "$_WIN32_MSVC"; then
         MOZ_CAIRO_LIBS='$(DEPTH)/gfx/cairo/cairo/src/mozcairo.lib $(DEPTH)/gfx/cairo/libpixman/src/mozlibpixman.lib'
     else
--- a/gfx/cairo/cairo/src/Makefile.in
+++ b/gfx/cairo/cairo/src/Makefile.in
@@ -143,18 +143,21 @@ PDF_CSRCS = \
 	$(NULL)
 
 PS_CSRCS = cairo-ps-surface.c
 
 PDF_EXPORTS = cairo-pdf.h
 PS_EXPORTS = cairo-ps.h
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
-CSRCS	+= 	cairo-win32-font.c \
-			cairo-win32-surface.c
+CSRCS	+=	cairo-win32-surface.c
+
+ifndef WINCE
+CSRCS	+=	cairo-win32-font.c
+endif
 
 ifdef NS_PRINTING
 CSRCS   += cairo-win32-printing-surface.c
 else
 DEFINES += -DCAIRO_OMIT_WIN32_PRINTING
 endif
 
 EXPORTS += cairo-win32.h
--- a/gfx/cairo/cairo/src/cairo-features.h.in
+++ b/gfx/cairo/cairo/src/cairo-features.h.in
@@ -84,9 +84,10 @@
 @FT_FONT_FEATURE@
 
 @WIN32_FONT_FEATURE@
 
 @QUARTZ_FONT_FEATURE@
 
 @PNG_FUNCTIONS_FEATURE@
 
+@FC_FONT_FEATURE@
 #endif
--- a/gfx/cairo/cairo/src/cairo-ft-font.c
+++ b/gfx/cairo/cairo/src/cairo-ft-font.c
@@ -40,18 +40,20 @@
 
 #define _BSD_SOURCE /* for strdup() */
 #include "cairoint.h"
 
 #include "cairo-ft-private.h"
 
 #include <float.h>
 
+#ifndef CAIRO_DISABLE_FONTCONFIG
 #include <fontconfig/fontconfig.h>
 #include <fontconfig/fcfreetype.h>
+#endif
 
 #include <ft2build.h>
 #include FT_FREETYPE_H
 #include FT_OUTLINE_H
 #include FT_IMAGE_H
 #include FT_TRUETYPE_TABLES_H
 #if HAVE_FT_GLYPHSLOT_EMBOLDEN
 #include FT_SYNTHESIS_H
@@ -116,19 +118,21 @@ struct _cairo_ft_unscaled_font {
 
 static int
 _cairo_ft_unscaled_font_keys_equal (const void *key_a,
 				    const void *key_b);
 
 static void
 _cairo_ft_unscaled_font_fini (cairo_ft_unscaled_font_t *unscaled);
 
+#ifndef CAIRO_DISABLE_FONTCONFIG
 static cairo_status_t
 _cairo_ft_font_options_substitute (const cairo_font_options_t *options,
 				   FcPattern                  *pattern);
+#endif
 
 typedef enum _cairo_ft_extra_flags {
     CAIRO_FT_OPTIONS_HINT_METRICS = (1 << 0),
     CAIRO_FT_OPTIONS_EMBOLDEN = (1 << 1)
 } cairo_ft_extra_flags_t;
 
 typedef struct _cairo_ft_options {
     cairo_font_options_t    base;
@@ -459,17 +463,17 @@ UNWIND_UNSCALED_FONT_INIT:
 UNWIND_UNSCALED_MALLOC:
     free (unscaled);
 UNWIND_FONT_MAP_LOCK:
     _cairo_ft_unscaled_font_map_unlock ();
 UNWIND:
     return NULL;
 }
 
-
+#ifndef CAIRO_DISABLE_FONTCONFIG
 static cairo_ft_unscaled_font_t *
 _cairo_ft_unscaled_font_create_for_pattern (FcPattern *pattern)
 {
     FT_Face font_face = NULL;
     char *filename = NULL;
     int id = 0;
 
     if (FcPatternGetFTFace (pattern, FC_FT_FACE, 0, &font_face) != FcResultMatch) {
@@ -483,16 +487,17 @@ static cairo_ft_unscaled_font_t *
 	    goto UNWIND;
     }
 
     return _cairo_ft_unscaled_font_create_internal (font_face != NULL, filename, id, font_face);
 
 UNWIND:
     return NULL;
 }
+#endif
 
 static cairo_ft_unscaled_font_t *
 _cairo_ft_unscaled_font_create_from_face (FT_Face face)
 {
     return _cairo_ft_unscaled_font_create_internal (TRUE, NULL, 0, face);
 }
 
 static void
@@ -1285,16 +1290,17 @@ static const cairo_unscaled_font_backend
 typedef struct _cairo_ft_scaled_font {
     cairo_scaled_font_t base;
     cairo_ft_unscaled_font_t *unscaled;
     cairo_ft_options_t ft_options;
 } cairo_ft_scaled_font_t;
 
 const cairo_scaled_font_backend_t _cairo_ft_scaled_font_backend;
 
+#ifndef CAIRO_DISABLE_FONTCONFIG
 /* The load flags passed to FT_Load_Glyph control aspects like hinting and
  * antialiasing. Here we compute them from the fields of a FcPattern.
  */
 static void
 _get_pattern_ft_options (FcPattern *pattern, cairo_ft_options_t *ret)
 {
     FcBool antialias, vertical_layout, hinting, autohint, bitmap, embolden;
     cairo_ft_options_t ft_options;
@@ -1420,16 +1426,17 @@ static void
 			  FC_EMBOLDEN, 0, &embolden) != FcResultMatch)
 	embolden = FcFalse;
     
     if (embolden)
 	ft_options.extra_flags |= CAIRO_FT_OPTIONS_EMBOLDEN;
 
     *ret = ft_options;
 }
+#endif /* CAIRO_DISABLE_FONTCONFIG */
 
 static void
 _cairo_ft_options_merge (cairo_ft_options_t *options,
 			 cairo_ft_options_t *other)
 {
     int load_flags = other->load_flags;
     int load_target = FT_LOAD_TARGET_NORMAL;
 
@@ -1616,16 +1623,17 @@ cairo_bool_t
 
 static cairo_status_t
 _cairo_ft_scaled_font_create_toy (cairo_toy_font_face_t	      *toy_face,
 				  const cairo_matrix_t	      *font_matrix,
 				  const cairo_matrix_t	      *ctm,
 				  const cairo_font_options_t  *font_options,
 				  cairo_scaled_font_t	     **font)
 {
+#ifndef CAIRO_DISABLE_FONTCONFIG
     FcPattern *pattern, *resolved;
     cairo_ft_unscaled_font_t *unscaled;
     FcResult result;
     int fcslant;
     int fcweight;
     cairo_matrix_t scale;
     cairo_status_t status;
     cairo_ft_font_transform_t sf;
@@ -1722,16 +1730,19 @@ static cairo_status_t
 
  FREE_RESOLVED:
     FcPatternDestroy (resolved);
 
  FREE_PATTERN:
     FcPatternDestroy (pattern);
 
     return status;
+#else
+    return CAIRO_INT_STATUS_UNSUPPORTED;
+#endif  /* CAIRO_DISABLE_FONTCONFIG */
 }
 
 static void
 _cairo_ft_scaled_font_fini (void *abstract_font)
 {
     cairo_ft_scaled_font_t *scaled_font = abstract_font;
 
     if (scaled_font == NULL)
@@ -2143,20 +2154,21 @@ static unsigned long
     cairo_ft_unscaled_font_t *unscaled = scaled_font->unscaled;
     FT_Face face;
     FT_UInt index;
 
     face = _cairo_ft_unscaled_font_lock_face (unscaled);
     if (!face)
 	return 0;
 
-    /* If making this compile without fontconfig, use:
-     * index = FT_Get_Char_Index (face, ucs4); */
+#ifdef CAIRO_DISABLE_FONTCONFIG
+    index = FT_Get_Char_Index (face, ucs4); 
+#else
     index = FcFreeTypeCharIndex (face, ucs4);
-
+#endif
     _cairo_ft_unscaled_font_unlock_face (unscaled);
     return index;
 }
 
 static cairo_int_status_t
 _cairo_ft_load_truetype_table (void	       *abstract_font,
                               unsigned long     tag,
                               long              offset,
@@ -2368,16 +2380,17 @@ static cairo_font_face_t *
     font_face->next = unscaled->faces;
     unscaled->faces = font_face;
 
     _cairo_font_face_init (&font_face->base, &_cairo_ft_font_face_backend);
 
     return &font_face->base;
 }
 
+#ifndef CAIRO_DISABLE_FONTCONFIG
 /* implement the platform-specific interface */
 
 static cairo_status_t
 _cairo_ft_font_options_substitute (const cairo_font_options_t *options,
 				   FcPattern                  *pattern)
 {
     FcValue v;
 
@@ -2543,16 +2556,17 @@ cairo_ft_font_face_create_for_pattern (F
     }
 
     _get_pattern_ft_options (pattern, &ft_options);
     font_face = _cairo_ft_font_face_create (unscaled, &ft_options);
     _cairo_unscaled_font_destroy (&unscaled->base);
 
     return font_face;
 }
+#endif /* CAIRO_DISABLE_FONTCONFIG */
 
 /**
  * cairo_ft_font_face_create_for_ft_face:
  * @face: A FreeType face object, already opened. This must
  *   be kept around until the face's ref_count drops to
  *   zero and it is freed. Since the face may be referenced
  *   internally to Cairo, the best way to determine when it
  *   is safe to free the face is to pass a
--- a/gfx/cairo/cairo/src/cairo-ft.h
+++ b/gfx/cairo/cairo/src/cairo-ft.h
@@ -38,28 +38,32 @@
 #define CAIRO_FT_H
 
 #include "cairo.h"
 
 #if CAIRO_HAS_FT_FONT
 
 /* Fontconfig/Freetype platform-specific font interface */
 
+#ifndef CAIRO_DISABLE_FONTCONFIG
 #include <fontconfig/fontconfig.h>
+#endif
 #include <ft2build.h>
 #include FT_FREETYPE_H
 
 CAIRO_BEGIN_DECLS
 
+#ifndef CAIRO_DISABLE_FONTCONFIG
 cairo_public cairo_font_face_t *
 cairo_ft_font_face_create_for_pattern (FcPattern *pattern);
 
 cairo_public void
 cairo_ft_font_options_substitute (const cairo_font_options_t *options,
 				  FcPattern                  *pattern);
+#endif
 
 cairo_public cairo_font_face_t *
 cairo_ft_font_face_create_for_ft_face (FT_Face         face,
 				       int             load_flags);
 
 cairo_public FT_Face
 cairo_ft_scaled_font_lock_face (cairo_scaled_font_t *scaled_font);
 
--- a/gfx/src/thebes/nsThebesFontMetrics.cpp
+++ b/gfx/src/thebes/nsThebesFontMetrics.cpp
@@ -87,16 +87,18 @@ nsThebesFontMetrics::Init(const nsFont& 
     mFontStyle = new gfxFontStyle(aFont.style, aFont.weight, size, langGroup,
                                   aFont.sizeAdjust, aFont.systemFont,
                                   aFont.familyNameQuirks,
                                   printerFont);
 
     mFontGroup =
         gfxPlatform::GetPlatform()->CreateFontGroup(aFont.name, mFontStyle, 
                                                     aUserFontSet);
+    if (mFontGroup->FontListLength() < 1) 
+        return NS_ERROR_UNEXPECTED;
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsThebesFontMetrics::Destroy()
 {
     return NS_OK;
--- a/gfx/thebes/public/Makefile.in
+++ b/gfx/thebes/public/Makefile.in
@@ -32,23 +32,28 @@ EXPORTS		= 	gfxASurface.h \
 			gfxTextRunWordCache.h \
 			gfxUtils.h \
 			gfxUserFontSet.h \
 			$(NULL)
 
 EXPORTS += gfxFontTest.h
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
-EXPORTS	+=	gfxWindowsFonts.h \
-		gfxWindowsPlatform.h \
+EXPORTS	+=	gfxWindowsPlatform.h \
 		gfxWindowsSurface.h \
 		gfxWindowsNativeDrawing.h \
 		$(NULL)
 EXPORTS +=	gfxPDFSurface.h
 
+ifdef WINCE
+EXPORTS +=	gfxFT2Fonts.h 
+else
+EXPORTS +=	gfxWindowsFonts.h 
+endif
+
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
 
 ifdef MOZ_X11
 EXPORTS += gfxXlibSurface.h
 endif
 
--- a/gfx/thebes/public/gfxFT2Fonts.h
+++ b/gfx/thebes/public/gfxFT2Fonts.h
@@ -39,16 +39,17 @@
 #ifndef GFX_GTKDFBFONTS_H
 #define GFX_GTKDFBFONTS_H
 
 #include "cairo.h"
 #include "gfxTypes.h"
 #include "gfxFont.h"
 #include "gfxContext.h"
 #include "gfxFontUtils.h"
+#include "gfxUserFontSet.h"
 
 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.
  */
@@ -56,16 +57,19 @@ class FontEntry;
 class FontFamily : public gfxFontFamily
 {
 public:
     FontFamily(const nsAString& aName) :
         gfxFontFamily(aName) { }
 
     FontEntry *FindFontEntry(const gfxFontStyle& aFontStyle);
 
+protected:
+    virtual PRBool FindWeightsForStyle(gfxFontEntry* aFontsForWeights[], const gfxFontStyle& aFontStyle);
+
 public:
     nsTArray<nsRefPtr<FontEntry> > mFaces;
     nsString mName;
 };
 
 class FontEntry : public gfxFontEntry
 {
 public:
@@ -80,16 +84,24 @@ public:
 
     FontEntry(const FontEntry& aFontEntry);
     ~FontEntry();
 
     const nsString& GetName() const {
         return mFaceName;
     }
 
+
+    static FontEntry* 
+    CreateFontEntry(const gfxProxyFontEntry &aProxyEntry, nsISupports *aLoader,
+                 const PRUint8 *aFontData, PRUint32 aLength);
+    
+    static FontEntry* 
+    CreateFontEntryFromFace(FT_Face aFace);
+    
     cairo_font_face_t *CairoFontFace();
 
     cairo_font_face_t *mFontFace;
 
     nsString mFaceName;
     nsCString mFilename;
     PRUint8 mFTFontIndex;
 
@@ -110,16 +122,20 @@ public: // new functions
     cairo_font_face_t *CairoFontFace();
     cairo_scaled_font_t *CairoScaledFont();
 
     virtual PRBool SetupCairoFont(gfxContext *aContext);
     virtual nsString GetUniqueName();
     virtual PRUint32 GetSpaceGlyph();
 
     FontEntry *GetFontEntry();
+
+    static already_AddRefed<gfxFT2Font>
+    GetOrMakeFont(const nsAString& aName, const gfxFontStyle *aStyle);
+
 private:
     cairo_scaled_font_t *mScaledFont;
 
     PRBool mHasSpaceGlyph;
     PRUint32 mSpaceGlyph;
     PRBool mHasMetrics;
     Metrics mMetrics;
     gfxFloat mAdjustedSize;
@@ -134,16 +150,18 @@ public: // new functions
     inline gfxFT2Font *GetFontAt (PRInt32 i) {
         // If it turns out to be hard for all clients that cache font
         // groups to call UpdateFontList at appropriate times, we could
         // instead consider just calling UpdateFontList from someplace
         // more central (such as here).
         NS_ASSERTION(!mUserFontSet || mCurrGeneration == GetGeneration(),
                      "Whoever was caching this font group should have "
                      "called UpdateFontList on it");
+        NS_ASSERTION(mFonts.Length() > PRUint32(i), 
+                     "Requesting a font index that doesn't exist");
 
         return static_cast <gfxFT2Font *>(static_cast <gfxFont *>(mFonts[i]));
     }
 
 protected: // from gfxFontGroup
     virtual gfxTextRun *MakeTextRun(const PRUnichar *aString, 
                                     PRUint32 aLength,
                                     const Parameters *aParams, 
--- a/gfx/thebes/public/gfxFont.h
+++ b/gfx/thebes/public/gfxFont.h
@@ -1533,16 +1533,18 @@ public:
     virtual gfxFont *GetFontAt(PRInt32 i) {
         // If it turns out to be hard for all clients that cache font
         // groups to call UpdateFontList at appropriate times, we could
         // instead consider just calling UpdateFontList from someplace
         // more central (such as here).
         NS_ASSERTION(!mUserFontSet || mCurrGeneration == GetGeneration(),
                      "Whoever was caching this font group should have "
                      "called UpdateFontList on it");
+        NS_ASSERTION(mFonts.Length() > PRUint32(i), 
+                     "Requesting a font index that doesn't exist");
 
         return static_cast<gfxFont*>(mFonts[i]);
     }
     virtual PRUint32 FontListLength() const {
         return mFonts.Length();
     }
 
     PRBool Equals(const gfxFontGroup& other) const {
--- a/gfx/thebes/public/gfxFontUtils.h
+++ b/gfx/thebes/public/gfxFontUtils.h
@@ -83,16 +83,17 @@ public:
         mBlocks.AppendElements(len);
         for (PRUint32 i = 0; i < len; ++i) {
             Block *block = aBitset.mBlocks[i];
             if (block)
                 mBlocks[i] = new Block(*block);
         }
     }
     PRBool test(PRUint32 aIndex) {
+        NS_ASSERTION(mBlocks.DebugGetHeader(), "mHdr is null, this is bad");
         PRUint32 blockIndex = aIndex/BLOCK_SIZE_BITS;
         if (blockIndex >= mBlocks.Length())
             return PR_FALSE;
         Block *block = mBlocks[blockIndex];
         if (!block)
             return PR_FALSE;
         return ((block->mBits[(aIndex>>3) & (BLOCK_SIZE - 1)]) & (1 << (aIndex & 0x7))) != 0;
     }
--- a/gfx/thebes/public/gfxWindowsFonts.h
+++ b/gfx/thebes/public/gfxWindowsFonts.h
@@ -41,23 +41,23 @@
 #define GFX_WINDOWSFONTS_H
 
 #include "prtypes.h"
 #include "gfxTypes.h"
 #include "gfxColor.h"
 #include "gfxFont.h"
 #include "gfxMatrix.h"
 #include "gfxFontUtils.h"
+#include "gfxUserFontSet.h"
 
 #include "nsDataHashtable.h"
 
 #include <usp10.h>
 #include <cairo-win32.h>
 
-
 /**
  * List of different types of fonts we support on Windows.
  * These can generally be lumped in to 3 categories where we have to
  * do special things:  Really old fonts bitmap and vector fonts (device
  * and raster), Type 1 fonts, and TrueType/OpenType fonts.
  * 
  * This list is sorted in order from least prefered to most prefered.
  * We prefer Type1 fonts over OpenType fonts to avoid falling back to
@@ -126,17 +126,23 @@ public:
         mFontType(aFontEntry.mFontType),
         mForceGDI(aFontEntry.mForceGDI),
         mUnknownCMAP(aFontEntry.mUnknownCMAP),
         mCharset(aFontEntry.mCharset),
         mUnicodeRanges(aFontEntry.mUnicodeRanges)
     {
 
     }
+    static void InitializeFontEmbeddingProcs();
 
+    static FontEntry* CreateFontEntry(const gfxProxyFontEntry &aProxyEntry,
+                                      nsISupports *aLoader,
+                                      const PRUint8 *aFontData,
+                                      PRUint32 aLength);
+    
     static FontEntry* CreateFontEntry(const nsAString& aName, gfxWindowsFontType aFontType, PRBool aItalic, PRUint16 aWeight, gfxUserFontData* aUserFontData, HDC hdc = 0, LOGFONTW *aLogFont = nsnull);
 
     static void FillLogFont(LOGFONTW *aLogFont, FontEntry *aFontEntry, gfxFloat aSize, PRBool aItalic);
 
     static gfxWindowsFontType DetermineFontType(const NEWTEXTMETRICW& metrics, DWORD fontType)
     {
         gfxWindowsFontType feType;
         if (metrics.ntmFlags & NTM_TYPE1)
--- a/gfx/thebes/public/gfxWindowsPlatform.h
+++ b/gfx/thebes/public/gfxWindowsPlatform.h
@@ -36,23 +36,31 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef GFX_WINDOWS_PLATFORM_H
 #define GFX_WINDOWS_PLATFORM_H
 
 #include "gfxFontUtils.h"
 #include "gfxWindowsSurface.h"
+#ifdef MOZ_FT2_FONTS
+#include "gfxFT2Fonts.h"
+#else
 #include "gfxWindowsFonts.h"
+#endif
 #include "gfxPlatform.h"
 
 #include "nsVoidArray.h"
 #include "nsTArray.h"
 #include "nsDataHashtable.h"
 
+#ifdef MOZ_FT2_FONTS
+typedef struct FT_LibraryRec_ *FT_Library;
+#endif
+
 #include <windows.h>
 
 class THEBES_API gfxWindowsPlatform : public gfxPlatform, private gfxFontInfoLoader {
 public:
     gfxWindowsPlatform();
     virtual ~gfxWindowsPlatform();
     static gfxWindowsPlatform *GetPlatform() {
         return (gfxWindowsPlatform*) gfxPlatform::GetPlatform();
@@ -100,27 +108,35 @@ public:
 
     /* Given a string and a font we already have find the font that
      * supports the most code points and most closely resembles aFont
      *
      * this involves looking at the fonts on your machine and seeing which
      * code points they support as well as looking at things like the font
      * family, style, weight, etc.
      */
-    already_AddRefed<gfxWindowsFont> FindFontForChar(PRUint32 aCh, gfxWindowsFont *aFont);
+    already_AddRefed<gfxFont>
+    gfxWindowsPlatform::FindFontForChar(PRUint32 aCh, gfxFont *aFont);
 
     /* Find a FontFamily/FontEntry object that represents a font on your system given a name */
     FontFamily *FindFontFamily(const nsAString& aName);
     FontEntry *FindFontEntry(const nsAString& aName, const gfxFontStyle& aFontStyle);
 
     PRBool GetPrefFontEntries(const nsCString& aLangGroup, nsTArray<nsRefPtr<FontEntry> > *array);
     void SetPrefFontEntries(const nsCString& aLangGroup, nsTArray<nsRefPtr<FontEntry> >& array);
 
     typedef nsDataHashtable<nsStringHashKey, nsRefPtr<FontFamily> > FontTable;
 
+#ifdef MOZ_FT2_FONTS
+    FT_Library GetFTLibrary();
+private:
+    void AppendFacesFromFontFile(const PRUnichar *aFileName);
+    void FindFonts();
+#endif
+
 private:
     void Init();
 
     void InitBadUnderlineList();
 
     static int CALLBACK FontEnumProc(const ENUMLOGFONTEXW *lpelfe,
                                      const NEWTEXTMETRICEXW *metrics,
                                      DWORD fontType, LPARAM data);
--- a/gfx/thebes/src/Makefile.in
+++ b/gfx/thebes/src/Makefile.in
@@ -47,22 +47,29 @@ EXTRA_DSO_LDOPTS += \
 	$(XPCOM_LIBS) \
 	$(NSPR_LIBS) \
 	$(ZLIB_LIBS) \
 	$(LCMS_LIBS) \
 	$(NULL)
 
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
-CPPSRCS	+= 	gfxWindowsFonts.cpp \
-		gfxWindowsPlatform.cpp \
+CPPSRCS	+= 	gfxWindowsPlatform.cpp \
 		gfxWindowsSurface.cpp \
 		gfxWindowsNativeDrawing.cpp \
 		nsUnicodeRange.cpp \
 		$(NULL)
+
+ifdef WINCE
+DEFINES += -DMOZ_FT2_FONTS
+CPPSRCS	+= gfxFT2Fonts.cpp
+else
+CPPSRCS	+= gfxWindowsFonts.cpp 
+endif
+
 CPPSRCS +=	gfxPDFSurface.cpp
 
 _OS_LIBS	= usp10 msimg32
 ifdef GNU_CXX
 _OS_LIBS	+= uuid
 endif
 OS_LIBS		+= $(call EXPAND_LIBNAME,$(_OS_LIBS))
 
@@ -153,20 +160,25 @@ EXTRA_DSO_LDOPTS += -framework OpenGL -f
 endif
 
 EXTRA_DSO_LDOPTS += $(TK_LIBS)
 
 DEFINES += -DIMPL_THEBES
 
 include $(topsrcdir)/config/rules.mk
 
-
 CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(TK_CFLAGS)
 CFLAGS += $(MOZ_CAIRO_CFLAGS) $(TK_CFLAGS)
 
+ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
+ifdef WINCE
+CXXFLAGS += $(CAIRO_FT_CFLAGS)
+endif
+endif
+
 ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
 CXXFLAGS += $(MOZ_PANGO_CFLAGS)
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),beos)
 CXXFLAGS += $(CAIRO_FT_CFLAGS)
 endif
 
--- a/gfx/thebes/src/gfxFT2Fonts.cpp
+++ b/gfx/thebes/src/gfxFT2Fonts.cpp
@@ -36,16 +36,22 @@
 
 #if defined(MOZ_WIDGET_GTK2)
 #include "gfxPlatformGtk.h"
 #define gfxToolkitPlatform gfxPlatformGtk
 #elif defined(MOZ_WIDGET_QT)
 #include "gfxQtPlatform.h"
 #include <qfontinfo.h>
 #define gfxToolkitPlatform gfxQtPlatform
+#elif defined(XP_WIN)
+#ifdef WINCE
+#define SHGetSpecialFolderPathW SHGetSpecialFolderPath
+#endif
+#include "gfxWindowsPlatform.h"
+#define gfxToolkitPlatform gfxWindowsPlatform
 #endif
 #include "gfxTypes.h"
 #include "gfxFT2Fonts.h"
 #include <locale.h>
 #include "cairo-ft.h"
 #include <freetype/tttables.h>
 #include "gfxFontUtils.h"
 #include "nsTArray.h"
@@ -66,23 +72,75 @@ FontEntry::FontEntry(const FontEntry& aF
 FontEntry::~FontEntry()
 {
     if (mFontFace) {
         cairo_font_face_destroy(mFontFace);
         mFontFace = nsnull;
     }
 }
 
+/* static */
+
+FontEntry*  
+FontEntry::CreateFontEntry(const gfxProxyFontEntry &aProxyEntry, 
+                           nsISupports *aLoader, const PRUint8 *aFontData, 
+                           PRUint32 aLength) {
+    if (!gfxFontUtils::ValidateSFNTHeaders(aFontData, aLength))
+        return nsnull;
+    FT_Face face;
+    FT_Error error =
+        FT_New_Memory_Face(gfxToolkitPlatform::GetPlatform()->GetFTLibrary(), 
+                           aFontData, aLength, 0, &face);
+    if (error != FT_Err_Ok)
+        return nsnull;
+    FontEntry* fe = FontEntry::CreateFontEntryFromFace(face);
+    fe->mItalic = aProxyEntry.mItalic;
+    fe->mWeight = aProxyEntry.mWeight;
+    fe->mStretch = aProxyEntry.mStretch;
+    return fe;
+
+}
+
 static void
 FTFontDestroyFunc(void *data)
 {
     FT_Face face = (FT_Face)data;
     FT_Done_Face(face);
 }
 
+/* static */
+FontEntry*  FontEntry::CreateFontEntryFromFace(FT_Face aFace) {
+    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->mFontFace = cairo_ft_font_face_create_for_ft_face(aFace, 0);
+    cairo_font_face_set_user_data(fe->mFontFace, &key,
+                                  aFace, FTFontDestroyFunc);
+    TT_OS2 *os2 = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(aFace, ft_sfnt_os2));
+    if (os2 && os2->version != 0xffff)
+        fe->mWeight  = os2->usWeightClass;
+    else if (aFace->style_flags & FT_STYLE_FLAG_BOLD)
+        fe->mWeight = 700;
+    else
+        fe->mWeight = 400;
+    return fe;
+}
+
 FontEntry*
 gfxFT2Font::GetFontEntry()
 {
     return static_cast<FontEntry*> (mFontEntry.get());
 }
 
 cairo_font_face_t *
 FontEntry::CairoFontFace()
@@ -96,84 +154,44 @@ FontEntry::CairoFontFace()
         cairo_font_face_set_user_data(mFontFace, &key, face, FTFontDestroyFunc);
     }
     return mFontFace;
 }
 
 FontEntry *
 FontFamily::FindFontEntry(const gfxFontStyle& aFontStyle)
 {
-    PRBool italic = (aFontStyle.style & (FONT_STYLE_ITALIC | FONT_STYLE_OBLIQUE)) != 0;
+    PRBool needsBold = PR_FALSE;
+    return static_cast<FontEntry*>(FindFontForStyle(aFontStyle, needsBold));
+}
 
-    FontEntry *weightList[10] = { 0 };
+PRBool
+FontFamily::FindWeightsForStyle(gfxFontEntry* aFontsForWeights[], const gfxFontStyle& aFontStyle)
+{
+    PRBool italic = (aFontStyle.style & (FONT_STYLE_ITALIC | FONT_STYLE_OBLIQUE)) != 0;
+    PRBool matchesSomething = PR_FALSE;
+
     for (PRUint32 j = 0; j < 2; j++) {
-        PRBool matchesSomething = PR_FALSE;
         // build up an array of weights that match the italicness we're looking for
         for (PRUint32 i = 0; i < mFaces.Length(); i++) {
             FontEntry *fe = mFaces[i];
             const PRUint8 weight = (fe->mWeight / 100);
             if (fe->mItalic == italic) {
-                weightList[weight] = fe;
+                aFontsForWeights[weight] = fe;
                 matchesSomething = PR_TRUE;
             }
         }
         if (matchesSomething)
             break;
         italic = !italic;
     }
 
-    PRInt8 baseWeight, weightDistance;
-    aFontStyle.ComputeWeightAndOffset(&baseWeight, &weightDistance);
-
-    // 500 isn't quite bold so we want to treat it as 400 if we don't
-    // have a 500 weight
-    if (baseWeight == 5 && weightDistance == 0) {
-        // If we have a 500 weight then use it
-        if (weightList[5])
-            return weightList[5];
-
-        // Otherwise treat as 400
-        baseWeight = 4;
-    }
-
-    PRInt8 matchBaseWeight = 0;
-    PRInt8 direction = (baseWeight > 5) ? 1 : -1;
-    for (PRInt8 i = baseWeight; ; i += direction) {
-        if (weightList[i]) {
-            matchBaseWeight = i;
-            break;
-        }
-
-        // if we've reached one side without finding a font,
-        // go the other direction until we find a match
-        if (i == 1 || i == 9)
-            direction = -direction;
-    }
-
-    FontEntry *matchFE;
-    const PRInt8 absDistance = abs(weightDistance);
-    direction = (weightDistance >= 0) ? 1 : -1;
-    for (PRInt8 i = matchBaseWeight, k = 0; i < 10 && i > 0; i += direction) {
-        if (weightList[i]) {
-            matchFE = weightList[i];
-            k++;
-        }
-        if (k > absDistance)
-            break;
-    }
-
-    if (!matchFE)
-        matchFE = weightList[matchBaseWeight];
-
-    NS_ASSERTION(matchFE, "we should always be able to return something here");
-    return matchFE;
+    return matchesSomething;
 }
 
-
-
 /**
  * gfxFT2FontGroup
  */
 
 PRBool
 gfxFT2FontGroup::FontCallback(const nsAString& fontName,
                              const nsACString& genericName,
                              void *closure)
@@ -185,43 +203,16 @@ gfxFT2FontGroup::FontCallback(const nsAS
 #ifdef DEBUG_pavlov
         printf(" - %s\n", NS_ConvertUTF16toUTF8(fontName).get());
 #endif
     }
 
     return PR_TRUE;
 }
 
-/**
- * Look up the font in the gfxFont cache. If we don't find it, create one.
- * 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.
- */
-static already_AddRefed<gfxFT2Font>
-GetOrMakeFont(const nsAString& aName, const gfxFontStyle *aStyle)
-{
-    nsRefPtr<gfxFont> font = gfxFontCache::GetCache()->Lookup(aName, aStyle);
-    if (!font) {
-        FontEntry *fe = gfxToolkitPlatform::GetPlatform()->FindFontEntry(aName, *aStyle);
-        if (!fe) {
-            printf("Failed to find font entry for %s\n", NS_ConvertUTF16toUTF8(aName).get());
-            return nsnull;
-        }
-
-        font = new gfxFT2Font(fe, aStyle);
-        if (!font)
-            return nsnull;
-        gfxFontCache::GetCache()->AddNew(font);
-    }
-    gfxFont *f = nsnull;
-    font.swap(f);
-    return static_cast<gfxFT2Font *>(f);
-}
-
-
 gfxFT2FontGroup::gfxFT2FontGroup(const nsAString& families,
                                const gfxFontStyle *aStyle)
     : gfxFontGroup(families, aStyle)
 {
 #ifdef DEBUG_pavlov
     printf("Looking for %s\n", NS_ConvertUTF16toUTF8(families).get());
 #endif
     nsTArray<nsString> familyArray;
@@ -229,32 +220,49 @@ gfxFT2FontGroup::gfxFT2FontGroup(const n
 
     if (familyArray.Length() == 0) {
         nsAutoString prefFamilies;
         gfxToolkitPlatform::GetPlatform()->GetPrefFonts(aStyle->langGroup.get(), prefFamilies, nsnull);
         if (!prefFamilies.IsEmpty()) {
             ForEachFont(prefFamilies, aStyle->langGroup, FontCallback, &familyArray);
         }
     }
+    if (familyArray.Length() == 0) {
 #if defined(MOZ_WIDGET_QT) /* FIXME DFB */
-    if (familyArray.Length() == 0) {
         printf("failde to find a font. sadface\n");
         // We want to get rid of this entirely at some point, but first we need real lists of fonts.
         QFont defaultFont;
         QFontInfo fi (defaultFont);
         familyArray.AppendElement(nsDependentString(static_cast<const PRUnichar *>(fi.family().utf16())));
+#elif defined(MOZ_WIDGET_GTK2)
+        FcResult result;
+        FcChar8 *family = nsnull;
+        FcPattern* pat = FcPatternCreate();
+        FcPattern *match = FcFontMatch(nsnull, pat, &result);
+        if (match)
+            FcPatternGetString(match, FC_FAMILY, 0, &family);
+        if (family)
+            familyArray.AppendString(NS_ConvertUTF8toUTF16((char*)family));
+#elif defined(XP_WIN)
+        HGDIOBJ hGDI = ::GetStockObject(SYSTEM_FONT);
+        LOGFONTW logFont;
+        if (hGDI && ::GetObjectW(hGDI, sizeof(logFont), &logFont)) 
+            familyArray.AppendElement(nsDependentString(logFont.lfFaceName));
+#else
+#error "Platform not supported"
+#endif
     }
-#endif
 
     for (PRUint32 i = 0; i < familyArray.Length(); i++) {
-        nsRefPtr<gfxFT2Font> font = GetOrMakeFont(familyArray[i], &mStyle);
+        nsRefPtr<gfxFT2Font> font = gfxFT2Font::GetOrMakeFont(familyArray[i], &mStyle);
         if (font) {
             mFonts.AppendElement(font);
         }
     }
+    NS_ASSERTION(mFonts.Length() > 0, "We need at least one font in a fontgroup");
 }
 
 gfxFT2FontGroup::~gfxFT2FontGroup()
 {
 }
 
 gfxFontGroup *
 gfxFT2FontGroup::Copy(const gfxFontStyle *aStyle)
@@ -865,8 +873,35 @@ gfxFT2Font::SetupCairoFont(gfxContext *a
     if (cairo_scaled_font_status(scaledFont) != CAIRO_STATUS_SUCCESS) {
         // Don't cairo_set_scaled_font as that would propagate the error to
         // the cairo_t, precluding any further drawing.
         return PR_FALSE;
     }
     cairo_set_scaled_font(aContext->GetCairo(), scaledFont);
     return PR_TRUE;
 }
+
+/**
+ * Look up the font in the gfxFont cache. If we don't find it, create one.
+ * 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)
+{
+    nsRefPtr<gfxFont> font = gfxFontCache::GetCache()->Lookup(aName, aStyle);
+    if (!font) {
+        FontEntry *fe = gfxToolkitPlatform::GetPlatform()->FindFontEntry(aName, *aStyle);
+        if (!fe) {
+            printf("Failed to find font entry for %s\n", NS_ConvertUTF16toUTF8(aName).get());
+            return nsnull;
+        }
+
+        font = new gfxFT2Font(fe, aStyle);
+        if (!font)
+            return nsnull;
+        gfxFontCache::GetCache()->AddNew(font);
+    }
+    gfxFont *f = nsnull;
+    font.swap(f);
+    return static_cast<gfxFT2Font *>(f);
+}
+
--- a/gfx/thebes/src/gfxWindowsFonts.cpp
+++ b/gfx/thebes/src/gfxWindowsFonts.cpp
@@ -342,16 +342,253 @@ FontFamily::FindWeightsForStyle(gfxFontE
         if (matchesSomething)
             break;
         italic = !italic;
     }
 
     return matchesSomething;
 }
 
+// from t2embapi.h, included in Platform SDK 6.1 but not 6.0
+
+#ifndef __t2embapi__
+
+#define TTLOAD_PRIVATE                  0x00000001
+#define LICENSE_PREVIEWPRINT            0x0004
+#define E_NONE                          0x0000L
+
+typedef unsigned long( WINAPIV *READEMBEDPROC ) ( void*, void*, const unsigned long );
+
+typedef struct
+{
+    unsigned short usStructSize;    // size in bytes of structure client should set to sizeof(TTLOADINFO)
+    unsigned short usRefStrSize;    // size in wide characters of pusRefStr including NULL terminator
+    unsigned short *pusRefStr;      // reference or actual string.
+}TTLOADINFO;
+
+LONG WINAPI TTLoadEmbeddedFont
+(
+    HANDLE*  phFontReference,           // on completion, contains handle to identify embedded font installed
+                                        // on system
+    ULONG    ulFlags,                   // flags specifying the request 
+    ULONG*   pulPrivStatus,             // on completion, contains the embedding status
+    ULONG    ulPrivs,                   // allows for the reduction of licensing privileges
+    ULONG*   pulStatus,                 // on completion, may contain status flags for request 
+    READEMBEDPROC lpfnReadFromStream,   // callback function for doc/disk reads
+    LPVOID   lpvReadStream,             // the input stream tokin
+    LPWSTR   szWinFamilyName,           // the new 16 bit windows family name can be NULL
+    LPSTR    szMacFamilyName,           // the new 8 bit mac family name can be NULL
+    TTLOADINFO* pTTLoadInfo             // optional security
+);
+
+#endif // __t2embapi__
+
+typedef LONG( WINAPI *TTLoadEmbeddedFontProc ) (HANDLE* phFontReference, ULONG ulFlags, ULONG* pulPrivStatus, ULONG ulPrivs, ULONG* pulStatus, 
+                                             READEMBEDPROC lpfnReadFromStream, LPVOID lpvReadStream, LPWSTR szWinFamilyName, 
+                                             LPSTR szMacFamilyName, TTLOADINFO* pTTLoadInfo);
+
+typedef LONG( WINAPI *TTDeleteEmbeddedFontProc ) (HANDLE hFontReference, ULONG ulFlags, ULONG* pulStatus);
+
+
+static TTLoadEmbeddedFontProc TTLoadEmbeddedFontPtr = nsnull;
+static TTDeleteEmbeddedFontProc TTDeleteEmbeddedFontPtr = nsnull;
+
+void FontEntry::InitializeFontEmbeddingProcs()
+{
+    HMODULE fontlib = LoadLibraryW(L"t2embed.dll");
+    if (!fontlib)
+        return;
+    TTLoadEmbeddedFontPtr = (TTLoadEmbeddedFontProc) GetProcAddress(fontlib, "TTLoadEmbeddedFont");
+    TTDeleteEmbeddedFontPtr = (TTDeleteEmbeddedFontProc) GetProcAddress(fontlib, "TTDeleteEmbeddedFont");
+}
+
+class WinUserFontData : public gfxUserFontData {
+public:
+    WinUserFontData(HANDLE aFontRef, PRBool aIsCFF)
+        : mFontRef(aFontRef), mIsCFF(aIsCFF)
+    { }
+
+    virtual ~WinUserFontData()
+    {
+        if (mIsCFF) {
+            RemoveFontMemResourceEx(mFontRef);
+        } else {
+            ULONG pulStatus;
+            TTDeleteEmbeddedFontPtr(mFontRef, 0, &pulStatus);
+        }
+    }
+    
+    HANDLE mFontRef;
+    PRPackedBool mIsCFF;
+};
+
+// used to control stream read by Windows TTLoadEmbeddedFont API
+
+class EOTFontStreamReader {
+public:
+    EOTFontStreamReader(const PRUint8 *aFontData, PRUint32 aLength, PRUint8 *aEOTHeader, 
+                        PRUint32 aEOTHeaderLen)
+        : mInHeader(PR_TRUE), mHeaderOffset(0), mEOTHeader(aEOTHeader), 
+          mEOTHeaderLen(aEOTHeaderLen), mFontData(aFontData), mFontDataLen(aLength),
+          mFontDataOffset(0)
+    {
+    
+    }
+
+    ~EOTFontStreamReader() 
+    { 
+
+    }
+
+    PRPackedBool            mInHeader;
+    PRUint32                mHeaderOffset;
+    PRUint8                 *mEOTHeader;
+    PRUint32                mEOTHeaderLen;
+    const PRUint8           *mFontData;
+    PRUint32                mFontDataLen;
+    PRUint32                mFontDataOffset;
+
+    unsigned long Read(void *outBuffer, const unsigned long aBytesToRead)
+    {
+        PRUint32 bytesLeft = aBytesToRead;
+        PRUint8 *out = static_cast<PRUint8*> (outBuffer);
+
+        // read from EOT header
+        if (mInHeader) {
+            PRUint32 toCopy = PR_MIN(aBytesToRead, mEOTHeaderLen - mHeaderOffset);
+            memcpy(out, mEOTHeader + mHeaderOffset, toCopy);
+            bytesLeft -= toCopy;
+            mHeaderOffset += toCopy;
+            out += toCopy;
+            if (mHeaderOffset == mEOTHeaderLen)
+                mInHeader = PR_FALSE;
+        }
+
+        if (bytesLeft) {
+            PRInt32 bytesRead = PR_MIN(bytesLeft, mFontDataLen - mFontDataOffset);
+            memcpy(out, mFontData, bytesRead);
+            mFontData += bytesRead;
+            mFontDataOffset += bytesRead;
+            if (bytesRead > 0)
+                bytesLeft -= bytesRead;
+        }
+
+        return aBytesToRead - bytesLeft;
+    }
+
+    static unsigned long ReadEOTStream(void *aReadStream, void *outBuffer, 
+                                       const unsigned long aBytesToRead) 
+    {
+        EOTFontStreamReader *eotReader = 
+                               static_cast<EOTFontStreamReader*> (aReadStream);
+        return eotReader->Read(outBuffer, aBytesToRead);
+    }        
+        
+};
+
+static void MakeUniqueFontName(nsAString& aName)
+{
+    char buf[50];
+
+    static PRUint32 fontCount = 0;
+    ++fontCount;
+
+    sprintf(buf, "mozfont%8.8x%8.8x", ::GetTickCount(), fontCount);  // slightly retarded, figure something better later...
+    aName.AssignASCII(buf);
+}
+
+/* static */
+FontEntry* 
+FontEntry::CreateFontEntry(const gfxProxyFontEntry &aProxyEntry, nsISupports *aLoader,
+             const PRUint8 *aFontData, PRUint32 aLength) {
+    // if calls aren't available, bail
+    if (!TTLoadEmbeddedFontPtr || !TTDeleteEmbeddedFontPtr)
+        return nsnull;
+
+    PRBool isCFF;
+    if (!gfxFontUtils::ValidateSFNTHeaders(aFontData, aLength, &isCFF))
+        return nsnull;
+        
+    nsresult rv;
+    HANDLE fontRef;
+
+    nsAutoString uniqueName;
+    MakeUniqueFontName(uniqueName);
+
+    if (isCFF) {
+        // Postscript-style glyphs, swizzle name table, load directly
+        nsTArray<PRUint8> newFontData;
+
+        rv = gfxFontUtils::RenameFont(uniqueName, aFontData, aLength, &newFontData);
+
+        if (NS_FAILED(rv))
+            return nsnull;
+        
+        DWORD numFonts = 0;
+
+        PRUint8 *fontData = reinterpret_cast<PRUint8*> (newFontData.Elements());
+        PRUint32 fontLength = newFontData.Length();
+        NS_ASSERTION(fontData, "null font data after renaming");
+
+        // http://msdn.microsoft.com/en-us/library/ms533942(VS.85).aspx
+        // "A font that is added by AddFontMemResourceEx is always private 
+        //  to the process that made the call and is not enumerable."
+        fontRef = AddFontMemResourceEx(fontData, fontLength, 
+                                       0 /* reserved */, &numFonts);
+        if (!fontRef)
+            return nsnull;
+
+        // only load fonts with a single face contained in the data
+        if (fontRef && numFonts != 1) {
+            RemoveFontMemResourceEx(fontRef);
+            return nsnull;
+        }
+    } else {
+        // TrueType-style glyphs, use EOT library
+        nsAutoTArray<PRUint8,2048> eotHeader;
+        PRUint8 *buffer;
+        PRUint32 eotlen;
+
+        PRUint32 nameLen = PR_MIN(uniqueName.Length(), LF_FACESIZE - 1);
+        nsPromiseFlatString fontName(Substring(uniqueName, 0, nameLen));
+
+        rv = gfxFontUtils::MakeEOTHeader(aFontData, aLength, &eotHeader);
+        if (NS_FAILED(rv))
+            return nsnull;
+
+        // load in embedded font data
+        eotlen = eotHeader.Length();
+        buffer = reinterpret_cast<PRUint8*> (eotHeader.Elements());
+        
+        PRInt32 ret;
+        ULONG privStatus, pulStatus;
+        EOTFontStreamReader eotReader(aFontData, aLength, buffer, eotlen);
+
+        ret = TTLoadEmbeddedFontPtr(&fontRef, TTLOAD_PRIVATE, &privStatus, 
+                                   LICENSE_PREVIEWPRINT, &pulStatus, 
+                                   EOTFontStreamReader::ReadEOTStream, 
+                                   &eotReader, (PRUnichar*)(fontName.get()), 0, 0);
+        if (ret != E_NONE)
+            return nsnull;
+    }
+
+    // make a new font entry using the unique name
+    WinUserFontData *winUserFontData = new WinUserFontData(fontRef, isCFF);
+    PRUint16 w = (aProxyEntry.mWeight == 0 ? 400 : aProxyEntry.mWeight);
+
+    FontEntry *fe = FontEntry::CreateFontEntry(uniqueName, 
+        gfxWindowsFontType(isCFF ? GFX_FONT_TYPE_PS_OPENTYPE : GFX_FONT_TYPE_TRUETYPE) /*type*/, 
+        PRUint32(aProxyEntry.mItalic ? FONT_STYLE_ITALIC : FONT_STYLE_NORMAL), 
+        w, winUserFontData);
+
+    if (fe && isCFF)
+        fe->mForceGDI = PR_TRUE;
+    return fe;
+}
+
 FontEntry* 
 FontEntry::CreateFontEntry(const nsAString& aName, gfxWindowsFontType aFontType, PRBool aItalic, PRUint16 aWeight, gfxUserFontData* aUserFontData, HDC hdc, LOGFONTW *aLogFont)
 {
     LOGFONTW logFont;
     PRBool needRelease = PR_FALSE;
 
     // jtdfix - need to set charset, unicode ranges, pitch/family
 
@@ -2152,28 +2389,27 @@ gfxWindowsFontGroup::WhichPrefFontSuppor
 
     return nsnull;
 }
 
 
 already_AddRefed<gfxFont> 
 gfxWindowsFontGroup::WhichSystemFontSupportsChar(PRUint32 aCh)
 {
-    nsRefPtr<gfxWindowsFont> selectedFont;
+    nsRefPtr<gfxFont> selectedFont;
 
     // system font lookup
     PR_LOG(gFontLog, PR_LOG_DEBUG, (" - Looking for best match"));
 
     nsRefPtr<gfxWindowsFont> refFont = GetFontAt(0);
     gfxWindowsPlatform *platform = gfxWindowsPlatform::GetPlatform();
     selectedFont = platform->FindFontForChar(aCh, refFont);
 
     if (selectedFont) {
-        nsRefPtr<gfxFont> f = static_cast<gfxFont*>(selectedFont.get());
-        return f.forget();
+        return selectedFont.forget();
     }
 
     return nsnull;
 }
 
 
 void
 gfxWindowsFontGroup::InitTextRunUniscribe(gfxContext *aContext, gfxTextRun *aRun, const PRUnichar *aString,
--- a/gfx/thebes/src/gfxWindowsPlatform.cpp
+++ b/gfx/thebes/src/gfxWindowsPlatform.cpp
@@ -48,24 +48,38 @@
 #include "nsIPref.h"
 #include "nsServiceManagerUtils.h"
 #include "nsTArray.h"
 
 #include "nsIWindowsRegKey.h"
 #include "nsILocalFile.h"
 #include "plbase64.h"
 
+#ifdef MOZ_FT2_FONTS
+#include "ft2build.h"
+#include FT_FREETYPE_H
+#include "gfxFT2Fonts.h"
+#include "cairo-ft.h"
+#else
 #include "gfxWindowsFonts.h"
+#endif
+
+#ifdef WINCE
+#include <shlwapi.h>
+#endif
+
 #include "gfxUserFontSet.h"
 
 #include <string>
 
 #include "lcms.h"
 
-static void InitializeFontEmbeddingProcs();
+#ifdef MOZ_FT2_FONTS
+static FT_Library gPlatformFTLibrary = NULL;
+#endif
 
 // font info loader constants
 static const PRUint32 kDelayBeforeLoadingCmaps = 8 * 1000; // 8secs
 static const PRUint32 kIntervalBetweenLoadingCmaps = 150; // 150ms
 static const PRUint32 kNumFontsPerSlice = 10; // read in info 10 fonts at a time
 
 static __inline void
 BuildKeyNameFromFontName(nsAString &aName)
@@ -88,29 +102,35 @@ gfxWindowsPlatform::PrefChangedCallback(
 gfxWindowsPlatform::gfxWindowsPlatform()
     : mStartIndex(0), mIncrement(kNumFontsPerSlice), mNumFamilies(0)
 {
     mFonts.Init(200);
     mFontAliases.Init(20);
     mFontSubstitutes.Init(50);
     mPrefFonts.Init(10);
 
+#ifdef MOZ_FT2_FONTS
+    FT_Init_FreeType(&gPlatformFTLibrary);
+#else
+    FontEntry::InitializeFontEmbeddingProcs();
+#endif
+
     UpdateFontList();
 
     nsCOMPtr<nsIPref> pref = do_GetService(NS_PREF_CONTRACTID);
     pref->RegisterCallback("font.", PrefChangedCallback, this);
     pref->RegisterCallback("font.name-list.", PrefChangedCallback, this);
     pref->RegisterCallback("intl.accept_languages", PrefChangedCallback, this);
     // don't bother unregistering.  We'll get shutdown after the pref service
-
-    InitializeFontEmbeddingProcs();
 }
 
 gfxWindowsPlatform::~gfxWindowsPlatform()
 {
+    // not calling FT_Done_FreeType because cairo may still hold references to
+    // these FT_Faces.  See bug 458169.
 }
 
 already_AddRefed<gfxASurface>
 gfxWindowsPlatform::CreateOffscreenSurface(const gfxIntSize& size,
                                            gfxASurface::gfxImageFormat imageFormat)
 {
 #ifndef WINCE
     gfxASurface *surf = new gfxWindowsSurface(size, imageFormat);
@@ -171,18 +191,20 @@ gfxWindowsPlatform::HashEnumFunc(nsStrin
     gfxFontStyle style;
     style.langGroup = data->mLangGroup;
     nsRefPtr<FontEntry> aFontEntry = aFontFamily->FindFontEntry(style);
 
     /* skip symbol fonts */
     if (aFontEntry->mSymbolFont)
         return PL_DHASH_NEXT;
 
+#ifndef MOZ_FT2_FONTS
     if (aFontEntry->SupportsLangGroup(data->mLangGroup) &&
         aFontEntry->MatchesGenericFamily(data->mGenericFamily))
+#endif
         data->mStringArray.AppendElement(aFontFamily->mName);
 
     return PL_DHASH_NEXT;
 }
 
 nsresult
 gfxWindowsPlatform::GetFontList(const nsACString& aLangGroup,
                                 const nsACString& aGenericFamily,
@@ -201,40 +223,106 @@ gfxWindowsPlatform::GetFontList(const ns
 static void
 RemoveCharsetFromFontSubstitute(nsAString &aName)
 {
     PRInt32 comma = aName.FindChar(PRUnichar(','));
     if (comma >= 0)
         aName.Truncate(comma);
 }
 
+#ifdef MOZ_FT2_FONTS
+void gfxWindowsPlatform::AppendFacesFromFontFile(const PRUnichar *aFileName) {
+    char fileName[MAX_PATH];
+    WideCharToMultiByte(CP_ACP, 0, aFileName, -1, fileName, MAX_PATH, NULL, NULL);
+    FT_Face dummy;
+    if (FT_Err_Ok == FT_New_Face(GetFTLibrary(), fileName, -1, &dummy)) {
+        for (FT_Long i = 0; i < dummy->num_faces; i++) {
+            FT_Face face;
+            if (FT_Err_Ok != FT_New_Face(GetFTLibrary(), fileName, 
+                                         i, &face))
+                continue;
+
+            FontEntry* fe = FontEntry::CreateFontEntryFromFace(face);
+            if (fe) {
+                NS_ConvertUTF8toUTF16 name(face->family_name);
+                BuildKeyNameFromFontName(name);       
+                nsRefPtr<FontFamily> ff;
+                if (!mFonts.Get(name, &ff)) {
+                    ff = new FontFamily(name);
+                    mFonts.Put(name, ff);
+                }
+                ff->mFaces.AppendElement(fe);
+            }
+        }
+        FT_Done_Face(dummy);
+    }
+}
+
+void
+gfxWindowsPlatform::FindFonts()
+{
+    nsTArray<nsString> searchPaths(2);
+    nsTArray<nsString> fontPatterns(4);
+    fontPatterns.AppendElement(NS_LITERAL_STRING("\\*.TTF"));
+    fontPatterns.AppendElement(NS_LITERAL_STRING("\\*.ttf"));
+    fontPatterns.AppendElement(NS_LITERAL_STRING("\\*.OTF"));
+    fontPatterns.AppendElement(NS_LITERAL_STRING("\\*.otf"));
+    wchar_t pathBuf[256];
+    SHGetSpecialFolderPathW(0, pathBuf, CSIDL_WINDOWS, 0);
+    searchPaths.AppendElement(pathBuf);
+    SHGetSpecialFolderPathW(0, pathBuf, CSIDL_FONTS, 0);
+    searchPaths.AppendElement(pathBuf);
+    WIN32_FIND_DATAW results;
+    for (PRUint32 i = 0;  i < searchPaths.Length(); i++) {
+        const nsString& path(searchPaths[i]);
+        for (PRUint32 j = 0; j < fontPatterns.Length(); j++) { 
+            nsAutoString pattern(path);
+            pattern.Append(fontPatterns[j]);
+            HANDLE handle = FindFirstFileW(pattern.get(), &results);
+            PRBool moreFiles = handle != INVALID_HANDLE_VALUE;
+            while (moreFiles) {
+                nsAutoString filePath(path);
+                filePath.AppendLiteral("\\");
+                filePath.Append(results.cFileName);
+                AppendFacesFromFontFile(static_cast<const PRUnichar*>(filePath.get()));
+                moreFiles = FindNextFile(handle, &results);
+            }
+        }
+    }
+}
+
+#endif
+
+
 nsresult
 gfxWindowsPlatform::UpdateFontList()
 {
     gfxFontCache *fc = gfxFontCache::GetCache();
     if (fc)
         fc->AgeAllGenerations();
     mFonts.Clear();
     mFontAliases.Clear();
     mNonExistingFonts.Clear();
     mFontSubstitutes.Clear();
     mPrefFonts.Clear();
     mCodepointsWithNoFonts.reset();
     CancelLoader();
-    
+#ifdef MOZ_FT2_FONTS
+    FindFonts();
+#else    
     LOGFONTW logFont;
     logFont.lfCharSet = DEFAULT_CHARSET;
     logFont.lfFaceName[0] = 0;
     logFont.lfPitchAndFamily = 0;
 
     // Use the screen DC here.. should we use something else for printing?
     HDC dc = ::GetDC(nsnull);
     EnumFontFamiliesExW(dc, &logFont, (FONTENUMPROCW)gfxWindowsPlatform::FontEnumProc, (LPARAM)&mFonts, 0);
     ::ReleaseDC(nsnull, dc);
-
+#endif
     // initialize the cmap loading process after font list has been initialized
     StartLoader(kDelayBeforeLoadingCmaps, kIntervalBetweenLoadingCmaps); 
 
     // Create the list of FontSubstitutes
     nsCOMPtr<nsIWindowsRegKey> regKey = do_CreateInstance("@mozilla.org/windows-registry-key;1");
     if (!regKey)
         return NS_ERROR_FAILURE;
      NS_NAMED_LITERAL_STRING(kFontSubstitutesKey, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes");
@@ -312,30 +400,33 @@ static PRBool SimpleResolverCallback(con
     nsString *result = static_cast<nsString*>(aClosure);
     result->Assign(aName);
     return PR_FALSE;
 }
 
 void
 gfxWindowsPlatform::InitBadUnderlineList()
 {
+// Only windows fonts have mIsBadUnderlineFontFamily flag
+#ifndef MOZ_FT2_FONTS
     nsAutoTArray<nsString, 10> blacklist;
     gfxFontUtils::GetPrefsFontList("font.blacklist.underline_offset", blacklist);
     PRUint32 numFonts = blacklist.Length();
     for (PRUint32 i = 0; i < numFonts; i++) {
         PRBool aborted;
         nsAutoString resolved;
         ResolveFontName(blacklist[i], SimpleResolverCallback, &resolved, aborted);
         if (resolved.IsEmpty())
             continue;
         FontFamily *ff = FindFontFamily(resolved);
         if (!ff)
             continue;
         ff->mIsBadUnderlineFontFamily = 1;
     }
+#endif
 }
 
 nsresult
 gfxWindowsPlatform::GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName)
 {
     aFamilyName.Truncate();
     PRBool aborted;
     return ResolveFontName(aFontName, SimpleResolverCallback, &aFamilyName, aborted);
@@ -433,55 +524,58 @@ gfxWindowsPlatform::FontResolveProc(cons
     rData->mCaller->mFontAliases.Put(*(rData->mFontName), ff);
 
     return (rData->mCallback)(name, rData->mClosure);
 
     // XXX If the font has font link, we should add the linked font.
 }
 
 struct FontSearch {
-    FontSearch(PRUint32 aCh, gfxWindowsFont *aFont) :
+    FontSearch(PRUint32 aCh, gfxFont *aFont) :
         ch(aCh), fontToMatch(aFont), matchRank(-1) {
     }
     PRUint32 ch;
-    nsRefPtr<gfxWindowsFont> fontToMatch;
+    nsRefPtr<gfxFont> fontToMatch;
     PRInt32 matchRank;
     nsRefPtr<FontEntry> bestMatch;
 };
 
 PLDHashOperator
 gfxWindowsPlatform::FindFontForCharProc(nsStringHashKey::KeyType aKey,
                                         nsRefPtr<FontFamily>& aFontFamily,
                                         void* userArg)
 {
     FontSearch *data = (FontSearch*)userArg;
 
     const PRUint32 ch = data->ch;
 
     nsRefPtr<FontEntry> fe = aFontFamily->FindFontEntry(*data->fontToMatch->GetStyle());
+    PRInt32 rank = 0;
 
+#ifndef MOZ_FT2_FONTS
     // skip over non-unicode and bitmap fonts and fonts that don't have
     // the code point we're looking for
     if (fe->IsCrappyFont() || !fe->mCharacterMap.test(ch))
         return PL_DHASH_NEXT;
 
-    PRInt32 rank = 0;
     // fonts that claim to support the range are more
     // likely to be "better fonts" than ones that don't... (in theory)
     if (fe->SupportsRange(gfxFontUtils::CharRangeBit(ch)))
         rank += 1;
 
     if (fe->SupportsLangGroup(data->fontToMatch->GetStyle()->langGroup))
         rank += 2;
 
-    if (fe->mWindowsFamily == data->fontToMatch->GetFontEntry()->mWindowsFamily)
+    FontEntry* mfe = static_cast<FontEntry*>(data->fontToMatch->GetFontEntry());
+
+    if (fe->mWindowsFamily == mfe->mWindowsFamily)
         rank += 3;
-    if (fe->mWindowsPitch == data->fontToMatch->GetFontEntry()->mWindowsFamily)
+    if (fe->mWindowsPitch == mfe->mWindowsPitch)
         rank += 3;
-
+#endif
     /* italic */
     const PRBool italic = (data->fontToMatch->GetStyle()->style != FONT_STYLE_NORMAL);
     if (fe->mItalic != italic)
         rank += 3;
 
     /* weight */
     PRInt8 baseWeight, weightDistance;
     data->fontToMatch->GetStyle()->ComputeWeightAndOffset(&baseWeight, &weightDistance);
@@ -494,63 +588,77 @@ gfxWindowsPlatform::FindFontForCharProc(
         (rank == data->matchRank && Compare(fe->Name(), data->bestMatch->Name()) > 0)) {
         data->bestMatch = fe;
         data->matchRank = rank;
     }
 
     return PL_DHASH_NEXT;
 }
 
-already_AddRefed<gfxWindowsFont>
-gfxWindowsPlatform::FindFontForChar(PRUint32 aCh, gfxWindowsFont *aFont)
+already_AddRefed<gfxFont>
+gfxWindowsPlatform::FindFontForChar(PRUint32 aCh, gfxFont *aFont)
 {
     // is codepoint with no matching font? return null immediately
     if (mCodepointsWithNoFonts.test(aCh)) {
         return nsnull;
     }
 
     FontSearch data(aCh, aFont);
 
     // find fonts that support the character
     mFonts.Enumerate(gfxWindowsPlatform::FindFontForCharProc, &data);
 
     if (data.bestMatch) {
+#ifdef MOZ_FT2_FONTS
+        nsRefPtr<gfxFT2Font> font =
+            gfxFT2Font::GetOrMakeFont(data.bestMatch->mName, 
+                                      aFont->GetStyle()); 
+            gfxFont* ret = font.forget().get();
+            return already_AddRefed<gfxFont>(ret);
+#else
         nsRefPtr<gfxWindowsFont> font =
             gfxWindowsFont::GetOrMakeFont(data.bestMatch, aFont->GetStyle());
-        if (font->IsValid())
-            return font.forget();
+        if (font->IsValid()) {
+            gfxFont* ret = font.forget().get();
+            return already_AddRefed<gfxFont>(ret);
+        }
+#endif
         return nsnull;
     }
-
     // no match? add to set of non-matching codepoints
     mCodepointsWithNoFonts.set(aCh);
     return nsnull;
 }
 
 gfxFontGroup *
 gfxWindowsPlatform::CreateFontGroup(const nsAString &aFamilies,
                                     const gfxFontStyle *aStyle,
                                     gfxUserFontSet *aUserFontSet)
 {
+#ifdef MOZ_FT2_FONTS
+    return new gfxFT2FontGroup(aFamilies, aStyle);
+#else
     return new gfxWindowsFontGroup(aFamilies, aStyle, aUserFontSet);
+#endif
 }
 
 
 struct FullFontNameSearch {
     FullFontNameSearch(const nsAString& aFullName)
         : mFound(PR_FALSE), mFullName(aFullName), mDC(nsnull), mFontEntry(nsnull)
     { }
 
     PRPackedBool mFound;
     nsString     mFullName;
     nsString     mFamilyName;
     HDC          mDC;
     gfxFontEntry *mFontEntry;
 };
 
+#ifndef MOZ_FT2_FONTS
 // callback called for each face within a single family
 // match against elfFullName
 
 static int CALLBACK 
 FindFullNameForFace(const ENUMLOGFONTEXW *lpelfe,
                     const NEWTEXTMETRICEXW *nmetrics,
                     DWORD fontType, LPARAM userArg)
 {
@@ -567,20 +675,20 @@ FindFullNameForFace(const ENUMLOGFONTEXW
     LOGFONTW logFont = lpelfe->elfLogFont;
 
     // Some fonts claim to support things > 900, but we don't so clamp the sizes
     logFont.lfWeight = PR_MAX(PR_MIN(logFont.lfWeight, 900), 100);
 
     gfxWindowsFontType feType = FontEntry::DetermineFontType(metrics, fontType);
 
     data->mFontEntry = FontEntry::CreateFontEntry(data->mFamilyName, feType, (logFont.lfItalic == 0xFF), (PRUint16) (logFont.lfWeight), nsnull, data->mDC, &logFont);
-    
+
     return 0;  // stop iteration
 }
-
+#endif
 
 // callback called for each family name, based on the assumption that the 
 // first part of the full name is the family name
 
 static PLDHashOperator
 FindFullName(nsStringHashKey::KeyType aKey,
              nsRefPtr<FontFamily>& aFontFamily,
              void* userArg)
@@ -590,16 +698,26 @@ FindFullName(nsStringHashKey::KeyType aK
     // does the family name match up to the length of the family name?
     const nsString& family = aFontFamily->Name();
     
     nsString fullNameFamily;
     data->mFullName.Left(fullNameFamily, family.Length());
 
     // if so, iterate over faces in this family to see if there is a match
     if (family.Equals(fullNameFamily)) {
+#ifdef MOZ_FT2_FONTS
+        int len = aFontFamily->mFaces.Length();
+        int index = 0;
+        for (; index < len && 
+                 !aFontFamily->mFaces[index]->Name().Equals(data->mFullName); index++);
+        if (index < len) {
+            data->mFound = PR_TRUE;
+            data->mFontEntry = aFontFamily->mFaces[index];
+        }
+#else
         HDC hdc;
         
         if (!data->mDC) {
             data->mDC= GetDC(nsnull);
             SetGraphicsMode(data->mDC, GM_ADVANCED);
         }
         hdc = data->mDC;
 
@@ -610,16 +728,17 @@ FindFullName(nsStringHashKey::KeyType aK
         PRUint32 l = PR_MIN(family.Length(), LF_FACESIZE - 1);
         memcpy(logFont.lfFaceName,
                nsPromiseFlatString(family).get(),
                l * sizeof(PRUnichar));
         logFont.lfFaceName[l] = 0;
         data->mFamilyName.Assign(family);
 
         EnumFontFamiliesExW(hdc, &logFont, (FONTENUMPROCW)FindFullNameForFace, (LPARAM)data, 0);
+#endif
     }
 
     if (data->mFound)
         return PL_DHASH_STOP;
 
     return PL_DHASH_NEXT;
 }
 
@@ -634,256 +753,23 @@ gfxWindowsPlatform::LookupLocalFont(cons
     mFonts.Enumerate(FindFullName, &data);
 
     if (data.mDC)
         ReleaseDC(nsnull, data.mDC);
     
     return data.mFontEntry;
 }
 
-static void MakeUniqueFontName(nsAString& aName)
-{
-    char buf[50];
-
-    static PRUint32 fontCount = 0;
-    ++fontCount;
-
-    sprintf(buf, "mozfont%8.8x%8.8x", ::GetTickCount(), fontCount);  // slightly retarded, figure something better later...
-    aName.AssignASCII(buf);
-}
-
-// from t2embapi.h, included in Platform SDK 6.1 but not 6.0
-
-#ifndef __t2embapi__
-
-#define TTLOAD_PRIVATE                  0x00000001
-#define LICENSE_PREVIEWPRINT            0x0004
-#define E_NONE                          0x0000L
-
-typedef unsigned long( WINAPIV *READEMBEDPROC ) ( void*, void*, const unsigned long );
-
-typedef struct
-{
-    unsigned short usStructSize;    // size in bytes of structure client should set to sizeof(TTLOADINFO)
-    unsigned short usRefStrSize;    // size in wide characters of pusRefStr including NULL terminator
-    unsigned short *pusRefStr;      // reference or actual string.
-}TTLOADINFO;
-
-LONG WINAPI TTLoadEmbeddedFont
-(
-    HANDLE*  phFontReference,           // on completion, contains handle to identify embedded font installed
-                                        // on system
-    ULONG    ulFlags,                   // flags specifying the request 
-    ULONG*   pulPrivStatus,             // on completion, contains the embedding status
-    ULONG    ulPrivs,                   // allows for the reduction of licensing privileges
-    ULONG*   pulStatus,                 // on completion, may contain status flags for request 
-    READEMBEDPROC lpfnReadFromStream,   // callback function for doc/disk reads
-    LPVOID   lpvReadStream,             // the input stream tokin
-    LPWSTR   szWinFamilyName,           // the new 16 bit windows family name can be NULL
-    LPSTR    szMacFamilyName,           // the new 8 bit mac family name can be NULL
-    TTLOADINFO* pTTLoadInfo             // optional security
-);
-
-#endif // __t2embapi__
-
-typedef LONG( WINAPI *TTLoadEmbeddedFontProc ) (HANDLE* phFontReference, ULONG ulFlags, ULONG* pulPrivStatus, ULONG ulPrivs, ULONG* pulStatus, 
-                                             READEMBEDPROC lpfnReadFromStream, LPVOID lpvReadStream, LPWSTR szWinFamilyName, 
-                                             LPSTR szMacFamilyName, TTLOADINFO* pTTLoadInfo);
-
-typedef LONG( WINAPI *TTDeleteEmbeddedFontProc ) (HANDLE hFontReference, ULONG ulFlags, ULONG* pulStatus);
-
-
-static TTLoadEmbeddedFontProc TTLoadEmbeddedFontPtr = nsnull;
-static TTDeleteEmbeddedFontProc TTDeleteEmbeddedFontPtr = nsnull;
-
-static void InitializeFontEmbeddingProcs()
-{
-    HMODULE fontlib = LoadLibraryW(L"t2embed.dll");
-    if (!fontlib)
-        return;
-    TTLoadEmbeddedFontPtr = (TTLoadEmbeddedFontProc) GetProcAddress(fontlib, "TTLoadEmbeddedFont");
-    TTDeleteEmbeddedFontPtr = (TTDeleteEmbeddedFontProc) GetProcAddress(fontlib, "TTDeleteEmbeddedFont");
-}
-
-class WinUserFontData : public gfxUserFontData {
-public:
-    WinUserFontData(HANDLE aFontRef, PRBool aIsCFF)
-        : mFontRef(aFontRef), mIsCFF(aIsCFF)
-    { }
-
-    virtual ~WinUserFontData()
-    {
-        if (mIsCFF) {
-            RemoveFontMemResourceEx(mFontRef);
-        } else {
-            ULONG pulStatus;
-            TTDeleteEmbeddedFontPtr(mFontRef, 0, &pulStatus);
-        }
-    }
-    
-    HANDLE mFontRef;
-    PRPackedBool mIsCFF;
-};
-
-// used to control stream read by Windows TTLoadEmbeddedFont API
-
-class EOTFontStreamReader {
-public:
-    EOTFontStreamReader(const PRUint8 *aFontData, PRUint32 aLength, PRUint8 *aEOTHeader, 
-                        PRUint32 aEOTHeaderLen)
-        : mInHeader(PR_TRUE), mHeaderOffset(0), mEOTHeader(aEOTHeader), 
-          mEOTHeaderLen(aEOTHeaderLen), mFontData(aFontData), mFontDataLen(aLength),
-          mFontDataOffset(0)
-    {
-    
-    }
-
-    ~EOTFontStreamReader() 
-    { 
-
-    }
-
-    PRPackedBool            mInHeader;
-    PRUint32                mHeaderOffset;
-    PRUint8                 *mEOTHeader;
-    PRUint32                mEOTHeaderLen;
-    const PRUint8           *mFontData;
-    PRUint32                mFontDataLen;
-    PRUint32                mFontDataOffset;
-
-    unsigned long Read(void *outBuffer, const unsigned long aBytesToRead)
-    {
-        PRUint32 bytesLeft = aBytesToRead;
-        PRUint8 *out = static_cast<PRUint8*> (outBuffer);
-
-        // read from EOT header
-        if (mInHeader) {
-            PRUint32 toCopy = PR_MIN(aBytesToRead, mEOTHeaderLen - mHeaderOffset);
-            memcpy(out, mEOTHeader + mHeaderOffset, toCopy);
-            bytesLeft -= toCopy;
-            mHeaderOffset += toCopy;
-            out += toCopy;
-            if (mHeaderOffset == mEOTHeaderLen)
-                mInHeader = PR_FALSE;
-        }
-
-        if (bytesLeft) {
-            PRInt32 bytesRead = PR_MIN(bytesLeft, mFontDataLen - mFontDataOffset);
-            memcpy(out, mFontData, bytesRead);
-            mFontData += bytesRead;
-            mFontDataOffset += bytesRead;
-            if (bytesRead > 0)
-                bytesLeft -= bytesRead;
-        }
-
-        return aBytesToRead - bytesLeft;
-    }
-
-    static unsigned long ReadEOTStream(void *aReadStream, void *outBuffer, 
-                                       const unsigned long aBytesToRead) 
-    {
-        EOTFontStreamReader *eotReader = 
-                               static_cast<EOTFontStreamReader*> (aReadStream);
-        return eotReader->Read(outBuffer, aBytesToRead);
-    }        
-        
-};
-
 gfxFontEntry* 
 gfxWindowsPlatform::MakePlatformFont(const gfxProxyFontEntry *aProxyEntry,
                                      nsISupports *aLoader,
                                      const PRUint8 *aFontData, PRUint32 aLength)
 {
-    // if calls aren't available, bail
-    if (!TTLoadEmbeddedFontPtr || !TTDeleteEmbeddedFontPtr)
-        return nsnull;
-
-    PRBool isCFF;
-    if (!gfxFontUtils::ValidateSFNTHeaders(aFontData, aLength, &isCFF))
-        return nsnull;
-        
-    nsresult rv;
-    HANDLE fontRef;
-
-    nsAutoString uniqueName;
-    MakeUniqueFontName(uniqueName);
-
-    if (isCFF) {
-        // Postscript-style glyphs, swizzle name table, load directly
-        nsTArray<PRUint8> newFontData;
-
-        rv = gfxFontUtils::RenameFont(uniqueName, aFontData, aLength, &newFontData);
-
-        if (NS_FAILED(rv))
-            return nsnull;
-        
-        DWORD numFonts = 0;
-
-        PRUint8 *fontData = reinterpret_cast<PRUint8*> (newFontData.Elements());
-        PRUint32 fontLength = newFontData.Length();
-        NS_ASSERTION(fontData, "null font data after renaming");
-
-        // http://msdn.microsoft.com/en-us/library/ms533942(VS.85).aspx
-        // "A font that is added by AddFontMemResourceEx is always private 
-        //  to the process that made the call and is not enumerable."
-        fontRef = AddFontMemResourceEx(fontData, fontLength, 
-                                       0 /* reserved */, &numFonts);
-
-        if (!fontRef)
-            return nsnull;
-
-        // only load fonts with a single face contained in the data
-        if (fontRef && numFonts != 1) {
-            RemoveFontMemResourceEx(fontRef);
-            return nsnull;
-        }
-    } else {
-        // TrueType-style glyphs, use EOT library
-        nsAutoTArray<PRUint8,2048> eotHeader;
-        PRUint8 *buffer;
-        PRUint32 eotlen;
-
-        PRUint32 nameLen = PR_MIN(uniqueName.Length(), LF_FACESIZE - 1);
-        nsPromiseFlatString fontName(Substring(uniqueName, 0, nameLen));
-
-
-        rv = gfxFontUtils::MakeEOTHeader(aFontData, aLength, &eotHeader);
-        if (NS_FAILED(rv))
-            return nsnull;
-
-        // load in embedded font data
-        eotlen = eotHeader.Length();
-        buffer = reinterpret_cast<PRUint8*> (eotHeader.Elements());
-        
-        PRInt32 ret;
-        ULONG privStatus, pulStatus;
-        EOTFontStreamReader eotReader(aFontData, aLength, buffer, eotlen);
-
-        ret = TTLoadEmbeddedFontPtr(&fontRef, TTLOAD_PRIVATE, &privStatus, 
-                                   LICENSE_PREVIEWPRINT, &pulStatus, 
-                                   EOTFontStreamReader::ReadEOTStream, 
-                                   &eotReader, (PRUnichar*)(fontName.get()), 0, 0);
-        if (ret != E_NONE)
-            return nsnull;
-    }
-
-    
-    // make a new font entry using the unique name
-    WinUserFontData *winUserFontData = new WinUserFontData(fontRef, isCFF);
-    PRUint16 w = (aProxyEntry->mWeight == 0 ? 400 : aProxyEntry->mWeight);
-
-    FontEntry *fe = FontEntry::CreateFontEntry(uniqueName, 
-        gfxWindowsFontType(isCFF ? GFX_FONT_TYPE_PS_OPENTYPE : GFX_FONT_TYPE_TRUETYPE) /*type*/, 
-        PRUint32(aProxyEntry->mItalic ? FONT_STYLE_ITALIC : FONT_STYLE_NORMAL), 
-        w, winUserFontData);
-
-    if (fe && isCFF)
-        fe->mForceGDI = PR_TRUE;
-
-    return fe;
+    return FontEntry::CreateFontEntry(*aProxyEntry, aLoader,
+                                      aFontData, aLength);
 }
 
 PRBool
 gfxWindowsPlatform::IsFontFormatSupported(nsIURI *aFontURI, PRUint32 aFormatFlags)
 {
     // check for strange format flags
     NS_ASSERTION(!(aFormatFlags & gfxUserFontSet::FLAG_FORMAT_NOT_USED),
                  "strange font format hint set");
@@ -926,17 +812,17 @@ gfxWindowsPlatform::FindFontEntry(const 
         return nsnull;
 
     return ff->FindFontEntry(aFontStyle);
 }
 
 cmsHPROFILE
 gfxWindowsPlatform::GetPlatformCMSOutputProfile()
 {
-#ifndef WINCE
+#ifndef MOZ_FT2_FONTS
     WCHAR str[1024+1];
     DWORD size = 1024;
 
     HDC dc = GetDC(nsnull);
     GetICMProfileW(dc, &size, (LPWSTR)&str);
     ReleaseDC(nsnull, dc);
 
     cmsHPROFILE profile =
@@ -973,27 +859,35 @@ gfxWindowsPlatform::InitLoader()
     mNumFamilies = mFontFamilies.Length();
 }
 
 PRBool 
 gfxWindowsPlatform::RunLoader()
 {
     PRUint32 i, endIndex = ( mStartIndex + mIncrement < mNumFamilies ? mStartIndex + mIncrement : mNumFamilies );
 
+#ifndef MOZ_FT2_FONTS
     // for each font family, load in various font info
     for (i = mStartIndex; i < endIndex; i++) {
         // load the cmaps for all variations
         mFontFamilies[i]->FindStyleVariations();
     }
-
+#endif
     mStartIndex += mIncrement;
     if (mStartIndex < mNumFamilies)
         return PR_FALSE;
     return PR_TRUE;
 }
 
 void 
 gfxWindowsPlatform::FinishLoader()
 {
     mFontFamilies.Clear();
     mNumFamilies = 0;
 }
 
+#ifdef MOZ_FT2_FONTS
+FT_Library
+gfxWindowsPlatform::GetFTLibrary()
+{
+    return gPlatformFTLibrary;
+}
+#endif
--- a/toolkit/library/Makefile.in
+++ b/toolkit/library/Makefile.in
@@ -232,16 +232,20 @@ EXTRA_DSO_LDOPTS += $(XLDFLAGS) $(XLIBS)
 EXTRA_DSO_LDOPTS += $(FT2_LIBS)
 endif
 
 ifeq (qt,$(MOZ_WIDGET_TOOLKIT))
 EXTRA_DSO_LDOPTS += $(XLDFLAGS) $(XLIBS) $(XT_LIBS) $(MOZ_QT_LIBS) -lgthread-2.0
 EXTRA_DSO_LDOPTS += $(FT2_LIBS)
 endif
 
+ifdef MOZ_TREE_FREETYPE
+EXTRA_DSO_LDOPTS += $(FT2_LIBS)
+endif
+
 EXTRA_DSO_LDOPTS += $(MOZ_LOCATION_LIBS)
 
 ifdef MOZ_ENABLE_STARTUP_NOTIFICATION
 EXTRA_DSO_LDOPTS += $(MOZ_STARTUP_NOTIFICATION_LIBS)
 endif
 
 ifeq ($(OS_ARCH),BeOS)
 EXTRA_DSO_LDOPTS += -lbe -ltracker