Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 46691 Details for
Bug 75404
Pango Support in Firefox/Mozilla - Ebuild Attached
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
mozilla-1.7.3-pango-render.patch
mozilla-1.7.3-pango-render.patch (text/plain), 98.72 KB, created by
Gautham Arumilli
on 2004-12-22 23:05:11 UTC
(
hide
)
Description:
mozilla-1.7.3-pango-render.patch
Filename:
MIME Type:
Creator:
Gautham Arumilli
Created:
2004-12-22 23:05:11 UTC
Size:
98.72 KB
patch
obsolete
>--- mozilla/config/autoconf.mk.in.foo 2004-03-20 21:31:17.000000000 -0500 >+++ mozilla/config/autoconf.mk.in 2004-10-18 22:49:40.000000000 -0400 >@@ -376,6 +376,10 @@ > MOZ_XFT_LIBS = @MOZ_XFT_LIBS@ > MOZ_ENABLE_COREXFONTS = @MOZ_ENABLE_COREXFONTS@ > >+MOZ_ENABLE_PANGO = @MOZ_ENABLE_PANGO@ >+MOZ_PANGO_CFLAGS = @MOZ_PANGO_CFLAGS@ >+MOZ_PANGO_LIBS = @MOZ_PANGO_LIBS@ >+ > MOZ_EXTRA_X11CONVERTERS = @MOZ_EXTRA_X11CONVERTERS@ > > MOZ_ENABLE_XINERAMA = @MOZ_ENABLE_XINERAMA@ >--- mozilla/gfx/src/gtk/nsGfxFactoryGTK.cpp.foo 2003-09-07 18:20:38.000000000 -0400 >+++ mozilla/gfx/src/gtk/nsGfxFactoryGTK.cpp 2004-10-18 22:49:40.000000000 -0400 >@@ -62,6 +62,9 @@ > #ifdef NATIVE_THEME_SUPPORT > #include "nsNativeThemeGTK.h" > #endif >+#ifdef MOZ_ENABLE_PANGO >+#include "nsFontMetricsPango.h" >+#endif > #ifdef MOZ_ENABLE_XFT > #include "nsFontMetricsXft.h" > #endif >@@ -112,6 +115,13 @@ > if (aOuter) > return NS_ERROR_NO_AGGREGATION; > >+#ifdef MOZ_ENABLE_PANGO >+ if (NS_IsPangoEnabled()) { >+ result = new nsFontMetricsPango(); >+ if (!result) >+ return NS_ERROR_OUT_OF_MEMORY; >+ } else { >+#endif > #ifdef MOZ_ENABLE_XFT > if (NS_IsXftEnabled()) { > result = new nsFontMetricsXft(); >@@ -127,6 +137,9 @@ > #ifdef MOZ_ENABLE_XFT > } > #endif >+#ifdef MOZ_ENABLE_PANGO >+ } >+#endif > > NS_ADDREF(result); > nsresult rv = result->QueryInterface(aIID, aResult); >@@ -148,6 +161,13 @@ > if (aOuter) > return NS_ERROR_NO_AGGREGATION; > >+#ifdef MOZ_ENABLE_PANGO >+ if (NS_IsPangoEnabled()) { >+ result = new nsFontEnumeratorPango(); >+ if (!result) >+ return NS_ERROR_OUT_OF_MEMORY; >+ } else { >+#endif > #ifdef MOZ_ENABLE_XFT > if (NS_IsXftEnabled()) { > result = new nsFontEnumeratorXft(); >@@ -163,6 +183,9 @@ > #ifdef MOZ_ENABLE_XFT > } > #endif >+#ifdef MOZ_ENABLE_PANGO >+ } >+#endif > > NS_ADDREF(result); > nsresult rv = result->QueryInterface(aIID, aResult); >--- /dev/null 2004-02-18 10:26:44.000000000 -0500 >+++ mozilla/gfx/src/gtk/mozilla-decoder.h 2004-10-18 22:49:40.000000000 -0400 >@@ -0,0 +1,72 @@ >+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ >+/* vim:expandtab:shiftwidth=4:tabstop=4: >+ */ >+/* ***** BEGIN LICENSE BLOCK ***** >+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 >+ * >+ * The contents of this file are subject to the Mozilla Public License Version >+ * 1.1 (the "License"); you may not use this file except in compliance with >+ * the License. You may obtain a copy of the License at >+ * http://www.mozilla.org/MPL/ >+ * >+ * Software distributed under the License is distributed on an "AS IS" basis, >+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License >+ * for the specific language governing rights and limitations under the >+ * License. >+ * >+ * The Original Code is mozilla.org code. >+ * >+ * The Initial Developer of the Original Code is Christopher Blizzard >+ * <blizzard@mozilla.org>. Portions created by the Initial Developer >+ * are Copyright (C) 2004 the Initial Developer. All Rights Reserved. >+ * >+ * Contributor(s): >+ * >+ * Alternatively, the contents of this file may be used under the terms of >+ * either the GNU General Public License Version 2 or later (the "GPL"), or >+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), >+ * in which case the provisions of the GPL or the LGPL are applicable instead >+ * of those above. If you wish to allow use of your version of this file only >+ * under the terms of either the GPL or the LGPL, and not to allow others to >+ * use your version of this file under the terms of the MPL, indicate your >+ * decision by deleting the provisions above and replace them with the notice >+ * and other provisions required by the GPL or the LGPL. If you do not delete >+ * the provisions above, a recipient may use your version of this file under >+ * the terms of any one of the MPL, the GPL or the LGPL. >+ * >+ * ***** END LICENSE BLOCK ***** */ >+ >+#ifndef _MOZILLA_DECODER_H >+#define _MOZILLA_DECODER_H >+ >+#include <pango/pangofc-decoder.h> >+ >+G_BEGIN_DECLS >+ >+#define MOZILLA_TYPE_DECODER (mozilla_decoder_get_type()) >+#define MOZILLA_DECODER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), MOZILLA_TYPE_DECODER, MozillaDecoder)) >+#define MOZILLA_IS_DECODER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), MOZILLA_TYPE_DECODER)) >+ >+typedef struct _MozillaDecoder MozillaDecoder; >+typedef struct _MozillaDecoderClass MozillaDecoderClass; >+ >+#define MOZILLA_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MOZILLA_TYPE_DECODER, MozillaDecoderClass)) >+#define MOZILLA_IS_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MOZILLA_TYPE_DECODER)) >+#define MOZILLA_DECODER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MOZILLA_TYPE_DECODER, MozillaDecoderClass)) >+ >+struct _MozillaDecoder >+{ >+ PangoFcDecoder parent_instance; >+}; >+ >+struct _MozillaDecoderClass >+{ >+ PangoFcDecoderClass parent_class; >+}; >+ >+GType mozilla_decoder_get_type (void); >+int mozilla_decoders_init (void); >+ >+G_END_DECLS >+ >+#endif /*_MOZILLA_DECODER_H */ >--- /dev/null 2004-02-18 10:26:44.000000000 -0500 >+++ mozilla/gfx/src/gtk/mozilla-decoder.cpp 2004-10-18 22:49:40.000000000 -0400 >@@ -0,0 +1,376 @@ >+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ >+/* vim:expandtab:shiftwidth=4:tabstop=4: >+ */ >+/* ***** BEGIN LICENSE BLOCK ***** >+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 >+ * >+ * The contents of this file are subject to the Mozilla Public License Version >+ * 1.1 (the "License"); you may not use this file except in compliance with >+ * the License. You may obtain a copy of the License at >+ * http://www.mozilla.org/MPL/ >+ * >+ * Software distributed under the License is distributed on an "AS IS" basis, >+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License >+ * for the specific language governing rights and limitations under the >+ * License. >+ * >+ * The Original Code is mozilla.org code. >+ * >+ * The Initial Developer of the Original Code is Christopher Blizzard >+ * <blizzard@mozilla.org>. Portions created by the Initial Developer >+ * are Copyright (C) 2004 the Initial Developer. All Rights Reserved. >+ * >+ * Contributor(s): >+ * >+ * Alternatively, the contents of this file may be used under the terms of >+ * either the GNU General Public License Version 2 or later (the "GPL"), or >+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), >+ * in which case the provisions of the GPL or the LGPL are applicable instead >+ * of those above. If you wish to allow use of your version of this file only >+ * under the terms of either the GPL or the LGPL, and not to allow others to >+ * use your version of this file under the terms of the MPL, indicate your >+ * decision by deleting the provisions above and replace them with the notice >+ * and other provisions required by the GPL or the LGPL. If you do not delete >+ * the provisions above, a recipient may use your version of this file under >+ * the terms of any one of the MPL, the GPL or the LGPL. >+ * >+ * ***** END LICENSE BLOCK ***** */ >+ >+#define PANGO_ENABLE_BACKEND >+#define PANGO_ENABLE_ENGINE >+ >+#include "mozilla-decoder.h" >+#include <pango/pangoxft.h> >+#include <pango/pangofc-fontmap.h> >+#include <pango/pangofc-font.h> >+#include <gdk/gdkx.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 (MozillaDecoder, mozilla_decoder, PANGO_TYPE_FC_DECODER) >+ >+MozillaDecoder *mozilla_decoder_new (void); >+ >+static FcCharSet *mozilla_decoder_get_charset (PangoFcDecoder *decoder, >+ PangoFcFont *fcfont); >+static PangoGlyph mozilla_decoder_get_glyph (PangoFcDecoder *decoder, >+ PangoFcFont *fcfont, >+ guint32 wc); >+ >+static PangoFcDecoder *mozilla_find_decoder (FcPattern *pattern, >+ gpointer user_data); >+ >+typedef struct _MozillaDecoderPrivate MozillaDecoderPrivate; >+ >+#define MOZILLA_DECODER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MOZILLA_TYPE_DECODER, MozillaDecoderPrivate)) >+ >+struct _MozillaDecoderPrivate { >+ char *family; >+ char *encoder; >+ char *cmap; >+ gboolean is_wide; >+ FcCharSet *charset; >+ nsCOMPtr<nsIUnicodeEncoder> uEncoder; >+}; >+ >+static nsICharsetConverterManager *gCharsetManager = NULL; >+ >+static NS_DEFINE_CID(kCharsetConverterManagerCID, >+ NS_ICHARSETCONVERTERMANAGER_CID); >+ >+// Hash tables that hold the custom encodings and custom cmaps used in >+// various fonts. >+GHashTable *encoder_hash = NULL; >+GHashTable *cmap_hash = NULL; >+GHashTable *wide_hash = NULL; >+ >+void >+mozilla_decoder_init (MozillaDecoder *decoder) >+{ >+} >+ >+void >+mozilla_decoder_class_init (MozillaDecoderClass *klass) >+{ >+ GObjectClass *object_class = G_OBJECT_CLASS(klass); >+ PangoFcDecoderClass *parent_class = PANGO_FC_DECODER_CLASS (klass); >+ >+ /* object_class->finalize = test_finalize; */ >+ >+ parent_class->get_charset = mozilla_decoder_get_charset; >+ parent_class->get_glyph = mozilla_decoder_get_glyph; >+ >+ g_type_class_add_private (object_class, sizeof (MozillaDecoderPrivate)); >+} >+ >+MozillaDecoder * >+mozilla_decoder_new(void) >+{ >+ return (MozillaDecoder *)g_object_new(MOZILLA_TYPE_DECODER, NULL); >+} >+ >+#ifdef DEBUG_CUSTOM_ENCODER >+void >+dump_hash(char *key, char *val, void *arg) >+{ >+ printf("%s -> %s\n", key, val); >+} >+#endif >+ >+/** >+ * mozilla_decoders_init: >+ * >+ * #mozilla_decoders_init: >+ * >+ * This initializes all of the application-specific custom decoders >+ * that Mozilla uses. This should only be called once during the >+ * lifetime of the application. >+ * >+ * Return value: zero on success, not zero on failure. >+ * >+ **/ >+ >+int >+mozilla_decoders_init(void) >+{ >+ static PRBool initialized = PR_FALSE; >+ if (initialized) >+ return 0; >+ >+ encoder_hash = g_hash_table_new(g_str_hash, g_str_equal); >+ cmap_hash = g_hash_table_new(g_str_hash, g_str_equal); >+ wide_hash = g_hash_table_new(g_str_hash, g_str_equal); >+ >+ PRBool dumb = PR_FALSE; >+ nsCOMPtr<nsIPersistentProperties> props; >+ nsCOMPtr<nsISimpleEnumerator> encodeEnum; >+ >+ NS_LoadPersistentPropertiesFromURISpec(getter_AddRefs(props), >+ NS_LITERAL_CSTRING("resource://gre/res/fonts/pangoFontEncoding.properties")); >+ >+ if (!props) >+ goto loser; >+ >+ // Enumerate the properties in this file and figure out all of the >+ // fonts for which we have custom encodings. >+ props->Enumerate(getter_AddRefs(encodeEnum)); >+ if (!encodeEnum) >+ goto loser; >+ >+ while (encodeEnum->HasMoreElements(&dumb), dumb) { >+ nsCOMPtr<nsIPropertyElement> prop; >+ encodeEnum->GetNext(getter_AddRefs(prop)); >+ if (!prop) >+ goto loser; >+ >+ nsCAutoString name; >+ prop->GetKey(name); >+ nsAutoString value; >+ prop->GetValue(value); >+ >+ if (!StringBeginsWith(name, NS_LITERAL_CSTRING("encoding."))) { >+ printf("string doesn't begin with encoding?\n"); >+ continue; >+ } >+ >+ name = Substring(name, 9); >+ >+ if (StringEndsWith(name, NS_LITERAL_CSTRING(".ttf"))) { >+ name = Substring(name, 0, name.Length() - 4); >+ >+ // Strip off a .wide if it's there. >+ if (StringEndsWith(value, NS_LITERAL_STRING(".wide"))) { >+ g_hash_table_insert(wide_hash, g_strdup(name.get()), >+ g_strdup("wide")); >+ value = Substring(value, 0, name.Length() - 5); >+ } >+ >+ g_hash_table_insert(encoder_hash, >+ g_strdup(name.get()), >+ g_strdup(NS_ConvertUTF16toUTF8(value).get())); >+ } >+ else if (StringEndsWith(name, NS_LITERAL_CSTRING(".ftcmap"))) { >+ name = Substring(name, 0, name.Length() - 7); >+ g_hash_table_insert(cmap_hash, >+ g_strdup(name.get()), >+ g_strdup(NS_ConvertUTF16toUTF8(value).get())); >+ } >+ else { >+ printf("unknown suffix used for mapping\n"); >+ } >+ } >+ >+ pango_fc_font_map_add_decoder_find_func(PANGO_FC_FONT_MAP(pango_xft_get_font_map(GDK_DISPLAY(),gdk_x11_get_default_screen())), >+ mozilla_find_decoder, >+ NULL, >+ NULL); >+ >+ initialized = PR_TRUE; >+ >+#ifdef DEBUG_CUSTOM_ENCODER >+ printf("*** encoders\n"); >+ g_hash_table_foreach(encoder_hash, (GHFunc)dump_hash, NULL); >+ >+ printf("*** cmaps\n"); >+ g_hash_table_foreach(cmap_hash, (GHFunc)dump_hash, NULL); >+#endif >+ >+ return 0; >+ >+ loser: >+ return -1; >+} >+ >+FcCharSet * >+mozilla_decoder_get_charset (PangoFcDecoder *decoder, >+ PangoFcFont *fcfont) >+{ >+ MozillaDecoderPrivate *priv = MOZILLA_DECODER_GET_PRIVATE(decoder); >+ >+ if (priv->charset) >+ return priv->charset; >+ >+ // First time this has been accessed. Populate the charset. >+ priv->charset = FcCharSetCreate(); >+ >+ if (!gCharsetManager) { >+ nsServiceManager::GetService(kCharsetConverterManagerCID, >+ NS_GET_IID(nsICharsetConverterManager), (nsISupports**)&gCharsetManager); >+ } >+ >+ nsCOMPtr<nsIUnicodeEncoder> encoder; >+ nsCOMPtr<nsICharRepresentable> represent; >+ >+ if (!gCharsetManager) >+ goto end; >+ >+ gCharsetManager->GetUnicodeEncoderRaw(priv->encoder, getter_AddRefs(encoder)); >+ if (!encoder) >+ goto end; >+ >+ encoder->SetOutputErrorBehavior(encoder->kOnError_Replace, nsnull, '?'); >+ >+ priv->uEncoder = encoder; >+ >+ represent = do_QueryInterface(encoder); >+ if (!represent) >+ goto end; >+ >+ PRUint32 map[UCS2_MAP_LEN]; >+ memset(map, 0, sizeof(map)); >+ >+ represent->FillInfo(map); >+ >+ for (int i = 0; i < NUM_UNICODE_CHARS; i++) { >+ if (IS_REPRESENTABLE(map, i)) >+ FcCharSetAddChar(priv->charset, i); >+ } >+ >+ end: >+ return priv->charset; >+} >+ >+PangoGlyph >+mozilla_decoder_get_glyph (PangoFcDecoder *decoder, >+ PangoFcFont *fcfont, >+ guint32 wc) >+{ >+ MozillaDecoderPrivate *priv = MOZILLA_DECODER_GET_PRIVATE(decoder); >+ >+ PangoGlyph retval = 0; >+ PRUnichar inchar = wc; >+ PRInt32 inlen = 1; >+ char outchar[2] = {0,0}; >+ PRInt32 outlen = 2; >+ >+ priv->uEncoder->Convert(&inchar, &inlen, outchar, &outlen); >+ if (outlen != 1) { >+ printf("Warning: mozilla_decoder_get_glyph doesn't support more than one character conversions.\n"); >+ return 0; >+ } >+ >+ FT_Face face = pango_fc_font_lock_face(fcfont); >+ >+#ifdef DEBUG_CUSTOM_ENCODER >+ char *filename; >+ FcPatternGetString(fcfont->font_pattern, FC_FILE, 0, (FcChar8 **)&filename); >+ printf("filename is %s\n", filename); >+#endif >+ >+ // Make sure to set the right charmap before trying to get the >+ // glyph >+ if (priv->cmap) { >+ if (!strcmp(priv->cmap, "mac_roman")) { >+ FT_Select_Charmap(face, ft_encoding_apple_roman); >+ } >+ else if (!strcmp(priv->cmap, "unicode")) { >+ FT_Select_Charmap(face, ft_encoding_unicode); >+ } >+ else { >+ printf("Warning: Invalid charmap entry for family %s\n", >+ priv->family); >+ } >+ } >+ >+ // Standard 8 bit to glyph translation >+ if (!priv->is_wide) { >+ FcChar32 blah = PRUint8(outchar[0]); >+ retval = FT_Get_Char_Index(face, blah); >+#ifdef DEBUG_CUSTOM_ENCODER >+ printf("wc 0x%x outchar[0] 0x%x index 0x%x retval 0x%x face %p\n", >+ wc, outchar[0], blah, retval, (void *)face); >+#endif >+ } >+ else { >+ printf("Warning: We don't support .wide fonts!\n"); >+ retval = 0; >+ } >+ >+ pango_fc_font_unlock_face(fcfont); >+ >+ return retval; >+} >+ >+PangoFcDecoder * >+mozilla_find_decoder (FcPattern *pattern, gpointer user_data) >+{ >+ // Compare the family name of the font that's been opened to see >+ // if we have a custom decoder. >+ const char *orig = NULL; >+ FcPatternGetString(pattern, FC_FAMILY, 0, (FcChar8 **)&orig); >+ >+ nsCAutoString family; >+ family.Assign(orig); >+ >+ family.StripWhitespace(); >+ ToLowerCase(family); >+ >+ char *encoder = (char *)g_hash_table_lookup(encoder_hash, family.get()); >+ if (!encoder) >+ return NULL; >+ >+ MozillaDecoder *decoder = mozilla_decoder_new(); >+ >+ MozillaDecoderPrivate *priv = MOZILLA_DECODER_GET_PRIVATE(decoder); >+ >+ priv->family = g_strdup(family.get()); >+ priv->encoder = g_strdup(encoder); >+ >+ char *cmap = (char *)g_hash_table_lookup(cmap_hash, family.get()); >+ if (cmap) >+ priv->cmap = g_strdup(cmap); >+ >+ char *wide = (char *)g_hash_table_lookup(wide_hash, family.get()); >+ if (wide) >+ priv->is_wide = TRUE; >+ >+ return PANGO_FC_DECODER(decoder); >+} >--- mozilla/gfx/src/gtk/gfxgtk.pkg.foo 2004-01-06 20:21:35.000000000 -0500 >+++ mozilla/gfx/src/gtk/gfxgtk.pkg 2004-10-18 22:49:40.000000000 -0400 >@@ -7,3 +7,6 @@ > #if MOZ_ENABLE_XFT > dist/bin/res/fonts/fontEncoding.properties > #endif >+#if MOZ_ENABLE_PANGO >+dist/bin/res/fonts/pangoFontEncoding.properties >+#endif >--- mozilla/gfx/src/gtk/nsFontMetricsXft.cpp.foo 2004-04-05 15:18:43.000000000 -0400 >+++ mozilla/gfx/src/gtk/nsFontMetricsXft.cpp 2004-10-18 22:49:40.000000000 -0400 >@@ -238,7 +238,7 @@ > > static int CalculateSlant (PRUint8 aStyle); > static int CalculateWeight (PRUint16 aWeight); >-static void AddLangGroup (FcPattern *aPattern, nsIAtom *aLangGroup); >+/* static */ void AddLangGroup (FcPattern *aPattern, nsIAtom *aLangGroup); > static void AddFFRE (FcPattern *aPattern, nsCString *aFamily, > PRBool aWeak); > static void FFREToFamily (nsACString &aFFREName, nsACString &oFamily); >@@ -449,7 +449,7 @@ > // Make sure that the pixel size is at least greater than zero > if (mPixelSize < 1) { > #ifdef DEBUG >- printf("*** Warning: nsFontMetricsXft was passed a pixel size of %d\n", >+ printf("*** Warning: nsFontMetricsXft was passed a pixel size of %f\n", > mPixelSize); > #endif > mPixelSize = 1; >@@ -474,6 +474,26 @@ > if (NS_FAILED(RealizeFont())) > return NS_ERROR_FAILURE; > >+#ifdef DEBUG_foo >+ printf("%i\n", mXHeight); >+ printf("%i\n", mSuperscriptOffset); >+ printf("%i\n", mSubscriptOffset); >+ printf("%i\n", mStrikeoutOffset); >+ printf("%i\n", mStrikeoutSize); >+ printf("%i\n", mUnderlineOffset); >+ printf("%i\n", mUnderlineSize); >+ printf("%i\n", mMaxHeight); >+ printf("%i\n", mLeading); >+ printf("%i\n", mEmHeight); >+ printf("%i\n", mEmAscent); >+ printf("%i\n", mEmDescent); >+ printf("%i\n", mMaxAscent); >+ printf("%i\n", mMaxDescent); >+ printf("%i\n", mMaxAdvance); >+ printf("%i\n", mSpaceWidth); >+ printf("%i\n", mAveCharWidth); >+#endif /* DEBUG_foo */ >+ > return NS_OK; > } > >@@ -530,6 +550,10 @@ > f = mDeviceContext->DevUnitsToAppUnits(); > aWidth = NSToCoordRound(glyphInfo.xOff * f); > >+#ifdef DEBUG_foo >+ printf("GetWidth (char *) %d\n", aWidth); >+#endif >+ > return NS_OK; > } > >@@ -553,6 +577,10 @@ > if (aFontID) > *aFontID = 0; > >+#ifdef DEBUG_foo >+ printf("GetWidth %d\n", aWidth); >+#endif >+ > return NS_OK; > } > >@@ -586,6 +614,11 @@ > if (nsnull != aFontID) > *aFontID = 0; > >+#ifdef DEBUG_foo >+ printf("GetTextDimensions %d %d %d\n", aDimensions.width, >+ aDimensions.ascent, aDimensions.descent); >+#endif >+ > return NS_OK; > } > >@@ -645,6 +678,10 @@ > nsAutoDrawSpecBuffer drawBuffer(data.draw, &data.color); > data.drawBuffer = &drawBuffer; > >+#ifdef DEBUG_foo >+ printf("DrawString (char *)\n"); >+#endif >+ > return EnumerateGlyphs(aString, aLength, > &nsFontMetricsXft::DrawStringCallback, &data); > } >@@ -675,6 +712,10 @@ > nsAutoDrawSpecBuffer drawBuffer(data.draw, &data.color); > data.drawBuffer = &drawBuffer; > >+#ifdef DEBUG_foo >+ printf("DrawString\n"); >+#endif >+ > return EnumerateGlyphs(aString, aLength, > &nsFontMetricsXft::DrawStringCallback, &data); > } >@@ -714,6 +755,15 @@ > aBoundingMetrics.ascent = NSToCoordRound(aBoundingMetrics.ascent * P2T); > aBoundingMetrics.descent = NSToCoordRound(aBoundingMetrics.descent * P2T); > >+#ifdef DEBUG_foo >+ printf("GetBoundingMetrics (char *)%d %d %d %d %d\n", >+ aBoundingMetrics.leftBearing, >+ aBoundingMetrics.rightBearing, >+ aBoundingMetrics.width, >+ aBoundingMetrics.ascent, >+ aBoundingMetrics.descent); >+#endif >+ > return NS_OK; > } > >@@ -755,6 +805,15 @@ > if (nsnull != aFontID) > *aFontID = 0; > >+#ifdef DEBUG_foo >+ printf("GetBoundingMetrics %d %d %d %d %d\n", >+ aBoundingMetrics.leftBearing, >+ aBoundingMetrics.rightBearing, >+ aBoundingMetrics.width, >+ aBoundingMetrics.ascent, >+ aBoundingMetrics.descent); >+#endif >+ > return NS_OK; > } > >@@ -766,6 +825,12 @@ > return nsnull; > } > >+nsresult >+nsFontMetricsXft::SetRightToLeftText(PRBool aIsRTL) >+{ >+ return NS_OK; >+} >+ > PRUint32 > nsFontMetricsXft::GetHints(void) > { >--- mozilla/gfx/src/gtk/Makefile.in.foo 2003-11-10 07:24:51.000000000 -0500 >+++ mozilla/gfx/src/gtk/Makefile.in 2004-10-18 22:51:01.000000000 -0400 >@@ -102,6 +102,12 @@ > nsFontMetricsXft.cpp > endif > >+ifdef MOZ_ENABLE_PANGO >+CPPSRCS += \ >+ nsFontMetricsPango.cpp \ >+ mozilla-decoder.cpp >+endif >+ > ifdef MOZ_ENABLE_GTK > CPPSRCS += \ > nsRegionGTK.cpp \ >@@ -155,10 +161,10 @@ > endif > > ifdef MOZ_ENABLE_XFT >-libs:: fontEncoding.properties >+libs:: fontEncoding.properties pangoFontEncoding.properties > $(INSTALL) $^ $(DIST)/bin/res/fonts > >-install:: fontEncoding.properties >+install:: fontEncoding.properties pangoFontEncoding.properties > $(SYSINSTALL) $(IFLAGS1) $^ $(DESTDIR)$(mozappdir)/res/fonts > endif > >--- /dev/null 2004-02-18 10:26:44.000000000 -0500 >+++ mozilla/gfx/src/gtk/pangoFontEncoding.properties 2004-10-18 22:49:40.000000000 -0400 >@@ -0,0 +1,120 @@ >+# ***** 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 MathML Project. >+# >+# The Initial Developer of the Original Code is >+# The University of Queensland. >+# Portions created by the Initial Developer are Copyright (C) 2001 >+# the Initial Developer. All Rights Reserved. >+# >+# Contributor(s): >+# Roger B. Sidje <rbs@maths.uq.edu.au> >+# Jungshik Shin <jshin@mailaps.org> >+# Christopher Blizzard <blizzard@mozilla.org> >+# >+# Alternatively, the contents of this file may be used under the terms of >+# either the GNU General Public License Version 2 or later (the "GPL"), or >+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), >+# in which case the provisions of the GPL or the LGPL are applicable instead >+# 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 ***** >+ >+# LOCALIZATION NOTE: FILE >+# Do not translate anything in this file >+ >+# This file contains supported custom encodings for pango font >+# rendering. For information about the specific encodings, look at >+# fontEncoding.properties. It contains a lot more verbiage than you >+# will find here. There are a lot of encodings supported in the old >+# encoding file that pango supports directly, so there should be >+# little reason to use those custom encodings. The pango custom code >+# doesn't support .wide fonts, so consider yourself warned! >+# >+ >+# To be honest, we basically support mathml and that's about it. >+ >+encoding.cmr10.ttf = x-ttf-cmr >+encoding.cmmi10.ttf = x-ttf-cmmi >+encoding.cmsy10.ttf = x-ttf-cmsy >+encoding.cmex10.ttf = x-ttf-cmex >+ >+encoding.cmr10.ftcmap = unicode >+encoding.cmmi10.ftcmap = unicode >+encoding.cmsy10.ftcmap = unicode >+encoding.cmex10.ftcmap = unicode >+ >+encoding.math1.ttf = x-mathematica1 >+encoding.math1-bold.ttf = x-mathematica1 >+encoding.math1mono.ttf = x-mathematica1 >+encoding.math1mono-bold.ttf = x-mathematica1 >+ >+encoding.math2.ttf = x-mathematica2 >+encoding.math2-bold.ttf = x-mathematica2 >+encoding.math2mono.ttf = x-mathematica2 >+encoding.math2mono-bold.ttf = x-mathematica2 >+ >+encoding.math3.ttf = x-mathematica3 >+encoding.math3-bold.ttf = x-mathematica3 >+encoding.math3mono.ttf = x-mathematica3 >+encoding.math3mono-bold.ttf = x-mathematica3 >+ >+encoding.math4.ttf = x-mathematica4 >+encoding.math4-bold.ttf = x-mathematica4 >+encoding.math4mono.ttf = x-mathematica4 >+encoding.math4mono-bold.ttf = x-mathematica4 >+ >+encoding.math5.ttf = x-mathematica5 >+encoding.math5-bold.ttf = x-mathematica5 >+encoding.math5bold.ttf = x-mathematica5 >+encoding.math5mono.ttf = x-mathematica5 >+encoding.math5mono-bold.ttf = x-mathematica5 >+encoding.math5monobold.ttf = x-mathematica5 >+ >+encoding.math1.ftcmap = mac_roman >+encoding.math1-bold.ftcmap = mac_roman >+encoding.math1mono.ftcmap = mac_roman >+encoding.math1mono-bold.ftcmap = mac_roman >+ >+encoding.math2.ftcmap = mac_roman >+encoding.math2-bold.ftcmap = mac_roman >+encoding.math2mono.ftcmap = mac_roman >+encoding.math2mono-bold.ftcmap = mac_roman >+ >+encoding.math3.ftcmap = mac_roman >+encoding.math3-bold.ftcmap = mac_roman >+encoding.math3mono.ftcmap = mac_roman >+encoding.math3mono-bold.ftcmap = mac_roman >+ >+encoding.math4.ftcmap = mac_roman >+encoding.math4-bold.ftcmap = mac_roman >+encoding.math4mono.ftcmap = mac_roman >+encoding.math4mono-bold.ftcmap = mac_roman >+ >+encoding.math5.ftcmap = mac_roman >+encoding.math5-bold.ftcmap = mac_roman >+encoding.math5bold.ftcmap = mac_roman >+encoding.math5mono.ftcmap = mac_roman >+encoding.math5mono-bold.ftcmap = mac_roman >+encoding.math5monobold.ftcmap = mac_roman >+ >+encoding.mtextra.ttf = x-mtextra >+encoding.mtextra.ftcmap = mac_roman >+ >--- mozilla/gfx/src/gtk/nsFontMetricsUtils.cpp.foo 2002-10-11 22:03:32.000000000 -0400 >+++ mozilla/gfx/src/gtk/nsFontMetricsUtils.cpp 2004-10-18 22:51:32.000000000 -0400 >@@ -50,11 +50,20 @@ > #include "nsFontMetricsGTK.h" > #endif > >+#ifdef MOZ_ENABLE_PANGO >+#include "nsFontMetricsPango.h" >+#endif >+ > #include "nsFontMetricsUtils.h" > > PRUint32 > NS_FontMetricsGetHints(void) > { >+#ifdef MOZ_ENABLE_PANGO >+ if (NS_IsPangoEnabled()) { >+ return nsFontMetricsPango::GetHints(); >+ } >+#endif > #ifdef MOZ_ENABLE_XFT > if (NS_IsXftEnabled()) { > return nsFontMetricsXft::GetHints(); >@@ -69,6 +78,11 @@ > nsresult > NS_FontMetricsFamilyExists(nsIDeviceContext *aDevice, const nsString &aName) > { >+#ifdef MOZ_ENABLE_PANGO >+ if (NS_IsPangoEnabled()) { >+ return nsFontMetricsPango::FamilyExists(aDevice, aName); >+ } >+#endif > #ifdef MOZ_ENABLE_XFT > // try to fall through to the core fonts if xft fails > if (NS_IsXftEnabled()) { >@@ -121,3 +135,17 @@ > } > > #endif /* MOZ_ENABLE_XFT */ >+ >+#ifdef MOZ_ENABLE_PANGO >+ >+PRBool >+NS_IsPangoEnabled(void) >+{ >+ char *val = PR_GetEnv("MOZ_ENABLE_PANGO"); >+ if (val) >+ return TRUE; >+ >+ return FALSE; >+} >+ >+#endif >--- /dev/null 2004-02-18 10:26:44.000000000 -0500 >+++ mozilla/gfx/src/gtk/nsFontMetricsPango.cpp 2004-10-18 22:49:40.000000000 -0400 >@@ -0,0 +1,1662 @@ >+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ >+/* vim:expandtab:shiftwidth=4:tabstop=4: >+ */ >+/* ***** BEGIN LICENSE BLOCK ***** >+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 >+ * >+ * The contents of this file are subject to the Mozilla Public License Version >+ * 1.1 (the "License"); you may not use this file except in compliance with >+ * the License. You may obtain a copy of the License at >+ * http://www.mozilla.org/MPL/ >+ * >+ * Software distributed under the License is distributed on an "AS IS" basis, >+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License >+ * for the specific language governing rights and limitations under the >+ * License. >+ * >+ * The Original Code is mozilla.org code. >+ * >+ * The Initial Developer of the Original Code is Christopher Blizzard >+ * <blizzard@mozilla.org>. Portions created by the Initial Developer >+ * are Copyright (C) 2004 the Initial Developer. All Rights Reserved. >+ * >+ * Contributor(s): >+ * >+ * Alternatively, the contents of this file may be used under the terms of >+ * either the GNU General Public License Version 2 or later (the "GPL"), or >+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), >+ * in which case the provisions of the GPL or the LGPL are applicable instead >+ * of those above. If you wish to allow use of your version of this file only >+ * under the terms of either the GPL or the LGPL, and not to allow others to >+ * use your version of this file under the terms of the MPL, indicate your >+ * decision by deleting the provisions above and replace them with the notice >+ * and other provisions required by the GPL or the LGPL. If you do not delete >+ * the provisions above, a recipient may use your version of this file under >+ * the terms of any one of the MPL, the GPL or the LGPL. >+ * >+ * ***** END LICENSE BLOCK ***** */ >+ >+#include "nsFont.h" >+#include "nsIDeviceContext.h" >+#include "nsICharsetConverterManager.h" >+#include "nsIPref.h" >+#include "nsIServiceManagerUtils.h" >+ >+#define PANGO_ENABLE_BACKEND >+#define PANGO_ENABLE_ENGINE >+ >+#include "nsFontMetricsPango.h" >+#include "nsRenderingContextGTK.h" >+#include "nsDeviceContextGTK.h" >+ >+#include "nsUnicharUtils.h" >+#include "nsQuickSort.h" >+ >+#include <pango/pangoxft.h> >+#include <fontconfig/fontconfig.h> >+#include <gdk/gdk.h> >+#include <gdk/gdkx.h> >+#include <freetype/tttables.h> >+ >+#include "mozilla-decoder.h" >+ >+#define FORCE_PR_LOG >+#include "prlog.h" >+ >+// Globals >+ >+static PRLogModuleInfo *gPangoFontLog; >+static int gNumInstances; >+ >+// Defines >+ >+// This is the scaling factor that we keep fonts limited to against >+// the display size. If a pixel size is requested that is more than >+// this factor larger than the height of the display, it's clamped to >+// that value instead of the requested size. >+#define FONT_MAX_FONT_SCALE 2 >+ >+static NS_DEFINE_CID(kCharsetConverterManagerCID, >+ NS_ICHARSETCONVERTERMANAGER_CID); >+ >+struct MozPangoLangGroup { >+ const char *mozLangGroup; >+ const char *PangoLang; >+}; >+ >+static const MozPangoLangGroup MozPangoLangGroups[] = { >+ { "x-western", "en" }, >+ { "x-central-euro", "pl" }, >+ { "x-cyrillic", "ru" }, >+ { "x-baltic", "lv" }, >+ { "x-devanagari", "hi" }, >+ { "x-tamil", "ta" }, >+ { "x-unicode", 0 }, >+ { "x-user-def", 0 }, >+}; >+ >+#define NUM_PANGO_LANG_GROUPS (sizeof (MozPangoLangGroups) / \ >+ sizeof (MozPangoLangGroups[0])) >+ >+#ifdef DEBUG >+#define DUMP_PRUNICHAR(ustr, ulen) for (PRUint32 llen=0;llen<ulen;llen++) \ >+ printf("0x%x ", ustr[llen]); \ >+ printf("\n"); >+#endif >+ >+// rounding and truncation functions for a Freetype floating point number >+// (FT26Dot6) stored in a 32bit integer with high 26 bits for the integer >+// part and low 6 bits for the fractional part. >+#define MOZ_FT_ROUND(x) (((x) + 32) & ~63) // 63 = 2^6 - 1 >+#define MOZ_FT_TRUNC(x) ((x) >> 6) >+#define CONVERT_DESIGN_UNITS_TO_PIXELS(v, s) \ >+ MOZ_FT_TRUNC(MOZ_FT_ROUND(FT_MulFix((v) , (s)))) >+ >+// Static function decls >+ >+static PRBool IsASCIIFontName (const nsString& aName); >+static int FFRECountHyphens (nsACString &aFFREName); >+ >+static PangoLanguage *GetPangoLanguage(nsIAtom *aLangGroup); >+static const MozPangoLangGroup* FindPangoLangGroup (nsACString &aLangGroup); >+ >+static void FreeGlobals (void); >+ >+static PangoStyle CalculateStyle (PRUint8 aStyle); >+static PangoWeight CalculateWeight (PRUint16 aWeight); >+ >+static nsresult EnumFontsPango (nsIAtom* aLangGroup, const char* aGeneric, >+ PRUint32* aCount, PRUnichar*** aResult); >+static int CompareFontNames (const void* aArg1, const void* aArg2, >+ void* aClosure); >+ >+extern void AddLangGroup (FcPattern *aPattern, nsIAtom *aLangGroup); >+ >+nsFontMetricsPango::nsFontMetricsPango() >+{ >+ if (!gPangoFontLog) >+ gPangoFontLog = PR_NewLogModule("PangoFont"); >+ >+ gNumInstances++; >+ >+ mPangoFontDesc = nsnull; >+ mPangoContext = nsnull; >+ mLTRPangoContext = nsnull; >+ mRTLPangoContext = nsnull; >+ mPangoAttrList = nsnull; >+ mIsRTL = PR_FALSE; >+ >+ static PRBool initialized = PR_FALSE; >+ if (initialized) >+ return; >+ >+ // Initialized the custom decoders >+ if (!mozilla_decoders_init()) >+ initialized = PR_TRUE; >+} >+ >+nsFontMetricsPango::~nsFontMetricsPango() >+{ >+ delete mFont; >+ >+ if (mDeviceContext) >+ mDeviceContext->FontMetricsDeleted(this); >+ >+ if (mPangoFontDesc) >+ pango_font_description_free(mPangoFontDesc); >+ >+ if (mLTRPangoContext) >+ g_object_unref(mLTRPangoContext); >+ >+ if (mRTLPangoContext) >+ g_object_unref(mRTLPangoContext); >+ >+ if (mPangoAttrList) >+ pango_attr_list_unref(mPangoAttrList); >+ >+ // XXX clean up all the pango objects >+ >+ if (--gNumInstances == 0) >+ FreeGlobals(); >+} >+ >+ >+NS_IMPL_ISUPPORTS1(nsFontMetricsPango, nsIFontMetrics) >+ >+// nsIFontMetrics impl >+ >+NS_IMETHODIMP >+nsFontMetricsPango::Init(const nsFont& aFont, nsIAtom* aLangGroup, >+ nsIDeviceContext *aContext) >+{ >+ mFont = new nsFont(aFont); >+ mLangGroup = aLangGroup; >+ >+ // Hang on to the device context >+ mDeviceContext = aContext; >+ >+ mPointSize = NSTwipsToFloatPoints(mFont->size); >+ >+ // Make sure to clamp the pixel size to something reasonable so we >+ // don't make the X server blow up. >+ nscoord screenPixels = gdk_screen_height(); >+ mPointSize = PR_MIN(screenPixels * FONT_MAX_FONT_SCALE, mPointSize); >+ >+ // enumerate over the font names passed in >+ mFont->EnumerateFamilies(nsFontMetricsPango::EnumFontCallback, this); >+ >+ nsCOMPtr<nsIPref> prefService; >+ prefService = do_GetService(NS_PREF_CONTRACTID); >+ if (!prefService) >+ return NS_ERROR_FAILURE; >+ >+ nsXPIDLCString value; >+ >+ // Set up the default font name if it's not set >+ if (!mGenericFont) { >+ prefService->CopyCharPref("font.default", getter_Copies(value)); >+ >+ if (value.get()) >+ mDefaultFont = value.get(); >+ else >+ mDefaultFont = "serif"; >+ >+ mGenericFont = &mDefaultFont; >+ } >+ >+ // set up the minimum sizes for fonts >+ if (mLangGroup) { >+ nsCAutoString name("font.min-size."); >+ >+ if (mGenericFont->Equals("monospace")) >+ name.Append("fixed"); >+ else >+ name.Append("variable"); >+ >+ name.Append(char('.')); >+ >+ const char* langGroup; >+ mLangGroup->GetUTF8String(&langGroup); >+ >+ name.Append(langGroup); >+ >+ PRInt32 minimumInt = 0; >+ float minimum; >+ nsresult res; >+ res = prefService->GetIntPref(name.get(), &minimumInt); >+ if (NS_FAILED(res)) >+ prefService->GetDefaultIntPref(name.get(), &minimumInt); >+ >+ if (minimumInt < 0) >+ minimumInt = 0; >+ >+ minimum = minimumInt; >+ >+ // The minimum size is specified in pixels, not in points. >+ // Convert the size from pixels to points. >+ minimum = NSTwipsToFloatPoints(NSFloatPixelsToTwips(minimum, mDeviceContext->DevUnitsToAppUnits())); >+ if (mPointSize < minimum) >+ mPointSize = minimum; >+ } >+ >+ // Make sure that the pixel size is at least greater than zero >+ if (mPointSize < 1) { >+#ifdef DEBUG >+ printf("*** Warning: nsFontMetricsPango created with point size %f\n", >+ mPointSize); >+#endif >+ mPointSize = 1; >+ } >+ >+ nsresult rv = RealizeFont(); >+ if (NS_FAILED(rv)) >+ return rv; >+ >+ // Cache font metrics for the 'x' character >+ return CacheFontMetrics(); >+} >+ >+nsresult >+nsFontMetricsPango::CacheFontMetrics(void) >+{ >+ // Get our scale factor >+ float f; >+ float val; >+ f = mDeviceContext->DevUnitsToAppUnits(); >+ >+ mPangoAttrList = pango_attr_list_new(); >+ >+ GList *items = pango_itemize(mPangoContext, >+ "a", 0, 1, mPangoAttrList, NULL); >+ >+ if (!items) >+ return NS_ERROR_FAILURE; >+ >+ guint nitems = g_list_length(items); >+ if (nitems != 1) >+ return NS_ERROR_FAILURE; >+ >+ PangoItem *item = (PangoItem *)items->data; >+ PangoFcFont *fcfont = PANGO_FC_FONT(item->analysis.font); >+ if (!fcfont) >+ return NS_ERROR_FAILURE; >+ >+ // Get our font face >+ FT_Face face; >+ TT_OS2 *os2; >+ XftFont *xftFont = pango_xft_font_get_font(PANGO_FONT(fcfont)); >+ if (!xftFont) >+ return NS_ERROR_NOT_AVAILABLE; >+ >+ face = XftLockFace(xftFont); >+ os2 = (TT_OS2 *) FT_Get_Sfnt_Table(face, ft_sfnt_os2); >+ >+ // mEmHeight (size in pixels of EM height) >+ int size; >+ if (FcPatternGetInteger(fcfont->font_pattern, FC_PIXEL_SIZE, 0, &size) != >+ FcResultMatch) { >+ size = 12; >+ } >+ mEmHeight = PR_MAX(1, nscoord(size * f)); >+ >+ // mMaxAscent >+ mMaxAscent = nscoord(xftFont->ascent * f); >+ >+ // mMaxDescent >+ mMaxDescent = nscoord(xftFont->descent * f); >+ >+ nscoord lineHeight = mMaxAscent + mMaxDescent; >+ >+ // mLeading (needs ascent and descent and EM height) >+ if (lineHeight > mEmHeight) >+ mLeading = lineHeight - mEmHeight; >+ else >+ mLeading = 0; >+ >+ // mMaxHeight (needs ascent and descent) >+ mMaxHeight = lineHeight; >+ >+ // mEmAscent (needs maxascent, EM height, ascent and descent) >+ mEmAscent = nscoord(mMaxAscent * mEmHeight / lineHeight); >+ >+ // mEmDescent (needs EM height and EM ascent >+ mEmDescent = mEmHeight - mEmAscent; >+ >+ // mMaxAdvance >+ mMaxAdvance = nscoord(xftFont->max_advance_width * f); >+ >+ // mSpaceWidth (width of a space) >+ nscoord tmpWidth; >+ GetWidth(" ", 1, tmpWidth, 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); >+ mAveCharWidth = tmpWidth; >+ >+ // mXHeight (height of an 'x' character) >+ PRUnichar xUnichar('x'); >+ XGlyphInfo extents; >+ if (FcCharSetHasChar(xftFont->charset, xUnichar)) { >+ XftTextExtents16(GDK_DISPLAY(), xftFont, &xUnichar, 1, &extents); >+ mXHeight = extents.height; >+ } >+ else { >+ // 56% of ascent, best guess for non-true type or asian fonts >+ mXHeight = nscoord(((float)mMaxAscent) * 0.56); >+ } >+ mXHeight = nscoord(mXHeight * f); >+ >+ // mUnderlineOffset (offset for underlines) >+ val = CONVERT_DESIGN_UNITS_TO_PIXELS(face->underline_position, >+ face->size->metrics.y_scale); >+ if (val) { >+ mUnderlineOffset = NSToIntRound(val * f); >+ } >+ else { >+ mUnderlineOffset = >+ -NSToIntRound(PR_MAX(1, floor(0.1 * xftFont->height + 0.5)) * f); >+ } >+ >+ // mUnderlineSize (thickness of an underline) >+ val = CONVERT_DESIGN_UNITS_TO_PIXELS(face->underline_thickness, >+ face->size->metrics.y_scale); >+ if (val) { >+ mUnderlineSize = nscoord(PR_MAX(f, NSToIntRound(val * f))); >+ } >+ else { >+ mUnderlineSize = >+ NSToIntRound(PR_MAX(1, floor(0.05 * xftFont->height + 0.5)) * f); >+ } >+ >+ // mSuperscriptOffset >+ if (os2 && os2->ySuperscriptYOffset) { >+ val = CONVERT_DESIGN_UNITS_TO_PIXELS(os2->ySuperscriptYOffset, >+ face->size->metrics.y_scale); >+ mSuperscriptOffset = nscoord(PR_MAX(f, NSToIntRound(val * f))); >+ } >+ else { >+ mSuperscriptOffset = mXHeight; >+ } >+ >+ // mSubscriptOffset >+ if (os2 && os2->ySubscriptYOffset) { >+ val = CONVERT_DESIGN_UNITS_TO_PIXELS(os2->ySubscriptYOffset, >+ face->size->metrics.y_scale); >+ // some fonts have the incorrect sign. >+ val = (val < 0) ? -val : val; >+ mSubscriptOffset = nscoord(PR_MAX(f, NSToIntRound(val * f))); >+ } >+ else { >+ mSubscriptOffset = mXHeight; >+ } >+ >+ // mStrikeoutOffset >+ mStrikeoutOffset = NSToCoordRound(mXHeight / 2.0); >+ >+ // mStrikeoutSize >+ mStrikeoutSize = mUnderlineSize; >+ >+ XftUnlockFace(xftFont); >+ >+ /* >+ printf("%i\n", mXHeight); >+ printf("%i\n", mSuperscriptOffset); >+ printf("%i\n", mSubscriptOffset); >+ printf("%i\n", mStrikeoutOffset); >+ printf("%i\n", mStrikeoutSize); >+ printf("%i\n", mUnderlineOffset); >+ printf("%i\n", mUnderlineSize); >+ printf("%i\n", mMaxHeight); >+ printf("%i\n", mLeading); >+ printf("%i\n", mEmHeight); >+ printf("%i\n", mEmAscent); >+ printf("%i\n", mEmDescent); >+ printf("%i\n", mMaxAscent); >+ printf("%i\n", mMaxDescent); >+ printf("%i\n", mMaxAdvance); >+ printf("%i\n", mSpaceWidth); >+ printf("%i\n", mAveCharWidth); >+ */ >+ >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsFontMetricsPango::Destroy() >+{ >+ mDeviceContext = nsnull; >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsFontMetricsPango::GetFont(const nsFont *&aFont) >+{ >+ aFont = mFont; >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsFontMetricsPango::GetLangGroup(nsIAtom** aLangGroup) >+{ >+ *aLangGroup = mLangGroup; >+ NS_IF_ADDREF(*aLangGroup); >+ >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsFontMetricsPango::GetFontHandle(nsFontHandle &aHandle) >+{ >+ return NS_ERROR_NOT_IMPLEMENTED; >+} >+ >+// nsIFontMetricsPango impl >+ >+nsresult >+nsFontMetricsPango::GetWidth(const char* aString, PRUint32 aLength, >+ nscoord& aWidth, >+ nsRenderingContextGTK *aContext) >+{ >+ PangoLayout *layout = pango_layout_new(mPangoContext); >+ >+ pango_layout_set_text(layout, aString, aLength); >+ >+ int width, height; >+ >+ pango_layout_get_size(layout, &width, &height); >+ >+ width /= PANGO_SCALE; >+ >+ g_object_unref(layout); >+ >+ float f; >+ f = mDeviceContext->DevUnitsToAppUnits(); >+ aWidth = NSToCoordRound(width * f); >+ >+ // printf("GetWidth (char *) %d\n", aWidth); >+ >+ return NS_OK; >+} >+ >+nsresult >+nsFontMetricsPango::GetWidth(const PRUnichar* aString, PRUint32 aLength, >+ nscoord& aWidth, PRInt32 *aFontID, >+ nsRenderingContextGTK *aContext) >+{ >+ 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)); >+ pango_layout_get_size(layout, &width, &height); >+ >+ width /= PANGO_SCALE; >+ >+ float f; >+ f = mDeviceContext->DevUnitsToAppUnits(); >+ aWidth = NSToCoordRound(width * f); >+ >+ // printf("GetWidth %d\n", aWidth); >+ >+ loser: >+ g_free(text); >+ g_object_unref(layout); >+ >+ return rv; >+} >+ >+ >+nsresult >+nsFontMetricsPango::GetTextDimensions(const PRUnichar* aString, >+ PRUint32 aLength, >+ nsTextDimensions& aDimensions, >+ PRInt32* aFontID, >+ nsRenderingContextGTK *aContext) >+{ >+ nsresult rv = NS_OK; >+ >+ PangoLayout *layout = pango_layout_new(mPangoContext); >+ >+ gchar *text = g_utf16_to_utf8(aString, aLength, >+ NULL, NULL, NULL); >+ >+ if (!text) { >+#ifdef DEBUG >+ NS_WARNING("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; >+ } >+ >+ >+ pango_layout_set_text(layout, text, strlen(text)); >+ >+ // Get the logical extents >+ PangoLayoutLine *line; >+ if (pango_layout_get_line_count(layout) != 1) { >+ printf("Warning: more than one line!\n"); >+ } >+ line = pango_layout_get_line(layout, 0); >+ >+ PangoRectangle rect; >+ pango_layout_line_get_extents(line, NULL, &rect); >+ >+ float P2T; >+ P2T = mDeviceContext->DevUnitsToAppUnits(); >+ >+ aDimensions.width = NSToCoordRound(rect.width / PANGO_SCALE * P2T); >+ aDimensions.ascent = NSToCoordRound(PANGO_ASCENT(rect) / PANGO_SCALE * P2T); >+ aDimensions.descent = NSToCoordRound(PANGO_DESCENT(rect) / PANGO_SCALE * P2T); >+ >+ // printf("GetTextDimensions %d %d %d\n", aDimensions.width, >+ //aDimensions.ascent, aDimensions.descent); >+ >+ loser: >+ g_free(text); >+ g_object_unref(layout); >+ >+ return rv; >+} >+ >+nsresult >+nsFontMetricsPango::GetTextDimensions(const char* aString, >+ PRInt32 aLength, >+ PRInt32 aAvailWidth, >+ PRInt32* aBreaks, >+ PRInt32 aNumBreaks, >+ nsTextDimensions& aDimensions, >+ PRInt32& aNumCharsFit, >+ nsTextDimensions& aLastWordDimensions, >+ PRInt32* aFontID, >+ nsRenderingContextGTK *aContext) >+{ >+ >+ return GetTextDimensionsInternal(aString, aLength, aAvailWidth, aBreaks, >+ aNumBreaks, aDimensions, aNumCharsFit, >+ aLastWordDimensions, aContext); >+ >+} >+ >+nsresult >+nsFontMetricsPango::GetTextDimensions(const PRUnichar* aString, >+ PRInt32 aLength, >+ PRInt32 aAvailWidth, >+ PRInt32* aBreaks, >+ PRInt32 aNumBreaks, >+ nsTextDimensions& aDimensions, >+ PRInt32& aNumCharsFit, >+ nsTextDimensions& aLastWordDimensions, >+ PRInt32* aFontID, >+ nsRenderingContextGTK *aContext) >+{ >+ nsresult rv = NS_OK; >+ PRInt32 curBreak = 0; >+ gchar *curChar; >+ >+ PRInt32 *utf8Breaks = new PRInt32[aNumBreaks]; >+ >+ gchar *text = g_utf16_to_utf8(aString, (PRInt32)aLength, >+ NULL, NULL, NULL); >+ >+ curChar = text; >+ >+ if (!text) { >+#ifdef DEBUG >+ NS_WARNING("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)) { >+ if (aBreaks[curBreak] == curOffset) { >+ utf8Breaks[curBreak] = curChar - text; >+ curBreak++; >+ } >+ >+ if (IS_HIGH_SURROGATE(aString[curOffset])) >+ curOffset++; >+ } >+ >+ // Always catch the last break >+ utf8Breaks[curBreak] = curChar - text; >+ >+#if 0 >+ if (strlen(text) != aLength) { >+ printf("Different lengths for utf16 %d and utf8 %d\n", aLength, strlen(text)); >+ DUMP_PRUNICHAR(aString, aLength) >+ DUMP_PRUNICHAR(text, strlen(text)) >+ for (PRInt32 i = 0; i < aNumBreaks; ++i) { >+ printf(" break %d utf16 %d utf8 %d\n", i, aBreaks[i], utf8Breaks[i]); >+ } >+ } >+#endif >+ >+ // We'll use curBreak to indicate which of the breaks end up being >+ // used for the break point for this line. >+ curBreak = 0; >+ rv = GetTextDimensionsInternal(text, strlen(text), aAvailWidth, utf8Breaks, >+ aNumBreaks, aDimensions, aNumCharsFit, >+ aLastWordDimensions, aContext); >+ >+ // Figure out which of the breaks we ended up using to convert >+ // back to utf16 - start from the end. >+ for (PRInt32 i = aNumBreaks - 1; i >= 0; --i) { >+ if (utf8Breaks[i] == aNumCharsFit) { >+ // if (aNumCharsFit != aBreaks[i]) >+ // printf("Fixing utf8 -> utf16 %d -> %d\n", aNumCharsFit, aBreaks[i]); >+ aNumCharsFit = aBreaks[i]; >+ break; >+ } >+ } >+ >+ loser: >+ if (text) >+ g_free(text); >+ >+ delete[] utf8Breaks; >+ >+ return rv; >+} >+ >+nsresult >+nsFontMetricsPango::DrawString(const char *aString, PRUint32 aLength, >+ nscoord aX, nscoord aY, >+ const nscoord* aSpacing, >+ nsRenderingContextGTK *aContext, >+ nsDrawingSurfaceGTK *aSurface) >+{ >+ PangoLayout *layout = pango_layout_new(mPangoContext); >+ >+ pango_layout_set_text(layout, aString, aLength); >+ >+ int x = aX; >+ int y = aY; >+ >+ aContext->GetTranMatrix()->TransformCoord(&x, &y); >+ >+ PangoLayoutLine *line; >+ if (pango_layout_get_line_count(layout) != 1) { >+ printf("Warning: more than one line!\n"); >+ } >+ line = pango_layout_get_line(layout, 0); >+ >+ aContext->UpdateGC(); >+ GdkGC *gc = aContext->GetGC(); >+ >+ 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); >+ } >+ >+ g_object_unref(gc); >+ g_object_unref(layout); >+ >+ // printf("DrawString (char *)\n"); >+ >+ return NS_OK; >+} >+ >+nsresult >+nsFontMetricsPango::DrawString(const PRUnichar* aString, PRUint32 aLength, >+ nscoord aX, nscoord aY, >+ PRInt32 aFontID, >+ const nscoord* aSpacing, >+ nsRenderingContextGTK *aContext, >+ nsDrawingSurfaceGTK *aSurface) >+{ >+ nsresult rv = NS_OK; >+ int x = aX; >+ int y = aY; >+ >+ aContext->UpdateGC(); >+ GdkGC *gc = aContext->GetGC(); >+ >+ PangoLayout *layout = pango_layout_new(mPangoContext); >+ >+ gchar *text = g_utf16_to_utf8(aString, aLength, >+ NULL, NULL, NULL); >+ >+ if (!text) { >+#ifdef DEBUG >+ NS_WARNING("nsFontMetricsPango::DrawString invalid unicode to follow"); >+ DUMP_PRUNICHAR(aString, aLength) >+#endif >+ rv = NS_ERROR_FAILURE; >+ goto loser; >+ } >+ >+ pango_layout_set_text(layout, text, strlen(text)); >+ >+ aContext->GetTranMatrix()->TransformCoord(&x, &y); >+ >+ PangoLayoutLine *line; >+ if (pango_layout_get_line_count(layout) != 1) { >+ printf("Warning: more than one line!\n"); >+ } >+ line = pango_layout_get_line(layout, 0); >+ >+ if (aSpacing && *aSpacing) { >+ DrawStringSlowly(text, aString, aLength, aSurface->GetDrawable(), >+ gc, x, y, line, aSpacing); >+ } >+ else { >+ gdk_draw_layout_line(aSurface->GetDrawable(), gc, >+ x, y, >+ line); >+ } >+ >+ loser: >+ >+ g_free(text); >+ g_object_unref(gc); >+ g_object_unref(layout); >+ >+ // printf("DrawString\n"); >+ >+ return rv; >+} >+ >+#ifdef MOZ_MATHML >+nsresult >+nsFontMetricsPango::GetBoundingMetrics(const char *aString, PRUint32 aLength, >+ nsBoundingMetrics &aBoundingMetrics, >+ nsRenderingContextGTK *aContext) >+{ >+ printf("GetBoundingMetrics (char *)\n"); >+ return NS_ERROR_FAILURE; >+} >+ >+nsresult >+nsFontMetricsPango::GetBoundingMetrics(const PRUnichar *aString, >+ PRUint32 aLength, >+ nsBoundingMetrics &aBoundingMetrics, >+ PRInt32 *aFontID, >+ nsRenderingContextGTK *aContext) >+{ >+ nsresult rv = NS_OK; >+ PangoLayout *layout = pango_layout_new(mPangoContext); >+ >+ gchar *text = g_utf16_to_utf8(aString, aLength, >+ NULL, NULL, NULL); >+ >+ if (!text) { >+#ifdef DEBUG >+ NS_WARNING("nsFontMetricsPango::GetBoundingMetrics invalid unicode to follow"); >+ DUMP_PRUNICHAR(aString, aLength) >+#endif >+ aBoundingMetrics.leftBearing = 0; >+ aBoundingMetrics.rightBearing = 0; >+ aBoundingMetrics.width = 0; >+ aBoundingMetrics.ascent = 0; >+ aBoundingMetrics.descent = 0; >+ >+ rv = NS_ERROR_FAILURE; >+ goto loser; >+ } >+ >+ pango_layout_set_text(layout, text, strlen(text)); >+ >+ // Get the logical extents >+ PangoLayoutLine *line; >+ if (pango_layout_get_line_count(layout) != 1) { >+ printf("Warning: more than one line!\n"); >+ } >+ line = pango_layout_get_line(layout, 0); >+ >+ // Get the ink extents >+ PangoRectangle rect; >+ pango_layout_line_get_extents(line, NULL, &rect); >+ >+ float P2T; >+ P2T = mDeviceContext->DevUnitsToAppUnits(); >+ >+ aBoundingMetrics.leftBearing = >+ NSToCoordRound(rect.x / PANGO_SCALE * P2T); >+ aBoundingMetrics.rightBearing = >+ NSToCoordRound(rect.width / PANGO_SCALE * P2T); >+ aBoundingMetrics.width = NSToCoordRound((rect.x + rect.width) / PANGO_SCALE * P2T); >+ aBoundingMetrics.ascent = NSToCoordRound(rect.y / PANGO_SCALE * P2T); >+ aBoundingMetrics.descent = NSToCoordRound(rect.height / PANGO_SCALE * P2T); >+ >+ loser: >+ g_free(text); >+ g_object_unref(layout); >+ >+ return rv; >+} >+ >+#endif /* MOZ_MATHML */ >+ >+GdkFont* >+nsFontMetricsPango::GetCurrentGDKFont(void) >+{ >+ return nsnull; >+} >+ >+nsresult >+nsFontMetricsPango::SetRightToLeftText(PRBool aIsRTL) >+{ >+ if (aIsRTL) { >+ if (!mRTLPangoContext) { >+ mRTLPangoContext = pango_xft_get_context(GDK_DISPLAY(), 0); >+ 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); >+ } >+ mPangoContext = mRTLPangoContext; >+ } >+ else { >+ mPangoContext = mLTRPangoContext; >+ } >+ >+ mIsRTL = aIsRTL; >+ return NS_OK; >+} >+ >+/* static */ >+PRUint32 >+nsFontMetricsPango::GetHints(void) >+{ >+ return (NS_RENDERING_HINT_BIDI_REORDERING | >+ NS_RENDERING_HINT_ARABIC_SHAPING | >+ NS_RENDERING_HINT_FAST_MEASURE); >+} >+ >+/* static */ >+nsresult >+nsFontMetricsPango::FamilyExists(nsIDeviceContext *aDevice, >+ const nsString &aName) >+{ >+ if (!IsASCIIFontName(aName)) >+ return NS_ERROR_FAILURE; >+ >+ NS_ConvertUCS2toUTF8 name(aName); >+ >+ nsresult rv = NS_ERROR_FAILURE; >+ PangoContext *context = pango_xft_get_context(GDK_DISPLAY(), 0); >+ PangoFontFamily **familyList; >+ int n; >+ >+ pango_context_list_families(context, &familyList, &n); >+ >+ for (int i=0; i < n; i++) { >+ const char *tmpname = pango_font_family_get_name(familyList[i]); >+ if (!Compare(nsDependentCString(tmpname), name, >+ nsCaseInsensitiveCStringComparator())) { >+ rv = NS_OK; >+ break; >+ } >+ } >+ >+ g_free(familyList); >+ g_object_unref(context); >+ >+ return rv; >+} >+ >+// Private Methods >+ >+nsresult >+nsFontMetricsPango::RealizeFont(void) >+{ >+ nsCString familyList; >+ // Create and fill out the font description. >+ mPangoFontDesc = pango_font_description_new(); >+ >+ // Add CSS names - walk the list of fonts, adding the generic as >+ // the last font >+ for (int i=0; i < mFontList.Count(); ++i) { >+ // if this was a generic name, break out of the loop since we >+ // don't want to add it to the pattern yet >+ if (mFontIsGeneric[i]) >+ break;; >+ >+ nsCString *familyName = mFontList.CStringAt(i); >+ familyList.Append(familyName->get()); >+ familyList.Append(','); >+ } >+ >+ // If there's a generic add a pref for the generic if there's one >+ // set. >+ if (mGenericFont && !mFont->systemFont) { >+ nsCString name; >+ name += "font.name."; >+ name += mGenericFont->get(); >+ name += "."; >+ >+ nsString langGroup; >+ mLangGroup->ToString(langGroup); >+ >+ name.AppendWithConversion(langGroup); >+ >+ nsCOMPtr<nsIPref> pref; >+ pref = do_GetService(NS_PREF_CONTRACTID); >+ if (pref) { >+ nsresult rv; >+ nsXPIDLCString value; >+ rv = pref->GetCharPref(name.get(), getter_Copies(value)); >+ >+ // we ignore prefs that have three hypens since they are X >+ // style prefs. >+ if (FFRECountHyphens(value) < 3) { >+ nsCString tmpstr; >+ tmpstr.Append(value); >+ >+ familyList.Append(tmpstr); >+ familyList.Append(','); >+ } >+ } >+ } >+ >+ // Add the generic if there is one. >+ if (mGenericFont && !mFont->systemFont) { >+ familyList.Append(mGenericFont->get()); >+ familyList.Append(','); >+ } >+ >+ // Set the family >+ pango_font_description_set_family(mPangoFontDesc, >+ familyList.get()); >+ >+ // Set the point size >+ pango_font_description_set_size(mPangoFontDesc, >+ (gint)(mPointSize * PANGO_SCALE)); >+ >+ // Set the style >+ pango_font_description_set_style(mPangoFontDesc, >+ CalculateStyle(mFont->style)); >+ >+ // Set the weight >+ pango_font_description_set_weight(mPangoFontDesc, >+ CalculateWeight(mFont->weight)); >+ >+ // Now that we have the font description set up, create the >+ // context. >+ mLTRPangoContext = pango_xft_get_context(GDK_DISPLAY(), 0); >+ mPangoContext = mLTRPangoContext; >+ >+ // 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)); >+ >+ // And attach the font description to this context >+ pango_context_set_font_description(mPangoContext, mPangoFontDesc); >+ >+ return NS_OK; >+} >+ >+/* static */ >+PRBool >+nsFontMetricsPango::EnumFontCallback(const nsString &aFamily, >+ PRBool aIsGeneric, void *aData) >+{ >+ // make sure it's an ascii name, if not then return and continue >+ // enumerating >+ if (!IsASCIIFontName(aFamily)) >+ return PR_TRUE; >+ >+ nsCAutoString name; >+ name.AssignWithConversion(aFamily.get()); >+ ToLowerCase(name); >+ nsFontMetricsPango *metrics = (nsFontMetricsPango *)aData; >+ metrics->mFontList.AppendCString(name); >+ metrics->mFontIsGeneric.AppendElement((void *)aIsGeneric); >+ if (aIsGeneric) { >+ metrics->mGenericFont = >+ metrics->mFontList.CStringAt(metrics->mFontList.Count() - 1); >+ return PR_FALSE; // stop processing >+ } >+ >+ return PR_TRUE; // keep processing >+} >+ >+/* >+ * This is only used when there's per-character spacing happening. >+ * Well, really it can be either line or character spacing but it's >+ * just turtles all the way down! >+ */ >+ >+void >+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; >+ >+ /* >+ * We walk the list of glyphs returned in each layout run, >+ * matching up the glyphs with the characters in the source text. >+ * We use the aSpacing argument to figure out where to place those >+ * glyphs. It's important to note that since the string we're >+ * working with is in UTF-8 while the spacing argument assumes >+ * that offset will be part of the UTF-16 string. Logical >+ * attributes in pango are in byte offsets in the UTF-8 string, so >+ * we need to store the offsets based on the UTF-8 string. >+ */ >+ nscoord *utf8spacing = new nscoord[strlen(aText)]; >+ >+ if (aOrigString) { >+ const gchar *curChar = aText; >+ bzero(utf8spacing, sizeof(nscoord) * strlen(aText)); >+ >+ // Covert the utf16 spacing offsets to utf8 spacing offsets >+ for (PRUint32 curOffset=0; curOffset < aLength; >+ curOffset++, curChar = g_utf8_find_next_char(curChar, NULL)) { >+ utf8spacing[curChar - aText] = aSpacing[curOffset]; >+ >+ if (IS_HIGH_SURROGATE(aOrigString[curOffset])) >+ curOffset++; >+ } >+ } >+ else { >+ memcpy(utf8spacing, aSpacing, (sizeof(nscoord *) * aLength)); >+ } >+ >+ gint curRun = 0; >+ >+ for (GSList *tmpList = aLine->runs; tmpList && tmpList->data; >+ tmpList = tmpList->next, curRun++) { >+ PangoLayoutRun *layoutRun = (PangoLayoutRun *)tmpList->data; >+ gint tmpOffset = 0; >+ >+ /* printf(" Rendering run %d: \"%s\"\n", curRun, >+ &aText[layoutRun->item->offset]); */ >+ >+ for (gint i=0; i < layoutRun->glyphs->num_glyphs; i++) { >+ /* printf("glyph %d offset %d orig width %d new width %d\n", i, >+ * layoutRun->glyphs->log_clusters[i] + layoutRun->item->offset, >+ * layoutRun->glyphs->glyphs[i].geometry.width, >+ * (gint)(utf8spacing[layoutRun->glyphs->log_clusters[i] + layoutRun->item->offset] * app2dev * PANGO_SCALE)); >+ */ >+ gint thisOffset = (gint)(utf8spacing[layoutRun->glyphs->log_clusters[i] + layoutRun->item->offset] >+ * app2dev * PANGO_SCALE); >+ layoutRun->glyphs->glyphs[i].geometry.width = thisOffset; >+ tmpOffset += thisOffset; >+ } >+ >+ /* printf(" rendering at X coord %d\n", aX + offset); */ >+ >+ gdk_draw_glyphs(aDrawable, aGC, layoutRun->item->analysis.font, >+ aX + (gint)(offset / PANGO_SCALE), aY, layoutRun->glyphs); >+ >+ offset += tmpOffset; >+ } >+ >+ delete[] utf8spacing; >+} >+ >+nsresult >+nsFontMetricsPango::GetTextDimensionsInternal(const gchar* aString, >+ PRInt32 aLength, >+ PRInt32 aAvailWidth, >+ PRInt32* aBreaks, >+ PRInt32 aNumBreaks, >+ nsTextDimensions& aDimensions, >+ PRInt32& aNumCharsFit, >+ nsTextDimensions& aLastWordDimensions, >+ nsRenderingContextGTK *aContext) >+{ >+ NS_PRECONDITION(aBreaks[aNumBreaks - 1] == aLength, "invalid break array"); >+ >+ // If we need to back up this state represents the last place >+ // we could break. We can use this to avoid remeasuring text >+ PRInt32 prevBreakState_BreakIndex = -1; // not known >+ // (hasn't been computed) >+ nscoord prevBreakState_Width = 0; // accumulated width to this point >+ >+ // Initialize OUT parameters >+ GetMaxAscent(aLastWordDimensions.ascent); >+ GetMaxDescent(aLastWordDimensions.descent); >+ aLastWordDimensions.width = -1; >+ aNumCharsFit = 0; >+ >+ // Iterate each character in the string and determine which font to use >+ nscoord width = 0; >+ PRInt32 start = 0; >+ nscoord aveCharWidth; >+ GetAveCharWidth(aveCharWidth); >+ >+ while (start < aLength) { >+ // Estimate how many characters will fit. Do that by >+ // diving the available space by the average character >+ // width. Make sure the estimated number of characters is >+ // at least 1 >+ PRInt32 estimatedNumChars = 0; >+ >+ if (aveCharWidth > 0) >+ estimatedNumChars = (aAvailWidth - width) / aveCharWidth; >+ >+ if (estimatedNumChars < 1) >+ estimatedNumChars = 1; >+ >+ // Find the nearest break offset >+ PRInt32 estimatedBreakOffset = start + estimatedNumChars; >+ PRInt32 breakIndex; >+ nscoord numChars; >+ >+ // Find the nearest place to break that is less than or equal to >+ // the estimated break offset >+ if (aLength <= estimatedBreakOffset) { >+ // All the characters should fit >+ numChars = aLength - start; >+ breakIndex = aNumBreaks - 1; >+ } >+ else { >+ breakIndex = prevBreakState_BreakIndex; >+ while (((breakIndex + 1) < aNumBreaks) && >+ (aBreaks[breakIndex + 1] <= estimatedBreakOffset)) { >+ ++breakIndex; >+ } >+ >+ if (breakIndex == prevBreakState_BreakIndex) { >+ ++breakIndex; // make sure we advanced past the >+ // previous break index >+ } >+ >+ numChars = aBreaks[breakIndex] - start; >+ } >+ >+ // Measure the text >+ nscoord twWidth = 0; >+ if ((1 == numChars) && (aString[start] == ' ')) >+ GetSpaceWidth(twWidth); >+ else if (numChars > 0) >+ GetWidth(&aString[start], numChars, twWidth, aContext); >+ >+ // See if the text fits >+ PRBool textFits = (twWidth + width) <= aAvailWidth; >+ >+ // If the text fits then update the width and the number of >+ // characters that fit >+ if (textFits) { >+ aNumCharsFit += numChars; >+ width += twWidth; >+ start += numChars; >+ >+ // This is a good spot to back up to if we need to so remember >+ // this state >+ prevBreakState_BreakIndex = breakIndex; >+ prevBreakState_Width = width; >+ } >+ else { >+ // See if we can just back up to the previous saved >+ // state and not have to measure any text >+ if (prevBreakState_BreakIndex > 0) { >+ // If the previous break index is just before the >+ // current break index then we can use it >+ if (prevBreakState_BreakIndex == (breakIndex - 1)) { >+ aNumCharsFit = aBreaks[prevBreakState_BreakIndex]; >+ width = prevBreakState_Width; >+ break; >+ } >+ } >+ >+ // We can't just revert to the previous break state >+ if (0 == breakIndex) { >+ // There's no place to back up to, so even though >+ // the text doesn't fit return it anyway >+ aNumCharsFit += numChars; >+ width += twWidth; >+ break; >+ } >+ >+ // Repeatedly back up until we get to where the text >+ // fits or we're all the way back to the first word >+ width += twWidth; >+ while ((breakIndex >= 1) && (width > aAvailWidth)) { >+ twWidth = 0; >+ start = aBreaks[breakIndex - 1]; >+ numChars = aBreaks[breakIndex] - start; >+ >+ if ((1 == numChars) && (aString[start] == ' ')) >+ GetSpaceWidth(twWidth); >+ else if (numChars > 0) >+ GetWidth(&aString[start], numChars, twWidth, >+ aContext); >+ width -= twWidth; >+ aNumCharsFit = start; >+ breakIndex--; >+ } >+ break; >+ } >+ } >+ >+ aDimensions.width = width; >+ GetMaxAscent(aDimensions.ascent); >+ GetMaxDescent(aDimensions.descent); >+ >+ /* printf("aDimensions %d %d %d aLastWordDimensions %d %d %d aNumCharsFit %d\n", >+ aDimensions.width, aDimensions.ascent, aDimensions.descent, >+ aLastWordDimensions.width, aLastWordDimensions.ascent, aLastWordDimensions.descent, >+ aNumCharsFit); */ >+ >+ return NS_OK; >+} >+ >+/* static */ >+PRBool >+IsASCIIFontName(const nsString& aName) >+{ >+ PRUint32 len = aName.Length(); >+ const PRUnichar* str = aName.get(); >+ for (PRUint32 i = 0; i < len; i++) { >+ /* >+ * X font names are printable ASCII, ignore others (for now) >+ */ >+ if ((str[i] < 0x20) || (str[i] > 0x7E)) { >+ return PR_FALSE; >+ } >+ } >+ >+ return PR_TRUE; >+} >+ >+/* static */ >+int >+FFRECountHyphens (nsACString &aFFREName) >+{ >+ int h = 0; >+ PRInt32 hyphen = 0; >+ while ((hyphen = aFFREName.FindChar('-', hyphen)) >= 0) { >+ ++h; >+ ++hyphen; >+ } >+ return h; >+} >+ >+/* static */ >+PangoLanguage * >+GetPangoLanguage(nsIAtom *aLangGroup) >+{ >+ // Find the FC lang group for this lang group >+ nsCAutoString cname; >+ aLangGroup->ToUTF8String(cname); >+ >+ // see if the lang group needs to be translated from mozilla's >+ // internal mapping into fontconfig's >+ const struct MozPangoLangGroup *langGroup; >+ langGroup = FindPangoLangGroup(cname); >+ >+ // if there's no lang group, just use the lang group as it was >+ // passed to us >+ // >+ // we're casting away the const here for the strings - should be >+ // safe. >+ if (!langGroup) >+ return pango_language_from_string(cname.get()); >+ else if (langGroup->PangoLang) >+ return pango_language_from_string(langGroup->PangoLang); >+ >+ return pango_language_from_string("en"); >+} >+ >+/* static */ >+const MozPangoLangGroup* >+FindPangoLangGroup (nsACString &aLangGroup) >+{ >+ for (unsigned int i=0; i < NUM_PANGO_LANG_GROUPS; ++i) { >+ if (aLangGroup.Equals(MozPangoLangGroups[i].mozLangGroup, >+ nsCaseInsensitiveCStringComparator())) { >+ return &MozPangoLangGroups[i]; >+ } >+ } >+ >+ return nsnull; >+} >+ >+/* static */ >+void >+FreeGlobals(void) >+{ >+} >+ >+/* static */ >+PangoStyle >+CalculateStyle(PRUint8 aStyle) >+{ >+ switch(aStyle) { >+ case NS_FONT_STYLE_ITALIC: >+ return PANGO_STYLE_OBLIQUE; >+ break; >+ case NS_FONT_STYLE_OBLIQUE: >+ return PANGO_STYLE_OBLIQUE; >+ break; >+ } >+ >+ return PANGO_STYLE_NORMAL; >+} >+ >+/* static */ >+PangoWeight >+CalculateWeight (PRUint16 aWeight) >+{ >+ /* >+ * weights come in two parts crammed into one >+ * integer -- the "base" weight is weight / 100, >+ * the rest of the value is the "offset" from that >+ * weight -- the number of steps to move to adjust >+ * the weight in the list of supported font weights, >+ * this value can be negative or positive. >+ */ >+ PRInt32 baseWeight = (aWeight + 50) / 100; >+ PRInt32 offset = aWeight - baseWeight * 100; >+ >+ /* clip weights to range 0 to 9 */ >+ if (baseWeight < 0) >+ baseWeight = 0; >+ if (baseWeight > 9) >+ baseWeight = 9; >+ >+ /* Map from weight value to fcWeights index */ >+ static int fcWeightLookup[10] = { >+ 0, 0, 0, 0, 1, 1, 2, 3, 3, 4, >+ }; >+ >+ PRInt32 fcWeight = fcWeightLookup[baseWeight]; >+ >+ /* >+ * adjust by the offset value, make sure we stay inside the >+ * fcWeights table >+ */ >+ fcWeight += offset; >+ >+ if (fcWeight < 0) >+ fcWeight = 0; >+ if (fcWeight > 4) >+ fcWeight = 4; >+ >+ /* Map to final PANGO_WEIGHT value */ >+ static int fcWeights[5] = { >+ 349, >+ 499, >+ 649, >+ 749, >+ 999 >+ }; >+ >+ return (PangoWeight)fcWeights[fcWeight]; >+} >+ >+/* static */ >+nsresult >+EnumFontsPango(nsIAtom* aLangGroup, const char* aGeneric, >+ PRUint32* aCount, PRUnichar*** aResult) >+{ >+ FcPattern *pat = NULL; >+ FcObjectSet *os = NULL; >+ FcFontSet *fs = NULL; >+ nsresult rv = NS_ERROR_FAILURE; >+ >+ PRUnichar **array = NULL; >+ PRUint32 narray = 0; >+ PRInt32 serif = 0, sansSerif = 0, monospace = 0, nGenerics; >+ >+ *aCount = 0; >+ *aResult = nsnull; >+ >+ pat = FcPatternCreate(); >+ if (!pat) >+ goto end; >+ >+ os = FcObjectSetBuild(FC_FAMILY, FC_FOUNDRY, 0); >+ if (!os) >+ goto end; >+ >+ // take the pattern and add the lang group to it >+ if (aLangGroup) >+ AddLangGroup(pat, aLangGroup); >+ >+ // get the font list >+ fs = FcFontList(0, pat, os); >+ >+ if (!fs) >+ goto end; >+ >+ if (!fs->nfont) { >+ rv = NS_OK; >+ goto end; >+ } >+ >+ // Fontconfig supports 3 generic fonts, "serif", "sans-serif", and >+ // "monospace", slightly different from CSS's 5. >+ if (!aGeneric) >+ serif = sansSerif = monospace = 1; >+ else if (!strcmp(aGeneric, "serif")) >+ serif = 1; >+ else if (!strcmp(aGeneric, "sans-serif")) >+ sansSerif = 1; >+ else if (!strcmp(aGeneric, "monospace")) >+ monospace = 1; >+ else if (!strcmp(aGeneric, "cursive") || !strcmp(aGeneric, "fantasy")) >+ serif = sansSerif = 1; >+ else >+ NS_NOTREACHED("unexpected generic family"); >+ nGenerics = serif + sansSerif + monospace; >+ >+ array = NS_STATIC_CAST(PRUnichar **, >+ nsMemory::Alloc((fs->nfont + nGenerics) * sizeof(PRUnichar *))); >+ if (!array) >+ goto end; >+ >+ if (serif) { >+ PRUnichar *name = ToNewUnicode(NS_LITERAL_STRING("serif")); >+ if (!name) >+ goto end; >+ array[narray++] = name; >+ } >+ >+ if (sansSerif) { >+ PRUnichar *name = ToNewUnicode(NS_LITERAL_STRING("sans-serif")); >+ if (!name) >+ goto end; >+ array[narray++] = name; >+ } >+ >+ if (monospace) { >+ PRUnichar *name = ToNewUnicode(NS_LITERAL_STRING("monospace")); >+ if (!name) >+ goto end; >+ array[narray++] = name; >+ } >+ >+ for (int i=0; i < fs->nfont; ++i) { >+ char *family; >+ PRUnichar *name; >+ >+ // if there's no family, just move to the next iteration >+ if (FcPatternGetString (fs->fonts[i], FC_FAMILY, 0, >+ (FcChar8 **) &family) != FcResultMatch) { >+ continue; >+ } >+ >+ name = NS_STATIC_CAST(PRUnichar *, >+ nsMemory::Alloc ((strlen (family) + 1) >+ * sizeof (PRUnichar))); >+ >+ if (!name) >+ goto end; >+ >+ PRUnichar *r = name; >+ for (char *f = family; *f; ++f) >+ *r++ = *f; >+ *r = '\0'; >+ >+ array[narray++] = name; >+ } >+ >+ NS_QuickSort(array + nGenerics, narray - nGenerics, sizeof (PRUnichar*), >+ CompareFontNames, nsnull); >+ >+ *aCount = narray; >+ if (narray) >+ *aResult = array; >+ else >+ nsMemory::Free(array); >+ >+ rv = NS_OK; >+ >+ end: >+ if (NS_FAILED(rv) && array) { >+ while (narray) >+ nsMemory::Free (array[--narray]); >+ nsMemory::Free (array); >+ } >+ if (pat) >+ FcPatternDestroy(pat); >+ if (os) >+ FcObjectSetDestroy(os); >+ if (fs) >+ FcFontSetDestroy(fs); >+ >+ return rv; >+} >+ >+/* static */ >+int >+CompareFontNames (const void* aArg1, const void* aArg2, void* aClosure) >+{ >+ const PRUnichar* str1 = *((const PRUnichar**) aArg1); >+ const PRUnichar* str2 = *((const PRUnichar**) aArg2); >+ >+ return nsCRT::strcmp(str1, str2); >+} >+ >+ >+// nsFontEnumeratorPango class >+ >+nsFontEnumeratorPango::nsFontEnumeratorPango() >+{ >+} >+ >+NS_IMPL_ISUPPORTS1(nsFontEnumeratorPango, nsIFontEnumerator) >+ >+NS_IMETHODIMP >+nsFontEnumeratorPango::EnumerateAllFonts(PRUint32 *aCount, >+ PRUnichar ***aResult) >+{ >+ NS_ENSURE_ARG_POINTER(aResult); >+ *aResult = nsnull; >+ NS_ENSURE_ARG_POINTER(aCount); >+ *aCount = 0; >+ >+ return EnumFontsPango(nsnull, nsnull, aCount, aResult); >+} >+ >+NS_IMETHODIMP >+nsFontEnumeratorPango::EnumerateFonts(const char *aLangGroup, >+ const char *aGeneric, >+ PRUint32 *aCount, >+ PRUnichar ***aResult) >+{ >+ NS_ENSURE_ARG_POINTER(aResult); >+ *aResult = nsnull; >+ NS_ENSURE_ARG_POINTER(aCount); >+ *aCount = 0; >+ >+ // aLangGroup=null or "" means any (i.e., don't care) >+ // aGeneric=null or "" means any (i.e, don't care) >+ nsCOMPtr<nsIAtom> langGroup; >+ if (aLangGroup && *aLangGroup) >+ langGroup = do_GetAtom(aLangGroup); >+ const char* generic = nsnull; >+ if (aGeneric && *aGeneric) >+ generic = aGeneric; >+ >+ return EnumFontsPango(langGroup, generic, aCount, aResult); >+} >+ >+NS_IMETHODIMP >+nsFontEnumeratorPango::HaveFontFor(const char *aLangGroup, >+ PRBool *aResult) >+{ >+ NS_ENSURE_ARG_POINTER(aResult); >+ *aResult = PR_FALSE; >+ NS_ENSURE_ARG_POINTER(aLangGroup); >+ >+ *aResult = PR_TRUE; // always return true for now. >+ // Finish me - ftang >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsFontEnumeratorPango::GetDefaultFont(const char *aLangGroup, >+ const char *aGeneric, >+ PRUnichar **aResult) >+{ >+ NS_ENSURE_ARG_POINTER(aResult); >+ *aResult = nsnull; >+ >+ // Have a look at nsFontEnumeratorXft::GetDefaultFont for some >+ // possible code for this function. >+ >+ return NS_OK; >+} >+ >+NS_IMETHODIMP >+nsFontEnumeratorPango::UpdateFontList(PRBool *_retval) >+{ >+ *_retval = PR_FALSE; // always return false for now >+ return NS_OK; >+} >--- mozilla/gfx/src/gtk/nsRenderingContextGTK.h.foo 2003-02-24 21:38:34.000000000 -0500 >+++ mozilla/gfx/src/gtk/nsRenderingContextGTK.h 2004-10-18 22:49:40.000000000 -0400 >@@ -194,6 +194,8 @@ > const nsRect &aDestBounds, PRUint32 aCopyFlags); > NS_IMETHOD RetrieveCurrentNativeGraphicData(PRUint32 * ngd); > >+ NS_IMETHOD SetRightToLeftText(PRBool aIsRTL); >+ > NS_IMETHOD DrawImage(imgIContainer *aImage, const nsRect * aSrcRect, const nsPoint * aDestPoint); > NS_IMETHOD DrawScaledImage(imgIContainer *aImage, const nsRect * aSrcRect, const nsRect * aDestRect); > >--- /dev/null 2004-02-18 10:26:44.000000000 -0500 >+++ mozilla/gfx/src/gtk/nsFontMetricsPango.h 2004-10-18 22:49:40.000000000 -0400 >@@ -0,0 +1,278 @@ >+/* -*- 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 Christopher Blizzard >+ * <blizzard@mozilla.org>. Portions created by the Initial Developer >+ * are Copyright (C) 2002 the Initial Developer. All Rights Reserved. >+ * >+ * Contributor(s): >+ * >+ * Alternatively, the contents of this file may be used under the terms of >+ * either the GNU General Public License Version 2 or later (the "GPL"), or >+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), >+ * in which case the provisions of the GPL or the LGPL are applicable instead >+ * of those above. If you wish to allow use of your version of this file only >+ * under the terms of either the GPL or the LGPL, and not to allow others to >+ * use your version of this file under the terms of the MPL, indicate your >+ * decision by deleting the provisions above and replace them with the notice >+ * and other provisions required by the GPL or the LGPL. If you do not delete >+ * the provisions above, a recipient may use your version of this file under >+ * the terms of any one of the MPL, the GPL or the LGPL. >+ * >+ * ***** END LICENSE BLOCK ***** */ >+ >+#include "nsIFontMetrics.h" >+#include "nsIFontEnumerator.h" >+#include "nsCRT.h" >+#include "nsIAtom.h" >+#include "nsString.h" >+#include "nsVoidArray.h" >+#include "nsIFontMetricsGTK.h" >+ >+#include <pango/pango.h> >+ >+class nsFontMetricsPango : public nsIFontMetricsGTK >+{ >+public: >+ nsFontMetricsPango(); >+ virtual ~nsFontMetricsPango(); >+ >+ NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW >+ >+ // nsISupports >+ NS_DECL_ISUPPORTS >+ >+ // nsIFontMetrics >+ NS_IMETHOD Init (const nsFont& aFont, nsIAtom* aLangGroup, >+ nsIDeviceContext *aContext); >+ NS_IMETHOD Destroy(); >+ NS_IMETHOD GetFont (const nsFont *&aFont); >+ NS_IMETHOD GetLangGroup (nsIAtom** aLangGroup); >+ NS_IMETHOD GetFontHandle (nsFontHandle &aHandle); >+ >+ NS_IMETHOD GetXHeight (nscoord& aResult) >+ { aResult = mXHeight; return NS_OK; }; >+ >+ NS_IMETHOD GetSuperscriptOffset (nscoord& aResult) >+ { aResult = mSuperscriptOffset; >+ return NS_OK; }; >+ >+ NS_IMETHOD GetSubscriptOffset (nscoord& aResult) >+ { aResult = mSubscriptOffset; >+ return NS_OK; }; >+ >+ NS_IMETHOD GetStrikeout (nscoord& aOffset, nscoord& aSize) >+ { aOffset = mStrikeoutOffset; >+ aSize = mStrikeoutSize; >+ return NS_OK; }; >+ >+ NS_IMETHOD GetUnderline (nscoord& aOffset, nscoord& aSize) >+ { aOffset = mUnderlineOffset; >+ aSize = mUnderlineSize; >+ return NS_OK; }; >+ >+ NS_IMETHOD GetHeight (nscoord &aHeight) >+ { aHeight = mMaxHeight; >+ return NS_OK; }; >+ >+ NS_IMETHOD GetNormalLineHeight (nscoord &aHeight) >+ { aHeight = mEmHeight + mLeading; >+ return NS_OK; }; >+ >+ NS_IMETHOD GetLeading (nscoord &aLeading) >+ { aLeading = mLeading; >+ return NS_OK; }; >+ >+ NS_IMETHOD GetEmHeight (nscoord &aHeight) >+ { aHeight = mEmHeight; >+ return NS_OK; }; >+ >+ NS_IMETHOD GetEmAscent (nscoord &aAscent) >+ { aAscent = mEmAscent; >+ return NS_OK; }; >+ >+ NS_IMETHOD GetEmDescent (nscoord &aDescent) >+ { aDescent = mEmDescent; >+ return NS_OK; }; >+ >+ NS_IMETHOD GetMaxHeight (nscoord &aHeight) >+ { aHeight = mMaxHeight; >+ return NS_OK; }; >+ >+ NS_IMETHOD GetMaxAscent (nscoord &aAscent) >+ { aAscent = mMaxAscent; >+ return NS_OK; }; >+ >+ NS_IMETHOD GetMaxDescent (nscoord &aDescent) >+ { aDescent = mMaxDescent; >+ return NS_OK; }; >+ >+ NS_IMETHOD GetMaxAdvance (nscoord &aAdvance) >+ { aAdvance = mMaxAdvance; >+ return NS_OK; }; >+ >+ NS_IMETHOD GetSpaceWidth (nscoord &aSpaceCharWidth) >+ { aSpaceCharWidth = mSpaceWidth; >+ return NS_OK; }; >+ >+ NS_IMETHOD GetAveCharWidth (nscoord &aAveCharWidth) >+ { aAveCharWidth = mAveCharWidth; >+ return NS_OK; }; >+ >+ // 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); >+ >+ virtual nsresult GetTextDimensions(const PRUnichar* aString, >+ PRUint32 aLength, >+ nsTextDimensions& aDimensions, >+ PRInt32* aFontID, >+ nsRenderingContextGTK *aContext); >+ virtual nsresult GetTextDimensions(const char* aString, >+ PRInt32 aLength, >+ PRInt32 aAvailWidth, >+ PRInt32* aBreaks, >+ PRInt32 aNumBreaks, >+ nsTextDimensions& aDimensions, >+ PRInt32& aNumCharsFit, >+ nsTextDimensions& aLastWordDimensions, >+ PRInt32* aFontID, >+ nsRenderingContextGTK *aContext); >+ virtual nsresult GetTextDimensions(const PRUnichar* aString, >+ PRInt32 aLength, >+ PRInt32 aAvailWidth, >+ PRInt32* aBreaks, >+ PRInt32 aNumBreaks, >+ nsTextDimensions& aDimensions, >+ PRInt32& aNumCharsFit, >+ nsTextDimensions& aLastWordDimensions, >+ PRInt32* aFontID, >+ nsRenderingContextGTK *aContext); >+ >+ virtual nsresult 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, >+ nscoord aX, nscoord aY, >+ PRInt32 aFontID, >+ const nscoord* aSpacing, >+ nsRenderingContextGTK *aContext, >+ nsDrawingSurfaceGTK *aSurface); >+ >+#ifdef MOZ_MATHML >+ virtual nsresult GetBoundingMetrics(const char *aString, PRUint32 aLength, >+ nsBoundingMetrics &aBoundingMetrics, >+ nsRenderingContextGTK *aContext); >+ virtual nsresult GetBoundingMetrics(const PRUnichar *aString, >+ PRUint32 aLength, >+ nsBoundingMetrics &aBoundingMetrics, >+ PRInt32 *aFontID, >+ nsRenderingContextGTK *aContext); >+#endif /* MOZ_MATHML */ >+ >+ virtual GdkFont* GetCurrentGDKFont(void); >+ >+ virtual nsresult SetRightToLeftText(PRBool aIsRTL); >+ >+ // get hints for the font >+ static 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; >+ nsFont *mFont; >+ float mPointSize; >+ >+ nsCAutoString mDefaultFont; >+ >+ // Pango-related items >+ PangoFontDescription *mPangoFontDesc; >+ PangoContext *mPangoContext; >+ PangoContext *mLTRPangoContext; >+ PangoContext *mRTLPangoContext; >+ PangoAttrList *mPangoAttrList; >+ PRBool mIsRTL; >+ >+ // Cached font metrics >+ nscoord mXHeight; >+ nscoord mSuperscriptOffset; >+ nscoord mSubscriptOffset; >+ nscoord mStrikeoutOffset; >+ nscoord mStrikeoutSize; >+ nscoord mUnderlineOffset; >+ nscoord mUnderlineSize; >+ nscoord mMaxHeight; >+ nscoord mLeading; >+ nscoord mEmHeight; >+ nscoord mEmAscent; >+ nscoord mEmDescent; >+ nscoord mMaxAscent; >+ nscoord mMaxDescent; >+ nscoord mMaxAdvance; >+ nscoord mSpaceWidth; >+ nscoord mAveCharWidth; >+ >+ // Private methods >+ nsresult RealizeFont(void); >+ nsresult CacheFontMetrics(void); >+ >+ static PRBool EnumFontCallback(const nsString &aFamily, >+ PRBool aIsGeneric, void *aData); >+ >+ void DrawStringSlowly(const gchar *aText, >+ const PRUnichar *aOrigString, >+ PRUint32 aLength, >+ GdkDrawable *aDrawable, >+ GdkGC *aGC, gint aX, gint aY, >+ PangoLayoutLine *aLine, >+ const nscoord *aSpacing); >+ >+ nsresult GetTextDimensionsInternal(const gchar* aString, >+ PRInt32 aLength, >+ PRInt32 aAvailWidth, >+ PRInt32* aBreaks, >+ PRInt32 aNumBreaks, >+ nsTextDimensions& aDimensions, >+ PRInt32& aNumCharsFit, >+ nsTextDimensions& aLastWordDimensions, >+ nsRenderingContextGTK *aContext); >+}; >+ >+class nsFontEnumeratorPango : public nsIFontEnumerator >+{ >+public: >+ nsFontEnumeratorPango(); >+ NS_DECL_ISUPPORTS >+ NS_DECL_NSIFONTENUMERATOR >+}; >--- mozilla/gfx/src/gtk/nsFontMetricsUtils.h.foo 2002-10-11 22:03:32.000000000 -0400 >+++ mozilla/gfx/src/gtk/nsFontMetricsUtils.h 2004-10-18 22:49:40.000000000 -0400 >@@ -42,9 +42,12 @@ > extern PRUint32 NS_FontMetricsGetHints (void); > extern nsresult NS_FontMetricsFamilyExists(nsIDeviceContext *aDevice, > const nsString &aName); >- > #ifdef MOZ_ENABLE_XFT > extern PRBool NS_IsXftEnabled(void); > #endif > >+#ifdef MOZ_ENABLE_PANGO >+extern PRBool NS_IsPangoEnabled(void); >+#endif >+ > #endif /* __nsFontMetricsUtils_h */ >--- mozilla/gfx/src/gtk/nsIFontMetricsGTK.h.foo 2002-10-11 23:00:17.000000000 -0400 >+++ mozilla/gfx/src/gtk/nsIFontMetricsGTK.h 2004-10-18 22:49:40.000000000 -0400 >@@ -121,6 +121,9 @@ > // particular handle. > virtual GdkFont* GetCurrentGDKFont(void) = 0; > >+ // Set the direction of the text rendering >+ virtual nsresult SetRightToLeftText(PRBool aIsRTL) = 0; >+ > }; > > #endif /* __nsIFontMetricsGTK_h */ >--- mozilla/gfx/src/gtk/nsRenderingContextGTK.cpp.foo 2004-02-12 11:52:22.000000000 -0500 >+++ mozilla/gfx/src/gtk/nsRenderingContextGTK.cpp 2004-10-18 22:49:40.000000000 -0400 >@@ -524,6 +524,9 @@ > > values.foreground.pixel = > gdk_rgb_xpixel_from_rgb(NS_TO_GDK_RGB(mCurrentColor)); >+ values.foreground.red = (NS_GET_R(mCurrentColor) << 8) | NS_GET_R(mCurrentColor); >+ values.foreground.green = (NS_GET_G(mCurrentColor) << 8) | NS_GET_G(mCurrentColor); >+ values.foreground.blue = (NS_GET_B(mCurrentColor) << 8) | NS_GET_B(mCurrentColor); > valuesMask = GDK_GC_FOREGROUND; > > #ifdef MOZ_ENABLE_COREXFONTS >@@ -1438,6 +1441,11 @@ > > #endif /* MOZ_MATHML */ > >+NS_IMETHODIMP nsRenderingContextGTK::SetRightToLeftText(PRBool aIsRTL) >+{ >+ return mFontMetrics->SetRightToLeftText(aIsRTL); >+} >+ > NS_IMETHODIMP nsRenderingContextGTK::DrawImage(imgIContainer *aImage, const nsRect * aSrcRect, const nsPoint * aDestPoint) > { > UpdateGC(); >--- mozilla/gfx/src/gtk/nsGCCache.cpp.foo 2002-02-02 22:47:15.000000000 -0500 >+++ mozilla/gfx/src/gtk/nsGCCache.cpp 2004-10-18 22:49:40.000000000 -0400 >@@ -232,98 +232,42 @@ > // We have old GC, reuse it and check what > // we have to change > >- XGCValues xvalues; >- unsigned long xvalues_mask=0; >+ GdkGCValues xvalues; >+ int xvalues_mask = 0; > > if (entry->clipRegion) { > // set it to none here and then set the clip region with > // gdk_gc_set_clip_region in GetGC() > xvalues.clip_mask = None; >- xvalues_mask |= GCClipMask; >+ xvalues_mask |= GDK_GC_CLIP_MASK; > gdk_region_destroy(entry->clipRegion); > entry->clipRegion = NULL; > } > > if (entry->gcv.foreground.pixel != gcv->foreground.pixel) { >- xvalues.foreground = gcv->foreground.pixel; >- xvalues_mask |= GCForeground; >+ xvalues.foreground.pixel = gcv->foreground.pixel; >+ xvalues_mask |= GDK_GC_FOREGROUND; > } > > if (entry->gcv.function != gcv->function) { >- switch (gcv->function) { >- case GDK_COPY: >- xvalues.function = GXcopy; >- break; >- case GDK_INVERT: >- xvalues.function = GXinvert; >- break; >- case GDK_XOR: >- xvalues.function = GXxor; >- break; >- case GDK_CLEAR: >- xvalues.function = GXclear; >- break; >- case GDK_AND: >- xvalues.function = GXand; >- break; >- case GDK_AND_REVERSE: >- xvalues.function = GXandReverse; >- break; >- case GDK_AND_INVERT: >- xvalues.function = GXandInverted; >- break; >- case GDK_NOOP: >- xvalues.function = GXnoop; >- break; >- case GDK_OR: >- xvalues.function = GXor; >- break; >- case GDK_EQUIV: >- xvalues.function = GXequiv; >- break; >- case GDK_OR_REVERSE: >- xvalues.function = GXorReverse; >- break; >- case GDK_COPY_INVERT: >- xvalues.function = GXcopyInverted; >- break; >- case GDK_OR_INVERT: >- xvalues.function = GXorInverted; >- break; >- case GDK_NAND: >- xvalues.function = GXnand; >- break; >- case GDK_SET: >- xvalues.function = GXset; >- break; >- } >- xvalues_mask |= GCFunction; >+ xvalues.function = gcv->function; >+ xvalues_mask |= GDK_GC_FUNCTION; > } > > if(entry->gcv.font != gcv->font && flags & GDK_GC_FONT) { >- xvalues.font = ((XFontStruct *)GDK_FONT_XFONT(gcv->font))->fid; >- xvalues_mask |= GCFont; >+ xvalues.font = gcv->font; >+ xvalues_mask |= GDK_GC_FONT; > } > > if (entry->gcv.line_style != gcv->line_style) { >- switch (gcv->line_style) { >- case GDK_LINE_SOLID: >- xvalues.line_style = LineSolid; >- break; >- case GDK_LINE_ON_OFF_DASH: >- xvalues.line_style = LineOnOffDash; >- break; >- case GDK_LINE_DOUBLE_DASH: >- xvalues.line_style = LineDoubleDash; >- break; >- } >- xvalues_mask |= GCLineStyle; >+ xvalues.line_style = gcv->line_style; >+ xvalues_mask |= GDK_GC_LINE_STYLE; > } > > if (xvalues_mask != 0) { >- XChangeGC(GDK_GC_XDISPLAY(entry->gc), GDK_GC_XGC(entry->gc), >- xvalues_mask, &xvalues); >+ gdk_gc_set_values(entry->gc, &xvalues, (GdkGCValuesMask)xvalues_mask); > } >+ > entry->flags = flags; > entry->gcv = *gcv; > } >--- mozilla/gfx/src/gtk/nsFontMetricsGTK.cpp.foo 2004-03-09 09:14:54.000000000 -0500 >+++ mozilla/gfx/src/gtk/nsFontMetricsGTK.cpp 2004-10-18 22:49:40.000000000 -0400 >@@ -4600,6 +4600,12 @@ > return mCurrentFont->GetGDKFont(); > } > >+nsresult >+nsFontMetricsGTK::SetRightToLeftText(PRBool aIsRTL) >+{ >+ return NS_OK; >+} >+ > PR_BEGIN_EXTERN_C > static int > CompareSizes(const void* aArg1, const void* aArg2, void *data) >--- mozilla/gfx/src/gtk/nsFontMetricsXft.h.foo 2004-02-23 16:38:52.000000000 -0500 >+++ mozilla/gfx/src/gtk/nsFontMetricsXft.h 2004-10-18 22:49:40.000000000 -0400 >@@ -202,6 +202,8 @@ > > virtual GdkFont* GetCurrentGDKFont(void); > >+ virtual nsresult SetRightToLeftText(PRBool aIsRTL); >+ > // get hints for the font > static PRUint32 GetHints (void); > >--- mozilla/gfx/src/gtk/nsFontMetricsGTK.h.foo 2004-02-04 20:57:03.000000000 -0500 >+++ mozilla/gfx/src/gtk/nsFontMetricsGTK.h 2004-10-18 22:49:40.000000000 -0400 >@@ -344,6 +344,8 @@ > > virtual GdkFont* GetCurrentGDKFont(void); > >+ virtual nsresult SetRightToLeftText(PRBool aIsRTL); >+ > static nsresult FamilyExists(nsIDeviceContext *aDevice, const nsString& aName); > static PRUint32 GetHints(void); > >--- mozilla/configure.in.foo 2004-05-25 22:25:16.000000000 -0400 >+++ mozilla/configure.in 2004-10-18 22:49:40.000000000 -0400 >@@ -3429,6 +3429,34 @@ > AC_SUBST(MOZ_XFT_LIBS) > > dnl ======================================================== >+dnl = pango font rendering >+dnl ======================================================== >+MOZ_ARG_ENABLE_BOOL(pango, >+[ --enable-pango Enable Pango font rendering support], >+ MOZ_ENABLE_PANGO=1, >+ MOZ_ENABLE_PANGO=) >+ >+if test "$MOZ_ENABLE_PANGO" >+then >+ AC_DEFINE(MOZ_ENABLE_PANGO) >+ PKG_CHECK_MODULES(MOZ_PANGO, pango >= 1.5.0) >+ >+ dnl Make sure that the pango version is _actually_ new enough >+ _SAVE_CFLAGS=$CFLAGS >+ _SAVE_LDFLAGS=$LDFLAGS >+ CFLAGS="$MOZ_PANGO_CFLAGS $CFLAGS" >+ LDFLAGS="$MOZ_PANGO_LIBS $LDFLAGS" >+ AC_CHECK_LIB(pangoft2-1.0, pango_fc_font_map_add_decoder_find_func,, >+ AC_MSG_ERROR([Your Pango is too old. Sorry.])) >+ CFLAGS=$_SAVE_CFLAGS >+ LDFLAGS=$_SAVE_LDFLAGS >+ >+ AC_SUBST(MOZ_ENABLE_PANGO) >+ AC_SUBST(MOZ_PANGO_CFLAGS) >+ AC_SUBST(MOZ_PANGO_LIBS) >+fi >+ >+dnl ======================================================== > dnl = disabling x11 core support, enabled by default > dnl ======================================================== > MOZ_ENABLE_COREXFONTS=${MOZ_ENABLE_COREXFONTS-1}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 75404
: 46691 |
46701
|
46708