? xpfe/bootstrap/mozilla Index: gfx/src/gtk/Makefile.in =================================================================== RCS file: /cvsroot/mozilla/gfx/src/gtk/Makefile.in,v retrieving revision 1.75.8.2 diff -u -r1.75.8.2 Makefile.in --- gfx/src/gtk/Makefile.in 7 Jun 2002 01:45:53 -0000 1.75.8.2 +++ gfx/src/gtk/Makefile.in 2 Sep 2002 15:02:37 -0000 @@ -95,6 +95,10 @@ endif +DEFINES += -DMOZ_ENABLE_XFT +INCLUDES += +EXTRA_DSO_LDOPTS += -lXft -lfontconfig + ifdef MOZ_ENABLE_GTK2 CPPSRCS += \ nsRegionGTK2.cpp \ Index: gfx/src/gtk/nsDeviceContextGTK.cpp =================================================================== RCS file: /cvsroot/mozilla/gfx/src/gtk/nsDeviceContextGTK.cpp,v retrieving revision 1.99.8.4 diff -u -r1.99.8.4 nsDeviceContextGTK.cpp --- gfx/src/gtk/nsDeviceContextGTK.cpp 20 Jun 2002 02:03:37 -0000 1.99.8.4 +++ gfx/src/gtk/nsDeviceContextGTK.cpp 2 Sep 2002 15:02:38 -0000 @@ -811,11 +811,11 @@ GetFontSize(XFontStruct *aFontStruct, float aPixelsToTwips) { unsigned long pr = 0; - Atom pixelSizeAtom = ::XInternAtom(GDK_DISPLAY(), "PIXEL_SIZE", 0); - ::XGetFontProperty(aFontStruct, pixelSizeAtom, &pr); + Atom pointSizeAtom = ::XInternAtom(GDK_DISPLAY(), "POINT_SIZE", 0); + ::XGetFontProperty(aFontStruct, pointSizeAtom, &pr); if (!pr) return DEFAULT_TWIP_FONT_SIZE; - return NSIntPixelsToTwips(pr, aPixelsToTwips); + return NSIntPointsToTwips(pr/10); } nsresult Index: gfx/src/gtk/nsDrawingSurfaceGTK.cpp =================================================================== RCS file: /cvsroot/mozilla/gfx/src/gtk/nsDrawingSurfaceGTK.cpp,v retrieving revision 1.35.10.1 diff -u -r1.35.10.1 nsDrawingSurfaceGTK.cpp --- gfx/src/gtk/nsDrawingSurfaceGTK.cpp 10 Apr 2002 02:46:15 -0000 1.35.10.1 +++ gfx/src/gtk/nsDrawingSurfaceGTK.cpp 2 Sep 2002 15:02:39 -0000 @@ -89,6 +89,9 @@ mPixFormat.mAlphaShift = 0; mDepth = v->depth; +#ifdef MOZ_ENABLE_XFT + mXftDraw = nsnull; +#endif /* MOZ_ENABLE_XFT */ } nsDrawingSurfaceGTK :: ~nsDrawingSurfaceGTK() @@ -101,6 +104,11 @@ if (mGC) gdk_gc_unref(mGC); + +#ifdef MOZ_ENABLE_XFT + if (mXftDraw) + XftDrawDestroy(mXftDraw); +#endif /* MOZ_ENABLE_XFT */ } /** @@ -249,6 +257,29 @@ return NS_OK; } + +#ifdef MOZ_ENABLE_XFT +XftDraw * nsDrawingSurfaceGTK :: GetXftDraw(void) +{ + if (!mXftDraw) + mXftDraw = XftDrawCreate(GDK_DISPLAY(), GDK_WINDOW_XWINDOW(mPixmap), + GDK_VISUAL_XVISUAL(::gdk_rgb_get_visual()), + GDK_COLORMAP_XCOLORMAP(::gdk_rgb_get_cmap())); + return mXftDraw; +} + +void nsDrawingSurfaceGTK :: GetLastXftClip(nsIRegion **aLastRegion) +{ + *aLastRegion = mLastXftClip.get(); + NS_IF_ADDREF(*aLastRegion); +} + +void nsDrawingSurfaceGTK :: SetLastXftClip(nsIRegion *aLastRegion) +{ + mLastXftClip = aLastRegion; +} + +#endif /* MOZ_ENABLE_XFT */ nsresult nsDrawingSurfaceGTK :: Init(GdkDrawable *aDrawable, GdkGC *aGC) { Index: gfx/src/gtk/nsDrawingSurfaceGTK.h =================================================================== RCS file: /cvsroot/mozilla/gfx/src/gtk/nsDrawingSurfaceGTK.h,v retrieving revision 1.17.34.1 diff -u -r1.17.34.1 nsDrawingSurfaceGTK.h --- gfx/src/gtk/nsDrawingSurfaceGTK.h 10 Apr 2002 02:46:15 -0000 1.17.34.1 +++ gfx/src/gtk/nsDrawingSurfaceGTK.h 2 Sep 2002 15:02:39 -0000 @@ -45,6 +45,20 @@ #include +#ifdef MOZ_ENABLE_XFT +#include "nsIRegion.h" +#include "nsCOMPtr.h" +#ifndef Bool +#include +#define MOZ_DEFINED_BOOL +#endif +#include +#include +#ifdef MOZ_DEFINED_BOOL +#undef Bool +#endif +#endif /* MOZ_ENABLE_XFT */ + class nsDrawingSurfaceGTK : public nsIDrawingSurface { public: @@ -102,6 +116,12 @@ PRInt32 GetDepth() { return mDepth; } +#ifdef MOZ_ENABLE_XFT + XftDraw *GetXftDraw (void); + void GetLastXftClip (nsIRegion **aLastRegion); + void SetLastXftClip (nsIRegion *aLastRegion); +#endif + protected: inline PRUint8 ConvertMaskToCount(unsigned long val); @@ -115,6 +135,11 @@ PRUint32 mHeight; PRUint32 mFlags; PRBool mIsOffscreen; + +#ifdef MOZ_ENABLE_XFT + XftDraw *mXftDraw; + nsCOMPtr mLastXftClip; +#endif /* for locks */ GdkImage *mImage; Index: gfx/src/gtk/nsFontMetricsGTK.cpp =================================================================== RCS file: /cvsroot/mozilla/gfx/src/gtk/nsFontMetricsGTK.cpp,v retrieving revision 1.204.2.8 diff -u -r1.204.2.8 nsFontMetricsGTK.cpp --- gfx/src/gtk/nsFontMetricsGTK.cpp 22 Jul 2002 19:19:18 -0000 1.204.2.8 +++ gfx/src/gtk/nsFontMetricsGTK.cpp 2 Sep 2002 15:02:50 -0000 @@ -68,6 +68,12 @@ #include #endif /* ENABLE_X_FONT_BANNING */ +#ifdef MOZ_ENABLE_XFT +#include +#include +#include +#endif + #include #include @@ -1205,6 +1211,11 @@ } if (mLoadedFonts) { + for (int i = 0; i < mLoadedFontsCount; i++) + { + if (mLoadedFonts[i]->IsXftFont()) + delete mLoadedFonts[i]; + } PR_Free(mLoadedFonts); mLoadedFonts = nsnull; } @@ -1480,11 +1491,20 @@ return; #endif /* (defined(MOZ_ENABLE_FREETYPE2)) */ } - nsXFont *xFont = mWesternFont->GetXFont(); - XFontStruct *fontInfo = xFont->GetXFontStruct(); - mDeviceContext->GetDevUnitsToAppUnits(f); - nscoord lineSpacing = nscoord((fontInfo->ascent + fontInfo->descent) * f); + float space_width, x_height, underline_position; + + nscoord ascent, descent, line_spacing, width_max_bounds; + nscoord underline_thickness, superscript_offset, subscript_offset; + mWesternFont->GetFontProperties(f, ascent, descent, + line_spacing, width_max_bounds, + space_width, x_height, + underline_position, + underline_thickness, + superscript_offset, + subscript_offset); + + nscoord lineSpacing = nscoord(line_spacing * f); mEmHeight = PR_MAX(1, nscoord(mWesternFont->mSize * f)); if (lineSpacing > mEmHeight) { mLeading = lineSpacing - mEmHeight; @@ -1492,97 +1512,32 @@ else { mLeading = 0; } - mMaxHeight = nscoord((fontInfo->ascent + fontInfo->descent) * f); - mMaxAscent = nscoord(fontInfo->ascent * f); - mMaxDescent = nscoord(fontInfo->descent * f); + mMaxHeight = nscoord(line_spacing * f); + mMaxAscent = nscoord(ascent * f); + mMaxDescent = nscoord(descent * f); mEmAscent = nscoord(mMaxAscent * mEmHeight / lineSpacing); mEmDescent = mEmHeight - mEmAscent; - mMaxAdvance = nscoord(fontInfo->max_bounds.width * f); + mMaxAdvance = nscoord(width_max_bounds * f); - gint rawWidth; - if ((fontInfo->min_byte1 == 0) && (fontInfo->max_byte1 == 0)) { - rawWidth = xFont->TextWidth8(" ", 1); - } - else { - XChar2b _16bit_space; - _16bit_space.byte1 = 0; - _16bit_space.byte2 = ' '; - rawWidth = xFont->TextWidth16(&_16bit_space, sizeof(_16bit_space)/2); - } - mSpaceWidth = NSToCoordRound(rawWidth * f); + mSpaceWidth = NSToCoordRound(space_width * f); - unsigned long pr = 0; - if (xFont->GetXFontProperty(XA_X_HEIGHT, &pr) && - pr < 0x00ffffff) // Bug 43214: arbitrary to exclude garbage values - { - mXHeight = nscoord(pr * f); -#ifdef REALLY_NOISY_FONTS - printf("xHeight=%d\n", mXHeight); -#endif - } - else - { - // 56% of ascent, best guess for non-true type - mXHeight = NSToCoordRound((float) fontInfo->ascent* f * 0.56f); - } + mXHeight = NSToCoordRound(x_height * f); + mUnderlineOffset = -NSToIntRound(underline_position * f); - if (xFont->GetXFontProperty(XA_UNDERLINE_POSITION, &pr)) - { - /* this will only be provided from adobe .afm fonts and TrueType - * fonts served by xfsft (not xfstt!) */ - mUnderlineOffset = -NSToIntRound(pr * f); -#ifdef REALLY_NOISY_FONTS - printf("underlineOffset=%d\n", mUnderlineOffset); -#endif - } - else - { - /* this may need to be different than one for those weird asian fonts */ - float height; - height = fontInfo->ascent + fontInfo->descent; - mUnderlineOffset = -NSToIntRound(MAX (1, floor (0.1 * height + 0.5)) * f); - } - - if (xFont->GetXFontProperty(XA_UNDERLINE_THICKNESS, &pr)) - { - /* this will only be provided from adobe .afm fonts */ - mUnderlineSize = nscoord(MAX(f, NSToIntRound(pr * f))); -#ifdef REALLY_NOISY_FONTS - printf("underlineSize=%d\n", mUnderlineSize); -#endif - } - else - { - float height; - height = fontInfo->ascent + fontInfo->descent; - mUnderlineSize = NSToIntRound(MAX(1, floor (0.05 * height + 0.5)) * f); - } - - if (xFont->GetXFontProperty(XA_SUPERSCRIPT_Y, &pr)) - { - mSuperscriptOffset = nscoord(MAX(f, NSToIntRound(pr * f))); -#ifdef REALLY_NOISY_FONTS - printf("superscriptOffset=%d\n", mSuperscriptOffset); -#endif - } - else - { - mSuperscriptOffset = mXHeight; - } + // these are pre-calculated with the scale in GetFontProperties + mUnderlineSize = underline_thickness; + mSuperscriptOffset = superscript_offset; + mSubscriptOffset = subscript_offset; - if (xFont->GetXFontProperty(XA_SUBSCRIPT_Y, &pr)) - { - mSubscriptOffset = nscoord(MAX(f, NSToIntRound(pr * f))); #ifdef REALLY_NOISY_FONTS - printf("subscriptOffset=%d\n", mSubscriptOffset); + printf("RealizeFont [%p]: underline size: %d underline offset %d " + "superscript offset %d subscript offset %d\n", + (void *)this, + mUnderlineSize, mUnderlineOffset, + mSuperscriptOffset, mSubscriptOffset); #endif - } - else - { - mSubscriptOffset = mXHeight; - } /* need better way to calculate this */ mStrikeoutOffset = NSToCoordRound(mXHeight / 2.0); @@ -2223,6 +2178,12 @@ return PR_TRUE; } +int +nsFontGTK::SupportsChar(PRUnichar aChar) +{ + return mFont && CCMAP_HAS_CHAR(mCCMap, aChar); +} + void nsFontGTK::LoadFont(void) { @@ -2348,6 +2309,143 @@ return ((PRBool) (mCharSetInfo == &ISO106461)); } +void +nsFontGTK::GetFontProperties(float &aScale, + nscoord &aAscent, + nscoord &aDescent, + nscoord &aLineSpacing, + nscoord &aWidthMaxBounds, + float &aSpaceWidth, + float &aXHeight, + float &aUnderlinePosition, + nscoord &aUnderlineThickness, + nscoord &aSuperscriptOffset, + nscoord &aSubscriptOffset) +{ + XFontStruct *fontInfo = mXFont->GetXFontStruct(); + + aAscent = fontInfo->ascent; + aDescent = fontInfo->descent; + aLineSpacing = aAscent + aDescent; + aWidthMaxBounds = fontInfo->max_bounds.width; + + // aSpaceWidth + gint rawWidth; + if ((fontInfo->min_byte1 == 0) && (fontInfo->max_byte1 == 0)) { + rawWidth = mXFont->TextWidth8(" ", 1); + } + else { + XChar2b _16bit_space; + _16bit_space.byte1 = 0; + _16bit_space.byte2 = ' '; + rawWidth = mXFont->TextWidth16(&_16bit_space, sizeof(_16bit_space)/2); + } + + aSpaceWidth = rawWidth; + + unsigned long pr = 0; + + // aXHeight + if (mXFont->GetXFontProperty(XA_X_HEIGHT, &pr) && + pr < 0x00ffffff) // Bug 43214: arbitrary to exclude garbage values + { + aXHeight = pr; +#ifdef REALLY_NOISY_FONTS + printf("aXHeight=%f\n", aXHeight); +#endif + } + else + { + // 56% of ascent, best guess for non-true type + aXHeight = ((float)fontInfo->ascent) * 0.56f; + } + + // aUnderlinePosition + if (mXFont->GetXFontProperty(XA_UNDERLINE_POSITION, &pr)) + { + /* this will only be provided from adobe .afm fonts and TrueType + * fonts served by xfsft (not xfstt!) */ + aUnderlinePosition = pr; +#ifdef REALLY_NOISY_FONTS + printf("aUnderlinePosition=%f\n", aUnderlinePosition); +#endif + } + else + { + /* this may need to be different than one for those weird asian fonts */ + float height; + height = fontInfo->ascent + fontInfo->descent; + aUnderlinePosition = MAX(1, floor(0.1 * height + 0.5)); + } + + // aUnderlineThickness + if (mXFont->GetXFontProperty(XA_UNDERLINE_THICKNESS, &pr)) + { + /* this will only be provided from adobe .afm fonts */ + aUnderlineThickness = nscoord(MAX(aScale, NSToIntRound(pr * aScale))); +#ifdef REALLY_NOISY_FONTS + printf("aUnderlineThickness=%d\n", aUnderlineThickness); +#endif + } + else + { + float height; + height = fontInfo->ascent + fontInfo->descent; + aUnderlineThickness = NSToIntRound(MAX(1, floor(0.05 * height + 0.5)) + * aScale); + } + + // aSuperscriptOffset + if (mXFont->GetXFontProperty(XA_SUPERSCRIPT_Y, &pr)) + { + aSuperscriptOffset = nscoord(MAX(aScale, NSToIntRound(pr * aScale))); +#ifdef REALLY_NOISY_FONTS + printf("superscriptOffset=%d\n", aSuperscriptOffset); +#endif + } + else + { + aSuperscriptOffset = NSToIntRound(aXHeight * aScale); + } + + // aSubscriptOffset + if (mXFont->GetXFontProperty(XA_SUBSCRIPT_Y, &pr)) + { + aSubscriptOffset = nscoord(MAX(aScale, NSToIntRound(pr * aScale))); +#ifdef REALLY_NOISY_FONTS + printf("aSubscriptOffset=%d\n", aSubscriptOffset); +#endif + } + else + { + aSubscriptOffset = NSToIntRound(aXHeight * aScale); + } +} + +PRBool +nsFontGTK::IsXftFont(void) +{ + return PR_FALSE; +} + +gint +nsFontGTK::GetWidth8(const char *aString, PRUint32 aLength) +{ + NS_NOTREACHED("nsFontGTK::GetWidth8\n"); + return 0; +} + +gint +nsFontGTK::DrawString8(nsRenderingContextGTK *aContext, + nsDrawingSurfaceGTK* aSurface, + nscoord aX, nscoord aY, + const char* aString, + PRUint32 aLength) +{ + NS_NOTREACHED("nsFontGTK::DrawString8\n"); + return 0; +} + PRBool nsFontGTK::IsFreeTypeFont(void) { @@ -2860,6 +2958,809 @@ } #endif +#ifdef MOZ_ENABLE_XFT + +struct xftLangGroup { + char *aMozLangGroup; + FcChar32 aChar; + FcChar8 *aXftLang; +}; + +static const struct xftLangGroup xftLangGroups[] = { + { "x-western", 0x0041, (FcChar8 *) "en" }, + { "x-central-euro", 0x0100, (FcChar8 *) "pl" }, + { "x-cyrillic", 0x0411, (FcChar8 *) "ru" }, + { "x-baltic", 0x0104, (FcChar8 *) "lv" }, + { "x-unicode", 0x0000, 0 }, + { "x-user-def", 0x0000, 0 }, +}; + +#define NUM_XFT_LANG_GROUPS (sizeof (xftLangGroups) / \ + sizeof (xftLangGroups[0])) + +static const struct xftLangGroup * +xftFindMozLangGroup (nsACString &mozLangGroup) +{ + for (unsigned int i = 0; i < NUM_XFT_LANG_GROUPS; i++) + { + if (mozLangGroup.Equals (xftLangGroups[i].aMozLangGroup, + nsCaseInsensitiveCStringComparator())) + { + return &xftLangGroups[i]; + } + } + return 0; +} + +static FcPattern * +xftAddMozLangAtom (nsIAtom *aLangGroup, FcPattern *pat) +{ + nsAutoString aName; + nsCAutoString aCName; + const struct xftLangGroup *aXftLangGroup; + + aLangGroup->ToString (aName); + aCName.AppendWithConversion (aName); + aXftLangGroup = xftFindMozLangGroup (aCName); + if (!aXftLangGroup) + { + if (!pat) + pat = FcPatternCreate (); + FcPatternAddString (pat, FC_LANG, (FcChar8 *) aCName.get()); + } + else if (aXftLangGroup->aXftLang) + { + if (!pat) + pat = FcPatternCreate (); + FcPatternAddString (pat, FC_LANG, aXftLangGroup->aXftLang); + } + return pat; +} + +class nsFontGTKXft : public nsFontGTK +{ +public: + nsFontGTKXft(); + nsFontGTKXft(nsFontGTKXft *aFont); + nsFontGTKXft(FcPattern *aPattern, FcPattern *aFontName); + virtual ~nsFontGTKXft(); + + virtual PRBool IsXftFont(void); + virtual PRBool SupportsChar(PRUnichar aChar); + virtual gint GetWidth8(const char *aString, PRUint32 aLength); + virtual gint GetWidth(const PRUnichar* aString, PRUint32 aLength); + virtual gint DrawString8(nsRenderingContextGTK *aContext, + nsDrawingSurfaceGTK* aSurface, + nscoord aX, nscoord aY, + const char* aString, + PRUint32 aLength); + virtual gint DrawString(nsRenderingContextGTK* aContext, + nsDrawingSurfaceGTK* aSurface, nscoord aX, + nscoord aY, const PRUnichar* aString, + PRUint32 aLength); + virtual void GetFontProperties(float &aScale, + nscoord &aAscent, + nscoord &aDescent, + nscoord &aLineSpacing, + nscoord &aWidthMaxBounds, + float &aSpaceWidth, + float &aXHeight, + float &aUnderlinePosition, + nscoord &aUnderlineThickness, + nscoord &aSuperscriptOffset, + nscoord &aSubscriptOffset); +#ifdef MOZ_MATHML + virtual nsresult GetBoundingMetrics(const PRUnichar* aString, + PRUint32 aLength, + nsBoundingMetrics& aBoundingMetrics); +#endif + FcCharSet *mSubstituteChars; +private: + XftFont *GetXftFont(void); + XftFont *mXftFont; + FcPattern *mPattern; + FcPattern *mFontName; + FcCharSet *mCharset; +}; + +static int nXftFonts = 0; + +nsFontGTKXft::nsFontGTKXft() +{ + ++nXftFonts; + printf ("%6d: Creating null Xft font\n", nXftFonts); + mXftFont = nsnull; + mPattern = 0; + mFontName = 0; + mCharset = 0; + mSubstituteChars = 0; + mSize = 0; +} + +nsFontGTKXft::nsFontGTKXft(nsFontGTKXft *aFont) +{ + ++nXftFonts; + printf ("%6d: Copying Xft font\n", nXftFonts); + if (aFont->mXftFont) + mXftFont = XftFontCopy(GDK_DISPLAY(), aFont->mXftFont); + else + mXftFont = 0; + if (aFont->mCharset) + mCharset = FcCharSetCopy (aFont->mCharset); + mSubstituteChars = 0; + mPattern = aFont->mPattern; + FcPatternReference (mPattern); + mFontName = aFont->mFontName; + FcPatternReference (mFontName); + mSize = aFont->mSize; +} + +nsFontGTKXft::nsFontGTKXft(FcPattern *pattern, FcPattern *fontName) +{ + mXftFont = 0; + mCharset = 0; + mSubstituteChars = 0; + + ++nXftFonts; + printf ("%6d: Creating Xft font\n", nXftFonts); + mPattern = pattern; + FcPatternReference (mPattern); + mFontName = fontName; + FcPatternReference (mFontName); + + FcCharSet *charset = 0; + (void) FcPatternGetCharSet (fontName, FC_CHARSET, 0, &charset); + if (charset) + mCharset = FcCharSetCopy (charset); + + int size; + if (FcPatternGetInteger (pattern, FC_PIXEL_SIZE, + 0, &size) != FcResultMatch && + FcPatternGetInteger (fontName, FC_PIXEL_SIZE, + 0, &size) != FcResultMatch) + size = 12; + mSize = size; +} + +nsFontGTKXft::~nsFontGTKXft() +{ + printf ("%6d: Destroying Xft font\n", nXftFonts); + --nXftFonts; + if (mXftFont) + XftFontClose(GDK_DISPLAY(), mXftFont); + if (mCharset) + FcCharSetDestroy (mCharset); + if (mSubstituteChars) + FcCharSetDestroy (mSubstituteChars); + if (mPattern) + FcPatternDestroy (mPattern); + if (mFontName) + FcPatternDestroy (mFontName); +} + +XftFont * +nsFontGTKXft::GetXftFont(void) +{ + if (!mXftFont && mPattern && mFontName) + { + FcPattern *pat = FcFontRenderPrepare (0, mPattern, mFontName); + if (pat) + mXftFont = XftFontOpenPattern (GDK_DISPLAY(), pat); + if (mXftFont) + mSize = mXftFont->ascent + mXftFont->descent; + } + return mXftFont; +} + +PRBool +nsFontGTKXft::IsXftFont(void) +{ + return PR_TRUE; +} + +PRBool +nsFontGTKXft::SupportsChar(PRUnichar aChar) +{ + if (mSubstituteChars && FcCharSetHasChar (mSubstituteChars, aChar)) + return PR_TRUE; + + if (mCharset && FcCharSetHasChar (mCharset, aChar)) + return PR_TRUE; + + return FALSE; +} + +gint +nsFontGTKXft::GetWidth8(const char *aString, PRUint32 aLength) +{ + XGlyphInfo glyphinfo; + XftFont *xftFont = GetXftFont (); + if (!xftFont) + return 0; + XftTextExtents8(GDK_DISPLAY(), xftFont, (FcChar8 *)aString, + aLength, &glyphinfo); + return glyphinfo.xOff; +} + +gint +nsFontGTKXft::GetWidth(const PRUnichar* aString, PRUint32 aLength) +{ + XGlyphInfo glyphinfo; + XftFont *xftFont = GetXftFont (); + if (!xftFont) + return 0; + XftTextExtents16(GDK_DISPLAY(), xftFont, (FcChar16 *)aString, + aLength, &glyphinfo); + return glyphinfo.xOff; +} + +#define NS_TO_GDK_RGB(ns) (ns & 0xff) << 16 | \ + (ns & 0xff00) | ((ns >> 16) & 0xff) + +gint +nsFontGTKXft::DrawString(nsRenderingContextGTK* aContext, + nsDrawingSurfaceGTK* aSurface, nscoord aX, + nscoord aY, const PRUnichar* aString, + PRUint32 aLength) +{ + XftColor color; + nscolor rccolor; + + aContext->GetColor(rccolor); + + color.pixel = gdk_rgb_xpixel_from_rgb(NS_TO_GDK_RGB(rccolor)); + color.color.red = (NS_GET_R(rccolor) << 8) | NS_GET_R(rccolor); + color.color.green = (NS_GET_G(rccolor) << 8) | NS_GET_G(rccolor); + color.color.blue = (NS_GET_B(rccolor) << 8) | NS_GET_B(rccolor); + color.color.alpha = 0xffff; + + XftDraw *draw = aSurface->GetXftDraw(); + + nsCOMPtr lastRegion; + nsCOMPtr clipRegion; + + aSurface->GetLastXftClip(getter_AddRefs(lastRegion)); + aContext->GetClipRegion(getter_AddRefs(clipRegion)); + + // avoid setting the clip, if possible + if (!lastRegion || !clipRegion || !lastRegion->IsEqual(*clipRegion)) { + aSurface->SetLastXftClip(clipRegion); + + GdkRegion *rgn = nsnull; + clipRegion->GetNativeRegion((void *&)rgn); + GdkRegionPrivate *priv = (GdkRegionPrivate *)rgn; + + XftDrawSetClip(draw, priv->xregion); + } + + XftDrawString16(draw, &color, GetXftFont(), aX, aY + mBaselineAdjust, + (FcChar16 *)aString, aLength); + + return GetWidth(aString, aLength); +} + +gint +nsFontGTKXft::DrawString8(nsRenderingContextGTK *aContext, + nsDrawingSurfaceGTK* aSurface, + nscoord aX, nscoord aY, + const char* aString, + PRUint32 aLength) +{ + XftColor color; + nscolor rccolor; + + aContext->GetColor(rccolor); + + color.pixel = gdk_rgb_xpixel_from_rgb(NS_TO_GDK_RGB(rccolor)); + color.color.red = (NS_GET_R(rccolor) << 8) | NS_GET_R(rccolor); + color.color.green = (NS_GET_G(rccolor) << 8) | NS_GET_G(rccolor); + color.color.blue = (NS_GET_B(rccolor) << 8) | NS_GET_B(rccolor); + color.color.alpha = 0xffff; + + XftDraw *draw = aSurface->GetXftDraw(); + + nsCOMPtr lastRegion; + nsCOMPtr clipRegion; + + aSurface->GetLastXftClip(getter_AddRefs(lastRegion)); + aContext->GetClipRegion(getter_AddRefs(clipRegion)); + + // avoid setting the clip, if possible + if (!lastRegion || !clipRegion || !lastRegion->IsEqual(*clipRegion)) { + aSurface->SetLastXftClip(clipRegion); + + GdkRegion *rgn = nsnull; + clipRegion->GetNativeRegion((void *&)rgn); + GdkRegionPrivate *priv = (GdkRegionPrivate *)rgn; + + XftDrawSetClip(draw, priv->xregion); + } + + XftDrawString8(draw, &color, GetXftFont(), aX, aY + mBaselineAdjust, + (FcChar8 *)aString, aLength); + + return aLength; +} + +void +nsFontGTKXft::GetFontProperties(float &aScale, + nscoord &aAscent, + nscoord &aDescent, + nscoord &aLineSpacing, + nscoord &aWidthMaxBounds, + float &aSpaceWidth, + float &aXHeight, + float &aUnderlinePosition, + nscoord &aUnderlineThickness, + nscoord &aSuperscriptOffset, + nscoord &aSubscriptOffset) +{ + FT_Face face; + TT_OS2 *os2; + XftFont *xftFont = GetXftFont(); + + face = XftLockFace(xftFont); + os2 = (TT_OS2 *) FT_Get_Sfnt_Table(face, ft_sfnt_os2); + + // aAscent + aAscent = xftFont->ascent; + // aDescent + aDescent = xftFont->descent; + // aLineSpacing + aLineSpacing = xftFont->height; + // aWidthMaxBounds + aWidthMaxBounds = xftFont->max_advance_width; + + // aSpaceWidth + PRUnichar unispace(' '); + aSpaceWidth = GetWidth(&unispace, 1); + + // aXHeight + PRUnichar xUnichar('x'); + if (SupportsChar(xUnichar)) { + XGlyphInfo extents; + XftTextExtents16(GDK_DISPLAY(), xftFont, &xUnichar, 1, &extents); + aXHeight = extents.height; + } + else { + // 56% of ascent, best guess for non-true type or asian fonts + aXHeight = ((float)aAscent) * 0.56; + } + + float val; + + // aUnderlinePosition + val = face->underline_position >> 16; + // val = FT_MulFix(face->underline_position, face->size->metrics.x_scale); + if (val) + aUnderlinePosition = -val; + else + aUnderlinePosition = -MAX(1, floor(0.1 * xftFont->height + 0.5)); + + // aUnderlineThickness + val = face->underline_thickness >> 16; + // val = FT_MulFix(face->underline_thickness, face->size->metrics.x_scale); + if (val) { + aUnderlineThickness = nscoord(MAX(aScale, NSToIntRound(val * aScale))); + } + else { + aUnderlineThickness = + NSToIntRound(MAX(1, floor(0.05 * xftFont->height + 0.5)) * aScale); + } + + // aSuperscriptOffset + if (os2 && os2->ySuperscriptYOffset) { + //val = FT_MulFix(os2->ySuperscriptYOffset, face->size->metrics.x_scale); + val = os2->ySuperscriptYOffset >> 16; + aSuperscriptOffset = nscoord(MAX(aScale, NSToIntRound(val * aScale))); + } + else { + aSuperscriptOffset = NSToIntRound(aXHeight * aScale); + } + + // aSubscriptOffset + if (os2 && os2->ySubscriptYOffset) { + // val = FT_MulFix(os2->ySubscriptYOffset, face->size->metrics.x_scale); + val = os2->ySubscriptYOffset >> 16; + aSubscriptOffset = nscoord(MAX(aScale, NSToIntRound(val * aScale))); + } + else { + aSubscriptOffset = NSToIntRound(aXHeight * aScale); + } + + XftUnlockFace(xftFont); +} + +#ifdef MOZ_MATHML +nsresult +nsFontGTKXft::GetBoundingMetrics(const PRUnichar* aString, + PRUint32 aLength, + nsBoundingMetrics& aBoundingMetrics) +{ + aBoundingMetrics.Clear (); + + if (aString && aLength) { + XGlyphInfo info; + XftTextExtents16 (GDK_DISPLAY (), GetXftFont(), (FcChar16 *) aString, + aLength, &info); + aBoundingMetrics.leftBearing = info.x; + aBoundingMetrics.rightBearing = info.width - info.x; + aBoundingMetrics.ascent = -info.y; + aBoundingMetrics.descent = info.height + info.y; + aBoundingMetrics.width = info.xOff; + } + return NS_OK; +} +#endif /* MOZ_MATHML */ + +PRBool +UseXft (void) +{ + static PRBool been_here_done_that = PR_FALSE; + static PRBool use_xft; + if (!been_here_done_that) + { + char *e = getenv ("MOZILLA_XFT"); + been_here_done_that = PR_TRUE; + use_xft = !e || atoi(e) == 1; + } + return use_xft; +} + +static FcPattern * +AddLangGroup (FcPattern *fcPat, + nsIAtom *aLangGroup) +{ + return xftAddMozLangAtom (aLangGroup, fcPat); +} + +static FcPattern * +ListLangGroup (nsIAtom *aLangGroup, const char *aGeneric) +{ + return xftAddMozLangAtom (aLangGroup, 0); +} + +static int +FFRECountHyphens (nsACString &aFFREName) +{ + int h = 0; + PRInt32 hyphen = 0; + while ((hyphen = aFFREName.FindChar('-', hyphen)) >= 0) { + h++; + hyphen++; + } + return h; +} + +static void +FFREToFamily(nsACString &aFFREName, nsACString &oFamily) +{ + if (FFRECountHyphens(aFFREName) == 3) + { + PRInt32 familyHyphen = aFFREName.FindChar('-') + 1; + PRInt32 registryHyphen = aFFREName.FindChar('-',familyHyphen); + oFamily.Append(PromiseFlatCString(aFFREName).get() + familyHyphen, + registryHyphen - familyHyphen); + } + else + oFamily.Append(aFFREName); +} + +struct nsXftFontSearch +{ + FcPattern *fcPat; + nsIAtom *langGroup; + PRBool weak; +}; + +static void +nsXftAddFFRE (FcPattern *fcPat, nsCString *familyName, PRBool weak) +{ + nsCAutoString family; + FFREToFamily (*familyName, family); + + FcValue v; + v.type = FcTypeString; + v.u.s = (FcChar8 *) family.get (); + if (weak) + FcPatternAddWeak (fcPat, FC_FAMILY, v, FcTrue); + else + FcPatternAdd (fcPat, FC_FAMILY, v, FcTrue); +} + +static PRBool +PrefXftMatchLang (const char *pref, nsIAtom *aLangGroup) +{ + if (aLangGroup) { + const char *lang = atomToName (aLangGroup); + int nlen = strlen (pref); + int alen = strlen (lang); + + if (alen > nlen || strcmp (pref + (nlen - alen), lang) != 0) + return PR_FALSE; + } + return PR_TRUE; +} + +static void +PrefXftEnumCallback(const char* aName, void* aClosure) +{ + nsXftFontSearch *s = (nsXftFontSearch *) aClosure; + + if (!PrefXftMatchLang (aName, s->langGroup)) + return; + nsXPIDLCString value; + gPref->CopyCharPref(aName, getter_Copies(value)); + nsCAutoString name; + if (value) { + name = value; + nsXftAddFFRE (s->fcPat, &name, s->weak); + } + gPref->CopyDefaultCharPref(aName, getter_Copies(value)); + if (value) { + name = value; + nsXftAddFFRE (s->fcPat, &name, s->weak); + } +} + +nsFontGTK * +nsFontMetricsGTK::FindXftFont(PRUnichar aChar) +{ + if (!mLoadedFontsCount) + { + FcPattern *fcPat; + + fcPat = FcPatternCreate (); + + /* Add user-defined family */ + if (mIsUserDefined && !mUserDefined.Equals(*mGeneric)) + FcPatternAddString (fcPat, FC_FAMILY, (const FcChar8 *) mUserDefined.get()); + + /* Add CSS names */ + for (int i = 0; i < mFonts.Count (); i++) + { + nsCString *familyName = mFonts.CStringAt(i); + if (!familyName->Equals(*mGeneric)) + nsXftAddFFRE (fcPat, familyName, PR_FALSE); + } + + if (0) + { + /* Add user preference names */ + // + // Search all font prefs for generic + // + nsCAutoString prefix("font.name."); + prefix.Append(*mGeneric); + prefix.Append("."); + prefix.Append(atomToName(mLangGroup)); + nsXftFontSearch search = { fcPat, mLangGroup, PR_TRUE }; + FIND_FONT_PRINTF((" Search all font prefs for generic")); + gPref->EnumerateChildren(prefix.get(), PrefXftEnumCallback, &search); + } + + // + // Add language group + // + fcPat = AddLangGroup (fcPat, mLangGroup); + + // + // Add the generic name to use the Fontconfig mappings + // + FcPatternAddString (fcPat, FC_FAMILY, (const FcChar8 *) mGeneric->get()); + + if (0) + { + // + // Search all font prefs + // + // find based on all prefs (no generic part (eg: sans-serif)) + nsCAutoString allPrefs("font.name."); + FIND_FONT_PRINTF((" Search all font prefs")); + nsXftFontSearch search = { fcPat, mLangGroup, PR_TRUE }; + gPref->EnumerateChildren(allPrefs.get(), PrefXftEnumCallback, &search); + } + + /* Add the style bits */ + FcPatternAddInteger (fcPat, FC_PIXEL_SIZE, mPixelSize); + + int fcSlant = FC_SLANT_ROMAN; + + switch(mFont->style) { + case NS_FONT_STYLE_ITALIC: + fcSlant = FC_SLANT_ITALIC; + break; + case NS_FONT_STYLE_OBLIQUE: + fcSlant = FC_SLANT_OBLIQUE; + break; + } + + FcPatternAddInteger(fcPat, FC_SLANT, fcSlant); + + /* + * 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 = (mFont->weight + 50) / 100; + PRInt32 offset = mFont->weight - baseWeight * 100; + + /* clip weights to range 0 to 9 */ + if (baseWeight < 0) baseWeight = 0; + if (baseWeight > 9) baseWeight = 9; + + /* Map to final FC_WEIGHT value */ + static int fcWeights[5] = { + FC_WEIGHT_LIGHT, /* 0 */ + FC_WEIGHT_MEDIUM, /* 1 */ + FC_WEIGHT_DEMIBOLD, /* 2 */ + FC_WEIGHT_BOLD, /* 3 */ + FC_WEIGHT_BLACK, /* 4 */ + }; + + /* 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; + + FcPatternAddInteger(fcPat, FC_WEIGHT, fcWeights[fcWeight]); + +#if 0 + FcChar8 *name = FcNameUnparse (fcPat); + if (name) { + printf ("font %s\n", name); + free (name); + } +#endif + + /* Go forth and match */ + FcFontSet *set; + FcCharSet *charset; + FcResult result; + + FcConfigSubstitute (0, fcPat, FcMatchPattern); + XftDefaultSubstitute (GDK_DISPLAY(), + DefaultScreen (GDK_DISPLAY ()), + fcPat); + + set = FcFontSort (0, fcPat, FcTrue, &charset, &result); + FcCharSetDestroy (charset); + + if (set) + { + for (int i = 0; i < set->nfont; i++) + { + nsFontGTKXft *font = new nsFontGTKXft (fcPat, set->fonts[i]); + AddToLoadedFontsList (font); + } + FcFontSetDestroy (set); + } + FcPatternDestroy (fcPat); + } + + for (int i = 0; i < mLoadedFontsCount; i++) + { + nsFontGTK *font = mLoadedFonts[i]; + if (font->SupportsChar (aChar)) + return font; + } + + /* + * Return the first font for any glyphs not in any font + * Tag this font with all of the glyphs we've substituted in to + * avoid traversing the whole list every time we hit a missing glyph + */ + nsFontGTKXft *font = (nsFontGTKXft *) mLoadedFonts[0]; + + if (!font->mSubstituteChars) + font->mSubstituteChars = FcCharSetCreate (); + if (font->mSubstituteChars) + FcCharSetAddChar (font->mSubstituteChars, aChar); + return font; +} + +static int +CompareXftFontNames(const void* aArg1, const void* aArg2, void* aClosure) +{ + const PRUnichar* str1 = *((const PRUnichar**) aArg1); + const PRUnichar* str2 = *((const PRUnichar**) aArg2); + + // XXX add nsICollation stuff + + return nsCRT::strcmp(str1, str2); +} + +static nsresult +EnumXftFonts(nsIAtom* aLangGroup, const char* aGeneric, PRUint32* aCount, + PRUnichar*** aResult) +{ + PRUnichar **array; + PRUint32 narray; + FcPattern *pat; + FcObjectSet *os = FcObjectSetBuild (FC_FAMILY, FC_FOUNDRY, 0); + FcFontSet *fs; + + fs = 0; + if ((pat = ListLangGroup (aLangGroup, aGeneric))) { + fs = FcFontList (0, pat, os); + if (fs && !fs->nfont) { + FcFontSetDestroy (fs); + fs = 0; + } + FcPatternDestroy (pat); + } + + if (!fs && (pat = FcPatternCreate ())) { + fs = FcFontList (0, pat, os); + FcPatternDestroy (pat); + } + FcObjectSetDestroy (os); + + if (!fs) + return NS_ERROR_OUT_OF_MEMORY; + + array = (PRUnichar**) nsMemory::Alloc(fs->nfont * sizeof(PRUnichar*)); + narray = 0; + for (int i = 0; i < fs->nfont; i++) { + char *family, *foundry; + PRUnichar *name; + + if (FcPatternGetString (fs->fonts[i], FC_FOUNDRY, 0, (FcChar8 **) &foundry) != + FcResultMatch) + foundry = "*"; + + if (FcPatternGetString (fs->fonts[i], FC_FAMILY, 0, (FcChar8 **) &family) != + FcResultMatch) + family = "*"; + + name = (PRUnichar *) nsMemory::Alloc ((strlen (foundry) + + 1 + + strlen (family) + + strlen ("-iso10646-1") + + 1) * sizeof (PRUnichar)); + if (!name) { + for (PRUint32 j = 0; j < narray; j++) + nsMemory::Free (array[j]); + nsMemory::Free (array); + return NS_ERROR_OUT_OF_MEMORY; + } + + PRUnichar *r = name; + for (char *f = foundry; *f; f++) + *r++ = *f; + *r++ = '-'; + for (char *f = family; *f; f++) + *r++ = *f; + for (char *f = "-iso10646-1"; *f; f++) + *r++ = *f; + *r++ = '\0'; + + array[narray++] = name; + } + FcFontSetDestroy (fs); + NS_QuickSort(array, narray, sizeof (PRUnichar*), CompareXftFontNames, nsnull); + *aCount = narray; + if (narray) + *aResult = array; + else + nsMemory::Free(array); + return NS_OK; +} +#endif /* MOZ_ENABLE_XFT */ + nsFontGTK* nsFontMetricsGTK::AddToLoadedFontsList(nsFontGTK* aFont) { @@ -4853,6 +5754,11 @@ { FIND_FONT_PRINTF(("\nFindFont(%c/0x%04x)", aChar, aChar)); +#ifdef MOZ_ENABLE_XFT + if (UseXft ()) { + return FindXftFont(aChar); + } +#endif /* MOZ_ENABLE_XFT */ nsFontGTK* font = FindUserDefinedFont(aChar); if (!font) { font = FindStyleSheetSpecificFont(aChar); @@ -4964,6 +5870,11 @@ EnumFonts(nsIAtom* aLangGroup, const char* aGeneric, PRUint32* aCount, PRUnichar*** aResult) { +#ifdef MOZ_ENABLE_XFT + if (UseXft ()) { + return EnumXftFonts (aLangGroup, aGeneric, aCount, aResult); + } +#endif /* MOZ_ENABLE_XFT */ nsresult res = GetAllFontNames(); if (NS_FAILED(res)) { return res; Index: gfx/src/gtk/nsFontMetricsGTK.h =================================================================== RCS file: /cvsroot/mozilla/gfx/src/gtk/nsFontMetricsGTK.h,v retrieving revision 1.48.2.2 diff -u -r1.48.2.2 nsFontMetricsGTK.h --- gfx/src/gtk/nsFontMetricsGTK.h 20 Jun 2002 02:03:39 -0000 1.48.2.2 +++ gfx/src/gtk/nsFontMetricsGTK.h 2 Sep 2002 15:02:50 -0000 @@ -222,18 +222,36 @@ void LoadFont(void); PRBool IsEmptyFont(XFontStruct*); - inline int SupportsChar(PRUnichar aChar) - { return mCCMap && CCMAP_HAS_CHAR(mCCMap, aChar); }; + virtual int SupportsChar(PRUnichar aChar); virtual GdkFont* GetGDKFont(void); virtual nsXFont* GetXFont(void); virtual PRBool GetXFontIs10646(void); + virtual PRBool IsXftFont(void); virtual PRBool IsFreeTypeFont(void); + virtual gint GetWidth8(const char *aString, PRUint32 aLength); virtual gint GetWidth(const PRUnichar* aString, PRUint32 aLength) = 0; + virtual gint DrawString8(nsRenderingContextGTK *aContext, + nsDrawingSurfaceGTK* aSurface, + nscoord aX, nscoord aY, + const char* aString, + PRUint32 aLength); virtual gint DrawString(nsRenderingContextGTK* aContext, nsDrawingSurfaceGTK* aSurface, nscoord aX, nscoord aY, const PRUnichar* aString, PRUint32 aLength) = 0; + virtual void GetFontProperties(float &aScale, + nscoord &aAscent, + nscoord &aDescent, + nscoord &aLineSpacing, + nscoord &aWidthMaxBounds, + float &aSpaceWidth, + float &aXHeight, + float &aUnderlinePosition, + nscoord &aUnderlineThickness, + nscoord &aSuperscriptOffset, + nscoord &aSubscriptOffset); + #ifdef MOZ_MATHML // bounding metrics for a string // remember returned values are not in app units @@ -301,6 +319,9 @@ NS_IMETHOD GetSpaceWidth(nscoord &aSpaceWidth); nsFontGTK* FindFont(PRUnichar aChar); +#ifdef MOZ_ENABLE_XFT + nsFontGTK* FindXftFont(PRUnichar aChar); +#endif nsFontGTK* FindUserDefinedFont(PRUnichar aChar); nsFontGTK* FindStyleSheetSpecificFont(PRUnichar aChar); nsFontGTK* FindStyleSheetGenericFont(PRUnichar aChar); Index: gfx/src/gtk/nsRenderingContextGTK.cpp =================================================================== RCS file: /cvsroot/mozilla/gfx/src/gtk/nsRenderingContextGTK.cpp,v retrieving revision 1.156.8.2 diff -u -r1.156.8.2 nsRenderingContextGTK.cpp --- gfx/src/gtk/nsRenderingContextGTK.cpp 31 May 2002 22:32:38 -0000 1.156.8.2 +++ gfx/src/gtk/nsRenderingContextGTK.cpp 2 Sep 2002 15:02:54 -0000 @@ -1304,6 +1304,12 @@ g_return_val_if_fail(mCurrentFont != NULL, NS_ERROR_FAILURE); gint rawWidth; nsXFont *xFont = mCurrentFont->GetXFont(); +#ifdef MOZ_ENABLE_XFT + if (mCurrentFont->IsXftFont()) { + rawWidth = mCurrentFont->GetWidth8(aString, aLength); + } + else +#endif if (mCurrentFont->IsFreeTypeFont()) { PRUnichar unichars[WIDEN_8_TO_16_BUF_SIZE]; // need to fix this for long strings @@ -1354,7 +1360,7 @@ nsFontGTK** font = metrics->mLoadedFonts; nsFontGTK** end = &metrics->mLoadedFonts[metrics->mLoadedFontsCount]; while (font < end) { - if (CCMAP_HAS_CHAR((*font)->mCCMap, c)) { + if ((*font)->SupportsChar(c)) { currFont = *font; goto FoundFont; // for speed -- avoid "if" statement } @@ -1419,7 +1425,7 @@ nsFontGTK** font = metrics->mLoadedFonts; nsFontGTK** end = &metrics->mLoadedFonts[metrics->mLoadedFontsCount]; while (font < end) { - if (CCMAP_HAS_CHAR((*font)->mCCMap, c)) { + if ((*font)->SupportsChar(c)) { currFont = *font; goto FoundFont; // for speed -- avoid "if" statement } @@ -1490,6 +1496,12 @@ nscoord xx = x; nscoord yy = y; mTranMatrix->TransformCoord(&xx, &yy); +#ifdef MOZ_ENABLE_XFT + if (mCurrentFont->IsXftFont()) { + mCurrentFont->DrawString8(this, mSurface, xx, yy, &ch, 1); + } + else +#endif if (mCurrentFont->IsFreeTypeFont()) { PRUnichar unichars[WIDEN_8_TO_16_BUF_SIZE]; // need to fix this for long strings @@ -1518,6 +1530,12 @@ } else { mTranMatrix->TransformCoord(&x, &y); +#ifdef MOZ_ENABLE_XFT + if (mCurrentFont->IsXftFont()) { + mCurrentFont->DrawString8(this, mSurface, x, y, aString, aLength); + } + else +#endif if (mCurrentFont->IsFreeTypeFont()) { PRUnichar unichars[WIDEN_8_TO_16_BUF_SIZE]; // need to fix this for long strings @@ -1607,7 +1625,7 @@ nsFontGTK** font = metrics->mLoadedFonts; nsFontGTK** lastFont = &metrics->mLoadedFonts[metrics->mLoadedFontsCount]; while (font < lastFont) { - if (CCMAP_HAS_CHAR((*font)->mCCMap, c)) { + if ((*font)->SupportsChar(c)) { currFont = *font; goto FoundFont; // for speed -- avoid "if" statement } @@ -1989,7 +2007,7 @@ nsFontGTK** font = metrics->mLoadedFonts; nsFontGTK** end = &metrics->mLoadedFonts[metrics->mLoadedFontsCount]; while (font < end) { - if (CCMAP_HAS_CHAR((*font)->mCCMap, c)) { + if ((*font)->SupportsChar(c)) { currFont = *font; goto FoundFont; // for speed -- avoid "if" statement } Index: gfx/src/x11shared/nsFT2FontCatalog.cpp =================================================================== RCS file: /cvsroot/mozilla/gfx/src/x11shared/nsFT2FontCatalog.cpp,v retrieving revision 1.8.2.5 diff -u -r1.8.2.5 nsFT2FontCatalog.cpp --- gfx/src/x11shared/nsFT2FontCatalog.cpp 19 Jul 2002 23:39:10 -0000 1.8.2.5 +++ gfx/src/x11shared/nsFT2FontCatalog.cpp 2 Sep 2002 15:03:01 -0000 @@ -100,7 +100,9 @@ // // Solaris is missing a prototype for ctime +extern "C" { extern char *ctime(const time_t *timep); +} #include #include FT_GLYPH_H