]> git.pld-linux.org Git - packages/firefox.git/commitdiff
- outdated
authorJakub Bogusz <qboosh@pld-linux.org>
Thu, 24 Jul 2008 18:14:22 +0000 (18:14 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    mozilla-firefox-fonts.patch -> 1.3
    mozilla-firefox-lib_path.patch -> 1.4
    mozilla-firefox-myspell.patch -> 1.4
    mozilla-firefox-pango-cursor-position-more.patch -> 1.2
    mozilla-firefox-pango-cursor-position.patch -> 1.2
    mozilla-firefox-pango-justified-range.patch -> 1.2
    mozilla-firefox-pango-ligatures.patch -> 1.3
    mozilla-firefox-pango-printing.patch -> 1.2
    mozilla-firefox-pango-underline.patch -> 1.2
    mozilla-firefox-xft-randewidth.patch -> 1.2

mozilla-firefox-fonts.patch [deleted file]
mozilla-firefox-lib_path.patch [deleted file]
mozilla-firefox-myspell.patch [deleted file]
mozilla-firefox-pango-cursor-position-more.patch [deleted file]
mozilla-firefox-pango-cursor-position.patch [deleted file]
mozilla-firefox-pango-justified-range.patch [deleted file]
mozilla-firefox-pango-ligatures.patch [deleted file]
mozilla-firefox-pango-printing.patch [deleted file]
mozilla-firefox-pango-underline.patch [deleted file]
mozilla-firefox-xft-randewidth.patch [deleted file]

diff --git a/mozilla-firefox-fonts.patch b/mozilla-firefox-fonts.patch
deleted file mode 100644 (file)
index 61ece27..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
---- mozilla.orig/modules/libpref/src/init/all.js       2006-05-08 22:22:51.000000000 +0200
-+++ mozilla/modules/libpref/src/init/all.js    2006-07-25 07:44:06.744790000 +0200
-@@ -1886,33 +1886,33 @@
- // th
--pref("font.name.serif.tr", "Times");
--pref("font.name.sans-serif.tr", "Helvetica");
--pref("font.name.monospace.tr", "Courier");
-+pref("font.name.serif.tr", "serif");
-+pref("font.name.sans-serif.tr", "sans-serif");
-+pref("font.name.monospace.tr", "monospace");
- pref("font.name.serif.x-baltic", "serif");
- pref("font.name.sans-serif.x-baltic", "sans-serif");
- pref("font.name.monospace.x-baltic", "monospace");
--pref("font.name.serif.x-central-euro", "Times");
--pref("font.name.sans-serif.x-central-euro", "Helvetica");
--pref("font.name.monospace.x-central-euro", "Courier");
-+pref("font.name.serif.x-central-euro", "serif");
-+pref("font.name.sans-serif.x-central-euro", "sans-serif");
-+pref("font.name.monospace.x-central-euro", "monospace");
- pref("font.name.serif.x-cyrillic", "serif");
- pref("font.name.sans-serif.x-cyrillic", "sans-serif");
- pref("font.name.monospace.x-cyrillic", "monospace");
--pref("font.name.serif.x-unicode", "Times");
--pref("font.name.sans-serif.x-unicode", "Helvetica");
--pref("font.name.monospace.x-unicode", "Courier");
--
--pref("font.name.serif.x-user-def", "Times");
--pref("font.name.sans-serif.x-user-def", "Helvetica");
--pref("font.name.monospace.x-user-def", "Courier");
--
--pref("font.name.serif.x-western", "Times");
--pref("font.name.sans-serif.x-western", "Helvetica");
--pref("font.name.monospace.x-western", "Courier");
-+pref("font.name.serif.x-unicode", "serif");
-+pref("font.name.sans-serif.x-unicode", "sans-serif");
-+pref("font.name.monospace.x-unicode", "monospace");
-+
-+pref("font.name.serif.x-user-def", "serif");
-+pref("font.name.sans-serif.x-user-def", "sans-serif");
-+pref("font.name.monospace.x-user-def", "monospace");
-+
-+pref("font.name.serif.x-western", "serif");
-+pref("font.name.sans-serif.x-western", "sans-serif");
-+pref("font.name.monospace.x-western", "monospace");
- pref("font.name.serif.zh-CN", "serif");
- pref("font.name.sans-serif.zh-CN", "sans-serif");
-@@ -1989,63 +1989,63 @@
- pref("font.default.ar", "sans-serif");
- pref("font.size.variable.ar", 16);
--pref("font.size.fixed.ar", 12);
-+pref("font.size.fixed.ar", 14);
--pref("font.default.el", "serif");
-+pref("font.default.el", "sans-serif");
- pref("font.size.variable.el", 16);
--pref("font.size.fixed.el", 12);
-+pref("font.size.fixed.el", 14);
- pref("font.default.he", "sans-serif");
- pref("font.size.variable.he", 16);
--pref("font.size.fixed.he", 12);
-+pref("font.size.fixed.he", 14);
- pref("font.default.ja", "sans-serif");
- pref("font.size.variable.ja", 16);
--pref("font.size.fixed.ja", 16);
-+pref("font.size.fixed.ja", 14);
- pref("font.default.ko", "sans-serif");
- pref("font.size.variable.ko", 16);
--pref("font.size.fixed.ko", 16);
-+pref("font.size.fixed.ko", 14);
--pref("font.default.th", "serif");
-+pref("font.default.th", "sans-serif");
- pref("font.size.variable.th", 16);
--pref("font.size.fixed.th", 12);
-+pref("font.size.fixed.th", 14);
--pref("font.default.tr", "serif");
-+pref("font.default.tr", "sans-serif");
- pref("font.size.variable.tr", 16);
--pref("font.size.fixed.tr", 12);
-+pref("font.size.fixed.tr", 14);
--pref("font.default.x-baltic", "serif");
-+pref("font.default.x-baltic", "sans-serif");
- pref("font.size.variable.x-baltic", 16);
--pref("font.size.fixed.x-baltic", 12);
-+pref("font.size.fixed.x-baltic", 14);
--pref("font.default.x-central-euro", "serif");
-+pref("font.default.x-central-euro", "sans-serif");
- pref("font.size.variable.x-central-euro", 16);
--pref("font.size.fixed.x-central-euro", 12);
-+pref("font.size.fixed.x-central-euro", 14);
--pref("font.default.x-cyrillic", "serif");
-+pref("font.default.x-cyrillic", "sans-serif");
- pref("font.size.variable.x-cyrillic", 16);
--pref("font.size.fixed.x-cyrillic", 12);
-+pref("font.size.fixed.x-cyrillic", 14);
--pref("font.default.x-unicode", "serif");
-+pref("font.default.x-unicode", "sans-serif");
- pref("font.size.variable.x-unicode", 16);
--pref("font.size.fixed.x-unicode", 12);
-+pref("font.size.fixed.x-unicode", 14);
--pref("font.default.x-western", "serif");
-+pref("font.default.x-western", "sans-serif");
- pref("font.size.variable.x-western", 16);
--pref("font.size.fixed.x-western", 12);
-+pref("font.size.fixed.x-western", 14);
- pref("font.default.zh-CN", "sans-serif");
- pref("font.size.variable.zh-CN", 16);
--pref("font.size.fixed.zh-CN", 16);
-+pref("font.size.fixed.zh-CN", 14);
- pref("font.default.zh-TW", "sans-serif");
- pref("font.size.variable.zh-TW", 16);
--pref("font.size.fixed.zh-TW", 16);
-+pref("font.size.fixed.zh-TW", 14);
- pref("font.default.zh-HK", "sans-serif");
- pref("font.size.variable.zh-HK", 16);
--pref("font.size.fixed.zh-HK", 16);
-+pref("font.size.fixed.zh-HK", 14);
- // below a certian pixel size outline scaled fonts produce poor results
- pref("font.scale.outline.min",      6);
diff --git a/mozilla-firefox-lib_path.patch b/mozilla-firefox-lib_path.patch
deleted file mode 100644 (file)
index fe55ee4..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-diff -ur firefox.orig/config/autoconf.mk.in firefox/config/autoconf.mk.in
---- firefox.orig/config/autoconf.mk.in 2004-03-21 03:31:17.000000000 +0100
-+++ firefox/config/autoconf.mk.in      2004-06-17 09:50:30.000000000 +0200
-@@ -37,7 +37,7 @@
- mandir                = @mandir@
- idldir                = @datadir@/idl/$(MOZ_APP_NAME)-$(MOZ_APP_VERSION)
--mozappdir     = $(libdir)/$(MOZ_APP_NAME)-$(MOZ_APP_VERSION)
-+mozappdir     = $(libdir)/mozilla-$(MOZ_APP_NAME)
- mredir                = $(libdir)/mre/mre-$(MOZ_APP_VERSION)
- mrelibdir     = $(mredir)/lib
diff --git a/mozilla-firefox-myspell.patch b/mozilla-firefox-myspell.patch
deleted file mode 100644 (file)
index 45902a3..0000000
+++ /dev/null
@@ -1,222 +0,0 @@
---- firefox-2.0+0dfsg.orig/extensions/spellcheck/myspell/src/Makefile.in
-+++ firefox-2.0+0dfsg/extensions/spellcheck/myspell/src/Makefile.in
-@@ -60,15 +60,18 @@
-                 xulapp \
-                 $(NULL)
--CPPSRCS =         affentry.cpp \
-+CPPSRCS =         mozMySpell.cpp \
-+                mozMySpellFactory.cpp \
-+                  $(NULL)
-+ifndef MOZ_NATIVE_MYSPELL
-+CPPSRCS +=      affentry.cpp \
-                 affixmgr.cpp \
-                 hashmgr.cpp \
-                 suggestmgr.cpp \
-                 csutil.cpp \
-                 myspell.cpp \
--                mozMySpell.cpp \
--                mozMySpellFactory.cpp \
-                   $(NULL)
-+endif
- ifdef MOZ_XUL_APP
- CPPSRCS += mozMySpellDirProvider.cpp
-@@ -79,6 +82,7 @@
-               $(XPCOM_LIBS) \
-               $(NSPR_LIBS) \
-               $(MOZ_UNICHARUTIL_LIBS) \
-+              $(MOZ_MYSPELL_LIBS) \
-               $(NULL)
- include $(topsrcdir)/config/rules.mk
---- firefox-2.0+0dfsg.orig/configure
-+++ firefox-2.0+0dfsg/configure
-@@ -60,6 +60,8 @@
-   --with-system-png[=PFX]
-                           Use system libpng [installed at prefix PFX]"
- ac_help="$ac_help
-+  --enable-system-myspell   Use system myspell (located with pkgconfig)"
-+ac_help="$ac_help
-   --with-java-include-path=dir   Location of Java SDK headers"
- ac_help="$ac_help
-   --with-java-bin-path=dir   Location of Java binaries (java, javac, jar)"
-@@ -12011,6 +11953,116 @@
- fi # SKIP_LIBRARY_CHECKS
-+# Check whether --enable-system-myspell or --disable-system-myspell was given.
-+if test "${enable_system_myspell+set}" = set; then
-+  enableval="$enable_system_myspell"
-+  if test "$enableval" = "yes"; then
-+    SYSTEM_MYSPELL=1 
-+  elif test "$enableval" = "no"; then
-+    :
-+  else
-+    { echo "configure: error: Option, system-myspell, does not take an argument ($enableval)." 1>&2; exit 1; }
-+  fi
-+fi
-+
-+
-+if test -n "$SYSTEM_MYSPELL"; then
-+    
-+  succeeded=no
-+
-+  if test -z "$PKG_CONFIG"; then
-+    # Extract the first word of "pkg-config", so it can be a program name with args.
-+set dummy pkg-config; ac_word=$2
-+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-+echo "configure:11978: checking for $ac_word" >&5
-+if eval "test \"`echo '$''{'ac_cv_path_PKG_CONFIG'+set}'`\" = set"; then
-+  echo $ac_n "(cached) $ac_c" 1>&6
-+else
-+  case "$PKG_CONFIG" in
-+  /*)
-+  ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
-+  ;;
-+  ?:/*)                        
-+  ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a dos path.
-+  ;;
-+  *)
-+  IFS="${IFS=         }"; ac_save_ifs="$IFS"; IFS=":"
-+  ac_dummy="$PATH"
-+  for ac_dir in $ac_dummy; do 
-+    test -z "$ac_dir" && ac_dir=.
-+    if test -f $ac_dir/$ac_word; then
-+      ac_cv_path_PKG_CONFIG="$ac_dir/$ac_word"
-+      break
-+    fi
-+  done
-+  IFS="$ac_save_ifs"
-+  test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no"
-+  ;;
-+esac
-+fi
-+PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
-+if test -n "$PKG_CONFIG"; then
-+  echo "$ac_t""$PKG_CONFIG" 1>&6
-+else
-+  echo "$ac_t""no" 1>&6
-+fi
-+
-+  fi
-+
-+  if test "$PKG_CONFIG" = "no" ; then
-+     echo "*** The pkg-config script could not be found. Make sure it is"
-+     echo "*** in your path, or set the PKG_CONFIG environment variable"
-+     echo "*** to the full path to pkg-config."
-+     echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config."
-+  else
-+     PKG_CONFIG_MIN_VERSION=0.9.0
-+     if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then
-+        echo $ac_n "checking for myspell""... $ac_c" 1>&6
-+echo "configure:12022: checking for myspell" >&5
-+
-+        if $PKG_CONFIG --exists "myspell" ; then
-+            echo "$ac_t""yes" 1>&6
-+            succeeded=yes
-+
-+            echo $ac_n "checking MOZ_MYSPELL_CFLAGS""... $ac_c" 1>&6
-+echo "configure:12029: checking MOZ_MYSPELL_CFLAGS" >&5
-+            MOZ_MYSPELL_CFLAGS=`$PKG_CONFIG --cflags "myspell"`
-+            echo "$ac_t""$MOZ_MYSPELL_CFLAGS" 1>&6
-+
-+            echo $ac_n "checking MOZ_MYSPELL_LIBS""... $ac_c" 1>&6
-+echo "configure:12034: checking MOZ_MYSPELL_LIBS" >&5
-+            ## don't use --libs since that can do evil things like add
-+            ## -Wl,--export-dynamic
-+            MOZ_MYSPELL_LIBS="`$PKG_CONFIG --libs-only-L \"myspell\"` `$PKG_CONFIG --libs-only-l \"myspell\"`"
-+            echo "$ac_t""$MOZ_MYSPELL_LIBS" 1>&6
-+        else
-+            MOZ_MYSPELL_CFLAGS=""
-+            MOZ_MYSPELL_LIBS=""
-+            ## If we have a custom action on failure, don't print errors, but 
-+            ## do set a variable so people can do so.
-+            MOZ_MYSPELL_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "myspell"`
-+            echo $MOZ_MYSPELL_PKG_ERRORS
-+        fi
-+
-+        
-+        
-+     else
-+        echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer."
-+        echo "*** See http://www.freedesktop.org/software/pkgconfig"
-+     fi
-+  fi
-+
-+  if test $succeeded = yes; then
-+     :
-+  else
-+     { echo "configure: error: Library requirements (myspell) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them." 1>&2; exit 1; }
-+  fi
-+
-+fi
-+
-+
-+
-+
- JAVA_INCLUDE_PATH=
- # Check whether --with-java-include-path or --without-java-include-path was given.
- if test "${with_java_include_path+set}" = set; then
-@@ -20291,10 +20347,13 @@
- s%@NSS_CONFIG@%$NSS_CONFIG%g
- s%@NSS_CFLAGS@%$NSS_CFLAGS%g
- s%@NSS_LIBS@%$NSS_LIBS%g
-+s%@PKG_CONFIG@%$PKG_CONFIG%g
-+s%@MOZ_MYSPELL_CFLAGS@%$MOZ_MYSPELL_CFLAGS%g
-+s%@MOZ_MYSPELL_LIBS@%$MOZ_MYSPELL_LIBS%g
-+s%@SYSTEM_MYSPELL@%$SYSTEM_MYSPELL%g
- s%@GTK_CONFIG@%$GTK_CONFIG%g
- s%@GTK_CFLAGS@%$GTK_CFLAGS%g
- s%@GTK_LIBS@%$GTK_LIBS%g
--s%@PKG_CONFIG@%$PKG_CONFIG%g
- s%@MOZ_GTK2_CFLAGS@%$MOZ_GTK2_CFLAGS%g
- s%@MOZ_GTK2_LIBS@%$MOZ_GTK2_LIBS%g
- s%@HOST_MOC@%$HOST_MOC%g
---- firefox-2.0+0dfsg.orig/configure.in
-+++ firefox-2.0+0dfsg/configure.in
-@@ -3840,6 +3870,19 @@
- fi # SKIP_LIBRARY_CHECKS
-+dnl system MySpell Support
-+dnl ========================================================
-+MOZ_ARG_ENABLE_BOOL(system-myspell,
-+[  --enable-system-myspell   Use system myspell (located with pkgconfig)],
-+    SYSTEM_MYSPELL=1 )
-+
-+if test -n "$SYSTEM_MYSPELL"; then
-+    PKG_CHECK_MODULES(MOZ_MYSPELL, myspell)
-+fi
-+
-+AC_SUBST(SYSTEM_MYSPELL)
-+AC_SUBST(MOZ_MYSPELL_LIBS)
-+
- dnl ========================================================
- dnl Java SDK support
- dnl ========================================================
---- firefox-2.0+0dfsg.orig/config/autoconf.mk.in
-+++ firefox-2.0+0dfsg/config/autoconf.mk.in
-@@ -190,6 +190,9 @@
- NECKO_SMALL_BUFFERS = @NECKO_SMALL_BUFFERS@
- NECKO_COOKIES = @NECKO_COOKIES@
-+MOZ_NATIVE_MYSPELL = @SYSTEM_MYSPELL@
-+MOZ_MYSPELL_LIBS = @MOZ_MYSPELL_LIBS@
-+
- MOZ_NATIVE_ZLIB       = @SYSTEM_ZLIB@
- MOZ_NATIVE_JPEG       = @SYSTEM_JPEG@
- MOZ_NATIVE_PNG        = @SYSTEM_PNG@
---- mozilla/toolkit/content/inlineSpellCheckUI.js~     2006-11-27 23:43:52.000000000 +0200
-+++ mozilla/toolkit/content/inlineSpellCheckUI.js      2007-03-05 00:41:13.030876638 +0200
-@@ -202,6 +166,10 @@
-     for (var i = 0; i < list.length; i ++) {
-       // get the display name for this dictionary
-       isoStrArray = list[i].split("-");
-+        // if we can't split by Mozilla locale names (en-US), try system separator (en_US)
-+        if (isoStrArray.length < 2) {
-+                isoStrArray = list[i].split("_");
-+        }
-       var displayName = "";
-       if (this.mLanguageBundle && isoStrArray[0]) {
-         try {
diff --git a/mozilla-firefox-pango-cursor-position-more.patch b/mozilla-firefox-pango-cursor-position-more.patch
deleted file mode 100644 (file)
index ef5b967..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-diff -pruN -x '.moz*' -x .deps -x 'firefox*' -x '*.mk' -x 'config*' -x dist -x build -x toolkit -x '*o' -x '*a' -x '*html' mozilla.orig/layout/generic/nsTextFrame.cpp mozilla/layout/generic/nsTextFrame.cpp
---- mozilla.orig/layout/generic/nsTextFrame.cpp        2006-08-26 13:33:35.000000000 +0900
-+++ mozilla/layout/generic/nsTextFrame.cpp     2006-12-13 20:54:32.000000000 +0900
-@@ -4261,12 +4261,10 @@ nsTextFrame::GetPointFromOffset(nsPresCo
-       if (tc) {
-         totalLength = tc->Text()->GetLength(); // raw value which includes whitespace
-       }
--      if ((hitLength == textLength) && (inOffset = mContentLength) &&
--          (mContentOffset + mContentLength == totalLength)) {
--        // no need to re-measure when at the end of the last-in-flow
--      }
-+      if (hitLength > 0)
-+      inRendContext->GetRangeWidth(paintBuffer.mBuffer, textLength, 0, hitLength, (PRUint32&)width);
-       else
--        inRendContext->GetWidth(paintBuffer.mBuffer, hitLength, width);
-+      width = 0;
-     }
-     if ((hitLength == textLength) && (TEXT_TRIMMED_WS & mState)) {
-       //
diff --git a/mozilla-firefox-pango-cursor-position.patch b/mozilla-firefox-pango-cursor-position.patch
deleted file mode 100644 (file)
index d287fd3..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-Index: mozilla/gfx/src/gtk/nsFontMetricsPango.cpp
-===================================================================
-RCS file: /cvsroot/mozilla/gfx/src/gtk/nsFontMetricsPango.cpp,v
-retrieving revision 1.24
-diff -d -u -p -6 -r1.24 nsFontMetricsPango.cpp
---- mozilla/gfx/src/gtk/nsFontMetricsPango.cpp 25 Aug 2006 01:02:34 -0000      1.24
-+++ mozilla/gfx/src/gtk/nsFontMetricsPango.cpp 6 Sep 2006 07:01:49 -0000
-@@ -948,13 +948,12 @@ nsFontMetricsPango::GetClusterInfo(const
- PRInt32
- nsFontMetricsPango::GetPosition(const PRUnichar *aText, PRUint32 aLength,
-                                 nsPoint aPt)
- {
-     int trailing = 0;
-     int inx = 0;
--    gboolean found = FALSE;
-     const gchar *curChar;
-     PRInt32 retval = 0;
-     float f = mDeviceContext->AppUnitsToDevUnits();
-     
-     PangoLayout *layout = pango_layout_new(mPangoContext);
-@@ -974,28 +973,18 @@ nsFontMetricsPango::GetPosition(const PR
-     }
-     // Set up the pango layout
-     pango_layout_set_text(layout, text, strlen(text));
-     FixupSpaceWidths(layout, text);
-     
--    found = pango_layout_xy_to_index(layout, localX, localY,
--                                     &inx, &trailing);
-+    pango_layout_xy_to_index(layout, localX, localY,
-+                             &inx, &trailing);
-     // Convert the index back to the utf-16 index
-     curChar = text;
--    // Jump to the end if it's not found.
--    if (!found) {
--        if (inx == 0)
--            retval = 0;
--        else if (trailing)
--            retval = aLength;
--
--        goto loser;
--    }
--
-     for (PRUint32 curOffset=0; curOffset < aLength;
-          curOffset++, curChar = g_utf8_find_next_char(curChar, NULL)) {
-         // Check for a match before checking for a surrogate pair
-         if (curChar - text == inx) {
-             retval = curOffset;
diff --git a/mozilla-firefox-pango-justified-range.patch b/mozilla-firefox-pango-justified-range.patch
deleted file mode 100644 (file)
index 7614d0e..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-diff -pruN -x '.moz*' -x .deps -x 'thunderbird*' -x '*.mk' -x 'config*' -x dist -x build -x toolkit -x '*o' -x '*a' -x '*html' -x 'firefox*' mozilla.orig/layout/generic/nsTextFrame.cpp mozilla/layout/generic/nsTextFrame.cpp
---- mozilla.orig/layout/generic/nsTextFrame.cpp        2006-12-20 12:15:38.000000000 +0900
-+++ mozilla/layout/generic/nsTextFrame.cpp     2006-12-20 21:29:39.000000000 +0900
-@@ -2973,15 +2973,16 @@ nsTextFrame::RenderString(nsIRenderingCo
-   nsIFontMetrics* lastFont = aTextStyle.mLastFont;
-   PRInt32 pendingCount;
--  PRUnichar* runStart = bp;
-+  PRUnichar* runStart = bp, *top = aBuffer;
-   nscoord charWidth, width = 0;
-   PRInt32 countSoFar = 0;
-+  PRUint32 offset;
-   // Save the color we want to use for the text, since calls to
-   // PaintTextDecorations in this method will call SetColor() on the rendering
-   // context.
-   nscolor textColor;
-   aRenderingContext.GetColor(textColor);
--  for (; --aLength >= 0; aBuffer++) {
-+  for (offset = 0; offset < aLength; aBuffer++, offset++) {
-     nsIFontMetrics* nextFont;
-     nscoord glyphWidth = 0;
-     PRUnichar ch = *aBuffer;
-@@ -3038,7 +3039,7 @@ nsTextFrame::RenderString(nsIRenderingCo
-     else if (ch == ' ') {
-       glyphWidth += aTextStyle.mSpaceWidth + aTextStyle.mWordSpacing + aTextStyle.mLetterSpacing;
-     }
--    else if (IS_HIGH_SURROGATE(ch) && aLength > 0 &&
-+    else if (IS_HIGH_SURROGATE(ch) && (offset + 1) < aLength &&
-            IS_LOW_SURROGATE(*(aBuffer+1))) {
-       
-       // special handling for surrogate pair
-@@ -3046,7 +3047,7 @@ nsTextFrame::RenderString(nsIRenderingCo
-       glyphWidth += charWidth + aTextStyle.mLetterSpacing;
-       // copy the surrogate low
-       *bp++ = ch;
--      --aLength;
-+      offset++;
-       aBuffer++;
-       ch = *aBuffer;
-       // put the width into the space buffer
-@@ -3058,10 +3059,10 @@ nsTextFrame::RenderString(nsIRenderingCo
-       glyphWidth = 0;
-     }
-     else {
--      aRenderingContext.GetWidth(ch, charWidth);
-+      aRenderingContext.GetRangeWidth(top, aLength, offset, offset + 1, (PRUint32&)charWidth);
-       glyphWidth += charWidth + aTextStyle.mLetterSpacing;
-     }
--    if (justifying && (!isEndOfLine || aLength > 0)
-+    if (justifying && (!isEndOfLine || (offset + 1) < aLength)
-         && IsJustifiableCharacter(ch, isCJ)) {
-       glyphWidth += aTextStyle.mExtraSpacePerJustifiableCharacter;
-       if ((PRUint32)--aTextStyle.mNumJustifiableCharacterToRender
diff --git a/mozilla-firefox-pango-ligatures.patch b/mozilla-firefox-pango-ligatures.patch
deleted file mode 100644 (file)
index 0d45dd9..0000000
+++ /dev/null
@@ -1,1934 +0,0 @@
---- mozilla.back/gfx/src/gtk/nsFontMetricsPango.cpp.orig       2007-06-28 14:44:31.000000000 +0200
-+++ mozilla.back/gfx/src/gtk/nsFontMetricsPango.cpp    2007-06-28 15:48:04.000000000 +0200
-@@ -21,6 +21,8 @@
-  * are Copyright (C) 2004 the Initial Developer. All Rights Reserved.
-  *
-  * Contributor(s):
-+ *   Christopher Blizzard <blizzard@mozilla.org>
-+ *   Behdad Esfahbod <behdad@behdad.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
-@@ -36,6 +38,10 @@
-  *
-  * ***** END LICENSE BLOCK ***** */
-+#define PANGO_ENABLE_BACKEND
-+
-+#include "nsFontMetricsPango.h"
-+
- #include <strings.h>
- #include "nsFont.h"
- #include "nsIDeviceContext.h"
-@@ -43,27 +49,37 @@
- #include "nsIPref.h"
- #include "nsServiceManagerUtils.h"
--#define PANGO_ENABLE_BACKEND
--#define PANGO_ENABLE_ENGINE
--
--#include "nsFontMetricsPango.h"
--#include "nsRenderingContextGTK.h"
--#include "nsDeviceContextGTK.h"
- #include "nsFontConfigUtils.h"
- #include "nsUnicharUtils.h"
- #include "nsQuickSort.h"
- #include "nsFontConfigUtils.h"
-+#include "mozilla-decoder.h"
-+
-+#define FORCE_PR_LOG
-+#include "prlog.h"
-+
- #include <fontconfig/fontconfig.h>
-+#include <freetype/tttables.h>
-+
-+#include <pango/pango.h>
-+#include <pango/pangofc-font.h>
-+
-+#ifdef PSPANGO
-+#include <pango/pangoft2.h>
-+#include "nsRenderingContextPS.h"
-+#include "nsDeviceContextPS.h"
-+#include "nsType1.h"
-+#else
- #include <gdk/gdk.h>
- #include <gdk/gdkx.h>
--#include <freetype/tttables.h>
-+#include "nsRenderingContextGTK.h"
-+#include "nsDeviceContextGTK.h"
-+#endif
-+
--#include "mozilla-decoder.h"
--#define FORCE_PR_LOG
--#include "prlog.h"
- // Globals
-@@ -108,6 +124,49 @@ static nsresult    EnumFontsPango   (nsI
-                                      PRUint32* aCount, PRUnichar*** aResult);
- static int         CompareFontNames (const void* aArg1, const void* aArg2,
-                                      void* aClosure);
-+static void  utf16_to_utf8 (const PRUnichar* aString, PRUint32 aLength,
-+                            char *&text, gint &text_len);
-+
-+#ifdef PSPANGO
-+static void
-+default_substitute (FcPattern *pattern,
-+                    gpointer   data)
-+{
-+  FcPatternDel (pattern, FC_HINTING);
-+  FcPatternAddBool (pattern, FC_HINTING, 0);
-+}
-+#endif
-+
-+static PangoFontMap *
-+get_fontmap (void)
-+{
-+  static PangoFontMap               *fontmap = NULL;
-+
-+  if (!fontmap) {
-+#ifdef PSPANGO
-+    fontmap = pango_ft2_font_map_new ();
-+    pango_ft2_font_map_set_resolution ((PangoFT2FontMap *)fontmap, 72., 72.);
-+    pango_ft2_font_map_set_default_substitute ((PangoFT2FontMap *)fontmap, default_substitute, NULL, NULL);
-+#else
-+    PangoContext* context = gdk_pango_context_get ();
-+    fontmap = pango_context_get_font_map (context);
-+    g_object_unref (context);
-+#endif
-+  }
-+
-+  return fontmap;
-+}
-+
-+static PangoContext *
-+get_context (void)
-+{
-+#ifdef PSPANGO
-+  return pango_ft2_font_map_create_context ((PangoFT2FontMap *) get_fontmap ());
-+#else
-+  return gdk_pango_context_get();
-+#endif
-+}
-+
- nsFontMetricsPango::nsFontMetricsPango()
- {
-@@ -169,15 +228,21 @@
-     mLangGroup = aLangGroup;
-     // Hang on to the device context
-+#ifdef PSPANGO
-+    mDeviceContext = (nsDeviceContextPS *)aContext;
-+#else
-     mDeviceContext = aContext;
--    
-+#endif
-+
-     mPointSize = NSTwipsToFloatPoints(mFont.size);
-+#ifndef PSPANGO
-     // Make sure to clamp the pixel size to something reasonable so we
-     // don't make the X server blow up.
-     nscoord screenPixels = gdk_screen_height();
-     mPointSize = PR_MIN((screenPixels - 1) * FONT_MAX_FONT_SCALE, mPointSize);
-     mPointSize = PR_MIN(2000, mPointSize);
-+#endif
-     // enumerate over the font names passed in
-     mFont.EnumerateFamilies(nsFontMetricsPango::EnumFontCallback, this);
-@@ -329,7 +394,7 @@ nsFontMetricsPango::CacheFontMetrics(voi
-     // mPangoSpaceWidth
-     PangoLayout *layout = pango_layout_new(mPangoContext);
--    pango_layout_set_text(layout, " ", 1);
-+    pango_layout_set_text(layout, " ", -1);
-     int pswidth, psheight;
-     pango_layout_get_size(layout, &pswidth, &psheight);
-     mPangoSpaceWidth = pswidth;
-@@ -337,14 +402,14 @@ nsFontMetricsPango::CacheFontMetrics(voi
-     // mSpaceWidth (width of a space)
-     nscoord tmpWidth;
--    GetWidth(" ", 1, tmpWidth, NULL);
-+    GetWidth(" ", 1, tmpWidth CONTEXT_ARG_NULL);
-     mSpaceWidth = tmpWidth;
-     // mAveCharWidth (width of an 'average' char)
-     //    XftTextExtents16(GDK_DISPLAY(), xftFont, &xUnichar, 1, &extents);
-     //rawWidth = extents.width;
-     //mAveCharWidth = NSToCoordRound(rawWidth * f);
--    GetWidth("x", 1, tmpWidth, NULL);
-+    GetWidth("x", 1, tmpWidth CONTEXT_ARG_NULL);
-     mAveCharWidth = tmpWidth;
-     // mXHeight (height of an 'x' character)
-@@ -460,130 +525,96 @@ nsFontMetricsPango::GetFontHandle(nsFont
- // nsIFontMetricsPango impl
--nsresult
--nsFontMetricsPango::GetWidth(const char* aString, PRUint32 aLength,
--                             nscoord& aWidth,
--                             nsRenderingContextGTK *aContext)
-+#ifdef PSPANGO
-+NS_IMETHODIMP
-+nsFontMetricsPSPango::GetStringWidth(const char *String,nscoord &aWidth,nscoord aLength)
- {
--    PangoLayout *layout = pango_layout_new(mPangoContext);
--
--    pango_layout_set_text(layout, aString, aLength);
-+    return GetWidth (String, (PRUint32) aLength, aWidth CONTEXT_ARG_NULL);
-+}
--    if (mPangoSpaceWidth)
--        FixupSpaceWidths(layout, aString);
-+NS_IMETHODIMP
-+nsFontMetricsPSPango::GetStringWidth(const PRUnichar *aString,nscoord &aWidth,nscoord aLength)
-+{
-+    return GetWidth (aString, (PRUint32)aLength, aWidth, NULL CONTEXT_ARG_NULL);
-+}
-+#endif
-+nsresult
-+nsFontMetricsPango::GetWidth(const char* aString, PRUint32 aLength,
-+                             nscoord& aWidth
-+                             CONTEXT_ARG_DEF)
-+{
-     int width, height;
--
-+    PangoLayout *layout = GetLayout(aString, aLength);
-     pango_layout_get_size(layout, &width, &height);
--
-     g_object_unref(layout);
--    float f;
--    f = mDeviceContext->DevUnitsToAppUnits();
-+    float f = mDeviceContext->DevUnitsToAppUnits();
-     aWidth = NSToCoordRound(width * f / PANGO_SCALE);
--    //    printf("GetWidth (char *) %d\n", aWidth);
--
-     return NS_OK;
- }
- nsresult
- nsFontMetricsPango::GetWidth(const PRUnichar* aString, PRUint32 aLength,
--                             nscoord& aWidth, PRInt32 *aFontID,
--                             nsRenderingContextGTK *aContext)
-+                             nscoord& aWidth, PRInt32 *aFontID
-+                             CONTEXT_ARG_DEF)
- {
--    nsresult rv = NS_OK;
--    PangoLayout *layout = pango_layout_new(mPangoContext);
--
--    gchar *text = g_utf16_to_utf8(aString, aLength,
--                                  NULL, NULL, NULL);
--
--    if (!text) {
--        aWidth = 0;
--#ifdef DEBUG
--        NS_WARNING("nsFontMetricsPango::GetWidth invalid unicode to follow");
--        DUMP_PRUNICHAR(aString, aLength)
--#endif
--        rv = NS_ERROR_FAILURE;
--        goto loser;
--    }
--
-     gint width, height;
--
--    pango_layout_set_text(layout, text, strlen(text));
--    FixupSpaceWidths(layout, text);
-+    PangoLayout *layout = GetLayout(aString, aLength);
-     pango_layout_get_size(layout, &width, &height);
-+    g_object_unref(layout);
--    float f;
--    f = mDeviceContext->DevUnitsToAppUnits();
-+    float f = mDeviceContext->DevUnitsToAppUnits();
-     aWidth = NSToCoordRound(width * f / PANGO_SCALE);
--    //    printf("GetWidth %d\n", aWidth);
--
-- loser:
--    g_free(text);
--    g_object_unref(layout);
--
--    return rv;
-+    return NS_OK;
- }
- nsresult
--nsFontMetricsPango::GetTextDimensions(const PRUnichar* aString,
-+nsFontMetricsPango::GetTextDimensions(const char* aString,
-                                       PRUint32 aLength,
--                                      nsTextDimensions& aDimensions, 
--                                      PRInt32* aFontID,
--                                      nsRenderingContextGTK *aContext)
-+                                      nsTextDimensions& aDimensions
-+                                      CONTEXT_ARG_DEF)
- {
--    nsresult rv = NS_OK;
--
--    PangoLayout *layout = pango_layout_new(mPangoContext);
-+    PangoLayout *layout = GetLayout(aString, aLength);
-+    PangoLayoutLine *line = pango_layout_get_line(layout, 0);
--    gchar *text = g_utf16_to_utf8(aString, aLength,
--                                  NULL, NULL, NULL);
--
--    if (!text) {
--#ifdef DEBUG
--        NS_WARNING("nsFontMetricsPango::GetTextDimensions invalid unicode to follow");
--        DUMP_PRUNICHAR(aString, aLength)
--#endif
--        aDimensions.width = 0;
--        aDimensions.ascent = 0;
--        aDimensions.descent = 0;
--
--        rv = NS_ERROR_FAILURE;
--        goto loser;
--    }
--        
-+    PangoRectangle logical;
-+    pango_layout_line_get_extents(line, NULL, &logical);
-+    g_object_unref(layout);
--    pango_layout_set_text(layout, text, strlen(text));
--    FixupSpaceWidths(layout, text);
-+    float P2T = mDeviceContext->DevUnitsToAppUnits();
--    // Get the logical extents
--    PangoLayoutLine *line;
--    if (pango_layout_get_line_count(layout) != 1) {
--        printf("Warning: more than one line!\n");
--    }
--    line = pango_layout_get_line(layout, 0);
-+    aDimensions.ascent  = NSToCoordRound(PANGO_ASCENT(logical)  * P2T / PANGO_SCALE);
-+    aDimensions.descent = NSToCoordRound(PANGO_DESCENT(logical) * P2T / PANGO_SCALE);
-+    aDimensions.width   = NSToCoordRound(logical.width          * P2T / PANGO_SCALE);
--    PangoRectangle rect;
--    pango_layout_line_get_extents(line, NULL, &rect);
-+    return NS_OK;
-+}
--    float P2T;
--    P2T = mDeviceContext->DevUnitsToAppUnits();
-+nsresult
-+nsFontMetricsPango::GetTextDimensions(const PRUnichar* aString,
-+                                      PRUint32 aLength,
-+                                      nsTextDimensions& aDimensions, 
-+                                      PRInt32* aFontID
-+                                      CONTEXT_ARG_DEF)
-+{
-+    PangoLayout *layout = GetLayout(aString, aLength);
-+    PangoLayoutLine *line = pango_layout_get_line(layout, 0);
--    aDimensions.width = NSToCoordRound(rect.width * P2T / PANGO_SCALE);
--    aDimensions.ascent = NSToCoordRound(PANGO_ASCENT(rect) * P2T / PANGO_SCALE);
--    aDimensions.descent = NSToCoordRound(PANGO_DESCENT(rect) * P2T / PANGO_SCALE);
-+    PangoRectangle logical;
-+    pango_layout_line_get_extents(line, NULL, &logical);
-+    g_object_unref(layout);
--    //    printf("GetTextDimensions %d %d %d\n", aDimensions.width,
--    //aDimensions.ascent, aDimensions.descent);
-+    float P2T = mDeviceContext->DevUnitsToAppUnits();
-- loser:
--    g_free(text);
--    g_object_unref(layout);
-+    aDimensions.ascent  = NSToCoordRound(PANGO_ASCENT(logical)  * P2T / PANGO_SCALE);
-+    aDimensions.descent = NSToCoordRound(PANGO_DESCENT(logical) * P2T / PANGO_SCALE);
-+    aDimensions.width   = NSToCoordRound(logical.width          * P2T / PANGO_SCALE);
--    return rv;
-+    return NS_OK;
- }
- nsresult
-@@ -595,13 +626,13 @@ nsFontMetricsPango::GetTextDimensions(co
-                                       nsTextDimensions&   aDimensions,
-                                       PRInt32&            aNumCharsFit,
-                                       nsTextDimensions&   aLastWordDimensions,
--                                      PRInt32*            aFontID,
--                                      nsRenderingContextGTK *aContext)
-+                                      PRInt32*            aFontID
-+                                      CONTEXT_ARG_DEF)
- {
-     return GetTextDimensionsInternal(aString, aLength, aAvailWidth, aBreaks,
-                                      aNumBreaks, aDimensions, aNumCharsFit,
--                                     aLastWordDimensions, aContext);
-+                                     aLastWordDimensions CONTEXT_ARG_PASS);
- }
-@@ -614,8 +645,8 @@ nsFontMetricsPango::GetTextDimensions(co
-                                       nsTextDimensions&   aDimensions,
-                                       PRInt32&            aNumCharsFit,
-                                       nsTextDimensions&   aLastWordDimensions,
--                                      PRInt32*            aFontID,
--                                      nsRenderingContextGTK *aContext)
-+                                      PRInt32*            aFontID
-+                                      CONTEXT_ARG_DEF)
- {
-     nsresult rv = NS_OK;
-     PRInt32 curBreak = 0;
-@@ -623,23 +654,15 @@ nsFontMetricsPango::GetTextDimensions(co
-     PRInt32 *utf8Breaks = new PRInt32[aNumBreaks];
--    gchar *text = g_utf16_to_utf8(aString, (PRInt32)aLength,
--                                  NULL, NULL, NULL);
-+    gchar* text;
-+    gint text_len;
-+    utf16_to_utf8 (aString, aLength, text, text_len);
-     curChar = text;
--    if (!text) {
--#ifdef DEBUG
--        NS_WARNING("nsFontMetricsPango::GetWidth invalid unicode to follow");
--        DUMP_PRUNICHAR(aString, (PRUint32)aLength)
--#endif
--        rv = NS_ERROR_FAILURE;
--        goto loser;
--    }
--
-     // Covert the utf16 break offsets to utf8 break offsets
-     for (PRInt32 curOffset=0; curOffset < aLength;
--         curOffset++, curChar = g_utf8_find_next_char(curChar, NULL)) {
-+         curOffset++, curChar = g_utf8_next_char(curChar)) {
-         if (aBreaks[curBreak] == curOffset) {
-             utf8Breaks[curBreak] = curChar - text;
-             curBreak++;
-@@ -653,10 +676,10 @@ nsFontMetricsPango::GetTextDimensions(co
-     utf8Breaks[curBreak] = curChar - text;
- #if 0
--    if (strlen(text) != aLength) {
--        printf("Different lengths for utf16 %d and utf8 %d\n", aLength, strlen(text));
-+    if (text_len != aLength) {
-+        printf("Different lengths for utf16 %d and utf8 %d\n", aLength, text_len);
-         DUMP_PRUNICHAR(aString, aLength)
--        DUMP_PRUNICHAR(text, strlen(text))
-+        DUMP_PRUNICHAR(text, text_len)
-         for (PRInt32 i = 0; i < aNumBreaks; ++i) {
-             printf("  break %d utf16 %d utf8 %d\n", i, aBreaks[i], utf8Breaks[i]);
-         }
-@@ -666,9 +689,9 @@ nsFontMetricsPango::GetTextDimensions(co
-     // We'll use curBreak to indicate which of the breaks end up being
-     // used for the break point for this line.
-     curBreak = 0;
--    rv = GetTextDimensionsInternal(text, strlen(text), aAvailWidth, utf8Breaks,
-+    rv = GetTextDimensionsInternal(text, text_len, aAvailWidth, utf8Breaks,
-                                    aNumBreaks, aDimensions, aNumCharsFit,
--                                   aLastWordDimensions, aContext);
-+                                   aLastWordDimensions CONTEXT_ARG_PASS);
-     // Figure out which of the breaks we ended up using to convert
-     // back to utf16 - start from the end.
-@@ -681,200 +704,365 @@ nsFontMetricsPango::GetTextDimensions(co
-         }
-     }
-- loser:
--    if (text)
--        g_free(text);
-+    g_free(text);
-     delete[] utf8Breaks;
-     return rv;
- }
--nsresult
--nsFontMetricsPango::DrawString(const char *aString, PRUint32 aLength,
--                               nscoord aX, nscoord aY,
--                               const nscoord* aSpacing,
--                               nsRenderingContextGTK *aContext,
--                               nsDrawingSurfaceGTK *aSurface)
-+#ifdef PSPANGO
-+
-+typedef struct _nsPSPangoRenderer        nsPSPangoRenderer;
-+typedef struct _nsPSPangoRendererClass   nsPSPangoRendererClass;
-+
-+struct _nsPSPangoRenderer
- {
--    PangoLayout *layout = pango_layout_new(mPangoContext);
-+  PangoRenderer parent_instance;
-+  nsRenderingContextPS *psContext;
-+  nsFontMetricsPSPango *psPangoFontMetrics;
-+  float zoom;
-+};
--    pango_layout_set_text(layout, aString, aLength);
--    FixupSpaceWidths(layout, aString);
-+struct _nsPSPangoRendererClass
-+{
-+  PangoRendererClass parent_class;
-+};
--    int x = aX;
--    int y = aY;
-+#define _PS_TYPE_PANGO_RENDERER            (_ps_pango_renderer_get_type())
-+#define _PS_PANGO_RENDERER(object)         (G_TYPE_CHECK_INSTANCE_CAST ((object), _PS_TYPE_PANGO_RENDERER, _nsPSPangoRenderer))
-+#define _PS_IS_PANGO_RENDERER(object)      (G_TYPE_CHECK_INSTANCE_TYPE ((object), _PS_TYPE_PANGO_RENDERER))
-+#define _PS_PANGO_RENDERER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), _PS_TYPE_PANGO_RENDERER, _nsPSPangoRendererClass))
-+#define _PS_IS_PANGO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), _PS_TYPE_PANGO_RENDERER))
-+#define _PS_PANGO_RENDERER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), _PS_TYPE_PANGO_RENDERER, _nsPSPangoRendererClass))
--    aContext->GetTranMatrix()->TransformCoord(&x, &y);
-+G_DEFINE_TYPE (_nsPSPangoRenderer, _ps_pango_renderer, PANGO_TYPE_RENDERER)
--    PangoLayoutLine *line;
--    if (pango_layout_get_line_count(layout) != 1) {
--        printf("Warning: more than one line!\n");
--    }
--    line = pango_layout_get_line(layout, 0);
-+static PangoRenderer *
-+get_renderer (void)
-+{
-+  static PangoRenderer               *renderer = NULL;
--    aContext->UpdateGC();
--    GdkGC *gc = aContext->GetGC();
-+  if (!renderer)
-+    renderer = (PangoRenderer *) g_object_new (_PS_TYPE_PANGO_RENDERER, NULL);
--    if (aSpacing && *aSpacing) {
--        DrawStringSlowly(aString, NULL, aLength, aSurface->GetDrawable(),
--                         gc, x, y, line, aSpacing);
--    }
--    else {
--        gdk_draw_layout_line(aSurface->GetDrawable(), gc,
--                             x, y,
--                             line);
--    }
-+  return renderer;
-+}
--    g_object_unref(gc);
--    g_object_unref(layout);
-+static void
-+_ps_pango_renderer_draw_glyphs (PangoRenderer    *renderer,
-+                              PangoFont        *font,
-+                              PangoGlyphString *glyphs,
-+                              int               x,
-+                              int               y);
--    //    printf("DrawString (char *)\n");
-+static void
-+_ps_pango_renderer_class_init (nsPSPangoRendererClass *klass)
-+{
-+  PangoRendererClass *renderer_class = PANGO_RENDERER_CLASS (klass);
-+  
-+  renderer_class->draw_glyphs = _ps_pango_renderer_draw_glyphs;
-+}
--    return NS_OK;
-+static void
-+_ps_pango_renderer_init (nsPSPangoRenderer *renderer)
-+{
-+}
-+
-+class nsPangoType1Generator : public nsPSFontGenerator {
-+public:
-+  nsPangoType1Generator();
-+  ~nsPangoType1Generator();
-+  nsresult Init(PangoFont *aFont);
-+  void  GeneratePSFont(FILE* aFile);
-+
-+protected:
-+  PangoFont *mFont;
-+};
-+
-+nsPangoType1Generator::nsPangoType1Generator()
-+{
- }
- nsresult
--nsFontMetricsPango::DrawString(const PRUnichar* aString, PRUint32 aLength,
--                               nscoord aX, nscoord aY,
--                               PRInt32 aFontID,
--                               const nscoord* aSpacing,
--                               nsRenderingContextGTK *aContext,
--                               nsDrawingSurfaceGTK *aSurface)
-+nsPangoType1Generator::Init(PangoFont *aFont)
-+  {
-+  NS_ENSURE_TRUE(aFont, NS_ERROR_FAILURE);
-+  mFont = aFont;
-+  g_object_ref (mFont);
-+  return NS_OK;
-+}
-+
-+nsPangoType1Generator::~nsPangoType1Generator()
- {
--    nsresult rv = NS_OK;
--    int x = aX;
--    int y = aY;
-+  g_object_unref (mFont);
-+  mFont = nsnull;
-+}
--    aContext->UpdateGC();
--    GdkGC *gc = aContext->GetGC();
-+void nsPangoType1Generator::GeneratePSFont(FILE* aFile)
-+{
-+  FT_Face face = pango_fc_font_lock_face ((PangoFcFont *) mFont);
--    PangoLayout *layout = pango_layout_new(mPangoContext);
-+  if (face == nsnull)
-+    return;
--    gchar *text = g_utf16_to_utf8(aString, aLength,
--                                  NULL, NULL, NULL);
-+  int wmode = 0;
-+  if (mGlyphSubset->Count())
-+    FT2SubsetToType1FontSet(face, mGlyphSubset, wmode, aFile);
--    if (!text) {
--#ifdef DEBUG
--        NS_WARNING("nsFontMetricsPango::DrawString invalid unicode to follow");
--        DUMP_PRUNICHAR(aString, aLength)
--#endif
--        rv = NS_ERROR_FAILURE;
--        goto loser;
--    }
-+ pango_fc_font_unlock_face ((PangoFcFont *) mFont);
-+}
--    pango_layout_set_text(layout, text, strlen(text));
--    FixupSpaceWidths(layout, text);
-+typedef struct
-+{
-+  nsCString    *FontNameBase;
-+  nsCStringKey *key;
-+  int           font_size;
-+} PSPangoFontData;
--    aContext->GetTranMatrix()->TransformCoord(&x, &y);
-+static void
-+ps_pango_font_data_destroy (PSPangoFontData *data)
-+{
-+  delete data->key;
-+  delete data->FontNameBase;
-+  g_free (data);
-+}
--    PangoLayoutLine *line;
--    if (pango_layout_get_line_count(layout) != 1) {
--        printf("Warning: more than one line!\n");
--    }
--    line = pango_layout_get_line(layout, 0);
-+static void
-+_ps_pango_renderer_draw_glyphs (PangoRenderer    *renderer,
-+                              PangoFont        *font,
-+                              PangoGlyphString *glyphs,
-+                              int               x,
-+                              int               y)
-+{
-+  if (!glyphs->num_glyphs)
-+    return;
--    if (aSpacing && *aSpacing) {
--        DrawStringSlowly(text, aString, aLength, aSurface->GetDrawable(),
--                         gc, x, y, line, aSpacing);
--    }
--    else {
--        gdk_draw_layout_line(aSurface->GetDrawable(), gc,
--                             x, y,
--                             line);
--    }
-+  static GQuark data_quark = 0;
-+  if (!data_quark)
-+    data_quark = g_quark_from_static_string ("ps-pango-font-data");
-- loser:
-+  PSPangoFontData *data;
-+  if (!(data = (PSPangoFontData *) g_object_get_qdata (G_OBJECT (font), data_quark)))
-+    {
-+      data = g_new (PSPangoFontData, 1);
--    g_free(text);
--    g_object_unref(gc);
--    g_object_unref(layout);
-+      FT_Face face = pango_fc_font_lock_face ((PangoFcFont *) font);
-+      if (face == nsnull)
-+        return;
-+      int wmode = 0;
-+      data->FontNameBase = new nsCString ();
-+      if (NS_FAILED(FT2ToType1FontName(face, wmode, *data->FontNameBase))) {
-+        g_free (data);
-+        pango_fc_font_unlock_face ((PangoFcFont *) font);
-+        return;
-+      }
-+      pango_fc_font_unlock_face ((PangoFcFont *) font);
--    //    printf("DrawString\n");
-+      PangoFontDescription *desc = pango_font_describe (font);
-+      data->font_size = pango_font_description_get_size (desc);
-+      pango_font_description_free (desc);
-+
-+      data->key = new nsCStringKey (*data->FontNameBase);
-+
-+      g_object_set_qdata_full (G_OBJECT (font), data_quark, data, (GDestroyNotify) ps_pango_font_data_destroy);
-+    }
-+
-+  nsPSPangoRenderer *ps_renderer = (nsPSPangoRenderer *)renderer;
-+  nsRenderingContextPS *aContext = ps_renderer->psContext;
-+  nsFontMetricsPSPango *metrics = ps_renderer->psPangoFontMetrics;
-+  nsDeviceContextPS* dc = NS_REINTERPRET_CAST (nsDeviceContextPS*, metrics->GetDeviceContext());
-+  nsPostScriptObj* psObj = aContext->GetPostScriptObj();
-+  nsHashtable *psFGList = dc->GetPSFontGeneratorList();
-+  g_return_if_fail (psFGList);
-+  nsPSFontGenerator* psFontGen = (nsPSFontGenerator*) psFGList->Get(data->key);
-+  if (!psFontGen) {
-+    nsresult rv;
-+    psFontGen = new nsPangoType1Generator;
-+    g_return_if_fail (psFontGen);
-+    rv = ((nsPangoType1Generator*)psFontGen)->Init(font);
-+    if (NS_FAILED(rv)) {
-+      delete psFontGen;
-+      return;
-+    }
-+    psFGList->Put(data->key, (void *) psFontGen);
-+  }
-+  nscoord font_size = NSToCoordRound (ps_renderer->zoom * data->font_size / PANGO_SCALE);
-+
-+  g_return_if_fail (aContext);
-+  g_return_if_fail (psObj);
-+
-+  nscoord aX = NSToCoordRound(ps_renderer->zoom * x / PANGO_SCALE);
-+  nscoord aY = NSToCoordRound(ps_renderer->zoom * y / PANGO_SCALE);
-+  psObj->moveto(aX, aY);
-+
-+  PRInt32 currSubFont, prevSubFont = -1;
-+  PRUint32 i;
-+  PangoGlyphString gl;
-+
-+  gl.glyphs = glyphs->glyphs;
-+  gl.num_glyphs = 0;
-+  currSubFont = prevSubFont;
-+  for (i = 0; i < glyphs->num_glyphs; ++i) {
-+    PangoGlyph glyph = glyphs->glyphs[i].glyph;
-+
-+    if (glyph != PANGO_GLYPH_EMPTY)
-+      currSubFont = psFontGen->AddToGlyphSubset(glyph > 0x0fffffff ? 0 : glyph);
-+
-+    if (prevSubFont != currSubFont) {
-+      if (prevSubFont != -1)
-+        psObj->show(&gl, ps_renderer->zoom,  psFontGen, prevSubFont);
-+
-+      psObj->setfont(*data->FontNameBase, (PRUint32) font_size, currSubFont);
-+      prevSubFont = currSubFont;
-+      gl.glyphs = glyphs->glyphs + i;
-+      gl.num_glyphs = 0;
-+    }
--    return rv;
-+    gl.num_glyphs++;
-+  }
-+
-+  if (prevSubFont != -1)
-+    psObj->show(&gl, ps_renderer->zoom, psFontGen, prevSubFont);
- }
-+#endif
-+
-+static void
-+draw_layout_line (int x, int y,
-+                  PangoLayoutLine *line,
-+                  nsFontMetricsPango *fm
-+                  CONTEXT_AND_SURFACE_ARG_DEF)
-+{
-+#ifdef PSPANGO
-+  PangoRenderer *renderer = get_renderer ();
-+  nsPSPangoRenderer *ps_renderer = (nsPSPangoRenderer *)renderer;
-+  ps_renderer->psContext = aContext;
-+  ps_renderer->psPangoFontMetrics = fm;
-+  nsDeviceContextPS* dc = NS_REINTERPRET_CAST (nsDeviceContextPS*, fm->GetDeviceContext());
-+  ps_renderer->zoom = dc->DevUnitsToAppUnits();
-+
-+  pango_renderer_draw_layout_line (renderer, line,
-+                                   NSToCoordRound (x * PANGO_SCALE / ps_renderer->zoom),
-+                                   NSToCoordRound (y * PANGO_SCALE / ps_renderer->zoom));
-+#else
-+    aContext->UpdateGC();
-+    GdkGC *gc = aContext->GetGC();
-+    gdk_draw_layout_line(aSurface->GetDrawable(), gc, x, y, line);
-+    g_object_unref(gc);
-+#endif
-+}
-+
--#ifdef MOZ_MATHML
- nsresult
--nsFontMetricsPango::GetBoundingMetrics(const char *aString, PRUint32 aLength,
--                                       nsBoundingMetrics &aBoundingMetrics,
--                                       nsRenderingContextGTK *aContext)
-+nsFontMetricsPango::DrawString(const char *aString, PRUint32 aLength,
-+                               nscoord aX, nscoord aY,
-+                               const nscoord* aSpacing
-+                               CONTEXT_AND_SURFACE_ARG_DEF)
- {
--    printf("GetBoundingMetrics (char *)\n");
--    return NS_ERROR_FAILURE;
-+    int x = aX;
-+    int y = aY;
-+
-+    aContext->GetTranMatrix()->TransformCoord(&x, &y);
-+
-+    PangoLayout *layout = GetLayout(aString, aLength);
-+    PangoLayoutLine *line = pango_layout_get_line(layout, 0);
-+
-+    ApplySpacing(aString, aLength, line, aSpacing);
-+    draw_layout_line(x, y, line, this CONTEXT_AND_SURFACE_ARG_PASS);
-+
-+    g_object_unref(layout);
-+
-+    return NS_OK;
- }
- nsresult
--nsFontMetricsPango::GetBoundingMetrics(const PRUnichar *aString,
--                                       PRUint32 aLength,
--                                       nsBoundingMetrics &aBoundingMetrics,
--                                       PRInt32 *aFontID,
--                                       nsRenderingContextGTK *aContext)
-+nsFontMetricsPango::DrawString(const PRUnichar* aString, PRUint32 aLength,
-+                               nscoord aX, nscoord aY,
-+                               PRInt32 aFontID,
-+                               const nscoord* aSpacing
-+                               CONTEXT_AND_SURFACE_ARG_DEF)
- {
--    nsresult rv = NS_OK;
--    PangoLayout *layout = pango_layout_new(mPangoContext);
-+    int x = aX;
-+    int y = aY;
--    gchar *text = g_utf16_to_utf8(aString, aLength,
--                                  NULL, NULL, NULL);
-+    aContext->GetTranMatrix()->TransformCoord(&x, &y);
--    if (!text) {
--#ifdef DEBUG
--        NS_WARNING("nsFontMetricsPango::GetBoundingMetrics invalid unicode to follow");
--        DUMP_PRUNICHAR(aString, aLength)
--#endif
--        aBoundingMetrics.Clear();
-+    PangoLayout *layout = GetLayout(aString, aLength);
-+    PangoLayoutLine *line = pango_layout_get_line(layout, 0);
--        rv = NS_ERROR_FAILURE;
--        goto loser;
--    }
-+    ApplySpacing(aString, aLength, line, aSpacing);
-+    draw_layout_line(x, y, line, this CONTEXT_AND_SURFACE_ARG_PASS);
--    pango_layout_set_text(layout, text, -1);
--    FixupSpaceWidths(layout, text);
-+    g_object_unref(layout);
-+
-+    return NS_OK;
-+}
--    PangoLayoutLine *line;
--    if (pango_layout_get_line_count(layout) != 1) {
--        printf("Warning: more than one line!\n");
--    }
--    line = pango_layout_get_line(layout, 0);
-+
-+#ifdef MOZ_MATHML
-+void
-+nsFontMetricsPango::GetBoundingMetricsInternal(PangoLayout *aLayout,
-+                                               nsBoundingMetrics &aBoundingMetrics
-+                                               CONTEXT_ARG_DEF)
-+{
-+    PangoLayoutLine *line = pango_layout_get_line(aLayout, 0);
-     // Get the ink and logical extents
-     PangoRectangle ink, logical;
-     pango_layout_line_get_extents(line, &ink, &logical);
--    float P2T;
--    P2T = mDeviceContext->DevUnitsToAppUnits();
-+    float P2T = mDeviceContext->DevUnitsToAppUnits();
-     aBoundingMetrics.leftBearing  = NSToCoordRound(PANGO_LBEARING(ink) * P2T / PANGO_SCALE);
-     aBoundingMetrics.rightBearing = NSToCoordRound(PANGO_RBEARING(ink) * P2T / PANGO_SCALE);
-     aBoundingMetrics.ascent       = NSToCoordRound(PANGO_ASCENT(ink)   * P2T / PANGO_SCALE);
-     aBoundingMetrics.descent      = NSToCoordRound(PANGO_DESCENT(ink)  * P2T / PANGO_SCALE);
-     aBoundingMetrics.width        = NSToCoordRound(logical.width       * P2T / PANGO_SCALE);
-+}
-- loser:
--    g_free(text);
-+nsresult
-+nsFontMetricsPango::GetBoundingMetrics(const char *aString, PRUint32 aLength,
-+                                       nsBoundingMetrics &aBoundingMetrics
-+                                       CONTEXT_ARG_DEF)
-+{
-+    PangoLayout *layout = GetLayout(aString, aLength);
-+    GetBoundingMetricsInternal (layout, aBoundingMetrics CONTEXT_ARG_PASS);
-     g_object_unref(layout);
--    return rv;
-+   return NS_OK;
-+}
-+
-+nsresult
-+nsFontMetricsPango::GetBoundingMetrics(const PRUnichar *aString,
-+                                       PRUint32 aLength,
-+                                       nsBoundingMetrics &aBoundingMetrics,
-+                                       PRInt32 *aFontID
-+                                       CONTEXT_ARG_DEF)
-+{
-+    PangoLayout *layout = GetLayout(aString, aLength);
-+    GetBoundingMetricsInternal (layout, aBoundingMetrics CONTEXT_ARG_PASS);
-+    g_object_unref(layout);
-+
-+    return NS_OK;
- }
- #endif /* MOZ_MATHML */
-+#ifndef PSPANGO
- GdkFont*
- nsFontMetricsPango::GetCurrentGDKFont(void)
- {
-     return nsnull;
- }
-+#endif
- nsresult
- nsFontMetricsPango::SetRightToLeftText(PRBool aIsRTL)
- {
-     if (aIsRTL) {
-         if (!mRTLPangoContext) {
--            mRTLPangoContext = gdk_pango_context_get();
-+            mRTLPangoContext = get_context();
-             pango_context_set_base_dir(mRTLPangoContext, PANGO_DIRECTION_RTL);
--
--            gdk_pango_context_set_colormap(mRTLPangoContext, gdk_rgb_get_cmap());
-             pango_context_set_language(mRTLPangoContext, GetPangoLanguage(mLangGroup));
-             pango_context_set_font_description(mRTLPangoContext, mPangoFontDesc);
-         }
-@@ -899,34 +1087,18 @@ nsFontMetricsPango::GetClusterInfo(const
-                                    PRUint32 aLength,
-                                    PRUint8 *aClusterStarts)
- {
--    nsresult rv = NS_OK;
-     PangoLogAttr *attrs = NULL;
-     gint n_attrs = 0;
--    PangoLayout *layout = pango_layout_new(mPangoContext);
--    
--    // Convert the incoming UTF-16 to UTF-8
--    gchar *text = g_utf16_to_utf8(aText, aLength, NULL, NULL, NULL);
--    if (!text) {
--#ifdef DEBUG
--        NS_WARNING("nsFontMetricsPango::GetWidth invalid unicode to follow");
--        DUMP_PRUNICHAR(aText, aLength)
--#endif
--        rv = NS_ERROR_FAILURE;
--        goto loser;
--    }
--
--    // Set up the pango layout
--    pango_layout_set_text(layout, text, strlen(text));
--    FixupSpaceWidths(layout, text);
-+    PangoLayout *layout = GetLayout(aText, aLength);
-+    pango_layout_get_log_attrs(layout, &attrs, &n_attrs);
-+    g_object_unref(layout);
-     // Convert back to UTF-16 while filling in the cluster info
-     // structure.
--    pango_layout_get_log_attrs(layout, &attrs, &n_attrs);
--
-     for (PRUint32 pos = 0; pos < aLength; pos++) {
-         if (IS_HIGH_SURROGATE(aText[pos])) {
--            aClusterStarts[pos] = 1;
-+            aClusterStarts[pos] = 1;//FIXME: shouldn't this be zero?! --be
-             pos++;
-         }
-         else {
-@@ -934,56 +1106,34 @@ nsFontMetricsPango::GetClusterInfo(const
-         }
-     }
-- loser:
--    if (attrs)
--        g_free(attrs);
--    if (text)
--        g_free(text);
--    if (layout)
--        g_object_unref(layout);
-+    g_free(attrs);
--    return rv;
-+    return NS_OK;
- }
- PRInt32
--nsFontMetricsPango::GetPosition(const PRUnichar *aText, PRUint32 aLength,
--                                nsPoint aPt)
-+nsFontMetricsPango::GetPosition(const PRUnichar *aText, PRUint32 aLength, nsPoint aPt)
- {
-     int trailing = 0;
-     int inx = 0;
--    const gchar *curChar;
-     PRInt32 retval = 0;
-     float f = mDeviceContext->AppUnitsToDevUnits();
-     
--    PangoLayout *layout = pango_layout_new(mPangoContext);
-     PRUint32 localX = (PRUint32)(aPt.x * PANGO_SCALE * f);
-     PRUint32 localY = (PRUint32)(aPt.y * PANGO_SCALE * f);
--    // Convert the incoming UTF-16 to UTF-8
--    gchar *text = g_utf16_to_utf8(aText, aLength, NULL, NULL, NULL);
--
--    if (!text) {
--#ifdef DEBUG
--        NS_WARNING("nsFontMetricsPango::GetWidth invalid unicode to follow");
--        DUMP_PRUNICHAR(aText, aLength)
--#endif
--        retval = -1;
--        goto loser;
--    }
--
--    // Set up the pango layout
--    pango_layout_set_text(layout, text, strlen(text));
--    FixupSpaceWidths(layout, text);
-+    PangoLayout *layout = GetLayout(aText, aLength);
-     
-     pango_layout_xy_to_index(layout, localX, localY,
-                              &inx, &trailing);
-     // Convert the index back to the utf-16 index
--    curChar = text;
-+    const gchar *text = pango_layout_get_text (layout);
-+    const gchar *curChar = text;
-     for (PRUint32 curOffset=0; curOffset < aLength;
--         curOffset++, curChar = g_utf8_find_next_char(curChar, NULL)) {
-+         curOffset++, curChar = g_utf8_next_char(curChar)) {
-         // Check for a match before checking for a surrogate pair
-         if (curChar - text == inx) {
-@@ -1006,13 +1156,9 @@ nsFontMetricsPango::GetPosition(const PR
-         trailing--;
-     }
-- loser:
--    if (text)
--        g_free(text);
--    if (layout)
--        g_object_unref(layout);
-+    g_object_unref(layout);
--    return retval;
-+    return retval; 
- }
- nsresult
-@@ -1022,28 +1168,21 @@ nsFontMetricsPango::GetRangeWidth(const 
-                                   PRUint32 aEnd,
-                                   PRUint32 &aWidth)
- {
--    nsresult rv = NS_OK;
-     PRUint32 utf8Start = 0;
-     PRUint32 utf8End = 0;
-     aWidth = 0;
-     // Convert the incoming UTF-16 to UTF-8
--    gchar *text = g_utf16_to_utf8(aText, aLength, NULL, NULL, NULL);
--    gchar *curChar = text;
--    if (!text) {
--#ifdef DEBUG
--        NS_WARNING("nsFontMetricsPango::GetWidth invalid unicode to follow");
--        DUMP_PRUNICHAR(aText, aLength)
--#endif
--        rv = NS_ERROR_FAILURE;
--        goto loser;
--    }
-+    gchar* text;
-+    gint text_len;
-+    utf16_to_utf8 (aText, aLength, text, text_len);
-+    gchar *curChar = text;
-     // Convert the utf16 offsets into utf8 offsets
-     for (PRUint32 curOffset = 0; curOffset < aLength;
--         curOffset++, curChar = g_utf8_find_next_char(curChar, NULL)) {
-+         curOffset++, curChar = g_utf8_next_char(curChar)) {
-         if (curOffset == aStart)
-             utf8Start = curChar - text;
-@@ -1057,15 +1196,13 @@ nsFontMetricsPango::GetRangeWidth(const 
-     // Special case where the end index is the same as the length
-     if (aLength == aEnd)
--        utf8End = strlen(text);
-+        utf8End = text_len;
--    rv = GetRangeWidth(text, strlen(text), utf8Start, utf8End, aWidth);
-+    GetRangeWidth(text, text_len, utf8Start, utf8End, aWidth);
-- loser:
--    if (text)
--        g_free(text);
-+    g_free(text);
--    return rv;
-+    return NS_OK;
- }
- nsresult
-@@ -1075,43 +1212,26 @@ nsFontMetricsPango::GetRangeWidth(const 
-                                   PRUint32 aEnd,
-                                   PRUint32 &aWidth)
- {
--    nsresult rv = NS_OK;
-     int *ranges = NULL;
-     int n_ranges = 0;
-     float f;
-     aWidth = 0;
--    PangoLayout *layout = pango_layout_new(mPangoContext);
--
--    if (!aText) {
--        rv = NS_ERROR_FAILURE;
--        goto loser;
--    }
--
--    pango_layout_set_text(layout, aText, aLength);
--    FixupSpaceWidths(layout, aText);
--
--    PangoLayoutLine *line;
--    if (pango_layout_get_line_count(layout) != 1) {
--        printf("Warning: more than one line!\n");
--    }
--    line = pango_layout_get_line(layout, 0);
-+    PangoLayout *layout = GetLayout(aText, aLength);
-+    PangoLayoutLine *line = pango_layout_get_line(layout, 0);
-     pango_layout_line_get_x_ranges(line, aStart, aEnd, &ranges, &n_ranges);
-     aWidth = (ranges[((n_ranges - 1) * 2) + 1] - ranges[0]);
-     f = mDeviceContext-> DevUnitsToAppUnits();
--    aWidth = nscoord(aWidth * f / PANGO_SCALE);
-+    aWidth = NSToCoordRound(aWidth * f / PANGO_SCALE);
-- loser:
--    if (ranges)
--        g_free(ranges);
--    if (layout)
--        g_object_unref(layout);
-+    g_free(ranges);
-+    g_object_unref(layout);
--    return rv;
-+    return NS_OK;
- }
- /* static */
-@@ -1134,7 +1254,7 @@ nsFontMetricsPango::FamilyExists(nsIDevi
-     NS_ConvertUTF16toUTF8 name(aName);
-     nsresult rv = NS_ERROR_FAILURE;
--    PangoContext *context = gdk_pango_context_get();
-+    PangoContext *context = get_context();
-     PangoFontFamily **familyList;
-     int n;
-@@ -1233,16 +1353,13 @@ nsFontMetricsPango::RealizeFont(void)
-     // Now that we have the font description set up, create the
-     // context.
--    mLTRPangoContext = gdk_pango_context_get();
-+    mLTRPangoContext = get_context();
-     mPangoContext = mLTRPangoContext;
-     // Make sure to set the base direction to LTR - if layout needs to
-     // render RTL text it will use ::SetRightToLeftText()
-     pango_context_set_base_dir(mPangoContext, PANGO_DIRECTION_LTR);
--    // Set the color map so we can draw later.
--    gdk_pango_context_set_colormap(mPangoContext, gdk_rgb_get_cmap());
--
-     // Set the pango language now that we have a context
-     pango_context_set_language(mPangoContext, GetPangoLanguage(mLangGroup));
-@@ -1280,79 +1397,268 @@ nsFontMetricsPango::EnumFontCallback(con
-  * This is only used when there's per-character spacing happening.
-  * Well, really it can be either line or character spacing but it's
-  * just turtles all the way down!
-+ *
-+ * To do it correctly (ligatures, etc) we need machinery that is private
-+ * in Pango.  IMPORT IT:
-+ */
-+
-+#define _PangoGlyphItemIter _nsFontMetricsPangoGlyphItemIter
-+#define PangoGlyphItemIter nsFontMetricsPangoGlyphItemIter
-+
-+#define LTR(glyph_item) (((glyph_item)->item->analysis.level % 2) == 0)
-+
-+/* Structure holding state when we're iterating over a GlyphItem.
-+ * start_index/cluster_end (and range_start/range_end in
-+ * apply_attrs()) are offsets into the text, so note the difference
-+ * of glyph_item->item->offset between them and clusters in the
-+ * log_clusters[] array.
-  */
-+typedef struct _PangoGlyphItemIter PangoGlyphItemIter;
-+
-+struct _PangoGlyphItemIter
-+{
-+  PangoGlyphItem *glyph_item;
-+  const gchar *text;
-+  
-+  int start_glyph;
-+  int start_index;
-+  int start_char;
-+
-+  int end_glyph;
-+  int end_index;
-+  int end_char;
-+};
-+
-+/**
-+ * _pango_glyph_item_iter_next_cluster:
-+ * @iter: a #PangoGlyphItemIter
-+ * 
-+ * Advances the iterator to the next cluster in the glyph item.
-+ * 
-+ * Return value: %TRUE if the iterator was advanced, %FALSE if we were already on the
-+ *  last cluster.
-+ **/
-+static gboolean
-+_pango_glyph_item_iter_next_cluster (PangoGlyphItemIter *iter)
-+{
-+  int glyph_index = iter->end_glyph;
-+  PangoGlyphString *glyphs = iter->glyph_item->glyphs;
-+  PangoItem *item = iter->glyph_item->item;
-+
-+  if (LTR (iter->glyph_item))
-+    {
-+      if (glyph_index == glyphs->num_glyphs)
-+      return FALSE;
-+    }
-+  else
-+    {
-+      if (glyph_index < 0)
-+      return FALSE;
-+    }
-+      
-+  iter->start_glyph = iter->end_glyph;
-+  iter->start_index = iter->end_index;
-+  iter->start_char = iter->end_char;
-+  
-+  if (LTR (iter->glyph_item))
-+    {
-+      while (TRUE)
-+      {
-+        glyph_index++;
-+        
-+        if (glyph_index == glyphs->num_glyphs)
-+          {
-+            iter->end_index = item->offset + item->length;
-+            iter->end_char = item->num_chars;
-+            break;
-+          }
-+        
-+        if (item->offset + glyphs->log_clusters[glyph_index] != iter->start_index)
-+          {
-+            iter->end_index = item->offset + glyphs->log_clusters[glyph_index];
-+            iter->end_char += g_utf8_strlen (iter->text + iter->start_index,
-+                                             iter->end_index - iter->start_index);
-+            break; 
-+          }
-+      }
-+    }
-+  else                        /* RTL */
-+    {
-+      while (TRUE)
-+      {
-+        glyph_index--;
-+        
-+        if (glyph_index < 0)
-+          {
-+            iter->end_index = item->offset + item->length;
-+            iter->end_char = item->num_chars;
-+            break;
-+          }
-+        
-+        if (item->offset + glyphs->log_clusters[glyph_index] != iter->start_index)
-+          {
-+            iter->end_index = item->offset + glyphs->log_clusters[glyph_index];
-+            iter->end_char += g_utf8_strlen (iter->text + iter->start_index,
-+                                             iter->end_index - iter->start_index);
-+            break; 
-+          }
-+      }
-+    }
-+
-+  iter->end_glyph = glyph_index;
-+  return TRUE;
-+}
-+
-+/**
-+ * _pango_glyph_item_iter_init_start:
-+ * @iter: pointer to a #PangoGlyphItemIter structure
-+ * @glyph_item: the glyph item that the iter points into
-+ * @text: text corresponding to the glyph item
-+ * 
-+ * Initializes a #PangoGlyphItemIter structure to point to the
-+ * first cluster in a glyph item.
-+ * 
-+ * Return value: %FALSE if there are no clusters in the glyph item;
-+ *  in this case, the state of the iter is undefined.
-+ **/
-+static gboolean
-+_pango_glyph_item_iter_init_start (PangoGlyphItemIter  *iter,
-+                                 PangoGlyphItem      *glyph_item,
-+                                 const char          *text)
-+{
-+  iter->glyph_item = glyph_item;
-+  iter->text = text;
-+  
-+  if (LTR (glyph_item))
-+    iter->end_glyph = 0;
-+  else
-+    iter->end_glyph = glyph_item->glyphs->num_glyphs - 1;
-+
-+  iter->end_index = glyph_item->item->offset;
-+  iter->end_char = 0;
-+
-+  /* Advance onto the first cluster of the glyph item */
-+  return _pango_glyph_item_iter_next_cluster (iter);
-+}
-+
- void
--nsFontMetricsPango::DrawStringSlowly(const gchar *aText,
--                                     const PRUnichar *aOrigString,
--                                     PRUint32 aLength,
--                                     GdkDrawable *aDrawable,
--                                     GdkGC *aGC, gint aX, gint aY,
--                                     PangoLayoutLine *aLine,
--                                     const nscoord *aSpacing)
--{
--    float app2dev;
--    app2dev = mDeviceContext->AppUnitsToDevUnits();
--    gint offset = 0;
-+nsFontMetricsPango::ApplySpacing(const gchar *aText,
-+                                 PRUint32 aLength,
-+                                 PangoLayoutLine *aLine,
-+                                 const nscoord *aSpacing)
-+{
-+    if (!(aSpacing && *aSpacing))
-+      return;
-+
-+    float app2dev = mDeviceContext->AppUnitsToDevUnits();
-     /*
-      * We walk the list of glyphs returned in each layout run,
-      * matching up the glyphs with the characters in the source text.
-      * We use the aSpacing argument to figure out where to place those
--     * glyphs.  It's important to note that since the string we're
--     * working with is in UTF-8 while the spacing argument assumes
--     * that offset will be part of the UTF-16 string.  Logical
--     * attributes in pango are in byte offsets in the UTF-8 string, so
--     * we need to store the offsets based on the UTF-8 string.
-+     * glyphs.
-      */
--    nscoord *utf8spacing = new nscoord[strlen(aText)];
-+    for (GSList *tmpList = aLine->runs; tmpList && tmpList->data;
-+         tmpList = tmpList->next) {
-+        PangoGlyphItem *glyph_item = (PangoGlyphItem *)tmpList->data;
-+        PangoGlyphItemIter iter;
-+        gboolean have_cluster;
-+        PangoGlyphInfo *glyphs = glyph_item->glyphs->glyphs;
-+        int residualWidth = 0;
-+
-+        for (have_cluster = _pango_glyph_item_iter_init_start (&iter, glyph_item, aText);
-+             have_cluster;
-+             have_cluster = _pango_glyph_item_iter_next_cluster (&iter))
-+        {
-+          int clusterOldWidth = 0;
-+          int clusterNewWidth = 0;
-+          int dir = iter.start_glyph < iter.end_glyph ? +1 : -1;
-+          gboolean has_zero_width = FALSE;
-+
-+          for (const char *p = iter.text + iter.start_index;
-+               p < iter.text + iter.end_index;
-+               p = g_utf8_next_char (p))
-+            clusterNewWidth += aSpacing[p - iter.text];
-+
-+          clusterNewWidth = (gint)(clusterNewWidth * app2dev * PANGO_SCALE);
-+
-+          for (gint i = iter.start_glyph; i != iter.end_glyph; i += dir) {
-+            if (!glyphs[i].geometry.width)
-+              has_zero_width = TRUE;
-+            clusterOldWidth += glyphs[i].geometry.width;
-+          }
-+            
-+          /* if a zero-width glyph exists, don't touch the glyph widths.
-+           * required for combining marks.  ff thinks they have a width.
-+           * instead, we charge the difference to the next space glyph. */
-+          if (has_zero_width) {
-+            residualWidth += clusterNewWidth - clusterOldWidth;
-+            continue;
-+          }
--    if (aOrigString) {
--        const gchar *curChar = aText;
--        bzero(utf8spacing, sizeof(nscoord) * strlen(aText));
--
--        // Covert the utf16 spacing offsets to utf8 spacing offsets
--        for (PRUint32 curOffset=0; curOffset < aLength;
--             curOffset++, curChar = g_utf8_find_next_char(curChar, NULL)) {
--            utf8spacing[curChar - aText] = aSpacing[curOffset];
-+          /* If a space glyph is found, charge it whatever residual we
-+           * have accumulated so far. */
-+          if (iter.end_index - iter.start_index == 1 &&
-+              *(iter.text + iter.start_index) == ' ') {
-+            clusterNewWidth += residualWidth;
-+            residualWidth = 0;
-+          }
-+          
-+#ifndef PSPANGO
-+          /* do some hinting for display */
-+
-+          if (clusterOldWidth % PANGO_SCALE == 0 && clusterNewWidth % PANGO_SCALE != 0) {
-+            int tmp = clusterNewWidth;
-+            clusterNewWidth = PANGO_PIXELS (clusterNewWidth) * PANGO_SCALE;
-+            residualWidth += tmp - clusterNewWidth;
-+          }
-+#endif
--            if (IS_HIGH_SURROGATE(aOrigString[curOffset]))
--                curOffset++;
-+          /* find the first non-zero-width glyph and adjust its width */
-+          for (gint i = iter.start_glyph; i != iter.end_glyph; i += dir)
-+            if (glyphs[i].geometry.width) {
-+              glyphs[i].geometry.width += clusterNewWidth - clusterOldWidth;
-+              break;
-+            }
-         }
-     }
--    else {
--        memcpy(utf8spacing, aSpacing, (sizeof(nscoord *) * aLength));
--    }
-+}
--    gint curRun = 0;
-+void
-+nsFontMetricsPango::ApplySpacing(const PRUnichar *aText,
-+                                 PRUint32 aLength,
-+                                 PangoLayoutLine *aLine,
-+                                 const nscoord *aSpacing)
-+{
-+    if (!(aSpacing && *aSpacing))
-+      return;
--    for (GSList *tmpList = aLine->runs; tmpList && tmpList->data;
--         tmpList = tmpList->next, curRun++) {
--        PangoLayoutRun *layoutRun = (PangoLayoutRun *)tmpList->data;
--        gint tmpOffset = 0;
-+    const char *utf8Text = pango_layout_get_text (aLine->layout);
-+    int utf8Text_len = aLine->start_index + aLine->length;
--        /*        printf("    Rendering run %d: \"%s\"\n", curRun,
--                  &aText[layoutRun->item->offset]); */
-+    /* Since the string we're
-+     * working with is in UTF-8 while the spacing argument assumes
-+     * that offset will be part of the UTF-16 string.  Logical
-+     * attributes in pango are in byte offsets in the UTF-8 string, so
-+     * we need to store the offsets based on the UTF-8 string.
-+     */
-+    nscoord *utf8spacing = g_new0 (nscoord, utf8Text_len);
--        for (gint i=0; i < layoutRun->glyphs->num_glyphs; i++) {
--            /* printf("glyph %d offset %d orig width %d new width %d\n", i,
--             *        layoutRun->glyphs->log_clusters[i] + layoutRun->item->offset,
--             *        layoutRun->glyphs->glyphs[i].geometry.width,
--             *       (gint)(utf8spacing[layoutRun->glyphs->log_clusters[i] + layoutRun->item->offset] * app2dev * PANGO_SCALE));
--             */
--            gint thisOffset = (gint)(utf8spacing[layoutRun->glyphs->log_clusters[i] + layoutRun->item->offset]
--                                     * app2dev * PANGO_SCALE);
--            layoutRun->glyphs->glyphs[i].geometry.width = thisOffset;
--            tmpOffset += thisOffset;
--        }
-+    const gchar *curChar = utf8Text + aLine->start_index;
--        /*        printf("    rendering at X coord %d\n", aX + offset); */
--        offset += tmpOffset;
-+    // Covert the utf16 spacing offsets to utf8 spacing offsets
-+    for (PRUint32 curOffset=0; curOffset < aLength;
-+         curOffset++, curChar = g_utf8_next_char(curChar)) {
-+        utf8spacing[curChar - utf8Text] = aSpacing[curOffset];
-+
-+        if (IS_HIGH_SURROGATE(aText[curOffset]))
-+            curOffset++;
-     }
--    gdk_draw_layout_line(aDrawable, aGC, aX, aY, aLine);
-+    ApplySpacing (utf8Text, utf8Text_len, aLine, utf8spacing);
--    delete[] utf8spacing;
-+    g_free (utf8spacing);
- }
- nsresult
-@@ -1363,8 +1669,8 @@ nsFontMetricsPango::GetTextDimensionsInt
-                                               PRInt32             aNumBreaks,
-                                               nsTextDimensions&   aDimensions,
-                                               PRInt32&            aNumCharsFit,
--                                              nsTextDimensions&   aLastWordDimensions,
--                                              nsRenderingContextGTK *aContext)
-+                                              nsTextDimensions&   aLastWordDimensions
-+                                              CONTEXT_ARG_DEF)
- {
-     NS_PRECONDITION(aBreaks[aNumBreaks - 1] == aLength, "invalid break array");
-@@ -1410,7 +1716,7 @@ nsFontMetricsPango::GetTextDimensionsInt
-             // All the characters should fit
-             numChars = aLength - start;
-             breakIndex = aNumBreaks - 1;
--        } 
-+        }
-         else {
-             breakIndex = prevBreakState_BreakIndex;
-             while (((breakIndex + 1) < aNumBreaks) &&
-@@ -1431,7 +1737,7 @@ nsFontMetricsPango::GetTextDimensionsInt
-         if ((1 == numChars) && (aString[start] == ' '))
-             GetSpaceWidth(twWidth);
-         else if (numChars > 0)
--            GetWidth(&aString[start], numChars, twWidth, aContext);
-+            GetWidth(&aString[start], numChars, twWidth CONTEXT_ARG_PASS);
-         // See if the text fits
-         PRBool  textFits = (twWidth + width) <= aAvailWidth;
-@@ -1481,8 +1787,7 @@ nsFontMetricsPango::GetTextDimensionsInt
-                 if ((1 == numChars) && (aString[start] == ' '))
-                     GetSpaceWidth(twWidth);
-                 else if (numChars > 0)
--                    GetWidth(&aString[start], numChars, twWidth,
--                             aContext);
-+                    GetWidth(&aString[start], numChars, twWidth CONTEXT_ARG_PASS);
-                 width -= twWidth;
-                 aNumCharsFit = start;
-                 breakIndex--;
-@@ -1504,9 +1809,16 @@ nsFontMetricsPango::GetTextDimensionsInt
- }
- void
--nsFontMetricsPango::FixupSpaceWidths (PangoLayout *aLayout,
--                                      const char *aString)
-+nsFontMetricsPango::FixupSpaceWidths (PangoLayout *aLayout)
- {
-+    if (!mPangoSpaceWidth)
-+      return;
-+
-+    const char *aString = pango_layout_get_text (aLayout);
-+
-+    if (pango_layout_get_line_count(aLayout) != 1) {
-+        printf("Warning: more than one line!\n");
-+    }
-     PangoLayoutLine *line = pango_layout_get_line(aLayout, 0);
-     gint curRun = 0;
-@@ -1523,6 +1835,107 @@ nsFontMetricsPango::FixupSpaceWidths (Pa
-     }
- }
-+PangoLayout*
-+nsFontMetricsPango::GetLayout (const PRUnichar* aText,
-+                               PRUint32         aLength)
-+{
-+  gchar* text;
-+  gint length;
-+  utf16_to_utf8 (aText, aLength, text, length);
-+
-+  PangoLayout *layout = pango_layout_new(mPangoContext);
-+  pango_layout_set_text (layout, text, length);
-+  FixupSpaceWidths (layout);
-+
-+  g_free ((gpointer) text);
-+
-+  return layout;
-+}
-+
-+PangoLayout*
-+nsFontMetricsPango::GetLayout (const gchar*     aText,
-+                               PRInt32          aLength)
-+{
-+  gboolean has_nul = FALSE;
-+  int i;
-+
-+  for (i = 0; i < aLength; i++)
-+    if (!aText[i]) {
-+      has_nul = TRUE;
-+      break;
-+    }
-+
-+  if (has_nul) {
-+    /* Pango doesn't correctly handle nuls.  We convert them to 0xff. */
-+
-+    char *p = (char *) g_memdup (aText, aLength);
-+
-+    /* don't need to reset i */
-+    for (; i < aLength; i++)
-+      if (!p[i])
-+        p[i] = (char) 0xff;
-+
-+    aText = p;
-+  }
-+
-+  PangoLayout *layout = pango_layout_new(mPangoContext);
-+  pango_layout_set_text (layout, aText, aLength);
-+  FixupSpaceWidths (layout);
-+
-+  if (has_nul)
-+    g_free ((gpointer) aText);
-+
-+  return layout;
-+}
-+
-+static void
-+utf16_to_utf8 (const PRUnichar* aText, PRUint32 aLength, char *&text, gint &length)
-+{
-+  gboolean need_copy = FALSE;
-+  int i;
-+
-+  for (i = 0; i < aLength; i++) {
-+    if (!aText[i] || IS_LOW_SURROGATE (aText[i]))
-+      need_copy = TRUE;
-+    else if (IS_HIGH_SURROGATE (aText[i])) {
-+      if (i < aLength - 1 && IS_LOW_SURROGATE (aText[i+1]))
-+        i++;
-+      else
-+        need_copy = TRUE;
-+    }
-+  }
-+
-+  if (need_copy) {
-+
-+    /* Pango doesn't correctly handle nuls.  We convert them to 0xff. */
-+    /* Also "validate" UTF-16 text to make sure conversion doesn't fail. */
-+
-+    PRUnichar *p = (PRUnichar *) g_memdup (aText, aLength * sizeof (aText[0]));
-+
-+    /* don't need to reset i */
-+    for (i = 0; i < aLength; i++) {
-+      if (!p[i] || IS_LOW_SURROGATE (p[i]))
-+        p[i] = 0xFFFD;
-+      else if (IS_HIGH_SURROGATE (p[i])) {
-+        if (i < aLength - 1 && IS_LOW_SURROGATE (aText[i+1]))
-+          i++;
-+        else
-+          p[i] = 0xFFFD;
-+      }
-+    }
-+
-+    aText = p;
-+  }
-+
-+  glong items_written;
-+  text = g_utf16_to_utf8 (aText, aLength, NULL, &items_written, NULL);
-+  length = items_written;
-+
-+  if (need_copy)
-+    g_free ((gpointer) aText);
-+
-+}
-+
- /* static */
- PangoLanguage *
- GetPangoLanguage(nsIAtom *aLangGroup)
---- mozilla.back/gfx/src/gtk/nsFontMetricsPango.h.orig 2006-06-30 01:18:34.000000000 +0200
-+++ mozilla.back/gfx/src/gtk/nsFontMetricsPango.h      2007-06-28 15:16:39.000000000 +0200
-@@ -37,17 +37,53 @@
-  *
-  * ***** END LICENSE BLOCK ***** */
-+
- #include "nsIFontMetrics.h"
- #include "nsIFontEnumerator.h"
- #include "nsCRT.h"
- #include "nsIAtom.h"
- #include "nsString.h"
- #include "nsVoidArray.h"
-+
-+#ifdef PSPANGO
-+#include "nsFontMetricsPS.h"
-+#else
- #include "nsIFontMetricsGTK.h"
-+#endif
- #include <pango/pango.h>
--class nsFontMetricsPango : public nsIFontMetricsGTK
-+#ifdef PSPANGO
-+
-+#define CONTEXT_ARG_DEF
-+#define CONTEXT_ARG_PASS
-+#define CONTEXT_ARG_NULL
-+#define CONTEXT_AND_SURFACE_ARG_DEF  , nsRenderingContextPS *aContext
-+#define CONTEXT_AND_SURFACE_ARG_PASS , aContext
-+
-+#else
-+
-+#define CONTEXT_ARG_DEF              , nsRenderingContextGTK *aContext
-+#define CONTEXT_ARG_PASS             , aContext
-+#define CONTEXT_ARG_NULL             , NULL
-+#define CONTEXT_AND_SURFACE_ARG_DEF  , nsRenderingContextGTK *aContext, nsDrawingSurfaceGTK *aSurface
-+#define CONTEXT_AND_SURFACE_ARG_PASS , aContext, aSurface
-+
-+#endif
-+
-+
-+#ifdef PSPANGO
-+
-+#define nsFontMetricsPango   nsFontMetricsPSPango
-+#define PSPANGO_PARENT_CLASS nsFontMetricsPS
-+
-+#else
-+
-+#define PSPANGO_PARENT_CLASS nsIFontMetricsGTK
-+
-+#endif
-+
-+class nsFontMetricsPango : public PSPANGO_PARENT_CLASS
- {
- public:
-     nsFontMetricsPango();
-@@ -136,20 +172,30 @@ public:
-     PRInt32 GetMaxStringLength() { return mMaxStringLength; }
--    // nsIFontMetricsGTK (calls from the font rendering layer)
--    virtual nsresult GetWidth(const char* aString, PRUint32 aLength,
--                              nscoord& aWidth,
--                              nsRenderingContextGTK *aContext);
--    virtual nsresult GetWidth(const PRUnichar* aString, PRUint32 aLength,
--                              nscoord& aWidth, PRInt32 *aFontID,
--                              nsRenderingContextGTK *aContext);
-+    // nsIFontMetrics (calls from the font rendering layer)
--    virtual nsresult GetTextDimensions(const PRUnichar* aString,
-+#ifdef PSPANGO
-+    NS_IMETHOD  GetStringWidth(const char *String,nscoord &aWidth,nscoord aLength);
-+    NS_IMETHOD  GetStringWidth(const PRUnichar *aString,nscoord &aWidth,nscoord aLength);
-+#endif
-+
-+    NS_METHOD        GetWidth(const char* aString, PRUint32 aLength,
-+                              nscoord& aWidth
-+                              CONTEXT_ARG_DEF);
-+    NS_METHOD        GetWidth(const PRUnichar* aString, PRUint32 aLength,
-+                              nscoord& aWidth, PRInt32 *aFontID
-+                              CONTEXT_ARG_DEF);
-+
-+    NS_METHOD        GetTextDimensions(const char* aString,
-+                                       PRUint32 aLength,
-+                                       nsTextDimensions& aDimensions
-+                                       CONTEXT_ARG_DEF);
-+    NS_METHOD        GetTextDimensions(const PRUnichar* aString,
-                                        PRUint32 aLength,
-                                        nsTextDimensions& aDimensions, 
--                                       PRInt32* aFontID,
--                                       nsRenderingContextGTK *aContext);
--    virtual nsresult GetTextDimensions(const char*         aString,
-+                                       PRInt32* aFontID
-+                                       CONTEXT_ARG_DEF);
-+    NS_METHOD        GetTextDimensions(const char*         aString,
-                                        PRInt32             aLength,
-                                        PRInt32             aAvailWidth,
-                                        PRInt32*            aBreaks,
-@@ -157,9 +203,9 @@ public:
-                                        nsTextDimensions&   aDimensions,
-                                        PRInt32&            aNumCharsFit,
-                                        nsTextDimensions&   aLastWordDimensions,
--                                       PRInt32*            aFontID,
--                                       nsRenderingContextGTK *aContext);
--    virtual nsresult GetTextDimensions(const PRUnichar*    aString,
-+                                       PRInt32*            aFontID
-+                                       CONTEXT_ARG_DEF);
-+    NS_METHOD        GetTextDimensions(const PRUnichar*    aString,
-                                        PRInt32             aLength,
-                                        PRInt32             aAvailWidth,
-                                        PRInt32*            aBreaks,
-@@ -167,38 +213,37 @@ public:
-                                        nsTextDimensions&   aDimensions,
-                                        PRInt32&            aNumCharsFit,
-                                        nsTextDimensions&   aLastWordDimensions,
--                                       PRInt32*            aFontID,
--                                       nsRenderingContextGTK *aContext);
-+                                       PRInt32*            aFontID
-+                                       CONTEXT_ARG_DEF);
--    virtual nsresult DrawString(const char *aString, PRUint32 aLength,
-+    NS_METHOD        DrawString(const char *aString, PRUint32 aLength,
-                                 nscoord aX, nscoord aY,
--                                const nscoord* aSpacing,
--                                nsRenderingContextGTK *aContext,
--                                nsDrawingSurfaceGTK *aSurface);
--    virtual nsresult DrawString(const PRUnichar* aString, PRUint32 aLength,
-+                                const nscoord* aSpacing  
-+                                CONTEXT_AND_SURFACE_ARG_DEF);
-+
-+    NS_METHOD        DrawString(const PRUnichar* aString, PRUint32 aLength,
-                                 nscoord aX, nscoord aY,
-                                 PRInt32 aFontID,
--                                const nscoord* aSpacing,
--                                nsRenderingContextGTK *aContext,
--                                nsDrawingSurfaceGTK *aSurface);
-+                                const nscoord* aSpacing  
-+                                CONTEXT_AND_SURFACE_ARG_DEF);
- #ifdef MOZ_MATHML
--    virtual nsresult GetBoundingMetrics(const char *aString, PRUint32 aLength,
--                                        nsBoundingMetrics &aBoundingMetrics,
--                                        nsRenderingContextGTK *aContext);
--    virtual nsresult GetBoundingMetrics(const PRUnichar *aString,
-+    NS_METHOD        GetBoundingMetrics(const char *aString, PRUint32 aLength,
-+                                        nsBoundingMetrics &aBoundingMetrics
-+                                        CONTEXT_ARG_DEF);
-+    NS_METHOD        GetBoundingMetrics(const PRUnichar *aString,
-                                         PRUint32 aLength,
-                                         nsBoundingMetrics &aBoundingMetrics,
--                                        PRInt32 *aFontID,
--                                        nsRenderingContextGTK *aContext);
-+                                        PRInt32 *aFontID
-+                                        CONTEXT_ARG_DEF);
- #endif /* MOZ_MATHML */
--
-+#ifndef PSPANGO
-     virtual GdkFont* GetCurrentGDKFont(void);
--
--    virtual nsresult SetRightToLeftText(PRBool aIsRTL);
-+#endif
-     virtual PRBool GetRightToLeftText();
--
--    virtual nsresult GetClusterInfo(const PRUnichar *aText,
-+    NS_METHOD        SetRightToLeftText(PRBool aIsRTL);
-+    
-+    NS_METHOD        GetClusterInfo(const PRUnichar *aText,
-                                     PRUint32 aLength,
-                                     PRUint8 *aClusterStarts);
-@@ -206,32 +251,35 @@ public:
-                                 PRUint32 aLength,
-                                 nsPoint aPt);
--    virtual nsresult GetRangeWidth(const PRUnichar *aText,
-+    NS_METHOD        GetRangeWidth(const PRUnichar *aText,
-                                    PRUint32 aLength,
-                                    PRUint32 aStart,
-                                    PRUint32 aEnd,
-                                    PRUint32 &aWidth);
--    virtual nsresult GetRangeWidth(const char *aText,
-+    NS_METHOD        GetRangeWidth(const char *aText,
-                                    PRUint32 aLength,
-                                    PRUint32 aStart,
-                                    PRUint32 aEnd,
-                                    PRUint32 &aWidth);
-     // get hints for the font
--    static PRUint32    GetHints     (void);
-+#ifndef PSPANGO
-+    static
-+#endif
-+    PRUint32    GetHints     (void);
-     // drawing surface methods
-     static nsresult FamilyExists    (nsIDeviceContext *aDevice,
-                                      const nsString &aName);
-+
- private:
-     // generic font metrics class bits
-     nsCStringArray       mFontList;
-     nsAutoVoidArray      mFontIsGeneric;
--    nsIDeviceContext    *mDeviceContext;
-     nsCOMPtr<nsIAtom>    mLangGroup;
-     nsCString           *mGenericFont;
-     float                mPointSize;
-@@ -246,6 +294,9 @@ private:
-     PangoAttrList        *mPangoAttrList;
-     PRBool                mIsRTL;
-+#ifndef PSPANGO
-+    nsIDeviceContext    *mDeviceContext; 
-+
-     // Cached font metrics
-     nscoord                  mXHeight;
-     nscoord                  mSuperscriptOffset;
-@@ -263,6 +314,7 @@ private:
-     nscoord                  mMaxDescent;
-     nscoord                  mMaxAdvance;
-     nscoord                  mSpaceWidth;
-+#endif
-     nscoord                  mPangoSpaceWidth;
-     nscoord                  mAveCharWidth;
-     PRInt32                  mMaxStringLength;
-@@ -274,13 +326,14 @@ private:
-     static PRBool EnumFontCallback(const nsString &aFamily,
-                                    PRBool aIsGeneric, void *aData);
--    void     DrawStringSlowly(const gchar *aText,
--                              const PRUnichar *aOrigString,
--                              PRUint32 aLength,
--                              GdkDrawable *aDrawable,
--                              GdkGC *aGC, gint aX, gint aY,
--                              PangoLayoutLine *aLine,
--                              const nscoord *aSpacing);
-+    void ApplySpacing(const gchar *aText,
-+                      PRUint32 aLength,
-+                      PangoLayoutLine *aLine,
-+                      const nscoord *aSpacing);
-+    void ApplySpacing(const PRUnichar *aText,
-+                      PRUint32 aLength,
-+                      PangoLayoutLine *aLine,
-+                      const nscoord *aSpacing);
-     nsresult GetTextDimensionsInternal(const gchar*        aString,
-                                        PRInt32             aLength,
-@@ -289,10 +342,20 @@ private:
-                                        PRInt32             aNumBreaks,
-                                        nsTextDimensions&   aDimensions,
-                                        PRInt32&            aNumCharsFit,
--                                       nsTextDimensions&   aLastWordDimensions,
--                                       nsRenderingContextGTK *aContext);
-+                                       nsTextDimensions&   aLastWordDimensions
-+                                       CONTEXT_ARG_DEF);
-+#ifdef MOZ_MATHML
-+    void GetBoundingMetricsInternal(PangoLayout *aLayout,
-+                                    nsBoundingMetrics &aBoundingMetrics
-+                                    CONTEXT_ARG_DEF);
-+#endif /* MOZ_MATHML */
-+
-+    void FixupSpaceWidths (PangoLayout *aLayout);
--    void FixupSpaceWidths (PangoLayout *aLayout, const char *aString);
-+    PangoLayout* GetLayout (const PRUnichar* aText,
-+                            PRUint32         aLength);
-+    PangoLayout* GetLayout (const gchar*     aText,
-+                            PRInt32          aLength);
- };
- class nsFontEnumeratorPango : public nsIFontEnumerator
diff --git a/mozilla-firefox-pango-printing.patch b/mozilla-firefox-pango-printing.patch
deleted file mode 100644 (file)
index 0490892..0000000
+++ /dev/null
@@ -1,4586 +0,0 @@
-Patch for Firefox 1.5.0.7 to add support for printing via Pango.
-This also implements printing MathML via Pango, and prints bitmap
-fonts too.
-
-Authors:
-       Behdad Esfahbod
-       Chris Blizzard
-       Akira TAGOH
-
-Index: gfx/src/freetype/nsFreeType.cpp
-===================================================================
-RCS file: /cvsroot/mozilla/gfx/src/freetype/nsFreeType.cpp,v
-retrieving revision 1.28
-diff -u -p -d -r1.28 nsFreeType.cpp
---- gfx/src/freetype/nsFreeType.cpp    13 Jul 2005 18:21:10 -0000      1.28
-+++ gfx/src/freetype/nsFreeType.cpp    23 Oct 2006 17:37:09 -0000
-@@ -123,6 +123,8 @@ FtFuncList nsFreeType2::FtFuncs [] = {
- // #endif
-   {"FT_Get_First_Char",       NS_FT2_OFFSET(nsFT_Get_First_Char),       PR_FALSE},
-   {"FT_Get_Next_Char",        NS_FT2_OFFSET(nsFT_Get_Next_Char),        PR_FALSE},
-+  {"FT_Has_PS_Glyph_Names",   NS_FT2_OFFSET(nsFT_Has_PS_Glyph_Names),   PR_FALSE},
-+  {"FT_Get_Glyph_Name",       NS_FT2_OFFSET(nsFT_Get_Glyph_Name),       PR_TRUE},
-   {nsnull,                    0, 0}
- };
-@@ -388,6 +390,22 @@ nsFreeType2::GetNextChar(FT_Face face, F
- } 
- NS_IMETHODIMP
-+nsFreeType2::HasPSGlyphNames(FT_Face face, FT_Int *result)
-+{
-+  // call the FreeType2 function via the function pointer
-+  *result = nsFT_Has_PS_Glyph_Names(face);
-+  return NS_OK;
-+}
-+
-+NS_IMETHODIMP
-+nsFreeType2::GetGlyphName(FT_Face face, FT_UInt glyph_index, FT_Pointer buffer, FT_UInt buffer_max)
-+{
-+  // call the FreeType2 function via the function pointer
-+  FT_Error error = nsFT_Get_Glyph_Name(face, glyph_index, buffer, buffer_max);
-+  return error ? NS_ERROR_FAILURE : NS_OK;
-+}
-+
-+NS_IMETHODIMP
- nsFreeType2::SupportsExtFunc(PRBool *res)
- { 
-   *res = gHasExtFunc;
-Index: gfx/src/freetype/nsFreeType.h
-===================================================================
-RCS file: /cvsroot/mozilla/gfx/src/freetype/nsFreeType.h,v
-retrieving revision 1.18
-diff -u -p -d -r1.18 nsFreeType.h
---- gfx/src/freetype/nsFreeType.h      1 May 2005 17:36:19 -0000       1.18
-+++ gfx/src/freetype/nsFreeType.h      23 Oct 2006 17:37:09 -0000
-@@ -52,6 +52,7 @@
- #include FT_CACHE_H
- #include FT_CACHE_IMAGE_H
- #include FT_TRUETYPE_TABLES_H
-+#include FT_TYPE1_TABLES_H
- #include "nsIFreeType2.h"
- typedef struct FT_FaceRec_*  FT_Face;
-@@ -138,6 +139,8 @@ typedef FT_Error (*FT_Glyph_To_Bitmap_t)
- typedef FT_ULong (*FT_Get_First_Char_t)(FT_Face, FT_UInt*);
- typedef FT_ULong (*FT_Get_Next_Char_t)(FT_Face, FT_ULong, FT_UInt*);
-+typedef FT_Int   (*FT_Has_PS_Glyph_Names_t)(FT_Face);
-+typedef FT_Error (*FT_Get_Glyph_Name_t)(FT_Face, FT_UInt, FT_Pointer, FT_UInt);
- class nsFreeTypeFace;
-@@ -193,11 +196,13 @@ protected:
- // #endif
-   FT_Get_First_Char_t       nsFT_Get_First_Char;
-   FT_Get_Next_Char_t        nsFT_Get_Next_Char;
-+  FT_Has_PS_Glyph_Names_t   nsFT_Has_PS_Glyph_Names;
-+  FT_Get_Glyph_Name_t       nsFT_Get_Glyph_Name;
-   // this array needs to be big enough to hold all the function pointers
-   // plus one extra for the null at the end
- // #ifdef MOZ_SVG
--  static FtFuncList FtFuncs[24];
-+  static FtFuncList FtFuncs[28];
- // #else
- //  static FtFuncList FtFuncs[20];
- // #endif
-Index: gfx/src/ps/Makefile.in
-===================================================================
-RCS file: /cvsroot/mozilla/gfx/src/ps/Makefile.in,v
-retrieving revision 1.57.8.1
-diff -d -u -p -r1.57.8.1 Makefile.in
---- gfx/src/ps/Makefile.in     17 Jun 2006 15:16:14 -0000      1.57.8.1
-+++ gfx/src/ps/Makefile.in     24 Oct 2006 18:36:45 -0000
-@@ -98,6 +98,15 @@ EXTRA_DSO_LDOPTS = \
-               $(MOZ_UNICHARUTIL_LIBS) \
-               $(NULL)
-+ifdef MOZ_ENABLE_PANGO
-+CPPSRCS                += \
-+               nsFontMetricsPSPango.cpp \
-+               mozilla-ps-decoder.cpp
-+EXTRA_DSO_LDOPTS += $(MOZ_PANGO_LIBS)
-+CXXFLAGS       += $(MOZ_PANGO_CFLAGS)
-+CFLAGS         += $(MOZ_PANGO_CFLAGS)
-+endif
-+
- ifdef MOZ_ENABLE_XFT
- EXTRA_DSO_LDOPTS += \
-               $(MOZ_XFT_LIBS) \
-@@ -105,7 +114,7 @@ EXTRA_DSO_LDOPTS += \
-               $(NULL)
- endif
--ifneq (,$(MOZ_ENABLE_FREETYPE2)$(MOZ_ENABLE_XFT))
-+ifneq (,$(MOZ_ENABLE_FREETYPE2)$(MOZ_ENABLE_XFT)$(MOZ_ENABLE_PANGO))
- CPPSRCS               += \
-               nsType1.cpp \
-               $(NULL)
-Index: gfx/src/ps/mozilla-ps-decoder.cpp
-===================================================================
-RCS file: gfx/src/ps/mozilla-ps-decoder.cpp
-diff -N gfx/src/ps/mozilla-ps-decoder.cpp
---- /dev/null  1 Jan 1970 00:00:00 -0000
-+++ gfx/src/ps/mozilla-ps-decoder.cpp  23 Oct 2006 17:37:10 -0000
-@@ -0,0 +1,376 @@
-+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-+/* vim:expandtab:shiftwidth=4:tabstop=4:
-+ */
-+/* ***** BEGIN LICENSE BLOCK *****
-+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
-+ *
-+ * The contents of this file are subject to the Mozilla Public License Version
-+ * 1.1 (the "License"); you may not use this file except in compliance with
-+ * the License. You may obtain a copy of the License at
-+ * http://www.mozilla.org/MPL/
-+ *
-+ * Software distributed under the License is distributed on an "AS IS" basis,
-+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-+ * for the specific language governing rights and limitations under the
-+ * License.
-+ *
-+ * The Original Code is mozilla.org code.
-+ *
-+ * The Initial Developer of the Original Code is Christopher Blizzard
-+ * <blizzard@mozilla.org>.  Portions created by the Initial Developer
-+ * are Copyright (C) 2004 the Initial Developer. All Rights Reserved.
-+ *
-+ * Contributor(s):
-+ *
-+ * 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
-+ * of those above. If you wish to allow use of your version of this file only
-+ * under the terms of either the GPL or the LGPL, and not to allow others to
-+ * 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 ***** */
-+
-+#define PANGO_ENABLE_BACKEND
-+#define PANGO_ENABLE_ENGINE
-+
-+#include "mozilla-ps-decoder.h"
-+#include <pango/pangofc-fontmap.h>
-+#include <pango/pangofc-font.h>
-+
-+#include "nsString.h"
-+#include "nsIPersistentProperties2.h"
-+#include "nsNetUtil.h"
-+#include "nsReadableUtils.h"
-+#include "nsICharsetConverterManager.h"
-+#include "nsICharRepresentable.h"
-+#include "nsCompressedCharMap.h"
-+
-+#undef DEBUG_CUSTOM_ENCODER
-+
-+G_DEFINE_TYPE (MozillaPSDecoder, mozilla_ps_decoder, PANGO_TYPE_FC_DECODER)
-+
-+MozillaPSDecoder *mozilla_ps_decoder_new      (void);
-+
-+static FcCharSet  *mozilla_ps_decoder_get_charset (PangoFcDecoder *decoder,
-+                                                PangoFcFont    *fcfont);
-+static PangoGlyph  mozilla_ps_decoder_get_glyph   (PangoFcDecoder *decoder,
-+                                                PangoFcFont    *fcfont,
-+                                                guint32         wc);
-+
-+static PangoFcDecoder *mozilla_find_ps_decoder    (FcPattern *pattern,
-+                                                gpointer   user_data);
-+
-+typedef struct _MozillaPSDecoderPrivate MozillaPSDecoderPrivate;
-+
-+#define MOZILLA_PS_DECODER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MOZILLA_TYPE_DECODER, MozillaPSDecoderPrivate))
-+
-+struct _MozillaPSDecoderPrivate {
-+    char *family;
-+    char *encoder;
-+    char *cmap;
-+    gboolean is_wide;
-+    FcCharSet *charset;
-+    nsCOMPtr<nsIUnicodeEncoder> uEncoder;
-+};
-+
-+static nsICharsetConverterManager *gCharsetManager = NULL;
-+
-+static NS_DEFINE_CID(kCharsetConverterManagerCID,
-+                     NS_ICHARSETCONVERTERMANAGER_CID);
-+
-+// Hash tables that hold the custom encodings and custom cmaps used in
-+// various fonts.
-+static GHashTable *encoder_hash = NULL;
-+static GHashTable *cmap_hash = NULL;
-+static GHashTable *wide_hash = NULL;
-+
-+void
-+mozilla_ps_decoder_init (MozillaPSDecoder *decoder)
-+{
-+}
-+
-+void
-+mozilla_ps_decoder_class_init (MozillaPSDecoderClass *klass)
-+{
-+    GObjectClass *object_class = G_OBJECT_CLASS(klass);
-+    PangoFcDecoderClass *parent_class = PANGO_FC_DECODER_CLASS (klass);
-+
-+    /*   object_class->finalize = test_finalize; */
-+
-+    parent_class->get_charset = mozilla_ps_decoder_get_charset;
-+    parent_class->get_glyph = mozilla_ps_decoder_get_glyph;
-+
-+    g_type_class_add_private (object_class, sizeof (MozillaPSDecoderPrivate));
-+}
-+
-+MozillaPSDecoder *
-+mozilla_ps_decoder_new(void)
-+{
-+    return (MozillaPSDecoder *)g_object_new(MOZILLA_TYPE_DECODER, NULL);
-+}
-+
-+#ifdef DEBUG_CUSTOM_ENCODER
-+void
-+dump_hash(char *key, char *val, void *arg)
-+{
-+    printf("%s -> %s\n", key, val);
-+}
-+#endif
-+
-+/**
-+ * mozilla_ps_decoders_init:
-+ *
-+ * #mozilla_ps_decoders_init:
-+ *
-+ * This initializes all of the application-specific custom decoders
-+ * that Mozilla uses.  This should only be called once during the
-+ * lifetime of the application.
-+ *
-+ * Return value: zero on success, not zero on failure.
-+ *
-+ **/
-+
-+int
-+mozilla_ps_decoders_init(PangoFontMap *fontmap)
-+{
-+    static PRBool initialized = PR_FALSE;
-+    if (initialized)
-+        return 0;
-+
-+    if (!PANGO_IS_FC_FONT_MAP (fontmap))
-+        return -1;
-+
-+    encoder_hash = g_hash_table_new(g_str_hash, g_str_equal);
-+    cmap_hash = g_hash_table_new(g_str_hash, g_str_equal);
-+    wide_hash = g_hash_table_new(g_str_hash, g_str_equal);
-+
-+    PRBool dumb = PR_FALSE;
-+    nsCOMPtr<nsIPersistentProperties> props;
-+    nsCOMPtr<nsISimpleEnumerator> encodeEnum;
-+
-+    NS_LoadPersistentPropertiesFromURISpec(getter_AddRefs(props),
-+        NS_LITERAL_CSTRING("resource://gre/res/fonts/pangoFontEncoding.properties"));
-+
-+    if (!props)
-+        goto loser;
-+
-+    // Enumerate the properties in this file and figure out all of the
-+    // fonts for which we have custom encodings.
-+    props->Enumerate(getter_AddRefs(encodeEnum));
-+    if (!encodeEnum)
-+        goto loser;
-+
-+    while (encodeEnum->HasMoreElements(&dumb), dumb) {
-+        nsCOMPtr<nsIPropertyElement> prop;
-+        encodeEnum->GetNext(getter_AddRefs(prop));
-+        if (!prop)
-+            goto loser;
-+
-+        nsCAutoString name;
-+        prop->GetKey(name);
-+        nsAutoString value;
-+        prop->GetValue(value);
-+
-+        if (!StringBeginsWith(name, NS_LITERAL_CSTRING("encoding."))) {
-+            printf("string doesn't begin with encoding?\n");
-+            continue;
-+        }
-+
-+        name = Substring(name, 9);
-+
-+        if (StringEndsWith(name, NS_LITERAL_CSTRING(".ttf"))) {
-+            name = Substring(name, 0, name.Length() - 4);
-+
-+            // Strip off a .wide if it's there.
-+            if (StringEndsWith(value, NS_LITERAL_STRING(".wide"))) {
-+                g_hash_table_insert(wide_hash, g_strdup(name.get()),
-+                                    g_strdup("wide"));
-+                value = Substring(value, 0, name.Length() - 5);
-+            }
-+
-+            g_hash_table_insert(encoder_hash,
-+                                g_strdup(name.get()),
-+                                g_strdup(NS_ConvertUTF16toUTF8(value).get()));
-+        }
-+        else if (StringEndsWith(name, NS_LITERAL_CSTRING(".ftcmap"))) {
-+            name = Substring(name, 0, name.Length() - 7);
-+            g_hash_table_insert(cmap_hash,
-+                                g_strdup(name.get()),
-+                                g_strdup(NS_ConvertUTF16toUTF8(value).get()));
-+        }
-+        else {
-+            printf("unknown suffix used for mapping\n");
-+        }
-+    }
-+
-+    pango_fc_font_map_add_decoder_find_func(PANGO_FC_FONT_MAP(fontmap),
-+                                            mozilla_find_ps_decoder,
-+                                            NULL,
-+                                            NULL);
-+
-+    initialized = PR_TRUE;
-+
-+#ifdef DEBUG_CUSTOM_ENCODER
-+    printf("*** encoders\n");
-+    g_hash_table_foreach(encoder_hash, (GHFunc)dump_hash, NULL);
-+
-+    printf("*** cmaps\n");
-+    g_hash_table_foreach(cmap_hash, (GHFunc)dump_hash, NULL);
-+#endif
-+
-+    return 0;
-+
-+ loser:
-+    return -1;
-+}
-+
-+static FcCharSet *
-+mozilla_ps_decoder_get_charset (PangoFcDecoder *decoder,
-+                             PangoFcFont    *fcfont)
-+{
-+    MozillaPSDecoderPrivate *priv = MOZILLA_PS_DECODER_GET_PRIVATE(decoder);
-+
-+    if (priv->charset)
-+        return priv->charset;
-+
-+    // First time this has been accessed.  Populate the charset.
-+    priv->charset = FcCharSetCreate();
-+
-+    if (!gCharsetManager) {
-+        CallGetService(kCharsetConverterManagerCID, &gCharsetManager);
-+    }
-+
-+    nsCOMPtr<nsIUnicodeEncoder> encoder;
-+    nsCOMPtr<nsICharRepresentable> represent;
-+
-+    if (!gCharsetManager)
-+        goto end;
-+
-+    gCharsetManager->GetUnicodeEncoderRaw(priv->encoder, getter_AddRefs(encoder));
-+    if (!encoder)
-+        goto end;
-+    
-+    encoder->SetOutputErrorBehavior(encoder->kOnError_Replace, nsnull, '?');
-+
-+    priv->uEncoder = encoder;
-+
-+    represent = do_QueryInterface(encoder);
-+    if (!represent)
-+        goto end;
-+
-+    PRUint32 map[UCS2_MAP_LEN];
-+    memset(map, 0, sizeof(map));
-+
-+    represent->FillInfo(map);
-+
-+    for (int i = 0; i < NUM_UNICODE_CHARS; i++) {
-+        if (IS_REPRESENTABLE(map, i))
-+            FcCharSetAddChar(priv->charset, i);
-+    }
-+
-+ end:
-+    return priv->charset;
-+}
-+
-+static PangoGlyph
-+mozilla_ps_decoder_get_glyph   (PangoFcDecoder *decoder,
-+                             PangoFcFont    *fcfont,
-+                             guint32         wc)
-+{
-+    MozillaPSDecoderPrivate *priv = MOZILLA_PS_DECODER_GET_PRIVATE(decoder);
-+
-+    PangoGlyph retval = 0;
-+    PRUnichar inchar = wc;
-+    PRInt32 inlen = 1;
-+    char outchar[2] = {0,0};
-+    PRInt32 outlen = 2;
-+
-+    priv->uEncoder->Convert(&inchar, &inlen, outchar, &outlen);
-+    if (outlen != 1) {
-+        printf("Warning: mozilla_ps_decoder_get_glyph doesn't support more than one character conversions.\n");
-+        return 0;
-+    }
-+
-+    FT_Face face = pango_fc_font_lock_face(fcfont);
-+
-+#ifdef DEBUG_CUSTOM_ENCODER
-+    char *filename;
-+    FcPatternGetString(fcfont->font_pattern, FC_FILE, 0, (FcChar8 **)&filename);
-+    printf("filename is %s\n", filename);
-+#endif
-+
-+    // Make sure to set the right charmap before trying to get the
-+    // glyph
-+    if (priv->cmap) {
-+        if (!strcmp(priv->cmap, "mac_roman")) {
-+            FT_Select_Charmap(face, ft_encoding_apple_roman);
-+        }
-+        else if (!strcmp(priv->cmap, "unicode")) {
-+            FT_Select_Charmap(face, ft_encoding_unicode);
-+        }
-+        else {
-+            printf("Warning: Invalid charmap entry for family %s\n",
-+                   priv->family);
-+        }
-+    }
-+
-+    // Standard 8 bit to glyph translation
-+    if (!priv->is_wide) {
-+        FcChar32 blah = PRUint8(outchar[0]);
-+        retval = FT_Get_Char_Index(face, blah);
-+#ifdef DEBUG_CUSTOM_ENCODER
-+        printf("wc 0x%x outchar[0] 0x%x index 0x%x retval 0x%x face %p\n",
-+               wc, outchar[0], blah, retval, (void *)face);
-+#endif
-+    }
-+    else {
-+        printf("Warning: We don't support .wide fonts!\n");
-+        retval = 0;
-+    }
-+
-+    pango_fc_font_unlock_face(fcfont);
-+
-+    return retval;
-+}
-+
-+static PangoFcDecoder *
-+mozilla_find_ps_decoder (FcPattern *pattern, gpointer user_data)
-+{
-+    // Compare the family name of the font that's been opened to see
-+    // if we have a custom decoder.
-+    const char *orig = NULL;
-+    FcPatternGetString(pattern, FC_FAMILY, 0, (FcChar8 **)&orig);
-+
-+    nsCAutoString family;
-+    family.Assign(orig);
-+
-+    family.StripWhitespace();
-+    ToLowerCase(family);
-+
-+    char *encoder = (char *)g_hash_table_lookup(encoder_hash, family.get());
-+    if (!encoder)
-+        return NULL;
-+
-+    MozillaPSDecoder *decoder = mozilla_ps_decoder_new();
-+
-+    MozillaPSDecoderPrivate *priv = MOZILLA_PS_DECODER_GET_PRIVATE(decoder);
-+
-+    priv->family = g_strdup(family.get());
-+    priv->encoder = g_strdup(encoder);
-+
-+    char *cmap = (char *)g_hash_table_lookup(cmap_hash, family.get());
-+    if (cmap)
-+        priv->cmap = g_strdup(cmap);
-+
-+    char *wide = (char *)g_hash_table_lookup(wide_hash, family.get());
-+    if (wide)
-+        priv->is_wide = TRUE;
-+
-+    return PANGO_FC_DECODER(decoder);
-+}
-Index: gfx/src/ps/mozilla-ps-decoder.h
-===================================================================
-RCS file: gfx/src/ps/mozilla-ps-decoder.h
-diff -N gfx/src/ps/mozilla-ps-decoder.h
---- /dev/null  1 Jan 1970 00:00:00 -0000
-+++ gfx/src/ps/mozilla-ps-decoder.h    23 Oct 2006 17:37:10 -0000
-@@ -0,0 +1,72 @@
-+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-+/* vim:expandtab:shiftwidth=4:tabstop=4:
-+ */
-+/* ***** BEGIN LICENSE BLOCK *****
-+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
-+ *
-+ * The contents of this file are subject to the Mozilla Public License Version
-+ * 1.1 (the "License"); you may not use this file except in compliance with
-+ * the License. You may obtain a copy of the License at
-+ * http://www.mozilla.org/MPL/
-+ *
-+ * Software distributed under the License is distributed on an "AS IS" basis,
-+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-+ * for the specific language governing rights and limitations under the
-+ * License.
-+ *
-+ * The Original Code is mozilla.org code.
-+ *
-+ * The Initial Developer of the Original Code is Christopher Blizzard
-+ * <blizzard@mozilla.org>.  Portions created by the Initial Developer
-+ * are Copyright (C) 2004 the Initial Developer. All Rights Reserved.
-+ *
-+ * Contributor(s):
-+ *
-+ * 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
-+ * of those above. If you wish to allow use of your version of this file only
-+ * under the terms of either the GPL or the LGPL, and not to allow others to
-+ * 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 ***** */
-+
-+#ifndef _MOZILLA_PS_DECODER_H
-+#define _MOZILLA_PS_DECODER_H
-+
-+#include <pango/pangofc-decoder.h>
-+
-+G_BEGIN_DECLS
-+
-+#define MOZILLA_TYPE_DECODER (mozilla_ps_decoder_get_type())
-+#define MOZILLA_PS_DECODER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), MOZILLA_TYPE_DECODER, MozillaPSDecoder))
-+#define MOZILLA_IS_DECODER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), MOZILLA_TYPE_DECODER))
-+
-+typedef struct _MozillaPSDecoder      MozillaPSDecoder;
-+typedef struct _MozillaPSDecoderClass MozillaPSDecoderClass;
-+
-+#define MOZILLA_PS_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MOZILLA_TYPE_DECODER, MozillaPSDecoderClass))
-+#define MOZILLA_IS_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MOZILLA_TYPE_DECODER))
-+#define MOZILLA_PS_DECODER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MOZILLA_TYPE_DECODER, MozillaPSDecoderClass))
-+
-+struct _MozillaPSDecoder
-+{
-+  PangoFcDecoder parent_instance;
-+};
-+
-+struct _MozillaPSDecoderClass
-+{
-+  PangoFcDecoderClass parent_class;
-+};
-+
-+GType           mozilla_ps_decoder_get_type (void);
-+int             mozilla_ps_decoders_init    (PangoFontMap *fontmap);
-+
-+G_END_DECLS
-+
-+#endif /*_MOZILLA_PS_DECODER_H */
-Index: gfx/src/ps/nsDeviceContextPS.cpp
-===================================================================
-RCS file: /cvsroot/mozilla/gfx/src/ps/nsDeviceContextPS.cpp,v
-retrieving revision 1.73
-diff -u -p -d -r1.73 nsDeviceContextPS.cpp
---- gfx/src/ps/nsDeviceContextPS.cpp   21 May 2005 15:33:08 -0000      1.73
-+++ gfx/src/ps/nsDeviceContextPS.cpp   23 Oct 2006 17:37:10 -0000
-@@ -58,12 +58,15 @@
- #include "nsIPref.h"
- #include "nsString.h"
- #include "nsFontMetricsPS.h"
-+#ifdef MOZ_ENABLE_PANGO
-+#include "nsFontMetricsPSPango.h"
-+#endif
- #include "nsPostScriptObj.h"
- #include "nspr.h"
- #include "nsILanguageAtomService.h"
- #include "nsPrintJobPS.h"
- #include "nsPrintJobFactoryPS.h"
--#if defined(MOZ_ENABLE_FREETYPE2) || defined(MOZ_ENABLE_XFT)
-+#if defined(MOZ_ENABLE_FREETYPE2) || defined(MOZ_ENABLE_XFT) || defined(MOZ_ENABLE_PANGO)
- #include "nsType1.h"
- #endif
-@@ -223,7 +226,7 @@ nsDeviceContextPS::InitDeviceContextPS(n
-  
-   nsresult rv;
-   nsCOMPtr<nsIPref> pref(do_GetService(NS_PREF_CONTRACTID, &rv));
--#ifdef MOZ_ENABLE_XFT
-+#if defined(MOZ_ENABLE_XFT) || defined(MOZ_ENABLE_PANGO)
-   if (NS_SUCCEEDED(rv)) {
-       rv = pref->GetBoolPref("font.FreeType2.printing", &mFTPEnable);
-       if (NS_FAILED(rv))
-@@ -469,7 +472,7 @@ NS_IMETHODIMP nsDeviceContextPS::EndDocu
-       NS_ASSERTION(submitFP, "No print job submission handle");
-       // Start writing the print job to the job handler
--#if defined(MOZ_ENABLE_FREETYPE2) || defined(MOZ_ENABLE_XFT)
-+#if defined(MOZ_ENABLE_FREETYPE2) || defined(MOZ_ENABLE_XFT) || defined(MOZ_ENABLE_PANGO)
-       mPSObj->write_prolog(submitFP, mFTPEnable);
- #else 
-       mPSObj->write_prolog(submitFP);
-@@ -550,15 +553,52 @@ public:
-   virtual nsresult CreateFontMetricsInstance(nsIFontMetrics** aResult);
- };
-+#if defined(MOZ_ENABLE_PANGO)
-+PRBool
-+NS_IsPangoEnabled(void)
-+{
-+    static PRBool beenHere;
-+    static PRBool pangoEnabled;
-+
-+    if (!beenHere) {
-+        beenHere = PR_TRUE;
-+
-+        char *val = PR_GetEnv("MOZ_DISABLE_PANGO");
-+        pangoEnabled = !(val);
-+
-+        if (pangoEnabled) {
-+            nsCOMPtr<nsIPref> prefService = do_GetService(NS_PREF_CONTRACTID);
-+            if (prefService)
-+                prefService->SetDefaultCharPref("general.useragent.extra.pango",
-+                                                "pango-text");
-+        }
-+    }
-+
-+    return pangoEnabled;
-+}
-+#endif
- nsresult nsFontCachePS::CreateFontMetricsInstance(nsIFontMetrics** aResult)
- {
-   NS_PRECONDITION(aResult, "null out param");
--  nsIFontMetrics *fm = new nsFontMetricsPS();
--  if (!fm)
--    return NS_ERROR_OUT_OF_MEMORY;
--  NS_ADDREF(fm);
--  *aResult = fm;
-+#ifdef MOZ_ENABLE_PANGO
-+  if (NS_IsPangoEnabled())
-+  {
-+    nsIFontMetrics *fm = new nsFontMetricsPSPango();
-+    if (!fm)
-+      return NS_ERROR_OUT_OF_MEMORY;
-+    NS_ADDREF(fm);
-+    *aResult = fm;
-+  }
-+  else
-+#endif
-+  {
-+    nsIFontMetrics *fm = new nsFontMetricsPS();
-+    if (!fm)
-+      return NS_ERROR_OUT_OF_MEMORY;
-+    NS_ADDREF(fm);
-+    *aResult = fm;
-+  }
-   return NS_OK;
- }
-Index: gfx/src/ps/nsFontMetricsPS.cpp
-===================================================================
-RCS file: /cvsroot/mozilla/gfx/src/ps/nsFontMetricsPS.cpp,v
-retrieving revision 1.57.16.2
-diff -u -p -d -r1.57.16.2 nsFontMetricsPS.cpp
---- gfx/src/ps/nsFontMetricsPS.cpp     7 May 2006 02:01:25 -0000       1.57.16.2
-+++ gfx/src/ps/nsFontMetricsPS.cpp     23 Oct 2006 17:37:11 -0000
-@@ -461,6 +461,239 @@ nsFontMetricsPS :: GetStringWidth(const 
-   return NS_OK;
- }
-+nsresult
-+nsFontMetricsPS::DrawString(const char *aString, PRUint32 aLength,
-+                               nscoord aX, nscoord aY,
-+                               const nscoord* aSpacing,
-+                               nsRenderingContextPS *aContext)
-+{
-+  nsPostScriptObj* psObj = aContext->GetPostScriptObj();
-+  // When FT2 printing is enabled, we don't need to set langgroup
-+#if defined(MOZ_ENABLE_FREETYPE2) || defined(MOZ_ENABLE_XFT)
-+  if (!NS_REINTERPRET_CAST(nsDeviceContextPS *, GetDeviceContext())->mFTPEnable) {
-+#endif
-+    nsCOMPtr<nsIAtom> langGroup;
-+    GetLangGroup(getter_AddRefs(langGroup));
-+    psObj->setlanggroup(langGroup);
-+#if defined(MOZ_ENABLE_FREETYPE2) || defined(MOZ_ENABLE_XFT)
-+  }
-+#endif
-+
-+  if (aLength == 0)
-+    return NS_OK;
-+  nsFontPS* fontPS = nsFontPS::FindFont(aString[0], Font(), this);
-+  NS_ENSURE_TRUE(fontPS, NS_ERROR_FAILURE);
-+  fontPS->SetupFont(aContext);
-+
-+  PRUint32 i, start = 0;
-+  for (i=0; i<aLength; i++) {
-+    nsFontPS* fontThisChar;
-+    fontThisChar = nsFontPS::FindFont(aString[i], Font(), this);
-+    NS_ENSURE_TRUE(fontThisChar, NS_ERROR_FAILURE);
-+    if (fontThisChar != fontPS) {
-+      // draw text up to this point
-+      aX += DrawString(aString+start, i-start, aX, aY, fontPS, 
-+                       aSpacing?aSpacing+start:nsnull, aContext);
-+      start = i;
-+
-+      // setup for following text
-+      fontPS = fontThisChar;
-+      fontPS->SetupFont(aContext);
-+    }
-+  }
-+
-+  // draw the last part
-+  if (aLength-start)
-+    DrawString(aString+start, aLength-start, aX, aY, fontPS, 
-+               aSpacing?aSpacing+start:nsnull, aContext);
-+
-+  return NS_OK;
-+}
-+
-+nsresult
-+nsFontMetricsPS::DrawString(const PRUnichar* aString, PRUint32 aLength,
-+                               nscoord aX, nscoord aY,
-+                               PRInt32 aFontID,
-+                               const nscoord* aSpacing,
-+                               nsRenderingContextPS *aContext)
-+{
-+  nsPostScriptObj* psObj = aContext->GetPostScriptObj();
-+#if defined(MOZ_ENABLE_FREETYPE2) || defined(MOZ_ENABLE_XFT)
-+  // When FT2 printing is enabled, we don't need to set langgroup
-+  if (!NS_REINTERPRET_CAST(nsDeviceContextPS *, GetDeviceContext())->mFTPEnable) {
-+#endif
-+    nsCOMPtr<nsIAtom> langGroup = nsnull;
-+    GetLangGroup(getter_AddRefs(langGroup));
-+    psObj->setlanggroup(langGroup);
-+#if defined(MOZ_ENABLE_FREETYPE2) || defined(MOZ_ENABLE_XFT)
-+  }
-+#endif
-+
-+  /* build up conversion table */
-+  psObj->preshow(aString, aLength);
-+
-+  if (aLength == 0)
-+    return NS_OK;
-+  nsFontPS* fontPS = nsFontPS::FindFont(aString[0], Font(), this);
-+  NS_ENSURE_TRUE(fontPS, NS_ERROR_FAILURE);
-+  fontPS->SetupFont(aContext);
-+
-+  PRUint32 i, start = 0;
-+  for (i=0; i<aLength; i++) {
-+    nsFontPS* fontThisChar;
-+    fontThisChar = nsFontPS::FindFont(aString[i], Font(), this);
-+    NS_ENSURE_TRUE(fontThisChar, NS_ERROR_FAILURE);
-+    if (fontThisChar != fontPS) {
-+      // draw text up to this point
-+      aX += DrawString(aString+start, i-start, aX, aY, fontPS, 
-+                       aSpacing?aSpacing+start:nsnull, aContext);
-+      start = i;
-+
-+      // setup for following text
-+      fontPS = fontThisChar;
-+      fontPS->SetupFont(aContext);
-+    }
-+  }
-+
-+  // draw the last part
-+  if (aLength-start)
-+    DrawString(aString+start, aLength-start, aX, aY, fontPS, 
-+               aSpacing?aSpacing+start:nsnull, aContext);
-+
-+  return NS_OK;
-+}
-+
-+PRInt32
-+nsFontMetricsPS::DrawString(const char *aString, PRUint32 aLength,
-+                        nscoord aX, nscoord aY, nsFontPS* aFontPS,
-+                        const nscoord* aSpacing,
-+                      nsRenderingContextPS *aContext)
-+{
-+  nscoord width = 0;
-+  PRInt32 x = aX;
-+  PRInt32 y = aY;
-+
-+  PRInt32 dxMem[500];
-+  PRInt32* dx0 = 0;
-+  if (aSpacing) {
-+    dx0 = dxMem;
-+    if (aLength > 500) {
-+      dx0 = new PRInt32[aLength];
-+      NS_ENSURE_TRUE(dx0, NS_ERROR_OUT_OF_MEMORY);
-+    }
-+    aContext->GetTranMatrix()->ScaleXCoords(aSpacing, aLength, dx0);
-+  }
-+
-+  aContext->GetTranMatrix()->TransformCoord(&x, &y);
-+  width = aFontPS->DrawString(aContext, x, y, aString, aLength);
-+
-+  if ((aSpacing) && (dx0 != dxMem)) {
-+    delete [] dx0;
-+  }
-+
-+  return width;
-+}
-+
-+
-+PRInt32
-+nsFontMetricsPS::DrawString(const PRUnichar* aString, PRUint32 aLength,
-+                                 nscoord &aX, nscoord &aY, nsFontPS* aFontPS,
-+                                 const nscoord* aSpacing,
-+                               nsRenderingContextPS *aContext)
-+{
-+  nscoord width = 0;
-+  PRInt32 x = aX;
-+  PRInt32 y = aY;
-+
-+  if (aSpacing) {
-+    // Slow, but accurate rendering
-+    const PRUnichar* end = aString + aLength;
-+    while (aString < end){
-+      x = aX;
-+      y = aY;
-+      aContext->GetTranMatrix()->TransformCoord(&x, &y);
-+      aFontPS->DrawString(aContext, x, y, aString, 1);
-+      aX += *aSpacing++;
-+      aString++;
-+    }
-+    width = aX;
-+  } else {
-+    aContext->GetTranMatrix()->TransformCoord(&x, &y);
-+    width = aFontPS->DrawString(aContext, x, y, aString, aLength);
-+  }
-+
-+  return width;
-+}
-+
-+NS_IMETHODIMP
-+nsFontMetricsPS::GetTextDimensions(const char*       aString,
-+                                        PRInt32           aLength,
-+                                        PRInt32           aAvailWidth,
-+                                        PRInt32*          aBreaks,
-+                                        PRInt32           aNumBreaks,
-+                                        nsTextDimensions& aDimensions,
-+                                        PRInt32&          aNumCharsFit,
-+                                        nsTextDimensions& aLastWordDimensions,
-+                                        PRInt32*          aFontID)
-+{
-+  NS_NOTYETIMPLEMENTED("nsFontMetricsPS::GetTextDimensions");
-+  return NS_ERROR_NOT_IMPLEMENTED;
-+}
-+
-+NS_IMETHODIMP
-+nsFontMetricsPS::GetTextDimensions(const PRUnichar*  aString,
-+                                        PRInt32           aLength,
-+                                        PRInt32           aAvailWidth,
-+                                        PRInt32*          aBreaks,
-+                                        PRInt32           aNumBreaks,
-+                                        nsTextDimensions& aDimensions,
-+                                        PRInt32&          aNumCharsFit,
-+                                        nsTextDimensions& aLastWordDimensions,
-+                                        PRInt32*          aFontID)
-+{
-+  NS_NOTYETIMPLEMENTED("nsFontMetricsPS::GetTextDimensions");
-+  return NS_ERROR_NOT_IMPLEMENTED;
-+}
-+
-+NS_IMETHODIMP
-+nsFontMetricsPS :: GetTextDimensions(const char* aString, PRUint32 aLength,
-+                                          nsTextDimensions& aDimensions)
-+{
-+  GetStringWidth(aString, aDimensions.width, aLength);
-+  GetMaxAscent(aDimensions.ascent);
-+  GetMaxDescent(aDimensions.descent);
-+  return NS_OK;
-+}
-+
-+NS_IMETHODIMP
-+nsFontMetricsPS :: GetTextDimensions(const PRUnichar* aString, PRUint32 aLength,
-+                                          nsTextDimensions& aDimensions, PRInt32* aFontID)
-+{
-+  GetStringWidth(aString, aDimensions.width, aLength);
-+  //XXX temporary - bug 96609
-+  GetMaxAscent(aDimensions.ascent);
-+  GetMaxDescent(aDimensions.descent);
-+  return NS_OK;
-+}
-+
-+nsresult
-+nsFontMetricsPS::GetBoundingMetrics(const char*        aString,
-+                                     PRUint32           aLength,
-+                                     nsBoundingMetrics& aBoundingMetrics)
-+{
-+  return NS_ERROR_NOT_IMPLEMENTED;
-+}
-+
-+nsresult
-+nsFontMetricsPS::GetBoundingMetrics(const PRUnichar*   aString,
-+                                     PRUint32           aLength,
-+                                     nsBoundingMetrics &aBoundingMetrics,
-+                                     PRInt32 *aFontID)
-+{
-+  return NS_ERROR_NOT_IMPLEMENTED;
-+}
-+
-+
- nsFontPS*
- nsFontPS::FindFont(char aChar, const nsFont& aFont, 
-                    nsFontMetricsPS* aFontMetrics)
-@@ -1128,23 +1361,38 @@ nsFontPSXft::DrawString(nsRenderingConte
-   PRUint32 start = 0;
-   PRUint32 i;
-+  FT_Face face = getFTFace();
-+  if (!face) {
-+    NS_WARNING("Failed to get FT Face in nsFontPSXft::DrawString\n");
-+    return 0;
-+  }
-+
-+  nsValueArray glyphs(PR_UINT16_MAX);
-+
-   // XXX : ignore surrogate pairs for now
--  nsString *subSet = mPSFontGenerator->GetSubset();
-   for (i = 0; i < aLength; ++i) {
--    currSubFont = mPSFontGenerator->AddToSubset(aString[i]);
-+    PRUint32 glyph = FT_Get_Char_Index(face, aString[i]);
-+    currSubFont = mPSFontGenerator->AddToGlyphSubset(glyph);
-+
-+    // Check if we need to render the current string
-     if (prevSubFont != currSubFont) {
--      if (prevSubFont != -1)
--        psObj->show(&aString[start], i - start, *subSet, prevSubFont);
-+      if (prevSubFont != -1) {
-+        psObj->show(&glyphs, mPSFontGenerator, prevSubFont);
-+      }
-       NS_ASSERTION(!mFontNameBase.IsEmpty(),
-                   "font base name shouldn't be empty");
-       psObj->setfont(mFontNameBase, mHeight, currSubFont);
-       prevSubFont = currSubFont;
-       start = i;
-+      glyphs.Clear();
-     }
-+
-+    glyphs.AppendValue(glyph);
-   }
--  if (prevSubFont != -1)
--    psObj->show(&aString[start], i - start, *subSet, prevSubFont); 
-+  if (prevSubFont != -1) {
-+    psObj->show(&glyphs, mPSFontGenerator, prevSubFont);
-+  }
-   
-   return GetWidth(aString, aLength);
- }
-@@ -2278,10 +2526,13 @@ nsFontPSFreeType::GetBoundingMetrics(con
- // Implementation of nsPSFontGenerator
- nsPSFontGenerator::nsPSFontGenerator()
- {
-+  mGlyphSubset = new nsValueArray(PR_UINT16_MAX, 40);
- }
- nsPSFontGenerator::~nsPSFontGenerator()
- {
-+  if (mGlyphSubset)
-+    delete mGlyphSubset;
- }
- void nsPSFontGenerator::GeneratePSFont(FILE* aFile)
-@@ -2289,24 +2540,29 @@ void nsPSFontGenerator::GeneratePSFont(F
-   NS_ERROR("should never call nsPSFontGenerator::GeneratePSFont");
- }
--// Add a Unicode character to mSubset which will be divided into 
--// multiple chunks (subfonts) of 255 (kSubFontSize) characters each. 
--// Each chunk will be converted to a Type 1 font. Return the index of 
--// a subfont (chunk) this character belongs to.
-+// Add a glyph offset to mSubset which will be divided into multiple
-+// chunks (subfonts) of 255 (kSubFontSize) glyphs each.  Each chunk
-+// will then be converted into a Type 1 font.  Return the index of a
-+// subfont (chunk) this glyph belongs to.
- PRInt32
--nsPSFontGenerator::AddToSubset(PRUnichar aChar)
-+nsPSFontGenerator::AddToGlyphSubset(PRUint32 aGlyph)
- {
--  PRInt32 index = mSubset.FindChar(aChar);
--  if (index == kNotFound) {
--    mSubset.Append(aChar);
--    index = mSubset.Length() - 1;
-+  nsValueArrayIndex index = mGlyphSubset->IndexOf(aGlyph);
-+  if (index == NSVALUEARRAY_INVALID) {
-+    mGlyphSubset->AppendValue(aGlyph);
-+    index = mGlyphSubset->Count() - 1;
-   }
-+
-   return index / kSubFontSize;
- }
--nsString *nsPSFontGenerator::GetSubset()
-+PRInt32
-+nsPSFontGenerator::InSubsetIndexOf(PRUint32 aGlyph)
- {
--  return &mSubset;
-+  nsValueArrayIndex index = mGlyphSubset->IndexOf(aGlyph);
-+  if (index == NSVALUEARRAY_INVALID)
-+    return 0;
-+  return (index % kSubFontSize) + 1;
- }
- #ifdef MOZ_ENABLE_XFT
-@@ -2353,8 +2609,8 @@ void nsXftType1Generator::GeneratePSFont
-   }
-   int wmode = 0;
--  if (!mSubset.IsEmpty())
--    FT2SubsetToType1FontSet(face, mSubset, wmode, aFile);
-+  if (mGlyphSubset->Count())
-+    FT2SubsetToType1FontSet(face, mGlyphSubset, wmode, aFile);
- }
- #else
-@@ -2402,8 +2658,8 @@ void nsFT2Type1Generator::GeneratePSFont
-     return;
-  
-   int wmode = 0;
--  if (!mSubset.IsEmpty())
--    FT2SubsetToType1FontSet(face, mSubset, wmode, aFile);
-+  if (mGlyphSubset->Count())
-+    FT2SubsetToType1FontSet(face, mGlyphSubset, wmode, aFile);
- }
- #endif //MOZ_ENABLE_FREETYPE2
-Index: gfx/src/ps/nsFontMetricsPS.h
-===================================================================
-RCS file: /cvsroot/mozilla/gfx/src/ps/nsFontMetricsPS.h,v
-retrieving revision 1.31
-diff -u -p -d -r1.31 nsFontMetricsPS.h
---- gfx/src/ps/nsFontMetricsPS.h       28 Jun 2005 18:29:10 -0000      1.31
-+++ gfx/src/ps/nsFontMetricsPS.h       23 Oct 2006 17:37:11 -0000
-@@ -66,6 +66,7 @@
- #endif
- #include "nsVoidArray.h"
- #include "nsHashtable.h"
-+#include "nsValueArray.h"
- class nsPSFontGenerator;
- class nsDeviceContextPS;
-@@ -108,6 +109,65 @@ public:
-   NS_IMETHOD  GetFontHandle(nsFontHandle &aHandle);
-   NS_IMETHOD  GetStringWidth(const char *String,nscoord &aWidth,nscoord aLength);
-   NS_IMETHOD  GetStringWidth(const PRUnichar *aString,nscoord &aWidth,nscoord aLength);
-+
-+    NS_IMETHOD       GetTextDimensions(const char* aString,
-+                                       PRUint32 aLength,
-+                                       nsTextDimensions& aDimensions);
-+    NS_IMETHOD       GetTextDimensions(const PRUnichar* aString,
-+                                       PRUint32 aLength,
-+                                       nsTextDimensions& aDimensions, 
-+                                       PRInt32* aFontID);
-+    NS_IMETHOD       GetTextDimensions(const char*         aString,
-+                                       PRInt32             aLength,
-+                                       PRInt32             aAvailWidth,
-+                                       PRInt32*            aBreaks,
-+                                       PRInt32             aNumBreaks,
-+                                       nsTextDimensions&   aDimensions,
-+                                       PRInt32&            aNumCharsFit,
-+                                       nsTextDimensions&   aLastWordDimensions,
-+                                       PRInt32*            aFontID);
-+    NS_IMETHOD       GetTextDimensions(const PRUnichar*    aString,
-+                                       PRInt32             aLength,
-+                                       PRInt32             aAvailWidth,
-+                                       PRInt32*            aBreaks,
-+                                       PRInt32             aNumBreaks,
-+                                       nsTextDimensions&   aDimensions,
-+                                       PRInt32&            aNumCharsFit,
-+                                       nsTextDimensions&   aLastWordDimensions,
-+                                       PRInt32*            aFontID);
-+#ifdef MOZ_MATHML
-+    NS_IMETHOD       GetBoundingMetrics(const char *aString, PRUint32 aLength,
-+                                        nsBoundingMetrics &aBoundingMetrics);
-+    NS_IMETHOD       GetBoundingMetrics(const PRUnichar *aString,
-+                                        PRUint32 aLength,
-+                                        nsBoundingMetrics &aBoundingMetrics,
-+                                        PRInt32 *aFontID);
-+#endif /* MOZ_MATHML */
-+
-+  NS_IMETHOD DrawString(const char *aString, PRUint32 aLength,
-+                        nscoord aX, nscoord aY,
-+                        const nscoord* aSpacing,
-+                      nsRenderingContextPS *aContext);
-+  NS_IMETHOD DrawString(const PRUnichar *aString, PRUint32 aLength,
-+                        nscoord aX, nscoord aY,
-+                        PRInt32 aFontID,
-+                        const nscoord* aSpacing,
-+                      nsRenderingContextPS *aContext);
-+
-+protected:
-+  PRInt32 DrawString(const char *aString, PRUint32 aLength,
-+                        nscoord aX, nscoord aY, nsFontPS* aFontPS,
-+                        const nscoord* aSpacing,
-+                      nsRenderingContextPS *aContext);
-+  PRInt32 DrawString(const PRUnichar *aString, PRUint32 aLength,
-+                        nscoord &aX, nscoord &aY, nsFontPS* aFontPS,
-+                        const nscoord* aSpacing,
-+                      nsRenderingContextPS *aContext);
-+
-+public:
-+
-+  virtual PRUint32    GetHints     (void) { return 0; }
-+
-   
-   inline void SetXHeight(nscoord aXHeight) { mXHeight = aXHeight; };
-   inline void SetSuperscriptOffset(nscoord aSuperscriptOffset) { mSuperscriptOffset = aSuperscriptOffset; };
-@@ -455,16 +515,14 @@ public:
-   nsPSFontGenerator();
-   virtual ~nsPSFontGenerator();
-   virtual void  GeneratePSFont(FILE* aFile);
--  PRInt32  AddToSubset(PRUnichar aChar);
--  nsString *GetSubset();
-+  PRInt32  AddToGlyphSubset(PRUint32 aGlyph);
-+  PRInt32  InSubsetIndexOf(PRUint32 aGlyph);
-   // 256 (PS type 1 encoding vector size) - 1 (1 is for mandatory /.notdef)
-   const static PRUint16 kSubFontSize; 
- protected:
--  // XXX To support non-BMP characters, we may have to use 
--  // nsValueArray with PRUint32
--  nsString mSubset;
-+  nsValueArray *mGlyphSubset;
- };
-Index: gfx/src/ps/nsFontMetricsPSPango.cpp
-===================================================================
-RCS file: gfx/src/ps/nsFontMetricsPSPango.cpp
-diff -N gfx/src/ps/nsFontMetricsPSPango.cpp
---- /dev/null  1 Jan 1970 00:00:00 -0000
-+++ gfx/src/ps/nsFontMetricsPSPango.cpp        23 Oct 2006 17:37:13 -0000
-@@ -0,0 +1,2107 @@
-+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-+/* vim:expandtab:shiftwidth=4:tabstop=4:
-+ */
-+/* ***** BEGIN LICENSE BLOCK *****
-+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
-+ *
-+ * The contents of this file are subject to the Mozilla Public License Version
-+ * 1.1 (the "License"); you may not use this file except in compliance with
-+ * the License. You may obtain a copy of the License at
-+ * http://www.mozilla.org/MPL/
-+ *
-+ * Software distributed under the License is distributed on an "AS IS" basis,
-+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-+ * for the specific language governing rights and limitations under the
-+ * License.
-+ *
-+ * The Original Code is mozilla.org code.
-+ *
-+ * The Initial Developer of the Original Code is Christopher Blizzard
-+ * <blizzard@mozilla.org>.  Portions created by the Initial Developer
-+ * are Copyright (C) 2004 the Initial Developer. All Rights Reserved.
-+ *
-+ * Contributor(s):
-+ *   Christopher Blizzard <blizzard@mozilla.org>
-+ *   Behdad Esfahbod <behdad@behdad.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
-+ * of those above. If you wish to allow use of your version of this file only
-+ * under the terms of either the GPL or the LGPL, and not to allow others to
-+ * 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 ***** */
-+
-+#include <strings.h>
-+#include "nsFont.h"
-+#include "nsIDeviceContext.h"
-+#include "nsICharsetConverterManager.h"
-+#include "nsIPref.h"
-+#include "nsServiceManagerUtils.h"
-+
-+#define PANGO_ENABLE_BACKEND
-+#define PANGO_ENABLE_ENGINE
-+
-+#include "nsFontMetricsPSPango.h"
-+#include "nsRenderingContextPS.h"
-+#include "nsDeviceContextPS.h"
-+#include "nsFontConfigUtils.h"
-+
-+#include "nsPrintfCString.h"
-+#include "nsUnicharUtils.h"
-+#include "nsQuickSort.h"
-+#include "nsFontConfigUtils.h"
-+
-+#include <fontconfig/fontconfig.h>
-+#include <pango/pangoft2.h>
-+#include <freetype/tttables.h>
-+#include "nsType1.h"
-+
-+#include "mozilla-ps-decoder.h"
-+
-+#define FORCE_PR_LOG
-+#include "prlog.h"
-+
-+// Globals
-+
-+static PRLogModuleInfo            *gPangoFontLog;
-+static int                         gNumInstances;
-+
-+
-+static void
-+default_substitute (FcPattern *pattern,
-+                    gpointer   data)
-+{
-+  FcPatternDel (pattern, FC_HINTING);
-+  FcPatternAddBool (pattern, FC_HINTING, 0);
-+}
-+
-+static PangoFontMap *
-+get_fontmap (void)
-+{
-+  static PangoFontMap               *fontmap = NULL;
-+
-+  if (!fontmap) {
-+    fontmap = pango_ft2_font_map_new ();
-+    pango_ft2_font_map_set_resolution ((PangoFT2FontMap *)fontmap, 72., 72.);
-+    pango_ft2_font_map_set_default_substitute ((PangoFT2FontMap *)fontmap, default_substitute, NULL, NULL);
-+  }
-+
-+  return fontmap;
-+}
-+
-+static PangoContext *
-+get_context (void)
-+{
-+  return pango_ft2_font_map_create_context ((PangoFT2FontMap *) get_fontmap ());
-+}
-+
-+// Defines
-+
-+// This is the scaling factor that we keep fonts limited to against
-+// the display size.  If a pixel size is requested that is more than
-+// this factor larger than the height of the display, it's clamped to
-+// that value instead of the requested size.
-+#define FONT_MAX_FONT_SCALE 2
-+
-+static NS_DEFINE_CID(kCharsetConverterManagerCID,
-+                     NS_ICHARSETCONVERTERMANAGER_CID);
-+
-+#ifdef DEBUG
-+#define DUMP_PRUNICHAR(ustr, ulen) for (PRUint32 llen=0;llen<ulen;llen++) \
-+                                      printf("0x%x ", ustr[llen]); \
-+                                   printf("\n");
-+#endif
-+
-+// rounding and truncation functions for a Freetype floating point number 
-+// (FT26Dot6) stored in a 32bit integer with high 26 bits for the integer
-+// part and low 6 bits for the fractional part. 
-+#define MOZ_FT_ROUND(x) (((x) + 32) & ~63) // 63 = 2^6 - 1
-+#define MOZ_FT_TRUNC(x) ((x) >> 6)
-+#define CONVERT_DESIGN_UNITS_TO_PIXELS(v, s) \
-+        MOZ_FT_TRUNC(MOZ_FT_ROUND(FT_MulFix((v) , (s))))
-+
-+// Static function decls
-+
-+static PangoLanguage *GetPangoLanguage(nsIAtom *aLangGroup);
-+
-+static void   FreeGlobals    (void);
-+
-+static PangoStyle  CalculateStyle  (PRUint8 aStyle);
-+static PangoWeight CalculateWeight (PRUint16 aWeight);
-+
-+static nsresult    EnumFontsPango   (nsIAtom* aLangGroup, const char* aGeneric,
-+                                     PRUint32* aCount, PRUnichar*** aResult);
-+static int         CompareFontNames (const void* aArg1, const void* aArg2,
-+                                     void* aClosure);
-+
-+nsFontMetricsPSPango::nsFontMetricsPSPango()
-+{
-+    if (!gPangoFontLog)
-+        gPangoFontLog = PR_NewLogModule("PangoFont");
-+
-+    gNumInstances++;
-+
-+    mPangoFontDesc = nsnull;
-+    mPangoContext = nsnull;
-+    mLTRPangoContext = nsnull;
-+    mRTLPangoContext = nsnull;
-+    mPangoAttrList = nsnull;
-+    mIsRTL = PR_FALSE;
-+    mPangoSpaceWidth = 0;
-+
-+    static PRBool initialized = PR_FALSE;
-+    if (initialized)
-+        return;
-+
-+    // Initialized the custom decoders
-+    if (!mozilla_ps_decoders_init(get_fontmap ()))
-+        initialized = PR_TRUE;
-+}
-+
-+nsFontMetricsPSPango::~nsFontMetricsPSPango()
-+{
-+    if (mDeviceContext)
-+        mDeviceContext->FontMetricsDeleted(this);
-+
-+    if (mPangoFontDesc)
-+        pango_font_description_free(mPangoFontDesc);
-+
-+    if (mLTRPangoContext)
-+        g_object_unref(mLTRPangoContext);
-+
-+    if (mRTLPangoContext)
-+        g_object_unref(mRTLPangoContext);
-+
-+    if (mPangoAttrList)
-+        pango_attr_list_unref(mPangoAttrList);
-+
-+    // XXX clean up all the pango objects
-+
-+    if (--gNumInstances == 0)
-+        FreeGlobals();
-+}
-+
-+
-+NS_IMPL_ISUPPORTS1(nsFontMetricsPSPango, nsIFontMetrics)
-+
-+// nsIFontMetrics impl
-+
-+NS_IMETHODIMP
-+nsFontMetricsPSPango::Init(const nsFont& aFont, nsIAtom* aLangGroup,
-+                         nsIDeviceContext *aContext)
-+{
-+    mFont = aFont;
-+    mLangGroup = aLangGroup;
-+
-+    // Hang on to the device context
-+    mDeviceContext = aContext;
-+    
-+    mPointSize = NSTwipsToFloatPoints(mFont.size);
-+
-+    // enumerate over the font names passed in
-+    mFont.EnumerateFamilies(nsFontMetricsPSPango::EnumFontCallback, this);
-+
-+    nsCOMPtr<nsIPref> prefService;
-+    prefService = do_GetService(NS_PREF_CONTRACTID);
-+    if (!prefService)
-+        return NS_ERROR_FAILURE;
-+        
-+    nsXPIDLCString value;
-+    const char* langGroup;
-+    mLangGroup->GetUTF8String(&langGroup);
-+
-+    // Set up the default font name if it's not set
-+    if (!mGenericFont) {
-+        nsCAutoString name("font.default.");
-+        name.Append(langGroup);
-+        prefService->CopyCharPref(name.get(), getter_Copies(value));
-+
-+        if (value.get())
-+            mDefaultFont = value.get();
-+        else
-+            mDefaultFont = "serif";
-+        
-+        mGenericFont = &mDefaultFont;
-+    }
-+
-+    // set up the minimum sizes for fonts
-+    if (mLangGroup) {
-+        nsCAutoString name("font.min-size.");
-+
-+        if (mGenericFont->Equals("monospace"))
-+            name.Append("fixed");
-+        else
-+            name.Append("variable");
-+
-+        name.Append(char('.'));
-+        name.Append(langGroup);
-+
-+        PRInt32 minimumInt = 0;
-+        float minimum;
-+        nsresult res;
-+        res = prefService->GetIntPref(name.get(), &minimumInt);
-+        if (NS_FAILED(res))
-+            prefService->GetDefaultIntPref(name.get(), &minimumInt);
-+
-+        if (minimumInt < 0)
-+            minimumInt = 0;
-+
-+        minimum = minimumInt;
-+
-+        // The minimum size is specified in pixels, not in points.
-+        // Convert the size from pixels to points.
-+        minimum = NSTwipsToFloatPoints(NSFloatPixelsToTwips(minimum, mDeviceContext->DevUnitsToAppUnits()));
-+        if (mPointSize < minimum)
-+            mPointSize = minimum;
-+    }
-+
-+    // Make sure that the pixel size is at least greater than zero
-+    if (mPointSize < 1) {
-+#ifdef DEBUG
-+        printf("*** Warning: nsFontMetricsPSPango created with point size %f\n",
-+               mPointSize);
-+#endif
-+        mPointSize = 1;
-+    }
-+
-+    nsresult rv = RealizeFont();
-+    if (NS_FAILED(rv))
-+        return rv;
-+
-+    // Cache font metrics for the 'x' character
-+    return CacheFontMetrics();
-+}
-+
-+nsresult
-+nsFontMetricsPSPango::CacheFontMetrics(void)
-+{
-+    // Get our scale factor
-+    float f;
-+    float val;
-+    f = mDeviceContext->DevUnitsToAppUnits();
-+
-+    mPangoAttrList = pango_attr_list_new();
-+
-+    GList *items = pango_itemize(mPangoContext,
-+                                 "a", 0, 1, mPangoAttrList, NULL);
-+
-+    if (!items)
-+        return NS_ERROR_FAILURE;
-+
-+    guint nitems = g_list_length(items);
-+    if (nitems != 1)
-+        return NS_ERROR_FAILURE;
-+
-+    PangoItem *item = (PangoItem *)items->data;
-+    PangoFcFont  *fcfont = PANGO_FC_FONT(item->analysis.font);
-+    if (!fcfont)
-+        return NS_ERROR_FAILURE;
-+
-+    // Get our font face
-+    FT_Face face;
-+    face = pango_fc_font_lock_face(fcfont);
-+    if (!face)
-+      return NS_ERROR_NOT_AVAILABLE;
-+      
-+    TT_OS2 *os2;
-+    os2 = (TT_OS2 *) FT_Get_Sfnt_Table(face, ft_sfnt_os2);
-+
-+    // mEmHeight (size in pixels of EM height)
-+    int size;
-+    if (FcPatternGetInteger(fcfont->font_pattern, FC_PIXEL_SIZE, 0, &size) !=
-+        FcResultMatch) {
-+        size = 12;
-+    }
-+    mEmHeight = PR_MAX(1, nscoord(size * f));
-+
-+    // mMaxAscent
-+    val = MOZ_FT_TRUNC(face->size->metrics.ascender);
-+    mMaxAscent = NSToIntRound(val * f);
-+
-+    // mMaxDescent
-+    val = -MOZ_FT_TRUNC(face->size->metrics.descender);
-+    mMaxDescent = NSToIntRound(val * f);
-+
-+    nscoord lineHeight = mMaxAscent + mMaxDescent;
-+
-+    // mLeading (needs ascent and descent and EM height) 
-+    if (lineHeight > mEmHeight)
-+        mLeading = lineHeight - mEmHeight;
-+    else
-+        mLeading = 0;
-+
-+    // mMaxHeight (needs ascent and descent)
-+    mMaxHeight = lineHeight;
-+
-+    // mEmAscent (needs maxascent, EM height, ascent and descent)
-+    mEmAscent = nscoord(mMaxAscent * mEmHeight / lineHeight);
-+
-+    // mEmDescent (needs EM height and EM ascent
-+    mEmDescent = mEmHeight - mEmAscent;
-+
-+    // mMaxAdvance
-+    val = MOZ_FT_TRUNC(face->size->metrics.max_advance);
-+    mMaxAdvance = NSToIntRound(val * f);
-+
-+    // mPangoSpaceWidth
-+    PangoLayout *layout = pango_layout_new(mPangoContext);
-+    pango_layout_set_text(layout, " ", 1);
-+    int pswidth, psheight;
-+    pango_layout_get_size(layout, &pswidth, &psheight);
-+    mPangoSpaceWidth = pswidth;
-+    g_object_unref(layout);
-+
-+    // mSpaceWidth (width of a space)
-+    nscoord tmpWidth;
-+    GetWidth(" ", 1, tmpWidth);
-+    mSpaceWidth = tmpWidth;
-+
-+    // mAveCharWidth (width of an 'average' char)
-+    //    XftTextExtents16(GDK_DISPLAY(), xftFont, &xUnichar, 1, &extents);
-+    //rawWidth = extents.width;
-+    //mAveCharWidth = NSToCoordRound(rawWidth * f);
-+    GetWidth("x", 1, tmpWidth);
-+    mAveCharWidth = tmpWidth;
-+
-+    // mXHeight (height of an 'x' character)
-+    if (pango_fc_font_has_char(fcfont, 'x')) {
-+        PangoRectangle rect;
-+        PangoGlyph glyph = pango_fc_font_get_glyph (fcfont, 'x');
-+        pango_font_get_glyph_extents (PANGO_FONT (fcfont), glyph, &rect, NULL);
-+        mXHeight = NSToIntRound(rect.height * f / PANGO_SCALE);
-+    }
-+    else {
-+        // 56% of ascent, best guess for non-true type or asian fonts
-+        mXHeight = nscoord(((float)mMaxAscent) * 0.56 * f);
-+    }
-+
-+    // mUnderlineOffset (offset for underlines)
-+    val = CONVERT_DESIGN_UNITS_TO_PIXELS(face->underline_position,
-+                                         face->size->metrics.y_scale);
-+    if (val) {
-+        mUnderlineOffset = NSToIntRound(val * f);
-+    }
-+    else {
-+        mUnderlineOffset =
-+            -NSToIntRound(PR_MAX(1, floor(0.1 *
-+                MOZ_FT_TRUNC(face->size->metrics.height) + 0.5)) * f);
-+    }
-+
-+    // mUnderlineSize (thickness of an underline)
-+    val = CONVERT_DESIGN_UNITS_TO_PIXELS(face->underline_thickness,
-+                                         face->size->metrics.y_scale);
-+    if (val) {
-+        mUnderlineSize = nscoord(PR_MAX(f, NSToIntRound(val * f)));
-+    }
-+    else {
-+        mUnderlineSize =
-+            NSToIntRound(PR_MAX(1,
-+               floor(0.05 * MOZ_FT_TRUNC(face->size->metrics.height) + 0.5)) * f);
-+    }
-+
-+    // mSuperscriptOffset
-+    if (os2 && os2->ySuperscriptYOffset) {
-+        val = CONVERT_DESIGN_UNITS_TO_PIXELS(os2->ySuperscriptYOffset,
-+                                             face->size->metrics.y_scale);
-+        mSuperscriptOffset = nscoord(PR_MAX(f, NSToIntRound(val * f)));
-+    }
-+    else {
-+        mSuperscriptOffset = mXHeight;
-+    }
-+
-+    // 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;
-+        mSubscriptOffset = nscoord(PR_MAX(f, NSToIntRound(val * f)));
-+    }
-+    else {
-+        mSubscriptOffset = mXHeight;
-+    }
-+
-+    // mStrikeoutOffset
-+    mStrikeoutOffset = NSToCoordRound(mXHeight / 2.0);
-+
-+    // mStrikeoutSize
-+    mStrikeoutSize = mUnderlineSize;
-+
-+    pango_fc_font_unlock_face(fcfont);
-+
-+    /*
-+    printf("%i\n", mXHeight);
-+    printf("%i\n", mSuperscriptOffset);
-+    printf("%i\n", mSubscriptOffset);
-+    printf("%i\n", mStrikeoutOffset);
-+    printf("%i\n", mStrikeoutSize);
-+    printf("%i\n", mUnderlineOffset);
-+    printf("%i\n", mUnderlineSize);
-+    printf("%i\n", mMaxHeight);
-+    printf("%i\n", mLeading);
-+    printf("%i\n", mEmHeight);
-+    printf("%i\n", mEmAscent);
-+    printf("%i\n", mEmDescent);
-+    printf("%i\n", mMaxAscent);
-+    printf("%i\n", mMaxDescent);
-+    printf("%i\n", mMaxAdvance);
-+    printf("%i\n", mSpaceWidth);
-+    printf("%i\n", mAveCharWidth);
-+    */
-+
-+    return NS_OK;
-+}
-+
-+NS_IMETHODIMP
-+nsFontMetricsPSPango::Destroy()
-+{
-+    mDeviceContext = nsnull;
-+    return NS_OK;
-+}
-+
-+NS_IMETHODIMP
-+nsFontMetricsPSPango::GetLangGroup(nsIAtom** aLangGroup)
-+{
-+    *aLangGroup = mLangGroup;
-+    NS_IF_ADDREF(*aLangGroup);
-+
-+    return NS_OK;
-+}
-+
-+NS_IMETHODIMP
-+nsFontMetricsPSPango::GetFontHandle(nsFontHandle &aHandle)
-+{
-+    return NS_ERROR_NOT_IMPLEMENTED;
-+}
-+
-+// nsIFontMetricsPango impl
-+NS_IMETHODIMP
-+nsFontMetricsPSPango::GetStringWidth(const char *String,nscoord &aWidth,nscoord aLength)
-+{
-+    return GetWidth (String, (PRUint32) aLength, aWidth);
-+}
-+
-+NS_IMETHODIMP
-+nsFontMetricsPSPango::GetStringWidth(const PRUnichar *aString,nscoord &aWidth,nscoord aLength)
-+{
-+    return GetWidth (aString, (PRUint32)aLength, aWidth);
-+}
-+
-+nsresult
-+nsFontMetricsPSPango::GetWidth(const char* aString, PRUint32 aLength,
-+                             nscoord& aWidth)
-+{
-+    PangoLayout *layout = pango_layout_new(mPangoContext);
-+
-+    pango_layout_set_text(layout, aString, aLength);
-+
-+    if (mPangoSpaceWidth)
-+        FixupSpaceWidths(layout, aString);
-+
-+    int width, height;
-+
-+    pango_layout_get_size(layout, &width, &height);
-+
-+    g_object_unref(layout);
-+
-+    float f;
-+    f = mDeviceContext->DevUnitsToAppUnits();
-+    aWidth = NSToCoordRound(width * f / PANGO_SCALE);
-+
-+    //    printf("GetWidth (char *) %d\n", aWidth);
-+
-+    return NS_OK;
-+}
-+
-+nsresult
-+nsFontMetricsPSPango::GetWidth(const PRUnichar* aString, PRUint32 aLength,
-+                             nscoord& aWidth)
-+{
-+    nsresult rv = NS_OK;
-+    PangoLayout *layout = pango_layout_new(mPangoContext);
-+
-+    gchar *text = g_utf16_to_utf8(aString, aLength,
-+                                  NULL, NULL, NULL);
-+
-+    if (!text) {
-+        aWidth = 0;
-+#ifdef DEBUG
-+        NS_WARNING("nsFontMetricsPSPango::GetWidth invalid unicode to follow");
-+        DUMP_PRUNICHAR(aString, aLength)
-+#endif
-+        rv = NS_ERROR_FAILURE;
-+        goto loser;
-+    }
-+
-+    gint width, height;
-+
-+    pango_layout_set_text(layout, text, strlen(text));
-+    FixupSpaceWidths(layout, text);
-+    pango_layout_get_size(layout, &width, &height);
-+
-+    float f;
-+    f = mDeviceContext->DevUnitsToAppUnits();
-+    aWidth = NSToCoordRound(width * f / PANGO_SCALE);
-+
-+    //    printf("GetWidth %d\n", aWidth);
-+
-+ loser:
-+    g_free(text);
-+    g_object_unref(layout);
-+
-+    return rv;
-+}
-+
-+
-+nsresult
-+nsFontMetricsPSPango :: GetTextDimensions(const char* aString, PRUint32 aLength,
-+                                          nsTextDimensions& aDimensions)
-+{
-+    nsresult rv = NS_OK;
-+
-+    PangoLayout *layout = pango_layout_new(mPangoContext);
-+
-+    pango_layout_set_text(layout, aString, aLength);
-+    FixupSpaceWidths(layout,aString);
-+
-+    // Get the logical extents
-+    PangoLayoutLine *line;
-+    if (pango_layout_get_line_count(layout) != 1) {
-+        printf("Warning: more than one line!\n");
-+    }
-+    line = pango_layout_get_line(layout, 0);
-+
-+    PangoRectangle rect;
-+    pango_layout_line_get_extents(line, NULL, &rect);
-+
-+    float P2T;
-+    P2T = mDeviceContext->DevUnitsToAppUnits();
-+
-+    aDimensions.width = NSToCoordRound(rect.width * P2T / PANGO_SCALE);
-+    aDimensions.ascent = NSToCoordRound(PANGO_ASCENT(rect) * P2T / PANGO_SCALE);
-+    aDimensions.descent = NSToCoordRound(PANGO_DESCENT(rect) * P2T / PANGO_SCALE);
-+
-+    //    printf("GetTextDimensions %d %d %d\n", aDimensions.width,
-+    //aDimensions.ascent, aDimensions.descent);
-+
-+ loser:
-+    g_object_unref(layout);
-+
-+    return rv;
-+}
-+
-+nsresult
-+nsFontMetricsPSPango::GetTextDimensions(const PRUnichar* aString,
-+                                      PRUint32 aLength,
-+                                      nsTextDimensions& aDimensions, 
-+                                      PRInt32* aFontID)
-+{
-+    nsresult rv = NS_OK;
-+
-+    PangoLayout *layout = pango_layout_new(mPangoContext);
-+
-+    gchar *text = g_utf16_to_utf8(aString, aLength,
-+                                  NULL, NULL, NULL);
-+
-+    if (!text) {
-+#ifdef DEBUG
-+        NS_WARNING("nsFontMetricsPSPango::GetTextDimensions invalid unicode to follow");
-+        DUMP_PRUNICHAR(aString, aLength)
-+#endif
-+        aDimensions.width = 0;
-+        aDimensions.ascent = 0;
-+        aDimensions.descent = 0;
-+
-+        rv = NS_ERROR_FAILURE;
-+        goto loser;
-+    }
-+        
-+
-+    pango_layout_set_text(layout, text, strlen(text));
-+    FixupSpaceWidths(layout, text);
-+
-+    // Get the logical extents
-+    PangoLayoutLine *line;
-+    if (pango_layout_get_line_count(layout) != 1) {
-+        printf("Warning: more than one line!\n");
-+    }
-+    line = pango_layout_get_line(layout, 0);
-+
-+    PangoRectangle rect;
-+    pango_layout_line_get_extents(line, NULL, &rect);
-+
-+    float P2T;
-+    P2T = mDeviceContext->DevUnitsToAppUnits();
-+
-+    aDimensions.width = NSToCoordRound(rect.width * P2T / PANGO_SCALE);
-+    aDimensions.ascent = NSToCoordRound(PANGO_ASCENT(rect) * P2T / PANGO_SCALE);
-+    aDimensions.descent = NSToCoordRound(PANGO_DESCENT(rect) * P2T / PANGO_SCALE);
-+
-+    //    printf("GetTextDimensions %d %d %d\n", aDimensions.width,
-+    //aDimensions.ascent, aDimensions.descent);
-+
-+ loser:
-+    g_free(text);
-+    g_object_unref(layout);
-+
-+    return rv;
-+}
-+
-+nsresult
-+nsFontMetricsPSPango::GetTextDimensions(const char*         aString,
-+                                      PRInt32             aLength,
-+                                      PRInt32             aAvailWidth,
-+                                      PRInt32*            aBreaks,
-+                                      PRInt32             aNumBreaks,
-+                                      nsTextDimensions&   aDimensions,
-+                                      PRInt32&            aNumCharsFit,
-+                                      nsTextDimensions&   aLastWordDimensions,
-+                                      PRInt32*            aFontID)
-+{
-+
-+    return GetTextDimensionsInternal(aString, aLength, aAvailWidth, aBreaks,
-+                                     aNumBreaks, aDimensions, aNumCharsFit,
-+                                     aLastWordDimensions);
-+
-+}
-+
-+nsresult
-+nsFontMetricsPSPango::GetTextDimensions(const PRUnichar*    aString,
-+                                      PRInt32             aLength,
-+                                      PRInt32             aAvailWidth,
-+                                      PRInt32*            aBreaks,
-+                                      PRInt32             aNumBreaks,
-+                                      nsTextDimensions&   aDimensions,
-+                                      PRInt32&            aNumCharsFit,
-+                                      nsTextDimensions&   aLastWordDimensions,
-+                                      PRInt32*            aFontID)
-+{
-+    nsresult rv = NS_OK;
-+    PRInt32 curBreak = 0;
-+    gchar *curChar;
-+
-+    PRInt32 *utf8Breaks = new PRInt32[aNumBreaks];
-+
-+    gchar *text = g_utf16_to_utf8(aString, (PRInt32)aLength,
-+                                  NULL, NULL, NULL);
-+
-+    curChar = text;
-+
-+    if (!text) {
-+#ifdef DEBUG
-+        NS_WARNING("nsFontMetricsPSPango::GetWidth invalid unicode to follow");
-+        DUMP_PRUNICHAR(aString, (PRUint32)aLength)
-+#endif
-+        rv = NS_ERROR_FAILURE;
-+        goto loser;
-+    }
-+
-+    // Covert the utf16 break offsets to utf8 break offsets
-+    for (PRInt32 curOffset=0; curOffset < aLength;
-+         curOffset++, curChar = g_utf8_find_next_char(curChar, NULL)) {
-+        if (aBreaks[curBreak] == curOffset) {
-+            utf8Breaks[curBreak] = curChar - text;
-+            curBreak++;
-+        }
-+
-+        if (IS_HIGH_SURROGATE(aString[curOffset]))
-+            curOffset++;
-+    }
-+
-+    // Always catch the last break
-+    utf8Breaks[curBreak] = curChar - text;
-+
-+#if 0
-+    if (strlen(text) != aLength) {
-+        printf("Different lengths for utf16 %d and utf8 %d\n", aLength, strlen(text));
-+        DUMP_PRUNICHAR(aString, aLength)
-+        DUMP_PRUNICHAR(text, strlen(text))
-+        for (PRInt32 i = 0; i < aNumBreaks; ++i) {
-+            printf("  break %d utf16 %d utf8 %d\n", i, aBreaks[i], utf8Breaks[i]);
-+        }
-+    }
-+#endif
-+
-+    // We'll use curBreak to indicate which of the breaks end up being
-+    // used for the break point for this line.
-+    curBreak = 0;
-+    rv = GetTextDimensionsInternal(text, strlen(text), aAvailWidth, utf8Breaks,
-+                                   aNumBreaks, aDimensions, aNumCharsFit,
-+                                   aLastWordDimensions);
-+
-+    // Figure out which of the breaks we ended up using to convert
-+    // back to utf16 - start from the end.
-+    for (PRInt32 i = aNumBreaks - 1; i >= 0; --i) {
-+        if (utf8Breaks[i] == aNumCharsFit) {
-+            //      if (aNumCharsFit != aBreaks[i])
-+            //                printf("Fixing utf8 -> utf16 %d -> %d\n", aNumCharsFit, aBreaks[i]);
-+            aNumCharsFit = aBreaks[i];
-+            break;
-+        }
-+    }
-+
-+ loser:
-+    if (text)
-+        g_free(text);
-+
-+    delete[] utf8Breaks;
-+
-+    return rv;
-+}
-+
-+typedef struct _nsPSPangoRenderer        nsPSPangoRenderer;
-+typedef struct _nsPSPangoRendererClass   nsPSPangoRendererClass;
-+
-+struct _nsPSPangoRenderer
-+{
-+  PangoRenderer parent_instance;
-+  nsRenderingContextPS *psContext;
-+  nsFontMetricsPSPango *psPangoFontMetrics;
-+  float zoom;
-+};
-+
-+struct _nsPSPangoRendererClass
-+{
-+  PangoRendererClass parent_class;
-+};
-+
-+#define _PS_TYPE_PANGO_RENDERER            (_ps_pango_renderer_get_type())
-+#define _PS_PANGO_RENDERER(object)         (G_TYPE_CHECK_INSTANCE_CAST ((object), _PS_TYPE_PANGO_RENDERER, _nsPSPangoRenderer))
-+#define _PS_IS_PANGO_RENDERER(object)      (G_TYPE_CHECK_INSTANCE_TYPE ((object), _PS_TYPE_PANGO_RENDERER))
-+#define _PS_PANGO_RENDERER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), _PS_TYPE_PANGO_RENDERER, _nsPSPangoRendererClass))
-+#define _PS_IS_PANGO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), _PS_TYPE_PANGO_RENDERER))
-+#define _PS_PANGO_RENDERER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), _PS_TYPE_PANGO_RENDERER, _nsPSPangoRendererClass))
-+
-+G_DEFINE_TYPE (_nsPSPangoRenderer, _ps_pango_renderer, PANGO_TYPE_RENDERER)
-+
-+static PangoRenderer *
-+get_renderer (void)
-+{
-+  static PangoRenderer               *renderer = NULL;
-+
-+  if (!renderer)
-+    renderer = (PangoRenderer *) g_object_new (_PS_TYPE_PANGO_RENDERER, NULL);
-+
-+  return renderer;
-+}
-+
-+static void
-+_ps_pango_renderer_draw_glyphs (PangoRenderer    *renderer,
-+                              PangoFont        *font,
-+                              PangoGlyphString *glyphs,
-+                              int               x,
-+                              int               y);
-+
-+static void
-+_ps_pango_renderer_class_init (nsPSPangoRendererClass *klass)
-+{
-+  PangoRendererClass *renderer_class = PANGO_RENDERER_CLASS (klass);
-+  
-+  renderer_class->draw_glyphs = _ps_pango_renderer_draw_glyphs;
-+}
-+
-+static void
-+_ps_pango_renderer_init (nsPSPangoRenderer *renderer)
-+{
-+}
-+
-+class nsPangoType1Generator : public nsPSFontGenerator {
-+public:
-+  nsPangoType1Generator();
-+  ~nsPangoType1Generator();
-+  nsresult Init(PangoFont *aFont);
-+  void  GeneratePSFont(FILE* aFile);
-+
-+protected:
-+  PangoFont *mFont;
-+};
-+
-+nsPangoType1Generator::nsPangoType1Generator()
-+{
-+}
-+
-+nsresult
-+nsPangoType1Generator::Init(PangoFont *aFont)
-+{
-+  NS_ENSURE_TRUE(aFont, NS_ERROR_FAILURE);
-+  mFont = aFont;
-+  g_object_ref (mFont);
-+  return NS_OK;
-+}
-+
-+nsPangoType1Generator::~nsPangoType1Generator()
-+{
-+  g_object_unref (mFont);
-+  mFont = nsnull;
-+}
-+
-+void nsPangoType1Generator::GeneratePSFont(FILE* aFile)
-+{
-+  FT_Face face = pango_fc_font_lock_face ((PangoFcFont *) mFont);
-+
-+  if (face == nsnull)
-+    return;
-+
-+  int wmode = 0;
-+  if (mGlyphSubset->Count())
-+    FT2SubsetToType1FontSet(face, mGlyphSubset, wmode, aFile);
-+
-+  pango_fc_font_unlock_face ((PangoFcFont *) mFont);
-+}
-+
-+typedef struct
-+{
-+  nsCString    *FontNameBase;
-+  nsCStringKey *key;
-+  int           font_size;
-+} PSPangoFontData;
-+
-+static void
-+ps_pango_font_data_destroy (PSPangoFontData *data)
-+{
-+  delete data->key;
-+  delete data->FontNameBase;
-+  g_free (data);
-+}
-+
-+static void
-+flattenName(nsCString& aString)
-+{
-+  nsCString::iterator start, end;
-+  aString.BeginWriting(start);
-+  aString.EndWriting(end);
-+  while(start != end) {
-+    if (*start == ' ')
-+      *start= '_';
-+    else if (*start == '(')
-+      *start = '_';
-+    else if (*start == ')')
-+      *start = '_';
-+    ++start;
-+  }
-+}
-+
-+static void
-+_ps_pango_renderer_draw_glyphs (PangoRenderer    *renderer,
-+                              PangoFont        *font,
-+                              PangoGlyphString *glyphs,
-+                              int               x,
-+                              int               y)
-+{
-+  if (!glyphs->num_glyphs)
-+    return;
-+
-+  static GQuark data_quark = 0;
-+  if (!data_quark)
-+    data_quark = g_quark_from_static_string ("ps-pango-font-data");
-+
-+  PSPangoFontData *data;
-+  if (!(data = (PSPangoFontData *) g_object_get_qdata (G_OBJECT (font), data_quark)))
-+    {
-+      data = g_new (PSPangoFontData, 1);
-+
-+      FT_Face face = pango_fc_font_lock_face ((PangoFcFont *) font);
-+      if (face == nsnull)
-+        return;
-+      int wmode = 0;
-+      data->FontNameBase = new nsCString ();
-+      if (NS_FAILED(FT2ToType1FontName(face, wmode, *data->FontNameBase))) {
-+        g_free (data);
-+        pango_fc_font_unlock_face ((PangoFcFont *) font);
-+        return;
-+      }
-+      pango_fc_font_unlock_face ((PangoFcFont *) font);
-+
-+      PangoFontDescription *desc = pango_font_describe (font);
-+      data->font_size = pango_font_description_get_size (desc);
-+      pango_font_description_free (desc);
-+
-+      data->key = new nsCStringKey (*data->FontNameBase);
-+
-+      g_object_set_qdata_full (G_OBJECT (font), data_quark, data, (GDestroyNotify) ps_pango_font_data_destroy);
-+    }
-+
-+  nsPSPangoRenderer *ps_renderer = (nsPSPangoRenderer *)renderer;
-+  nsRenderingContextPS *aContext = ps_renderer->psContext;
-+  nsFontMetricsPSPango *metrics = ps_renderer->psPangoFontMetrics;
-+  nsDeviceContextPS* dc = NS_REINTERPRET_CAST (nsDeviceContextPS*, metrics->GetDeviceContext());
-+  nsPostScriptObj* psObj = aContext->GetPostScriptObj();
-+  nsHashtable *psFGList = dc->GetPSFontGeneratorList();
-+  g_return_if_fail (psFGList);
-+  nsPSFontGenerator* psFontGen = (nsPSFontGenerator*) psFGList->Get(data->key);
-+  if (!psFontGen) {
-+    nsresult rv;
-+    psFontGen = new nsPangoType1Generator;
-+    g_return_if_fail (psFontGen);
-+    rv = ((nsPangoType1Generator*)psFontGen)->Init(font);
-+    if (NS_FAILED(rv)) {
-+      delete psFontGen;
-+      return;
-+    }
-+    psFGList->Put(data->key, (void *) psFontGen);
-+  }
-+  nscoord font_size = NSToCoordRound (ps_renderer->zoom * data->font_size / PANGO_SCALE);
-+
-+  g_return_if_fail (aContext);
-+  g_return_if_fail (psObj);
-+
-+  nscoord aX = NSToCoordRound(ps_renderer->zoom * x / PANGO_SCALE);
-+  nscoord aY = NSToCoordRound(ps_renderer->zoom * y / PANGO_SCALE);
-+  psObj->moveto(aX, aY);
-+
-+  PRInt32 currSubFont, prevSubFont = -1;
-+  PRUint32 i;
-+  PangoGlyphString gl;
-+
-+  gl.glyphs = glyphs->glyphs;
-+  gl.num_glyphs = 0;
-+  for (i = 0; i < glyphs->num_glyphs; ++i) {
-+    currSubFont = psFontGen->AddToGlyphSubset(glyphs->glyphs[i].glyph >= 0x00ffffff ? 0 : glyphs->glyphs[i].glyph);
-+    if (prevSubFont != currSubFont) {
-+      if (prevSubFont != -1)
-+        psObj->show(&gl, ps_renderer->zoom,  psFontGen, prevSubFont);
-+
-+
-+      psObj->setfont(*data->FontNameBase, (PRUint32) font_size, currSubFont);
-+      prevSubFont = currSubFont;
-+      gl.glyphs = glyphs->glyphs + i;
-+      gl.num_glyphs = 0;
-+    }
-+
-+    gl.num_glyphs++;
-+  }
-+
-+  if (prevSubFont != -1)
-+    psObj->show(&gl, ps_renderer->zoom, psFontGen, prevSubFont);
-+}
-+
-+static void
-+draw_layout_line (int x, int y, PangoLayoutLine *line, nsFontMetricsPSPango *aPSPangoFontMetrics, nsRenderingContextPS *aContext)
-+{
-+  PangoRenderer *renderer = get_renderer ();
-+  nsPSPangoRenderer *ps_renderer = (nsPSPangoRenderer *)renderer;
-+  ps_renderer->psContext = aContext;
-+  ps_renderer->psPangoFontMetrics = aPSPangoFontMetrics;
-+  nsDeviceContextPS* dc = NS_REINTERPRET_CAST (nsDeviceContextPS*, aPSPangoFontMetrics->GetDeviceContext());
-+  ps_renderer->zoom = dc->DevUnitsToAppUnits();
-+
-+  pango_renderer_draw_layout_line (renderer, line,
-+                                   NSToCoordRound (x * PANGO_SCALE / ps_renderer->zoom),
-+                                   NSToCoordRound (y * PANGO_SCALE / ps_renderer->zoom));
-+}
-+
-+nsresult
-+nsFontMetricsPSPango::DrawString(const char *aString, PRUint32 aLength,
-+                               nscoord aX, nscoord aY,
-+                               const nscoord* aSpacing,
-+                               nsRenderingContextPS *aContext)
-+{
-+    PangoLayout *layout = pango_layout_new(mPangoContext);
-+
-+    pango_layout_set_text(layout, aString, aLength);
-+    FixupSpaceWidths(layout, aString);
-+
-+    int x = aX;
-+    int y = aY;
-+
-+    aContext->GetTranMatrix()->TransformCoord(&x, &y);
-+
-+    PangoLayoutLine *line;
-+    if (pango_layout_get_line_count(layout) != 1) {
-+        printf("Warning: more than one line!\n");
-+    }
-+    line = pango_layout_get_line(layout, 0);
-+
-+    if (aSpacing && *aSpacing) {
-+        DrawStringSlowly(aString, NULL, aLength, x, y, line, aSpacing, aContext);
-+    }
-+    else {
-+       draw_layout_line (x, y, line, this, aContext);
-+    }
-+
-+    g_object_unref(layout);
-+
-+    return NS_OK;
-+}
-+
-+nsresult
-+nsFontMetricsPSPango::DrawString(const PRUnichar* aString, PRUint32 aLength,
-+                               nscoord aX, nscoord aY,
-+                               PRInt32 aFontID,
-+                               const nscoord* aSpacing,
-+                               nsRenderingContextPS *aContext)
-+{
-+    nsresult rv = NS_OK;
-+    int x = aX;
-+    int y = aY;
-+
-+    PangoLayout *layout = pango_layout_new(mPangoContext);
-+
-+    gchar *text = g_utf16_to_utf8(aString, aLength,
-+                                  NULL, NULL, NULL);
-+    if (!text) {
-+#ifdef DEBUG
-+        NS_WARNING("nsFontMetricsPSPango::DrawString invalid unicode to follow");
-+        DUMP_PRUNICHAR(aString, aLength)
-+#endif
-+        rv = NS_ERROR_FAILURE;
-+        goto loser;
-+    }
-+
-+    pango_layout_set_text(layout, text, strlen(text));
-+    FixupSpaceWidths(layout, text);
-+
-+    aContext->GetTranMatrix()->TransformCoord(&x, &y);
-+
-+    PangoLayoutLine *line;
-+    if (pango_layout_get_line_count(layout) != 1) {
-+        printf("Warning: more than one line!\n");
-+    }
-+    line = pango_layout_get_line(layout, 0);
-+
-+    if (aSpacing && *aSpacing) {
-+        DrawStringSlowly(text, aString, aLength, x, y, line, aSpacing, aContext);
-+    }
-+    else {
-+       draw_layout_line (x, y, line, this, aContext);
-+    }
-+
-+ loser:
-+
-+    g_free(text);
-+    g_object_unref(layout);
-+
-+    return rv;
-+}
-+
-+#ifdef MOZ_MATHML
-+nsresult
-+nsFontMetricsPSPango::GetBoundingMetrics(const char *aString, PRUint32 aLength,
-+                                       nsBoundingMetrics &aBoundingMetrics)
-+{
-+    printf("GetBoundingMetrics (char *)\n");
-+    return NS_ERROR_FAILURE;
-+}
-+
-+nsresult
-+nsFontMetricsPSPango::GetBoundingMetrics(const PRUnichar *aString,
-+                                       PRUint32 aLength,
-+                                       nsBoundingMetrics &aBoundingMetrics,
-+                                       PRInt32 *aFontID)
-+{
-+    nsresult rv = NS_OK;
-+    PangoLayout *layout = pango_layout_new(mPangoContext);
-+
-+    gchar *text = g_utf16_to_utf8(aString, aLength,
-+                                  NULL, NULL, NULL);
-+
-+    if (!text) {
-+#ifdef DEBUG
-+        NS_WARNING("nsFontMetricsPSPango::GetBoundingMetrics invalid unicode to follow");
-+        DUMP_PRUNICHAR(aString, aLength)
-+#endif
-+        aBoundingMetrics.leftBearing = 0;
-+        aBoundingMetrics.rightBearing = 0;
-+        aBoundingMetrics.width = 0;
-+        aBoundingMetrics.ascent = 0;
-+        aBoundingMetrics.descent = 0;
-+
-+        rv = NS_ERROR_FAILURE;
-+        goto loser;
-+    }
-+
-+    pango_layout_set_text(layout, text, -1);
-+    FixupSpaceWidths(layout, text);
-+
-+    PangoLayoutLine *line;
-+    if (pango_layout_get_line_count(layout) != 1) {
-+        printf("Warning: more than one line!\n");
-+    }
-+    line = pango_layout_get_line(layout, 0);
-+
-+    // Get the ink and logical extents
-+    PangoRectangle ink, logical;
-+    pango_layout_line_get_extents(line, &ink, &logical);
-+
-+    float P2T;
-+    P2T = mDeviceContext->DevUnitsToAppUnits();
-+
-+    aBoundingMetrics.leftBearing  = NSToCoordRound(PANGO_LBEARING(ink) * P2T / PANGO_SCALE);
-+    aBoundingMetrics.rightBearing = NSToCoordRound(PANGO_RBEARING(ink) * P2T / PANGO_SCALE);
-+    aBoundingMetrics.ascent       = NSToCoordRound(PANGO_ASCENT(ink)   * P2T / PANGO_SCALE);
-+    aBoundingMetrics.descent      = NSToCoordRound(PANGO_DESCENT(ink)  * P2T / PANGO_SCALE);
-+    aBoundingMetrics.width        = NSToCoordRound(logical.width       * P2T / PANGO_SCALE);
-+
-+ loser:
-+    g_free(text);
-+    g_object_unref(layout);
-+
-+    return rv;
-+}
-+
-+#endif /* MOZ_MATHML */
-+
-+nsresult
-+nsFontMetricsPSPango::SetRightToLeftText(PRBool aIsRTL)
-+{
-+    if (aIsRTL) {
-+        if (!mRTLPangoContext) {
-+            mRTLPangoContext = get_context();
-+            pango_context_set_base_dir(mRTLPangoContext, PANGO_DIRECTION_RTL);
-+
-+            pango_context_set_language(mRTLPangoContext, GetPangoLanguage(mLangGroup));
-+            pango_context_set_font_description(mRTLPangoContext, mPangoFontDesc);
-+        }
-+        mPangoContext = mRTLPangoContext;
-+    }
-+    else {
-+        mPangoContext = mLTRPangoContext;
-+    }
-+
-+    mIsRTL = aIsRTL;
-+    return NS_OK;
-+}
-+
-+nsresult
-+nsFontMetricsPSPango::GetClusterInfo(const PRUnichar *aText,
-+                                   PRUint32 aLength,
-+                                   PRUint8 *aClusterStarts)
-+{
-+    nsresult rv = NS_OK;
-+    PangoLogAttr *attrs = NULL;
-+    gint n_attrs = 0;
-+    PangoLayout *layout = pango_layout_new(mPangoContext);
-+    
-+    // Convert the incoming UTF-16 to UTF-8
-+    gchar *text = g_utf16_to_utf8(aText, aLength, NULL, NULL, NULL);
-+
-+    if (!text) {
-+#ifdef DEBUG
-+        NS_WARNING("nsFontMetricsPSPango::GetWidth invalid unicode to follow");
-+        DUMP_PRUNICHAR(aText, aLength)
-+#endif
-+        rv = NS_ERROR_FAILURE;
-+        goto loser;
-+    }
-+
-+    // Set up the pango layout
-+    pango_layout_set_text(layout, text, strlen(text));
-+    FixupSpaceWidths(layout, text);
-+
-+    // Convert back to UTF-16 while filling in the cluster info
-+    // structure.
-+    pango_layout_get_log_attrs(layout, &attrs, &n_attrs);
-+
-+    for (PRUint32 pos = 0; pos < aLength; pos++) {
-+        if (IS_HIGH_SURROGATE(aText[pos])) {
-+            aClusterStarts[pos] = 1;
-+            pos++;
-+        }
-+        else {
-+            aClusterStarts[pos] = attrs[pos].is_cursor_position;
-+        }
-+    }
-+
-+ loser:
-+    if (attrs)
-+        g_free(attrs);
-+    if (text)
-+        g_free(text);
-+    if (layout)
-+        g_object_unref(layout);
-+
-+    return rv;
-+}
-+
-+PRInt32
-+nsFontMetricsPSPango::GetPosition(const PRUnichar *aText, PRUint32 aLength,
-+                                nsPoint aPt)
-+{
-+    int trailing = 0;
-+    int inx = 0;
-+    const gchar *curChar;
-+    PRInt32 retval = 0;
-+
-+    float f = mDeviceContext->AppUnitsToDevUnits();
-+    
-+    PangoLayout *layout = pango_layout_new(mPangoContext);
-+    PRUint32 localX = (PRUint32)(aPt.x * PANGO_SCALE * f);
-+    PRUint32 localY = (PRUint32)(aPt.y * PANGO_SCALE * f);
-+
-+    // Convert the incoming UTF-16 to UTF-8
-+    gchar *text = g_utf16_to_utf8(aText, aLength, NULL, NULL, NULL);
-+
-+    if (!text) {
-+#ifdef DEBUG
-+        NS_WARNING("nsFontMetricsPSPango::GetWidth invalid unicode to follow");
-+        DUMP_PRUNICHAR(aText, aLength)
-+#endif
-+        retval = -1;
-+        goto loser;
-+    }
-+
-+    // Set up the pango layout
-+    pango_layout_set_text(layout, text, strlen(text));
-+    FixupSpaceWidths(layout, text);
-+    
-+    pango_layout_xy_to_index(layout, localX, localY,
-+                             &inx, &trailing);
-+
-+    // Convert the index back to the utf-16 index
-+    curChar = text;
-+
-+    for (PRUint32 curOffset=0; curOffset < aLength;
-+         curOffset++, curChar = g_utf8_find_next_char(curChar, NULL)) {
-+
-+        // Check for a match before checking for a surrogate pair
-+        if (curChar - text == inx) {
-+            retval = curOffset;
-+            break;
-+        }
-+
-+        if (IS_HIGH_SURROGATE(aText[curOffset]))
-+            curOffset++;
-+    }
-+
-+    // If there was a trailing result, advance the index pointer the
-+    // number of characters equal to the trailing result.
-+    while (trailing) {
-+        retval++;
-+        // Yes, this can make aInx > length to indicate the end of the
-+        // string.
-+        if (retval < (PRInt32)aLength && IS_HIGH_SURROGATE(aText[retval]))
-+            retval++;
-+        trailing--;
-+    }
-+
-+ loser:
-+    if (text)
-+        g_free(text);
-+    if (layout)
-+        g_object_unref(layout);
-+
-+    return retval;
-+}
-+
-+nsresult
-+nsFontMetricsPSPango::GetRangeWidth(const PRUnichar *aText,
-+                                  PRUint32 aLength,
-+                                  PRUint32 aStart,
-+                                  PRUint32 aEnd,
-+                                  PRUint32 &aWidth)
-+{
-+    nsresult rv = NS_OK;
-+    PRUint32 utf8Start = 0;
-+    PRUint32 utf8End = 0;
-+
-+    aWidth = 0;
-+
-+    // Convert the incoming UTF-16 to UTF-8
-+    gchar *text = g_utf16_to_utf8(aText, aLength, NULL, NULL, NULL);
-+    gchar *curChar = text;
-+
-+    if (!text) {
-+#ifdef DEBUG
-+        NS_WARNING("nsFontMetricsPSPango::GetWidth invalid unicode to follow");
-+        DUMP_PRUNICHAR(aText, aLength)
-+#endif
-+        rv = NS_ERROR_FAILURE;
-+        goto loser;
-+    }
-+
-+    // Convert the utf16 offsets into utf8 offsets
-+    for (PRUint32 curOffset = 0; curOffset < aLength;
-+         curOffset++, curChar = g_utf8_find_next_char(curChar, NULL)) {
-+
-+        if (curOffset == aStart)
-+            utf8Start = curChar - text;
-+
-+        if (curOffset == aEnd)
-+            utf8End = curChar - text;
-+        
-+        if (IS_HIGH_SURROGATE(aText[curOffset]))
-+            curOffset++;
-+    }
-+
-+    // Special case where the end index is the same as the length
-+    if (aLength == aEnd)
-+        utf8End = strlen(text);
-+
-+    rv = GetRangeWidth(text, strlen(text), utf8Start, utf8End, aWidth);
-+
-+ loser:
-+    if (text)
-+        g_free(text);
-+
-+    return rv;
-+}
-+
-+nsresult
-+nsFontMetricsPSPango::GetRangeWidth(const char *aText,
-+                                  PRUint32 aLength,
-+                                  PRUint32 aStart,
-+                                  PRUint32 aEnd,
-+                                  PRUint32 &aWidth)
-+{
-+    nsresult rv = NS_OK;
-+    int *ranges = NULL;
-+    int n_ranges = 0;
-+    float f;
-+
-+    aWidth = 0;
-+
-+    PangoLayout *layout = pango_layout_new(mPangoContext);
-+
-+    if (!aText) {
-+        rv = NS_ERROR_FAILURE;
-+        goto loser;
-+    }
-+
-+    pango_layout_set_text(layout, aText, aLength);
-+    FixupSpaceWidths(layout, aText);
-+
-+    PangoLayoutLine *line;
-+    if (pango_layout_get_line_count(layout) != 1) {
-+        printf("Warning: more than one line!\n");
-+    }
-+    line = pango_layout_get_line(layout, 0);
-+
-+    pango_layout_line_get_x_ranges(line, aStart, aEnd, &ranges, &n_ranges);
-+
-+    aWidth = (ranges[((n_ranges - 1) * 2) + 1] - ranges[0]);
-+
-+    f = mDeviceContext-> DevUnitsToAppUnits();
-+    aWidth = nscoord(aWidth * f / PANGO_SCALE);
-+
-+ loser:
-+    if (ranges)
-+        g_free(ranges);
-+    if (layout)
-+        g_object_unref(layout);
-+
-+    return rv;
-+}
-+
-+PRUint32
-+nsFontMetricsPSPango::GetHints(void)
-+{
-+    return (NS_RENDERING_HINT_BIDI_REORDERING |
-+            NS_RENDERING_HINT_ARABIC_SHAPING | 
-+            NS_RENDERING_HINT_FAST_MEASURE |
-+            NS_RENDERING_HINT_REORDER_SPACED_TEXT |
-+            NS_RENDERING_HINT_TEXT_CLUSTERS);
-+}
-+
-+/* static */
-+nsresult
-+nsFontMetricsPSPango::FamilyExists(nsIDeviceContext *aDevice,
-+                                 const nsString &aName)
-+{
-+    // fontconfig family name is always in UTF-8
-+    NS_ConvertUTF16toUTF8 name(aName);
-+
-+    nsresult rv = NS_ERROR_FAILURE;
-+    PangoContext *context = get_context();
-+    PangoFontFamily **familyList;
-+    int n;
-+
-+    pango_context_list_families(context, &familyList, &n);
-+
-+    for (int i=0; i < n; i++) {
-+        const char *tmpname = pango_font_family_get_name(familyList[i]);
-+        if (!Compare(nsDependentCString(tmpname), name,
-+                     nsCaseInsensitiveCStringComparator())) {
-+            rv = NS_OK;
-+            break;
-+        }
-+    }
-+
-+    g_free(familyList);
-+    g_object_unref(context);
-+
-+    return rv;
-+}
-+
-+// Private Methods
-+
-+nsresult
-+nsFontMetricsPSPango::RealizeFont(void)
-+{
-+    nsCString familyList;
-+    // Create and fill out the font description.
-+    mPangoFontDesc = pango_font_description_new();
-+
-+    // Add CSS names - walk the list of fonts, adding the generic as
-+    // the last font
-+    for (int i=0; i < mFontList.Count(); ++i) {
-+        // if this was a generic name, break out of the loop since we
-+        // don't want to add it to the pattern yet
-+        if (mFontIsGeneric[i])
-+            break;;
-+
-+        nsCString *familyName = mFontList.CStringAt(i);
-+        familyList.Append(familyName->get());
-+        familyList.Append(',');
-+    }
-+
-+    // If there's a generic add a pref for the generic if there's one
-+    // set.
-+    if (mGenericFont && !mFont.systemFont) {
-+        nsCString name;
-+        name += "font.name.";
-+        name += mGenericFont->get();
-+        name += ".";
-+
-+        nsString langGroup;
-+        mLangGroup->ToString(langGroup);
-+
-+        name.AppendWithConversion(langGroup);
-+
-+        nsCOMPtr<nsIPref> pref;
-+        pref = do_GetService(NS_PREF_CONTRACTID);
-+        if (pref) {
-+            nsresult rv;
-+            nsXPIDLCString value;
-+            rv = pref->GetCharPref(name.get(), getter_Copies(value));
-+
-+            // we ignore prefs that have three hypens since they are X
-+            // style prefs.
-+            if (NS_FFRECountHyphens(value) < 3) {
-+                nsCString tmpstr;
-+                tmpstr.Append(value);
-+
-+                familyList.Append(tmpstr);
-+                familyList.Append(',');
-+            }
-+        }
-+    }
-+
-+    // Add the generic if there is one.
-+    if (mGenericFont && !mFont.systemFont) {
-+        familyList.Append(mGenericFont->get());
-+        familyList.Append(',');
-+    }
-+
-+    // Set the family
-+    pango_font_description_set_family(mPangoFontDesc,
-+                                      familyList.get());
-+
-+    // Set the point size
-+    pango_font_description_set_size(mPangoFontDesc,
-+                                    (gint)(mPointSize * PANGO_SCALE));
-+
-+    // Set the style
-+    pango_font_description_set_style(mPangoFontDesc,
-+                                     CalculateStyle(mFont.style));
-+
-+    // Set the weight
-+    pango_font_description_set_weight(mPangoFontDesc,
-+                                      CalculateWeight(mFont.weight));
-+
-+    // Now that we have the font description set up, create the
-+    // context.
-+    mLTRPangoContext = get_context();
-+    mPangoContext = mLTRPangoContext;
-+
-+    // Make sure to set the base direction to LTR - if layout needs to
-+    // render RTL text it will use ::SetRightToLeftText()
-+    pango_context_set_base_dir(mPangoContext, PANGO_DIRECTION_LTR);
-+
-+    // Set the pango language now that we have a context
-+    pango_context_set_language(mPangoContext, GetPangoLanguage(mLangGroup));
-+
-+    // And attach the font description to this context
-+    pango_context_set_font_description(mPangoContext, mPangoFontDesc);
-+
-+    return NS_OK;
-+}
-+
-+/* static */
-+PRBool
-+nsFontMetricsPSPango::EnumFontCallback(const nsString &aFamily,
-+                                     PRBool aIsGeneric, void *aData)
-+{
-+    NS_ConvertUTF16toUTF8 name(aFamily);
-+
-+    // The newest fontconfig does the full Unicode case folding so that 
-+    // we're being lazy here by calling |ToLowerCase| after converting
-+    // to UTF-8  assuming that in virtually all cases, we just have to
-+    // fold [A-Z].  (bug 223653). 
-+    ToLowerCase(name);
-+    nsFontMetricsPSPango *metrics = (nsFontMetricsPSPango *)aData;
-+    metrics->mFontList.AppendCString(name);
-+    metrics->mFontIsGeneric.AppendElement((void *)aIsGeneric);
-+    if (aIsGeneric) {
-+        metrics->mGenericFont = 
-+            metrics->mFontList.CStringAt(metrics->mFontList.Count() - 1);
-+        return PR_FALSE; // stop processing
-+    }
-+
-+    return PR_TRUE; // keep processing
-+}
-+
-+/*
-+ * This is only used when there's per-character spacing happening.
-+ * Well, really it can be either line or character spacing but it's
-+ * just turtles all the way down!
-+ */
-+
-+void
-+nsFontMetricsPSPango::DrawStringSlowly(const gchar *aText,
-+                                     const PRUnichar *aOrigString,
-+                                     PRUint32 aLength,
-+                                     gint aX, gint aY,
-+                                     PangoLayoutLine *aLine,
-+                                     const nscoord *aSpacing,
-+                                     nsRenderingContextPS *aContext)
-+{
-+    float app2dev;
-+    app2dev = mDeviceContext->AppUnitsToDevUnits();
-+    gint offset = 0;
-+
-+    /*
-+     * We walk the list of glyphs returned in each layout run,
-+     * matching up the glyphs with the characters in the source text.
-+     * We use the aSpacing argument to figure out where to place those
-+     * glyphs.  It's important to note that since the string we're
-+     * working with is in UTF-8 while the spacing argument assumes
-+     * that offset will be part of the UTF-16 string.  Logical
-+     * attributes in pango are in byte offsets in the UTF-8 string, so
-+     * we need to store the offsets based on the UTF-8 string.
-+     */
-+    nscoord *utf8spacing = new nscoord[strlen(aText)];
-+
-+    if (aOrigString) {
-+        const gchar *curChar = aText;
-+        bzero(utf8spacing, sizeof(nscoord) * strlen(aText));
-+
-+        // Covert the utf16 spacing offsets to utf8 spacing offsets
-+        for (PRUint32 curOffset=0; curOffset < aLength;
-+             curOffset++, curChar = g_utf8_find_next_char(curChar, NULL)) {
-+            utf8spacing[curChar - aText] = aSpacing[curOffset];
-+
-+            if (IS_HIGH_SURROGATE(aOrigString[curOffset]))
-+                curOffset++;
-+        }
-+    }
-+    else {
-+        memcpy(utf8spacing, aSpacing, (sizeof(nscoord *) * aLength));
-+    }
-+
-+    gint curRun = 0;
-+
-+    for (GSList *tmpList = aLine->runs; tmpList && tmpList->data;
-+         tmpList = tmpList->next, curRun++) {
-+        PangoLayoutRun *layoutRun = (PangoLayoutRun *)tmpList->data;
-+        gint tmpOffset = 0;
-+
-+        /*        printf("    Rendering run %d: \"%s\"\n", curRun,
-+                  &aText[layoutRun->item->offset]); */
-+
-+        for (gint i=0; i < layoutRun->glyphs->num_glyphs; i++) {
-+            /* printf("glyph %d offset %d orig width %d new width %d\n", i,
-+             *        layoutRun->glyphs->log_clusters[i] + layoutRun->item->offset,
-+             *        layoutRun->glyphs->glyphs[i].geometry.width,
-+             *       (gint)(utf8spacing[layoutRun->glyphs->log_clusters[i] + layoutRun->item->offset] * app2dev * PANGO_SCALE));
-+             */
-+            gint thisOffset = (gint)(utf8spacing[layoutRun->glyphs->log_clusters[i] + layoutRun->item->offset]
-+                                     * app2dev * PANGO_SCALE);
-+            layoutRun->glyphs->glyphs[i].geometry.width = thisOffset;
-+            tmpOffset += thisOffset;
-+        }
-+
-+        /*        printf("    rendering at X coord %d\n", aX + offset); */
-+        offset += tmpOffset;
-+    }
-+
-+    draw_layout_line (aX, aY, aLine, this, aContext);
-+
-+    delete[] utf8spacing;
-+}
-+
-+nsresult
-+nsFontMetricsPSPango::GetTextDimensionsInternal(const gchar*        aString,
-+                                              PRInt32             aLength,
-+                                              PRInt32             aAvailWidth,
-+                                              PRInt32*            aBreaks,
-+                                              PRInt32             aNumBreaks,
-+                                              nsTextDimensions&   aDimensions,
-+                                              PRInt32&            aNumCharsFit,
-+                                              nsTextDimensions&   aLastWordDimensions)
-+{
-+    NS_PRECONDITION(aBreaks[aNumBreaks - 1] == aLength, "invalid break array");
-+
-+    // If we need to back up this state represents the last place
-+    // we could break. We can use this to avoid remeasuring text
-+    PRInt32 prevBreakState_BreakIndex = -1; // not known
-+                                            // (hasn't been computed)
-+    nscoord prevBreakState_Width = 0; // accumulated width to this point
-+
-+    // Initialize OUT parameters
-+    GetMaxAscent(aLastWordDimensions.ascent);
-+    GetMaxDescent(aLastWordDimensions.descent);
-+    aLastWordDimensions.width = -1;
-+    aNumCharsFit = 0;
-+
-+    // Iterate each character in the string and determine which font to use
-+    nscoord width = 0;
-+    PRInt32 start = 0;
-+    nscoord aveCharWidth;
-+    GetAveCharWidth(aveCharWidth);
-+
-+    while (start < aLength) {
-+        // Estimate how many characters will fit. Do that by
-+        // diving the available space by the average character
-+        // width. Make sure the estimated number of characters is
-+        // at least 1
-+        PRInt32 estimatedNumChars = 0;
-+
-+        if (aveCharWidth > 0)
-+            estimatedNumChars = (aAvailWidth - width) / aveCharWidth;
-+
-+        if (estimatedNumChars < 1)
-+            estimatedNumChars = 1;
-+
-+        // Find the nearest break offset
-+        PRInt32 estimatedBreakOffset = start + estimatedNumChars;
-+        PRInt32 breakIndex;
-+        nscoord numChars;
-+
-+        // Find the nearest place to break that is less than or equal to
-+        // the estimated break offset
-+        if (aLength <= estimatedBreakOffset) {
-+            // All the characters should fit
-+            numChars = aLength - start;
-+            breakIndex = aNumBreaks - 1;
-+        } 
-+        else {
-+            breakIndex = prevBreakState_BreakIndex;
-+            while (((breakIndex + 1) < aNumBreaks) &&
-+                   (aBreaks[breakIndex + 1] <= estimatedBreakOffset)) {
-+                ++breakIndex;
-+            }
-+
-+            if (breakIndex == prevBreakState_BreakIndex) {
-+                ++breakIndex; // make sure we advanced past the
-+                // previous break index
-+            }
-+
-+            numChars = aBreaks[breakIndex] - start;
-+        }
-+
-+        // Measure the text
-+        nscoord twWidth = 0;
-+        if ((1 == numChars) && (aString[start] == ' '))
-+            GetSpaceWidth(twWidth);
-+        else if (numChars > 0)
-+            GetWidth(&aString[start], numChars, twWidth);
-+
-+        // See if the text fits
-+        PRBool  textFits = (twWidth + width) <= aAvailWidth;
-+
-+        // If the text fits then update the width and the number of
-+        // characters that fit
-+        if (textFits) {
-+            aNumCharsFit += numChars;
-+            width += twWidth;
-+            start += numChars;
-+
-+            // This is a good spot to back up to if we need to so remember
-+            // this state
-+            prevBreakState_BreakIndex = breakIndex;
-+            prevBreakState_Width = width;
-+        }
-+        else {
-+            // See if we can just back up to the previous saved
-+            // state and not have to measure any text
-+            if (prevBreakState_BreakIndex > 0) {
-+                // If the previous break index is just before the
-+                // current break index then we can use it
-+                if (prevBreakState_BreakIndex == (breakIndex - 1)) {
-+                    aNumCharsFit = aBreaks[prevBreakState_BreakIndex];
-+                    width = prevBreakState_Width;
-+                    break;
-+                }
-+            }
-+
-+            // We can't just revert to the previous break state
-+            if (0 == breakIndex) {
-+                // There's no place to back up to, so even though
-+                // the text doesn't fit return it anyway
-+                aNumCharsFit += numChars;
-+                width += twWidth;
-+                break;
-+            }
-+
-+            // Repeatedly back up until we get to where the text
-+            // fits or we're all the way back to the first word
-+            width += twWidth;
-+            while ((breakIndex >= 1) && (width > aAvailWidth)) {
-+                twWidth = 0;
-+                start = aBreaks[breakIndex - 1];
-+                numChars = aBreaks[breakIndex] - start;
-+
-+                if ((1 == numChars) && (aString[start] == ' '))
-+                    GetSpaceWidth(twWidth);
-+                else if (numChars > 0)
-+                    GetWidth(&aString[start], numChars, twWidth);
-+                width -= twWidth;
-+                aNumCharsFit = start;
-+                breakIndex--;
-+            }
-+            break;
-+        }
-+    }
-+
-+    aDimensions.width = width;
-+    GetMaxAscent(aDimensions.ascent);
-+    GetMaxDescent(aDimensions.descent);
-+
-+    /*    printf("aDimensions %d %d %d aLastWordDimensions %d %d %d aNumCharsFit %d\n",
-+           aDimensions.width, aDimensions.ascent, aDimensions.descent,
-+           aLastWordDimensions.width, aLastWordDimensions.ascent, aLastWordDimensions.descent,
-+           aNumCharsFit); */
-+
-+    return NS_OK;
-+}
-+
-+void
-+nsFontMetricsPSPango::FixupSpaceWidths (PangoLayout *aLayout,
-+                                      const char *aString)
-+{
-+    PangoLayoutLine *line = pango_layout_get_line(aLayout, 0);
-+
-+    gint curRun = 0;
-+
-+    for (GSList *tmpList = line->runs; tmpList && tmpList->data;
-+         tmpList = tmpList->next, curRun++) {
-+        PangoLayoutRun *layoutRun = (PangoLayoutRun *)tmpList->data;
-+
-+        for (gint i=0; i < layoutRun->glyphs->num_glyphs; i++) {
-+            gint thisOffset = (gint)layoutRun->glyphs->log_clusters[i] + layoutRun->item->offset;
-+            if (aString[thisOffset] == ' ')
-+                layoutRun->glyphs->glyphs[i].geometry.width = mPangoSpaceWidth;
-+        }
-+    }
-+}
-+
-+/* static */
-+PangoLanguage *
-+GetPangoLanguage(nsIAtom *aLangGroup)
-+{
-+    // Find the FC lang group for this lang group
-+    nsCAutoString cname;
-+    aLangGroup->ToUTF8String(cname);
-+
-+    // see if the lang group needs to be translated from mozilla's
-+    // internal mapping into fontconfig's
-+    const MozGtkLangGroup *langGroup;
-+    langGroup = NS_FindFCLangGroup(cname);
-+
-+    // if there's no lang group, just use the lang group as it was
-+    // passed to us
-+    //
-+    // we're casting away the const here for the strings - should be
-+    // safe.
-+    if (!langGroup)
-+        return pango_language_from_string(cname.get());
-+    else if (langGroup->Lang) 
-+        return pango_language_from_string((char *) langGroup->Lang);
-+
-+    return pango_language_from_string("en");
-+}
-+
-+/* static */
-+void
-+FreeGlobals(void)
-+{
-+}
-+
-+/* static */
-+PangoStyle
-+CalculateStyle(PRUint8 aStyle)
-+{
-+    switch(aStyle) {
-+    case NS_FONT_STYLE_ITALIC:
-+        return PANGO_STYLE_OBLIQUE;
-+        break;
-+    case NS_FONT_STYLE_OBLIQUE:
-+        return PANGO_STYLE_OBLIQUE;
-+        break;
-+    }
-+
-+    return PANGO_STYLE_NORMAL;
-+}
-+
-+/* static */
-+PangoWeight
-+CalculateWeight (PRUint16 aWeight)
-+{
-+    /*
-+     * weights come in two parts crammed into one
-+     * integer -- the "base" weight is weight / 100,
-+     * the rest of the value is the "offset" from that
-+     * weight -- the number of steps to move to adjust
-+     * the weight in the list of supported font weights,
-+     * this value can be negative or positive.
-+     */
-+    PRInt32 baseWeight = (aWeight + 50) / 100;
-+    PRInt32 offset = aWeight - baseWeight * 100;
-+
-+    /* clip weights to range 0 to 9 */
-+    if (baseWeight < 0)
-+        baseWeight = 0;
-+    if (baseWeight > 9)
-+        baseWeight = 9;
-+
-+    /* Map from weight value to fcWeights index */
-+    static int fcWeightLookup[10] = {
-+        0, 0, 0, 0, 1, 1, 2, 3, 3, 4,
-+    };
-+
-+    PRInt32 fcWeight = fcWeightLookup[baseWeight];
-+
-+    /*
-+     * adjust by the offset value, make sure we stay inside the 
-+     * fcWeights table
-+     */
-+    fcWeight += offset;
-+
-+    if (fcWeight < 0)
-+        fcWeight = 0;
-+    if (fcWeight > 4)
-+        fcWeight = 4;
-+
-+    /* Map to final PANGO_WEIGHT value */
-+    static int fcWeights[5] = {
-+        349,
-+        499,
-+        649,
-+        749,
-+        999
-+    };
-+
-+    return (PangoWeight)fcWeights[fcWeight];
-+}
-+
-+/* static */
-+nsresult
-+EnumFontsPango(nsIAtom* aLangGroup, const char* aGeneric,
-+               PRUint32* aCount, PRUnichar*** aResult)
-+{
-+    FcPattern   *pat = NULL;
-+    FcObjectSet *os  = NULL;
-+    FcFontSet   *fs  = NULL;
-+    nsresult     rv  = NS_ERROR_FAILURE;
-+
-+    PRUnichar **array = NULL;
-+    PRUint32    narray = 0;
-+    PRInt32     serif = 0, sansSerif = 0, monospace = 0, nGenerics;
-+
-+    *aCount = 0;
-+    *aResult = nsnull;
-+
-+    pat = FcPatternCreate();
-+    if (!pat)
-+        goto end;
-+
-+    os = FcObjectSetBuild(FC_FAMILY, FC_FOUNDRY, NULL);
-+    if (!os)
-+        goto end;
-+
-+    // take the pattern and add the lang group to it
-+    if (aLangGroup)
-+        NS_AddLangGroup(pat, aLangGroup);
-+
-+    // get the font list
-+    fs = FcFontList(0, pat, os);
-+
-+    if (!fs)
-+        goto end;
-+
-+    if (!fs->nfont) {
-+        rv = NS_OK;
-+        goto end;
-+    }
-+
-+    // Fontconfig supports 3 generic fonts, "serif", "sans-serif", and
-+    // "monospace", slightly different from CSS's 5.
-+    if (!aGeneric)
-+        serif = sansSerif = monospace = 1;
-+    else if (!strcmp(aGeneric, "serif"))
-+        serif = 1;
-+    else if (!strcmp(aGeneric, "sans-serif"))
-+        sansSerif = 1;
-+    else if (!strcmp(aGeneric, "monospace"))
-+        monospace = 1;
-+    else if (!strcmp(aGeneric, "cursive") || !strcmp(aGeneric, "fantasy"))
-+        serif = sansSerif =  1;
-+    else
-+        NS_NOTREACHED("unexpected generic family");
-+    nGenerics = serif + sansSerif + monospace;
-+
-+    array = NS_STATIC_CAST(PRUnichar **,
-+               nsMemory::Alloc((fs->nfont + nGenerics) * sizeof(PRUnichar *)));
-+    if (!array)
-+        goto end;
-+
-+    if (serif) {
-+        PRUnichar *name = ToNewUnicode(NS_LITERAL_STRING("serif"));
-+        if (!name)
-+            goto end;
-+        array[narray++] = name;
-+    }
-+
-+    if (sansSerif) {
-+        PRUnichar *name = ToNewUnicode(NS_LITERAL_STRING("sans-serif"));
-+        if (!name)
-+            goto end;
-+        array[narray++] = name;
-+    }
-+
-+    if (monospace) {
-+        PRUnichar *name = ToNewUnicode(NS_LITERAL_STRING("monospace"));
-+        if (!name)
-+            goto end;
-+        array[narray++] = name;
-+    }
-+
-+    for (int i=0; i < fs->nfont; ++i) {
-+        char *family;
-+
-+        // if there's no family, just move to the next iteration
-+        if (FcPatternGetString (fs->fonts[i], FC_FAMILY, 0,
-+                                (FcChar8 **) &family) != FcResultMatch) {
-+            continue;
-+        }
-+
-+        // fontconfig always returns family names in UTF-8
-+        PRUnichar* name =  UTF8ToNewUnicode(nsDependentCString(family));
-+
-+        if (!name)
-+            goto end;
-+
-+        array[narray++] = name;
-+    }
-+
-+    NS_QuickSort(array + nGenerics, narray - nGenerics, sizeof (PRUnichar*),
-+                 CompareFontNames, nsnull);
-+
-+    *aCount = narray;
-+    if (narray)
-+        *aResult = array;
-+    else
-+        nsMemory::Free(array);
-+
-+    rv = NS_OK;
-+
-+ end:
-+    if (NS_FAILED(rv) && array) {
-+        while (narray)
-+            nsMemory::Free (array[--narray]);
-+        nsMemory::Free (array);
-+    }
-+    if (pat)
-+        FcPatternDestroy(pat);
-+    if (os)
-+        FcObjectSetDestroy(os);
-+    if (fs)
-+        FcFontSetDestroy(fs);
-+
-+    return rv;
-+}
-+
-+/* static */
-+int
-+CompareFontNames (const void* aArg1, const void* aArg2, void* aClosure)
-+{
-+    const PRUnichar* str1 = *((const PRUnichar**) aArg1);
-+    const PRUnichar* str2 = *((const PRUnichar**) aArg2);
-+
-+    return nsCRT::strcmp(str1, str2);
-+}
-+
-+
-+// nsFontEnumeratorPango class
-+
-+nsFontEnumeratorPango::nsFontEnumeratorPango()
-+{
-+}
-+
-+NS_IMPL_ISUPPORTS1(nsFontEnumeratorPango, nsIFontEnumerator)
-+
-+NS_IMETHODIMP
-+nsFontEnumeratorPango::EnumerateAllFonts(PRUint32 *aCount,
-+                                         PRUnichar ***aResult)
-+{
-+    NS_ENSURE_ARG_POINTER(aResult);
-+    *aResult = nsnull;
-+    NS_ENSURE_ARG_POINTER(aCount);
-+    *aCount = 0;
-+
-+    return EnumFontsPango(nsnull, nsnull, aCount, aResult);
-+}
-+
-+NS_IMETHODIMP
-+nsFontEnumeratorPango::EnumerateFonts(const char *aLangGroup,
-+                                      const char *aGeneric,
-+                                      PRUint32 *aCount,
-+                                      PRUnichar ***aResult)
-+{
-+    NS_ENSURE_ARG_POINTER(aResult);
-+    *aResult = nsnull;
-+    NS_ENSURE_ARG_POINTER(aCount);
-+    *aCount = 0;
-+
-+    // aLangGroup=null or ""  means any (i.e., don't care)
-+    // aGeneric=null or ""  means any (i.e, don't care)
-+    nsCOMPtr<nsIAtom> langGroup;
-+    if (aLangGroup && *aLangGroup)
-+        langGroup = do_GetAtom(aLangGroup);
-+    const char* generic = nsnull;
-+    if (aGeneric && *aGeneric)
-+        generic = aGeneric;
-+
-+    return EnumFontsPango(langGroup, generic, aCount, aResult);
-+}
-+
-+NS_IMETHODIMP
-+nsFontEnumeratorPango::HaveFontFor(const char *aLangGroup,
-+                                   PRBool *aResult)
-+{
-+    NS_ENSURE_ARG_POINTER(aResult);
-+    *aResult = PR_FALSE;
-+    NS_ENSURE_ARG_POINTER(aLangGroup);
-+
-+    *aResult = PR_TRUE; // always return true for now.
-+    // Finish me - ftang
-+    return NS_OK;
-+}
-+
-+NS_IMETHODIMP
-+nsFontEnumeratorPango::GetDefaultFont(const char *aLangGroup,
-+                                      const char *aGeneric,
-+                                      PRUnichar **aResult)
-+{
-+    NS_ENSURE_ARG_POINTER(aResult);
-+    *aResult = nsnull;
-+
-+    // Have a look at nsFontEnumeratorXft::GetDefaultFont for some
-+    // possible code for this function.
-+
-+    return NS_OK;
-+}
-+
-+NS_IMETHODIMP
-+nsFontEnumeratorPango::UpdateFontList(PRBool *_retval)
-+{
-+    *_retval = PR_FALSE; // always return false for now
-+    return NS_OK;
-+}
-Index: gfx/src/ps/nsFontMetricsPSPango.h
-===================================================================
-RCS file: gfx/src/ps/nsFontMetricsPSPango.h
-diff -N gfx/src/ps/nsFontMetricsPSPango.h
---- /dev/null  1 Jan 1970 00:00:00 -0000
-+++ gfx/src/ps/nsFontMetricsPSPango.h  23 Oct 2006 17:37:13 -0000
-@@ -0,0 +1,305 @@
-+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-+/* vim:expandtab:shiftwidth=4:tabstop=4:
-+ */
-+/* ***** BEGIN LICENSE BLOCK *****
-+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
-+ *
-+ * The contents of this file are subject to the Mozilla Public License Version
-+ * 1.1 (the "License"); you may not use this file except in compliance with
-+ * the License. You may obtain a copy of the License at
-+ * http://www.mozilla.org/MPL/
-+ *
-+ * Software distributed under the License is distributed on an "AS IS" basis,
-+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-+ * for the specific language governing rights and limitations under the
-+ * License.
-+ *
-+ * The Original Code is mozilla.org code.
-+ *
-+ * The Initial Developer of the Original Code is
-+ * Christopher Blizzard <blizzard@mozilla.org>.  
-+ * Portions created by the Initial Developer are Copyright (C) 2002
-+ * the Initial Developer. All Rights Reserved.
-+ *
-+ * Contributor(s):
-+ *
-+ * 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
-+ * of those above. If you wish to allow use of your version of this file only
-+ * under the terms of either the GPL or the LGPL, and not to allow others to
-+ * 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 ***** */
-+
-+#ifndef nsFontMetricsPSPango_h__
-+#define nsFontMetricsPSPango_h__
-+
-+#include "nsIFontMetrics.h"
-+#include "nsIFontEnumerator.h"
-+#include "nsCRT.h"
-+#include "nsIAtom.h"
-+#include "nsString.h"
-+#include "nsVoidArray.h"
-+#include "nsFontMetricsPS.h"
-+
-+#include <pango/pango.h>
-+
-+class nsRenderingContextPS;
-+class nsIDrawingSurface;
-+
-+class nsFontMetricsPSPango : public nsFontMetricsPS
-+{
-+public:
-+    nsFontMetricsPSPango();
-+    virtual ~nsFontMetricsPSPango();
-+
-+    NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
-+
-+    // nsISupports
-+    NS_DECL_ISUPPORTS
-+
-+    // nsIFontMetrics
-+    NS_IMETHOD  Init                 (const nsFont& aFont, nsIAtom* aLangGroup,
-+                                      nsIDeviceContext *aContext);
-+    NS_IMETHOD  Destroy();
-+    NS_IMETHOD  GetLangGroup         (nsIAtom** aLangGroup);
-+    NS_IMETHOD  GetFontHandle        (nsFontHandle &aHandle);
-+
-+    NS_IMETHOD  GetXHeight           (nscoord& aResult)
-+                                     { aResult = mXHeight; return NS_OK; };
-+
-+    NS_IMETHOD GetSuperscriptOffset  (nscoord& aResult)
-+                                     { aResult = mSuperscriptOffset;
-+                                       return NS_OK; };
-+
-+    NS_IMETHOD GetSubscriptOffset    (nscoord& aResult)
-+                                     { aResult = mSubscriptOffset;
-+                                       return NS_OK; };
-+                              
-+    NS_IMETHOD GetStrikeout          (nscoord& aOffset, nscoord& aSize)
-+                                     { aOffset = mStrikeoutOffset;
-+                                       aSize = mStrikeoutSize; 
-+                                       return NS_OK; };
-+
-+    NS_IMETHOD GetUnderline          (nscoord& aOffset, nscoord& aSize)
-+                                     { aOffset = mUnderlineOffset;
-+                                       aSize = mUnderlineSize; 
-+                                       return NS_OK; };
-+
-+    NS_IMETHOD GetHeight             (nscoord &aHeight)
-+                                     { aHeight = mMaxHeight; 
-+                                       return NS_OK; };
-+
-+    NS_IMETHOD GetNormalLineHeight   (nscoord &aHeight)
-+                                     { aHeight = mEmHeight + mLeading;
-+                                       return NS_OK; };
-+
-+    NS_IMETHOD GetLeading            (nscoord &aLeading)
-+                                     { aLeading = mLeading; 
-+                                       return NS_OK; };
-+
-+    NS_IMETHOD GetEmHeight           (nscoord &aHeight)
-+                                     { aHeight = mEmHeight; 
-+                                       return NS_OK; };
-+
-+    NS_IMETHOD GetEmAscent           (nscoord &aAscent)
-+                                     { aAscent = mEmAscent;
-+                                       return NS_OK; };
-+
-+    NS_IMETHOD GetEmDescent          (nscoord &aDescent)
-+                                     { aDescent = mEmDescent;
-+                                       return NS_OK; };
-+
-+    NS_IMETHOD GetMaxHeight          (nscoord &aHeight)
-+                                     { aHeight = mMaxHeight;
-+                                       return NS_OK; };
-+
-+    NS_IMETHOD GetMaxAscent          (nscoord &aAscent)
-+                                     { aAscent = mMaxAscent;
-+                                       return NS_OK; };
-+
-+    NS_IMETHOD GetMaxDescent         (nscoord &aDescent)
-+                                     { aDescent = mMaxDescent;
-+                                       return NS_OK; };
-+
-+    NS_IMETHOD GetMaxAdvance         (nscoord &aAdvance)
-+                                     { aAdvance = mMaxAdvance;
-+                                       return NS_OK; };
-+
-+    NS_IMETHOD GetSpaceWidth         (nscoord &aSpaceCharWidth)
-+                                     { aSpaceCharWidth = mSpaceWidth;
-+                                       return NS_OK; };
-+
-+    NS_IMETHOD GetAveCharWidth       (nscoord &aAveCharWidth)
-+                                     { aAveCharWidth = mAveCharWidth;
-+                                       return NS_OK; };
-+
-+    // nsIFontMetricsPS (calls from the font rendering layer)
-+    NS_IMETHOD  GetStringWidth(const char *String,nscoord &aWidth,nscoord aLength);
-+    NS_IMETHOD  GetStringWidth(const PRUnichar *aString,nscoord &aWidth,nscoord aLength);
-+
-+    NS_IMETHOD       GetWidth(const char* aString, PRUint32 aLength,
-+                              nscoord& aWidth);
-+    NS_IMETHOD       GetWidth(const PRUnichar* aString, PRUint32 aLength,
-+                              nscoord& aWidth);
-+
-+    NS_IMETHOD       GetTextDimensions(const char* aString,
-+                                       PRUint32 aLength,
-+                                       nsTextDimensions& aDimensions);
-+    NS_IMETHOD       GetTextDimensions(const PRUnichar* aString,
-+                                       PRUint32 aLength,
-+                                       nsTextDimensions& aDimensions, 
-+                                       PRInt32* aFontID);
-+    NS_IMETHOD       GetTextDimensions(const char*         aString,
-+                                       PRInt32             aLength,
-+                                       PRInt32             aAvailWidth,
-+                                       PRInt32*            aBreaks,
-+                                       PRInt32             aNumBreaks,
-+                                       nsTextDimensions&   aDimensions,
-+                                       PRInt32&            aNumCharsFit,
-+                                       nsTextDimensions&   aLastWordDimensions,
-+                                       PRInt32*            aFontID);
-+    NS_IMETHOD       GetTextDimensions(const PRUnichar*    aString,
-+                                       PRInt32             aLength,
-+                                       PRInt32             aAvailWidth,
-+                                       PRInt32*            aBreaks,
-+                                       PRInt32             aNumBreaks,
-+                                       nsTextDimensions&   aDimensions,
-+                                       PRInt32&            aNumCharsFit,
-+                                       nsTextDimensions&   aLastWordDimensions,
-+                                       PRInt32*            aFontID);
-+
-+    NS_IMETHOD       DrawString(const char *aString, PRUint32 aLength,
-+                                nscoord aX, nscoord aY,
-+                                const nscoord* aSpacing,
-+                                nsRenderingContextPS *aContext);
-+    NS_IMETHOD       DrawString(const PRUnichar* aString, PRUint32 aLength,
-+                                nscoord aX, nscoord aY,
-+                                PRInt32 aFontID,
-+                                const nscoord* aSpacing,
-+                                nsRenderingContextPS *aContext);
-+
-+#ifdef MOZ_MATHML
-+    NS_IMETHOD       GetBoundingMetrics(const char *aString, PRUint32 aLength,
-+                                        nsBoundingMetrics &aBoundingMetrics);
-+    NS_IMETHOD       GetBoundingMetrics(const PRUnichar *aString,
-+                                        PRUint32 aLength,
-+                                        nsBoundingMetrics &aBoundingMetrics,
-+                                        PRInt32 *aFontID);
-+#endif /* MOZ_MATHML */
-+
-+    NS_IMETHOD       SetRightToLeftText(PRBool aIsRTL);
-+
-+    NS_IMETHOD       GetClusterInfo(const PRUnichar *aText,
-+                                    PRUint32 aLength,
-+                                    PRUint8 *aClusterStarts);
-+
-+    virtual PRInt32 GetPosition(const PRUnichar *aText,
-+                                PRUint32 aLength,
-+                                nsPoint aPt);
-+
-+    NS_IMETHOD       GetRangeWidth(const PRUnichar *aText,
-+                                   PRUint32 aLength,
-+                                   PRUint32 aStart,
-+                                   PRUint32 aEnd,
-+                                   PRUint32 &aWidth);
-+
-+    NS_IMETHOD       GetRangeWidth(const char *aText,
-+                                   PRUint32 aLength,
-+                                   PRUint32 aStart,
-+                                   PRUint32 aEnd,
-+                                   PRUint32 &aWidth);
-+
-+    // get hints for the font
-+    virtual PRUint32    GetHints     (void);
-+
-+    // drawing surface methods
-+    static nsresult FamilyExists    (nsIDeviceContext *aDevice,
-+                                     const nsString &aName);
-+
-+    inline nsIDeviceContext *GetDeviceContext() { return mDeviceContext; }
-+
-+private:
-+
-+    // generic font metrics class bits
-+    nsCStringArray       mFontList;
-+    nsAutoVoidArray      mFontIsGeneric;
-+
-+    nsIDeviceContext    *mDeviceContext;
-+    nsCOMPtr<nsIAtom>    mLangGroup;
-+    nsCString           *mGenericFont;
-+    float                mPointSize;
-+
-+    nsCAutoString        mDefaultFont;
-+
-+    // Pango-related items
-+    PangoFontDescription *mPangoFontDesc;
-+    PangoContext         *mPangoContext;
-+    PangoContext         *mLTRPangoContext;
-+    PangoContext         *mRTLPangoContext;
-+    PangoAttrList        *mPangoAttrList;
-+    PRBool                mIsRTL;
-+
-+    // Cached font metrics
-+    nscoord                  mXHeight;
-+    nscoord                  mSuperscriptOffset;
-+    nscoord                  mSubscriptOffset;
-+    nscoord                  mStrikeoutOffset;
-+    nscoord                  mStrikeoutSize;
-+    nscoord                  mUnderlineOffset;
-+    nscoord                  mUnderlineSize;
-+    nscoord                  mMaxHeight;
-+    nscoord                  mLeading;
-+    nscoord                  mEmHeight;
-+    nscoord                  mEmAscent;
-+    nscoord                  mEmDescent;
-+    nscoord                  mMaxAscent;
-+    nscoord                  mMaxDescent;
-+    nscoord                  mMaxAdvance;
-+    nscoord                  mSpaceWidth;
-+    nscoord                  mPangoSpaceWidth;
-+    nscoord                  mAveCharWidth;
-+
-+    // Private methods
-+    nsresult RealizeFont(void);
-+    nsresult CacheFontMetrics(void);
-+
-+    static PRBool EnumFontCallback(const nsString &aFamily,
-+                                   PRBool aIsGeneric, void *aData);
-+
-+    void     DrawStringSlowly(const gchar *aText,
-+                              const PRUnichar *aOrigString,
-+                              PRUint32 aLength,
-+                              gint aX, gint aY,
-+                              PangoLayoutLine *aLine,
-+                              const nscoord *aSpacing,
-+                              nsRenderingContextPS *aContext);
-+
-+    nsresult GetTextDimensionsInternal(const gchar*        aString,
-+                                       PRInt32             aLength,
-+                                       PRInt32             aAvailWidth,
-+                                       PRInt32*            aBreaks,
-+                                       PRInt32             aNumBreaks,
-+                                       nsTextDimensions&   aDimensions,
-+                                       PRInt32&            aNumCharsFit,
-+                                       nsTextDimensions&   aLastWordDimensions);
-+
-+    void FixupSpaceWidths (PangoLayout *aLayout, const char *aString);
-+};
-+
-+class nsFontEnumeratorPango : public nsIFontEnumerator
-+{
-+public:
-+    nsFontEnumeratorPango();
-+    NS_DECL_ISUPPORTS
-+    NS_DECL_NSIFONTENUMERATOR
-+};
-+
-+#endif
-+
-Index: gfx/src/ps/nsPostScriptObj.cpp
-===================================================================
-RCS file: /cvsroot/mozilla/gfx/src/ps/nsPostScriptObj.cpp,v
-retrieving revision 1.124
-diff -u -p -d -r1.124 nsPostScriptObj.cpp
---- gfx/src/ps/nsPostScriptObj.cpp     26 Jul 2005 15:54:18 -0000      1.124
-+++ gfx/src/ps/nsPostScriptObj.cpp     23 Oct 2006 17:37:29 -0000
-@@ -2061,31 +2061,74 @@ nsPostScriptObj::show(const PRUnichar* t
- #if defined(MOZ_ENABLE_FREETYPE2) || defined(MOZ_ENABLE_XFT)
- void 
--nsPostScriptObj::show(const PRUnichar* aTxt, int aLen,
--                      const nsAFlatString& aCharList, PRUint16 aSubFontIdx)
-+/*nsPostScriptObj::show(const PRUnichar* aTxt, int aLen,
-+  const nsAFlatString& aCharList, PRUint16 aSubFontIdx) */
-+nsPostScriptObj::show(const nsValueArray *aGlyphs, nsPSFontGenerator *aSubset,
-+                      PRUint16 aSubFontIdx)
- {
--  int i;
-+  PRUint32 i;
-   fputc('<', mScriptFP);
--  const PRUint16 subFontSize = nsPSFontGenerator::kSubFontSize;
-+  for (i = 0; i < aGlyphs->Count(); i++) {
-+    PRUint32 glyph = aGlyphs->ValueAt(i);
-+    fprintf(mScriptFP, "%02x", aSubset->InSubsetIndexOf(glyph));
-+  }
--  // the character repertoire of a subfont (255 characters max)
--  const nsAString& repertoire = 
--        Substring(aCharList, aSubFontIdx * subFontSize,
--                  PR_MIN(subFontSize, 
--                  aCharList.Length() - aSubFontIdx * subFontSize));
-+  fputs("> show\n", mScriptFP);
-+}
-+#endif
--  for (i = 0; i < aLen; i++) {
--    // XXX This is a little inefficient, but printing is not perf. critical. 
--    NS_ASSERTION(repertoire.FindChar(aTxt[i]) != kNotFound,
--        "character is not covered by this subfont");
--      
--    // Type 1 encoding vector has 256 slots, but the 0-th slot is 
--    // reserved for /.notdef so that we use the 1st through 255th slots
--    // for actual characters (hence '+ 1')
--    fprintf(mScriptFP, "%02x", repertoire.FindChar(aTxt[i]) + 1); 
-+#ifdef MOZ_ENABLE_PANGO
-+void
-+nsPostScriptObj::show(const PangoGlyphString *glyphs, float zoom, 
-+                      nsPSFontGenerator *aSubset, PRUint16 aSubFontIdx)
-+{
-+  PRUint32 i;
-+  int horiz = 1;
-+
-+  if (glyphs->glyphs[0].geometry.x_offset || glyphs->glyphs[0].geometry.y_offset)
-+    rmoveto (NSToCoordRound (zoom * glyphs->glyphs[0].geometry.x_offset / PANGO_SCALE),
-+             NSToCoordRound (zoom * glyphs->glyphs[0].geometry.y_offset / PANGO_SCALE));
-+
-+  fputc('<', mScriptFP);
-+
-+  for (i = 0; i < glyphs->num_glyphs; i++) {
-+    PRUint32 glyph = glyphs->glyphs[i].glyph;
-+    fprintf(mScriptFP, "%02x", aSubset->InSubsetIndexOf(glyph));
-+    if (glyphs->glyphs[i].geometry.y_offset)
-+      horiz = 0;
-+  }
-+
-+  if (horiz) {
-+    fputs(">\n[", mScriptFP);
-+    for (i = 1; i < glyphs->num_glyphs; i++) {
-+      fprintf(mScriptFP, "%d ",
-+              NSToCoordRound (zoom * (+ glyphs->glyphs[i  ].geometry.x_offset
-+                                      + glyphs->glyphs[i-1].geometry.width
-+                                      - glyphs->glyphs[i-1].geometry.x_offset) / PANGO_SCALE));
-+    }
-+    fprintf(mScriptFP, "%d",
-+              NSToCoordRound (zoom * (+ glyphs->glyphs[i-1].geometry.width
-+                                      - glyphs->glyphs[i-1].geometry.x_offset
-+                                      - glyphs->glyphs[  0].geometry.x_offset) / PANGO_SCALE));
-+    fputs("] xshow\n", mScriptFP);
-+  } else {
-+    fputs(">\n[", mScriptFP);
-+    for (i = 1; i < glyphs->num_glyphs; i++) {
-+      fprintf(mScriptFP, "%d %d ",
-+              NSToCoordRound (zoom * (+ glyphs->glyphs[i  ].geometry.x_offset
-+                                      + glyphs->glyphs[i-1].geometry.width
-+                                      - glyphs->glyphs[i-1].geometry.x_offset) / PANGO_SCALE),
-+              NSToCoordRound (zoom * (+ glyphs->glyphs[i  ].geometry.y_offset
-+                                      - glyphs->glyphs[i-1].geometry.y_offset) / PANGO_SCALE));
-+    }
-+    fprintf(mScriptFP, "%d %d",
-+              NSToCoordRound (zoom * (+ glyphs->glyphs[i-1].geometry.width
-+                                      - glyphs->glyphs[i-1].geometry.x_offset
-+                                      - glyphs->glyphs[  0].geometry.x_offset) / PANGO_SCALE),
-+              NSToCoordRound (zoom * (- glyphs->glyphs[i-1].geometry.y_offset) / PANGO_SCALE));
-+    fputs("] xyshow\n", mScriptFP);
-   }
--  fputs("> show\n", mScriptFP);
- }
- #endif
-@@ -2101,6 +2144,16 @@ nsPostScriptObj::moveto(nscoord x, nscoo
- /** ---------------------------------------------------
-  *  See documentation in nsPostScriptObj.h
-+ *    @update 10/20/06 behdad
-+ */
-+void 
-+nsPostScriptObj::rmoveto(nscoord x, nscoord y)
-+{
-+  fprintf(mScriptFP, "%d %d rmoveto\n", x, y);
-+}
-+
-+/** ---------------------------------------------------
-+ *  See documentation in nsPostScriptObj.h
-  *    @update 2/1/99 dwc
-  */
- void 
-Index: gfx/src/ps/nsPostScriptObj.h
-===================================================================
-RCS file: /cvsroot/mozilla/gfx/src/ps/nsPostScriptObj.h,v
-retrieving revision 1.47
-diff -u -p -d -r1.47 nsPostScriptObj.h
---- gfx/src/ps/nsPostScriptObj.h       8 May 2005 15:01:20 -0000       1.47
-+++ gfx/src/ps/nsPostScriptObj.h       23 Oct 2006 17:37:30 -0000
-@@ -57,9 +57,15 @@
- #include "nsIPersistentProperties2.h"
- #include "nsTempfilePS.h"
- #include "nsEPSObjectPS.h"
-+#ifdef MOZ_ENABLE_PANGO
-+#include <pango/pango.h>
-+#endif
-+
-+class nsPSFontGenerator;
- class nsIImage;
- class nsIAtom;
-+class nsValueArray;
- #endif
- #include <stdio.h>
-@@ -217,6 +223,14 @@ public:
-    */
-   void moveto(nscoord aX, nscoord aY);
-   /** ---------------------------------------------------
-+   *  Move relative to the current point
-+   *  @update 10/20/2006 behdad
-+   *  @param  aX   X coordinate
-+   *          aY   Y coordinate
-+   *    @return VOID
-+   */
-+  void rmoveto(nscoord aX, nscoord aY);
-+  /** ---------------------------------------------------
-    *  Add a line to the current path, from the current point
-    *  to the specified point.
-    *  @update 9/30/2003
-@@ -346,12 +360,24 @@ public:
-    */
-   void show(const PRUnichar* aText, int aLen, const char *aAlign, int aType);
-   /** ---------------------------------------------------
--   *  This version takes a PRUnichar string, a font subset string
--   *  for freetype printing and a subfont index
-+   *  This version of show takes an array of glyphs, subfont and subfont index
-+   *  to render and is used for freetype and xft printing.
-    *  @update 2/15/2005 jshin@mailaps.org
-+   *    @update 6/7/2005 blizzard@mozilla.org
-    */
--  void show(const PRUnichar* aText, int aLen, const nsAFlatString& aCharList,
-+  void show(const nsValueArray *aGlyphs, nsPSFontGenerator *aSubset,
-             PRUint16 aSubFontIdx);
-+  /*void show(const PRUnichar* aText, int aLen, const nsAFlatString& aCharList,
-+    PRUint16 aSubFontIdx); */
-+#ifdef MOZ_ENABLE_PANGO
-+  /** ---------------------------------------------------
-+   *  This version of show takes a pango glyph string, subfont and subfont index
-+   *  to render and is used for pango printing.
-+   *  @update 10/20/2006 behdad@behdad.org
-+   */
-+  void show(const PangoGlyphString *glyphs, float zoom,
-+            nsPSFontGenerator *aSubset, PRUint16 aSubFontIdx);
-+#endif
-   /** ---------------------------------------------------
-    *  set the clipping path to the current path using the winding rule
-    *  @update 2/1/99 dwc
-Index: gfx/src/ps/nsRenderingContextPS.cpp
-===================================================================
-RCS file: /cvsroot/mozilla/gfx/src/ps/nsRenderingContextPS.cpp,v
-retrieving revision 1.83
-diff -u -p -d -r1.83 nsRenderingContextPS.cpp
---- gfx/src/ps/nsRenderingContextPS.cpp        4 Mar 2005 07:39:27 -0000       1.83
-+++ gfx/src/ps/nsRenderingContextPS.cpp        23 Oct 2006 17:37:31 -0000
-@@ -251,6 +251,8 @@ nsRenderingContextPS :: GetDrawingSurfac
- NS_IMETHODIMP
- nsRenderingContextPS :: GetHints(PRUint32& aResult)
- {
-+  nsFontMetricsPS *metrics = NS_REINTERPRET_CAST(nsFontMetricsPS *, mFontMetrics.get());
-+  aResult = metrics->GetHints ();
-   return NS_OK;
- }
-@@ -1006,8 +1008,11 @@ nsRenderingContextPS::GetTextDimensions(
-                                         nsTextDimensions& aLastWordDimensions,
-                                         PRInt32*          aFontID)
- {
--  NS_NOTYETIMPLEMENTED("nsRenderingContextPS::GetTextDimensions");
--  return NS_ERROR_NOT_IMPLEMENTED;
-+  NS_ENSURE_TRUE(mFontMetrics, NS_ERROR_NULL_POINTER);
-+  nsFontMetricsPS *metrics = NS_REINTERPRET_CAST(nsFontMetricsPS *, mFontMetrics.get());
-+  NS_ENSURE_TRUE(metrics, NS_ERROR_FAILURE);
-+  return metrics->GetTextDimensions (aString, aLength, aAvailWidth, aBreaks, aNumBreaks,
-+                                   aDimensions, aNumCharsFit, aLastWordDimensions, aFontID);
- }
- NS_IMETHODIMP
-@@ -1021,43 +1026,31 @@ nsRenderingContextPS::GetTextDimensions(
-                                         nsTextDimensions& aLastWordDimensions,
-                                         PRInt32*          aFontID)
- {
--  NS_NOTYETIMPLEMENTED("nsRenderingContextPS::GetTextDimensions");
--  return NS_ERROR_NOT_IMPLEMENTED;
-+  NS_ENSURE_TRUE(mFontMetrics, NS_ERROR_NULL_POINTER);
-+  nsFontMetricsPS *metrics = NS_REINTERPRET_CAST(nsFontMetricsPS *, mFontMetrics.get());
-+  NS_ENSURE_TRUE(metrics, NS_ERROR_FAILURE);
-+  return metrics->GetTextDimensions (aString, aLength, aAvailWidth, aBreaks, aNumBreaks,
-+                                   aDimensions, aNumCharsFit, aLastWordDimensions, aFontID);
- }
- NS_IMETHODIMP
- nsRenderingContextPS :: GetTextDimensions(const char* aString, PRUint32 aLength,
-                                           nsTextDimensions& aDimensions)
- {
--  nsresult rv = NS_ERROR_FAILURE;
--
--  if (mFontMetrics) {
--    nsFontMetricsPS *metrics = NS_REINTERPRET_CAST(nsFontMetricsPS *, mFontMetrics.get());
--    metrics->GetStringWidth(aString, aDimensions.width, aLength);
--    metrics->GetMaxAscent(aDimensions.ascent);
--    metrics->GetMaxDescent(aDimensions.descent);
--    rv = NS_OK;
--  }
--  
--  return rv;
-+  NS_ENSURE_TRUE(mFontMetrics, NS_ERROR_NULL_POINTER);
-+  nsFontMetricsPS *metrics = NS_REINTERPRET_CAST(nsFontMetricsPS *, mFontMetrics.get());
-+  NS_ENSURE_TRUE(metrics, NS_ERROR_FAILURE);
-+  return metrics->GetTextDimensions (aString, aLength, aDimensions);
- }
- NS_IMETHODIMP
- nsRenderingContextPS :: GetTextDimensions(const PRUnichar* aString, PRUint32 aLength,
-                                           nsTextDimensions& aDimensions, PRInt32* aFontID)
- {
--  nsresult rv = NS_ERROR_FAILURE;
--
--  if (mFontMetrics) {
--    nsFontMetricsPS *metrics = NS_REINTERPRET_CAST(nsFontMetricsPS *, mFontMetrics.get());
--    metrics->GetStringWidth(aString, aDimensions.width, aLength);
--     //XXX temporary - bug 96609
--    metrics->GetMaxAscent(aDimensions.ascent);
--    metrics->GetMaxDescent(aDimensions.descent);
--    rv = NS_OK;
--  }
--
--  return rv;
-+  NS_ENSURE_TRUE(mFontMetrics, NS_ERROR_NULL_POINTER);
-+  nsFontMetricsPS *metrics = NS_REINTERPRET_CAST(nsFontMetricsPS *, mFontMetrics.get());
-+  NS_ENSURE_TRUE(metrics, NS_ERROR_FAILURE);
-+  return metrics->GetTextDimensions (aString, aLength, aDimensions, aFontID);
- }
- /** ---------------------------------------------------
-@@ -1073,47 +1066,7 @@ nsRenderingContextPS :: DrawString(const
-   nsFontMetricsPS *metrics = NS_REINTERPRET_CAST(nsFontMetricsPS *, mFontMetrics.get());
-   NS_ENSURE_TRUE(metrics, NS_ERROR_FAILURE);
--
--  // When FT2 printing is enabled, we don't need to set langgroup
--#if defined(MOZ_ENABLE_FREETYPE2) || defined(MOZ_ENABLE_XFT)
--  if (!NS_REINTERPRET_CAST(nsDeviceContextPS *, mContext.get())->mFTPEnable) {
--#endif
--    nsCOMPtr<nsIAtom> langGroup;
--    mFontMetrics->GetLangGroup(getter_AddRefs(langGroup));
--    mPSObj->setlanggroup(langGroup);
--#if defined(MOZ_ENABLE_FREETYPE2) || defined(MOZ_ENABLE_XFT)
--  }
--#endif
--
--  if (aLength == 0)
--    return NS_OK;
--  nsFontPS* fontPS = nsFontPS::FindFont(aString[0], metrics->Font(), metrics);
--  NS_ENSURE_TRUE(fontPS, NS_ERROR_FAILURE);
--  fontPS->SetupFont(this);
--
--  PRUint32 i, start = 0;
--  for (i=0; i<aLength; i++) {
--    nsFontPS* fontThisChar;
--    fontThisChar = nsFontPS::FindFont(aString[i], metrics->Font(), metrics);
--    NS_ENSURE_TRUE(fontThisChar, NS_ERROR_FAILURE);
--    if (fontThisChar != fontPS) {
--      // draw text up to this point
--      aX += DrawString(aString+start, i-start, aX, aY, fontPS, 
--                       aSpacing?aSpacing+start:nsnull);
--      start = i;
--
--      // setup for following text
--      fontPS = fontThisChar;
--      fontPS->SetupFont(this);
--    }
--  }
--
--  // draw the last part
--  if (aLength-start)
--    DrawString(aString+start, aLength-start, aX, aY, fontPS, 
--               aSpacing?aSpacing+start:nsnull);
--
--  return NS_OK;
-+  return metrics->DrawString (aString, aLength, aX, aY, aSpacing, this);
- }
- /** ---------------------------------------------------
-@@ -1129,110 +1082,7 @@ nsRenderingContextPS :: DrawString(const
-   
-   nsFontMetricsPS *metrics = NS_REINTERPRET_CAST(nsFontMetricsPS *, mFontMetrics.get());
-   NS_ENSURE_TRUE(metrics, NS_ERROR_FAILURE);
--
--#if defined(MOZ_ENABLE_FREETYPE2) || defined(MOZ_ENABLE_XFT)
--  // When FT2 printing is enabled, we don't need to set langgroup
--  if (!NS_REINTERPRET_CAST(nsDeviceContextPS *, mContext.get())->mFTPEnable) {
--#endif
--    nsCOMPtr<nsIAtom> langGroup = nsnull;
--    mFontMetrics->GetLangGroup(getter_AddRefs(langGroup));
--    mPSObj->setlanggroup(langGroup);
--#if defined(MOZ_ENABLE_FREETYPE2) || defined(MOZ_ENABLE_XFT)
--  }
--#endif
--
--  /* build up conversion table */
--  mPSObj->preshow(aString, aLength);
--
--  if (aLength == 0)
--    return NS_OK;
--  nsFontPS* fontPS = nsFontPS::FindFont(aString[0], metrics->Font(), metrics);
--  NS_ENSURE_TRUE(fontPS, NS_ERROR_FAILURE);
--  fontPS->SetupFont(this);
--
--  PRUint32 i, start = 0;
--  for (i=0; i<aLength; i++) {
--    nsFontPS* fontThisChar;
--    fontThisChar = nsFontPS::FindFont(aString[i], metrics->Font(), metrics);
--    NS_ENSURE_TRUE(fontThisChar, NS_ERROR_FAILURE);
--    if (fontThisChar != fontPS) {
--      // draw text up to this point
--      aX += DrawString(aString+start, i-start, aX, aY, fontPS, 
--                       aSpacing?aSpacing+start:nsnull);
--      start = i;
--
--      // setup for following text
--      fontPS = fontThisChar;
--      fontPS->SetupFont(this);
--    }
--  }
--
--  // draw the last part
--  if (aLength-start)
--    DrawString(aString+start, aLength-start, aX, aY, fontPS, 
--               aSpacing?aSpacing+start:nsnull);
--
--  return NS_OK;
--}
--
--PRInt32 
--nsRenderingContextPS::DrawString(const char *aString, PRUint32 aLength,
--                                 nscoord &aX, nscoord &aY, nsFontPS* aFontPS,
--                                 const nscoord* aSpacing)
--{
--  nscoord width = 0;
--  PRInt32 x = aX;
--  PRInt32 y = aY;
--
--  PRInt32 dxMem[500];
--  PRInt32* dx0 = 0;
--  if (aSpacing) {
--    dx0 = dxMem;
--    if (aLength > 500) {
--      dx0 = new PRInt32[aLength];
--      NS_ENSURE_TRUE(dx0, NS_ERROR_OUT_OF_MEMORY);
--    }
--    mTranMatrix->ScaleXCoords(aSpacing, aLength, dx0);
--  }
--
--  mTranMatrix->TransformCoord(&x, &y);
--  width = aFontPS->DrawString(this, x, y, aString, aLength);
--
--  if ((aSpacing) && (dx0 != dxMem)) {
--    delete [] dx0;
--  }
--
--  return width;
--}
--
--
--PRInt32 
--nsRenderingContextPS::DrawString(const PRUnichar *aString, PRUint32 aLength,
--                                 nscoord aX, nscoord aY, nsFontPS* aFontPS,
--                                 const nscoord* aSpacing)
--{
--  nscoord width = 0;
--  PRInt32 x = aX;
--  PRInt32 y = aY;
--
--  if (aSpacing) {
--    // Slow, but accurate rendering
--    const PRUnichar* end = aString + aLength;
--    while (aString < end){
--      x = aX;
--      y = aY;
--      mTranMatrix->TransformCoord(&x, &y);
--      aFontPS->DrawString(this, x, y, aString, 1);
--      aX += *aSpacing++;
--      aString++;
--    }
--    width = aX;
--  } else {
--    mTranMatrix->TransformCoord(&x, &y);
--    width = aFontPS->DrawString(this, x, y, aString, aLength);
--  }
--
--  return width;
-+  return metrics->DrawString (aString, aLength, aX, aY, aFontID, aSpacing, this);
- }
- /** ---------------------------------------------------
-@@ -1346,8 +1196,10 @@ nsRenderingContextPS::GetBoundingMetrics
-                                          PRUint32           aLength,
-                                          nsBoundingMetrics& aBoundingMetrics)
- {
--  // Fill me up 
--  return NS_ERROR_NOT_IMPLEMENTED;
-+  NS_ENSURE_TRUE(mFontMetrics, NS_ERROR_NULL_POINTER);
-+  nsFontMetricsPS *metrics = NS_REINTERPRET_CAST(nsFontMetricsPS *, mFontMetrics.get());
-+  NS_ENSURE_TRUE(metrics, NS_ERROR_FAILURE);
-+  return metrics->GetBoundingMetrics (aString, aLength, aBoundingMetrics);
- }
-   /**
-@@ -1359,8 +1211,10 @@ nsRenderingContextPS::GetBoundingMetrics
-                                          nsBoundingMetrics& aBoundingMetrics,
-                                          PRInt32*           aFontID)
- {
--  // Fill me up 
--  return NS_ERROR_NOT_IMPLEMENTED;
-+  NS_ENSURE_TRUE(mFontMetrics, NS_ERROR_NULL_POINTER);
-+  nsFontMetricsPS *metrics = NS_REINTERPRET_CAST(nsFontMetricsPS *, mFontMetrics.get());
-+  NS_ENSURE_TRUE(metrics, NS_ERROR_FAILURE);
-+  return metrics->GetBoundingMetrics (aString, aLength, aBoundingMetrics, aFontID);
- }
- #endif /* MOZ_MATHML */
-Index: gfx/src/ps/nsRenderingContextPS.h
-===================================================================
-RCS file: /cvsroot/mozilla/gfx/src/ps/nsRenderingContextPS.h,v
-retrieving revision 1.49
-diff -u -p -d -r1.49 nsRenderingContextPS.h
---- gfx/src/ps/nsRenderingContextPS.h  20 Sep 2004 06:46:16 -0000      1.49
-+++ gfx/src/ps/nsRenderingContextPS.h  23 Oct 2006 17:37:35 -0000
-@@ -154,6 +154,10 @@ public:
-   NS_IMETHOD GetWidth(const PRUnichar* aString, PRUint32 aLength,
-                       nscoord& aWidth, PRInt32 *aFontID);
-+  nsTransform2D *GetTranMatrix() {
-+    return mTranMatrix;
-+  }
-+
-   NS_IMETHOD DrawString(const char *aString, PRUint32 aLength,
-                         nscoord aX, nscoord aY,
-                         const nscoord* aSpacing);
-@@ -164,13 +168,6 @@ public:
-   NS_IMETHOD DrawString(const nsString& aString, nscoord aX, nscoord aY,
-                         PRInt32 aFontID,
-                         const nscoord* aSpacing);
--protected:
--  PRInt32 DrawString(const PRUnichar *aString, PRUint32 aLength,
--                        nscoord aX, nscoord aY, nsFontPS* aFontPS,
--                        const nscoord* aSpacing);
--  PRInt32 DrawString(const char *aString, PRUint32 aLength,
--                        nscoord &aX, nscoord &aY, nsFontPS* aFontPS,
--                        const nscoord* aSpacing);
- public:
-   NS_IMETHOD GetTextDimensions(const char* aString, PRUint32 aLength,
-Index: gfx/src/ps/nsType1.cpp
-===================================================================
-RCS file: /cvsroot/mozilla/gfx/src/ps/nsType1.cpp,v
-retrieving revision 1.5.8.1
-diff -u -p -d -r1.5.8.1 nsType1.cpp
---- gfx/src/ps/nsType1.cpp     19 Oct 2005 08:16:22 -0000      1.5.8.1
-+++ gfx/src/ps/nsType1.cpp     23 Oct 2006 17:37:39 -0000
-@@ -73,8 +73,13 @@
- #include "nsIFreeType2.h"
- #include "nsServiceManagerUtils.h"
- #endif
-+#if defined(MOZ_ENABLE_XFT) || defined(MOZ_ENABLE_PANGO)
-+#include FT_TYPE1_TABLES_H
-+#endif
- #include "nsPrintfCString.h"
- #include "nsAutoBuffer.h"
-+#include "nsValueArray.h"
-+#include "nsVoidArray.h"
- #define HEXASCII_LINE_LEN 64
-@@ -113,7 +118,7 @@ static void encryptAndHexOut(FILE *aFile
-                              const char *aBuf, PRInt32 aLen = -1);
- static void charStringOut(FILE* aFile, PRUint32* aPos, PRUint16* aKey,
-                           const char *aStr, PRUint32 aLen, 
--                          PRUnichar aId);
-+                          const char *aGlyphName);
- static void flattenName(nsCString& aString);
- /* thunk a short name for this function */
-@@ -202,19 +207,30 @@ Type1EncryptString(unsigned char *aInBuf
-     aOutBuf[i] = Type1Encrypt(aInBuf[i], &key);
- }
-+static FT_UShort
-+get_upm (FT_Face face)
-+{
-+  FT_UShort upm = face->units_per_EM;
-+
-+  if (!upm)
-+    upm = 1000; // bitmap font or something
-+
-+  return upm;
-+}
-+
- static PRBool
- sideWidthAndBearing(const FT_Vector *aEndPt, FT2PT1_info *aFti)
- {
-   int aw = 0;
-   int ah = 0;
--  FT_UShort upm = aFti->face->units_per_EM;
-+  FT_UShort upm = get_upm (aFti->face);
-   FT_GlyphSlot slot;
-   FT_Glyph glyph;
-   FT_BBox bbox;
-   slot = aFti->face->glyph;
--#ifdef MOZ_ENABLE_XFT
-+#if defined(MOZ_ENABLE_XFT) || defined(MOZ_ENABLE_PANGO)
-   FT_Error error = FT_Get_Glyph(slot, &glyph);
-   if (error) {
-     NS_ERROR("sideWidthAndBearing failed to get glyph");
-@@ -256,7 +272,7 @@ static int
- moveto(nsFT_CONST FT_Vector *aEndPt, void *aClosure)
- {
-   FT2PT1_info *fti = (FT2PT1_info *)aClosure;
--  FT_UShort upm = fti->face->units_per_EM;
-+  FT_UShort upm = get_upm (fti->face);
-   PRBool rslt;
-   if (fti->elm_cnt == 0) {
-@@ -293,7 +309,7 @@ static int
- lineto(nsFT_CONST FT_Vector *aEndPt, void *aClosure)
- {
-   FT2PT1_info *fti = (FT2PT1_info *)aClosure;
--  FT_UShort upm = fti->face->units_per_EM;
-+  FT_UShort upm = get_upm (fti->face);
-   if (toCS(upm, aEndPt->x) == fti->cur_x) {
-     fti->len += ecsi(&fti->buf, toCS(upm, aEndPt->y) - (int)fti->cur_y);
-@@ -320,7 +336,7 @@ conicto(nsFT_CONST FT_Vector *aControlPt
-         void *aClosure)
- {
-   FT2PT1_info *ftinfo = (FT2PT1_info *)aClosure;
--  FT_UShort upm = ftinfo->face->units_per_EM;
-+  FT_UShort upm = get_upm (ftinfo->face);
-   double ctl_x, ctl_y;
-   double cur_x, cur_y, x3, y3;
-   FT_Vector aControlPt1, aControlPt2;
-@@ -353,7 +369,7 @@ cubicto(nsFT_CONST FT_Vector *aControlPt
-         nsFT_CONST FT_Vector *aEndPt, void *aClosure)
- {
-   FT2PT1_info *ftinfo = (FT2PT1_info *)aClosure;
--  FT_UShort upm = ftinfo->face->units_per_EM;
-+  FT_UShort upm = get_upm (ftinfo->face);
-   double cur_x, cur_y, x1, y1, x2, y2, x3, y3;
-   cur_x = ftinfo->cur_x;
-@@ -408,8 +424,55 @@ static FT_Outline_Funcs ft_outline_funcs
-   0
- };
-+
-+static int
-+trace_bitmap_glyph (FT_GlyphSlot slot, FT2PT1_info *fti)
-+{
-+  unsigned char *row, *byte_ptr, byte;
-+  int rows, cols;
-+  int x, y, bit_mask;
-+  int upm, x_off, y_off, x_mult, y_mult;
-+
-+  upm = get_upm (slot->face);
-+  x_off = slot->bitmap_left;
-+  y_off = slot->bitmap_top;
-+  x_mult = upm / slot->face->size->metrics.x_ppem;
-+  y_mult = upm / slot->face->size->metrics.y_ppem;
-+
-+  switch (slot->bitmap.pixel_mode) {
-+  case FT_PIXEL_MODE_MONO:
-+
-+    for (y = 0, row = slot->bitmap.buffer, rows = slot->bitmap.rows; rows; row += slot->bitmap.pitch, rows--, y++) {
-+      for (x = 0, byte_ptr = row, cols = (slot->bitmap.width + 7) / 8; cols; byte_ptr++, cols--) {
-+          byte = *byte_ptr;
-+          for (bit_mask = 128; bit_mask && x < slot->bitmap.width; bit_mask >>= 1, x++) {
-+              if (byte & bit_mask) {
-+                  FT_Vector p;
-+                  p.x = x_mult * (x_off + x);
-+                  p.y = y_mult * (y_off - y);
-+                  moveto(&p, (void *) fti);
-+                  p.x += x_mult;
-+                  lineto(&p, (void *) fti);
-+                  p.y += y_mult;
-+                  lineto(&p, (void *) fti);
-+                  p.x -= x_mult;
-+                  lineto(&p, (void *) fti);
-+              }
-+          }
-+      }
-+    }
-+    break;
-+
-+  default:
-+    return 1;
-+  }
-+
-+  return 0;
-+}
-+
-+
- FT_Error
--#ifdef MOZ_ENABLE_XFT
-+#if defined(MOZ_ENABLE_XFT) || defined(MOZ_ENABLE_PANGO)
- FT2GlyphToType1CharString(FT_Face aFace, PRUint32 aGlyphID,
-                           int aWmode, int aLenIV, unsigned char *aBuf)
- #else
-@@ -423,7 +486,7 @@ FT2GlyphToType1CharString(nsIFreeType2 *
-   unsigned char *start = aBuf;
-   FT2PT1_info fti;
--#ifdef MOZ_ENABLE_XFT
-+#if defined(MOZ_ENABLE_XFT) || defined(MOZ_ENABLE_PANGO)
-   FT_Error error = FT_Load_Glyph(aFace, aGlyphID, flags);
-   if (error) {
-     NS_ERROR("failed to load aGlyphID");
-@@ -438,11 +501,6 @@ FT2GlyphToType1CharString(nsIFreeType2 *
- #endif
-   slot = aFace->glyph;
--  if (slot->format != ft_glyph_format_outline) {
--    NS_ERROR("aGlyphID is not an outline glyph");
--    return 1;
--  }
--
- #ifdef MOZ_ENABLE_FREETYPE2
-   fti.ft2     = aFt2;
- #endif
-@@ -456,18 +514,27 @@ FT2GlyphToType1CharString(nsIFreeType2 *
-   for (j=0; j< aLenIV; j++) {
-     fti.len += ecsi(&fti.buf, 0);
-   }
--#ifdef MOZ_ENABLE_XFT
--  if (FT_Outline_Decompose(&slot->outline, &ft_outline_funcs, &fti))  {
--    NS_ERROR("error decomposing aGlyphID");
--    return 1;
--  }
-+
-+  if (slot->format == ft_glyph_format_outline) {
-+#if defined(MOZ_ENABLE_XFT) || defined(MOZ_ENABLE_PANGO)
-+    if (FT_Outline_Decompose(&slot->outline, &ft_outline_funcs, &fti))  {
-+      NS_ERROR("error decomposing aGlyphID");
-+      return 1;
-+    }
- #else
--  rv = aFt2->OutlineDecompose(&slot->outline, &ft_outline_funcs, &fti);
--  if (NS_FAILED(rv)) {
--    NS_ERROR("error decomposing aGlyphID");
--    return 1;
--  }
-+    rv = aFt2->OutlineDecompose(&slot->outline, &ft_outline_funcs, &fti);
-+    if (NS_FAILED(rv)) {
-+      NS_ERROR("error decomposing aGlyphID");
-+    }
- #endif
-+  } else if (slot->format == ft_glyph_format_bitmap) {
-+    /* ok, it's a bitmap glyph.  trace it! */
-+    if (trace_bitmap_glyph (slot, &fti)) {
-+      NS_ERROR("error tracing bitmap glyph");
-+    }
-+  } else {
-+      NS_ERROR("aGlyphID has unhandled format");
-+  }
-   if (fti.elm_cnt) {
-     fti.len += csc(&fti.buf, T1_CLOSEPATH);
-@@ -491,28 +558,52 @@ FT2GlyphToType1CharString(nsIFreeType2 *
- }
- static PRBool
--#ifdef MOZ_ENABLE_XFT
-+#if defined(MOZ_ENABLE_XFT) || defined(MOZ_ENABLE_PANGO)
- outputType1SubFont(FT_Face aFace,
- #else
- outputType1SubFont(nsIFreeType2 *aFt2, FT_Face aFace,
- #endif
--                 const nsAString &aCharIDs, const char *aFontName,
--                 int aWmode, int aLenIV, FILE *aFile);
-+                   nsValueArray *aGlyphs,
-+                   PRUint32 aOffset, PRUint32 aLen,
-+                   const char *aFontName,
-+                   int aWmode, int aLenIV, FILE *aFile);
- nsresult
- FT2ToType1FontName(FT_Face aFace, int aWmode, nsCString& aFontName)
- {
-+  // only hash the first 10 000 bytes of the font
-+  int size = aFace->stream->size;
-+  size = size > 10000 ? 10000 : size;
-+
-+  unsigned char *data;
-+  if (aFace->stream->read) {
-+    data = (unsigned char *) malloc (size);
-+    aFace->stream->read (aFace->stream, 0, data, size);
-+  } else {
-+    data = aFace->stream->base;
-+  }
-+
-+  unsigned int data_hash = 0;
-+  int i;
-+  for (i = 0; i < size; i++)
-+    data_hash = (data_hash << 5) - data_hash + data[size];
-+
-+  if (aFace->stream->read)
-+    free (data);
-+
-   aFontName = aFace->family_name;
-   aFontName.AppendLiteral(".");
-   aFontName += aFace->style_name;
--  aFontName += nsPrintfCString(".%ld.%d", aFace->face_index, aWmode ? 1 : 0);
-+  aFontName += nsPrintfCString(".%ld.%d.%lx.%x", aFace->face_index, aWmode ? 1 : 0,
-+                               (long) aFace->stream->size, data_hash);
-   flattenName(aFontName);
-+
-   return NS_OK;
- }
- // output a subsetted truetype font converted to multiple type 1 fonts
- PRBool
--FT2SubsetToType1FontSet(FT_Face aFace, const nsString& aSubset,
-+FT2SubsetToType1FontSet(FT_Face aFace, nsValueArray *aGlyphSubset,
-                         int aWmode,  FILE *aFile)
- {
- #ifdef MOZ_ENABLE_FREETYPE2
-@@ -527,32 +618,35 @@ FT2SubsetToType1FontSet(FT_Face aFace, c
-   nsCAutoString fontNameBase;
-   FT2ToType1FontName(aFace, aWmode, fontNameBase);
-   PRUint32 i = 0;
--  for (; i <= aSubset.Length() / 255 ; i++) {
-+  for (; i <= aGlyphSubset->Count() / 255 ; i++) {
-     nsCAutoString fontName(fontNameBase);
-     fontName.AppendLiteral(".Set");
-     fontName.AppendInt(i);
--#ifdef MOZ_ENABLE_XFT
-+#if defined(MOZ_ENABLE_XFT) || defined(MOZ_ENABLE_PANGO)
-     outputType1SubFont(aFace,
- #else
-     outputType1SubFont(ft2, aFace, 
- #endif
--      Substring(aSubset, i * 255, PR_MIN(255, aSubset.Length() - i * 255)),
--      fontName.get(), aWmode, 4, aFile);
-+                       aGlyphSubset,
-+                       (i * 255), PR_MIN(255, aGlyphSubset->Count() - i * 255),
-+                       fontName.get(), aWmode, 4, aFile);
-   }
-   return PR_TRUE;
- }
- // output a type 1 font (with 255 characters or fewer) 
- static PRBool
--#ifdef MOZ_ENABLE_XFT
-+#if defined(MOZ_ENABLE_XFT) || defined(MOZ_ENABLE_PANGO)
- outputType1SubFont(FT_Face aFace,
- #else
- outputType1SubFont(nsIFreeType2 *aFt2, FT_Face aFace,
- #endif
--                 const nsAString& aCharIDs, const char *aFontName,
--                 int aWmode, int aLenIV, FILE *aFile)
-+                   nsValueArray *aGlyphs,
-+                   PRUint32 aOffset, PRUint32 aLen,
-+                   const char *aFontName,
-+                   int aWmode, int aLenIV, FILE *aFile)
- {
--  FT_UShort upm = aFace->units_per_EM;
-+  FT_UShort upm = get_upm (aFace);
-   fprintf(aFile, "%%%%BeginResource: font %s\n"
-                  "%%!PS-AdobeFont-1.0-3.0 %s 1.0\n"
-@@ -573,9 +667,13 @@ outputType1SubFont(nsIFreeType2 *aFt2, F
-                  toCS(upm, aFace->bbox.xMax),
-                  toCS(upm, aFace->bbox.yMax));
--  nsString charIDstr(aCharIDs);
--  PRUint32 len = aCharIDs.Length();
--  
-+  nsValueArray glyphs(PR_UINT16_MAX);
-+  nsCStringArray glyphnames(PR_UINT16_MAX);
-+  glyphs = *aGlyphs;
-+
-+  PRUint32 len = aLen;
-+  PRUint32 i;
-+
-   if (len < 10) { 
-     // Add a small set of characters to the subset of the user
-     // defined font to produce to make sure the font ends up
-@@ -584,25 +682,47 @@ outputType1SubFont(nsIFreeType2 *aFt2, F
-     // XXX : need to check if this is true of type 1 fonts as well.
-     // I suspect it's only the case of CID-keyed fonts (type 9) we used to
-     // generate. 
--    charIDstr.AppendLiteral("1234567890"); 
-+    for (i = 1; i <= 10; i++) {
-+      glyphs.AppendValue(i);
-+    }
-     len += 10;
-   }
-   
--  const PRUnichar *charIDs = charIDstr.get();
--
--  PRUint32 i;
-+  FT_Int has_glyph_name;
-+#if defined (MOZ_ENABLE_XFT) || defined (MOZ_ENABLE_PANGO)
-+  has_glyph_name = FT_Has_PS_Glyph_Names(aFace);
-+#else
-+  has_glyph_name = aFt2->hasPSGlyphNames(aFace);
-+#endif
-   // construct an Encoding vector : the 0th element
-   // is /.notdef
--  fputs("/Encoding [\n/.notdef\n", aFile); 
--  for (i = 0; i < len; ++i) {
--      fprintf(aFile, "/uni%04X", charIDs[i]); 
--      if (i % 8 == 7) fputc('\n', aFile);
-+  fputs("/Encoding [\n/.notdef", aFile); 
-+  for (i = aOffset; i < aOffset + aLen; ++i) {
-+      nsCString name;
-+      char buffer[256];
-+
-+      if (glyphs.ValueAt(i) == 0) {
-+        name = "/.notdef";
-+      } else if (!has_glyph_name ||
-+#if defined (MOZ_ENABLE_XFT) || defined (MOZ_ENABLE_PANGO)
-+                 FT_Get_Glyph_Name(aFace, glyphs.ValueAt(i), buffer, 255) != FT_Err_Ok
-+#else
-+                 NS_FAILED(aFt2->getGlyphName(aFace, glyphs.ValueAt(i), buffer, 255))
-+#endif
-+      ) {
-+        name = nsPrintfCString(256, "/idx%04X", glyphs.ValueAt(i));
-+      } else {
-+        name = nsPrintfCString(256, "/%s", buffer);
-+      }
-+      glyphnames.AppendCString(name);
-+      fprintf(aFile, name.get());
-+      if ((i-aOffset) % 8 == 6) fputc('\n', aFile);
-   }
--  for (i = len; i < 255; ++i) {
-+  for (i = PR_MAX (0, 255 - int(aLen)); i; --i) {
-       fputs("/.notdef", aFile);
--      if (i % 8 == 7) fputc('\n', aFile);
-+      if (i % 8 == 1) fputc('\n', aFile);
-   }
-   fputs("] def\n", aFile); 
-@@ -630,23 +750,21 @@ outputType1SubFont(nsIFreeType2 *aFt2, F
-   // get the maximum charstring length without actually filling up the buffer
-   PRInt32 charStringLen;
-   PRInt32 maxCharStringLen =
--#ifdef MOZ_ENABLE_XFT
-+#if defined(MOZ_ENABLE_XFT) || defined(MOZ_ENABLE_PANGO)
-     FT2GlyphToType1CharString(aFace, 0, aWmode, aLenIV, nsnull);
- #else
-     FT2GlyphToType1CharString(aFt2, aFace, 0, aWmode, aLenIV, nsnull);
- #endif
--  PRUint32 glyphID;
--
--  for (i = 0; i < len; i++) {
--#ifdef MOZ_ENABLE_XFT
--    glyphID = FT_Get_Char_Index(aFace, charIDs[i]);
-+  for (i = aOffset; i < aOffset + aLen; i++) {
-+#if defined(MOZ_ENABLE_XFT) || defined(MOZ_ENABLE_PANGO)
-     charStringLen =
--      FT2GlyphToType1CharString(aFace, glyphID, aWmode, aLenIV, nsnull);
-+      FT2GlyphToType1CharString(aFace, glyphs.ValueAt(i), aWmode, aLenIV,
-+                                nsnull);
- #else
--    aFt2->GetCharIndex(aFace, charIDs[i], &glyphID);
-     charStringLen =
--      FT2GlyphToType1CharString(aFt2, aFace, glyphID, aWmode, aLenIV, nsnull);
-+      FT2GlyphToType1CharString(aFt2, aFace, glyphs.ValueAt(i), aWmode, aLenIV,
-+                                nsnull);
- #endif
-     if (charStringLen > maxCharStringLen)
-@@ -666,7 +784,7 @@ outputType1SubFont(nsIFreeType2 *aFt2, F
-                                    len + 1).get()); 
-   // output the notdef glyph
--#ifdef MOZ_ENABLE_XFT
-+#if defined(MOZ_ENABLE_XFT) || defined(MOZ_ENABLE_PANGO)
-   charStringLen = FT2GlyphToType1CharString(aFace, 0, aWmode, aLenIV,
-                                             charString.get());
- #else
-@@ -676,22 +794,20 @@ outputType1SubFont(nsIFreeType2 *aFt2, F
-   // enclose charString with  "/.notdef RD .....  ND" 
-   charStringOut(aFile, &pos, &key, NS_REINTERPRET_CAST(const char*, charString.get()),
--                charStringLen, 0); 
-+                charStringLen, "/.notdef");
-   // output the charstrings for each glyph in this sub font
--  for (i = 0; i < len; i++) {
--#ifdef MOZ_ENABLE_XFT
--    glyphID = FT_Get_Char_Index(aFace, charIDs[i]);
--    charStringLen = FT2GlyphToType1CharString(aFace, glyphID, aWmode,
-+  for (i = aOffset; i < aOffset + aLen; i++) {
-+#if defined(MOZ_ENABLE_XFT) || defined(MOZ_ENABLE_PANGO)
-+    charStringLen = FT2GlyphToType1CharString(aFace, glyphs.ValueAt(i), aWmode,
-                                               aLenIV, charString.get());
- #else
--    aFt2->GetCharIndex(aFace, charIDs[i], &glyphID);
--    charStringLen = FT2GlyphToType1CharString(aFt2, aFace, glyphID, aWmode,
--                                              aLenIV, charString.get());
-+    charStringLen = FT2GlyphToType1CharString(aFt2, aFace, glyphs.ValueAt(i),
-+                                              aWmode, aLenIV, charString.get());
- #endif
-     charStringOut(aFile, &pos, &key, NS_REINTERPRET_CAST(const char*, charString.get()),
--                  charStringLen, charIDs[i]);
-+                  charStringLen, glyphnames.CStringAt(i - aOffset)->get());
-   }
-   // wrap up the encrypted part of the font definition
-@@ -753,15 +869,12 @@ void encryptAndHexOut(FILE *aFile, PRUin
- /* static */ 
- void charStringOut(FILE* aFile,  PRUint32* aPos, PRUint16* aKey, 
--                   const char *aStr, PRUint32 aLen, PRUnichar aId)
-+                   const char *aStr, PRUint32 aLen, const char *aGlyphName)
- {
-     // use a local buffer instead of nsPrintfCString to avoid alloc.
-     char buf[30];
-     int oLen;
--    if (aId == 0)
--      oLen = PR_snprintf(buf, 30, "/.notdef %d RD ", aLen); 
--    else 
--      oLen = PR_snprintf(buf, 30, "/uni%04X %d RD ", aId, aLen); 
-+    oLen = PR_snprintf(buf, 30, "%s %d RD ", aGlyphName, aLen);
-     if (oLen >= 30) {
-       NS_WARNING("buffer size exceeded. charstring will be truncated");
-Index: gfx/src/ps/nsType1.h
-===================================================================
-RCS file: /cvsroot/mozilla/gfx/src/ps/nsType1.h,v
-retrieving revision 1.5
-diff -u -p -d -r1.5 nsType1.h
---- gfx/src/ps/nsType1.h       4 Mar 2005 07:39:27 -0000       1.5
-+++ gfx/src/ps/nsType1.h       23 Oct 2006 17:37:39 -0000
-@@ -122,8 +122,9 @@ FT_Error FT2GlyphToType1CharString(nsIFr
- class nsString;
- class nsCString;
-+class nsValueArray;
--PRBool FT2SubsetToType1FontSet(FT_Face aFace, const nsString& aSubset,
-+PRBool FT2SubsetToType1FontSet(FT_Face aFace, nsValueArray *aGlyphSubset,
-                                int aWmode,  FILE *aFile);
- nsresult FT2ToType1FontName(FT_Face aFace, int aWmode,
-                             nsCString& aFontName);
-Index: config/system-headers
-===================================================================
---- config/system-headers      2006-10-26 12:21:39.000000000 -0400
-+++ config/system-headers      2006-10-26 12:23:29.000000000 -0400
-@@ -199,6 +199,7 @@
- freetype/ftoutln.h
- freetype/ttnameid.h
- freetype/tttables.h
-+freetype/t1tables.h
- fribidi/fribidi.h
- FSp_fopen.h
- fstream.h
-@@ -501,6 +503,7 @@
- pango/pangofc-fontmap.h
- pango/pango-fontmap.h
- pango/pango.h
-+pango/pangoft2.h
- pango/pangoxft.h
- pango/pangox.h
- pango-types.h
-
diff --git a/mozilla-firefox-pango-underline.patch b/mozilla-firefox-pango-underline.patch
deleted file mode 100644 (file)
index c6b8649..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-diff -pruN -x '.moz*' -x .deps -x 'thunderbird*' -x '*.mk' -x 'config*' -x dist -x build -x toolkit -x '*o' -x '*a' -x '*html' mozilla.orig/layout/generic/nsTextFrame.cpp mozilla/layout/generic/nsTextFrame.cpp
---- mozilla.orig/layout/generic/nsTextFrame.cpp        2006-12-20 12:53:26.000000000 +0900
-+++ mozilla/layout/generic/nsTextFrame.cpp     2006-12-20 15:43:14.000000000 +0900
-@@ -2097,11 +2097,11 @@ nsTextFrame::PaintTextDecorations(nsIRen
-     nsRect rect = GetRect();
-     while(aDetails){
-       const nscoord* sp= aSpacing;
--      PRInt32 startOffset = 0;
--      PRInt32 textWidth = 0;
--      PRInt32 start = PR_MAX(0,(aDetails->mStart - (PRInt32)aIndex));
--      PRInt32 end = PR_MIN((PRInt32)aLength,(aDetails->mEnd - (PRInt32)aIndex));
--      PRInt32 i;
-+      PRUint32 startOffset = 0;
-+      PRUint32 textWidth = 0;
-+      PRInt32 start = PR_MAX(0,(aDetails->mStart - (PRInt32)aIndex));
-+      PRInt32 end = PR_MIN((PRInt32)aLength,(aDetails->mEnd - (PRInt32)aIndex));
-+      PRInt32 i;
-       if ((start < end) && ((aLength - start) > 0))
-       {
-         //aDetails allready processed to have offsets from frame start not content offsets
-@@ -2117,7 +2117,7 @@ nsTextFrame::PaintTextDecorations(nsIRen
-                 }
-               }
-               else
--                aRenderingContext.GetWidth(aText, start, startOffset);
-+                aRenderingContext.GetRangeWidth(aText, aLength, 0, start, startOffset);
-             }
-             if (sp){
-               for (i = start; i < end;i ++){
-@@ -2125,8 +2125,7 @@ nsTextFrame::PaintTextDecorations(nsIRen
-               }
-             }
-             else
--              aRenderingContext.GetWidth(aText + start,
--                                           PRUint32(end - start), textWidth);
-+              aRenderingContext.GetRangeWidth(aText, aLength, start, end, textWidth);
-   
-           }
-           nscoord offset, size;
diff --git a/mozilla-firefox-xft-randewidth.patch b/mozilla-firefox-xft-randewidth.patch
deleted file mode 100644 (file)
index 1ecc5f2..0000000
+++ /dev/null
@@ -1,283 +0,0 @@
-diff -pruN -x '.moz*' -x .libs -x .deps -x dist -x 'config*' -x 'firefox*' -x '*a' -x '*so' -x '*o' -x build -x '*html' mozilla.orig/gfx/src/gtk/nsFontMetricsXft.cpp mozilla/gfx/src/gtk/nsFontMetricsXft.cpp
---- mozilla.orig/gfx/src/gtk/nsFontMetricsXft.cpp      2006-04-25 08:58:36.000000000 +0900
-+++ mozilla/gfx/src/gtk/nsFontMetricsXft.cpp   2007-02-08 01:50:05.000000000 +0900
-@@ -227,10 +227,14 @@ static nsresult EnumFontsXft     (nsIAto
- static        void ConvertCharToUCS4    (const char *aString,
-                                          PRUint32 aLength,
-+                                         PRUint32 aStart,
-+                                         PRUint32 aEnd,
-                                          nsAutoFcChar32Buffer &aOutBuffer,
-                                          PRUint32 *aOutLen);
- static        void ConvertUnicharToUCS4 (const PRUnichar *aString,
-                                          PRUint32 aLength,
-+                                         PRUint32 aStart,
-+                                         PRUint32 aEnd,
-                                          nsAutoFcChar32Buffer &aOutBuffer,
-                                          PRUint32 *aOutLen);
- static    nsresult ConvertUCS4ToCustom  (FcChar32 *aSrc, PRUint32 aSrcLen,
-@@ -507,7 +511,7 @@ nsFontMetricsXft::GetWidth(const PRUnich
-         return NS_OK;
-     }
--    gint rawWidth = RawGetWidth(aString, aLength);
-+    gint rawWidth = RawGetWidth(aString, aLength, 0, aLength);
-     float f;
-     f = mDeviceContext->DevUnitsToAppUnits();
-@@ -533,7 +537,7 @@ nsFontMetricsXft::GetTextDimensions(cons
-         return NS_OK;
-     nsresult rv;
--    rv = EnumerateGlyphs(aString, aLength,
-+    rv = EnumerateGlyphs(aString, aLength, 0, aLength,
-                          &nsFontMetricsXft::TextDimensionsCallback,
-                          &aDimensions);
-@@ -608,7 +612,7 @@ nsFontMetricsXft::DrawString(const char 
-     nsAutoDrawSpecBuffer drawBuffer(data.draw, &data.color);
-     data.drawBuffer = &drawBuffer;
--    return EnumerateGlyphs(aString, aLength,
-+    return EnumerateGlyphs(aString, aLength, 0, aLength,
-                            &nsFontMetricsXft::DrawStringCallback, &data);
- }
-@@ -638,7 +642,7 @@ nsFontMetricsXft::DrawString(const PRUni
-     nsAutoDrawSpecBuffer drawBuffer(data.draw, &data.color);
-     data.drawBuffer = &drawBuffer;
--    return EnumerateGlyphs(aString, aLength,
-+    return EnumerateGlyphs(aString, aLength, 0, aLength,
-                            &nsFontMetricsXft::DrawStringCallback, &data);
- }
-@@ -662,7 +666,7 @@ nsFontMetricsXft::GetBoundingMetrics(con
-     data.firstTime = PR_TRUE; 
-     nsresult rv;
--    rv = EnumerateGlyphs(aString, aLength,
-+    rv = EnumerateGlyphs(aString, aLength, 0, aLength,
-                          &nsFontMetricsXft::BoundingMetricsCallback, &data);
-     NS_ENSURE_SUCCESS(rv, rv);
-@@ -700,7 +704,7 @@ nsFontMetricsXft::GetBoundingMetrics(con
-     data.firstTime = PR_TRUE; 
-     nsresult rv;
--    rv = EnumerateGlyphs(aString, aLength,
-+    rv = EnumerateGlyphs(aString, aLength, 0, aLength,
-                          &nsFontMetricsXft::BoundingMetricsCallback, &data);
-     NS_ENSURE_SUCCESS(rv, rv);
-@@ -758,7 +762,17 @@ nsFontMetricsXft::GetRangeWidth(const PR
-                                 PRUint32 aEnd,
-                                 PRUint32 &aWidth)
- {
--    return NS_ERROR_NOT_IMPLEMENTED;
-+    if (!aLength) {
-+        aWidth = 0;
-+        return NS_OK;
-+    }
-+
-+    gint rawWidth = RawGetWidth(aText, aLength, aStart, aEnd);
-+    float f = mDeviceContext->DevUnitsToAppUnits();
-+
-+    aWidth = NSToCoordRound(rawWidth * f);
-+
-+    return NS_OK;
- }
- nsresult
-@@ -768,7 +782,17 @@ nsFontMetricsXft::GetRangeWidth(const ch
-                                 PRUint32 aEnd,
-                                 PRUint32 &aWidth)
- {
--    return NS_ERROR_NOT_IMPLEMENTED;
-+    if (!aLength) {
-+        aWidth = 0;
-+        return NS_OK;
-+    }
-+
-+    gint rawWidth = RawGetWidth(aText, aLength, aStart, aEnd);
-+    float f = mDeviceContext->DevUnitsToAppUnits();
-+
-+    aWidth = NSToCoordRound(rawWidth * f);
-+
-+    return NS_OK;
- }
- PRUint32
-@@ -850,12 +874,12 @@ nsFontMetricsXft::CacheFontMetrics(void)
-     // mSpaceWidth (width of a space)
-     gint rawWidth;
-     PRUnichar unispace(' ');
--    rawWidth = RawGetWidth(&unispace, 1);
-+    rawWidth = RawGetWidth(&unispace, 1, 0, 1);
-     mSpaceWidth = NSToCoordRound(rawWidth * f);
-     // mAveCharWidth (width of an 'average' char)
-     PRUnichar xUnichar('x');
--    rawWidth = RawGetWidth(&xUnichar, 1);
-+    rawWidth = RawGetWidth(&xUnichar, 1, 0, 1);
-     mAveCharWidth = NSToCoordRound(rawWidth * f);
-     // mXHeight (height of an 'x' character)
-@@ -1226,12 +1250,27 @@ nsFontMetricsXft::DoMatch(PRBool aMatchA
- }
- gint
--nsFontMetricsXft::RawGetWidth(const PRUnichar* aString, PRUint32 aLength)
-+nsFontMetricsXft::RawGetWidth(const PRUnichar* aString, PRUint32 aLength, PRUint32 aStart, PRUint32 aEnd)
-+{
-+    nscoord width = 0;
-+    nsresult rv;
-+
-+    rv = EnumerateGlyphs(aString, aLength, aStart, aEnd,
-+                         &nsFontMetricsXft::GetWidthCallback, &width);
-+
-+    if (NS_FAILED(rv))
-+        width = 0;
-+
-+    return width;
-+}
-+
-+gint
-+nsFontMetricsXft::RawGetWidth(const char* aString, PRUint32 aLength, PRUint32 aStart, PRUint32 aEnd)
- {
-     nscoord width = 0;
-     nsresult rv;
--    rv = EnumerateGlyphs(aString, aLength,
-+    rv = EnumerateGlyphs(aString, aLength, aStart, aEnd,
-                          &nsFontMetricsXft::GetWidthCallback, &width);
-     if (NS_FAILED(rv))
-@@ -1457,6 +1496,8 @@ nsFontMetricsXft::EnumerateXftGlyphs(con
- nsresult
- nsFontMetricsXft::EnumerateGlyphs(const PRUnichar *aString,
-                                   PRUint32 aLen,
-+                                  PRUint32 aStart,
-+                                  PRUint32 aEnd,
-                                   GlyphEnumeratorCallback aCallback,
-                                   void *aCallbackData)
- {
-@@ -1465,7 +1506,7 @@ nsFontMetricsXft::EnumerateGlyphs(const 
-     NS_ENSURE_TRUE(aLen, NS_OK); 
--    ConvertUnicharToUCS4(aString, aLen, charBuffer, &len);
-+    ConvertUnicharToUCS4(aString, aLen, aStart, aEnd, charBuffer, &len);
-     if (!len)
-         return NS_ERROR_OUT_OF_MEMORY;
-@@ -1475,6 +1516,8 @@ nsFontMetricsXft::EnumerateGlyphs(const 
- nsresult
- nsFontMetricsXft::EnumerateGlyphs(const char *aString,
-                                   PRUint32 aLen,
-+                                  PRUint32 aStart,
-+                                  PRUint32 aEnd,
-                                   GlyphEnumeratorCallback aCallback,
-                                   void *aCallbackData)
- {
-@@ -1484,7 +1527,7 @@ nsFontMetricsXft::EnumerateGlyphs(const 
-     NS_ENSURE_TRUE(aLen, NS_OK); 
-     // Convert the incoming string into an array of UCS4 chars
--    ConvertCharToUCS4(aString, aLen, charBuffer, &len);
-+    ConvertCharToUCS4(aString, aLen, aStart, aEnd, charBuffer, &len);
-     if (!len)
-         return NS_ERROR_OUT_OF_MEMORY;
-@@ -2343,7 +2386,7 @@ EnumFontsXft(nsIAtom* aLangGroup, const 
- /* static */
- void
--ConvertCharToUCS4(const char *aString, PRUint32 aLength, 
-+ConvertCharToUCS4(const char *aString, PRUint32 aLength, PRUint32 aStart, PRUint32 aEnd,
-                   nsAutoFcChar32Buffer &aOutBuffer, PRUint32 *aOutLen)
- {
-     *aOutLen = 0;
-@@ -2352,19 +2395,21 @@ ConvertCharToUCS4(const char *aString, P
-     if (!aOutBuffer.EnsureElemCapacity(aLength))
-         return;
-     outBuffer  = aOutBuffer.get();
-+    if (aEnd > aLength)
-+        aEnd = aLength;
-     
--    for (PRUint32 i = 0; i < aLength; ++i) {
--        outBuffer[i] = PRUint8(aString[i]); // to convert char >= 0x80 correctly
-+    for (PRUint32 i = aStart; i < aLength && i < aEnd; ++i) {
-+        outBuffer[i - aStart] = PRUint8(aString[i]); // to convert char >= 0x80 correctly
-     }
--    *aOutLen = aLength;
-+    *aOutLen = aEnd - aStart;
- }
- // Convert the incoming string into an array of UCS4 chars
-   
- /* static */
- void
--ConvertUnicharToUCS4(const PRUnichar *aString, PRUint32 aLength,
-+ConvertUnicharToUCS4(const PRUnichar *aString, PRUint32 aLength, PRUint32 aStart, PRUint32 aEnd,
-                      nsAutoFcChar32Buffer &aOutBuffer, PRUint32 *aOutLen)
- {
-     *aOutLen = 0;
-@@ -2378,7 +2423,7 @@ ConvertUnicharToUCS4(const PRUnichar *aS
-     // Walk the passed in string looking for surrogates to convert to
-     // their full ucs4 representation.
--    for (PRUint32 i = 0; i < aLength; ++i) {
-+    for (PRUint32 i = aStart; i < aLength && i < aEnd; ++i) {
-         PRUnichar c = aString[i];
-         // Optimized for the non-surrogate case
-@@ -2693,12 +2738,12 @@ ConvertUCS4ToCustom(FcChar32 *aSrc,  PRU
- #endif
-         // Convert 16bit  custom font codes to UCS4
-         ConvertUnicharToUCS4(NS_REINTERPRET_CAST(PRUnichar *, med),
--                             medLen >> 1, aResult, &aDestLen);
-+                             medLen >> 1, 0, medLen >> 1, aResult, &aDestLen);
-         rv = aDestLen ? rv : NS_ERROR_OUT_OF_MEMORY;
-     }
-     else {
-         // Convert 8bit custom font codes to UCS4
--        ConvertCharToUCS4(med, medLen, aResult, &aDestLen);
-+        ConvertCharToUCS4(med, medLen, 0, medLen, aResult, &aDestLen);
-         rv = aDestLen ? rv : NS_ERROR_OUT_OF_MEMORY;
-     }
-diff -pruN -x '.moz*' -x .libs -x .deps -x dist -x 'config*' -x 'firefox*' -x '*a' -x '*so' -x '*o' -x build -x '*html' mozilla.orig/gfx/src/gtk/nsFontMetricsXft.h mozilla/gfx/src/gtk/nsFontMetricsXft.h
---- mozilla.orig/gfx/src/gtk/nsFontMetricsXft.h        2005-05-03 05:48:30.000000000 +0900
-+++ mozilla/gfx/src/gtk/nsFontMetricsXft.h     2007-02-08 01:38:27.000000000 +0900
-@@ -259,7 +259,13 @@ private:
-     void        DoMatch            (PRBool aMatchAll);
-     gint        RawGetWidth        (const PRUnichar* aString,
--                                    PRUint32         aLength);
-+                                    PRUint32         aLength,
-+                                    PRUint32         aStart,
-+                                    PRUint32         aEnd);
-+    gint        RawGetWidth        (const char* aString,
-+                                    PRUint32    aLength,
-+                                    PRUint32    aStart,
-+                                    PRUint32    aEnd);
-     nsresult    SetupMiniFont      (void);
-     nsresult    DrawUnknownGlyph   (FcChar32   aChar,
-                                     nscoord    aX,
-@@ -272,10 +278,14 @@ private:
-                                     void     *aCallbackData);
-     nsresult    EnumerateGlyphs    (const char *aString,
-                                     PRUint32  aLen,
-+                                    PRUint32  aStart,
-+                                    PRUint32  aEnd,
-                                     GlyphEnumeratorCallback aCallback,
-                                     void     *aCallbackData);
-     nsresult    EnumerateGlyphs    (const PRUnichar *aString,
-                                     PRUint32  aLen,
-+                                    PRUint32  aStart,
-+                                    PRUint32  aEnd,
-                                     GlyphEnumeratorCallback aCallback,
-                                     void     *aCallbackData);
-     void        PrepareToDraw      (nsRenderingContextGTK *aContext,
This page took 0.484123 seconds and 4 git commands to generate.