rpms/thunderbird-enigmail/F-10 firefox-1.0-prdtoa.patch, NONE, 1.1 firefox-1.1-uriloader.patch, NONE, 1.1 firefox-1.5-bullet-bill.patch, NONE, 1.1 firefox-1.5-pango-cursor-position-more.patch, NONE, 1.1 firefox-1.5-pango-cursor-position.patch, NONE, 1.1 firefox-1.5-pango-justified-range.patch, NONE, 1.1 firefox-1.5-pango-underline.patch, NONE, 1.1 firefox-1.5-theme-change.patch, NONE, 1.1 firefox-1.5-xft-rangewidth.patch, NONE, 1.1 firefox-2.0-link-layout.patch, NONE, 1.1 firefox-2.0-pango-ligatures.patch, NONE, 1.1 firefox-2.0-pango-printing.patch, NONE, 1.1 firefox-2.0.0.4-undo-uriloader.patch, NONE, 1.1 mozilla-extension-update.sh, NONE, 1.1 thunderbird-0.7.3-gnome-uriloader.patch, NONE, 1.1 thunderbird-0.7.3-psfonts.patch, NONE, 1.1 thunderbird-1.5-profile-migrator.patch, NONE, 1.1 thunderbird-2.0-default-applications.patch, NONE, 1.1 thunderbird-2.0-enable-debug.patch, NONE, 1.1 thunderbird-2.0.0.4-suse-visibility.patch, NONE, 1.1 thunderbird-enigmail.spec, NONE, 1.1 thunderbird-mozconfig, NONE, 1.1 thunderbird-mozconfig-branded, NONE, 1.1 thunderbird-path.patch, NONE, 1.1 .cvsignore, 1.1, 1.2 sources, 1.1, 1.2

Remi Collet remi at rpmfusion.org
Sat May 23 09:36:17 CEST 2009


Author: remi

Update of /cvs/free/rpms/thunderbird-enigmail/F-10
In directory se02.es.rpmfusion.net:/tmp/cvs-serv12185/F-10

Modified Files:
	.cvsignore sources 
Added Files:
	firefox-1.0-prdtoa.patch firefox-1.1-uriloader.patch 
	firefox-1.5-bullet-bill.patch 
	firefox-1.5-pango-cursor-position-more.patch 
	firefox-1.5-pango-cursor-position.patch 
	firefox-1.5-pango-justified-range.patch 
	firefox-1.5-pango-underline.patch 
	firefox-1.5-theme-change.patch 
	firefox-1.5-xft-rangewidth.patch firefox-2.0-link-layout.patch 
	firefox-2.0-pango-ligatures.patch 
	firefox-2.0-pango-printing.patch 
	firefox-2.0.0.4-undo-uriloader.patch 
	mozilla-extension-update.sh 
	thunderbird-0.7.3-gnome-uriloader.patch 
	thunderbird-0.7.3-psfonts.patch 
	thunderbird-1.5-profile-migrator.patch 
	thunderbird-2.0-default-applications.patch 
	thunderbird-2.0-enable-debug.patch 
	thunderbird-2.0.0.4-suse-visibility.patch 
	thunderbird-enigmail.spec thunderbird-mozconfig 
	thunderbird-mozconfig-branded thunderbird-path.patch 
Log Message:
	New Package


firefox-1.0-prdtoa.patch:

--- NEW FILE firefox-1.0-prdtoa.patch ---
Index: nsprpub/pr/src/misc/Makefile.in
===================================================================
RCS file: /cvsroot/mozilla/nsprpub/pr/src/misc/Makefile.in,v
retrieving revision 1.15.2.2
diff -u -r1.15.2.2 Makefile.in
--- nsprpub/pr/src/misc/Makefile.in	6 Jun 2003 03:09:17 -0000	1.15.2.2
+++ nsprpub/pr/src/misc/Makefile.in	19 Nov 2004 00:58:35 -0000
@@ -82,6 +82,14 @@
 
 include $(topsrcdir)/config/rules.mk
 
+NONOPT_CFLAGS=$(filter-out -O%, $(CFLAGS))
+
+ifeq ($(OS_ARCH),Linux)
+$(OBJDIR)/prdtoa.$(OBJ_SUFFIX): prdtoa.c
+	@$(MAKE_OBJDIR)
+	$(CC) -o $@ -c $(NONOPT_CFLAGS) -ffloat-store $<
+endif
+
 # Prevent floating point errors caused by MSVC 6.0 Processor Pack
 # optimizations (bug 207421).  This disables optimizations that
 # could change the precision of floating-point calculations for

firefox-1.1-uriloader.patch:

--- NEW FILE firefox-1.1-uriloader.patch ---
Index: uriloader/exthandler/Makefile.in
===================================================================
RCS file: /cvsroot/mozilla/uriloader/exthandler/Makefile.in,v
retrieving revision 1.60
diff -d -u -p -r1.60 Makefile.in
--- uriloader/exthandler/Makefile.in	2 May 2005 16:30:03 -0000	1.60
+++ uriloader/exthandler/Makefile.in	21 Jul 2005 03:07:39 -0000
@@ -102,7 +102,7 @@ endif
 LOCAL_INCLUDES = -I$(srcdir)
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
-OSHELPER	+= nsGNOMERegistry.cpp
+OSHELPER	+= nsMIMEInfoUnix.cpp nsGNOMERegistry.cpp
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),beos)
Index: uriloader/exthandler/unix/nsGNOMERegistry.cpp
===================================================================
RCS file: /cvsroot/mozilla/uriloader/exthandler/unix/nsGNOMERegistry.cpp,v
retrieving revision 1.10
diff -d -u -p -r1.10 nsGNOMERegistry.cpp
--- uriloader/exthandler/unix/nsGNOMERegistry.cpp	16 Oct 2004 13:46:17 -0000	1.10
+++ uriloader/exthandler/unix/nsGNOMERegistry.cpp	21 Jul 2005 03:07:40 -0000
@@ -42,7 +42,7 @@
 #include "nsString.h"
 #include "nsIComponentManager.h"
 #include "nsILocalFile.h"
-#include "nsMIMEInfoImpl.h"
+#include "nsMIMEInfoUnix.h"
 #include "nsAutoPtr.h"
 
 #include <glib.h>
@@ -56,12 +56,12 @@ typedef struct _GConfClient GConfClient;
 typedef struct _GnomeProgram GnomeProgram;
 typedef struct _GnomeModuleInfo GnomeModuleInfo;
 
