bug 362682. fix missing glyphs on linux. patch by myself and Behdad Esfahbod <mozilla@behdad.org>. r=vlad
authorpavlov@pavlov.net
Wed, 19 Sep 2007 15:18:42 -0700
changeset 6119 9d331dd65db8844cfb2ecf70f8e9b21e7ad76e3a
parent 6118 f70788ac18973b574d71e00bb79d9507d071a73b
child 6120 a25baa6a9e23ecb23734e900f7bfaecce386e55c
push idunknown
push userunknown
push dateunknown
reviewersvlad
bugs362682
milestone1.9a8pre
bug 362682. fix missing glyphs on linux. patch by myself and Behdad Esfahbod <mozilla@behdad.org>. r=vlad
config/system-headers
configure.in
gfx/cairo/cairo/src/cairo-ft-font.c
gfx/thebes/public/gfxPangoFonts.h
gfx/thebes/public/gfxPlatformGtk.h
gfx/thebes/src/cairo-xlib-utils.c
gfx/thebes/src/gfxPangoFonts.cpp
gfx/thebes/src/gfxPlatformGtk.cpp
--- a/config/system-headers
+++ b/config/system-headers
@@ -208,16 +208,17 @@ fribidi/fribidi.h
 FSp_fopen.h
 fstream.h
 ft2build.h
 gconf/gconf-client.h
 Gdiplus.h
 gdk/gdkevents.h
 gdk/gdk.h
 gdk/gdkkeysyms.h
+gdk/gdkpango.h
 gdk/gdkprivate.h
 gdk/gdkregion.h
 gdk/gdkwindow.h
 gdk/gdkx.h
 gdk-pixbuf/gdk-pixbuf.h
 Gestalt.h
 getopt.h
 glibconfig.h
@@ -500,24 +501,26 @@ OS.h
 osreldate.h
 OSUtils.h
 Packages.h
 Palettes.h
 PALM_CMN.H
 pango-engine.h
 pango-glyph.h
 pango-modules.h
+pango/pangocairo.h
 pango/pangofc-decoder.h
 pango/pangofc-font.h
 pango/pangofc-fontmap.h
 pango/pango-break.h
 pango/pango-fontmap.h
 pango/pango.h
 pango/pangoxft.h
 pango/pangox.h
+pango/pango-utils.h
 pango-types.h
 pascal.h
 Patches.h
 Path.h
 pcfs/pc_dir.h
 Pgenerr.h
 PGenErr.h
 Ph.h
--- a/configure.in
+++ b/configure.in
@@ -111,17 +111,18 @@ NSS_VERSION=3
 dnl Set the minimum version of toolkit libs used by mozilla
 dnl ========================================================
 GLIB_VERSION=1.2.0
 LIBIDL_VERSION=0.6.3
 PERL_VERSION=5.006
 LIBART_VERSION=2.3.4
 CAIRO_VERSION=1.4.2
 GLITZ_VERSION=0.4.0
-GTK2_VERSION=1.3.7
+PANGO_VERSION=1.10.0
+GTK2_VERSION=1.8.0
 MAKE_VERSION=3.78
 WINDRES_VERSION=2.14.90
 W32API_VERSION=3.8
 GNOMEVFS_VERSION=2.0
 GNOMEUI_VERSION=2.2.0
 GCONF_VERSION=1.2.1
 LIBGNOME_VERSION=2.0
 STARTUP_NOTIFICATION_VERSION=0.8
@@ -4562,17 +4563,17 @@ esac
 
 if test "$MOZ_ENABLE_XREMOTE"; then
     AC_DEFINE(MOZ_ENABLE_XREMOTE)
 fi
 
 if test "$COMPILE_ENVIRONMENT"; then
 if test "$MOZ_ENABLE_GTK2"
 then
-    PKG_CHECK_MODULES(MOZ_GTK2, gtk+-2.0 >= 1.3.7 gdk-x11-2.0 glib-2.0 gobject-2.0)
+    PKG_CHECK_MODULES(MOZ_GTK2, gtk+-2.0 >= $GTK2_VERSION gdk-x11-2.0 glib-2.0 gobject-2.0)
 fi
 fi # COMPILE_ENVIRONMENT
 
 AC_SUBST(MOZ_DEFAULT_TOOLKIT)
 
 dnl ========================================================
 dnl = startup-notification support module
 dnl ========================================================
@@ -4801,61 +4802,50 @@ fi
 if test "$MOZ_ENABLE_XFT" && test "$MOZ_ENABLE_FREETYPE2"; then
     AC_MSG_ERROR([Cannot enable XFT and FREETYPE2 at the same time.])
 fi
 
 if test "$MOZ_ENABLE_XFT"
 then
     AC_DEFINE(MOZ_ENABLE_XFT)
     PKG_CHECK_MODULES(MOZ_XFT, xft)
-    PKG_CHECK_MODULES(_PANGOCHK, pango >= 1.1.0)
+    PKG_CHECK_MODULES(_PANGOCHK, pango >= $PANGO_VERSION)
 fi
 
 AC_SUBST(MOZ_ENABLE_XFT)
 AC_SUBST(MOZ_XFT_CFLAGS)
 AC_SUBST(MOZ_XFT_LIBS)
 
 dnl ========================================================
 dnl = pango font rendering
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(pango,
 [  --enable-pango          Enable Pango font rendering support],
     MOZ_ENABLE_PANGO=1,
     MOZ_ENABLE_PANGO=)
 
 if test "$MOZ_ENABLE_PANGO" && test -z "$MOZ_ENABLE_CAIRO_GFX"
 then
-    AC_DEFINE(MOZ_ENABLE_PANGO)
-    PKG_CHECK_MODULES(MOZ_PANGO, pangoxft >= 1.6.0)
-
-    AC_SUBST(MOZ_ENABLE_PANGO)
-    AC_SUBST(MOZ_PANGO_CFLAGS)
-    AC_SUBST(MOZ_PANGO_LIBS)
+    AC_MSG_ERROR([Cairo gfx is required for Pango font rendering])
 fi
 
 if test "$MOZ_ENABLE_GTK2" && test "$MOZ_ENABLE_CAIRO_GFX"
 then
     # For gtk2, we require --enable-pango; gtk2 already implies --enable-xft
     if test -z "$MOZ_ENABLE_PANGO"
     then
         AC_MSG_WARN([Pango is required for cairo gfx builds, assuming --enable-pango])
         MOZ_ENABLE_PANGO=1
     fi
 fi
 
 if test "$MOZ_ENABLE_PANGO" && test "$MOZ_ENABLE_CAIRO_GFX"
 then
     AC_DEFINE(MOZ_ENABLE_PANGO)
-    dnl PKG_CHECK_MODULES(MOZ_PANGO, pango >= 1.10.0 pangocairo >= 1.10.0)
-    if test "$MOZ_X11"; then
-        PKG_CHECK_MODULES(MOZ_PANGO, pango >= 1.6.0 pangoft2 >= 1.6.0 pangoxft >= 1.6.0)
-    else
-        PKG_CHECK_MODULES(MOZ_PANGO, pango >= 1.6.0 pangoft2 >= 1.6.0)
-    fi
-
+    PKG_CHECK_MODULES(MOZ_PANGO, pango >= $PANGO_VERSION pangocairo >= $PANGO_VERSION)
     AC_SUBST(MOZ_ENABLE_PANGO)
     AC_SUBST(MOZ_PANGO_CFLAGS)
     AC_SUBST(MOZ_PANGO_LIBS)
 fi
 
 dnl ========================================================
 dnl = x11 core font support (default and ability to enable depend on toolkit)
 dnl ========================================================
--- a/gfx/cairo/cairo/src/cairo-ft-font.c
+++ b/gfx/cairo/cairo/src/cairo-ft-font.c
@@ -1092,17 +1092,19 @@ static cairo_status_t
     /* According to the FreeType docs, glyphslot->format could be
      * something other than FT_GLYPH_FORMAT_OUTLINE or
      * FT_GLYPH_FORMAT_BITMAP. Calling FT_Render_Glyph gives FreeType
      * the opportunity to convert such to
      * bitmap. FT_GLYPH_FORMAT_COMPOSITE will not be encountered since
      * we avoid the FT_LOAD_NO_RECURSE flag.
      */
     error = FT_Render_Glyph (glyphslot, FT_RENDER_MODE_NORMAL);
