This commit is contained in:
ftang%netscape.com 1999-04-23 20:53:49 +00:00
Родитель fdeef7af48
Коммит 2c53d70289
7 изменённых файлов: 1169 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,61 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsUnicodeBlock_h__
#define nsUnicodeBlock_h__
typedef enum {
// blocks which always use the same script to render, regardless of the order of fonts
kGreek = 0,
kCyrillic,
kArmenian,
kHebrew,
kArabic,
kDevanagari,
kBengali,
kGurmukhi,
kGujarati,
kOriya,
kTamil,
kTelugu,
kKannada,
kMalayalam,
kThai,
kLao,
kTibetan,
kGeorgian,
kHangul,
kBopomofo,
kUnicodeBlockFixedScriptMax,
// blocks which may use different script to render, depend on the order of fonts
kBasicLatin = kUnicodeBlockFixedScriptMax,
kLatin ,
kCJKMisc,
kHiraganaKatakana,
kCJKIdeographs,
kOthers,
kUnicodeBlockSize,
kUnicodeBlockVarScriptMax = kUnicodeBlockSize - kUnicodeBlockFixedScriptMax
} nsUnicodeBlock;
#endif nsUnicodeBlock_h__

Просмотреть файл

@ -0,0 +1,92 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsUnicodeFallbackCache_h__
#define nsUnicodeFallbackCache_h__
#include "prtypes.h"
#include "plhash.h"
#include <Script.h>
#include "nsDebug.h"
#include "nscore.h"
class nsUnicodeFallbackCache
{
public:
nsUnicodeFallbackCache()
{
mTable = PL_NewHashTable(8, (PLHashFunction)HashKey,
(PLHashComparator)CompareKeys,
(PLHashComparator)CompareValues,
nsnull, nsnull);
mCount = 0;
};
~nsUnicodeFallbackCache()
{
if (mTable)
{
PL_HashTableEnumerateEntries(mTable, FreeHashEntries, 0);
PL_HashTableDestroy(mTable);
mTable = nsnull;
}
};
inline PRBool Get(PRUnichar aChar, ScriptCode& oScript)
{
ScriptCode ret = (ScriptCode)PL_HashTableLookup(mTable, (void*)aChar);
oScript = 0x00FF & ret ;
return 0x00 != (0xFF00 & ret);
};
inline void Set(PRUnichar aChar, ScriptCode aScript)
{
PL_HashTableAdd(mTable,(void*) aChar, (void*)(aScript | 0xFF00));
mCount ++;
};
inline static nsUnicodeFallbackCache* GetSingleton()
{
if(! gSingleton)
gSingleton = new nsUnicodeFallbackCache();
return gSingleton;
}
private:
inline static PR_CALLBACK PLHashNumber HashKey(const void *aKey)
{
return (PRUnichar)aKey;
};
inline static PR_CALLBACK PRIntn CompareKeys(const void *v1, const void *v2)
{
return (((PRUnichar ) v1) == ((PRUnichar ) v2));
};
inline static PR_CALLBACK PRIntn CompareValues(const void *v1, const void *v2)
{
return (((ScriptCode)v1) == ((ScriptCode)v2));
};
inline static PR_CALLBACK PRIntn FreeHashEntries(PLHashEntry *he, PRIntn italic, void *arg)
{
return HT_ENUMERATE_REMOVE;
};
struct PLHashTable* mTable;
PRUint32 mCount;
static nsUnicodeFallbackCache* gSingleton;
};
#endif nsUnicodeFallbackCache_h__

Просмотреть файл

@ -0,0 +1,86 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsUnicodeFontMappingCache_h__
#define nsUnicodeFontMappingCache_h__
#include "plhash.h"
#include "nsCRT.h"
#include "nsString.h"
#include "nsUnicodeFontMappingMac.h"
class nsUnicodeFontMappingCache
{
public:
nsUnicodeFontMappingCache()
{
mTable = PL_NewHashTable(8, (PLHashFunction)HashKey,
(PLHashComparator)CompareKeys,
(PLHashComparator)CompareValues,
nsnull, nsnull);
mCount = 0;
};
~nsUnicodeFontMappingCache()
{
if (mTable)
{
PL_HashTableEnumerateEntries(mTable, FreeHashEntries, 0);
PL_HashTableDestroy(mTable);
mTable = nsnull;
}
};
inline PRBool Get(const nsString& key, nsUnicodeFontMappingMac **item)
{
*item = (nsUnicodeFontMappingMac*)PL_HashTableLookup(mTable, &key);
return nsnull != (*item);
};
inline void Set(const nsString& key, nsUnicodeFontMappingMac *item)
{
nsString *newKey = new nsString(key);
if (newKey)
{
PL_HashTableAdd(mTable, newKey, item);
mCount ++;
}
};
private:
inline static PR_CALLBACK PLHashNumber HashKey(const void *aKey)
{
PRUint32 uslen;
return nsCRT::HashValue(((nsString*)aKey)->GetUnicode(), &uslen);
};
inline static PR_CALLBACK PRIntn CompareKeys(const void *v1, const void *v2)
{
return ((nsString *)v1) -> Equals(* ((nsString *)v2));
};
inline static PR_CALLBACK PRIntn CompareValues(const void *v1, const void *v2)
{
return ((nsUnicodeFontMappingMac*)v1) -> Equals(* ((nsUnicodeFontMappingMac*)v2));
};
inline static PR_CALLBACK PRIntn FreeHashEntries(PLHashEntry *he, PRIntn italic, void *arg)
{
delete (nsString*)he->key;
delete (nsUnicodeFontMappingMac*)he->value;
return HT_ENUMERATE_REMOVE;
};
struct PLHashTable* mTable;
PRUint32 mCount;
};
#endif /* nsUnicodeFontMappingCache_h__ */

