Bug 339513 neutral characters rendering problem (refactoring of gfxPangoTextRun) r=vlad+pavlov

This commit is contained in:
masayuki%d-toybox.com 2006-09-26 04:20:41 +00:00
parent 02908cee68
commit 6601a25062
14 changed files with 1056 additions and 242 deletions

View File

@ -94,6 +94,7 @@ public:
protected:
static PRBool FindATSUFont(const nsAString& aName,
const nsACString& aGenericName,
const nsACString& aLangGroup,
void *closure);
ATSUFontFallbacks mFallbacks;

View File

@ -184,7 +184,10 @@ public:
/* helper function for splitting font families on commas and
* calling a function for each family to fill the mFonts array
*/
typedef PRBool (*FontCreationCallback) (const nsAString& aName, const nsACString& aGenericName, void *closure);
typedef PRBool (*FontCreationCallback) (const nsAString& aName,
const nsACString& aGenericName,
const nsACString& aLangGroup,
void *closure);
static PRBool ForEachFont(const nsAString& aFamilies,
const nsACString& aLangGroup,
FontCreationCallback fc,
@ -201,9 +204,9 @@ protected:
static PRBool ForEachFontInternal(const nsAString& aFamilies,
const nsACString& aLangGroup,
PRBool aResolveGeneric,
FontCreationCallback fc,
void *closure,
PRBool aAllowRecursive);
void *closure);
};

View File

@ -44,16 +44,24 @@
#include <pango/pango.h>
#include <X11/Xft/Xft.h>
#include "nsDataHashtable.h"
class gfxPangoFont : public gfxFont {
public:
gfxPangoFont (const nsAString& aName,
const gfxFontStyle *aFontStyle);
const gfxFontStyle *aFontStyle,
PangoLanguage* aPangoLang = nsnull);
virtual ~gfxPangoFont ();
virtual const gfxFont::Metrics& GetMetrics();
PangoFontDescription* GetPangoFontDescription() { RealizeFont(); return mPangoFontDesc; }
PangoContext* GetPangoContext() { RealizeFont(); return mPangoCtx; }
void GetMozLang(nsACString &aMozLang);
void GetActualFontFamily(nsACString &aFamily);
PangoFont* GetPangoFont();
XftFont * GetXftFont () { RealizeXftFont (); return mXftFont; }
protected:
@ -65,6 +73,10 @@ protected:
PRBool mHasMetrics;
Metrics mMetrics;
PangoLanguage *mPangoLang;
nsCString mMozLang;
nsCString mActualFontFamily;
void RealizeFont(PRBool force = PR_FALSE);
void RealizeXftFont(PRBool force = PR_FALSE);
void GetSize(const char *aString, PRUint32 aLength, gfxSize& inkSize, gfxSize& logSize);
@ -84,10 +96,24 @@ public:
NS_STATIC_CAST(gfxFont*, mFonts[i]));
}
gfxPangoFont *GetCachedFont(const nsAString& aName) const {
nsRefPtr<gfxPangoFont> font;
if (mFontCache.Get(aName, &font))
return font;
return nsnull;
}
void PutCachedFont(const nsAString& aName, gfxPangoFont *aFont) {
mFontCache.Put(aName, aFont);
}
protected:
static PRBool FontCallback (const nsAString& fontName,
const nsACString& genericName,
const nsACString& aLangGroup,
void *closure);
private:
nsDataHashtable<nsStringHashKey, nsRefPtr<gfxPangoFont> > mFontCache;
nsTArray<gfxFontStyle> mAdditionalStyles;
};
class THEBES_API gfxXftTextRun : public gfxTextRun {
@ -133,9 +159,15 @@ private:
gfxPangoFontGroup *mGroup;
PangoLayout *mPangoLayout;
int mWidth, mHeight;
int mWidth;
void EnsurePangoLayout(gfxContext *aContext = nsnull);
int MeasureOrDraw(gfxContext *aContext, PRBool aDraw, gfxPoint aPt);
int MeasureOrDrawFast(gfxContext *aContext, PRBool aDraw,
gfxPoint aPt, nsAFlatCString &aUTF8Str,
PRBool aIsRTL, gfxPangoFont *aFont);
int MeasureOrDrawItemizing(gfxContext *aContext, PRBool aDraw,
gfxPoint aPt, nsAFlatCString &aUTF8Str,
PRBool aIsRTL, gfxPangoFont *aFont);
nsTArray<gfxFloat> mSpacing;
nsTArray<PRInt32> mUTF8Spacing;

View File

@ -102,6 +102,8 @@ public:
PRUint32 height,
PRUint32 stride);
void GetPrefFonts(const char *aLangGroup, nsString& array);
protected:
gfxPlatform() { }
virtual ~gfxPlatform() { }