-typedef struct {
+struct GnomeVFSMimeApplication {
   char *id;
   char *name;
   char *command;
   /* there is more here, but we don't need it */
-} GnomeVFSMimeApplication;
+};
 
 typedef GConfClient * (*_gconf_client_get_default_fn)();
 typedef gchar * (*_gconf_client_get_string_fn)(GConfClient *,
@@ -264,7 +264,7 @@ nsGNOMERegistry::GetAppDescForScheme(con
 }
 
 
-/* static */ already_AddRefed<nsMIMEInfoBase>
+/* static */ already_AddRefed<nsMIMEInfoUnix>
 nsGNOMERegistry::GetFromExtension(const char *aFileExt)
 {
   if (!gconfLib)
@@ -286,7 +286,7 @@ nsGNOMERegistry::GetFromExtension(const 
   return GetFromType(mimeType);
 }
 
-/* static */ already_AddRefed<nsMIMEInfoBase>
+/* static */ already_AddRefed<nsMIMEInfoUnix>
 nsGNOMERegistry::GetFromType(const char *aMIMEType)
 {
   if (!gconfLib)
@@ -296,9 +296,11 @@ nsGNOMERegistry::GetFromType(const char 
   if (!handlerApp)
     return nsnull;
 
-  nsRefPtr<nsMIMEInfoImpl> mimeInfo = new nsMIMEInfoImpl(aMIMEType);
+  nsRefPtr<nsMIMEInfoUnix> mimeInfo = new nsMIMEInfoUnix(aMIMEType);
   NS_ENSURE_TRUE(mimeInfo, nsnull);
 
+  mimeInfo->SetDefaultGnomeVFSMimeApplication(handlerApp);
+
   // Get the list of extensions and append then to the mimeInfo.
   GList *extensions = _gnome_vfs_mime_get_extensions_list(aMIMEType);
   for (GList *extension = extensions; extension; extension = extension->next)
@@ -320,11 +322,21 @@ nsGNOMERegistry::GetFromType(const char 
     return nsnull;
   }
 
-  gchar *commandPath = g_find_program_in_path(nativeCommand);
+  gchar **argv;
+  gboolean res = g_shell_parse_argv(nativeCommand, NULL, &argv, NULL);
+  if (!res) {
+    NS_ERROR("Could not convert helper app command to filesystem encoding");
+    _gnome_vfs_mime_application_free(handlerApp);
+    return nsnull;
+  }
+
+  gchar *commandPath = g_find_program_in_path(argv[0]);
 
   g_free(nativeCommand);
+  g_strfreev(argv);
 
   if (!commandPath) {
+    NS_WARNING("could not find command in path");
     _gnome_vfs_mime_application_free(handlerApp);
     return nsnull;
   }
@@ -342,7 +354,7 @@ nsGNOMERegistry::GetFromType(const char 
 
   _gnome_vfs_mime_application_free(handlerApp);
 
-  nsMIMEInfoBase* retval;
+  nsMIMEInfoUnix* retval;
   NS_ADDREF((retval = mimeInfo));
   return retval;
 }
Index: uriloader/exthandler/unix/nsGNOMERegistry.h
===================================================================
RCS file: /cvsroot/mozilla/uriloader/exthandler/unix/nsGNOMERegistry.h,v
retrieving revision 1.3
diff -d -u -p -r1.3 nsGNOMERegistry.h
--- uriloader/exthandler/unix/nsGNOMERegistry.h	16 Oct 2004 13:46:17 -0000	1.3
+++ uriloader/exthandler/unix/nsGNOMERegistry.h	21 Jul 2005 03:07:40 -0000
@@ -35,10 +35,13 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
+#ifndef nsGNOMERegistry_h__
+#define nsGNOMERegistry_h__
+
 #include "nsIURI.h"
 #include "nsCOMPtr.h"
 
-class nsMIMEInfoBase;
+class nsMIMEInfoUnix;
 
 class nsGNOMERegistry
 {
@@ -52,7 +55,9 @@ class nsGNOMERegistry
   static void GetAppDescForScheme(const nsACString& aScheme,
                                   nsAString& aDesc);
 
-  static already_AddRefed<nsMIMEInfoBase> GetFromExtension(const char *aFileExt);
+  static already_AddRefed<nsMIMEInfoUnix> GetFromExtension(const char *aFileExt);
 
-  static already_AddRefed<nsMIMEInfoBase> GetFromType(const char *aMIMEType);
+  static already_AddRefed<nsMIMEInfoUnix> GetFromType(const char *aMIMEType);
 };
+
+#endif // nsGNOMERegistry_h__
Index: uriloader/exthandler/unix/nsMIMEInfoUnix.cpp
===================================================================
RCS file: uriloader/exthandler/unix/nsMIMEInfoUnix.cpp
diff -N uriloader/exthandler/unix/nsMIMEInfoUnix.cpp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ uriloader/exthandler/unix/nsMIMEInfoUnix.cpp	21 Jul 2005 03:07:40 -0000
@@ -0,0 +1,196 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.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
+ * Red Hat, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2005
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Christopher Aillon <caillon at redhat.com> (Original author)
+ *
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsMIMEInfoUnix.h"
+#include "prlink.h"
+#include "prmem.h"
+#include <glib.h>
+#include <glib-object.h>
+
+static PRLibrary *gnomeLib;
+static PRLibrary *vfsLib;
+
+typedef struct _GnomeProgram GnomeProgram;
+typedef struct _GnomeModuleInfo GnomeModuleInfo;
+
+typedef enum {
+  GNOME_VFS_OK // there's more but we don't care about them.
+} GnomeVFSResult;
+
+typedef GnomeVFSResult (*_gnome_vfs_mime_application_launch_fn)
+                              (GnomeVFSMimeApplication *app,
+                               GList *uris);
+typedef void (*_gnome_vfs_mime_application_free_fn)(GnomeVFSMimeApplication *);
+typedef GnomeVFSMimeApplication * (*_gnome_vfs_mime_application_copy_fn)(GnomeVFSMimeApplication *);
+typedef GnomeProgram * (*_gnome_program_init_fn)(const char *, const char *,
+						 const GnomeModuleInfo *, int,
+						 char **, const char *, ...);
+typedef const char * (*_gnome_vfs_mime_application_get_name_fn)(GnomeVFSMimeApplication *);
+typedef const GnomeModuleInfo * (*_libgnome_module_info_get_fn)();
+typedef GnomeProgram * (*_gnome_program_get_fn)();
+typedef char * (*_gnome_vfs_make_uri_from_input_fn)(const char *);
+
+#define DECL_FUNC_PTR(func) static _##func##_fn _##func
+
+DECL_FUNC_PTR(gnome_vfs_mime_application_launch);
+DECL_FUNC_PTR(gnome_vfs_mime_application_free);
+DECL_FUNC_PTR(gnome_vfs_mime_application_copy);
+DECL_FUNC_PTR(gnome_vfs_mime_application_get_name);
+DECL_FUNC_PTR(gnome_program_init);
+DECL_FUNC_PTR(gnome_program_get);
+DECL_FUNC_PTR(libgnome_module_info_get);
+DECL_FUNC_PTR(gnome_vfs_make_uri_from_input);
+
+static PRLibrary *
+LoadVersionedLibrary(const char* libName, const char* libVersion)
+{
+  char *platformLibName = PR_GetLibraryName(nsnull, libName);
+  nsCAutoString versionLibName(platformLibName);
+  versionLibName.Append(libVersion);
+  PR_Free(platformLibName);
+  return PR_LoadLibrary(versionLibName.get());
+}
+
+static void
+Cleanup()
+{
+  // Unload all libraries
+  if (gnomeLib)
+    PR_UnloadLibrary(gnomeLib);
+  if (vfsLib)
+    PR_UnloadLibrary(vfsLib);
+
+  gnomeLib = vfsLib = nsnull;
+}
+
+static void
+InitGnomeVFS()
+{
+  static PRBool initialized = PR_FALSE;
+
+  if (initialized)
+    return;
+
+  #define ENSURE_LIB(lib) \
+    PR_BEGIN_MACRO \
+    if (!lib) { \
+      Cleanup(); \
+      return; \
+    } \
+    PR_END_MACRO
+
+  #define GET_LIB_FUNCTION(lib, func, failure) \
+    PR_BEGIN_MACRO \
+    _##func = (_##func##_fn) PR_FindFunctionSymbol(lib##Lib, #func); \
+    if (!_##func) { \
+      failure; \
+    } \
+    PR_END_MACRO
+
+  // Attempt to open libgnome
+  gnomeLib = LoadVersionedLibrary("gnome-2", ".0");
+  ENSURE_LIB(gnomeLib);
+
+  GET_LIB_FUNCTION(gnome, gnome_program_init, return Cleanup());
+  GET_LIB_FUNCTION(gnome, libgnome_module_info_get, return Cleanup());
+  GET_LIB_FUNCTION(gnome, gnome_program_get, return Cleanup());
+
+  // Attempt to open libgnomevfs
+  vfsLib = LoadVersionedLibrary("gnomevfs-2", ".0");
+  ENSURE_LIB(vfsLib);
+
+  GET_LIB_FUNCTION(vfs, gnome_vfs_mime_application_launch, /* do nothing */);
+  GET_LIB_FUNCTION(vfs, gnome_vfs_make_uri_from_input, return Cleanup());
+  GET_LIB_FUNCTION(vfs, gnome_vfs_mime_application_get_name, return Cleanup());
+  GET_LIB_FUNCTION(vfs, gnome_vfs_mime_application_free, return Cleanup());
+  GET_LIB_FUNCTION(vfs, gnome_vfs_mime_application_copy, return Cleanup());
+
+  // Initialize GNOME, if it's not already initialized.  It's not
+  // necessary to tell GNOME about our actual command line arguments.
+
+  if (!_gnome_program_get()) {
+    char *argv[1] = { "gecko" };
+    _gnome_program_init("Gecko", "1.0", _libgnome_module_info_get(),
+                        1, argv, NULL);
+  }
+
+  // Note: after GNOME has been initialized, do not ever unload these
+  // libraries.  They register atexit handlers, so if they are unloaded, we'll
+  // crash on exit.  
+}
+
+void
+nsMIMEInfoUnix::SetDefaultGnomeVFSMimeApplication(GnomeVFSMimeApplication* app)
+{
+  if (_gnome_vfs_mime_application_copy && _gnome_vfs_mime_application_free) {
+    mDefaultVFSApplication = _gnome_vfs_mime_application_copy(app);
+
+    mPreferredAction = nsIMIMEInfo::useSystemDefault;
+
+    const gchar * name = _gnome_vfs_mime_application_get_name(mDefaultVFSApplication);
+    if (name) 
+      mDefaultAppDescription = NS_ConvertUTF8toUCS2(name);
+  }
+}
+
+nsMIMEInfoUnix::~nsMIMEInfoUnix()
+{
+  if (mDefaultVFSApplication)
+    _gnome_vfs_mime_application_free(mDefaultVFSApplication);
+}
+
+nsresult
+nsMIMEInfoUnix::LaunchDefaultWithFile(nsIFile* aFile)
+{
+  NS_ENSURE_ARG_POINTER(aFile);
+
+  InitGnomeVFS();
+
+  if (_gnome_vfs_mime_application_launch && mDefaultVFSApplication) {
+    nsCAutoString nativePath;
+    aFile->GetNativePath(nativePath);
+
+    gchar *uri = _gnome_vfs_make_uri_from_input(nativePath.get());
+
+    GList *uris = NULL;
+    uris = g_list_append(uris, uri);
+
+    GnomeVFSResult result = _gnome_vfs_mime_application_launch(mDefaultVFSApplication, uris);
+
+    g_free(uri);
+    g_list_free(uris);
+
+    if (result != GNOME_VFS_OK)
+      return NS_ERROR_FAILURE;
+
+    return NS_OK;
+  }
+
+  if (!mDefaultApplication)
+    return NS_ERROR_FILE_NOT_FOUND;
+
+  return LaunchWithIProcess(mDefaultApplication, aFile);
+}
Index: uriloader/exthandler/unix/nsMIMEInfoUnix.h
===================================================================
RCS file: uriloader/exthandler/unix/nsMIMEInfoUnix.h
diff -N uriloader/exthandler/unix/nsMIMEInfoUnix.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ uriloader/exthandler/unix/nsMIMEInfoUnix.h	21 Jul 2005 03:07:40 -0000
@@ -0,0 +1,50 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.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
+ * Red Hat, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2005
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Christopher Aillon <caillon at redhat.com> (Original author)
+ *
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsMimeInfoUnix_h__
+#define nsMimeInfoUnix_h__
+
+#include "nsMIMEInfoImpl.h"
+
+struct GnomeVFSMimeApplication;
+
+class nsMIMEInfoUnix : public nsMIMEInfoImpl
+{
+public:
+  nsMIMEInfoUnix(const char* aType = "") : nsMIMEInfoImpl(aType), mDefaultVFSApplication(nsnull) {}
+  nsMIMEInfoUnix(const nsACString& aMIMEType) : nsMIMEInfoImpl(aMIMEType) {};
+
+  virtual ~nsMIMEInfoUnix();
+
+  void SetDefaultGnomeVFSMimeApplication(GnomeVFSMimeApplication *app);
+
+protected:
+  virtual NS_HIDDEN_(nsresult) LaunchDefaultWithFile(nsIFile* aFile);
+
+  GnomeVFSMimeApplication *mDefaultVFSApplication;
+};
+ 
+#endif // nsMimeInfoUnix_h__
Index: uriloader/exthandler/unix/nsOSHelperAppService.cpp
===================================================================
RCS file: /cvsroot/mozilla/uriloader/exthandler/unix/nsOSHelperAppService.cpp,v
retrieving revision 1.58
diff -d -u -p -r1.58 nsOSHelperAppService.cpp
--- uriloader/exthandler/unix/nsOSHelperAppService.cpp	25 Oct 2004 07:46:01 -0000	1.58
+++ uriloader/exthandler/unix/nsOSHelperAppService.cpp	21 Jul 2005 03:07:40 -0000
@@ -44,6 +44,7 @@
 #include "nsOSHelperAppService.h"
 #ifdef MOZ_WIDGET_GTK2
 #include "nsGNOMERegistry.h"
+#include "nsMIMEInfoUnix.h"
 #endif
 #include "nsISupports.h"
 #include "nsString.h"
@@ -1486,6 +1487,17 @@ nsOSHelperAppService::GetFromType(const 
   
   LOG(("Here we do a mimetype lookup for '%s'\n", aMIMEType.get()));
 
+#ifdef MOZ_WIDGET_GTK2
+  // Look in GNOME registry first since it is the preferred method in GNOME,
+  // should trump the mailcap entry
+  LOG(("Looking in GNOME registry\n"));
+  nsMIMEInfoBase *gnomeInfo = nsGNOMERegistry::GetFromType(aMIMEType.get()).get();
+  if (gnomeInfo) {
+    LOG(("Got MIMEInfo from GNOME registry\n"));
+    return gnomeInfo;
+  }
+#endif
+
   // extract the major and minor types
   NS_ConvertASCIItoUTF16 mimeType(aMIMEType);
   nsAString::const_iterator start_iter, end_iter,
@@ -1522,21 +1534,6 @@ nsOSHelperAppService::GetFromType(const 
                                 mozillaFlags,
                                 PR_TRUE);
 
-  
-  if (handler.IsEmpty() && extensions.IsEmpty() &&
-      mailcap_description.IsEmpty() && mime_types_description.IsEmpty()) {
-    // No useful data yet
-    
-#ifdef MOZ_WIDGET_GTK2
-    LOG(("Looking in GNOME registry\n"));
-    nsMIMEInfoBase *gnomeInfo = nsGNOMERegistry::GetFromType(aMIMEType.get()).get();
-    if (gnomeInfo) {
-      LOG(("Got MIMEInfo from GNOME registry\n"));
-      return gnomeInfo;
-    }
-#endif
-  }
-
   if (handler.IsEmpty() && mailcap_description.IsEmpty()) {
     DoLookUpHandlerAndDescription(majorType,
                                   minorType,

firefox-1.5-bullet-bill.patch:

--- NEW FILE firefox-1.5-bullet-bill.patch ---
Index: mozilla/editor/libeditor/text/nsTextEditRules.cpp
===================================================================
RCS file: /cvsroot/mozilla/editor/libeditor/text/nsTextEditRules.cpp,v
retrieving revision 1.195
diff -d -u -p -r1.195 nsTextEditRules.cpp
--- mozilla/editor/libeditor/text/nsTextEditRules.cpp	16 Jun 2005 13:10:56 -0000	1.195
+++ mozilla/editor/libeditor/text/nsTextEditRules.cpp	4 Oct 2006 16:02:19 -0000
@@ -1390,13 +1390,13 @@ nsTextEditRules::EchoInsertionToPWBuff(P
   // manage the password buffer
   mPasswordText.Insert(*aOutString, aStart);
 
-  // change the output to '*' only
+  // change the output to 'U+2022' only
   PRInt32 length = aOutString->Length();
   PRInt32 i;
   aOutString->Truncate();
   for (i=0; i<length; i++)
   {
-    aOutString->Append(PRUnichar('*'));
+    aOutString->Append(PRUnichar(0x2022));
   }
 
   return NS_OK;

firefox-1.5-pango-cursor-position-more.patch:

--- NEW FILE firefox-1.5-pango-cursor-position-more.patch ---
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)) {
       //

firefox-1.5-pango-cursor-position.patch:

--- NEW FILE firefox-1.5-pango-cursor-position.patch ---
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;

firefox-1.5-pango-justified-range.patch:

--- NEW FILE firefox-1.5-pango-justified-range.patch ---
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

firefox-1.5-pango-underline.patch:

--- NEW FILE firefox-1.5-pango-underline.patch ---
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;

firefox-1.5-theme-change.patch:

--- NEW FILE firefox-1.5-theme-change.patch ---
Index: layout/base/nsPresContext.cpp
===================================================================
RCS file: /cvsroot/mozilla/layout/base/nsPresContext.cpp,v
retrieving revision 3.288.12.5
diff -d -u -p -r3.288.12.5 nsPresContext.cpp
--- layout/base/nsPresContext.cpp	17 May 2006 07:56:35 -0000	3.288.12.5
+++ layout/base/nsPresContext.cpp	19 Sep 2008 16:33:31 -0000
@@ -73,6 +73,9 @@
 #include "nsIDOMDocument.h"
 #include "nsAutoPtr.h"
 #include "nsEventStateManager.h"
+#include "nsIEventQueue.h"
+#include "nsIEventQueueService.h"
+
 #ifdef IBMBIDI
 #include "nsBidiPresUtils.h"
 #endif // IBMBIDI
@@ -267,6 +270,7 @@ nsPresContext::~nsPresContext()
   NS_IF_RELEASE(mDeviceContext);
   NS_IF_RELEASE(mLookAndFeel);
   NS_IF_RELEASE(mLangGroup);
+  NS_IF_RELEASE(mEventQueueService);
 }
 
 NS_IMPL_ISUPPORTS2(nsPresContext, nsPresContext, nsIObserver)
@@ -285,6 +289,17 @@ static const char* const kGenericFont[] 
   ".fantasy."
 };
 
+// Set to true when LookAndFeelChanged needs to be called.  This is used
+// because the look and feel is a service, so there's no need to notify it from
+// more than one prescontext.
+static PRBool sLookAndFeelChanged;
+
+// Set to true when ThemeChanged needs to be called on mTheme.  This is used
+// because mTheme is a service, so there's no need to notify it from more than
+// one prescontext.
+static PRBool sThemeChanged;
+
+
 void
 nsPresContext::GetFontPreferences()
 {
@@ -716,6 +731,9 @@ nsPresContext::Init(nsIDeviceContext* aD
                                        this);
 #endif
 
+  rv = CallGetService(NS_EVENTQUEUESERVICE_CONTRACTID, &mEventQueueService);
+  NS_ENSURE_SUCCESS(rv, rv);
+
   // Initialize our state from the user preferences
   GetUserPreferences();
 
@@ -1197,33 +1215,126 @@ nsPresContext::GetTheme()
 void
 nsPresContext::ThemeChanged()
 {
+  if (!mPendingThemeChanged) {
+    sLookAndFeelChanged = PR_TRUE;
+    sThemeChanged = PR_TRUE;
+
+    nsCOMPtr<nsIEventQueue> eventQ;
+    mEventQueueService->
+      GetSpecialEventQueue(nsIEventQueueService::UI_THREAD_EVENT_QUEUE,
+                           getter_AddRefs(eventQ));
+    if (!eventQ) {
+      return;
+    }
+
+    PLEvent* evt = new PLEvent();
+    if (!evt) {
+      return;
+    }
+
+    PL_InitEvent(evt, this, nsPresContext::ThemeChangedInternal,
+                 nsPresContext::DestroyThemeChangeEvt);
+
+    // After this point, event destruction will release |this|
+    NS_ADDREF_THIS();
+
+    nsresult rv = eventQ->PostEvent(evt);
+    if (NS_FAILED(rv)) {
+      PL_DestroyEvent(evt);
+    } else {
+      mPendingThemeChanged = PR_TRUE;
+    }
+  }    
+}
+
+void* PR_CALLBACK
+nsPresContext::ThemeChangedInternal(PLEvent *aEvent)
+{
+  nsPresContext* pc = NS_STATIC_CAST(nsPresContext*, aEvent->owner);
+
+  pc->mPendingThemeChanged = PR_FALSE;
+
   // Tell the theme that it changed, so it can flush any handles to stale theme
   // data.
-  if (mTheme)
-    mTheme->ThemeChanged();
+  if (pc->mTheme && sThemeChanged) {
+    pc->mTheme->ThemeChanged();
+    sThemeChanged = PR_FALSE;
+  }
 
   // Clear all cached nsILookAndFeel colors.
-  if (mLookAndFeel)
-    mLookAndFeel->LookAndFeelChanged();
+  if (pc->mLookAndFeel && sLookAndFeelChanged) {
+    pc->mLookAndFeel->LookAndFeelChanged();
+    sLookAndFeelChanged = PR_FALSE;
+  }
 
   // We have to clear style data because the assumption of style rule
   // immutability has been violated since any style rule that uses
   // system colors or fonts (and probably -moz-appearance as well) has
   // changed.
-  nsPresContext::ClearStyleDataAndReflow();
+  pc->ClearStyleDataAndReflow();
+
+  return nsnull;
+}
+
+
+void PR_CALLBACK
+nsPresContext::DestroyThemeChangeEvt(PLEvent* aEvent)
+{
+  nsPresContext* pc = NS_STATIC_CAST(nsPresContext*, aEvent->owner);
+  NS_RELEASE(pc);
+  delete aEvent;
 }
 
 void
 nsPresContext::SysColorChanged()
 {
-  if (mLookAndFeel) {
+  if (!mPendingSysColorChanged) {
+    sLookAndFeelChanged = PR_TRUE;
+
+    nsCOMPtr<nsIEventQueue> eventQ;
+    mEventQueueService->
+      GetSpecialEventQueue(nsIEventQueueService::UI_THREAD_EVENT_QUEUE,
+                           getter_AddRefs(eventQ));
+    if (!eventQ) {
+      return;
+    }
+
+    PLEvent* evt = new PLEvent();
+    if (!evt) {
+      return;
+    }
+
+    PL_InitEvent(evt, this, nsPresContext::SysColorChangedInternal,
+                 nsPresContext::DestroySysColorChangeEvt);
+
+    // After this point, event destruction will release |this|
+    NS_ADDREF_THIS();
+
+    nsresult rv = eventQ->PostEvent(evt);
+    if (NS_FAILED(rv)) {
+      PL_DestroyEvent(evt);
+    } else {
+      mPendingSysColorChanged = PR_TRUE;
+    }
+  }
+}
+
+void* PR_CALLBACK
+nsPresContext::SysColorChangedInternal(PLEvent *aEvent)
+{
+  nsPresContext* pc = NS_STATIC_CAST(nsPresContext*, aEvent->owner);
+
+  pc->mPendingSysColorChanged = PR_FALSE;
+  
+  if (pc->mLookAndFeel && sLookAndFeelChanged) {
      // Don't use the cached values for the system colors
-    mLookAndFeel->LookAndFeelChanged();
+    pc->mLookAndFeel->LookAndFeelChanged();
+    sLookAndFeelChanged = PR_FALSE;
   }
-   
+
   // Reset default background and foreground colors for the document since
   // they may be using system colors
-  GetDocumentColorPreferences();
+  pc->GetDocumentColorPreferences();
 
   // Clear out all of the style data since it may contain RGB values
   // which originated from system colors.
@@ -1239,7 +1350,17 @@ nsPresContext::SysColorChanged()
   // data without reflowing/updating views will lead to incorrect change hints
   // later, because when generating change hints, any style structs which have
   // been cleared and not reread are assumed to not be used at all.
-  ClearStyleDataAndReflow();
+  pc->ClearStyleDataAndReflow();
+
+  return nsnull;
+}
+
+void PR_CALLBACK
+nsPresContext::DestroySysColorChangeEvt(PLEvent* aEvent)
+{
+  nsPresContext* pc = NS_STATIC_CAST(nsPresContext*, aEvent->owner);
+  NS_RELEASE(pc);
+  delete aEvent;
 }
 
 void
Index: layout/base/nsPresContext.h
===================================================================
RCS file: /cvsroot/mozilla/layout/base/nsPresContext.h,v
retrieving revision 3.150.4.3
diff -d -u -p -r3.150.4.3 nsPresContext.h
--- layout/base/nsPresContext.h	29 Aug 2007 23:07:47 -0000	3.150.4.3
+++ layout/base/nsPresContext.h	19 Sep 2008 16:33:31 -0000
@@ -56,6 +56,7 @@
 #include "nsCRT.h"
 #include "nsIPrintSettings.h"
 #include "nsPropertyTable.h"
+#include "plevent.h"
 #ifdef IBMBIDI
 class nsBidiPresUtils;
 #endif // IBMBIDI
@@ -76,6 +77,7 @@ class nsIAtom;
 class nsIEventStateManager;
 class nsIURI;
 class nsILookAndFeel;
+class nsIEventQueueService;
 class nsICSSPseudoComparator;
 class nsIAtom;
 struct nsStyleStruct;
@@ -630,6 +632,14 @@ public:
   PRBool IsChrome();
 
 protected:
+  static NS_HIDDEN_(void*) PR_CALLBACK ThemeChangedInternal(PLEvent* aEvent);
+  static NS_HIDDEN_(void*) PR_CALLBACK SysColorChangedInternal(PLEvent* aEvent);
+  static NS_HIDDEN_(void) PR_CALLBACK DestroyThemeChangeEvt(PLEvent* aEvent);
+  static NS_HIDDEN_(void) PR_CALLBACK DestroySysColorChangeEvt(PLEvent* aEvent);
+
+  friend void* PR_CALLBACK ThemeChangedInternal(PLEvent* aEvent);
+  friend void* PR_CALLBACK SysColorChangedInternal(PLEvent* aEvent);
+
   NS_HIDDEN_(void) SetImgAnimations(nsIContent *aParent, PRUint16 aMode);
   NS_HIDDEN_(void) GetDocumentColorPreferences();
 
@@ -657,6 +667,7 @@ protected:
                                         // from gfx back to layout.
   nsIEventStateManager* mEventManager;  // [STRONG]
   nsILookAndFeel*       mLookAndFeel;   // [STRONG]
+  nsIEventQueueService *mEventQueueService; // [STRONG]
   nsIAtom*              mMedium;        // initialized by subclass ctors;
                                         // weak pointer to static atom
 
@@ -727,6 +738,8 @@ protected:
   unsigned              mCanPaginatedScroll : 1;
   unsigned              mDoScaledTwips : 1;
   unsigned              mEnableJapaneseTransform : 1;
+  unsigned              mPendingSysColorChanged : 1;
+  unsigned              mPendingThemeChanged : 1;
 #ifdef IBMBIDI
   unsigned              mIsVisual : 1;
   unsigned              mIsBidiSystem : 1;

firefox-1.5-xft-rangewidth.patch:

--- NEW FILE firefox-1.5-xft-rangewidth.patch ---
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,

firefox-2.0-link-layout.patch:

--- NEW FILE firefox-2.0-link-layout.patch ---
Index: mozilla/layout/build/Makefile.in
===================================================================
RCS file: /cvsroot/mozilla/layout/build/Makefile.in,v
retrieving revision 1.127.8.7
diff -d -u -p -r1.127.8.7 Makefile.in
--- mozilla/layout/build/Makefile.in	17 Jul 2006 19:05:13 -0000	1.127.8.7
+++ mozilla/layout/build/Makefile.in	10 Oct 2006 04:29:16 -0000
@@ -240,6 +240,11 @@ EXTRA_DSO_LDOPTS += \
 	$(NULL)
 endif
 
+# Add explicit X11 dependency when building against X11 toolkits
+ifneq (,$(filter gtk gtk2 qt xlib,$(MOZ_WIDGET_TOOLKIT)))
+EXTRA_DSO_LDOPTS += $(XLDFLAGS) $(XLIBS) -lXrender
+endif
+
 include $(topsrcdir)/config/rules.mk
 
 LOCAL_INCLUDES	+= -I$(srcdir)/../base \

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,15 +228,21 @@ 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 - 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

firefox-2.0-pango-printing.patch:

--- NEW FILE firefox-2.0-pango-printing.patch ---
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 at 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 {
[...4187 lines suppressed...]
                  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


firefox-2.0.0.4-undo-uriloader.patch:

--- NEW FILE firefox-2.0.0.4-undo-uriloader.patch ---
Index: mozilla/uriloader/exthandler/unix/nsOSHelperAppService.cpp
===================================================================
RCS file: /cvsroot/mozilla/uriloader/exthandler/unix/nsOSHelperAppService.cpp,v
retrieving revision 1.58.20.1
retrieving revision 1.58
diff -d -u -p -r1.58.20.1 -r1.58
--- mozilla/uriloader/exthandler/unix/nsOSHelperAppService.cpp	16 Apr 2007 18:54:53 -0000	1.58.20.1
+++ mozilla/uriloader/exthandler/unix/nsOSHelperAppService.cpp	25 Oct 2004 07:46:01 -0000	1.58
@@ -1506,8 +1506,13 @@ nsOSHelperAppService::GetFromType(const 
 
   nsDependentSubstring majorType(majorTypeStart, majorTypeEnd);
   nsDependentSubstring minorType(minorTypeStart, minorTypeEnd);
+  nsAutoString extensions, mime_types_description;
+  LookUpExtensionsAndDescription(majorType,
+                                 minorType,
+                                 extensions,
+                                 mime_types_description);
+
 
-  // First check the user's private mailcap file
   nsAutoString mailcap_description, handler, mozillaFlags;
   DoLookUpHandlerAndDescription(majorType,
                                 minorType,
@@ -1516,46 +1521,23 @@ nsOSHelperAppService::GetFromType(const 
                                 mailcap_description,
                                 mozillaFlags,
                                 PR_TRUE);
-  
-  LOG(("Private Handler/Description results:  handler='%s', description='%s'\n",
-          NS_LossyConvertUTF16toASCII(handler).get(),
-          NS_LossyConvertUTF16toASCII(mailcap_description).get()));
 
+  
+  if (handler.IsEmpty() && extensions.IsEmpty() &&
+      mailcap_description.IsEmpty() && mime_types_description.IsEmpty()) {
+    // No useful data yet
+    
 #ifdef MOZ_WIDGET_GTK2
-  nsMIMEInfoBase *gnomeInfo = nsnull;
-  if (handler.IsEmpty()) {
-    // No useful data yet.  Check the GNOME registry.  Unfortunately, newer
-    // GNOME versions no longer have type-to-extension mappings, so we might
-    // get back a MIMEInfo without any extensions set.  In that case we'll have
-    // to look in our mime.types files for the extensions.    
     LOG(("Looking in GNOME registry\n"));
-    gnomeInfo = nsGNOMERegistry::GetFromType(aMIMEType.get()).get();
-    if (gnomeInfo && gnomeInfo->HasExtensions()) {
-      LOG(("Got MIMEInfo from GNOME registry, and it has extensions set\n"));
+    nsMIMEInfoBase *gnomeInfo = nsGNOMERegistry::GetFromType(aMIMEType.get()).get();
+    if (gnomeInfo) {
+      LOG(("Got MIMEInfo from GNOME registry\n"));
       return gnomeInfo;
     }
-  }
 #endif
-
-  // Now look up our extensions
-  nsAutoString extensions, mime_types_description;
-  LookUpExtensionsAndDescription(majorType,
-                                 minorType,
-                                 extensions,
-                                 mime_types_description);
-
-#ifdef MOZ_WIDGET_GTK2
-  if (gnomeInfo) {
-    LOG(("Got MIMEInfo from GNOME registry without extensions; setting them "
-         "to %s\n", NS_LossyConvertUTF16toASCII(extensions).get()));
-
-    NS_ASSERTION(!gnomeInfo->HasExtensions(), "How'd that happen?");
-    gnomeInfo->SetFileExtensions(NS_ConvertUTF16toUTF8(extensions));
-    return gnomeInfo;
   }
-#endif
 
-  if (handler.IsEmpty()) {
+  if (handler.IsEmpty() && mailcap_description.IsEmpty()) {
     DoLookUpHandlerAndDescription(majorType,
                                   minorType,
                                   typeOptions,
@@ -1565,7 +1547,7 @@ nsOSHelperAppService::GetFromType(const 
                                   PR_FALSE);
   }
 
-  if (handler.IsEmpty()) {
+  if (handler.IsEmpty() && mailcap_description.IsEmpty()) {
     DoLookUpHandlerAndDescription(majorType,
                                   NS_LITERAL_STRING("*"),
                                   typeOptions,
@@ -1575,7 +1557,7 @@ nsOSHelperAppService::GetFromType(const 
                                   PR_TRUE);
   }
 
-  if (handler.IsEmpty()) {
+  if (handler.IsEmpty() && mailcap_description.IsEmpty()) {
     DoLookUpHandlerAndDescription(majorType,
                                   NS_LITERAL_STRING("*"),
                                   typeOptions,


--- NEW FILE mozilla-extension-update.sh ---
#!/bin/sh
# 
# This script is used to add and remove our extension from one of the Mozilla
# products directory, and is run from 'triggers' when the product is installed or
# upgraded, as well as when our package is installed. It is needed because
# Mozilla products are installed into versioned directories in /usr/lib[64]/<product>
# so we have to make a new symlink into the right directory when the
# application is installed or upgraded. But we would rather not leave
# our old symlinks behind, since that will cause the application
# directories not to be removed. (flash-player leaves its old symlinks behind,
# but that's no excuse for us to do the same...)
#
# Because I don't know any way of finding out what the new version
# is on installation or old version on uninstallation, we have
# to do things in a somewhat non-intuitive way
#
# The order on upgrade of the mozilla application is:
#
#  1. new package installed
#  2. triggerin for new package - we add all symlinks
#  3. triggerun for old package - we remove all symlinks
#  4. old package uninstalled
#  5. triggerpostun for old package - we add all symlinks
#
# Triggers are also run on self-upgrade, in that case we do:
#
#  1. new package installed
#  2. triggerin for new package - we add all symlinks
#  3. triggerun for old package - we remove all symlinks
#  4. old package uninstalled
#  5. postun for old package - we add all symlinks
#  6. triggerpostun for old package - NOT RUN (contrary to RPM docs)
#
#
# Script arguments:
# --appname: the mozilla application that this extension should register into.
#            Usually firefox or thunderbird.
# --extname: the name of the extension. It can be determined by looking at
#            the install.rdf file, in the extension directory. This file
#            contains several <em:id> tags. The extname parameter is the
#            content of the em:id tag which is not contained in the
#            em:targetApplication tag
# --extpath: the path where the extension will be installed
# --action:  either "install" or "remove"
# --basedir: the dirname of the directory where the target application is
#            installed. Usually /usr/lib or /usr/lib64>, it defaults to
#            /usr/lib
#
#
# Here's an example implementation in rpm scriptlets:
#
# %define tbupdate %{_libdir}/lightning/mozilla-extension-update.sh --appname thunderbird --extname {e2fda1a4-762b-4020-b5ad-a41df1933103} --basedir %{_libdir} --extpath %{_libdir}/lightning --action 
# 
# %post
# %{tbupdate} install || true
# 
# %preun
# # On removal (but not upgrade), remove the extention
# if [ $1 = 0 ] ; then
#     %{tbupdate} remove || true
# fi
# 
# %postun
# # This is needed not to reverse the effect of our preun, which
# # is guarded against upgrade, but because of our triggerun,
# # which is run on self-upgrade, though triggerpostun isn't
# if [ $1 != 0 ] ; then
#     %{tbupdate} install || true
# fi
# 
# %triggerin -- thunderbird
# %{tbupdate} install || true
# 
# %triggerun -- thunderbird
# %{tbupdate} remove || true
# 
# %triggerpostun -- thunderbird
# # Guard against being run post-self-uninstall, even though that
# # doesn't happen currently (see comment above)
# if [ "$1" != 0 ] ; then
#     %{tbupdate} install || true
# fi


die() {
	echo >&2 "$@"
	exit 0
}

usage() {
	die "Usage: $0 --appname <application-name> --extname <extension-name> --extpath <extension-path> --action <install|remove> [--basedir </usr/lib|/usr/lib64>]"
}

appname=
extname=
extpath=
action=
basedir=/usr/lib
while [ "$#" -gt "0" ]; do
	case "$1" in
	--appname)
		shift; appname="$1" ;;
	--extname)
		shift; extname="$1" ;;
	--extpath)
		shift; extpath="$1" ;;
	--action)
		shift; action="$1" ;;
	--basedir)
		shift; basedir="$1" ;;
	*) usage ;;
	esac
	shift
done


if [ "$action" = "install" ] ; then
	# Add symlinks to any mozilla directory that looks like it is part of a
	# currently installed package
	for d in $basedir/${appname}*; do
	    if [ "$d" = "$basedir/${appname}*" ] ; then
            continue
	    fi
	    link=$d/extensions/$extname
	    if [ -e $extpath -a -e $d/$appname-bin -a -d $d/extensions -a ! -L $link ] ; then
            ln -s $extpath $link
	    fi
	done
elif [ "$action" = "remove" ] ; then
	# Remove any symlinks we've created into any mozilla directory
	for d in $basedir/${appname}*; do
	    if [ "$d" = "$basedir/${appname}*" ] ; then
            continue
	    fi
	    link=$d/extensions/$extname
	    if [ -L $link ] ; then
            rm $link
	    fi
	done
else
    usage
fi

exit 0

thunderbird-0.7.3-gnome-uriloader.patch:

--- NEW FILE thunderbird-0.7.3-gnome-uriloader.patch ---
--- mozilla/uriloader/exthandler/unix/nsGNOMERegistry.cpp.foo	2004-01-05 18:38:48.000000000 -0500
+++ mozilla/uriloader/exthandler/unix/nsGNOMERegistry.cpp	2004-01-05 19:14:51.000000000 -0500
@@ -39,6 +39,7 @@
 #include "nsGNOMERegistry.h"
 #include "prlink.h"
 #include "prmem.h"
+#include "prenv.h"
 #include "nsString.h"
 #include "nsIComponentManager.h"
 #include "nsILocalFile.h"
@@ -137,6 +138,10 @@
     } \
     PR_END_MACRO
 
+  // Don't even use this code if an env var is set
+  if (PR_GetEnv("MOZ_DISABLE_GNOME"))
+    return;
+
   // Attempt to open libgconf
   gconfLib = LoadVersionedLibrary("gconf-2", ".4");
   ENSURE_LIB(gconfLib);

thunderbird-0.7.3-psfonts.patch:

--- NEW FILE thunderbird-0.7.3-psfonts.patch ---
--- mozilla/modules/libpref/src/init/all.js.foo	2004-06-18 13:16:32.000000000 -0400
+++ mozilla/modules/libpref/src/init/all.js	2004-06-18 13:17:28.000000000 -0400
@@ -1776,8 +1776,10 @@
 pref("print.postscript.nativefont.ar",             "");
 pref("print.postscript.nativefont.el",             "");
 pref("print.postscript.nativefont.he",             "");
-pref("print.postscript.nativefont.ja",             "");
-pref("print.postscript.nativefont.ko",             "");
+pref("print.postscript.nativecode.ja",             "euc-jp");
+pref("print.postscript.nativefont.ja",             "Ryumin-Light-EUC-H");
+pref("print.postscript.nativecode.ko",             "euc-kr");
+pref("print.postscript.nativefont.ko",             "Baekmuk-Gulim-KSC-EUC-H");
 pref("print.postscript.nativefont.th",             "");
 pref("print.postscript.nativefont.tr",             "");
 pref("print.postscript.nativefont.x-baltic",       "");
@@ -1786,8 +1788,10 @@
 pref("print.postscript.nativefont.x-unicode",      "");
 pref("print.postscript.nativefont.x-user-def",     "");
 pref("print.postscript.nativefont.x-western",      "");
-pref("print.postscript.nativefont.zh-CN",          "");
-pref("print.postscript.nativefont.zh-TW",          "");
+pref("print.postscript.nativecode.zh-CN", "gb18030");
+pref("print.postscript.nativefont.zh-CN", "MSungGBK-Light-GBK2K-H");
+pref("print.postscript.nativecode.zh-TW", "big5");
+pref("print.postscript.nativefont.zh-TW", "ShanHeiSun-Light-B5-H");
 pref("print.postscript.nativefont.zh-HK",          "");
 
 # XP_UNIX

thunderbird-1.5-profile-migrator.patch:

--- NEW FILE thunderbird-1.5-profile-migrator.patch ---
Index: mozilla/mail/components/migration/src/nsProfileMigrator.cpp
===================================================================
RCS file: /cvsroot/mozilla/mail/components/migration/src/nsProfileMigrator.cpp,v
retrieving revision 1.9
diff -pu -r1.9 mozilla/mail/components/migration/src/nsProfileMigrator.cpp
--- mozilla/mail/components/migration/src/nsProfileMigrator.cpp
+++ mozilla/mail/components/migration/src/nsProfileMigrator.cpp
@@ -131,24 +131,55 @@ nsProfileMigrator::GetDefaultMailMigrato
 
   // if we are being forced to migrate to a particular migration type, then create an instance of that migrator
   // and return it.
+  NS_NAMED_LITERAL_CSTRING(migratorPrefix,
+                           NS_MAILPROFILEMIGRATOR_CONTRACTID_PREFIX);
+  nsCAutoString migratorID;
   if (forceMigrationType.get())
   {
     PRBool exists = PR_FALSE;
-    nsCAutoString migratorID (NS_MAILPROFILEMIGRATOR_CONTRACTID_PREFIX);
+    migratorID = migratorPrefix;
     migratorID.Append(forceMigrationType);
     mailMigrator = do_CreateInstance(migratorID.get());
-  
-    if (mailMigrator)
+    if (!mailMigrator)
+      return NS_ERROR_NOT_AVAILABLE;
+
+    mailMigrator->GetSourceExists(&exists);
+    /* trying to force migration on a source which doesn't
+     * have any profiles.
+     */
+    if (!exists)
+      return NS_ERROR_NOT_AVAILABLE;
+    aKey = forceMigrationType;
+    return NS_OK;
+  }
+
+  #define MAX_SOURCE_LENGTH 10
+  const char sources[][MAX_SOURCE_LENGTH] = {
+    "seamonkey",
+    "oexpress",
+    "outlook",
+    "dogbert",
+    "eudora",
+    0
+  };
+  for (PRUint32 i = 0; sources[i]; ++i)
+  {
+    migratorID = migratorPrefix;
+    migratorID.Append(sources[i]);
+    mailMigrator = do_CreateInstance(migratorID.get());
+    if (!mailMigrator)
+      continue;
+
+    PRBool exists = PR_FALSE;
+    mailMigrator->GetSourceExists(&exists);
+    if (exists)
     {
-      mailMigrator->GetSourceExists(&exists);
-      if (exists) 
-        aKey = forceMigrationType;
-      else
-        rv = NS_ERROR_FAILURE; // trying to force migration on a source which does not have any profiles
+      mailMigrator = nsnull;
+      return NS_OK;
     }
   }
  
-  return rv;
+  return NS_ERROR_NOT_AVAILABLE;
 }
 
 NS_IMETHODIMP


thunderbird-2.0-default-applications.patch:

--- NEW FILE thunderbird-2.0-default-applications.patch ---
Index: mozilla/mail/components/shell/nsMailGNOMEIntegration.cpp
===================================================================
RCS file: /cvsroot/mozilla/mail/components/shell/nsMailGNOMEIntegration.cpp,v
retrieving revision 1.8.2.1
diff -d -u -p -r1.8.2.1 nsMailGNOMEIntegration.cpp
--- mozilla/mail/components/shell/nsMailGNOMEIntegration.cpp	23 Oct 2006 03:32:47 -0000	1.8.2.1
+++ mozilla/mail/components/shell/nsMailGNOMEIntegration.cpp	11 Apr 2007 18:50:02 -0000
@@ -69,7 +69,7 @@ static const char* const sFeedProtocols[
   "feed"
 };
 
-nsMailGNOMEIntegration::nsMailGNOMEIntegration(): mCheckedThisSession(PR_FALSE)
+nsMailGNOMEIntegration::nsMailGNOMEIntegration(): mCheckedThisSession(PR_TRUE)
 {}
 
 nsresult
Index: mozilla/mail/components/preferences/general.xul
===================================================================
RCS file: /cvsroot/mozilla/mail/components/preferences/general.xul,v
retrieving revision 1.4.2.9
diff -d -u -p -r1.4.2.9 general.xul
--- mozilla/mail/components/preferences/general.xul	18 Feb 2007 20:26:46 -0000	1.4.2.9
+++ mozilla/mail/components/preferences/general.xul	13 Apr 2007 19:34:19 -0000
@@ -70,7 +70,7 @@
 
     <stringbundle id="bundlePreferences" src="chrome://messenger/locale/preferences/preferences.properties"/>
 
-#ifdef HAVE_SHELL_SERVICE
+#ifdef 0
     <stringbundle id="bundleShell" src="chrome://messenger/locale/shellservice.properties"/>
     <stringbundle id="bundleBrand" src="chrome://branding/locale/brand.properties"/>
     

thunderbird-2.0-enable-debug.patch:

--- NEW FILE thunderbird-2.0-enable-debug.patch ---
diff -up mozilla/mail/app/Makefile.in.old mozilla/mail/app/Makefile.in
--- mozilla/mail/app/Makefile.in.old	2007-02-28 07:52:59.000000000 +0100
+++ mozilla/mail/app/Makefile.in	2007-09-26 16:53:51.000000000 +0200
@@ -257,7 +257,7 @@ libs:: thunderbird
 	$(INSTALL) $< $(DIST)/bin
 
 install:: thunderbird
-	$(SYSINSTALL) $< $(DESTDIR)$(bindir)
+	$(SYSINSTALL) $< $(DESTDIR)$(mozappdir)
 
 GARBAGE += thunderbird
 GARBAGE += $(addprefix $(DIST)/bin/defaults/pref/, all.js all-thunderbird.js channel-prefs.js mailnews.js)

thunderbird-2.0.0.4-suse-visibility.patch:

--- NEW FILE thunderbird-2.0.0.4-suse-visibility.patch ---
--- configure.orig	2007-06-07 15:53:57.000000000 +0200
+++ configure	2007-06-07 15:55:00.000000000 +0200
@@ -7949,7 +7949,7 @@
                       if ${CC-cc} -Werror -S conftest.c -o conftest.s >/dev/null 2>&1; then
                         if egrep '\.(hidden|extern_private).*foo_hidden' conftest.s >/dev/null; then
                           if ! egrep '\.(hidden|extern_private).*foo_default' conftest.s > /dev/null; then
-                            ac_cv_visibility_pragma=yes
+                            ac_cv_visibility_pragma=no
                           fi
                         fi
                       fi


--- NEW FILE thunderbird-enigmail.spec ---
%define desktop_file_utils_version 0.9
%define nspr_version 4.6
%define nss_version 3.10
%define cairo_version 1.0

%define official_branding 1

%define thunver    2.0.0.21

Summary:        Authentication and encryption extension for Mozilla Thunderbird
Name:           thunderbird-enigmail
Version:        0.95.7
Release:        1%{?dist}
URL:            http://enigmail.mozdev.org/
License:        MPLv1.1 or GPLv2+
Group:          Applications/Internet
Source0:        http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/%{thunver}/source/thunderbird-%{thunver}-source.tar.bz2
Source10:       thunderbird-mozconfig
Source11:       thunderbird-mozconfig-branded

# ===== Enigmail files =====
Source100:  http://www.mozilla-enigmail.org/downloads/src/enigmail-%{version}.tar.gz

# From sunbird.src.rpm
Source102: mozilla-extension-update.sh


# Build patches
Patch1:         firefox-2.0-link-layout.patch
Patch2:         firefox-1.0-prdtoa.patch

Patch10:        thunderbird-0.7.3-psfonts.patch
Patch11:        thunderbird-0.7.3-gnome-uriloader.patch

# customization patches
Patch24:        thunderbird-2.0-default-applications.patch

# local bugfixes
Patch40:        firefox-1.5-bullet-bill.patch
Patch41:        firefox-2.0.0.4-undo-uriloader.patch
Patch42:        firefox-1.1-uriloader.patch

# font system fixes
Patch83:        firefox-1.5-pango-cursor-position.patch
Patch84:        firefox-2.0-pango-printing.patch
Patch85:        firefox-1.5-pango-cursor-position-more.patch
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
Patch103:       thunderbird-1.5-profile-migrator.patch
Patch111:       thunderbird-path.patch
Patch112:       thunderbird-2.0-enable-debug.patch

# Specific enigmail, to avoid : hidden symbol NS_NewGenericModule2
Patch200:       thunderbird-2.0.0.4-suse-visibility.patch

%if %{official_branding}
# Required by Mozilla Corporation


%else
# Not yet approved by Mozillla Corporation


%endif

BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
Requires:       nspr >= %{nspr_version}
Requires:       nss >= %{nss_version}
%if 0%{?rhel} >= 5
Requires:       launchmail
%endif
BuildRequires:  cairo-devel >= %{cairo_version}
BuildRequires:  libpng-devel, libjpeg-devel, gtk2-devel
BuildRequires:  zlib-devel, gzip, zip, unzip
BuildRequires:  nspr-devel >= %{nspr_version}
BuildRequires:  nss-devel >= %{nss_version}
BuildRequires:  libIDL-devel
BuildRequires:  desktop-file-utils
BuildRequires:  freetype-devel
BuildRequires:  libXt-devel
BuildRequires:  libXrender-devel

Requires:       gnupg, thunderbird = %{thunver}

%define mozappdir %{_libdir}/thunderbird-%{thunver}

# Without this enigmmail will require libxpcom.so and other .so  
# which are not provided by thunderbird (to avoid mistake, 
# because provided by xulrunner). 
AutoReq:  0
# All others deps already required by thunderbird
Requires: gnupg, thunderbird >= %{thunver}

# Nothing usefull provided
AutoProv: 0

%global enigmail_extname '{847b3a00-7ab1-11d4-8f02-006008948af5}'
%global tbupdate                                          \\\
        %{_libdir}/%{name}/mozilla-extension-update.sh    \\\
        --appname thunderbird                             \\\
        --extname %{enigmail_extname}                     \\\
        --basedir %{_libdir}                              \\\
        --extpath %{_libdir}/%{name}                      \\\
        --action 


%description
Enigmail is an extension to the mail client Mozilla Thunderbird
which allows users to access the authentication and encryption
features provided by GnuPG 

#===============================================================================

%prep
%setup -q -c
cd mozilla

%patch1 -p1 -b .link-layout
%patch2 -p0

# to avoid : hidden symbol NS_NewGenericModule2
%patch200 -p0 -b .visibility

%patch10 -p1 -b .psfonts
%patch11 -p1 -b .gnome-uriloader
%patch24 -p1 -b .default-applications
%patch40 -p1
%patch41 -p1
%patch42 -p0
# font system fixes
%patch83 -p1 -b .pango-cursor-position
%patch84 -p0 -b .pango-printing
%patch85 -p1 -b .pango-cursor-position-more
%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 .
  ln -s ../gtk/nsFontMetricsPango.cpp .
  ln -s ../gtk/mozilla-decoder.h .
  ln -s ../gtk/mozilla-decoder.cpp .
popd


%patch102 -p0 -b .theme-change
%patch103 -p1 -b .profile-migrator
%patch111 -p1 -b .path
%patch112 -p1 -b .debug

%if %{official_branding}
# Required by Mozilla Corporation


%else
# Not yet approved by Mozillla Corporation


%endif



%{__rm} -f .mozconfig
%{__cp} %{SOURCE10} .mozconfig
%if %{official_branding}
%{__cat} %{SOURCE11} >> .mozconfig
%endif

# ===== Enigmail work =====
tar xzf %{SOURCE100}
mv enigmail mailnews/extensions/

#===============================================================================

%build
cd mozilla

# Build with -Os as it helps the browser; also, don't override mozilla's warning
# level; they use -Wall but disable a few warnings that show up _everywhere_
MOZ_OPT_FLAGS=$(echo $RPM_OPT_FLAGS | %{__sed} -e 's/-O2/-Os/' -e 's/-Wall//')

export RPM_OPT_FLAGS=$MOZ_OPT_FLAGS
export PREFIX='%{_prefix}'
export LIBDIR='%{_libdir}'

%ifarch ppc ppc64 s390 s390x
%define moz_make_flags -j1
%else
%define moz_make_flags %{?_smp_mflags}
%endif

export LDFLAGS="-Wl,-rpath,%{mozappdir}"
export MAKE="gmake %{moz_make_flags}"
# make -f client.mk build
make -f client.mk export
pushd modules/libreg
make
cd ../../xpcom/string
make
cd ..
make
cd obsolete
make
popd

# ===== Enigmail work =====
pushd mailnews/extensions/enigmail
./makemake -r
make
make xpi
popd


#===============================================================================

%install
%{__rm} -rf $RPM_BUILD_ROOT

%{__mkdir_p} $RPM_BUILD_ROOT%{_libdir}

%{__unzip} -q mozilla/dist/bin/enigmail-%{version}-linux-*.xpi -d $RPM_BUILD_ROOT%{_libdir}/%{name}
%{__install} -p -m 755 %{SOURCE102} $RPM_BUILD_ROOT%{_libdir}/%{name}/mozilla-extension-update.sh



%clean
%{__rm} -rf $RPM_BUILD_ROOT


%post
%{tbupdate} install || :


%preun
if [ $1 = 0 ]; then
    %{tbupdate} remove || :
fi

%postun
# This is needed not to reverse the effect of our preun, which
# is guarded against upgrade, but because of our triggerun,
# which is run on self-upgrade, though triggerpostun isn't
if [ $1 != 0 ]; then
    %{tbupdate} install || :
fi

%triggerin -- thunderbird
%{tbupdate} install || :

%triggerun -- thunderbird
%{tbupdate} remove || :

%triggerpostun -- thunderbird
# Guard against being run post-self-uninstall, even though that
# doesn't happen currently (see comment above)
if [ $1 != 0 ]; then
    %{tbupdate} install || :
fi


%files
%defattr(-,root,root,-)
%{_libdir}/%{name}


#===============================================================================

%changelog
* Sat May 23 2009 Remi Collet <rpms at famillecollet.com> 0.95.7-1
- Initial rpmfusion RPM



--- NEW FILE thunderbird-mozconfig ---
mk_add_options MOZ_CO_PROJECT=mail
ac_add_options --enable-application=mail
mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/objdir-tb/
mk_add_options AUTOCONF=autoconf-2.13

#ac_add_options --with-system-png

ac_add_options --prefix="$PREFIX"
ac_add_options --libdir="$LIBDIR"
ac_add_options --with-system-nspr
ac_add_options --with-system-nss
ac_add_options --with-system-jpeg
ac_add_options --with-system-zlib
ac_add_options --with-pthreads
ac_add_options --disable-tests
ac_add_options --disable-debug
ac_add_options --disable-installer
ac_add_options --enable-optimize="$RPM_OPT_FLAGS"
ac_add_options --enable-xinerama
ac_add_options --enable-default-toolkit=cairo-gtk2
ac_add_options --disable-xprint
ac_add_options --disable-strip
ac_add_options --disable-install-strip
ac_add_options --enable-pango
ac_add_options --enable-system-cairo
ac_add_options --enable-svg
ac_add_options --enable-canvas
ac_add_options --disable-crashreporter

export BUILD_OFFICIAL=1
export MOZILLA_OFFICIAL=1
mk_add_options BUILD_OFFICIAL=1
mk_add_options MOZILLA_OFFICIAL=1



--- NEW FILE thunderbird-mozconfig-branded ---
ac_add_options --enable-official-branding

thunderbird-path.patch:

--- NEW FILE thunderbird-path.patch ---
--- mozilla/toolkit/xre/nsAppRunner.h.old	2007-09-25 18:01:56.000000000 +0200
+++ mozilla/toolkit/xre/nsAppRunner.h	2007-09-25 18:02:23.000000000 +0200
@@ -48,7 +48,8 @@
 #elif defined(CCHMAXPATH)
 #define MAXPATHLEN CCHMAXPATH
 #else
-#define MAXPATHLEN 1024
+#include <limits.h>
+#define MAXPATHLEN PATH_MAX
 #endif
 #endif
 
diff -up mozilla/toolkit/mozapps/update/src/updater/updater.cpp.old mozilla/toolkit/mozapps/update/src/updater/updater.cpp
--- mozilla/toolkit/mozapps/update/src/updater/updater.cpp.old	2007-09-25 18:00:26.000000000 +0200
+++ mozilla/toolkit/mozapps/update/src/updater/updater.cpp	2007-09-25 18:00:53.000000000 +0200
@@ -107,7 +107,8 @@ void LaunchChild(int argc, char **argv);
 # elif defined(CCHMAXPATH)
 #  define MAXPATHLEN CCHMAXPATH
 # else
-#  define MAXPATHLEN 1024
+#  include <limits.h>
+#  define MAXPATHLEN PATH_MAX
 # endif
 #endif
 
diff -up mozilla/mailnews/import/comm4x/src/nsComm4xProfile.cpp.old mozilla/mailnews/import/comm4x/src/nsComm4xProfile.cpp
--- mozilla/mailnews/import/comm4x/src/nsComm4xProfile.cpp.old	2007-09-25 17:58:43.000000000 +0200
+++ mozilla/mailnews/import/comm4x/src/nsComm4xProfile.cpp	2007-09-25 17:59:22.000000000 +0200
@@ -70,7 +70,8 @@
 #elif defined(CCHMAXPATH)
 #define MAXPATHLEN CCHMAXPATH
 #else
-#define MAXPATHLEN 1024
+#include <limits.h>
+#define MAXPATHLEN PATH_MAX
 #endif
 #endif
 
diff -up mozilla/xpcom/io/SpecialSystemDirectory.cpp.old mozilla/xpcom/io/SpecialSystemDirectory.cpp
--- mozilla/xpcom/io/SpecialSystemDirectory.cpp.old	2007-09-25 18:04:25.000000000 +0200
+++ mozilla/xpcom/io/SpecialSystemDirectory.cpp	2007-09-25 18:04:48.000000000 +0200
@@ -109,7 +109,8 @@
 #elif defined(CCHMAXPATH)
 #define MAXPATHLEN CCHMAXPATH
 #else
-#define MAXPATHLEN 1024
+#include <limits.h>
+#define MAXPATHLEN PATH_MAX
 #endif
 #endif
 
diff -up mozilla/xpcom/obsolete/nsFileSpecUnix.cpp.old mozilla/xpcom/obsolete/nsFileSpecUnix.cpp
--- mozilla/xpcom/obsolete/nsFileSpecUnix.cpp.old	2006-11-28 01:18:37.000000000 +0100
+++ mozilla/xpcom/obsolete/nsFileSpecUnix.cpp	2007-09-25 18:05:49.000000000 +0200
@@ -79,7 +79,8 @@
 #endif
 
 #ifndef MAXPATHLEN
-#define MAXPATHLEN	1024  /* Guessing this is okay.  Works for SCO. */
+#include <limits.h>
+#define MAXPATHLEN	PATH_MAX  /* Guessing this is okay.  Works for SCO. */
 #endif
  
 #if defined(__QNX__)
diff -up mozilla/xpcom/build/nsXPCOMPrivate.h.old mozilla/xpcom/build/nsXPCOMPrivate.h
--- mozilla/xpcom/build/nsXPCOMPrivate.h.old	2007-09-25 18:02:58.000000000 +0200
+++ mozilla/xpcom/build/nsXPCOMPrivate.h	2007-09-25 18:03:15.000000000 +0200
@@ -252,7 +252,8 @@ NS_GetFrozenFunctions(XPCOMFunctions *en
 #elif defined(CCHMAXPATH)
 #define MAXPATHLEN CCHMAXPATH
 #else
-#define MAXPATHLEN 1024
+#include <limits.h>
+#define MAXPATHLEN PATH_MAX
 #endif
 #endif
 
diff -up mozilla/dbm/include/mcom_db.h.old mozilla/dbm/include/mcom_db.h
--- mozilla/dbm/include/mcom_db.h.old	2007-09-25 17:57:09.000000000 +0200
+++ mozilla/dbm/include/mcom_db.h	2007-09-25 17:57:49.000000000 +0200
@@ -214,7 +214,8 @@
 #endif  /* __DBINTERFACE_PRIVATE */
 
 #ifdef SCO
-#define MAXPATHLEN 	1024              
+#include <limits.h>
+#define MAXPATHLEN 	PATH_MAX     
 #endif
 
 #include <fcntl.h>
diff -up mozilla/mail/components/migration/src/nsProfileMigrator.cpp.old mozilla/mail/components/migration/src/nsProfileMigrator.cpp
--- mozilla/mail/components/migration/src/nsProfileMigrator.cpp.old	2007-09-25 17:55:11.000000000 +0200
+++ mozilla/mail/components/migration/src/nsProfileMigrator.cpp	2007-09-25 18:07:56.000000000 +0200
@@ -73,7 +73,8 @@
 #elif defined(CCHMAXPATH)
 #define MAXPATHLEN CCHMAXPATH
 #else
-#define MAXPATHLEN 1024
+#include <limits.h>
+#define MAXPATHLEN PATH_MAX
 #endif
 #endif
 
diff -up mozilla/nsprpub/config/nsinstall.c.old mozilla/nsprpub/config/nsinstall.c
diff -up mozilla/js/src/jsfile.c.old mozilla/js/src/jsfile.c
--- mozilla/js/src/jsfile.c.old	2006-07-26 20:55:08.000000000 +0200
+++ mozilla/js/src/jsfile.c	2007-09-25 18:22:52.000000000 +0200
@@ -105,7 +105,8 @@
 #define utfstring               "binary"
 #define unicodestring           "unicode"
 
-#define MAX_PATH_LENGTH         1024
+#include <limits.h>
+#define MAX_PATH_LENGTH         PATH_MAX
 #define MODE_SIZE               256
 #define NUMBER_SIZE             32
 #define MAX_LINE_LENGTH         256
diff -up mozilla/webshell/tests/viewer/nsViewerApp.cpp.old mozilla/webshell/tests/viewer/nsViewerApp.cpp
--- mozilla/webshell/tests/viewer/nsViewerApp.cpp.old	2007-09-25 18:34:51.000000000 +0200
+++ mozilla/webshell/tests/viewer/nsViewerApp.cpp	2007-09-25 18:35:33.000000000 +0200
@@ -692,7 +692,8 @@ nsViewerApp::OpenWindow(PRUint32 aNewChr
 
 #if !defined(XP_WIN) && !defined(XP_OS2)
 #ifndef XP_MAC
-#define _MAX_PATH 512
+#include <limits.h>
+#define _MAX_PATH PATH_MAX
 #endif
 #endif
 
diff -up mozilla/xpcom/typelib/xpidl/xpidl_java.c.old mozilla/xpcom/typelib/xpidl/xpidl_java.c
--- mozilla/xpcom/typelib/xpidl/xpidl_java.c.old	2007-09-25 18:38:52.000000000 +0200
+++ mozilla/xpcom/typelib/xpidl/xpidl_java.c	2007-09-25 18:39:17.000000000 +0200
@@ -44,6 +44,7 @@
 #include "xpidl.h"
 #include <ctype.h>
 #include <glib.h>
+#include <limits.h>
 
 #ifdef XP_WIN
 #include <windef.h>
diff -up mozilla/widget/src/xremoteclient/XRemoteClient.cpp.old mozilla/widget/src/xremoteclient/XRemoteClient.cpp
--- mozilla/widget/src/xremoteclient/XRemoteClient.cpp.old	2007-09-25 18:14:08.000000000 +0200
+++ mozilla/widget/src/xremoteclient/XRemoteClient.cpp	2007-09-25 18:36:55.000000000 +0200
@@ -76,7 +76,8 @@
 #endif
     
 #ifndef MAX_PATH
-#define MAX_PATH 1024
+#include <limits.h>
+#define MAX_PATH PATH_MAX
 #endif
 
 #define ARRAY_LENGTH(array_) (sizeof(array_)/sizeof(array_[0]))
diff -up mozilla/modules/libreg/src/reg.c.old mozilla/modules/libreg/src/reg.c
--- mozilla/modules/libreg/src/reg.c.old	2007-09-25 18:25:02.000000000 +0200
+++ mozilla/modules/libreg/src/reg.c	2007-09-25 18:27:46.000000000 +0200
@@ -96,7 +96,8 @@
 #define MAX_PATH PATH_MAX
 #elif defined(XP_UNIX)
 #ifndef MAX_PATH
-#define MAX_PATH 1024
+#include <limits.h>
+#define MAX_PATH PATH_MAX
 #endif
 #elif defined(XP_OS2)
 #ifndef MAX_PATH
diff -up mozilla/directory/c-sdk/config/pathsub.h.old mozilla/directory/c-sdk/config/pathsub.h
--- mozilla/directory/c-sdk/config/pathsub.h.old	2006-02-03 15:41:18.000000000 +0100
+++ mozilla/directory/c-sdk/config/pathsub.h	2007-09-25 18:48:58.000000000 +0200
@@ -50,7 +50,7 @@
 #endif
 
 #ifndef PATH_MAX
-#define PATH_MAX 1024
+#error  "PATH_MAX is not defined!"
 #endif
 
 /*
diff -up mozilla/config/pathsub.h.old mozilla/config/pathsub.h
--- mozilla/config/pathsub.h.old	2004-04-18 16:17:25.000000000 +0200
+++ mozilla/config/pathsub.h	2007-09-25 18:48:13.000000000 +0200
@@ -46,7 +46,7 @@
 #include <sys/types.h>
 
 #ifndef PATH_MAX
-#define PATH_MAX 1024
+#error  "PATH_MAX is not defined!"
 #endif
 
 /*
diff -up mozilla/modules/libjar/nsZipArchive.cpp.old mozilla/modules/libjar/nsZipArchive.cpp
--- mozilla/modules/libjar/nsZipArchive.cpp.old	2006-09-13 20:32:37.000000000 +0200
+++ mozilla/modules/libjar/nsZipArchive.cpp	2007-09-25 18:51:00.000000000 +0200
@@ -121,7 +121,7 @@ char * strdup(const char *src)
 #    define S_IFLNK  0120000
 #  endif
 #  ifndef PATH_MAX
-#    define PATH_MAX 1024
+#    include <limits.h>
 #  endif
 #endif  /* XP_UNIX */
 
diff -up mozilla/nsprpub/config/pathsub.h.old mozilla/nsprpub/config/pathsub.h
--- mozilla/nsprpub/config/pathsub.h.old	2004-04-25 17:00:34.000000000 +0200
+++ mozilla/nsprpub/config/pathsub.h	2007-09-25 18:57:51.000000000 +0200
@@ -50,7 +50,7 @@
 #endif
 
 #ifndef PATH_MAX
-#define PATH_MAX 1024
+#error  "PATH_MAX is not defined!"
 #endif
 
 /*
diff -up mozilla/gfx/src/gtk/nsPrintdGTK.h.old mozilla/gfx/src/gtk/nsPrintdGTK.h
--- mozilla/gfx/src/gtk/nsPrintdGTK.h.old	2004-04-17 23:52:29.000000000 +0200
+++ mozilla/gfx/src/gtk/nsPrintdGTK.h	2007-09-25 18:56:48.000000000 +0200
@@ -63,7 +63,7 @@ PR_BEGIN_EXTERN_C
 #ifdef _POSIX_PATH_MAX
 #define PATH_MAX	_POSIX_PATH_MAX
 #else
-#define PATH_MAX	256
+#error "PATH_MAX is not defined!"
 #endif
 #endif
 
diff -up mozilla/security/coreconf/nsinstall/pathsub.h.old mozilla/security/coreconf/nsinstall/pathsub.h
--- mozilla/security/coreconf/nsinstall/pathsub.h.old	2004-04-25 17:02:18.000000000 +0200
+++ mozilla/security/coreconf/nsinstall/pathsub.h	2007-09-25 19:00:35.000000000 +0200
@@ -49,7 +49,7 @@
 #endif
 
 #ifndef PATH_MAX
-#define PATH_MAX 1024
+#error  "PATH_MAX is not defined!"
 #endif
 
 /*


Index: .cvsignore
===================================================================
RCS file: /cvs/free/rpms/thunderbird-enigmail/F-10/.cvsignore,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- .cvsignore	22 May 2009 17:02:37 -0000	1.1
+++ .cvsignore	23 May 2009 07:36:17 -0000	1.2
@@ -0,0 +1,2 @@
+enigmail-0.95.7.tar.gz
+thunderbird-2.0.0.21-source.tar.bz2


Index: sources
===================================================================
RCS file: /cvs/free/rpms/thunderbird-enigmail/F-10/sources,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- sources	22 May 2009 17:02:37 -0000	1.1
+++ sources	23 May 2009 07:36:17 -0000	1.2
@@ -0,0 +1,2 @@
+bbee59bab58b97e33e85015a5ae5de7b  enigmail-0.95.7.tar.gz
+55e24753a7ccf2fbf0272987dd4bb086  thunderbird-2.0.0.21-source.tar.bz2



More information about the rpmfusion-commits mailing list