Просмотреть файл

@ -0,0 +1,505 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include <Script.h>
#include "nsDeviceContextMac.h"
#include "plhash.h"
#include "nsCRT.h"
#include "nsUnicodeFontMappingMac.h"
#include "nsUnicodeFontMappingCache.h"
#include "nsUnicodeMappingUtil.h"
#define BAD_FONT_NUM -1
#define BAD_SCRIPT 0x7f
//--------------------------------------------------------------------------
static void FillVarBlockToScript( PRInt8 script, PRInt8 *aMap)
{
if(BAD_SCRIPT == aMap[kBasicLatin - kUnicodeBlockFixedScriptMax])
aMap[kBasicLatin - kUnicodeBlockFixedScriptMax] = script;
if(BAD_SCRIPT == aMap[kOthers - kUnicodeBlockFixedScriptMax])
aMap[kOthers - kUnicodeBlockFixedScriptMax] = script;
switch( script )
{
case smRoman:
case smCentralEuroRoman:
case smVietnamese:
if(BAD_SCRIPT == aMap[kLatin - kUnicodeBlockFixedScriptMax])
aMap[kLatin - kUnicodeBlockFixedScriptMax] = script;
break;
case smTradChinese:
if(BAD_SCRIPT == aMap[kCJKMisc - kUnicodeBlockFixedScriptMax])
aMap[kCJKMisc - kUnicodeBlockFixedScriptMax] = script;
if(BAD_SCRIPT == aMap[kCJKIdeographs - kUnicodeBlockFixedScriptMax])
aMap[kCJKIdeographs - kUnicodeBlockFixedScriptMax] = script;
break;
case smKorean:
case smJapanese:
case smSimpChinese:
if(BAD_SCRIPT == aMap[kCJKMisc - kUnicodeBlockFixedScriptMax])
aMap[kCJKMisc - kUnicodeBlockFixedScriptMax] = script;
if(BAD_SCRIPT == aMap[kCJKIdeographs - kUnicodeBlockFixedScriptMax])
aMap[kCJKIdeographs - kUnicodeBlockFixedScriptMax] = script;
if(BAD_SCRIPT == aMap[kHiraganaKatakana - kUnicodeBlockFixedScriptMax])
aMap[kHiraganaKatakana - kUnicodeBlockFixedScriptMax] = script;
break;
};
}
struct MyFontEnumData {
MyFontEnumData(nsIDeviceContext* aDC, PRInt8* pMap, short* pFonts) : mContext(aDC) {
mMap = pMap;
mFont = pFonts;
};
nsIDeviceContext* mContext;
PRInt8 *mMap;
short *mFont;
};
//--------------------------------------------------------------------------
static PRBool FontEnumCallback(const nsString& aFamily, PRBool aGeneric, void *aData)
{
MyFontEnumData* data = (MyFontEnumData*)aData;
nsUnicodeMappingUtil * info = nsUnicodeMappingUtil::GetSingleton();
NS_PRECONDITION(info != nsnull, "out of memory");
if (aGeneric)
{
if(nsnull == info)
return PR_FALSE;
nsGenericFontNameType type = info->MapGenericFontNameType(aFamily);
if( type != kUknownGenericFontName) {
for(ScriptCode script = 0; script < 32 ; script++)
{
const nsString* fontName = info->GenericFontNameForScript(script,type);
if(nsnull != fontName) {
short fontNum;
nsDeviceContextMac::GetMacFontNumber(*fontName, fontNum);
if((0 != fontNum) && (BAD_FONT_NUM == data->mFont[ script ]))
data->mFont[ script ] = fontNum;
// since this is a generic font name, it won't impact the order of script we used
}
}
}
}
else
{
nsAutoString realFace;
PRBool aliased;
data->mContext->GetLocalFontName(aFamily, realFace, aliased);
if (aliased || (NS_OK == data->mContext->CheckFontExistence(realFace)))
{
short fontNum;
nsDeviceContextMac::GetMacFontNumber(realFace, fontNum);
if(0 != fontNum) {
ScriptCode script = ::FontToScript(fontNum);
if(BAD_FONT_NUM == data->mFont[ script ])
data->mFont[ script ] = fontNum;
FillVarBlockToScript( script, data->mMap);
}
}
}
return PR_TRUE;
}
//--------------------------------------------------------------------------
nsUnicodeMappingUtil *nsUnicodeFontMappingMac::gUtil = nsnull;
nsUnicodeFontMappingCache *nsUnicodeFontMappingMac::gCache = nsnull;
//--------------------------------------------------------------------------
void nsUnicodeFontMappingMac::InitByFontFamily(nsFont* aFont, nsIDeviceContext *aDeviceContext)
{
MyFontEnumData fontData(aDeviceContext, mPrivBlockToScript, mScriptFallbackFontIDs);
aFont->EnumerateFamilies(FontEnumCallback, &fontData);
}
//--------------------------------------------------------------------------
void nsUnicodeFontMappingMac::processOneLangRegion(const char* aLanguage, const char* aRegion )
{
if(! nsCRT::strcmp(aLanguage,"zh")) {
if((! nsCRT::strcmp(aRegion,"TW")) || (! nsCRT::strcmp(aRegion,"HK"))) {
if(gUtil->ScriptEnabled(smTradChinese))
FillVarBlockToScript(smTradChinese, mPrivBlockToScript);
} else {
if(gUtil->ScriptEnabled(smSimpChinese))
FillVarBlockToScript(smSimpChinese, mPrivBlockToScript);
}
} else if(! nsCRT::strcmp(aLanguage,"ko")) {
if(gUtil->ScriptEnabled(smKorean))
FillVarBlockToScript(smKorean, mPrivBlockToScript);
} else if(! nsCRT::strcmp(aLanguage,"ja")) {
if(gUtil->ScriptEnabled(smJapanese))
FillVarBlockToScript(smJapanese, mPrivBlockToScript);
}
}
//--------------------------------------------------------------------------
PRBool nsUnicodeFontMappingMac::ScriptMapInitComplete()
{
PRInt32 i;
for(i = kUnicodeBlockFixedScriptMax ; i < kUnicodeBlockSize; i++) {
if(BAD_SCRIPT == mPrivBlockToScript[i - kUnicodeBlockFixedScriptMax])
return PR_FALSE;
}
return PR_TRUE;
}
//--------------------------------------------------------------------------
const PRUnichar kA = PRUnichar('A');
const PRUnichar kZ = PRUnichar('Z');
const PRUnichar ka = PRUnichar('a');
const PRUnichar kz = PRUnichar('z');
const PRUnichar kComma = PRUnichar(',');
const PRUnichar kUnderline = PRUnichar('_');
const PRUnichar kSpace = PRUnichar(' ');
const PRUnichar kNullCh = PRUnichar('\0');
//--------------------------------------------------------------------------
void nsUnicodeFontMappingMac::InitByLANG(const nsString& aLANG)
{
// do not countinue if there are no difference to look at the lang tag
if( ScriptMapInitComplete() )
return;
const PRUnichar *p = aLANG.GetUnicode();
PRUint32 len = aLANG.Length();
char language[3];
char region[3];
language[2] = region[2]= '\0';;
language[0]= language[1] = region[0]= region[1] = ' ';
PRUint32 state = 0;
for(PRUint32 i = 0; (state != -1) && (i < len); i++, p++)
{
switch (state) {
case 0:
if(( ka <= *p) && (*p <= kz )) {
language[state++] = (char)*p;
} else if( kSpace == *p) {
state = 0;
} else {
state = -1;
}
break;
case 1:
if(( ka <= *p) && (*p <= kz )) {
language[state++] = (char)*p;
} else {
state = -1;
}
break;
case 2:
if(kComma == *p) {
processOneLangRegion(language, region);
language[0]= language[1] = region[0]= region[1] = ' ';
state = 0;
} else if(kUnderline == *p) {
state = 3;
} else {
state = -1;
}
break;
case 3:
case 4:
if(( kA <= *p) && (*p <= kZ )) {
region[state - 3] = (char)*p;
state++;
} else {
state = -1;
}
break;
case 5:
if(kComma == *p) {
processOneLangRegion(language, region);
language[0]= language[1] = region[0]= region[1] = ' ';
state = 0;
} else {
state = -1;
}
break;
};
}
if((2 == state) || (5 == state)) {
processOneLangRegion(language, region);
}
}
//--------------------------------------------------------------------------
void nsUnicodeFontMappingMac::InitByDocumentCharset(const nsString& aDocumentCharset)
{
// do not countinue if there are no difference to look at the document Charset
if( ScriptMapInitComplete() )
return;
if (aDocumentCharset.EqualsIgnoreCase("GB2312") ||
aDocumentCharset.EqualsIgnoreCase("ISO-2022-CN") ||
aDocumentCharset.EqualsIgnoreCase("ZH") )
{
if(gUtil->ScriptEnabled(smSimpChinese))
FillVarBlockToScript(smSimpChinese, mPrivBlockToScript);
} else if( aDocumentCharset.EqualsIgnoreCase("EUC-KR") ||
aDocumentCharset.EqualsIgnoreCase("ISO-2022-KR") )
{
if(gUtil->ScriptEnabled(smKorean))
FillVarBlockToScript(smKorean, mPrivBlockToScript);
} else if( aDocumentCharset.EqualsIgnoreCase("Big5") ||
aDocumentCharset.EqualsIgnoreCase("x-euc-tw") )
{
if(gUtil->ScriptEnabled(smTradChinese))
FillVarBlockToScript(smTradChinese, mPrivBlockToScript);
} else if( aDocumentCharset.EqualsIgnoreCase("Shift_JIS") ||
aDocumentCharset.EqualsIgnoreCase("EUC-JP") ||
aDocumentCharset.EqualsIgnoreCase("ISO-2022-JP") )
{
if(gUtil->ScriptEnabled(smJapanese))
FillVarBlockToScript(smJapanese, mPrivBlockToScript);
}
}
//--------------------------------------------------------------------------
void nsUnicodeFontMappingMac::InitDefaultScriptFonts()
{
for(PRInt32 i = 0 ; i < 32; i++)
{
// copy from global mapping
if(BAD_FONT_NUM == mScriptFallbackFontIDs[i])
mScriptFallbackFontIDs[i] = gUtil->ScriptFont(i);
}
}
//--------------------------------------------------------------------------
nsUnicodeFontMappingMac::nsUnicodeFontMappingMac(
nsFont* aFont, nsIDeviceContext *aDeviceContext,
const nsString& aDocumentCharset, const nsString& aLANG)
{
PRInt32 i;
for(i = kUnicodeBlockFixedScriptMax ; i < kUnicodeBlockSize; i++)
mPrivBlockToScript[i - kUnicodeBlockFixedScriptMax] = BAD_SCRIPT;
for(i = 0 ; i < 32; i++)
mScriptFallbackFontIDs[i] = BAD_FONT_NUM;
InitByFontFamily(aFont, aDeviceContext);
InitByLANG(aLANG);
InitByDocumentCharset(aDocumentCharset);
InitDefaultScriptFonts();
}
//--------------------------------------------------------------------------
nsUnicodeFontMappingMac* nsUnicodeFontMappingMac::GetCachedInstance(
nsFont* aFont, nsIDeviceContext *aDeviceContext, const nsString& aDocumentCharset, const nsString& aLANG)
{
if(! gUtil)
gUtil = nsUnicodeMappingUtil::GetSingleton();
if(! gCache)
gCache = gUtil->GetFontMappingCache();
nsUnicodeFontMappingMac* obj = nsnull;
nsAutoString key = aFont->name;
key.Append(":");
key.Append(aDocumentCharset);
key.Append(":");
key.Append(aLANG);
if(! gCache->Get ( key, &obj )){
obj = new nsUnicodeFontMappingMac(aFont, aDeviceContext, aDocumentCharset, aLANG);
if( obj )
gCache->Set ( key, obj);
}
NS_PRECONDITION(nsnull != obj, "out of memory");
return obj;
}
//--------------------------------------------------------------------------
PRBool nsUnicodeFontMappingMac::Equals(const nsUnicodeFontMappingMac& aMap)
{
PRUint32 i;
if(&aMap != this) {
for( i=0; i < 32; i++)
{
if(mScriptFallbackFontIDs[i] != aMap.mScriptFallbackFontIDs[i])
return PR_FALSE;
}
for( i=0; i < kUnicodeBlockVarScriptMax; i++)
{
if(mPrivBlockToScript[i] != aMap.mPrivBlockToScript[i])
return PR_FALSE;
}
}
return PR_TRUE;
}
//--------------------------------------------------------------------------
short nsUnicodeFontMappingMac::GetFontID(PRUnichar aChar) {
nsUnicodeBlock block = GetBlock(aChar);
if(block < kUnicodeBlockFixedScriptMax)
return mScriptFallbackFontIDs[gUtil->BlockToScript(block)];
else
return mScriptFallbackFontIDs[ mPrivBlockToScript[ block - kUnicodeBlockFixedScriptMax] ];
}
//------------------------------------------------------------------------
static nsUnicodeBlock gU0xxxMap[32]=
{
kBasicLatin, kLatin, // U+0000
kLatin, kLatin, // U+0100
kOthers, kOthers, // U+0200
kOthers, kGreek, // U+0300
kCyrillic, kCyrillic, // U+0400
kArmenian, kOthers, // U+0500
kArabic, kArabic, // U+0600
kOthers, kOthers, // U+0700
kOthers, kOthers, // U+0800
kDevanagari, kBengali, // U+0900
kGurmukhi, kGujarati, // U+0a00
kOriya, kTamil, // U+0b00
kTelugu, kKannada, // U+0c00
kMalayalam, kOthers , // U+0d00
kThai, kLao, // U+0e00
kTibetan, kTibetan, // U+0f00
};
//--------------------------------------------------------------------------
static nsUnicodeBlock GetBlockU0XXX(PRUnichar aChar)
{
nsUnicodeBlock res = gU0xxxMap[ (aChar >> 8) & 0x0F];
if(res == kOthers) {
if((0x0200 <= aChar) && ( aChar <= 0x024F )) res = kLatin;
else if((0x0370 <= aChar) && ( aChar <= 0x037F )) res = kGreek;
else if((0x0580 <= aChar) && ( aChar <= 0x058F )) res = kArmenian;
else if((0x0590 <= aChar) && ( aChar <= 0x05ff )) res = kHebrew;
}
return res;
}
//--------------------------------------------------------------------------
static nsUnicodeBlock GetBlockU1XXX(PRUnichar aChar)
{
switch( aChar & 0x0F00 )
{
case 0x0000: return kGeorgian;
case 0x0100: return kHangul;
case 0x0e00: return kLatin;
case 0x0f00: return kGreek;
default: return kOthers;
}
}
//--------------------------------------------------------------------------
static nsUnicodeBlock GetBlockU2XXX(PRUnichar aChar)
{
return kOthers;
}
//--------------------------------------------------------------------------
static nsUnicodeBlock GetBlockU3XXX(PRUnichar aChar)
{
if(aChar < 0x3040) return kCJKMisc;
else if(aChar < 0x3100) return kHiraganaKatakana;
else if(aChar < 0x3130) return kBopomofo;
else if(aChar < 0x3190) return kHangul;
else return kCJKMisc;
}
//--------------------------------------------------------------------------
static nsUnicodeBlock GetBlockU4XXX(PRUnichar aChar)
{
if(aChar < 0x4E00) return kOthers;
else return kCJKIdeographs;
}
//--------------------------------------------------------------------------
static nsUnicodeBlock GetBlockCJKIdeographs(PRUnichar aChar)
{
return kCJKIdeographs;
}
//--------------------------------------------------------------------------
static nsUnicodeBlock GetBlockHangul(PRUnichar aChar)
{
return kHangul;
}
//--------------------------------------------------------------------------
static nsUnicodeBlock GetBlockUAXXX(PRUnichar aChar)
{
if(aChar < 0xAC00) return kOthers;
else return kHangul;
}
//--------------------------------------------------------------------------
static nsUnicodeBlock GetBlockUDXXX(PRUnichar aChar)
{
if(aChar < 0xD800) return kHangul;
else return kOthers;
}
//--------------------------------------------------------------------------
static nsUnicodeBlock GetBlockUEXXX(PRUnichar aChar)
{
return kOthers;
}
//--------------------------------------------------------------------------
static nsUnicodeBlock GetBlockUFXXX(PRUnichar aChar)
{
// U+FFxx is used more frequently in the U+Fxxxx block
if(aChar >= 0xff00)
{
if(aChar < 0xff60) return kCJKMisc;
else if(aChar < 0xffA0) return kHiraganaKatakana;
else if(aChar < 0xffe0) return kHangul;
else return kOthers;
}
// The rest is rarely used, we don't care the performance below.
if(aChar < 0xf900) return kOthers;
else if(aChar < 0xfb00) return kCJKIdeographs;
else if(aChar < 0xfb10) return kLatin;
else if(aChar < 0xfb18) return kArmenian;
else if(aChar < 0xfb50) return kHebrew;
else if(aChar < 0xfe20) return kArabic;
else if(aChar < 0xfe70) return kOthers;
else return kArabic;
}
//--------------------------------------------------------------------------
typedef nsUnicodeBlock (* getUnicodeBlock)(PRUnichar aChar);
static getUnicodeBlock gAllGetBlock[16] =
{
&GetBlockU0XXX, // 0
&GetBlockU1XXX, // 1
&GetBlockU2XXX, // 2
&GetBlockU3XXX, // 3
&GetBlockU4XXX, // 4
&GetBlockCJKIdeographs, // 5
&GetBlockCJKIdeographs, // 6
&GetBlockCJKIdeographs, // 7
&GetBlockCJKIdeographs, // 8
&GetBlockCJKIdeographs, // 9
&GetBlockUAXXX, // a
&GetBlockHangul, // b
&GetBlockHangul, // c
&GetBlockUDXXX, // d
&GetBlockUEXXX, // e
&GetBlockUFXXX // f
};
//--------------------------------------------------------------------------
nsUnicodeBlock nsUnicodeFontMappingMac:: GetBlock(PRUnichar aChar)
{
return (*(gAllGetBlock[(aChar >> 12)]))(aChar);
}

