Bug 30300/6588

This commit is contained in:
garywade%netscape.com 2000-06-14 23:40:25 +00:00
parent f87982d2f2
commit ea8a2e41a0
7 changed files with 141 additions and 30 deletions

View File

@ -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);
}

View File

@ -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,

View File

@ -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;

View File

@ -55,7 +55,7 @@ protected:
private:
PRInt8 mPrivBlockToScript [kUnicodeBlockVarScriptMax] ;
short mScriptFallbackFontIDs [32] ;
short mScriptFallbackFontIDs [smPseudoTotalScripts] ;
static nsUnicodeMappingUtil* gUtil;
static nsUnicodeFontMappingCache* gCache;
};

View File

@ -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) ) {

View File

@ -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;

View File

@ -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;