View File

@ -452,7 +452,10 @@ public:
}
protected:
static PRBool MakeFont(const nsAString& fontName, const nsACString& genericName, void *closure);
static PRBool MakeFont(const nsAString& fontName,
const nsACString& genericName,
const nsACString& aLangGroup,
void *closure);
private:
friend class gfxWindowsTextRun;

View File

@ -67,7 +67,6 @@ public:
/* local methods */
void GetPrefFonts(const char *aLangGroup, nsString& array);
void FindOtherFonts(const PRUnichar *aString, PRUint32 aLength, const char *aLangGroup, const char *aGeneric, nsString& array);
WeightTable *GetFontWeightTable(const nsAString& aName);

View File

@ -67,6 +67,7 @@ ifeq ($(MOZ_GFX_TOOLKIT),gtk2)
CPPSRCS += gfxXlibSurface.cpp gfxPlatformGtk.cpp gfxXlibNativeRenderer.cpp
CPPSRCS += gfxPangoFonts.cpp
CPPSRCS += gfxPDFSurface.cpp gfxPSSurface.cpp
CPPSRCS += nsUnicodeRange.cpp
CSRCS = cairo-xlib-utils.c
EXTRA_DSO_LDOPTS += $(MOZ_PANGO_LIBS) $(ZLIB_LIBS) $(MOZ_XFT_LIBS) $(XLDFLAGS) $(XLIBS)
endif
@ -75,6 +76,7 @@ ifeq ($(MOZ_GFX_TOOLKIT),beos)
CPPSRCS += gfxBeOSSurface.cpp gfxBeOSPlatform.cpp
CPPSRCS += gfxPangoFonts.cpp
#CPPSRCS += gfxPDFSurface.cpp
CPPSRCS += nsUnicodeRange.cpp
EXTRA_DSO_LDOPTS += $(MOZ_PANGO_LIBS) $(CAIRO_FT_LIBS) -lfontconfig -lpangocairo-1.0
endif

View File