Просмотреть файл

@ -0,0 +1,59 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsUnicodeFontMappingMac_h__
#define nsUnicodeFontMappingMac_h__
#include "nsUnicodeBlock.h"
#include "nsIDeviceContext.h"
#include "nsFont.h"
class nsUnicodeMappingUtil;
class nsUnicodeFontMappingCache;
class nsUnicodeFontMappingMac {
public:
nsUnicodeFontMappingMac(nsFont* aFont, nsIDeviceContext *aDeviceContext,
const nsString& aDocumentCharset, const nsString& aLANG);
short GetFontID(PRUnichar aChar);
inline const short *GetScriptFallbackFonts() {
return mScriptFallbackFontIDs;
}
PRBool Equals(const nsUnicodeFontMappingMac& anther);
static nsUnicodeFontMappingMac* GetCachedInstance(nsFont* aFont, nsIDeviceContext *aDeviceContext,
const nsString& aDocumentCharset, const nsString& aLANG);
protected:
PRBool ScriptMapInitComplete();
void InitByFontFamily(nsFont* aFont, nsIDeviceContext *aDeviceContext);
void InitByLANG(const nsString& aLANG);
void InitByDocumentCharset(const nsString& aDocumentCharset);
void InitDefaultScriptFonts();
void processOneLangRegion(const char* aLanguage, const char* aRegion );
nsUnicodeBlock GetBlock(PRUnichar aChar);
private:
PRInt8 mPrivBlockToScript [kUnicodeBlockVarScriptMax] ;
short mScriptFallbackFontIDs [32] ;
static nsUnicodeMappingUtil* gUtil;
static nsUnicodeFontMappingCache* gCache;
};
#endif /* nsUnicodeFontMappingMac_h__ */

