rpms/thunderbird/F-7 firefox-2.0-pango-ligatures.patch, NONE, 1.1 thunderbird.spec, 1.100, 1.101

Martin Stransky (stransky) fedora-extras-commits at redhat.com
Fri Jul 27 12:50:51 UTC 2007


Author: stransky

Update of /cvs/pkgs/rpms/thunderbird/F-7
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv22435

Modified Files:
	thunderbird.spec 
Added Files:
	firefox-2.0-pango-ligatures.patch 
Log Message:
added ligature pango fix

firefox-2.0-pango-ligatures.patch:

--- NEW FILE firefox-2.0-pango-ligatures.patch ---
--- 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 at mozilla.org>
+ *   Behdad Esfahbod <behdad at 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,14 +228,20 @@ nsFontMetricsPango::Init(const nsFont& a
     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 * FONT_MAX_FONT_SCALE, 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


Index: thunderbird.spec
===================================================================
RCS file: /cvs/pkgs/rpms/thunderbird/F-7/thunderbird.spec,v
retrieving revision 1.100
retrieving revision 1.101
diff -u -r1.100 -r1.101
--- thunderbird.spec	20 Jul 2007 00:41:45 -0000	1.100
+++ thunderbird.spec	27 Jul 2007 12:50:19 -0000	1.101
@@ -8,7 +8,7 @@
 Summary:	Mozilla Thunderbird mail/newsgroup client
 Name:		thunderbird
 Version:	2.0.0.5
-Release:	1%{?dist}
+Release:	2%{?dist}
 URL:		http://www.mozilla.org/projects/thunderbird/
 License:	MPL
 Group:		Applications/Internet
@@ -56,6 +56,7 @@
 Patch86:        firefox-1.5-pango-justified-range.patch
 Patch87:        firefox-1.5-pango-underline.patch
 Patch88:        firefox-1.5-xft-rangewidth.patch
+Patch89:        firefox-2.0-pango-ligatures.patch
 
 # Other 
 Patch102:       firefox-1.5-theme-change.patch
@@ -129,6 +130,7 @@
 %patch86 -p1 -b .pango-justified-range
 %patch87 -p1 -b .pango-underline
 %patch88 -p1 -b .nopangoxft2
+%patch89 -p1 -b .pango-ligatures
 pushd gfx/src/ps
   # This sort of sucks, but it works for now.
   ln -s ../gtk/nsFontMetricsPango.h .
@@ -311,6 +313,9 @@
 #===============================================================================
 
 %changelog
+* Wed Jul 25 2007 Martin Stransky <stransky at redhat.com> 2.0.0.5-2
+- added ligature pango fix
+
 * Fri Jul 20 2007 Kai Engert <kengert at redhat.com> - 2.0.0.5-1
 - 2.0.0.5
 




More information about the scm-commits mailing list