mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-03 12:35:58 +00:00
Bug 30300/6588
This commit is contained in:
parent
f87982d2f2
commit
ea8a2e41a0
@ -111,14 +111,14 @@ nsUnicodeFontMappingMac* nsFontMetricsMac::GetUnicodeFontMapping()
|
||||
}
|
||||
|
||||
|
||||
static void MapGenericFamilyToFont(const nsString& aGenericFamily, nsString& aFontFace)
|
||||
static void MapGenericFamilyToFont(const nsString& aGenericFamily, nsString& aFontFace, ScriptCode aScriptCode)
|
||||
{
|
||||
// the CSS generic names (conversions from the old Mac Mozilla code for now)
|
||||
nsUnicodeMappingUtil* unicodeMappingUtil = nsUnicodeMappingUtil::GetSingleton();
|
||||
if (unicodeMappingUtil)
|
||||
{
|
||||
nsString* foundFont = unicodeMappingUtil->GenericFontNameForScript(
|
||||
smRoman, // should we be looking at a language-group here?
|
||||
aScriptCode,
|
||||
unicodeMappingUtil->MapGenericFontNameType(aGenericFamily));
|
||||
if (foundFont)
|
||||
{
|
||||
@ -160,11 +160,12 @@ static void MapGenericFamilyToFont(const nsString& aGenericFamily, nsString& aFo
|
||||
}
|
||||
|
||||
struct FontEnumData {
|
||||
FontEnumData(nsIDeviceContext* aDC, nsString& aFaceName)
|
||||
: mContext(aDC), mFaceName(aFaceName)
|
||||
FontEnumData(nsIDeviceContext* aDC, nsString& aFaceName, ScriptCode aScriptCode)
|
||||
: mContext(aDC), mFaceName(aFaceName), mScriptCode(aScriptCode)
|
||||
{}
|
||||
nsIDeviceContext* mContext;
|
||||
nsString& mFaceName;
|
||||
ScriptCode mScriptCode;
|
||||
};
|
||||
|
||||
static PRBool FontEnumCallback(const nsString& aFamily, PRBool aGeneric, void *aData)
|
||||
@ -173,7 +174,7 @@ static PRBool FontEnumCallback(const nsString& aFamily, PRBool aGeneric, void *a
|
||||
if (aGeneric)
|
||||
{
|
||||
nsAutoString realFace;
|
||||
MapGenericFamilyToFont(aFamily, realFace);
|
||||
MapGenericFamilyToFont(aFamily, realFace, data->mScriptCode);
|
||||
data->mFaceName = realFace;
|
||||
return PR_FALSE; // stop
|
||||
}
|
||||
@ -194,10 +195,37 @@ static PRBool FontEnumCallback(const nsString& aFamily, PRBool aGeneric, void *a
|
||||
void nsFontMetricsMac::RealizeFont()
|
||||
{
|
||||
nsAutoString fontName;
|
||||
FontEnumData fontData(mContext, fontName);
|
||||
mFont->EnumerateFamilies(FontEnumCallback, &fontData);
|
||||
nsUnicodeMappingUtil *unicodeMappingUtil;
|
||||
ScriptCode theScriptCode;
|
||||
|
||||
unicodeMappingUtil = nsUnicodeMappingUtil::GetSingleton ();
|
||||
if (unicodeMappingUtil)
|
||||
{
|
||||
const char *theCString;
|
||||
nsAutoString theLangGroupString;
|
||||
|
||||
if (mLangGroup)
|
||||
mLangGroup->ToString(theLangGroupString);
|
||||
else
|
||||
theLangGroupString.AssignWithConversion("ja");
|
||||
theCString = theLangGroupString.GetBuffer ();
|
||||
if (theCString)
|
||||
theScriptCode = unicodeMappingUtil->MapLangGroupToScriptCode (theCString);
|
||||
else
|
||||
{
|
||||
NS_ConvertUCS2toUTF8 theUnicodeString (theLangGroupString.GetUnicode ());
|
||||
|
||||
theScriptCode = unicodeMappingUtil->MapLangGroupToScriptCode (theUnicodeString);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
theScriptCode = GetScriptManagerVariable (smSysScript);
|
||||
|
||||
FontEnumData fontData(mContext, fontName, theScriptCode);
|
||||
mFont->EnumerateFamilies(FontEnumCallback, &fontData);
|
||||
|
||||
nsDeviceContextMac::GetMacFontNumber(fontName, mFontNum);
|
||||
nsDeviceContextMac::GetMacFontNumber(fontName, mFontNum);
|
||||
}
|
||||
|
||||
|
||||
|
@ -23,6 +23,14 @@
|
||||
#ifndef nsUnicodeBlock_h__
|
||||
#define nsUnicodeBlock_h__
|
||||
|
||||
#include <Script.h>
|
||||
|
||||
enum
|
||||
{
|
||||
smPseudoUnicode = smUninterp + 0,
|
||||
smPseudoUserDef = smUninterp + 1,
|
||||
smPseudoTotalScripts = smUninterp + 2
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
// blocks which always use the same script to render, regardless of the order of fonts
|
||||
@ -46,6 +54,7 @@ typedef enum {
|
||||
kGeorgian,
|
||||
kHangul,
|
||||
kBopomofo,
|
||||
kUserDefinedEncoding,
|
||||
|
||||
kUnicodeBlockFixedScriptMax,
|
||||
|
||||
|
@ -271,7 +271,7 @@ void nsUnicodeFontMappingMac::InitByLangGroup(const nsString& aLangGroup)
|
||||
|
||||
void nsUnicodeFontMappingMac::InitDefaultScriptFonts()
|
||||
{
|
||||
for(PRInt32 i = 0 ; i < 32; i++)
|
||||
for(PRInt32 i = 0 ; i < smPseudoTotalScripts; i++)
|
||||
{
|
||||
// copy from global mapping
|
||||
if(BAD_FONT_NUM == mScriptFallbackFontIDs[i])
|
||||
@ -293,7 +293,7 @@ nsUnicodeFontMappingMac::nsUnicodeFontMappingMac(
|
||||
PRInt32 i;
|
||||
for(i = kUnicodeBlockFixedScriptMax ; i < kUnicodeBlockSize; i++)
|
||||
mPrivBlockToScript[i - kUnicodeBlockFixedScriptMax] = BAD_SCRIPT;
|
||||
for(i = 0 ; i < 32; i++)
|
||||
for(i = 0 ; i < smPseudoTotalScripts; i++)
|
||||
mScriptFallbackFontIDs[i] = BAD_FONT_NUM;
|
||||
|
||||
InitByFontFamily(aFont, aDeviceContext);
|
||||
@ -331,7 +331,7 @@ PRBool nsUnicodeFontMappingMac::Equals(const nsUnicodeFontMappingMac& aMap)
|
||||
{
|
||||
PRUint32 i;
|
||||
if(&aMap != this) {
|
||||
for( i=0; i < 32; i++)
|
||||
for( i=0; i < smPseudoTotalScripts; i++)
|
||||
{
|
||||
if(mScriptFallbackFontIDs[i] != aMap.mScriptFallbackFontIDs[i])
|
||||
return PR_FALSE;
|
||||
@ -465,7 +465,8 @@ static nsUnicodeBlock GetBlockUFXXX(PRUnichar aChar)
|
||||
}
|
||||
|
||||
// The rest is rarely used, we don't care the performance below.
|
||||
if(aChar < 0xf900) return kOthers;
|
||||
if((0xf780 <= aChar) && (aChar <= 0xf7ff)) return kUserDefinedEncoding;
|
||||
else if(aChar < 0xf900) return kOthers;
|
||||
else if(aChar < 0xfb00) return kCJKIdeographs;
|
||||
else if(aChar < 0xfb10) return kLatin;
|
||||
else if(aChar < 0xfb18) return kArmenian;
|
||||
|
@ -55,7 +55,7 @@ protected:
|
||||
private:
|
||||
|
||||
PRInt8 mPrivBlockToScript [kUnicodeBlockVarScriptMax] ;
|
||||
short mScriptFallbackFontIDs [32] ;
|
||||
short mScriptFallbackFontIDs [smPseudoTotalScripts] ;
|
||||
static nsUnicodeMappingUtil* gUtil;
|
||||
static nsUnicodeFontMappingCache* gCache;
|
||||
};
|
||||
|
@ -64,7 +64,7 @@ void nsUnicodeMappingUtil::Init()
|
||||
}
|
||||
void nsUnicodeMappingUtil::CleanUp()
|
||||
{
|
||||
for(int i= 0 ; i < 32; i ++) {
|
||||
for(int i= 0 ; i < smPseudoTotalScripts; i ++) {
|
||||
for(int j=0; j < 5; j++) {
|
||||
if(mGenericFontMapping[i][j])
|
||||
nsString::Recycle(mGenericFontMapping[i][j]);
|
||||
@ -95,7 +95,7 @@ void nsUnicodeMappingUtil::InitScriptEnabled()
|
||||
mScriptEnabled = 0;
|
||||
PRUint32 scriptMask = 1;
|
||||
for(script = gotScripts = 0;
|
||||
((script < 32) && ( gotScripts < numOfScripts)) ;
|
||||
((script < smUninterp) && ( gotScripts < numOfScripts)) ;
|
||||
script++, scriptMask <<= 1)
|
||||
{
|
||||
if(::GetScriptVariable(script, smScriptEnabled))
|
||||
@ -106,7 +106,7 @@ void nsUnicodeMappingUtil::InitScriptEnabled()
|
||||
|
||||
void nsUnicodeMappingUtil::InitGenericFontMapping()
|
||||
{
|
||||
for(int i= 0 ; i < 32; i ++)
|
||||
for(int i= 0 ; i < smPseudoTotalScripts; i ++)
|
||||
for(int j=0; j < 5; j++)
|
||||
mGenericFontMapping[i][j] = nsnull;
|
||||
|
||||
@ -207,6 +207,12 @@ void nsUnicodeMappingUtil::InitGenericFontMapping()
|
||||
}
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// nsUnicodeMappingUtil::MapLangGroupToScriptCode
|
||||
//
|
||||
// This method normally returns ScriptCode values, but CAN RETURN pseudo-
|
||||
// ScriptCode values for Unicode (32) and User-Defined (33)
|
||||
//--------------------------------------------------------------------------
|
||||
ScriptCode nsUnicodeMappingUtil::MapLangGroupToScriptCode(const char* aLangGroup)
|
||||
{
|
||||
if(0==nsCRT::strcmp(aLangGroup, "x-western")) {
|
||||
@ -248,6 +254,12 @@ ScriptCode nsUnicodeMappingUtil::MapLangGroupToScriptCode(const char* aLangGroup
|
||||
if(0==nsCRT::strcmp(aLangGroup, "zh-TW")) {
|
||||
return smTradChinese;
|
||||
} else
|
||||
if(0==nsCRT::strcmp(aLangGroup, "x-unicode")) {
|
||||
return (smPseudoUnicode);
|
||||
} else
|
||||
if(0==nsCRT::strcmp(aLangGroup, "x-user-def")) {
|
||||
return (smPseudoUserDef);
|
||||
} else
|
||||
{
|
||||
return smRoman;
|
||||
}
|
||||
@ -274,17 +286,19 @@ PrefEnumCallback(const char* aName, void* aClosure)
|
||||
curPrefName.Mid(langGroup, p1+1, curPrefName.Length()-p1-1);
|
||||
curPrefName.Mid(genName, p2+1, p1-p2-1);
|
||||
|
||||
if(langGroup.Equals(nsCAutoString("x-unicode")))
|
||||
return;
|
||||
ScriptCode script = Self->MapLangGroupToScriptCode(langGroup);
|
||||
if(script >= smUninterp)
|
||||
if(script >= (smPseudoTotalScripts))
|
||||
{
|
||||
// Because of the pseudo-scripts of Unicode and User-Defined, we have to handle
|
||||
// the expanded ScriptCode value.
|
||||
return;
|
||||
}
|
||||
if((script == smRoman) && !langGroup.Equals(nsCAutoString("x-western"))) {
|
||||
// need special processing for t,r x-baltic, x-usr-defined
|
||||
return;
|
||||
}
|
||||
|
||||
nsString genNameString; genNameString.AssignWithConversion(genName);
|
||||
nsString genNameString ((const nsString &)genName);
|
||||
nsGenericFontNameType type = Self->MapGenericFontNameType(genNameString);
|
||||
if(type >= kUknownGenericFontName)
|
||||
return;
|
||||
@ -307,7 +321,7 @@ PrefEnumCallback(const char* aName, void* aClosure)
|
||||
return;
|
||||
short fontID=0;
|
||||
if( (! nsDeviceContextMac::GetMacFontNumber(*fontname, fontID)) ||
|
||||
( ::FontToScript(fontID) != script ))
|
||||
((script < smUninterp) && (::FontToScript(fontID) != script)))
|
||||
{
|
||||
nsString::Recycle(fontname);
|
||||
return;
|
||||
@ -339,11 +353,49 @@ void nsUnicodeMappingUtil::InitFromPref()
|
||||
void nsUnicodeMappingUtil::InitScriptFontMapping()
|
||||
{
|
||||
// Get font from Script manager
|
||||
for(ScriptCode script = 0; script< 32 ; script++)
|
||||
for(ScriptCode script = 0; script< smPseudoTotalScripts ; script++)
|
||||
{
|
||||
mScriptFontMapping[script] = BAD_FONT_NUM;
|
||||
short fontNum;
|
||||
if(ScriptEnabled(script)) {
|
||||
if ((smPseudoUnicode == script) || (smPseudoUserDef == script))
|
||||
{
|
||||
char *theNeededPreference;
|
||||
|
||||
if (smPseudoUnicode == script)
|
||||
theNeededPreference = "font.name.serif.x-unicode";
|
||||
else
|
||||
theNeededPreference = "font.name.serif.x-user-def";
|
||||
|
||||
char *valueInUTF8 = nsnull;
|
||||
|
||||
gPref->CopyCharPref (theNeededPreference,&valueInUTF8);
|
||||
|
||||
if ((nsnull == valueInUTF8) || (PL_strlen (valueInUTF8) == 0))
|
||||
Recycle (valueInUTF8);
|
||||
else
|
||||
{
|
||||
PRUnichar valueInUCS2[FACESIZE]= { 0 };
|
||||
PRUnichar format[] = { '%', 's', 0 };
|
||||
PRUint32 n = nsTextFormatter::snprintf(valueInUCS2, FACESIZE, format, valueInUTF8);
|
||||
|
||||
Recycle (valueInUTF8);
|
||||
if (n != 0)
|
||||
{
|
||||
nsString *fontname = new nsAutoString (valueInUCS2);
|
||||
|
||||
if (nsnull != fontname)
|
||||
{
|
||||
short fontID = 0;
|
||||
|
||||
if (nsDeviceContextMac::GetMacFontNumber (*fontname,fontID))
|
||||
mScriptFontMapping[script] = fontID;
|
||||
|
||||
nsString::Recycle (fontname);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(ScriptEnabled(script)) {
|
||||
long fondsize = ::GetScriptVariable(script, smScriptPrefFondSize);
|
||||
if((fondsize) && ((fondsize >> 16))) {
|
||||
fontNum = (fondsize >> 16);
|
||||
@ -364,6 +416,7 @@ void nsUnicodeMappingUtil::InitBlockToScriptMapping()
|
||||
smTelugu, smKannada, smMalayalam, smThai,
|
||||
smLao, smTibetan, smGeorgian, smKorean,
|
||||
smTradChinese,
|
||||
smPseudoUserDef,
|
||||
|
||||
// start the variable section
|
||||
smRoman, smRoman, smJapanese, smJapanese, smJapanese,
|
||||
@ -374,7 +427,9 @@ void nsUnicodeMappingUtil::InitBlockToScriptMapping()
|
||||
if( ScriptEnabled(prebuildMapping[i]) ) {
|
||||
mBlockToScriptMapping[i] = prebuildMapping[i];
|
||||
} else {
|
||||
if(i < kUnicodeBlockFixedScriptMax) {
|
||||
if (i == kUserDefinedEncoding)
|
||||
mBlockToScriptMapping[i] = prebuildMapping[i];
|
||||
else if(i < kUnicodeBlockFixedScriptMax) {
|
||||
mBlockToScriptMapping[i] = (PRInt8) smRoman;
|
||||
} else {
|
||||
if( (kCJKMisc == i) || (kHiraganaKatakana == i) || (kCJKIdeographs == i) ) {
|
||||
|
@ -56,13 +56,13 @@ public:
|
||||
};
|
||||
inline short ScriptFont(ScriptCode script)
|
||||
{
|
||||
NS_PRECONDITION(script < 32, "bad script code");
|
||||
NS_PRECONDITION(script < smPseudoTotalScripts, "bad script code");
|
||||
return mScriptFontMapping[script];
|
||||
};
|
||||
nsGenericFontNameType MapGenericFontNameType(const nsString& aGenericName);
|
||||
inline nsString* GenericFontNameForScript(ScriptCode aScript, nsGenericFontNameType aType) const
|
||||
{
|
||||
NS_PRECONDITION(aScript < 32, "bad script code");
|
||||
NS_PRECONDITION(aScript < smPseudoTotalScripts, "bad script code");
|
||||
NS_PRECONDITION(aType <= kUknownGenericFontName, "illegal value");
|
||||
if( aType >= kUknownGenericFontName)
|
||||
return nsnull;
|
||||
@ -73,7 +73,7 @@ public:
|
||||
|
||||
ScriptCode MapLangGroupToScriptCode(const char* aLangGroup);
|
||||
static nsUnicodeMappingUtil* GetSingleton();
|
||||
nsString *mGenericFontMapping[smUninterp][kUknownGenericFontName];
|
||||
nsString *mGenericFontMapping[smPseudoTotalScripts][kUknownGenericFontName];
|
||||
|
||||
protected:
|
||||
void InitScriptEnabled();
|
||||
@ -84,7 +84,7 @@ protected:
|
||||
|
||||
private:
|
||||
PRUint32 mScriptEnabled;
|
||||
short mScriptFontMapping[smUninterp];
|
||||
short mScriptFontMapping[smPseudoTotalScripts];
|
||||
PRInt8 mBlockToScriptMapping[kUnicodeBlockSize];
|
||||
nsUnicodeFontMappingCache* gCache;
|
||||
|
||||
|
@ -152,7 +152,16 @@ PRBool nsUnicodeRenderingToolkit :: TECFallbackGetWidth(
|
||||
ScriptCode fallbackScript;
|
||||
nsUnicodeFallbackCache* cache = GetTECFallbackCache();
|
||||
|
||||
if( cache->Get(*aCharPt, fallbackScript))
|
||||
if ((0xf780 <= *aCharPt) && (*aCharPt <= 0xf7ff))
|
||||
{
|
||||
// If we are encountering our PUA characters for User-Defined characters, we better
|
||||
// just drop the high-byte and return the width for the low-byte.
|
||||
*buf = (*aCharPt & 0x00FF);
|
||||
GetScriptTextWidth (buf,1,oWidth);
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
else if( cache->Get(*aCharPt, fallbackScript))
|
||||
{
|
||||
if(BAD_SCRIPT == fallbackScript)
|
||||
return PR_FALSE;
|
||||
@ -220,7 +229,16 @@ PRBool nsUnicodeRenderingToolkit :: TECFallbackDrawChar(
|
||||
|
||||
// since we always call TECFallbackGetWidth before TECFallbackDrawChar
|
||||
// we could assume that we can always get the script code from cache.
|
||||
if( cache->Get(*aCharPt, fallbackScript))
|
||||
if ((0xf780 <= *aCharPt) && (*aCharPt <= 0xf7ff))
|
||||
{
|
||||
// If we are encountering our PUA characters for User-Defined characters, we better
|
||||
// just drop the high-byte and draw the text for the low-byte.
|
||||
*buf = (*aCharPt & 0x00FF);
|
||||
DrawScriptText (buf,1,x,y,oWidth);
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
else if( cache->Get(*aCharPt, fallbackScript))
|
||||
{
|
||||
if(BAD_SCRIPT == fallbackScript)
|
||||
return PR_FALSE;
|
||||
|
Loading…
x
Reference in New Issue
Block a user