Просмотреть файл

@ -0,0 +1,281 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsUnicodeMappingUtil.h"
#include "nsUnicodeFontMappingCache.h"
#define BAD_FONT_NUM -1
//--------------------------------------------------------------------------
nsUnicodeMappingUtil *nsUnicodeMappingUtil::gSingleton = nsnull;
//--------------------------------------------------------------------------
nsUnicodeMappingUtil::nsUnicodeMappingUtil()
{
InitScriptEnabled();
InitGenericFontMapping();
InitScriptFontMapping();
InitBlockToScriptMapping(); // this must be called after InitScriptEnabled()
gCache = new nsUnicodeFontMappingCache();
}
//--------------------------------------------------------------------------
nsUnicodeMappingUtil::~nsUnicodeMappingUtil()
{
for(int i= 0 ; i < 32; i ++) {
for(int j=0; j < 5; j++) {
if(mGenericFontMapping[i][j])
delete mGenericFontMapping[i][j];
}
}
if(gCache)
delete gCache;
}
//--------------------------------------------------------------------------
void nsUnicodeMappingUtil::InitScriptEnabled()
{
PRUint8 numOfScripts = ::GetScriptManagerVariable(smEnabled);
ScriptCode script, gotScripts;
mScriptEnabled = 0;
PRUint32 scriptMask = 1;
for(script = gotScripts = 0;
((script < 32) && ( gotScripts < numOfScripts)) ;
script++, scriptMask <<= 1)
{
if(::GetScriptVariable(script, smScriptEnabled))
mScriptEnabled |= scriptMask;
}
}
//--------------------------------------------------------------------------
void nsUnicodeMappingUtil::InitGenericFontMapping()
{
for(int i= 0 ; i < 32; i ++)
for(int j=0; j < 5; j++)
mGenericFontMapping[i][j] = nsnull;
// We probabaly should put the following info into resource ....
// smRoman
static nsAutoString times_str("Times");
static nsAutoString helvetica_str("Helvetica");
static nsAutoString courier_str("Courier");
static nsAutoString zapfChancery_str("Zapf Chancery");
static nsAutoString newCenturySchlbk_str("New Century Schlbk");
mGenericFontMapping[smRoman][kSerif] = & times_str;
mGenericFontMapping[smRoman][kSansSerif] = & helvetica_str; // note: MRJ use Geneva for Sans-Serif
mGenericFontMapping[smRoman][kMonospace] = & courier_str;
mGenericFontMapping[smRoman][kCursive] = & zapfChancery_str;
mGenericFontMapping[smRoman][kFantasy] = & newCenturySchlbk_str;
// smJapanese
static PRUnichar jfontname1[] = {
0x672C, 0x660E, 0x671D, 0x2212, 0xFF2D, 0x0000 // –{–¾©<E28099>|l
};
static PRUnichar jfontname2[] = {
0x4E38, 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0x2212, 0xFF2D, 0x0000 // ŠÛƒSƒVƒbƒN<C692>|l
};
static PRUnichar jfontname3[] = {
0x004F, 0x0073, 0x0061, 0x006B, 0x0061, 0x2212, 0x7B49, 0x5E45, 0x0000 // Osaka<6B>|“™•<E284A2>
};
static nsAutoString nsJFont1(jfontname1);
static nsAutoString nsJFont2(jfontname2);
static nsAutoString nsJFont3(jfontname3);
mGenericFontMapping[smJapanese][kSerif] = &nsJFont1;
mGenericFontMapping[smJapanese][kSansSerif] = &nsJFont2;
mGenericFontMapping[smJapanese][kMonospace] = &nsJFont3;
// smTradChinese
static nsAutoString appleLiSungLight_str("Apple LiSung Light");
static nsAutoString appleLiGothicMedium_str("Apple LiGothic Medium");
mGenericFontMapping[smTradChinese][kSerif] = & appleLiSungLight_str;
mGenericFontMapping[smTradChinese][kSansSerif]
= mGenericFontMapping[smTradChinese][kMonospace] = & appleLiGothicMedium_str;
// smKorean
static nsAutoString appleMyungjo_str("AppleMyungjo");
static nsAutoString appleGothic_str("AppleGothic");
mGenericFontMapping[smKorean][kSerif] = & appleMyungjo_str;
mGenericFontMapping[smKorean][kSansSerif]
= mGenericFontMapping[smKorean][kMonospace] = &appleGothic_str;
// smArabic
static PRUnichar afontname1[] = {
0x062B, 0x0644, 0x062B, 0x202E, 0x0020, 0x202C, 0x0623, 0x0628, 0x064A, 0x0636, 0x0000 // ËäË ÃÈêÖ
};
static PRUnichar afontname2[] = {
0x0627, 0x0644, 0x0628, 0x064A, 0x0627, 0x0646, 0x0000 // ÇäÈêÇæ
};
static PRUnichar afontname3[] = {
0x062C, 0x064A, 0x0632, 0x0629, 0x0000 // ÌêÒÉ
};
static nsAutoString nsAFont1(afontname1);
static nsAutoString nsAFont2(afontname2);
static nsAutoString nsAFont3(afontname3);
mGenericFontMapping[smArabic][kSerif] = &nsAFont1;
mGenericFontMapping[smArabic][kSansSerif] = &nsAFont2;
mGenericFontMapping[smArabic][kMonospace] = &nsAFont3;
// smHebrew
static PRUnichar hfontname1[] = {
0x05E4, 0x05E0, 0x05D9, 0x05E0, 0x05D9, 0x05DD, 0x202E, 0x0020, 0x202C, 0x05D7, 0x05D3, 0x05E9, 0x0000 // ôðéðéí çãù
};
static PRUnichar hfontname2[] = {
0x05D0, 0x05E8, 0x05D9, 0x05D0, 0x05DC, 0x0000 // àøéàì
};
static nsAutoString nsHFont1(hfontname1);
static nsAutoString nsHFont2(hfontname2);
mGenericFontMapping[smHebrew][kSerif] = & nsHFont1;
mGenericFontMapping[smHebrew][kSansSerif]
= mGenericFontMapping[smHebrew][kMonospace] = & nsHFont2;
// smCyrillic
static nsAutoString latinski_str("Latinski");
static nsAutoString pryamoyProp_str("Pryamoy Prop");
static nsAutoString apcCourier_str("APC Courier");
mGenericFontMapping[smCyrillic][kSerif] = &latinski_str;
mGenericFontMapping[smCyrillic][kSansSerif] = &pryamoyProp_str;
mGenericFontMapping[smCyrillic][kMonospace] = &apcCourier_str;
// smDevanagari
static nsAutoString devanagariMT_str("Devanagari MT");
mGenericFontMapping[smDevanagari][kSerif]
= mGenericFontMapping[smDevanagari][kSansSerif]
= mGenericFontMapping[smDevanagari][kMonospace] = & devanagariMT_str;
// smGurmukhi
static nsAutoString gurukhiMT_str("Gurmukhi MT");
mGenericFontMapping[smGurmukhi][kSerif]
= mGenericFontMapping[smGurmukhi][kSansSerif]
= mGenericFontMapping[smGurmukhi][kMonospace] = & gurukhiMT_str;
// smGujarati
static nsAutoString gujaratiMT_str("Gujarati MT");
mGenericFontMapping[smGujarati][kSerif]
= mGenericFontMapping[smGujarati][kSansSerif]
= mGenericFontMapping[smGujarati][kMonospace] = & gujaratiMT_str;
// smThai
static nsAutoString thonburi_str("Thonburi");
static nsAutoString krungthep_str("Krungthep");
static nsAutoString ayuthaya_str("Ayuthaya");
mGenericFontMapping[smThai][kSerif] = &thonburi_str;
mGenericFontMapping[smThai][kSansSerif] = &krungthep_str;
mGenericFontMapping[smThai][kMonospace] = &ayuthaya_str;
// smSimpChinese
static nsAutoString song_str("Song");
static nsAutoString hei_str("Hei");
mGenericFontMapping[smSimpChinese][kSerif] = &song_str;
mGenericFontMapping[smSimpChinese][kSansSerif]
= mGenericFontMapping[smSimpChinese][kMonospace] = & hei_str;
// smCentralEuroRoman
static nsAutoString timesCE_str("Times CE");
static nsAutoString helveticaCE_str("Helvetica CE");
static nsAutoString courierCE_str("Courier CE");
mGenericFontMapping[smCentralEuroRoman][kSerif] = &timesCE_str;
mGenericFontMapping[smCentralEuroRoman][kSansSerif] = &helveticaCE_str;
mGenericFontMapping[smCentralEuroRoman][kMonospace] = &courierCE_str;
}
//--------------------------------------------------------------------------
void nsUnicodeMappingUtil::InitScriptFontMapping()
{
// Get font from Script manager
for(ScriptCode script = 0; script< 32 ; script++)
{
mScriptFontMapping[script] = BAD_FONT_NUM;
short fontNum;
if(ScriptEnabled(script)) {
long fondsize = ::GetScriptVariable(script, smScriptPrefFondSize);
if((fondsize) && ((fondsize >> 16))) {
fontNum = (fondsize >> 16);
mScriptFontMapping[script] = fontNum;
}
}
}
}
//--------------------------------------------------------------------------
void nsUnicodeMappingUtil::InitBlockToScriptMapping()
{
static ScriptCode prebuildMapping[kUnicodeBlockSize] =
{
// start the fixed section
smGreek, smCyrillic, smArmenian,
smHebrew, smArabic, smDevanagari, smBengali,
smGurmukhi, smGujarati, smOriya, smTamil,
smTelugu, smKannada, smMalayalam, smThai,
smLao, smTibetan, smGeorgian, smKorean,
smTradChinese,
// start the variable section
smRoman, smRoman, smJapanese, smJapanese, smJapanese,
smRoman
};
for(PRUint32 i= 0; i < kUnicodeBlockSize; i++)
{
if( ScriptEnabled(prebuildMapping[i]) ) {
mBlockToScriptMapping[i] = prebuildMapping[i];
} else {
if(i < kUnicodeBlockFixedScriptMax) {
mBlockToScriptMapping[i] = (PRInt8) smRoman;
} else {
if( (kCJKMisc == i) || (kHiraganaKatakana == i) || (kCJKIdeographs == i) ) {
// fallback in the following sequence
// smTradChinese smKorean smSimpChinese
mBlockToScriptMapping[i] = (PRInt8)
( ScriptEnabled(smTradChinese) ? smTradChinese :
( ScriptEnabled(smKorean) ? smKorean :
( ScriptEnabled(smSimpChinese) ? smSimpChinese : smRoman )
)
);
}
}
}
}
}
//--------------------------------------------------------------------------
nsGenericFontNameType nsUnicodeMappingUtil::MapGenericFontNameType(const nsString& aGenericName)
{
if (aGenericName.EqualsIgnoreCase("serif"))
return kSerif;
if (aGenericName.EqualsIgnoreCase("sans-serif"))
return kSansSerif;
if (aGenericName.EqualsIgnoreCase("monospace"))
return kMonospace;
if (aGenericName.EqualsIgnoreCase("cursive"))
return kCursive;
if (aGenericName.EqualsIgnoreCase("fantasy"))
return kFantasy;
return kUknownGenericFontName;
}
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
nsUnicodeMappingUtil* nsUnicodeMappingUtil::GetSingleton()
{
if( ! gSingleton)
gSingleton = new nsUnicodeMappingUtil();
return gSingleton;
}
//--------------------------------------------------------------------------