@ -256,6 +256,7 @@ gfxAtsuiFontGroup::gfxAtsuiFontGroup(const nsAString& families,
PRBool
gfxAtsuiFontGroup::FindATSUFont(const nsAString& aName,
const nsACString& aGenericName,
const nsACString& aLangGroup,
void *closure)
{
gfxAtsuiFontGroup *fontGroup = (gfxAtsuiFontGroup*) closure;

View File

@ -63,7 +63,8 @@ PRBool
gfxFontGroup::ForEachFont(FontCreationCallback fc,
void *closure)
{
return ForEachFont(mFamilies, mStyle.langGroup, fc, closure);
return ForEachFontInternal(mFamilies, mStyle.langGroup,
PR_TRUE, fc, closure);
}
PRBool
@ -73,15 +74,15 @@ gfxFontGroup::ForEachFont(const nsAString& aFamilies,
void *closure)
{
return ForEachFontInternal(aFamilies, aLangGroup,
fc, closure, PR_TRUE);
PR_FALSE, fc, closure);
}
PRBool
gfxFontGroup::ForEachFontInternal(const nsAString& aFamilies,
const nsACString& aLangGroup,
PRBool aResolveGeneric,
FontCreationCallback fc,
void *closure,
PRBool aAllowRecursive)
void *closure)
{
const PRUnichar kSingleQuote = PRUnichar('\'');
const PRUnichar kDoubleQuote = PRUnichar('\"');
@ -97,6 +98,9 @@ gfxFontGroup::ForEachFontInternal(const nsAString& aFamilies,
nsAutoString family;
nsCAutoString lcFamily;
nsAutoString genericFamily;
nsCAutoString lang(aLangGroup);
if (lang.IsEmpty())
lang.Assign("x-unicode"); // XXX or should use "x-user-def"?
while (p < p_end) {
while (nsCRT::IsAsciiSpace(*p))
@ -131,11 +135,12 @@ gfxFontGroup::ForEachFontInternal(const nsAString& aFamilies,
family = Substring(nameStart, p);
family.CompressWhitespace(PR_FALSE, PR_TRUE);
if (family.LowerCaseEqualsLiteral("serif") ||
family.LowerCaseEqualsLiteral("sans-serif") ||
family.LowerCaseEqualsLiteral("monospace") ||
family.LowerCaseEqualsLiteral("cursive") ||
family.LowerCaseEqualsLiteral("fantasy"))
if (aResolveGeneric &&
(family.LowerCaseEqualsLiteral("serif") ||
family.LowerCaseEqualsLiteral("sans-serif") ||
family.LowerCaseEqualsLiteral("monospace") ||
family.LowerCaseEqualsLiteral("cursive") ||
family.LowerCaseEqualsLiteral("fantasy")))
{
generic = PR_TRUE;
@ -144,7 +149,7 @@ gfxFontGroup::ForEachFontInternal(const nsAString& aFamilies,
nsCAutoString prefName("font.name.");
prefName.Append(lcFamily);
prefName.AppendLiteral(".");
prefName.Append(aLangGroup);
prefName.Append(lang);
// prefs file always uses (must use) UTF-8 so that we can use
// |GetCharPref| and treat the result as a UTF-8 string.
@ -161,11 +166,12 @@ gfxFontGroup::ForEachFontInternal(const nsAString& aFamilies,
}
if (!family.IsEmpty()) {
if (!((*fc) (family, NS_LossyConvertUTF16toASCII(genericFamily), closure)))
if (!((*fc) (family, NS_LossyConvertUTF16toASCII(genericFamily),
lang, closure)))
return PR_FALSE;
}
if (generic && aAllowRecursive) {
if (generic && aResolveGeneric) {
nsCAutoString prefName("font.name-list.");
prefName.Append(lcFamily);
prefName.AppendLiteral(".");
@ -173,7 +179,7 @@ gfxFontGroup::ForEachFontInternal(const nsAString& aFamilies,
nsXPIDLString value;
nsresult rv = prefs->CopyUnicharPref(prefName.get(), getter_Copies(value));
if (NS_SUCCEEDED(rv)) {
ForEachFontInternal(value, aLangGroup, fc, closure, PR_FALSE);
ForEachFontInternal(value, lang, PR_FALSE, fc, closure);
}
}
@ -207,7 +213,8 @@ gfxFontGroup::FindGenericFontFromStyle(FontCreationCallback fc,
rv = prefs->CopyUnicharPref(prefName.get(), getter_Copies(familyName));
if (NS_SUCCEEDED(rv)) {
(*fc)(familyName, NS_LossyConvertUTF16toASCII(genericName), closure);
(*fc)(familyName, NS_LossyConvertUTF16toASCII(genericName),
mStyle.langGroup, closure);
}
prefName.AssignLiteral("font.name-list.");
@ -218,7 +225,7 @@ gfxFontGroup::FindGenericFontFromStyle(FontCreationCallback fc,
rv = prefs->CopyUnicharPref(prefName.get(), getter_Copies(familyName));
if (NS_SUCCEEDED(rv)) {
ForEachFontInternal(familyName, mStyle.langGroup,
fc, closure, PR_FALSE);
PR_FALSE, fc, closure);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -50,6 +50,9 @@
#include "gfxContext.h"
#include "gfxImageSurface.h"
#include "nsIPref.h"
#include "nsServiceManagerUtils.h"
#ifdef MOZ_ENABLE_GLITZ
#include <stdlib.h>
#endif
@ -166,3 +169,58 @@ gfxPlatform::UpdateFontList()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
static void
AppendGenericFontFromPref(nsString& aFonts, const char *aLangGroup, const char *aGenericName)
{
nsresult rv;
nsCOMPtr<nsIPref> prefs(do_GetService(NS_PREF_CONTRACTID));
if (!prefs)
return;
nsCAutoString prefName;
nsXPIDLString value;
nsXPIDLString genericName;
if (aGenericName) {
genericName = NS_ConvertASCIItoUTF16(aGenericName);
} else {
prefName.AssignLiteral("font.default.");
prefName.Append(aLangGroup);
prefs->CopyUnicharPref(prefName.get(), getter_Copies(genericName));
}
nsCAutoString genericDotLang;
genericDotLang.Assign(NS_ConvertUTF16toUTF8(genericName));
genericDotLang.AppendLiteral(".");
genericDotLang.Append(aLangGroup);
prefName.AssignLiteral("font.name.");
prefName.Append(genericDotLang);
rv = prefs->CopyUnicharPref(prefName.get(), getter_Copies(value));
if (NS_SUCCEEDED(rv)) {
if (!aFonts.IsEmpty())
aFonts.AppendLiteral(", ");
aFonts.Append(value);
}
prefName.AssignLiteral("font.name-list.");
prefName.Append(genericDotLang);
rv = prefs->CopyUnicharPref(prefName.get(), getter_Copies(value));
if (NS_SUCCEEDED(rv)) {
if (!aFonts.IsEmpty())
aFonts.AppendLiteral(", ");
aFonts.Append(value);
}
}
void
gfxPlatform::GetPrefFonts(const char *aLangGroup, nsString& aFonts)
{
aFonts.Truncate();
AppendGenericFontFromPref(aFonts, aLangGroup, nsnull);
AppendGenericFontFromPref(aFonts, "x-unicode", nsnull);
}

View File

@ -292,7 +292,7 @@ gfxPlatformGtk::GetFontList(const nsACString& aLangGroup,
continue;
}
aListOfFonts.AppendString(NS_ConvertASCIItoUTF16(nsDependentCString(family)));
aListOfFonts.AppendString(NS_ConvertUTF8toUTF16(nsDependentCString(family)));
}
aListOfFonts.Sort();

View File

@ -384,7 +384,10 @@ gfxWindowsFont::FillLogFont(PRInt16 currentWeight)
**********************************************************************/
PRBool
gfxWindowsFontGroup::MakeFont(const nsAString& aName, const nsACString& aGenericName, void *closure)
gfxWindowsFontGroup::MakeFont(const nsAString& aName,
const nsACString& aGenericName,
const nsACString& aLangGroup,
void *closure)
{
if (!aName.IsEmpty()) {
gfxWindowsFontGroup *fg = NS_STATIC_CAST(gfxWindowsFontGroup*, closure);
@ -941,6 +944,7 @@ public:
static PRBool AddFontCallback(const nsAString& aName,
const nsACString& aGenericName,
const nsACString& aLangGroup,
void *closure) {
if (aName.IsEmpty())
return PR_TRUE;
@ -1243,7 +1247,7 @@ private:
void AppendPrefFonts(const char *aLangGroup) {
NS_ASSERTION(aLangGroup, "aLangGroup is null");
gfxWindowsPlatform *platform = gfxWindowsPlatform::GetPlatform();
gfxPlatform *platform = gfxPlatform::GetPlatform();
nsString fonts;
platform->GetPrefFonts(aLangGroup, fonts);
if (fonts.IsEmpty())

View File

@ -254,60 +254,6 @@ gfxWindowsPlatform::FindFontForChar(nsStringHashKey::KeyType aKey,
return PL_DHASH_NEXT;
}
static void
AppendGenericFontFromPref(nsString& aFonts, const char *aLangGroup, const char *aGenericName)
{
nsresult rv;
nsCOMPtr<nsIPref> prefs(do_GetService(NS_PREF_CONTRACTID));
if (!prefs)
return;
nsCAutoString prefName;
nsXPIDLString value;
nsXPIDLString genericName;
if (aGenericName) {
genericName = NS_ConvertASCIItoUTF16(aGenericName);
} else {
prefName.AssignLiteral("font.default.");
prefName.Append(aLangGroup);
prefs->CopyUnicharPref(prefName.get(), getter_Copies(genericName));
}
nsCAutoString genericDotLang;
genericDotLang.Assign(NS_ConvertUTF16toUTF8(genericName));
genericDotLang.AppendLiteral(".");
genericDotLang.Append(aLangGroup);
prefName.AssignLiteral("font.name.");
prefName.Append(genericDotLang);
rv = prefs->CopyUnicharPref(prefName.get(), getter_Copies(value));
if (NS_SUCCEEDED(rv)) {
if (!aFonts.IsEmpty())
aFonts.AppendLiteral(", ");
aFonts.Append(value);
}
prefName.AssignLiteral("font.name-list.");
prefName.Append(genericDotLang);
rv = prefs->CopyUnicharPref(prefName.get(), getter_Copies(value));
if (NS_SUCCEEDED(rv)) {
if (!aFonts.IsEmpty())
aFonts.AppendLiteral(", ");
aFonts.Append(value);
}
}
void
gfxWindowsPlatform::GetPrefFonts(const char *aLangGroup, nsString& aFonts)
{
aFonts.Truncate();
AppendGenericFontFromPref(aFonts, aLangGroup, nsnull);
AppendGenericFontFromPref(aFonts, "x-unicode", nsnull);
}
void
gfxWindowsPlatform::FindOtherFonts(const PRUnichar* aString, PRUint32 aLength, const char *aLangGroup, const char *aGeneric, nsString& fonts)
{