-    if (error) {
+    /* XXX ignoring all other errors for now.  They are not fatal, typically
+     * just a glyph-not-found. */
+    if (error == FT_Err_Out_Of_Memory) {
 	_cairo_error (CAIRO_STATUS_NO_MEMORY);
 	return CAIRO_STATUS_NO_MEMORY;
     }
 
     status = _get_bitmap_surface (&glyphslot->bitmap, FALSE, font_options, surface);
     if (status)
 	return status;
 
@@ -1886,18 +1888,19 @@ static cairo_int_status_t
     if (load_flags & FT_LOAD_VERTICAL_LAYOUT) {
 	load_flags &= ~FT_LOAD_VERTICAL_LAYOUT;
 	vertical_layout = TRUE;
     }
 
     error = FT_Load_Glyph (scaled_font->unscaled->face,
 			   _cairo_scaled_glyph_index(scaled_glyph),
 			   load_flags);
-
-    if (error) {
+    /* XXX ignoring all other errors for now.  They are not fatal, typically
+     * just a glyph-not-found. */
+    if (error == FT_Err_Out_Of_Memory) {
 	status = CAIRO_STATUS_NO_MEMORY;
 	goto FAIL;
     }
 
     glyph = face->glyph;
 
 #if HAVE_FT_GLYPHSLOT_EMBOLDEN
     /*
@@ -2037,18 +2040,19 @@ static cairo_int_status_t
 	/*
 	 * A kludge -- the above code will trash the outline,
 	 * so reload it. This will probably never occur though
 	 */
 	if ((info & CAIRO_SCALED_GLYPH_INFO_SURFACE) != 0) {
 	    error = FT_Load_Glyph (face,
 				   _cairo_scaled_glyph_index(scaled_glyph),
 				   load_flags | FT_LOAD_NO_BITMAP);
-
-	    if (error) {
+	    /* XXX ignoring all other errors for now.  They are not fatal, typically
+	     * just a glyph-not-found. */
+	    if (error == FT_Err_Out_Of_Memory) {
 		_cairo_ft_unscaled_font_unlock_face (unscaled);
 		_cairo_error (CAIRO_STATUS_NO_MEMORY);
 		return CAIRO_STATUS_NO_MEMORY;
 	    }
 #if HAVE_FT_GLYPHSLOT_EMBOLDEN
 	    /*
 	     * embolden glyphs if requested
 	     */
--- a/gfx/thebes/public/gfxPangoFonts.h
+++ b/gfx/thebes/public/gfxPangoFonts.h
@@ -39,24 +39,25 @@
 #ifndef GFX_PANGOFONTS_H
 #define GFX_PANGOFONTS_H
 
 #include "cairo.h"
 #include "gfxTypes.h"
 #include "gfxFont.h"
 
 #include <pango/pango.h>
-#include <X11/Xft/Xft.h>
 
-// Control when we use Xft directly, bypassing Pango
-// Enable this to use Xft to glyph-convert 8bit-only textruns, but use Pango
+// Control when we bypass Pango
+// Enable this to use FreeType to glyph-convert 8bit-only textruns, but use Pango
 // to shape any textruns with non-8bit characters
-#define ENABLE_XFT_FAST_PATH_8BIT
-// Enable this to use Xft to glyph-convert all textruns
-// #define ENABLE_XFT_FAST_PATH_ALWAYS
+// XXX
+#define ENABLE_FAST_PATH_8BIT
+// Enable this to bypass Pango shaping for all textruns.  Don't expect
+// anything other than simple Latin work though!
+//#define ENABLE_FAST_PATH_ALWAYS
 
 #include "nsDataHashtable.h"
 #include "nsClassHashtable.h"
 
 class FontSelector;
 
 class gfxPangoTextRun;
 
@@ -65,53 +66,48 @@ public:
     gfxPangoFont (const nsAString& aName,
                   const gfxFontStyle *aFontStyle);
     virtual ~gfxPangoFont ();
 
     static void Shutdown();
 
     virtual const gfxFont::Metrics& GetMetrics();
 
-    PangoFontDescription *GetPangoFontDescription() { RealizeFont(); return mPangoFontDesc; }
-    PangoContext *GetPangoContext() { RealizeFont(); return mPangoCtx; }
+    PangoFontDescription *GetPangoFontDescription() { if (!mPangoFontDesc) RealizeFont(); return mPangoFontDesc; }
+    PangoContext *GetPangoContext() { if (!mPangoFontDesc) RealizeFont(); return mPangoCtx; }
 
     void GetMozLang(nsACString &aMozLang);
     void GetActualFontFamily(nsACString &aFamily);
 
-    XftFont *GetXftFont () { RealizeXftFont (); return mXftFont; }
-    PangoFont *GetPangoFont() { RealizePangoFont(); return mPangoFont; }
-    gfxFloat GetAdjustedSize() { RealizeFont(); return mAdjustedSize; }
+    PangoFont *GetPangoFont() { if (!mPangoFont) RealizePangoFont(); return mPangoFont; }
+    gfxFloat GetAdjustedSize() { if (!mPangoFontDesc) RealizeFont(); return mAdjustedSize; }
 
-    PRBool HasGlyph(const PRUint32 aChar);
     PRUint32 GetGlyph(const PRUint32 aChar);
 
     virtual nsString GetUniqueName();
 
     // Get the glyphID of a space
     virtual PRUint32 GetSpaceGlyph() {
         GetMetrics();
         return mSpaceGlyph;
     }
 
 protected:
     PangoFontDescription *mPangoFontDesc;
     PangoContext *mPangoCtx;
 
-    XftFont *mXftFont;
     PangoFont *mPangoFont;
-    PangoFont *mGlyphTestingFont;
     cairo_scaled_font_t *mCairoFont;
 
     PRBool   mHasMetrics;
     PRUint32 mSpaceGlyph;
     Metrics  mMetrics;
     gfxFloat mAdjustedSize;
 
     void RealizeFont(PRBool force = PR_FALSE);
-    void RealizeXftFont(PRBool force = PR_FALSE);
     void RealizePangoFont(PRBool aForce = PR_FALSE);
     void GetCharSize(const char aChar, gfxSize& aInkSize, gfxSize& aLogSize,
                      PRUint32 *aGlyphID = nsnull);
 
     virtual PRBool SetupCairoFont(cairo_t *aCR);
 };
 
 class FontSelector;
@@ -119,17 +115,17 @@ class FontSelector;
 class THEBES_API gfxPangoFontGroup : public gfxFontGroup {
 public:
     gfxPangoFontGroup (const nsAString& families,
                        const gfxFontStyle *aStyle);
     virtual ~gfxPangoFontGroup ();
 
     virtual gfxFontGroup *Copy(const gfxFontStyle *aStyle);
 
-    // Create and initialize a textrun using Pango (or Xft)
+    // Create and initialize a textrun using Pango
     virtual gfxTextRun *MakeTextRun(const PRUnichar *aString, PRUint32 aLength,
                                     const Parameters *aParams, PRUint32 aFlags);
     virtual gfxTextRun *MakeTextRun(const PRUint8 *aString, PRUint32 aLength,
                                     const Parameters *aParams, PRUint32 aFlags);
 
     gfxPangoFont *GetFontAt(PRInt32 i) {
         return static_cast<gfxPangoFont*>(static_cast<gfxFont*>(mFonts[i]));
     }
@@ -141,33 +137,33 @@ protected:
 
     /**
      * Fill in the glyph-runs for the textrun.
      * @param aTake8BitPath the text contains only characters below 0x100
      * (TEXT_IS_8BIT can return false when the characters are all below 0x100
      * but stored in UTF16 format)
      */
     void InitTextRun(gfxTextRun *aTextRun, const gchar *aUTF8Text,
-                     PRUint32 aUTF8Length, PRUint32 aUTF8HeaderLength,
-                     PRBool aTake8BitPath);
+                     PRUint32 aUTF8Length, PRBool aTake8BitPath);
+
     // Returns NS_ERROR_FAILURE if there's a missing glyph
     nsresult SetGlyphs(gfxTextRun *aTextRun, gfxPangoFont *aFont,
                        const gchar *aUTF8, PRUint32 aUTF8Length,
                        PRUint32 *aUTF16Offset, PangoGlyphString *aGlyphs,
                        PangoGlyphUnit aOverrideSpaceWidth,
                        PRBool aAbortOnMissingGlyph);
     nsresult SetMissingGlyphs(gfxTextRun *aTextRun,
                               const gchar *aUTF8, PRUint32 aUTF8Length,
                               PRUint32 *aUTF16Offset);
     void CreateGlyphRunsItemizing(gfxTextRun *aTextRun,
-                                  const gchar *aUTF8, PRUint32 aUTF8Length,
-                                  PRUint32 aUTF8HeaderLength);
-#if defined(ENABLE_XFT_FAST_PATH_8BIT) || defined(ENABLE_XFT_FAST_PATH_ALWAYS)
-    void CreateGlyphRunsXft(gfxTextRun *aTextRun,
-                            const gchar *aUTF8, PRUint32 aUTF8Length);
+                                  const gchar *aUTF8, PRUint32 aUTF8Length);
+#if defined(ENABLE_FAST_PATH_8BIT) || defined(ENABLE_FAST_PATH_ALWAYS)
+    PRBool CanTakeFastPath(PRUint32 aFlags);
+    void CreateGlyphRunsFast(gfxTextRun *aTextRun,
+                             const gchar *aUTF8, PRUint32 aUTF8Length);
 #endif
 
     static PRBool FontCallback (const nsAString& fontName,
                                 const nsACString& genericName,
                                 void *closure);
 
 private:
     nsTArray<gfxFontStyle> mAdditionalStyles;
@@ -207,35 +203,9 @@ public:
 
     void Put(const PangoFontDescription *aFontDesc, PangoFont *aPangoFont);
     PangoFont* Get(const PangoFontDescription *aFontDesc);
 private:
     static gfxPangoFontCache *sPangoFontCache;
     nsClassHashtable<nsUint32HashKey,  gfxPangoFontWrapper> mPangoFonts;
 };
 
-// XXX we should remove this class, because this class is used only in |HasGlyph| of gfxPangoFont.
-// But it can use fontconfig directly after bug 366664.
-class gfxPangoFontNameMap
-{
-public:
-    gfxPangoFontNameMap();
-    ~gfxPangoFontNameMap();
-
-    static gfxPangoFontNameMap* GetPangoFontNameMap() {
-        if (!sPangoFontNameMap)
-            sPangoFontNameMap = new gfxPangoFontNameMap();
-        return sPangoFontNameMap;
-    }
-    static void Shutdown() {
-        if (sPangoFontNameMap)
-            delete sPangoFontNameMap;
-        sPangoFontNameMap = nsnull;
-    }
-
-    void Put(const nsACString &aName, PangoFont *aPangoFont);
-    PangoFont* Get(const nsACString &aName);
-
-private:
-    static gfxPangoFontNameMap *sPangoFontNameMap;
-    nsClassHashtable<nsCStringHashKey, gfxPangoFontWrapper> mPangoFonts;
-};
 #endif /* GFX_PANGOFONTS_H */
--- a/gfx/thebes/public/gfxPlatformGtk.h
+++ b/gfx/thebes/public/gfxPlatformGtk.h
@@ -74,17 +74,17 @@ public:
 
     gfxFontGroup *CreateFontGroup(const nsAString &aFamilies,
                                   const gfxFontStyle *aStyle);
 
     static PRInt32 DPI() {
         if (sDPI == -1) {
             InitDPI();
         }
-        NS_ASSERTION(sDPI != 0, "Something is wrong");
+        NS_ASSERTION(sDPI > 0, "Something is wrong");
         return sDPI;
     }
 
 protected:
     static void InitDPI();
 
     static PRInt32 sDPI;
     static gfxFontconfigUtils *sFontconfigUtils;
--- a/gfx/thebes/src/cairo-xlib-utils.c
+++ b/gfx/thebes/src/cairo-xlib-utils.c
@@ -35,16 +35,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "cairo-xlib-utils.h"
 
 #include "cairo-xlib.h"
 #include <stdlib.h>
 
+#include <stdint.h>
 #if   HAVE_STDINT_H
 #include <stdint.h>
 #elif HAVE_INTTYPES_H
 #include <inttypes.h>
 #elif HAVE_SYS_INT_TYPES_H
 #include <sys/int_types.h>
 #endif
 
--- a/gfx/thebes/src/gfxPangoFonts.cpp
+++ b/gfx/thebes/src/gfxPangoFonts.cpp
@@ -16,16 +16,17 @@
  *
  * The Initial Developer of the Original Code is Mozilla Foundation.
  * Portions created by the Initial Developer are Copyright (C) 2005
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   Vladimir Vukicevic <vladimir@mozilla.com>
  *   Masayuki Nakano <masayuki@d-toybox.com>
+ *   Behdad Esfahbod <behdad@gnome.org>
  *
  * based on nsFontMetricsPango.cpp by
  *   Christopher Blizzard <blizzard@mozilla.org>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
@@ -34,21 +35,16 @@
  * 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 ***** */
 
-#ifdef XP_BEOS
-#define THEBES_USE_PANGO_CAIRO
-#endif
-
-#define PANGO_ENABLE_ENGINE
 #define PANGO_ENABLE_BACKEND
 
 #include "prtypes.h"
 #include "prlink.h"
 #include "gfxTypes.h"
 
 #include "nsUnicodeRange.h"
 
@@ -57,55 +53,48 @@
 #include "nsIPrefService.h"
 #include "nsServiceManagerUtils.h"
 #include "nsMathUtils.h"
 
 #include "nsVoidArray.h"
 #include "nsPromiseFlatString.h"
 
 #include "gfxContext.h"
+#include "gfxPlatformGtk.h"
 #include "gfxPangoFonts.h"
 
 #include "nsCRT.h"
 
-#include "cairo.h"
+#include <freetype/tttables.h>
 
-#ifndef THEBES_USE_PANGO_CAIRO
-#include <gdk/gdk.h>
-#include <gdk/gdkx.h>
-#include <gdk/gdkpango.h>
-
-
-#include <freetype/tttables.h>
-#include <fontconfig/fontconfig.h>
+#include <cairo.h>
+#include <cairo-ft.h>
 
-#include <pango/pango-font.h>
-#include <pango/pangoxft.h>
-
-#include "cairo-ft.h"
+#include <pango/pango.h>
+#include <pango/pango-utils.h>
+#include <pango/pangocairo.h>
+#include <pango/pangofc-fontmap.h>
 
-#include "gfxPlatformGtk.h"
-
-#else // THEBES_USE_PANGO_CAIRO
-
-#include <pango/pangocairo.h>
-
-#endif // THEBES_USE_PANGO_CAIRO
+#include <gdk/gdkpango.h>
 
 #include <math.h>
 
 #define FLOAT_PANGO_SCALE ((gfxFloat)PANGO_SCALE)
 
-#define IS_MISSING_GLYPH(g) (((g) & 0x10000000) || (g) == 0x0FFFFFFF)
+#ifndef PANGO_GLYPH_UNKNOWN_FLAG
+#define PANGO_GLYPH_UNKNOWN_FLAG ((PangoGlyph)0x10000000)
+#endif
+#ifndef PANGO_GLYPH_EMPTY
+#define PANGO_GLYPH_EMPTY           ((PangoGlyph)0)
+#endif
+#define IS_MISSING_GLYPH(g) (((g) & PANGO_GLYPH_UNKNOWN_FLAG) || (g) == PANGO_GLYPH_EMPTY)
 
 static PangoLanguage *GetPangoLanguage(const nsACString& aLangGroup);
-static void GetMozLanguage(const PangoLanguage *aLang, nsACString &aMozLang);
 
 /* static */ gfxPangoFontCache* gfxPangoFontCache::sPangoFontCache = nsnull;
-/* static */ gfxPangoFontNameMap* gfxPangoFontNameMap::sPangoFontNameMap = nsnull;
 
 /**
  ** gfxPangoFontGroup
  **/
 
 static int
 FFRECountHyphens (const nsAString &aFFREName)
 {
@@ -161,16 +150,17 @@ gfxPangoFontGroup::gfxPangoFontGroup (co
     nsStringArray familyArray;
 
     ForEachFont (FontCallback, &familyArray);
 
     FindGenericFontFromStyle (FontCallback, &familyArray);
 
     // XXX If there are no actual fonts, we should use dummy family.
     // Pango will resolve from this.
+    // behdad: yep, looks good.
     if (familyArray.Count() == 0) {
         // printf("%s(%s)\n", NS_ConvertUTF16toUTF8(families).get(),
         //                    aStyle->langGroup.get());
         familyArray.AppendString(NS_LITERAL_STRING("sans-serif"));
     }
 
     for (int i = 0; i < familyArray.Count(); i++) {
         nsRefPtr<gfxPangoFont> font = GetOrMakeFont(*familyArray[i], &mStyle);
@@ -189,118 +179,48 @@ gfxPangoFontGroup::Copy(const gfxFontSty
 {
     return new gfxPangoFontGroup(mFamilies, aStyle);
 }
 
 /**
  ** gfxPangoFont
  **/
 
-// Glue to avoid build/runtime dependencies on Pango > 1.6,
-// because we like living in 1999
-
-#ifndef THEBES_USE_PANGO_CAIRO
-static void
-(* PTR_pango_font_description_set_absolute_size)(PangoFontDescription*, double)
-    = nsnull;
-
-static void InitPangoLib()
-{
-    static PRBool initialized = PR_FALSE;
-    if (initialized)
-        return;
-    initialized = PR_TRUE;
-
-    g_type_init();
-
-    PRLibrary *pangoLib = nsnull;
-    PTR_pango_font_description_set_absolute_size =
-        (void (*)(PangoFontDescription*, double))
-        PR_FindFunctionSymbolAndLibrary("pango_font_description_set_absolute_size",
-                                        &pangoLib);
-    if (pangoLib)
-        PR_UnloadLibrary(pangoLib);
-
-    PRLibrary *xftLib = nsnull;
-    int *xft_max_freetype_files_ptr = nsnull;
-    xft_max_freetype_files_ptr = (int*) PR_FindSymbolAndLibrary("XftMaxFreeTypeFiles", &xftLib);
-    if (xft_max_freetype_files_ptr && *xft_max_freetype_files_ptr < 50)
-        *xft_max_freetype_files_ptr = 50;
-    if (xftLib)
-        PR_UnloadLibrary(xftLib);
-}
-
-static void
-ShutdownPangoLib()
-{
-}
-
-static void
-MOZ_pango_font_description_set_absolute_size(PangoFontDescription *desc,
-                                             double size)
-{
-    if (PTR_pango_font_description_set_absolute_size) {
-        PTR_pango_font_description_set_absolute_size(desc, size);
-    } else {
-        pango_font_description_set_size(desc,
-                                        (gint)(size * 72.0 /
-                                               gfxPlatformGtk::DPI()));
-    }
-}
-#else
-static inline void InitPangoLib()
-{
-}
-
-static inline void ShutdownPangoLib()
-{
-}
-
-static inline void
-MOZ_pango_font_description_set_absolute_size(PangoFontDescription *desc, double size)
-{
-    pango_font_description_set_absolute_size(desc, size);
-}
-#endif
-
 gfxPangoFont::gfxPangoFont(const nsAString &aName,
                            const gfxFontStyle *aFontStyle)
     : gfxFont(aName, aFontStyle),
-    mPangoFontDesc(nsnull), mPangoCtx(nsnull),
-    mXftFont(nsnull), mPangoFont(nsnull), mGlyphTestingFont(nsnull),
-    mCairoFont(nsnull), mHasMetrics(PR_FALSE),
-    mAdjustedSize(0)
+    mPangoFontDesc(nsnull), mPangoCtx(nsnull), mPangoFont(nsnull),
+    mCairoFont(nsnull), mHasMetrics(PR_FALSE), mAdjustedSize(0)
 {
-    InitPangoLib();
 }
 
 gfxPangoFont::~gfxPangoFont()
 {
     if (mPangoCtx)
         g_object_unref(mPangoCtx);
 
     if (mPangoFont)
         g_object_unref(mPangoFont);
 
-    if (mGlyphTestingFont)
-        g_object_unref(mGlyphTestingFont);
-
     if (mPangoFontDesc)
         pango_font_description_free(mPangoFontDesc);
 
     if (mCairoFont)
         cairo_scaled_font_destroy(mCairoFont);
 }
 
 /* static */ void
 gfxPangoFont::Shutdown()
 {
-    ShutdownPangoLib();
     gfxPangoFontCache::Shutdown();
-    gfxPangoFontNameMap::Shutdown();
+
+    PangoFontMap *fontmap = pango_cairo_font_map_get_default ();
+    if (PANGO_IS_FC_FONT_MAP (fontmap))
+	pango_fc_font_map_shutdown (PANGO_FC_FONT_MAP (fontmap));
+
 }
 
 static PangoStyle
 ThebesStyleToPangoStyle (const gfxFontStyle *fs)
 {
     if (fs->style == FONT_STYLE_ITALIC)
         return PANGO_STYLE_ITALIC;
     if (fs->style == FONT_STYLE_OBLIQUE)
@@ -370,38 +290,34 @@ gfxPangoFont::RealizeFont(PRBool force)
 
     if (mPangoCtx)
         g_object_unref(mPangoCtx);
     if (mPangoFontDesc)
         pango_font_description_free(mPangoFontDesc);
     if (mPangoFont) {
         g_object_unref(mPangoFont);
         mPangoFont = nsnull;
-        mXftFont = nsnull;
-        // XXX we don't need to reset mGlyphTestingFont
     }
 
     mPangoFontDesc = pango_font_description_new();
 
     pango_font_description_set_family(mPangoFontDesc, NS_ConvertUTF16toUTF8(mName).get());
     gfxFloat size = mAdjustedSize ? mAdjustedSize : GetStyle()->size;
-    MOZ_pango_font_description_set_absolute_size(mPangoFontDesc, size * PANGO_SCALE);
+    pango_font_description_set_absolute_size(mPangoFontDesc, size * PANGO_SCALE);
     pango_font_description_set_style(mPangoFontDesc, ThebesStyleToPangoStyle(GetStyle()));
     pango_font_description_set_weight(mPangoFontDesc, ThebesStyleToPangoWeight(GetStyle()));
 
     //printf ("%s, %f, %d, %d\n", NS_ConvertUTF16toUTF8(mName).get(), GetStyle()->size, ThebesStyleToPangoStyle(GetStyle()), ThebesStyleToPangoWeight(GetStyle()));
-#ifndef THEBES_USE_PANGO_CAIRO
-    mPangoCtx = pango_xft_get_context(GDK_DISPLAY(), 0);
-    gdk_pango_context_set_colormap(mPangoCtx, gdk_rgb_get_cmap());
-#else
-    mPangoCtx = pango_cairo_font_map_create_context(PANGO_CAIRO_FONT_MAP(pango_cairo_font_map_get_default()));
-#endif
+    mPangoCtx = gdk_pango_context_get ();
 
-    if (!GetStyle()->langGroup.IsEmpty())
-        pango_context_set_language(mPangoCtx, GetPangoLanguage(GetStyle()->langGroup));
+    if (!GetStyle()->langGroup.IsEmpty()) {
+        PangoLanguage *lang = GetPangoLanguage(GetStyle()->langGroup);
+        if (lang)
+            pango_context_set_language(mPangoCtx, lang);
+    }
 
     pango_context_set_font_description(mPangoCtx, mPangoFontDesc);
 
     mHasMetrics = PR_FALSE;
 
     if (mAdjustedSize != 0)
         return;
 
@@ -412,63 +328,35 @@ gfxPangoFont::RealizeFont(PRBool force)
     gfxSize isz, lsz;
     GetCharSize('x', isz, lsz);
     gfxFloat aspect = isz.height / GetStyle()->size;
     mAdjustedSize = GetStyle()->GetAdjustedSize(aspect);
     RealizeFont(PR_TRUE);
 }
 
 void
-gfxPangoFont::RealizeXftFont(PRBool force)
-{
-    // already realized?
-    if (!force && mXftFont)
-        return;
-    if (GDK_DISPLAY() == 0) {
-        mXftFont = nsnull;
-        return;
-    }
-
-    mXftFont = pango_xft_font_get_font(GetPangoFont());
-}
-
-void
 gfxPangoFont::RealizePangoFont(PRBool aForce)
 {
     if (!aForce && mPangoFont)
         return;
     if (mPangoFont) {
         g_object_unref(mPangoFont);
         mPangoFont = nsnull;
-        mXftFont = nsnull;
     }
     RealizeFont();
     gfxPangoFontCache *cache = gfxPangoFontCache::GetPangoFontCache();
     if (!cache)
         return; // Error
     mPangoFont = cache->Get(mPangoFontDesc);
     if (mPangoFont)
         return;
     mPangoFont = pango_context_load_font(mPangoCtx, mPangoFontDesc);
     if (!mPangoFont)
         return; // Error
     cache->Put(mPangoFontDesc, mPangoFont);
-
-    if (mGlyphTestingFont)
-        return;
-
-    // Append this to font name map
-    gfxPangoFontNameMap *fontNameMap = gfxPangoFontNameMap::GetPangoFontNameMap();
-    if (!fontNameMap)
-        return; // Error
-    NS_ConvertUTF16toUTF8 name(mName);
-    mGlyphTestingFont = fontNameMap->Get(name);
-    if (mGlyphTestingFont)
-        return;
-    fontNameMap->Put(name, mPangoFont);
 }
 
 void
 gfxPangoFont::GetCharSize(char aChar, gfxSize& aInkSize, gfxSize& aLogSize,
                           PRUint32 *aGlyphID)
 {
     PangoAnalysis analysis;
     // Initialize new fields, gravity and flags in pango 1.16
@@ -515,99 +403,16 @@ gfxPangoFont::GetCharSize(char aChar, gf
         MOZ_FT_TRUNC(MOZ_FT_ROUND(FT_MulFix((v) , (s))))
 
 const gfxFont::Metrics&
 gfxPangoFont::GetMetrics()
 {
     if (mHasMetrics)
         return mMetrics;
 
-#ifndef THEBES_USE_PANGO_CAIRO
-    float val;
-
-    XftFont *xftFont = GetXftFont(); // RealizeFont is called here.
-    if (!xftFont)
-        return mMetrics;        // XXX error
-
-    FT_Face face = XftLockFace(xftFont);
-    if (!face)
-        return mMetrics;        // XXX error
-
-    int size;
-    PangoFcFont *fcfont = PANGO_FC_FONT(mPangoFont);
-    if (FcPatternGetInteger(fcfont->font_pattern, FC_PIXEL_SIZE, 0, &size) != FcResultMatch)
-        size = 12;
-    mMetrics.emHeight = PR_MAX(1, size);
-
-    mMetrics.maxAscent = xftFont->ascent;
-    mMetrics.maxDescent = xftFont->descent;
-
-    double lineHeight = mMetrics.maxAscent + mMetrics.maxDescent;
-
-    if (lineHeight > mMetrics.emHeight)
-        mMetrics.internalLeading = lineHeight - mMetrics.emHeight;
-    else
-        mMetrics.internalLeading = 0;
-    mMetrics.externalLeading = 0;
-
-    mMetrics.maxHeight = lineHeight;
-    mMetrics.emAscent = mMetrics.maxAscent * mMetrics.emHeight / lineHeight;
-    mMetrics.emDescent = mMetrics.emHeight - mMetrics.emAscent;
-    mMetrics.maxAdvance = xftFont->max_advance_width;
-
-    gfxSize isz, lsz;
-    GetCharSize(' ', isz, lsz, &mSpaceGlyph);
-    mMetrics.spaceWidth = lsz.width;
-
-    // XXX do some FcCharSetHasChar work here to make sure
-    // we have an "x"
-    GetCharSize('x', isz, lsz);
-    mMetrics.xHeight = isz.height;
-    mMetrics.aveCharWidth = isz.width;
-
-    val = CONVERT_DESIGN_UNITS_TO_PIXELS(face->underline_position,
-                                         face->size->metrics.y_scale);
-    if (!val)
-        val = - PR_MAX(1, floor(0.1 * xftFont->height + 0.5));
-
-    mMetrics.underlineOffset = val;
-
-    val = CONVERT_DESIGN_UNITS_TO_PIXELS(face->underline_thickness,
-                                         face->size->metrics.y_scale);
-    if (!val)
-        val = floor(0.05 * xftFont->height + 0.5);
-
-    mMetrics.underlineSize = PR_MAX(1, val);
-
-    TT_OS2 *os2 = (TT_OS2 *) FT_Get_Sfnt_Table(face, ft_sfnt_os2);
-
-    if (os2 && os2->ySuperscriptYOffset) {
-        val = CONVERT_DESIGN_UNITS_TO_PIXELS(os2->ySuperscriptYOffset,
-                                             face->size->metrics.y_scale);
-        mMetrics.superscriptOffset = PR_MAX(1, val);
-    } else {
-        mMetrics.superscriptOffset = mMetrics.xHeight;
-    }
-
-    // mSubscriptOffset
-    if (os2 && os2->ySubscriptYOffset) {
-        val = CONVERT_DESIGN_UNITS_TO_PIXELS(os2->ySubscriptYOffset,
-                                             face->size->metrics.y_scale);
-        // some fonts have the incorrect sign. 
-        val = (val < 0) ? -val : val;
-        mMetrics.subscriptOffset = PR_MAX(1, val);
-    } else {
-        mMetrics.subscriptOffset = mMetrics.xHeight;
-    }
-
-    mMetrics.strikeoutOffset = mMetrics.xHeight / 2.0;
-    mMetrics.strikeoutSize = mMetrics.underlineSize;
-
-    XftUnlockFace(xftFont);
-#else
     /* pango_cairo case; try to get all the metrics from pango itself */
     PangoFont *font = GetPangoFont(); // RealizeFont is called here.
 
     PangoFontMetrics *pfm = pango_font_get_metrics (font, NULL);
 
     // ??
     mMetrics.emHeight = mAdjustedSize ? mAdjustedSize : GetStyle()->size;
 
@@ -622,284 +427,219 @@ gfxPangoFont::GetMetrics()
         mMetrics.externalLeading = 0;
     mMetrics.internalLeading = 0;
 
     mMetrics.maxHeight = lineHeight;
 
     mMetrics.emAscent = mMetrics.maxAscent * mMetrics.emHeight / lineHeight;
     mMetrics.emDescent = mMetrics.emHeight - mMetrics.emAscent;
 
-    mMetrics.maxAdvance = pango_font_metrics_get_approximate_char_width(pfm) / FLOAT_PANGO_SCALE; // XXX
+    // XXX should we move this down, get max-advance from FT_Face?
+    mMetrics.maxAdvance = pango_font_metrics_get_approximate_char_width(pfm) / FLOAT_PANGO_SCALE;
 
     gfxSize isz, lsz;
     GetCharSize(' ', isz, lsz, &mSpaceGlyph);
     mMetrics.spaceWidth = lsz.width;
     GetCharSize('x', isz, lsz);
     mMetrics.xHeight = isz.height;
 
     mMetrics.aveCharWidth = pango_font_metrics_get_approximate_char_width(pfm) / FLOAT_PANGO_SCALE;
 
     mMetrics.underlineOffset = pango_font_metrics_get_underline_position(pfm) / FLOAT_PANGO_SCALE;
     mMetrics.underlineSize = pango_font_metrics_get_underline_thickness(pfm) / FLOAT_PANGO_SCALE;
 
     mMetrics.strikeoutOffset = pango_font_metrics_get_strikethrough_position(pfm) / FLOAT_PANGO_SCALE;
     mMetrics.strikeoutSize = pango_font_metrics_get_strikethrough_thickness(pfm) / FLOAT_PANGO_SCALE;
 
-    // these are specified by the so-called OS2 SFNT info, but
-    // pango doesn't expose this to us.  This really sucks,
-    // so we just assume it's the xHeight
-    mMetrics.superscriptOffset = mMetrics.xHeight;
-    mMetrics.subscriptOffset = mMetrics.xHeight;
+    FT_Face face = NULL;
+    if (PANGO_IS_FC_FONT (font))
+      face = pango_fc_font_lock_face (PANGO_FC_FONT (font));
+
+    if (face) {
+
+	float val;
+
+        TT_OS2 *os2 = (TT_OS2 *) FT_Get_Sfnt_Table(face, ft_sfnt_os2);
+    
+        if (os2 && os2->ySuperscriptYOffset) {
+            val = CONVERT_DESIGN_UNITS_TO_PIXELS(os2->ySuperscriptYOffset,
+                                                 face->size->metrics.y_scale);
+            mMetrics.superscriptOffset = PR_MAX(1, val);
+        } else {
+            mMetrics.superscriptOffset = mMetrics.xHeight;
+        }
+    
+        // mSubscriptOffset
+        if (os2 && os2->ySubscriptYOffset) {
+            val = CONVERT_DESIGN_UNITS_TO_PIXELS(os2->ySubscriptYOffset,
+                                                 face->size->metrics.y_scale);
+            // some fonts have the incorrect sign. 
+            val = (val < 0) ? -val : val;
+            mMetrics.subscriptOffset = PR_MAX(1, val);
+        } else {
+            mMetrics.subscriptOffset = mMetrics.xHeight;
+        }
+
+    } else {
+
+	mMetrics.superscriptOffset = mMetrics.xHeight;
+	mMetrics.subscriptOffset = mMetrics.xHeight;
+    }
+
 
     pango_font_metrics_unref (pfm);
-#endif
 
 #if 0
     fprintf (stderr, "Font: %s\n", NS_ConvertUTF16toUTF8(mName).get());
     fprintf (stderr, "    emHeight: %f emAscent: %f emDescent: %f\n", mMetrics.emHeight, mMetrics.emAscent, mMetrics.emDescent);
     fprintf (stderr, "    maxAscent: %f maxDescent: %f\n", mMetrics.maxAscent, mMetrics.maxDescent);
     fprintf (stderr, "    internalLeading: %f externalLeading: %f\n", mMetrics.externalLeading, mMetrics.internalLeading);
     fprintf (stderr, "    spaceWidth: %f aveCharWidth: %f xHeight: %f\n", mMetrics.spaceWidth, mMetrics.aveCharWidth, mMetrics.xHeight);
     fprintf (stderr, "    uOff: %f uSize: %f stOff: %f stSize: %f suOff: %f suSize: %f\n", mMetrics.underlineOffset, mMetrics.underlineSize, mMetrics.strikeoutOffset, mMetrics.strikeoutSize, mMetrics.superscriptOffset, mMetrics.subscriptOffset);
 #endif
 
     mHasMetrics = PR_TRUE;
     return mMetrics;
 }
 
-// XXX we should replace this to |pango_is_zero_width| after we don't support pre pango 1.10
-static PRBool MOZ_pango_is_zero_width(PRUint32 aChar)
-{
-    if (aChar == 0x00AD)
-        return PR_TRUE;
-    if (aChar < 0x200B)
-        return PR_FALSE;
-    if (aChar <= 0x200F || aChar == 0x2028)
-        return PR_TRUE;
-    if (aChar < 0x202A)
-        return PR_FALSE;
-    if (aChar <= 0x202E)
-        return PR_TRUE;
-    if (aChar < 0x2060)
-        return PR_FALSE;
-    if (aChar <= 0x2063 || aChar == 0xFEFF)
-        return PR_TRUE;
-    return PR_FALSE;
-}
-PRBool
-gfxPangoFont::HasGlyph(PRUint32 aChar)
-{
-    // Ensure that null character should be missing.
-    if (aChar == 0)
-        return PR_FALSE;
-
-    if (MOZ_pango_is_zero_width(aChar))
-        return PR_TRUE;
-
-    PangoFont *font = nsnull;
-    if (mPangoFont)
-        font = mPangoFont;
-    else if (mGlyphTestingFont)
-        font = mGlyphTestingFont;
-    else {
-        gfxPangoFontNameMap *fontNameMap = gfxPangoFontNameMap::GetPangoFontNameMap();
-        NS_ENSURE_TRUE(fontNameMap, PR_FALSE);
-        // XXX in a prinsiple, we need to add weight and style for the key.
-        // But this method should be independent from pango for the performance.
-        // For the temporary, the name is enough for the key. The members of
-        // a font-family should have same glyphs.
-        NS_ConvertUTF16toUTF8 name(mName);
-        mGlyphTestingFont = fontNameMap->Get(name);
-        if (!mGlyphTestingFont) {
-            font = GetPangoFont();
-            NS_ENSURE_TRUE(font, PR_FALSE);
-        } else
-            font = mGlyphTestingFont;
-    }
-    return pango_fc_font_has_char(PANGO_FC_FONT(font), aChar) ? PR_TRUE : PR_FALSE;
-}
-
 PRUint32
 gfxPangoFont::GetGlyph(const PRUint32 aChar)
 {
     // Ensure that null character should be missing.
     if (aChar == 0)
         return 0;
-    RealizePangoFont();
-    return pango_fc_font_get_glyph(PANGO_FC_FONT(mPangoFont), aChar);
+    return pango_fc_font_get_glyph(PANGO_FC_FONT(GetPangoFont()), aChar);
 }
 
 nsString
 gfxPangoFont::GetUniqueName()
 {
     PangoFont *font = GetPangoFont();
     PangoFontDescription *desc = pango_font_describe(font);
+    pango_font_description_unset_fields (desc, PANGO_FONT_MASK_SIZE);
     char *str = pango_font_description_to_string(desc);
-
-    // chop off the trailing size, e.g. "Albany AMT 15.359375" -> "Albany AMT"
-    PRUint32 end = strlen(str);
-    while (end > 0) {
-        --end;
-        if (str[end] == ' ')
-            break;
-    }
-    str[end] = 0;
+    pango_font_description_free (desc);
 
     nsString result;
     CopyUTF8toUTF16(str, result);
     g_free(str);
     return result;
 }
 
-static const char *sCJKLangGroup[] = {
-    "ja",
-    "ko",
-    "zh-CN",
-    "zh-HK",
-    "zh-TW"
-};
-
-#define COUNT_OF_CJK_LANG_GROUP 5
-#define CJK_LANG_JA    sCJKLangGroup[0]
-#define CJK_LANG_KO    sCJKLangGroup[1]
-#define CJK_LANG_ZH_CN sCJKLangGroup[2]
-#define CJK_LANG_ZH_HK sCJKLangGroup[3]
-#define CJK_LANG_ZH_TW sCJKLangGroup[4]
-
-static PRInt32
-GetCJKLangGroupIndex(const char *aLangGroup)
-{
-    PRInt32 i;
-    for (i = 0; i < COUNT_OF_CJK_LANG_GROUP; i++) {
-        if (!PL_strcasecmp(aLangGroup, sCJKLangGroup[i]))
-            return i;
-    }
-    return -1;
-}
-
 /**
  ** gfxTextRun
  * 
  * Some serious problems:
  *
  * -- We draw with a font that's hinted for the CTM, but we measure with a font
  * hinted to the identity matrix, so our "bounding metrics" may not be accurate.
  * 
  * -- CreateScaledFont doesn't necessarily give us the font that the Pango
  * metrics assume.
  * 
  **/
 
-/**
- * We use this to append an LTR or RTL Override character to the start of the
- * string. This forces Pango to honour our direction even if there are neutral characters
- * in the string.
- */
-static PRInt32 AppendDirectionalIndicatorUTF8(PRBool aIsRTL, nsACString& aString)
-{
-    static const PRUnichar overrides[2][2] =
-      { { 0x202d, 0 }, { 0x202e, 0 }}; // LRO, RLO
-    AppendUTF16toUTF8(overrides[aIsRTL], aString);
-    return 3; // both overrides map to 3 bytes in UTF8
-}
-
 gfxTextRun *
 gfxPangoFontGroup::MakeTextRun(const PRUint8 *aString, PRUint32 aLength,
                                const Parameters *aParams, PRUint32 aFlags)
 {
     NS_ASSERTION(aFlags & TEXT_IS_8BIT, "8bit should have been set");
     gfxTextRun *run = new gfxTextRun(aParams, aString, aLength, this, aFlags);
     if (!run)
         return nsnull;
 
     PRBool isRTL = run->IsRightToLeft();
     if ((aFlags & TEXT_IS_ASCII) && !isRTL) {
-        // We don't need to send an override character here, the characters must be all
-        // LTR
         const gchar *utf8Chars = reinterpret_cast<const gchar*>(aString);
-        InitTextRun(run, utf8Chars, aLength, 0, PR_TRUE);
+        InitTextRun(run, utf8Chars, aLength, PR_TRUE);
     } else {
+        // this is really gross...
         const char *chars = reinterpret_cast<const char*>(aString);
-        // XXX this could be more efficient.
-        // Although chars in not necessarily ASCII (as it may point to the low
-        // bytes of any UCS-2 characters < 256), NS_ConvertASCIItoUTF16 seems
-        // to DTRT.
         NS_ConvertASCIItoUTF16 unicodeString(chars, aLength);
-        nsCAutoString utf8;
-        PRInt32 headerLen = AppendDirectionalIndicatorUTF8(isRTL, utf8);
-        AppendUTF16toUTF8(unicodeString, utf8);
-        InitTextRun(run, utf8.get(), utf8.Length(), headerLen, PR_TRUE);
+        NS_ConvertUTF16toUTF8 utf8String(unicodeString);
+        InitTextRun(run, utf8String.get(), utf8String.Length(), PR_TRUE);
     }
+
     return run;
 }
 
-static PRBool
-CanTakeFastPath(PRUint32 aFlags)
+#if defined(ENABLE_FAST_PATH_8BIT)
+PRBool
+gfxPangoFontGroup::CanTakeFastPath(PRUint32 aFlags)
 {
+    if (!PANGO_IS_FC_FONT (GetFontAt(0)->GetPangoFont ()))
+        return FALSE;
+
     // Can take fast path only if OPTIMIZE_SPEED is set and IS_RTL isn't
     // We need to always use Pango for RTL text, in case glyph mirroring is required
     return (aFlags &
             (gfxTextRunFactory::TEXT_OPTIMIZE_SPEED | gfxTextRunFactory::TEXT_IS_RTL)) ==
         gfxTextRunFactory::TEXT_OPTIMIZE_SPEED;
 }
+#endif
 
 gfxTextRun *
 gfxPangoFontGroup::MakeTextRun(const PRUnichar *aString, PRUint32 aLength,
                                const Parameters *aParams, PRUint32 aFlags)
 {
     gfxTextRun *run = new gfxTextRun(aParams, aString, aLength, this, aFlags);
     if (!run)
         return nsnull;
 
     run->RecordSurrogates(aString);
 
-    nsCAutoString utf8;
-    PRInt32 headerLen = AppendDirectionalIndicatorUTF8(run->IsRightToLeft(), utf8);
-    AppendUTF16toUTF8(Substring(aString, aString + aLength), utf8);
+    NS_ConvertUTF16toUTF8 utf8(aString, aLength);
     PRBool is8Bit = PR_FALSE;
-#if defined(ENABLE_XFT_FAST_PATH_8BIT)
+
+#if defined(ENABLE_FAST_PATH_8BIT)
     if (CanTakeFastPath(aFlags)) {
         PRUint32 allBits = 0;
         PRUint32 i;
         for (i = 0; i < aLength; ++i) {
             allBits |= aString[i];
         }
         is8Bit = (allBits & 0xFF00) == 0;
     }
 #endif
-    InitTextRun(run, utf8.get(), utf8.Length(), headerLen, is8Bit);
+    InitTextRun(run, utf8.get(), utf8.Length(), is8Bit);
     return run;
 }
 
 void
 gfxPangoFontGroup::InitTextRun(gfxTextRun *aTextRun, const gchar *aUTF8Text,
-                               PRUint32 aUTF8Length, PRUint32 aUTF8HeaderLength,
-                               PRBool aTake8BitPath)
+                               PRUint32 aUTF8Length, PRBool aTake8BitPath)
 {
-#if defined(ENABLE_XFT_FAST_PATH_ALWAYS)
-    CreateGlyphRunsXft(aTextRun, aUTF8Text + aUTF8HeaderLength, aUTF8Length - aUTF8HeaderLength);
+#if defined(ENABLE_FAST_PATH_ALWAYS)
+    CreateGlyphRunsFast(aTextRun, aUTF8Text, aUTF8Length);
 #else
-#if defined(ENABLE_XFT_FAST_PATH_8BIT)
+#if defined(ENABLE_FAST_PATH_8BIT)
     if (aTake8BitPath && CanTakeFastPath(aTextRun->GetFlags())) {
-        CreateGlyphRunsXft(aTextRun, aUTF8Text + aUTF8HeaderLength, aUTF8Length - aUTF8HeaderLength);
+        CreateGlyphRunsFast(aTextRun, aUTF8Text, aUTF8Length);
         return;
     }
 #endif
 
     pango_context_set_base_dir(GetFontAt(0)->GetPangoContext(),
                                (aTextRun->IsRightToLeft()
                                   ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR));
 
-    CreateGlyphRunsItemizing(aTextRun, aUTF8Text, aUTF8Length, aUTF8HeaderLength);
+    CreateGlyphRunsItemizing(aTextRun, aUTF8Text, aUTF8Length);
 #endif
 }
 
 static cairo_scaled_font_t*
 CreateScaledFont(cairo_t *aCR, cairo_matrix_t *aCTM, PangoFont *aPangoFont)
 {
+#if 0
+//XXX enalbe this #if defined(PANGO_VERSION_CHECK) && PANGO_VERSION_CHECK(1,17,5)
+    // Lets just use pango_cairo_font_get_scaled_font() for now.  it's only
+    // available in pango 1.17.x though :(
+    return cairo_scaled_font_reference (pango_cairo_font_get_scaled_font (PANGO_CAIRO_FONT (aPangoFont)));
+#else
+
     // XXX is this safe really? We should probably check the font type or something.
     // XXX does this really create the same font that Pango used for measurement?
     // We probably need to work harder here. We should pay particular attention
     // to the font options.
     PangoFcFont *fcfont = PANGO_FC_FONT(aPangoFont);
     cairo_font_face_t *face = cairo_ft_font_face_create_for_pattern(fcfont->font_pattern);
     double size;
     if (FcPatternGetDouble(fcfont->font_pattern, FC_PIXEL_SIZE, 0, &size) != FcResultMatch)
@@ -908,16 +648,17 @@ CreateScaledFont(cairo_t *aCR, cairo_mat
     cairo_matrix_init_scale(&fontMatrix, size, size);
     cairo_font_options_t *fontOptions = cairo_font_options_create();
     cairo_get_font_options(aCR, fontOptions);
     cairo_scaled_font_t *scaledFont =
         cairo_scaled_font_create(face, &fontMatrix, aCTM, fontOptions);
     cairo_font_options_destroy(fontOptions);
     cairo_font_face_destroy(face);
     return scaledFont;
+#endif
 }
 
 PRBool
 gfxPangoFont::SetupCairoFont(cairo_t *aCR)
 {
     cairo_matrix_t currentCTM;
     cairo_get_matrix(aCR, &currentCTM);
 
@@ -946,16 +687,18 @@ gfxPangoFont::SetupCairoFont(cairo_t *aC
 
 static void
 SetupClusterBoundaries(gfxTextRun* aTextRun, const gchar *aUTF8, PRUint32 aUTF8Length,
                        PRUint32 aUTF16Offset, PangoAnalysis *aAnalysis)
 {
     if (aTextRun->GetFlags() & gfxTextRunFactory::TEXT_IS_8BIT) {
         // 8-bit text doesn't have clusters.
         // XXX is this true in all languages???
+	// behdad: don't think so.  Czech for example IIRC has a
+	// 'ch' grapheme.
         return;
     }
 
     // Pango says "the array of PangoLogAttr passed in must have at least N+1
     // elements, if there are N characters in the text being broken".
     // Could use g_utf8_strlen(aUTF8, aUTF8Length) + 1 but the memory savings
     // may not be worth the call.
     nsAutoTArray<PangoLogAttr,2000> buffer;
@@ -1190,18 +933,19 @@ gfxPangoFontGroup::SetGlyphs(gfxTextRun 
             if (aAbortOnMissingGlyph &&
                 (*clusterUTF8 != '\0' || clusterUTF8Length != 1)) {
                 return NS_ERROR_FAILURE;
             }
         } else {
             gunichar ch = g_utf8_get_char(clusterUTF8);
             do { // Does pango ever provide more than one glyph in the cluster
                  // if there is a missing glyph?
+		 // behdad: yes
                 if (IS_MISSING_GLYPH(glyphs[glyphIndex].glyph)) {
-                    if (MOZ_pango_is_zero_width(ch)) {
+                    if (pango_is_zero_width(ch)) {
                         // the zero width characters returns empty glyph ID at shaping,
                         // we should override it if the font has the character.
                         glyphs[glyphIndex].glyph = aFont->GetGlyph(' ');
                         glyphs[glyphIndex].geometry.width = 0;
                     } else
                         haveMissingGlyph = PR_TRUE;
                 }
                 glyphIndex++;
@@ -1251,25 +995,25 @@ gfxPangoFontGroup::SetMissingGlyphs(gfxT
         // We produced this UTF8 so we don't need to worry about malformed stuff
         index = g_utf8_next_char(aUTF8 + index) - aUTF8;
     }
 
     *aUTF16Offset = utf16Offset;
     return NS_OK;
 }
 
-#if defined(ENABLE_XFT_FAST_PATH_8BIT) || defined(ENABLE_XFT_FAST_PATH_ALWAYS)
+#if defined(ENABLE_FAST_PATH_8BIT) || defined(ENABLE_FAST_PATH_ALWAYS)
 void
-gfxPangoFontGroup::CreateGlyphRunsXft(gfxTextRun *aTextRun,
-                                      const gchar *aUTF8, PRUint32 aUTF8Length)
+gfxPangoFontGroup::CreateGlyphRunsFast(gfxTextRun *aTextRun,
+                                       const gchar *aUTF8, PRUint32 aUTF8Length)
 {
     const gchar *p = aUTF8;
-    Display *dpy = GDK_DISPLAY();
     gfxPangoFont *font = GetFontAt(0);
-    XftFont *xfont = font->GetXftFont();
+    PangoFont *pangofont = font->GetPangoFont();
+    PangoFcFont *fcfont = PANGO_FC_FONT (pangofont);
     PRUint32 utf16Offset = 0;
     gfxTextRun::CompressedGlyph g;
     const PRUint32 appUnitsPerDevUnit = aTextRun->GetAppUnitsPerDevUnit();
 
     aTextRun->AddGlyphRun(font, 0);
 
     while (p < aUTF8 + aUTF8Length) {
         // glib-2.12.9: "If p does not point to a valid UTF-8 encoded
@@ -1280,24 +1024,21 @@ gfxPangoFontGroup::CreateGlyphRunsXft(gf
         p = g_utf8_next_char(p);
         
         if (ch == 0) {
             // treat this null byte as a missing glyph. Pango
             // doesn't create glyphs for these, not even missing-glyphs.
             aTextRun->SetMissingGlyph(utf16Offset, 0);
         } else {
             NS_ASSERTION(!IsInvalidChar(ch), "Invalid char detected");
-            FT_UInt glyph = XftCharIndex(dpy, xfont, ch);
-            XGlyphInfo info;
-            XftGlyphExtents(dpy, xfont, &glyph, 1, &info);
-            if (info.yOff > 0) {
-                NS_WARNING("vertical offsets not supported");
-            }
+            FT_UInt glyph = pango_fc_font_get_glyph (fcfont, ch);
+            PangoRectangle rect;
+            pango_font_get_glyph_extents (pangofont, glyph, NULL, &rect);
 
-            PRInt32 advance = info.xOff*appUnitsPerDevUnit;
+            PRInt32 advance = PANGO_PIXELS (rect.width * appUnitsPerDevUnit);
             if (advance >= 0 &&
                 gfxTextRun::CompressedGlyph::IsSimpleAdvance(advance) &&
                 gfxTextRun::CompressedGlyph::IsSimpleGlyphID(glyph)) {
                 aTextRun->SetCharacterGlyph(utf16Offset,
                                             g.SetSimpleGlyph(advance, glyph));
             } else if (IS_MISSING_GLYPH(glyph)) {
                 // Note that missing-glyph IDs are not simple glyph IDs, so we'll
                 // always get here when a glyph is missing
@@ -1321,330 +1062,103 @@ gfxPangoFontGroup::CreateGlyphRunsXft(gf
             }
         }
 
         ++utf16Offset;
     }
 }
 #endif
 
-class FontSelector
+void 
+gfxPangoFontGroup::CreateGlyphRunsItemizing(gfxTextRun *aTextRun,
+                                            const gchar *aUTF8, PRUint32 aUTF8Length)
 {
-public:
-    FontSelector(const gchar *aString, PRInt32 aLength,
-                 gfxPangoFontGroup *aGroup, gfxTextRun *aTextRun,
-                 PangoItem *aItem, PRUint32 aUTF16Offset, PRPackedBool aIsRTL) :
-        mItem(aItem),
-        mGroup(aGroup), mTextRun(aTextRun), mString(aString),
-        mFontIndex(0), mLength(aLength), mUTF16Offset(aUTF16Offset),
-        mTriedPrefFonts(0), mTriedOtherFonts(0), mIsRTL(aIsRTL)
-    {
-        for (PRUint32 i = 0; i < mGroup->FontListLength(); ++i)
-            mFonts.AppendElement(mGroup->GetFontAt(i));
-        mSpaceWidth = NS_lround(mGroup->GetFontAt(0)->GetMetrics().spaceWidth * FLOAT_PANGO_SCALE);
-    }
-    
-    nsresult Run()
-    {
-        return InitSegments(mString, mLength);
-    }
-
-    PRUint32 GetUTF16Offset() { return mUTF16Offset; }
 
-    static PRBool ExistsFont(FontSelector *aFs,
-                             const nsAString &aName) {
-        PRUint32 len = aFs->mFonts.Length();
-        for (PRUint32 i = 0; i < len; ++i) {
-            if (aName.Equals(aFs->mFonts[i]->GetName()))
-                return PR_TRUE;
-        }
-        return PR_FALSE;
-    }
-
-    static PRBool AddFontCallback(const nsAString &aName,
-                                  const nsACString &aGenericName,
-                                  void *closure) {
-        if (aName.IsEmpty())
-            return PR_TRUE;
-
-        FontSelector *fs = static_cast<FontSelector*>(closure);
-
-        // XXX do something better than this to remove dups
-        if (ExistsFont(fs, aName))
-            return PR_TRUE;
-
-        nsRefPtr<gfxPangoFont> font = GetOrMakeFont(aName, fs->mGroup->GetStyle());
-        if (font) {
-            fs->mFonts.AppendElement(font);
-        }
-
-        return PR_TRUE;
-    }
-
-private:
-    PangoItem *mItem;
-
-    nsTArray< nsRefPtr<gfxPangoFont> > mFonts;
+    PangoContext *context = gdk_pango_context_get ();
 
-    gfxPangoFontGroup *mGroup;
-    gfxTextRun   *mTextRun;
-    const char        *mString; // UTF-8
-    PRUint32           mFontIndex;
-    PRInt32            mLength;
-    PRUint32           mUTF16Offset;
-    PRUint32           mSpaceWidth;
-
-    PRPackedBool mTriedPrefFonts;
-    PRPackedBool mTriedOtherFonts;
-    PRPackedBool mIsRTL;
-
-    nsresult InitSegments(const gchar *aUTF8, PRUint32 aLength) {
-        if (aLength == 0)
-            return NS_OK;
-        const gchar *start = aUTF8;
-        const gchar *last = start + aLength;
-
-RetryNextFont:
-        nsRefPtr<gfxPangoFont> font = GetNextFont();
-
-        // If we cannot found the font that has the current character glyph,
-        // we should return default font's missing data.
-        if (!font)
-            return AppendMissingSegment(start, last - start);
+    PangoFontDescription *fontDesc = pango_font_description_new();
 
-        nsresult rv;
-        for (const gchar *c = start; c < last;) {
-            // find the first missing glyph
-            gunichar u = g_utf8_get_char(c);
-            if (font->HasGlyph(PRUint32(u))) {
-                c = g_utf8_next_char(c);
-                continue;
-            }
-
-            // find the next point that can be renderd with current font
-            const gchar *missingStart = c;
-            const gchar *next;
-            for (next = g_utf8_next_char(missingStart); next < last; next = g_utf8_next_char(next)) {
-                u = g_utf8_get_char(next);
-                if (font->HasGlyph(PRUint32(u)))
-                    break;
-            }
+    // these should be FontEntries or something similar rather than gfxPangoFonts...
+    nsString fontList;
 
-            // current font has 0 glyphs for current segment, try with next font
-            if (missingStart == start && next == last)
-                goto RetryNextFont;
-
-            // create the segment for found glyphs
-            rv = AppendSegment(font, start, missingStart - start);
-            NS_ENSURE_SUCCESS(rv, rv);
-
-            // init the missing glyphs with remains fonts.
-            PRUint32 fontIndex = mFontIndex;
-            rv = InitSegments(missingStart, next - missingStart);
-            mFontIndex = fontIndex;
-            NS_ENSURE_SUCCESS(rv, rv);
-
-            start = c = next;
-        }
-
-        rv = AppendSegment(font, start, last - start);
-        NS_ENSURE_SUCCESS(rv, rv);
-        return NS_OK;
+    for (PRUint32 i = 0; i < mFonts.Length(); i++) {
+        fontList.Append(mFonts[i]->GetName());
+        fontList.Append(NS_LITERAL_STRING(", "));
     }
 
-    nsresult AppendSegment(gfxPangoFont* aFont, const gchar *aUTF8, PRUint32 aLength) {
-        if (aLength == 0)
-            return NS_OK;
-
-        PangoFont* pf = aFont->GetPangoFont();
-
-        PangoGlyphString *glyphString = pango_glyph_string_new();
-        if (!glyphString)
-            return NS_ERROR_OUT_OF_MEMORY;
-        PangoFont *tmpFont = mItem->analysis.font;
-        mItem->analysis.font = pf;
-        pango_shape(aUTF8, aLength, &mItem->analysis, glyphString);
-        mItem->analysis.font = tmpFont;
-
-        nsresult rv = mTextRun->AddGlyphRun(aFont, mUTF16Offset);
-        if (NS_FAILED(rv)) {
-            NS_ERROR("AddGlyphRun Failed");
-            pango_glyph_string_free(glyphString);
-            return rv;
-        }
-        PRUint32 utf16Offset = mUTF16Offset;
-        rv = mGroup->SetGlyphs(mTextRun, aFont, aUTF8, aLength,
-                               &utf16Offset, glyphString, mSpaceWidth, PR_FALSE);
-        pango_glyph_string_free(glyphString);
-        NS_ENSURE_SUCCESS(rv, rv);
-
-        mUTF16Offset = utf16Offset;
-        return NS_OK;
-    }
+    PangoLanguage *lang = GetPangoLanguage(GetStyle()->langGroup);
 
-    nsresult AppendMissingSegment(const gchar *aUTF8, PRUint32 aLength) {
-        if (aLength == 0)
-            return NS_OK;
-
-        nsresult rv = mTextRun->AddGlyphRun(mFonts[0], mUTF16Offset);
-        NS_ENSURE_SUCCESS(rv, rv);
-        PRUint32 utf16Offset = mUTF16Offset;
-        rv = mGroup->SetMissingGlyphs(mTextRun, aUTF8, aLength, &utf16Offset);
-        NS_ENSURE_SUCCESS(rv, rv);
-
-        mUTF16Offset = utf16Offset;
-        return NS_OK;
-    }
-
-    gfxPangoFont *GetNextFont() {
-TRY_AGAIN_HOPE_FOR_THE_BEST_2:
-        if (mFontIndex < mFonts.Length()) {
-            return mFonts[mFontIndex++];
-        } else if (!mTriedPrefFonts) {
-            mTriedPrefFonts = PR_TRUE;
-            nsCAutoString mozLang;
-            GetMozLanguage(mItem->analysis.language, mozLang);
-            if (!mozLang.IsEmpty()) {
-                PRInt32 index = GetCJKLangGroupIndex(mozLang.get());
-                if (index >= 0)
-                    AppendCJKPrefFonts();
-                else
-                    AppendPrefFonts(mozLang.get());
-            } else {
-                NS_ConvertUTF8toUTF16 str(mString);
-                PRBool appenedCJKFonts = PR_FALSE;
-                for (PRUint32 i = 0; i < str.Length(); ++i) {
-                    const PRUnichar ch = str[i];
-                    PRUint32 unicodeRange = FindCharUnicodeRange(ch);
+    pango_font_description_set_family(fontDesc, NS_ConvertUTF16toUTF8(fontList).get());
+    pango_font_description_set_absolute_size(fontDesc, GetStyle()->size * PANGO_SCALE);
+    pango_font_description_set_style(fontDesc, ThebesStyleToPangoStyle(GetStyle()));
+    pango_font_description_set_weight(fontDesc, ThebesStyleToPangoWeight(GetStyle()));
 
-                    /* special case CJK */
-                    if (unicodeRange == kRangeSetCJK) {
-                        if (!appenedCJKFonts) {
-                            appenedCJKFonts = PR_TRUE;
-                            AppendCJKPrefFonts();
-                        }
-                    } else {
-                        const char *langGroup =
-                            LangGroupFromUnicodeRange(unicodeRange);
-                        if (langGroup)
-                            AppendPrefFonts(langGroup);
-                    }
-                }
-            }
-            goto TRY_AGAIN_HOPE_FOR_THE_BEST_2;
-        } else if (!mTriedOtherFonts) {
-            mTriedOtherFonts = PR_TRUE;
-            // XXX we should try by all system fonts
-            goto TRY_AGAIN_HOPE_FOR_THE_BEST_2;
-        }
-        return nsnull;
-    }
-
-    void AppendPrefFonts(const char *aLangGroup) {
-        NS_ASSERTION(aLangGroup, "aLangGroup is null");
-        gfxPlatform *platform = gfxPlatform::GetPlatform();
-        nsString fonts;
-        platform->GetPrefFonts(aLangGroup, fonts);
-        if (fonts.IsEmpty())
-            return;
-        gfxFontGroup::ForEachFont(fonts, nsDependentCString(aLangGroup),
-                                  FontSelector::AddFontCallback, this);
-        return;
-   }
-
-   void AppendCJKPrefFonts() {
-       nsCOMPtr<nsIPrefService> prefs =
-           do_GetService(NS_PREFSERVICE_CONTRACTID);
-       if (!prefs)
-           return;
-
-       nsCOMPtr<nsIPrefBranch> prefBranch;
-       prefs->GetBranch(0, getter_AddRefs(prefBranch));
-       if (!prefBranch)
-           return;
+    pango_context_set_font_description(context, fontDesc);
 
-       // Add the accept languages.
-       nsXPIDLCString list;
-       nsresult rv = prefBranch->GetCharPref("intl.accept_languages",
-                                             getter_Copies(list));
-       if (NS_SUCCEEDED(rv) && !list.IsEmpty()) {
-           const char kComma = ',';
-           const char *p, *p_end;
-           list.BeginReading(p);
-           list.EndReading(p_end);
-           while (p < p_end) {
-               while (nsCRT::IsAsciiSpace(*p)) {
-                   if (++p == p_end)
-                       break;
-               }
-               if (p == p_end)
-                   break;
-               const char *start = p;
-               while (++p != p_end && *p != kComma)
-                   /* nothing */ ;
-               nsCAutoString lang(Substring(start, p));
-               lang.CompressWhitespace(PR_FALSE, PR_TRUE);
-               PRInt32 index = GetCJKLangGroupIndex(lang.get());
-               if (index >= 0)
-                   AppendPrefFonts(sCJKLangGroup[index]);
-               p++;
-           }
-       }
+    // we should set this to null if we don't have a text language from the page...
+    // except that we almost always have something...
+    pango_context_set_language(context, lang);
 
-       // XXX I think that we should append system locale here if it is CJK.
+    PangoDirection dir = aTextRun->IsRightToLeft() ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR;
+    GList *items = pango_itemize_with_base_dir(context, dir, aUTF8, 0, aUTF8Length, nsnull, nsnull);
 
-       // last resort...
-       AppendPrefFonts(CJK_LANG_JA);
-       AppendPrefFonts(CJK_LANG_KO);
-       AppendPrefFonts(CJK_LANG_ZH_CN);
-       AppendPrefFonts(CJK_LANG_ZH_HK);
-       AppendPrefFonts(CJK_LANG_ZH_TW);
-    }
-};
-
-void 
-gfxPangoFontGroup::CreateGlyphRunsItemizing(gfxTextRun *aTextRun,
-                                            const gchar *aUTF8, PRUint32 aUTF8Length,
-                                            PRUint32 aUTF8HeaderLen)
-{
-    GList *items = pango_itemize(GetFontAt(0)->GetPangoContext(), aUTF8, 0,
-                                 aUTF8Length, nsnull, nsnull);
-    
     PRUint32 utf16Offset = 0;
     PRBool isRTL = aTextRun->IsRightToLeft();
     GList *pos = items;
     for (; pos && pos->data; pos = pos->next) {
         PangoItem *item = (PangoItem *)pos->data;
         NS_ASSERTION(isRTL == item->analysis.level % 2, "RTL assumption mismatch");
 
         PRUint32 offset = item->offset;
         PRUint32 length = item->length;
-        if (offset < aUTF8HeaderLen) {
-            if (offset + length <= aUTF8HeaderLen) {
-                pango_item_free(item);
-                continue;
-            }
-            length -= aUTF8HeaderLen - offset;
-            offset = aUTF8HeaderLen;
+
+        // need to append glyph runs here.
+        PangoGlyphString *glyphString = pango_glyph_string_new();
+        if (!glyphString)
+            return; // OOM
+
+        pango_shape(aUTF8 + offset, length, &item->analysis, glyphString);
+
+        /* look up the gfxPangoFont from the PangoFont */
+        // XXX we need a function to do this.. until then do this
+        // behdad: use g_object_[sg]et_qdata() for it.
+        PangoFontDescription *d = pango_font_describe(item->analysis.font);
+        nsRefPtr<gfxPangoFont> font = GetOrMakeFont(NS_ConvertUTF8toUTF16(pango_font_description_get_family(d)), GetStyle());
+
+        //printf("Using %s\n", pango_font_description_get_family(d));
+
+        pango_font_description_free(d);
+        SetupClusterBoundaries(aTextRun, aUTF8 + offset, length, utf16Offset, &item->analysis);
+
+        nsresult rv = aTextRun->AddGlyphRun(font, utf16Offset, PR_TRUE);
+        if (NS_FAILED(rv)) {
+            NS_ERROR("AddGlyphRun Failed");
+            pango_glyph_string_free(glyphString);
+            return;
         }
-        
-        SetupClusterBoundaries(aTextRun, aUTF8 + offset, length, utf16Offset, &item->analysis);
-        FontSelector fs(aUTF8 + offset, length, this, aTextRun, item, utf16Offset, isRTL);
-        fs.Run(); // appends GlyphRuns
-        utf16Offset = fs.GetUTF16Offset();
-        pango_item_free(item);
+
+        PRUint32 spaceWidth = NS_lround(font->GetMetrics().spaceWidth * FLOAT_PANGO_SCALE);
+
+        rv = SetGlyphs(aTextRun, font, aUTF8 + offset, length, &utf16Offset, glyphString, spaceWidth, PR_FALSE);
+
+        pango_glyph_string_free(glyphString);
     }
 
-    NS_ASSERTION(utf16Offset == aTextRun->GetLength(),
-                 "Didn't resolve all characters");
-  
     if (items)
         g_list_free(items);
+
+    pango_font_description_free(fontDesc);
+
+    g_object_unref(context);
+
+    aTextRun->SortGlyphRuns();
 }
 
+
+
 /**
  ** language group helpers
  **/
 
 struct MozPangoLangGroup {
     const char *mozLangGroup;
     const char *PangoLang;
 };
@@ -1703,17 +1217,17 @@ GetPangoLanguage(const nsACString& cname
     //
     // we're casting away the const here for the strings - should be
     // safe.
     if (!langGroup)
         return pango_language_from_string(nsPromiseFlatCString(cname).get());
     else if (langGroup->PangoLang) 
         return pango_language_from_string(langGroup->PangoLang);
 
-    return pango_language_from_string("en");
+    return nsnull;
 }
 
 // See pango-script-lang-table.h in pango.
 static const MozPangoLangGroup PangoAllLangGroup[] = {
     { "x-western",      "aa"    },
     { "x-cyrillic",     "ab"    },
     { "x-western",      "af"    },
     { "x-ethi",         "am"    },
@@ -1887,48 +1401,17 @@ static const MozPangoLangGroup PangoAllL
     { "zh-CN",          "zh-cn" },
     { "zh-HK",          "zh-hk" },
     { "zh-HK",          "zh-mo" },
     { "zh-CN",          "zh-sg" },
     { "zh-TW",          "zh-tw" },
     { "x-western",      "zu"    },
 };
 
-#define NUM_PANGO_ALL_LANG_GROUPS (sizeof (PangoAllLangGroup) / \
-                                   sizeof (PangoAllLangGroup[0]))
-
-/* static */
-void
-GetMozLanguage(const PangoLanguage *aLang, nsACString &aMozLang)
-{
-    aMozLang.Truncate();
-    if (!aLang)
-        return;
-
-    nsCAutoString lang(pango_language_to_string(aLang));
-    if (lang.IsEmpty() || lang.Equals("xx"))
-        return;
-
-    while (1) {
-        for (PRUint32 i = 0; i < NUM_PANGO_ALL_LANG_GROUPS; ++i) {
-            if (lang.Equals(PangoAllLangGroup[i].PangoLang)) {
-                if (PangoAllLangGroup[i].mozLangGroup)
-                    aMozLang.Assign(PangoAllLangGroup[i].mozLangGroup);
-                return;
-            }
-        }
-
-        PRInt32 hyphen = lang.FindChar('-');
-        if (hyphen != kNotFound) {
-            lang.Cut(hyphen, lang.Length());
-            continue;
-        }
-        break;
-    }
-}
+#define NUM_PANGO_ALL_LANG_GROUPS (G_N_ELEMENTS (PangoAllLangGroup))
 
 gfxPangoFontCache::gfxPangoFontCache()
 {
     mPangoFonts.Init(500);
 }
 
 gfxPangoFontCache::~gfxPangoFontCache()
 {
@@ -1952,44 +1435,8 @@ gfxPangoFontCache::Get(const PangoFontDe
     PRUint32 key = pango_font_description_hash(aFontDesc);
     gfxPangoFontWrapper *value;
     if (!mPangoFonts.Get(key, &value))
         return nsnull;
     PangoFont *font = value->Get();
     g_object_ref(font);
     return font;
 }
-
-gfxPangoFontNameMap::gfxPangoFontNameMap()
-{
-    mPangoFonts.Init(100);
-}
-
-gfxPangoFontNameMap::~gfxPangoFontNameMap()
-{
-}
-
-void
-gfxPangoFontNameMap::Put(const nsACString &aName, PangoFont *aPangoFont)
-{
-    nsCAutoString key(aName);
-    ToLowerCase(key);
-    gfxPangoFontWrapper *value;
-    if (!mPangoFonts.Get(key, &value)) {
-        value = new gfxPangoFontWrapper(aPangoFont);
-        if (!value)
-            return;
-        mPangoFonts.Put(key, value);
-    }
-}
-
-PangoFont*
-gfxPangoFontNameMap::Get(const nsACString &aName)
-{
-    nsCAutoString key(aName);
-    ToLowerCase(key);
-    gfxPangoFontWrapper *value;
-    if (!mPangoFonts.Get(key, &value))
-        return nsnull;
-    PangoFont *font = value->Get();
-    g_object_ref(font);
-    return font;
-}
--- a/gfx/thebes/src/gfxPlatformGtk.cpp
+++ b/gfx/thebes/src/gfxPlatformGtk.cpp
@@ -55,22 +55,16 @@
 
 #ifdef MOZ_ENABLE_GLITZ
 #include "gfxGlitzSurface.h"
 #include "glitz-glx.h"
 #endif
 
 #include <fontconfig/fontconfig.h>
 
-#ifndef THEBES_USE_PANGO_CAIRO
-#include <pango/pangoxft.h>
-#endif // THEBES_USE_PANGO_CAIRO
-
-#include <pango/pango-font.h>
-
 #include "nsMathUtils.h"
 
 #include "lcms.h"
 
 PRInt32 gfxPlatformGtk::sDPI = -1;
 gfxFontconfigUtils *gfxPlatformGtk::sFontconfigUtils = nsnull;
 
 static cairo_user_data_key_t cairo_gdk_window_key;
@@ -84,29 +78,27 @@ static void do_gdk_pixmap_unref (void *d
 gfxPlatformGtk::gfxPlatformGtk()
 {
 #ifdef MOZ_ENABLE_GLITZ
     if (UseGlitz())
         glitz_glx_init(NULL);
 #endif
     if (!sFontconfigUtils)
         sFontconfigUtils = gfxFontconfigUtils::GetFontconfigUtils();
+
+    InitDPI();
 }
 
 gfxPlatformGtk::~gfxPlatformGtk()
 {
     gfxFontconfigUtils::Shutdown();
     sFontconfigUtils = nsnull;
 
     gfxPangoFont::Shutdown();
 
-#ifndef THEBES_USE_PANGO_CAIRO
-    pango_xft_shutdown_display(GDK_DISPLAY(), 0);
-#endif
-
 #if 0
     // It would be nice to do this (although it might need to be after
     // the cairo shutdown that happens in ~gfxPlatform).  It even looks
     // idempotent.  But it has fatal assertions that fire if stuff is
     // leaked, and we hit them.
     FcFini();
 #endif
 }
@@ -273,103 +265,27 @@ gfxPlatformGtk::ResolveFontName(const ns
 
 gfxFontGroup *
 gfxPlatformGtk::CreateFontGroup(const nsAString &aFamilies,
                                 const gfxFontStyle *aStyle)
 {
     return new gfxPangoFontGroup(aFamilies, aStyle);
 }
 
-static PRInt32
-GetXftDPI()
-{
-  char *val = XGetDefault(GDK_DISPLAY(), "Xft", "dpi");
-  if (val) {
-    char *e;
-    double d = strtod(val, &e);
-
-    if (e != val)
-      return NS_lround(d);
-  }
-
-  return -1;
-}
-
-static PRInt32
-GetDPIFromPangoFont()
-{
-#ifndef THEBES_USE_PANGO_CAIRO
-    PangoContext* ctx = pango_xft_get_context(GDK_DISPLAY(), 0);
-    gdk_pango_context_set_colormap(ctx, gdk_rgb_get_cmap());
-#else
-    PangoContext* ctx =
-        pango_cairo_font_map_create_context(
-          PANGO_CAIRO_FONT_MAP(pango_cairo_font_map_get_default()));
-#endif
-
-    if (!ctx) {
-        return 0;
-    }
-
-    double dblDPI = 0.0f;
-    GList *items = nsnull;
-    PangoItem *item = nsnull;
-    PangoFcFont *fcfont = nsnull;
-    
-    PangoAttrList *al = pango_attr_list_new();
-
-    if (!al) {
-        goto cleanup;
-    }
-
-    // Just using the string "a" because we need _some_ text.
-    items = pango_itemize(ctx, "a", 0, 1, al, NULL);
-
-    if (!items) {
-        goto cleanup;
-    }
-
-    item = (PangoItem*)items->data;
-
-    if (!item) {
-        goto cleanup;
-    }
-
-    fcfont = PANGO_FC_FONT(item->analysis.font);
-
-    if (!fcfont) {
-        goto cleanup;
-    }
-
-    FcPatternGetDouble(fcfont->font_pattern, FC_DPI, 0, &dblDPI);
-
- cleanup:   
-    if (al)
-        pango_attr_list_unref(al);
-    if (item)
-        pango_item_free(item);
-    if (items)
-        g_list_free(items);
-    if (ctx)
-        g_object_unref(ctx);
-
-    return NS_lround(dblDPI);
-}
-
 /* static */
 void
 gfxPlatformGtk::InitDPI()
 {
-    sDPI = GetXftDPI();
+    PangoContext *context = gdk_pango_context_get ();
+    sDPI = pango_cairo_context_get_resolution (context);
+    g_object_unref (context);
+
     if (sDPI <= 0) {
-        sDPI = GetDPIFromPangoFont();
-        if (sDPI <= 0) {
-            // Fall back to something sane
-            sDPI = 96;
-        }
+	// Fall back to something sane
+	sDPI = 96;
     }
 }
 
 cmsHPROFILE
 gfxPlatformGtk::GetPlatformCMSOutputProfile()
 {
     const char EDID1_ATOM_NAME[] = "XFree86_DDC_EDID1_RAWDATA";
     const char ICC_PROFILE_ATOM_NAME[] = "_ICC_PROFILE";