Просмотреть файл

@ -0,0 +1,85 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include <Script.h>
#include "prtypes.h"
#include "nsUnicodeBlock.h"
#include "nsDebug.h"
#include "nscore.h"
class nsUnicodeFontMappingCache;
class nsString;
//--------------------------------------------------------------------------
typedef enum {
kSerif = 0,
kSansSerif,
kMonospace,
kCursive,
kFantasy,
kUknownGenericFontName
} nsGenericFontNameType;
//--------------------------------------------------------------------------
class nsUnicodeMappingUtil {
public:
nsUnicodeMappingUtil();
~nsUnicodeMappingUtil();
inline PRBool ScriptEnabled(ScriptCode script)
{ return (0 != (mScriptEnabled & (1L << script))); };
inline ScriptCode BlockToScript(nsUnicodeBlock blockID)
{
NS_PRECONDITION(blockID < kUnicodeBlockSize, "illegal value");
return (ScriptCode) mBlockToScriptMapping[blockID];
};
inline short ScriptFont(ScriptCode script)
{
NS_PRECONDITION(script < 32, "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(aType <= kUknownGenericFontName, "illegal value");
if( aType >= kUknownGenericFontName)
return nsnull;
else
return mGenericFontMapping[aScript][aType];
}
inline nsUnicodeFontMappingCache* GetFontMappingCache() { return gCache; };
static nsUnicodeMappingUtil* GetSingleton();
protected:
void InitScriptEnabled();
void InitGenericFontMapping();
void InitBlockToScriptMapping();
void InitScriptFontMapping();
private:
PRUint32 mScriptEnabled;
nsString *mGenericFontMapping[32][5];
short mScriptFontMapping[32];
PRInt8 mBlockToScriptMapping[kUnicodeBlockSize];
nsUnicodeFontMappingCache* gCache;
static nsUnicodeMappingUtil* gSingleton;
};