зеркало из https://github.com/mozilla/gecko-dev.git
Fixes for bugs 4800 and 4810. Was crashing on Japanese Windows 95 because
GetTextExtentPoint32W and ExtTextOutW are not properly implemented on that version of Windows. This is a workaround.
This commit is contained in:
Родитель
ca63b7e7b6
Коммит
32b1be8ffc
|
@ -22,16 +22,11 @@
|
|||
|
||||
static NS_DEFINE_IID(kIFontMetricsIID, NS_IFONT_METRICS_IID);
|
||||
|
||||
typedef struct nsGlobalFont
|
||||
{
|
||||
nsString* name;
|
||||
LOGFONT logFont;
|
||||
PRUint8* map;
|
||||
} nsGlobalFont;
|
||||
|
||||
static nsGlobalFont* gGlobalFonts = nsnull;
|
||||
nsGlobalFont* nsFontMetricsWin::gGlobalFonts = nsnull;
|
||||
static int gGlobalFontsAlloc = 0;
|
||||
static int gGlobalFontsCount = 0;
|
||||
int nsFontMetricsWin::gGlobalFontsCount = 0;
|
||||
|
||||
PLHashTable* nsFontMetricsWin::gFamilyNames = nsnull;
|
||||
|
||||
nsFontMetricsWin :: nsFontMetricsWin()
|
||||
{
|
||||
|
@ -53,12 +48,13 @@ nsFontMetricsWin :: ~nsFontMetricsWin()
|
|||
}
|
||||
|
||||
if (mLoadedFonts) {
|
||||
nsFontWin* font = mLoadedFonts;
|
||||
nsFontWin* end = &mLoadedFonts[mLoadedFontsCount];
|
||||
nsFontWin** font = mLoadedFonts;
|
||||
nsFontWin** end = &mLoadedFonts[mLoadedFontsCount];
|
||||
while (font < end) {
|
||||
if (font->font) {
|
||||
::DeleteObject(font->font);
|
||||
if ((*font)->font) {
|
||||
::DeleteObject((*font)->font);
|
||||
}
|
||||
delete *font;
|
||||
font++;
|
||||
}
|
||||
PR_Free(mLoadedFonts);
|
||||
|
@ -353,8 +349,8 @@ GetSpaces(HDC aDC)
|
|||
#undef SHOULD_BE_SPACE
|
||||
#define SHOULD_BE_SPACE(c) FONT_HAS_GLYPH(spaces, c)
|
||||
|
||||
static PRUint8*
|
||||
GetCMAP(HDC aDC)
|
||||
PRUint8*
|
||||
nsFontMetricsWin::GetCMAP(HDC aDC)
|
||||
{
|
||||
static PLHashTable* fontMaps = nsnull;
|
||||
static int initialized = 0;
|
||||
|
@ -542,20 +538,26 @@ nsFontMetricsWin::LoadFont(HDC aDC, nsString* aName)
|
|||
HFONT hfont = ::CreateFontIndirect(&logFont);
|
||||
|
||||
if (hfont) {
|
||||
HFONT oldFont = (HFONT) ::SelectObject(aDC, (HGDIOBJ) hfont);
|
||||
if (mLoadedFontsCount == mLoadedFontsAlloc) {
|
||||
int newSize = 2 * (mLoadedFontsAlloc ? mLoadedFontsAlloc : 1);
|
||||
nsFontWin* newPointer = (nsFontWin*) PR_Realloc(mLoadedFonts,
|
||||
newSize * sizeof(nsFontWin));
|
||||
nsFontWin** newPointer = (nsFontWin**) PR_Realloc(mLoadedFonts,
|
||||
newSize * sizeof(nsFontWin*));
|
||||
if (newPointer) {
|
||||
mLoadedFonts = newPointer;
|
||||
mLoadedFontsAlloc = newSize;
|
||||
}
|
||||
else {
|
||||
::DeleteObject(hfont);
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
nsFontWin* font = &mLoadedFonts[mLoadedFontsCount++];
|
||||
nsFontWin* font = new nsFontWin;
|
||||
if (!font) {
|
||||
::DeleteObject(hfont);
|
||||
return nsnull;
|
||||
}
|
||||
mLoadedFonts[mLoadedFontsCount++] = font;
|
||||
HFONT oldFont = (HFONT) ::SelectObject(aDC, (HGDIOBJ) hfont);
|
||||
font->font = hfont;
|
||||
font->map = GetCMAP(aDC);
|
||||
if (!font->map) {
|
||||
|
@ -583,36 +585,40 @@ static int CALLBACK enumProc(const LOGFONT* logFont, const TEXTMETRIC* metrics,
|
|||
|
||||
// XXX make this smarter: don't add font to list if we already have a font
|
||||
// with the same font signature -- erik
|
||||
if (gGlobalFontsCount == gGlobalFontsAlloc) {
|
||||
if (nsFontMetricsWin::gGlobalFontsCount == gGlobalFontsAlloc) {
|
||||
int newSize = 2 * (gGlobalFontsAlloc ? gGlobalFontsAlloc : 1);
|
||||
nsGlobalFont* newPointer = (nsGlobalFont*) PR_Realloc(gGlobalFonts,
|
||||
newSize * sizeof(nsGlobalFont));
|
||||
nsGlobalFont* newPointer = (nsGlobalFont*)
|
||||
PR_Realloc(nsFontMetricsWin::gGlobalFonts, newSize*sizeof(nsGlobalFont));
|
||||
if (newPointer) {
|
||||
gGlobalFonts = newPointer;
|
||||
nsFontMetricsWin::gGlobalFonts = newPointer;
|
||||
gGlobalFontsAlloc = newSize;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
nsGlobalFont* font = &gGlobalFonts[gGlobalFontsCount++];
|
||||
nsGlobalFont* font =
|
||||
&nsFontMetricsWin::gGlobalFonts[nsFontMetricsWin::gGlobalFontsCount++];
|
||||
|
||||
// XXX do correct character encoding conversion here
|
||||
font->name = new nsString(logFont->lfFaceName);
|
||||
if (!font->name) {
|
||||
gGlobalFontsCount--;
|
||||
nsFontMetricsWin::gGlobalFontsCount--;
|
||||
return 0;
|
||||
}
|
||||
font->map = nsnull;
|
||||
font->logFont = *logFont;
|
||||
font->skip = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
nsFontWin*
|
||||
nsFontMetricsWin::FindGlobalFont(HDC aDC, PRUnichar c)
|
||||
nsGlobalFont*
|
||||
nsFontMetricsWin::InitializeGlobalFonts(HDC aDC)
|
||||
{
|
||||
if (!gGlobalFonts) {
|
||||
static int gInitialized = 0;
|
||||
if (!gInitialized) {
|
||||
gInitialized = 1;
|
||||
LOGFONT logFont;
|
||||
logFont.lfCharSet = DEFAULT_CHARSET;
|
||||
logFont.lfFaceName[0] = 0;
|
||||
|
@ -624,22 +630,66 @@ nsFontMetricsWin::FindGlobalFont(HDC aDC, PRUnichar c)
|
|||
*/
|
||||
EnumFontFamiliesEx(aDC, &logFont, enumProc, nsnull, 0);
|
||||
}
|
||||
for (int i = 0; i < gGlobalFontsCount; i++) {
|
||||
if (!gGlobalFonts[i].map) {
|
||||
HFONT font = ::CreateFontIndirect(&gGlobalFonts[i].logFont);
|
||||
if (!font) {
|
||||
continue;
|
||||
|
||||
return gGlobalFonts;
|
||||
}
|
||||
|
||||
int
|
||||
nsFontMetricsWin::SameAsPreviousMap(int aIndex)
|
||||
{
|
||||
for (int i = 0; i < aIndex; i++) {
|
||||
if (!gGlobalFonts[i].skip) {
|
||||
if (gGlobalFonts[i].map == gGlobalFonts[aIndex].map) {
|
||||
gGlobalFonts[aIndex].skip = 1;
|
||||
return 1;
|
||||
}
|
||||
HFONT oldFont = (HFONT) ::SelectObject(aDC, font);
|
||||
gGlobalFonts[i].map = GetCMAP(aDC);
|
||||
::SelectObject(aDC, oldFont);
|
||||
::DeleteObject(font);
|
||||
if (!gGlobalFonts[i].map) {
|
||||
continue;
|
||||
PRUint8* map1 = gGlobalFonts[i].map;
|
||||
PRUint8* map2 = gGlobalFonts[aIndex].map;
|
||||
int j;
|
||||
for (j = 0; j < 8192; j++) {
|
||||
if (map1[j] != map2[j]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j == 8192) {
|
||||
gGlobalFonts[aIndex].skip = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (FONT_HAS_GLYPH(gGlobalFonts[i].map, c)) {
|
||||
return LoadFont(aDC, gGlobalFonts[i].name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
nsFontWin*
|
||||
nsFontMetricsWin::FindGlobalFont(HDC aDC, PRUnichar c)
|
||||
{
|
||||
if (!gGlobalFonts) {
|
||||
if (!InitializeGlobalFonts(aDC)) {
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < gGlobalFontsCount; i++) {
|
||||
if (!gGlobalFonts[i].skip) {
|
||||
if (!gGlobalFonts[i].map) {
|
||||
HFONT font = ::CreateFontIndirect(&gGlobalFonts[i].logFont);
|
||||
if (!font) {
|
||||
continue;
|
||||
}
|
||||
HFONT oldFont = (HFONT) ::SelectObject(aDC, font);
|
||||
gGlobalFonts[i].map = GetCMAP(aDC);
|
||||
::SelectObject(aDC, oldFont);
|
||||
::DeleteObject(font);
|
||||
if (!gGlobalFonts[i].map) {
|
||||
continue;
|
||||
}
|
||||
if (SameAsPreviousMap(i)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (FONT_HAS_GLYPH(gGlobalFonts[i].map, c)) {
|
||||
return LoadFont(aDC, gGlobalFonts[i].name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -671,16 +721,17 @@ static nsFontFamilyName gFamilyNameTable[] =
|
|||
{ nsnull, nsnull }
|
||||
};
|
||||
|
||||
static PLHashTable* gFamilyNames = nsnull;
|
||||
|
||||
nsFontWin*
|
||||
nsFontMetricsWin::FindLocalFont(HDC aDC, PRUnichar aChar)
|
||||
PLHashTable*
|
||||
nsFontMetricsWin::InitializeFamilyNames(void)
|
||||
{
|
||||
static int gInitialized = 0;
|
||||
if (!gInitialized) {
|
||||
gInitialized = 1;
|
||||
gFamilyNames = PL_NewHashTable(0, HashKey, CompareKeys, nsnull, nsnull,
|
||||
nsnull);
|
||||
if (!gFamilyNames) {
|
||||
return nsnull;
|
||||
}
|
||||
nsFontFamilyName* f = gFamilyNameTable;
|
||||
while (f->mName) {
|
||||
nsString* name = new nsString(f->mName);
|
||||
|
@ -692,6 +743,18 @@ nsFontMetricsWin::FindLocalFont(HDC aDC, PRUnichar aChar)
|
|||
}
|
||||
}
|
||||
|
||||
return gFamilyNames;
|
||||
}
|
||||
|
||||
nsFontWin*
|
||||
nsFontMetricsWin::FindLocalFont(HDC aDC, PRUnichar aChar)
|
||||
{
|
||||
if (!gFamilyNames) {
|
||||
if (!InitializeFamilyNames()) {
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
while (mFontsIndex < mFontsCount) {
|
||||
nsString* name = &mFonts[mFontsIndex++];
|
||||
nsString* low = new nsString(*name);
|
||||
|
@ -907,3 +970,719 @@ nsFontMetricsWin::GetFontHandle(nsFontHandle &aHandle)
|
|||
aHandle = mFontHandle;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
// The following is a workaround for a Japanese Windows 95 problem.
|
||||
|
||||
PRUint8 bitToCharSet[64] =
|
||||
{
|
||||
/*00*/ ANSI_CHARSET,
|
||||
/*01*/ EASTEUROPE_CHARSET,
|
||||
/*02*/ RUSSIAN_CHARSET,
|
||||
/*03*/ GREEK_CHARSET,
|
||||
/*04*/ TURKISH_CHARSET,
|
||||
/*05*/ HEBREW_CHARSET,
|
||||
/*06*/ ARABIC_CHARSET,
|
||||
/*07*/ BALTIC_CHARSET,
|
||||
/*08*/ DEFAULT_CHARSET,
|
||||
/*09*/ DEFAULT_CHARSET,
|
||||
/*10*/ DEFAULT_CHARSET,
|
||||
/*11*/ DEFAULT_CHARSET,
|
||||
/*12*/ DEFAULT_CHARSET,
|
||||
/*13*/ DEFAULT_CHARSET,
|
||||
/*14*/ DEFAULT_CHARSET,
|
||||
/*15*/ DEFAULT_CHARSET,
|
||||
/*16*/ DEFAULT_CHARSET,
|
||||
/*17*/ THAI_CHARSET,
|
||||
/*18*/ SHIFTJIS_CHARSET,
|
||||
/*19*/ GB2312_CHARSET,
|
||||
/*20*/ HANGEUL_CHARSET,
|
||||
/*21*/ CHINESEBIG5_CHARSET,
|
||||
/*22*/ JOHAB_CHARSET,
|
||||
/*23*/ DEFAULT_CHARSET,
|
||||
/*24*/ DEFAULT_CHARSET,
|
||||
/*25*/ DEFAULT_CHARSET,
|
||||
/*26*/ DEFAULT_CHARSET,
|
||||
/*27*/ DEFAULT_CHARSET,
|
||||
/*28*/ DEFAULT_CHARSET,
|
||||
/*29*/ DEFAULT_CHARSET,
|
||||
/*30*/ DEFAULT_CHARSET,
|
||||
/*31*/ DEFAULT_CHARSET,
|
||||
/*32*/ DEFAULT_CHARSET,
|
||||
/*33*/ DEFAULT_CHARSET,
|
||||
/*34*/ DEFAULT_CHARSET,
|
||||
/*35*/ DEFAULT_CHARSET,
|
||||
/*36*/ DEFAULT_CHARSET,
|
||||
/*37*/ DEFAULT_CHARSET,
|
||||
/*38*/ DEFAULT_CHARSET,
|
||||
/*39*/ DEFAULT_CHARSET,
|
||||
/*40*/ DEFAULT_CHARSET,
|
||||
/*41*/ DEFAULT_CHARSET,
|
||||
/*42*/ DEFAULT_CHARSET,
|
||||
/*43*/ DEFAULT_CHARSET,
|
||||
/*44*/ DEFAULT_CHARSET,
|
||||
/*45*/ DEFAULT_CHARSET,
|
||||
/*46*/ DEFAULT_CHARSET,
|
||||
/*47*/ DEFAULT_CHARSET,
|
||||
/*48*/ DEFAULT_CHARSET,
|
||||
/*49*/ DEFAULT_CHARSET,
|
||||
/*50*/ DEFAULT_CHARSET,
|
||||
/*51*/ DEFAULT_CHARSET,
|
||||
/*52*/ DEFAULT_CHARSET,
|
||||
/*53*/ DEFAULT_CHARSET,
|
||||
/*54*/ DEFAULT_CHARSET,
|
||||
/*55*/ DEFAULT_CHARSET,
|
||||
/*56*/ DEFAULT_CHARSET,
|
||||
/*57*/ DEFAULT_CHARSET,
|
||||
/*58*/ DEFAULT_CHARSET,
|
||||
/*59*/ DEFAULT_CHARSET,
|
||||
/*60*/ DEFAULT_CHARSET,
|
||||
/*61*/ DEFAULT_CHARSET,
|
||||
/*62*/ DEFAULT_CHARSET,
|
||||
/*63*/ DEFAULT_CHARSET
|
||||
};
|
||||
|
||||
enum nsCharSet
|
||||
{
|
||||
eCharSet_DEFAULT = 0,
|
||||
eCharSet_ANSI,
|
||||
eCharSet_EASTEUROPE,
|
||||
eCharSet_RUSSIAN,
|
||||
eCharSet_GREEK,
|
||||
eCharSet_TURKISH,
|
||||
eCharSet_HEBREW,
|
||||
eCharSet_ARABIC,
|
||||
eCharSet_BALTIC,
|
||||
eCharSet_THAI,
|
||||
eCharSet_SHIFTJIS,
|
||||
eCharSet_GB2312,
|
||||
eCharSet_HANGEUL,
|
||||
eCharSet_CHINESEBIG5,
|
||||
eCharSet_JOHAB,
|
||||
eCharSet_COUNT
|
||||
};
|
||||
|
||||
static nsCharSet gCharSetToIndex[256] =
|
||||
{
|
||||
/* 000 */ eCharSet_ANSI,
|
||||
/* 001 */ eCharSet_DEFAULT,
|
||||
/* 002 */ eCharSet_DEFAULT, // SYMBOL
|
||||
/* 003 */ eCharSet_DEFAULT,
|
||||
/* 004 */ eCharSet_DEFAULT,
|
||||
/* 005 */ eCharSet_DEFAULT,
|
||||
/* 006 */ eCharSet_DEFAULT,
|
||||
/* 007 */ eCharSet_DEFAULT,
|
||||
/* 008 */ eCharSet_DEFAULT,
|
||||
/* 009 */ eCharSet_DEFAULT,
|
||||
/* 010 */ eCharSet_DEFAULT,
|
||||
/* 011 */ eCharSet_DEFAULT,
|
||||
/* 012 */ eCharSet_DEFAULT,
|
||||
/* 013 */ eCharSet_DEFAULT,
|
||||
/* 014 */ eCharSet_DEFAULT,
|
||||
/* 015 */ eCharSet_DEFAULT,
|
||||
/* 016 */ eCharSet_DEFAULT,
|
||||
/* 017 */ eCharSet_DEFAULT,
|
||||
/* 018 */ eCharSet_DEFAULT,
|
||||
/* 019 */ eCharSet_DEFAULT,
|
||||
/* 020 */ eCharSet_DEFAULT,
|
||||
/* 021 */ eCharSet_DEFAULT,
|
||||
/* 022 */ eCharSet_DEFAULT,
|
||||
/* 023 */ eCharSet_DEFAULT,
|
||||
/* 024 */ eCharSet_DEFAULT,
|
||||
/* 025 */ eCharSet_DEFAULT,
|
||||
/* 026 */ eCharSet_DEFAULT,
|
||||
/* 027 */ eCharSet_DEFAULT,
|
||||
/* 028 */ eCharSet_DEFAULT,
|
||||
/* 029 */ eCharSet_DEFAULT,
|
||||
/* 030 */ eCharSet_DEFAULT,
|
||||
/* 031 */ eCharSet_DEFAULT,
|
||||
/* 032 */ eCharSet_DEFAULT,
|
||||
/* 033 */ eCharSet_DEFAULT,
|
||||
/* 034 */ eCharSet_DEFAULT,
|
||||
/* 035 */ eCharSet_DEFAULT,
|
||||
/* 036 */ eCharSet_DEFAULT,
|
||||
/* 037 */ eCharSet_DEFAULT,
|
||||
/* 038 */ eCharSet_DEFAULT,
|
||||
/* 039 */ eCharSet_DEFAULT,
|
||||
/* 040 */ eCharSet_DEFAULT,
|
||||
/* 041 */ eCharSet_DEFAULT,
|
||||
/* 042 */ eCharSet_DEFAULT,
|
||||
/* 043 */ eCharSet_DEFAULT,
|
||||
/* 044 */ eCharSet_DEFAULT,
|
||||
/* 045 */ eCharSet_DEFAULT,
|
||||
/* 046 */ eCharSet_DEFAULT,
|
||||
/* 047 */ eCharSet_DEFAULT,
|
||||
/* 048 */ eCharSet_DEFAULT,
|
||||
/* 049 */ eCharSet_DEFAULT,
|
||||
/* 050 */ eCharSet_DEFAULT,
|
||||
/* 051 */ eCharSet_DEFAULT,
|
||||
/* 052 */ eCharSet_DEFAULT,
|
||||
/* 053 */ eCharSet_DEFAULT,
|
||||
/* 054 */ eCharSet_DEFAULT,
|
||||
/* 055 */ eCharSet_DEFAULT,
|
||||
/* 056 */ eCharSet_DEFAULT,
|
||||
/* 057 */ eCharSet_DEFAULT,
|
||||
/* 058 */ eCharSet_DEFAULT,
|
||||
/* 059 */ eCharSet_DEFAULT,
|
||||
/* 060 */ eCharSet_DEFAULT,
|
||||
/* 061 */ eCharSet_DEFAULT,
|
||||
/* 062 */ eCharSet_DEFAULT,
|
||||
/* 063 */ eCharSet_DEFAULT,
|
||||
/* 064 */ eCharSet_DEFAULT,
|
||||
/* 065 */ eCharSet_DEFAULT,
|
||||
/* 066 */ eCharSet_DEFAULT,
|
||||
/* 067 */ eCharSet_DEFAULT,
|
||||
/* 068 */ eCharSet_DEFAULT,
|
||||
/* 069 */ eCharSet_DEFAULT,
|
||||
/* 070 */ eCharSet_DEFAULT,
|
||||
/* 071 */ eCharSet_DEFAULT,
|
||||
/* 072 */ eCharSet_DEFAULT,
|
||||
/* 073 */ eCharSet_DEFAULT,
|
||||
/* 074 */ eCharSet_DEFAULT,
|
||||
/* 075 */ eCharSet_DEFAULT,
|
||||
/* 076 */ eCharSet_DEFAULT,
|
||||
/* 077 */ eCharSet_DEFAULT, // MAC
|
||||
/* 078 */ eCharSet_DEFAULT,
|
||||
/* 079 */ eCharSet_DEFAULT,
|
||||
/* 080 */ eCharSet_DEFAULT,
|
||||
/* 081 */ eCharSet_DEFAULT,
|
||||
/* 082 */ eCharSet_DEFAULT,
|
||||
/* 083 */ eCharSet_DEFAULT,
|
||||
/* 084 */ eCharSet_DEFAULT,
|
||||
/* 085 */ eCharSet_DEFAULT,
|
||||
/* 086 */ eCharSet_DEFAULT,
|
||||
/* 087 */ eCharSet_DEFAULT,
|
||||
/* 088 */ eCharSet_DEFAULT,
|
||||
/* 089 */ eCharSet_DEFAULT,
|
||||
/* 090 */ eCharSet_DEFAULT,
|
||||
/* 091 */ eCharSet_DEFAULT,
|
||||
/* 092 */ eCharSet_DEFAULT,
|
||||
/* 093 */ eCharSet_DEFAULT,
|
||||
/* 094 */ eCharSet_DEFAULT,
|
||||
/* 095 */ eCharSet_DEFAULT,
|
||||
/* 096 */ eCharSet_DEFAULT,
|
||||
/* 097 */ eCharSet_DEFAULT,
|
||||
/* 098 */ eCharSet_DEFAULT,
|
||||
/* 099 */ eCharSet_DEFAULT,
|
||||
/* 100 */ eCharSet_DEFAULT,
|
||||
/* 101 */ eCharSet_DEFAULT,
|
||||
/* 102 */ eCharSet_DEFAULT,
|
||||
/* 103 */ eCharSet_DEFAULT,
|
||||
/* 104 */ eCharSet_DEFAULT,
|
||||
/* 105 */ eCharSet_DEFAULT,
|
||||
/* 106 */ eCharSet_DEFAULT,
|
||||
/* 107 */ eCharSet_DEFAULT,
|
||||
/* 108 */ eCharSet_DEFAULT,
|
||||
/* 109 */ eCharSet_DEFAULT,
|
||||
/* 110 */ eCharSet_DEFAULT,
|
||||
/* 111 */ eCharSet_DEFAULT,
|
||||
/* 112 */ eCharSet_DEFAULT,
|
||||
/* 113 */ eCharSet_DEFAULT,
|
||||
/* 114 */ eCharSet_DEFAULT,
|
||||
/* 115 */ eCharSet_DEFAULT,
|
||||
/* 116 */ eCharSet_DEFAULT,
|
||||
/* 117 */ eCharSet_DEFAULT,
|
||||
/* 118 */ eCharSet_DEFAULT,
|
||||
/* 119 */ eCharSet_DEFAULT,
|
||||
/* 120 */ eCharSet_DEFAULT,
|
||||
/* 121 */ eCharSet_DEFAULT,
|
||||
/* 122 */ eCharSet_DEFAULT,
|
||||
/* 123 */ eCharSet_DEFAULT,
|
||||
/* 124 */ eCharSet_DEFAULT,
|
||||
/* 125 */ eCharSet_DEFAULT,
|
||||
/* 126 */ eCharSet_DEFAULT,
|
||||
/* 127 */ eCharSet_DEFAULT,
|
||||
/* 128 */ eCharSet_SHIFTJIS,
|
||||
/* 129 */ eCharSet_HANGEUL,
|
||||
/* 130 */ eCharSet_JOHAB,
|
||||
/* 131 */ eCharSet_DEFAULT,
|
||||
/* 132 */ eCharSet_DEFAULT,
|
||||
/* 133 */ eCharSet_DEFAULT,
|
||||
/* 134 */ eCharSet_GB2312,
|
||||
/* 135 */ eCharSet_DEFAULT,
|
||||
/* 136 */ eCharSet_CHINESEBIG5,
|
||||
/* 137 */ eCharSet_DEFAULT,
|
||||
/* 138 */ eCharSet_DEFAULT,
|
||||
/* 139 */ eCharSet_DEFAULT,
|
||||
/* 140 */ eCharSet_DEFAULT,
|
||||
/* 141 */ eCharSet_DEFAULT,
|
||||
/* 142 */ eCharSet_DEFAULT,
|
||||
/* 143 */ eCharSet_DEFAULT,
|
||||
/* 144 */ eCharSet_DEFAULT,
|
||||
/* 145 */ eCharSet_DEFAULT,
|
||||
/* 146 */ eCharSet_DEFAULT,
|
||||
/* 147 */ eCharSet_DEFAULT,
|
||||
/* 148 */ eCharSet_DEFAULT,
|
||||
/* 149 */ eCharSet_DEFAULT,
|
||||
/* 150 */ eCharSet_DEFAULT,
|
||||
/* 151 */ eCharSet_DEFAULT,
|
||||
/* 152 */ eCharSet_DEFAULT,
|
||||
/* 153 */ eCharSet_DEFAULT,
|
||||
/* 154 */ eCharSet_DEFAULT,
|
||||
/* 155 */ eCharSet_DEFAULT,
|
||||
/* 156 */ eCharSet_DEFAULT,
|
||||
/* 157 */ eCharSet_DEFAULT,
|
||||
/* 158 */ eCharSet_DEFAULT,
|
||||
/* 159 */ eCharSet_DEFAULT,
|
||||
/* 160 */ eCharSet_DEFAULT,
|
||||
/* 161 */ eCharSet_GREEK,
|
||||
/* 162 */ eCharSet_TURKISH,
|
||||
/* 163 */ eCharSet_DEFAULT, // VIETNAMESE
|
||||
/* 164 */ eCharSet_DEFAULT,
|
||||
/* 165 */ eCharSet_DEFAULT,
|
||||
/* 166 */ eCharSet_DEFAULT,
|
||||
/* 167 */ eCharSet_DEFAULT,
|
||||
/* 168 */ eCharSet_DEFAULT,
|
||||
/* 169 */ eCharSet_DEFAULT,
|
||||
/* 170 */ eCharSet_DEFAULT,
|
||||
/* 171 */ eCharSet_DEFAULT,
|
||||
/* 172 */ eCharSet_DEFAULT,
|
||||
/* 173 */ eCharSet_DEFAULT,
|
||||
/* 174 */ eCharSet_DEFAULT,
|
||||
/* 175 */ eCharSet_DEFAULT,
|
||||
/* 176 */ eCharSet_DEFAULT,
|
||||
/* 177 */ eCharSet_HEBREW,
|
||||
/* 178 */ eCharSet_ARABIC,
|
||||
/* 179 */ eCharSet_DEFAULT,
|
||||
/* 180 */ eCharSet_DEFAULT,
|
||||
/* 181 */ eCharSet_DEFAULT,
|
||||
/* 182 */ eCharSet_DEFAULT,
|
||||
/* 183 */ eCharSet_DEFAULT,
|
||||
/* 184 */ eCharSet_DEFAULT,
|
||||
/* 185 */ eCharSet_DEFAULT,
|
||||
/* 186 */ eCharSet_BALTIC,
|
||||
/* 187 */ eCharSet_DEFAULT,
|
||||
/* 188 */ eCharSet_DEFAULT,
|
||||
/* 189 */ eCharSet_DEFAULT,
|
||||
/* 190 */ eCharSet_DEFAULT,
|
||||
/* 191 */ eCharSet_DEFAULT,
|
||||
/* 192 */ eCharSet_DEFAULT,
|
||||
/* 193 */ eCharSet_DEFAULT,
|
||||
/* 194 */ eCharSet_DEFAULT,
|
||||
/* 195 */ eCharSet_DEFAULT,
|
||||
/* 196 */ eCharSet_DEFAULT,
|
||||
/* 197 */ eCharSet_DEFAULT,
|
||||
/* 198 */ eCharSet_DEFAULT,
|
||||
/* 199 */ eCharSet_DEFAULT,
|
||||
/* 200 */ eCharSet_DEFAULT,
|
||||
/* 201 */ eCharSet_DEFAULT,
|
||||
/* 202 */ eCharSet_DEFAULT,
|
||||
/* 203 */ eCharSet_DEFAULT,
|
||||
/* 204 */ eCharSet_RUSSIAN,
|
||||
/* 205 */ eCharSet_DEFAULT,
|
||||
/* 206 */ eCharSet_DEFAULT,
|
||||
/* 207 */ eCharSet_DEFAULT,
|
||||
/* 208 */ eCharSet_DEFAULT,
|
||||
/* 209 */ eCharSet_DEFAULT,
|
||||
/* 210 */ eCharSet_DEFAULT,
|
||||
/* 211 */ eCharSet_DEFAULT,
|
||||
/* 212 */ eCharSet_DEFAULT,
|
||||
/* 213 */ eCharSet_DEFAULT,
|
||||
/* 214 */ eCharSet_DEFAULT,
|
||||
/* 215 */ eCharSet_DEFAULT,
|
||||
/* 216 */ eCharSet_DEFAULT,
|
||||
/* 217 */ eCharSet_DEFAULT,
|
||||
/* 218 */ eCharSet_DEFAULT,
|
||||
/* 219 */ eCharSet_DEFAULT,
|
||||
/* 220 */ eCharSet_DEFAULT,
|
||||
/* 221 */ eCharSet_DEFAULT,
|
||||
/* 222 */ eCharSet_THAI,
|
||||
/* 223 */ eCharSet_DEFAULT,
|
||||
/* 224 */ eCharSet_DEFAULT,
|
||||
/* 225 */ eCharSet_DEFAULT,
|
||||
/* 226 */ eCharSet_DEFAULT,
|
||||
/* 227 */ eCharSet_DEFAULT,
|
||||
/* 228 */ eCharSet_DEFAULT,
|
||||
/* 229 */ eCharSet_DEFAULT,
|
||||
/* 230 */ eCharSet_DEFAULT,
|
||||
/* 231 */ eCharSet_DEFAULT,
|
||||
/* 232 */ eCharSet_DEFAULT,
|
||||
/* 233 */ eCharSet_DEFAULT,
|
||||
/* 234 */ eCharSet_DEFAULT,
|
||||
/* 235 */ eCharSet_DEFAULT,
|
||||
/* 236 */ eCharSet_DEFAULT,
|
||||
/* 237 */ eCharSet_DEFAULT,
|
||||
/* 238 */ eCharSet_EASTEUROPE,
|
||||
/* 239 */ eCharSet_DEFAULT,
|
||||
/* 240 */ eCharSet_DEFAULT,
|
||||
/* 241 */ eCharSet_DEFAULT,
|
||||
/* 242 */ eCharSet_DEFAULT,
|
||||
/* 243 */ eCharSet_DEFAULT,
|
||||
/* 244 */ eCharSet_DEFAULT,
|
||||
/* 245 */ eCharSet_DEFAULT,
|
||||
/* 246 */ eCharSet_DEFAULT,
|
||||
/* 247 */ eCharSet_DEFAULT,
|
||||
/* 248 */ eCharSet_DEFAULT,
|
||||
/* 249 */ eCharSet_DEFAULT,
|
||||
/* 250 */ eCharSet_DEFAULT,
|
||||
/* 251 */ eCharSet_DEFAULT,
|
||||
/* 252 */ eCharSet_DEFAULT,
|
||||
/* 253 */ eCharSet_DEFAULT,
|
||||
/* 254 */ eCharSet_DEFAULT,
|
||||
/* 255 */ eCharSet_DEFAULT // OEM
|
||||
};
|
||||
|
||||
typedef struct nsCharSetInfo nsCharSetInfo;
|
||||
|
||||
struct nsCharSetInfo
|
||||
{
|
||||
char* mName;
|
||||
PRUint16 mCodePage;
|
||||
void (*GenerateMap)(nsCharSetInfo* aSelf);
|
||||
PRUint8* mMap;
|
||||
};
|
||||
|
||||
static void
|
||||
GenerateDefault(nsCharSetInfo* aSelf)
|
||||
{
|
||||
printf("%s defaulted\n", aSelf->mName);
|
||||
PRUint8* map = aSelf->mMap;
|
||||
for (int i = 0; i < 8192; i++) {
|
||||
map[i] = 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
GenerateSingleByte(nsCharSetInfo* aSelf)
|
||||
{
|
||||
PRUint8 mb[256];
|
||||
PRUint16 wc[256];
|
||||
int i;
|
||||
for (i = 0; i < 256; i++) {
|
||||
mb[i] = i;
|
||||
}
|
||||
int len = MultiByteToWideChar(aSelf->mCodePage, 0, (char*) mb, 256, wc, 256);
|
||||
if (len != 256) {
|
||||
printf("%s: MultiByteToWideChar returned %d\n", aSelf->mName, len);
|
||||
}
|
||||
PRUint8* map = aSelf->mMap;
|
||||
for (i = 0; i < 256; i++) {
|
||||
ADD_GLYPH(map, wc[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
GenerateMultiByte(nsCharSetInfo* aSelf)
|
||||
{
|
||||
PRUint8* map = aSelf->mMap;
|
||||
for (PRUint16 c = 0; c < 0xFFFF; c++) {
|
||||
BOOL defaulted = FALSE;
|
||||
WideCharToMultiByte(aSelf->mCodePage, 0, &c, 1, nsnull, 0, nsnull,
|
||||
&defaulted);
|
||||
if (!defaulted) {
|
||||
ADD_GLYPH(map, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static nsCharSetInfo gCharSetInfo[eCharSet_COUNT] =
|
||||
{
|
||||
{ "DEFAULT", 0, GenerateDefault },
|
||||
{ "ANSI", 1252, GenerateSingleByte },
|
||||
{ "EASTEUROPE", 1250, GenerateSingleByte },
|
||||
{ "RUSSIAN", 1251, GenerateSingleByte },
|
||||
{ "GREEK", 1253, GenerateSingleByte },
|
||||
{ "TURKISH", 1254, GenerateSingleByte },
|
||||
{ "HEBREW", 1255, GenerateSingleByte },
|
||||
{ "ARABIC", 1256, GenerateSingleByte },
|
||||
{ "BALTIC", 1257, GenerateSingleByte },
|
||||
{ "THAI", 874, GenerateSingleByte },
|
||||
{ "SHIFTJIS", 932, GenerateMultiByte },
|
||||
{ "GB2312", 936, GenerateMultiByte },
|
||||
{ "HANGEUL", 949, GenerateMultiByte },
|
||||
{ "CHINESEBIG5", 950, GenerateMultiByte },
|
||||
{ "JOHAB", 0, GenerateMultiByte }
|
||||
};
|
||||
|
||||
static int
|
||||
HaveConverterFor(PRUint8 aCharSet)
|
||||
{
|
||||
PRUint16 wc = 'a';
|
||||
char mb[8];
|
||||
if (WideCharToMultiByte(gCharSetInfo[gCharSetToIndex[aCharSet]].mCodePage, 0,
|
||||
&wc, 1, mb, sizeof(mb), nsnull, nsnull)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
nsFontWinA::GetSubsets(HDC aDC)
|
||||
{
|
||||
FONTSIGNATURE signature;
|
||||
if (::GetTextCharsetInfo(aDC, &signature, 0) == DEFAULT_CHARSET) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dword;
|
||||
DWORD* array = signature.fsCsb;
|
||||
mSubsetsCount = 0;
|
||||
for (dword = 0; dword < 2; dword++) {
|
||||
for (int bit = 0; bit < sizeof(DWORD) * 8; bit++) {
|
||||
if ((array[dword] >> bit) & 1) {
|
||||
PRUint8 charSet = bitToCharSet[bit];
|
||||
if (charSet != DEFAULT_CHARSET) {
|
||||
if (HaveConverterFor(charSet)) {
|
||||
mSubsetsCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mSubsets = (nsFontSubset*) PR_Calloc(mSubsetsCount, sizeof(nsFontSubset));
|
||||
if (!mSubsets) {
|
||||
mSubsetsCount = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for (dword = 0; dword < 2; dword++) {
|
||||
for (int bit = 0; bit < sizeof(DWORD) * 8; bit++) {
|
||||
if ((array[dword] >> bit) & 1) {
|
||||
PRUint8 charSet = bitToCharSet[bit];
|
||||
if (charSet != DEFAULT_CHARSET) {
|
||||
if (HaveConverterFor(charSet)) {
|
||||
mSubsets[i].mCharSet = charSet;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
FreeFont(nsFontWinA* aFont)
|
||||
{
|
||||
nsFontSubset* subset = aFont->mSubsets;
|
||||
nsFontSubset* endSubsets = &(aFont->mSubsets[aFont->mSubsetsCount]);
|
||||
while (subset < endSubsets) {
|
||||
if (subset->mFont) {
|
||||
::DeleteObject(subset->mFont);
|
||||
}
|
||||
if (subset->mMap) {
|
||||
PR_Free(subset->mMap);
|
||||
}
|
||||
subset++;
|
||||
}
|
||||
PR_Free(aFont->mSubsets);
|
||||
delete aFont;
|
||||
}
|
||||
|
||||
nsFontMetricsWinA::~nsFontMetricsWinA()
|
||||
{
|
||||
if (nsnull != mFont) {
|
||||
delete mFont;
|
||||
mFont = nsnull;
|
||||
}
|
||||
|
||||
mFontHandle = nsnull; // released below
|
||||
|
||||
if (mFonts) {
|
||||
delete [] mFonts;
|
||||
mFonts = nsnull;
|
||||
}
|
||||
|
||||
if (mLoadedFonts) {
|
||||
nsFontWinA** font = (nsFontWinA**) mLoadedFonts;
|
||||
nsFontWinA** end = (nsFontWinA**) &mLoadedFonts[mLoadedFontsCount];
|
||||
while (font < end) {
|
||||
FreeFont(*font);
|
||||
font++;
|
||||
}
|
||||
PR_Free(mLoadedFonts);
|
||||
mLoadedFonts = nsnull;
|
||||
}
|
||||
|
||||
mDeviceContext = nsnull;
|
||||
}
|
||||
|
||||
nsFontWin*
|
||||
nsFontMetricsWinA::LoadFont(HDC aDC, nsString* aName)
|
||||
{
|
||||
LOGFONT logFont;
|
||||
FillLogFont(&logFont);
|
||||
|
||||
// XXX need to preserve Unicode chars in face name (use LOGFONTW) -- erik
|
||||
aName->ToCString(logFont.lfFaceName, LF_FACESIZE);
|
||||
|
||||
HFONT hfont = ::CreateFontIndirect(&logFont);
|
||||
|
||||
if (hfont) {
|
||||
if (mLoadedFontsCount == mLoadedFontsAlloc) {
|
||||
int newSize = 2 * (mLoadedFontsAlloc ? mLoadedFontsAlloc : 1);
|
||||
nsFontWinA** newPointer = (nsFontWinA**) PR_Realloc(mLoadedFonts,
|
||||
newSize * sizeof(nsFontWinA*));
|
||||
if (newPointer) {
|
||||
mLoadedFonts = (nsFontWin**) newPointer;
|
||||
mLoadedFontsAlloc = newSize;
|
||||
}
|
||||
else {
|
||||
::DeleteObject(hfont);
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
nsFontWinA* font = new nsFontWinA;
|
||||
if (!font) {
|
||||
::DeleteObject(hfont);
|
||||
return nsnull;
|
||||
}
|
||||
mLoadedFonts[mLoadedFontsCount++] = (nsFontWin*) font;
|
||||
HFONT oldFont = (HFONT) ::SelectObject(aDC, (HGDIOBJ) hfont);
|
||||
font->mFont = hfont;
|
||||
font->mLogFont = logFont;
|
||||
if (!font->GetSubsets(aDC)) {
|
||||
mLoadedFontsCount--;
|
||||
::SelectObject(aDC, (HGDIOBJ) oldFont);
|
||||
::DeleteObject(hfont);
|
||||
return nsnull;
|
||||
}
|
||||
font->mMap = GetCMAP(aDC);
|
||||
if (!font->mMap) {
|
||||
mLoadedFontsCount--;
|
||||
::SelectObject(aDC, (HGDIOBJ) oldFont);
|
||||
::DeleteObject(hfont);
|
||||
return nsnull;
|
||||
}
|
||||
::SelectObject(aDC, (HGDIOBJ) oldFont);
|
||||
|
||||
return (nsFontWin*) font;
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
int
|
||||
nsFontSubset::Load(nsFontWinA* aFont)
|
||||
{
|
||||
LOGFONT* logFont = &aFont->mLogFont;
|
||||
logFont->lfCharSet = mCharSet;
|
||||
HFONT hfont = ::CreateFontIndirect(logFont);
|
||||
if (hfont) {
|
||||
int i = gCharSetToIndex[mCharSet];
|
||||
PRUint8* charSetMap = gCharSetInfo[i].mMap;
|
||||
if (!charSetMap) {
|
||||
charSetMap = (PRUint8*) PR_Calloc(8192, 1);
|
||||
if (charSetMap) {
|
||||
gCharSetInfo[i].mMap = charSetMap;
|
||||
gCharSetInfo[i].GenerateMap(&gCharSetInfo[i]);
|
||||
}
|
||||
else {
|
||||
::DeleteObject(hfont);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
mMap = (PRUint8*) PR_Malloc(8192);
|
||||
if (!mMap) {
|
||||
::DeleteObject(hfont);
|
||||
return 0;
|
||||
}
|
||||
PRUint8* fontMap = aFont->mMap;
|
||||
for (int j = 0; j < 8192; j++) {
|
||||
mMap[j] = (charSetMap[j] & fontMap[j]);
|
||||
}
|
||||
mCodePage = gCharSetInfo[i].mCodePage;
|
||||
mFont = hfont;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
nsFontWin*
|
||||
nsFontMetricsWinA::FindLocalFont(HDC aDC, PRUnichar aChar)
|
||||
{
|
||||
if (!gFamilyNames) {
|
||||
if (!InitializeFamilyNames()) {
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
while (mFontsIndex < mFontsCount) {
|
||||
nsString* name = &mFonts[mFontsIndex++];
|
||||
nsString* low = new nsString(*name);
|
||||
if (low) {
|
||||
low->ToLowerCase();
|
||||
nsString* winName = (nsString*) PL_HashTableLookup(gFamilyNames, low);
|
||||
delete low;
|
||||
if (!winName) {
|
||||
winName = name;
|
||||
}
|
||||
nsFontWinA* font = (nsFontWinA*) LoadFont(aDC, winName);
|
||||
if (font && FONT_HAS_GLYPH(font->mMap, aChar)) {
|
||||
nsFontSubset* subset = font->mSubsets;
|
||||
nsFontSubset* endSubsets = &(font->mSubsets[font->mSubsetsCount]);
|
||||
while (subset < endSubsets) {
|
||||
if (!subset->mMap) {
|
||||
if (!subset->Load(font)) {
|
||||
subset++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (FONT_HAS_GLYPH(subset->mMap, aChar)) {
|
||||
return (nsFontWin*) subset;
|
||||
}
|
||||
subset++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsFontWin*
|
||||
nsFontMetricsWinA::FindGlobalFont(HDC aDC, PRUnichar c)
|
||||
{
|
||||
if (!gGlobalFonts) {
|
||||
if (!InitializeGlobalFonts(aDC)) {
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < gGlobalFontsCount; i++) {
|
||||
if (!gGlobalFonts[i].skip) {
|
||||
if (!gGlobalFonts[i].map) {
|
||||
HFONT font = ::CreateFontIndirect(&gGlobalFonts[i].logFont);
|
||||
if (!font) {
|
||||
continue;
|
||||
}
|
||||
HFONT oldFont = (HFONT) ::SelectObject(aDC, font);
|
||||
gGlobalFonts[i].map = GetCMAP(aDC);
|
||||
::SelectObject(aDC, oldFont);
|
||||
::DeleteObject(font);
|
||||
if (!gGlobalFonts[i].map) {
|
||||
continue;
|
||||
}
|
||||
if (SameAsPreviousMap(i)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (FONT_HAS_GLYPH(gGlobalFonts[i].map, c)) {
|
||||
nsFontWinA* font = (nsFontWinA*) LoadFont(aDC, gGlobalFonts[i].name);
|
||||
if (font) {
|
||||
nsFontSubset* subset = font->mSubsets;
|
||||
nsFontSubset* endSubsets = &(font->mSubsets[font->mSubsetsCount]);
|
||||
while (subset < endSubsets) {
|
||||
if (!subset->mMap) {
|
||||
if (!subset->Load(font)) {
|
||||
subset++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (FONT_HAS_GLYPH(subset->mMap, c)) {
|
||||
return (nsFontWin*) subset;
|
||||
}
|
||||
subset++;
|
||||
}
|
||||
mLoadedFontsCount--;
|
||||
FreeFont(font);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include <windows.h>
|
||||
|
||||
#include "plhash.h"
|
||||
#include "nsIFontMetrics.h"
|
||||
#include "nsFont.h"
|
||||
#include "nsString.h"
|
||||
|
@ -45,11 +46,19 @@ typedef struct nsFontWin
|
|||
PRUint8* map;
|
||||
} nsFontWin;
|
||||
|
||||
typedef struct nsGlobalFont
|
||||
{
|
||||
nsString* name;
|
||||
LOGFONT logFont;
|
||||
PRUint8* map;
|
||||
PRUint8 skip;
|
||||
} nsGlobalFont;
|
||||
|
||||
class nsFontMetricsWin : public nsIFontMetrics
|
||||
{
|
||||
public:
|
||||
nsFontMetricsWin();
|
||||
~nsFontMetricsWin();
|
||||
virtual ~nsFontMetricsWin();
|
||||
|
||||
NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
|
||||
|
||||
|
@ -72,12 +81,14 @@ public:
|
|||
NS_IMETHOD GetFont(const nsFont *&aFont);
|
||||
NS_IMETHOD GetFontHandle(nsFontHandle &aHandle);
|
||||
|
||||
nsFontWin* FindGlobalFont(HDC aDC, PRUnichar aChar);
|
||||
nsFontWin* FindLocalFont(HDC aDC, PRUnichar aChar);
|
||||
nsFontWin* FindFont(HDC aDC, PRUnichar aChar);
|
||||
nsFontWin* LoadFont(HDC aDC, nsString* aName);
|
||||
virtual nsFontWin* FindGlobalFont(HDC aDC, PRUnichar aChar);
|
||||
virtual nsFontWin* FindLocalFont(HDC aDC, PRUnichar aChar);
|
||||
nsFontWin* FindFont(HDC aDC, PRUnichar aChar);
|
||||
virtual nsFontWin* LoadFont(HDC aDC, nsString* aName);
|
||||
|
||||
nsFontWin *mLoadedFonts;
|
||||
int SameAsPreviousMap(int aIndex);
|
||||
|
||||
nsFontWin **mLoadedFonts;
|
||||
PRUint16 mLoadedFontsAlloc;
|
||||
PRUint16 mLoadedFontsCount;
|
||||
|
||||
|
@ -86,6 +97,9 @@ public:
|
|||
PRUint16 mFontsCount;
|
||||
PRUint16 mFontsIndex;
|
||||
|
||||
static nsGlobalFont* gGlobalFonts;
|
||||
static int gGlobalFontsCount;
|
||||
|
||||
protected:
|
||||
void FillLogFont(LOGFONT* aLogFont);
|
||||
void RealizeFont();
|
||||
|
@ -107,6 +121,50 @@ protected:
|
|||
nscoord mUnderlineSize;
|
||||
nscoord mUnderlineOffset;
|
||||
HFONT mFontHandle;
|
||||
|
||||
static PLHashTable* InitializeFamilyNames(void);
|
||||
static PLHashTable* gFamilyNames;
|
||||
|
||||
static nsGlobalFont* InitializeGlobalFonts(HDC aDC);
|
||||
|
||||
static PRUint8* GetCMAP(HDC aDC);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// The following is a workaround for a Japanse Windows 95 problem.
|
||||
|
||||
typedef struct nsFontWinA nsFontWinA;
|
||||
|
||||
// must start with same fields as nsFontWin
|
||||
struct nsFontSubset
|
||||
{
|
||||
int Load(nsFontWinA* aFont);
|
||||
|
||||
HFONT mFont;
|
||||
PRUint8* mMap;
|
||||
BYTE mCharSet;
|
||||
PRUint16 mCodePage;
|
||||
};
|
||||
|
||||
struct nsFontWinA
|
||||
{
|
||||
int GetSubsets(HDC aDC);
|
||||
|
||||
LOGFONT mLogFont;
|
||||
HFONT mFont;
|
||||
PRUint8* mMap;
|
||||
nsFontSubset* mSubsets;
|
||||
PRUint16 mSubsetsCount;
|
||||
};
|
||||
|
||||
class nsFontMetricsWinA : public nsFontMetricsWin
|
||||
{
|
||||
public:
|
||||
virtual ~nsFontMetricsWinA();
|
||||
|
||||
virtual nsFontWin* FindLocalFont(HDC aDC, PRUnichar aChar);
|
||||
virtual nsFontWin* FindGlobalFont(HDC aDC, PRUnichar aChar);
|
||||
virtual nsFontWin* LoadFont(HDC aDC, nsString* aName);
|
||||
};
|
||||
|
||||
#endif /* nsFontMetricsWin_h__ */
|
||||
|
|
|
@ -66,8 +66,24 @@ class nsGfxFactoryWin : public nsIFactory
|
|||
nsCID mClassID;
|
||||
};
|
||||
|
||||
static int gUseAFunctions = 0;
|
||||
|
||||
nsGfxFactoryWin::nsGfxFactoryWin(const nsCID &aClass)
|
||||
{
|
||||
static int init = 0;
|
||||
if (!init) {
|
||||
init = 1;
|
||||
OSVERSIONINFO os;
|
||||
os.dwOSVersionInfoSize = sizeof(os);
|
||||
::GetVersionEx(&os);
|
||||
if ((os.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) &&
|
||||
(os.dwMajorVersion == 4) &&
|
||||
(os.dwMinorVersion == 0) && // Windows 95 (not 98)
|
||||
(::GetACP() == 932)) { // Shift-JIS (Japanese)
|
||||
gUseAFunctions = 1;
|
||||
}
|
||||
}
|
||||
|
||||
mRefCnt = 0;
|
||||
mClassID = aClass;
|
||||
}
|
||||
|
@ -129,7 +145,12 @@ nsresult nsGfxFactoryWin::CreateInstance(nsISupports *aOuter,
|
|||
|
||||
if (mClassID.Equals(kCFontMetrics)) {
|
||||
nsFontMetricsWin* fm;
|
||||
NS_NEWXPCOM(fm, nsFontMetricsWin);
|
||||
if (gUseAFunctions) {
|
||||
NS_NEWXPCOM(fm, nsFontMetricsWinA);
|
||||
}
|
||||
else {
|
||||
NS_NEWXPCOM(fm, nsFontMetricsWin);
|
||||
}
|
||||
inst = (nsISupports *)fm;
|
||||
}
|
||||
else if (mClassID.Equals(kCDeviceContext)) {
|
||||
|
@ -139,7 +160,12 @@ nsresult nsGfxFactoryWin::CreateInstance(nsISupports *aOuter,
|
|||
}
|
||||
else if (mClassID.Equals(kCRenderingContext)) {
|
||||
nsRenderingContextWin* rc;
|
||||
NS_NEWXPCOM(rc, nsRenderingContextWin);
|
||||
if (gUseAFunctions) {
|
||||
NS_NEWXPCOM(rc, nsRenderingContextWinA);
|
||||
}
|
||||
else {
|
||||
NS_NEWXPCOM(rc, nsRenderingContextWin);
|
||||
}
|
||||
inst = (nsISupports *)((nsIRenderingContext*)rc);
|
||||
}
|
||||
else if (mClassID.Equals(kCImage)) {
|
||||
|
|
|
@ -1454,7 +1454,7 @@ NS_IMETHODIMP nsRenderingContextWin :: GetWidth(const PRUnichar *aString,
|
|||
if (nsnull != mFontMetrics)
|
||||
{
|
||||
nsFontMetricsWin* metrics = (nsFontMetricsWin*) mFontMetrics;
|
||||
HFONT prevFont = nsnull;
|
||||
nsFontWin* prevFont = nsnull;
|
||||
SIZE size;
|
||||
|
||||
SetupFontAndColor();
|
||||
|
@ -1463,32 +1463,22 @@ NS_IMETHODIMP nsRenderingContextWin :: GetWidth(const PRUnichar *aString,
|
|||
PRUint32 start = 0;
|
||||
for (PRUint32 i = 0; i < aLength; i++) {
|
||||
PRUnichar c = aString[i];
|
||||
HFONT currFont = mCurrFont;
|
||||
nsFontWin* font = metrics->mLoadedFonts;
|
||||
nsFontWin* end = &metrics->mLoadedFonts[metrics->mLoadedFontsCount];
|
||||
nsFontWin* currFont = nsnull;
|
||||
nsFontWin** font = metrics->mLoadedFonts;
|
||||
nsFontWin** end = &metrics->mLoadedFonts[metrics->mLoadedFontsCount];
|
||||
while (font < end) {
|
||||
if (FONT_HAS_GLYPH(font->map, c)) {
|
||||
currFont = font->font;
|
||||
if (FONT_HAS_GLYPH((*font)->map, c)) {
|
||||
currFont = *font;
|
||||
goto FoundFont; // for speed -- avoid "if" statement
|
||||
}
|
||||
font++;
|
||||
}
|
||||
font = metrics->FindLocalFont(mDC, c);
|
||||
if (font) {
|
||||
currFont = font->font;
|
||||
}
|
||||
else {
|
||||
// XXX get CSS to pass inherited or default font list?
|
||||
font = metrics->FindGlobalFont(mDC, c);
|
||||
if (font) {
|
||||
currFont = font->font;
|
||||
}
|
||||
}
|
||||
currFont = metrics->FindFont(mDC, c);
|
||||
FoundFont:
|
||||
// XXX avoid this test by duplicating code
|
||||
if (prevFont) {
|
||||
if (currFont != prevFont) {
|
||||
::SelectObject(mDC, prevFont);
|
||||
::SelectObject(mDC, prevFont->font);
|
||||
::GetTextExtentPoint32W(mDC, &aString[start], i - start, &size);
|
||||
width += size.cx;
|
||||
prevFont = currFont;
|
||||
|
@ -1502,7 +1492,7 @@ FoundFont:
|
|||
}
|
||||
|
||||
if (prevFont) {
|
||||
::SelectObject(mDC, prevFont);
|
||||
::SelectObject(mDC, prevFont->font);
|
||||
::GetTextExtentPoint32W(mDC, &aString[start], i - start, &size);
|
||||
width += size.cx;
|
||||
}
|
||||
|
@ -1560,7 +1550,7 @@ NS_IMETHODIMP nsRenderingContextWin :: DrawString(const PRUnichar *aString, PRUi
|
|||
PRInt32 y = aY;
|
||||
mTMatrix->TransformCoord(&x, &y);
|
||||
nsFontMetricsWin* metrics = (nsFontMetricsWin*) mFontMetrics;
|
||||
HFONT prevFont = nsnull;
|
||||
nsFontWin* prevFont = nsnull;
|
||||
SIZE size;
|
||||
|
||||
SetupFontAndColor();
|
||||
|
@ -1568,31 +1558,21 @@ NS_IMETHODIMP nsRenderingContextWin :: DrawString(const PRUnichar *aString, PRUi
|
|||
PRUint32 start = 0;
|
||||
for (PRUint32 i = 0; i < aLength; i++) {
|
||||
PRUnichar c = aString[i];
|
||||
HFONT currFont = mCurrFont;
|
||||
nsFontWin* font = metrics->mLoadedFonts;
|
||||
nsFontWin* end = &metrics->mLoadedFonts[metrics->mLoadedFontsCount];
|
||||
nsFontWin* currFont = nsnull;
|
||||
nsFontWin** font = metrics->mLoadedFonts;
|
||||
nsFontWin** end = &metrics->mLoadedFonts[metrics->mLoadedFontsCount];
|
||||
while (font < end) {
|
||||
if (FONT_HAS_GLYPH(font->map, c)) {
|
||||
currFont = font->font;
|
||||
if (FONT_HAS_GLYPH((*font)->map, c)) {
|
||||
currFont = *font;
|
||||
goto FoundFont; // for speed -- avoid "if" statement
|
||||
}
|
||||
font++;
|
||||
}
|
||||
font = metrics->FindLocalFont(mDC, c);
|
||||
if (font) {
|
||||
currFont = font->font;
|
||||
}
|
||||
else {
|
||||
// XXX get CSS to pass UA's default font list?
|
||||
font = metrics->FindGlobalFont(mDC, c);
|
||||
if (font) {
|
||||
currFont = font->font;
|
||||
}
|
||||
}
|
||||
currFont = metrics->FindFont(mDC, c);
|
||||
FoundFont:
|
||||
if (prevFont) {
|
||||
if (currFont != prevFont) {
|
||||
::SelectObject(mDC, prevFont);
|
||||
::SelectObject(mDC, prevFont->font);
|
||||
if (aSpacing) {
|
||||
// XXX Fix path to use a twips transform in the DC and use the
|
||||
// spacing values directly and let windows deal with the sub-pixel
|
||||
|
@ -1628,7 +1608,7 @@ FoundFont:
|
|||
}
|
||||
|
||||
if (prevFont) {
|
||||
::SelectObject(mDC, prevFont);
|
||||
::SelectObject(mDC, prevFont->font);
|
||||
if (aSpacing) {
|
||||
// XXX Fix path to use a twips transform in the DC and use the
|
||||
// spacing values directly and let windows deal with the sub-pixel
|
||||
|
@ -2027,3 +2007,252 @@ NS_IMETHODIMP nsRenderingContextWin :: CreateDrawingSurface(HDC aDC, nsDrawingSu
|
|||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
// The following is a workaround for a Japanese Windows 95 problem.
|
||||
|
||||
NS_IMETHODIMP nsRenderingContextWinA :: GetWidth(const PRUnichar *aString,
|
||||
PRUint32 aLength,
|
||||
nscoord &aWidth,
|
||||
PRInt32 *aFontID)
|
||||
{
|
||||
if (nsnull != mFontMetrics)
|
||||
{
|
||||
nsFontMetricsWinA* metrics = (nsFontMetricsWinA*) mFontMetrics;
|
||||
nsFontSubset* prevFont = nsnull;
|
||||
SIZE size;
|
||||
|
||||
SetupFontAndColor();
|
||||
|
||||
LONG width = 0;
|
||||
PRUint32 start = 0;
|
||||
for (PRUint32 i = 0; i < aLength; i++) {
|
||||
PRUnichar c = aString[i];
|
||||
nsFontSubset* currFont = nsnull;
|
||||
nsFontWinA** font = (nsFontWinA**) metrics->mLoadedFonts;
|
||||
nsFontWinA** end = (nsFontWinA**) &metrics->mLoadedFonts[metrics->mLoadedFontsCount];
|
||||
while (font < end) {
|
||||
if (FONT_HAS_GLYPH((*font)->mMap, c)) {
|
||||
nsFontSubset* subset = (*font)->mSubsets;
|
||||
nsFontSubset* endSubsets = &((*font)->mSubsets[(*font)->mSubsetsCount]);
|
||||
while (subset < endSubsets) {
|
||||
if (!subset->mMap) {
|
||||
if (!subset->Load(*font)) {
|
||||
subset++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (FONT_HAS_GLYPH(subset->mMap, c)) {
|
||||
currFont = subset;
|
||||
goto FoundFont; // for speed -- avoid "if" statement
|
||||
}
|
||||
subset++;
|
||||
}
|
||||
}
|
||||
font++;
|
||||
}
|
||||
currFont = (nsFontSubset*) metrics->FindFont(mDC, c);
|
||||
FoundFont:
|
||||
// XXX avoid this test by duplicating code
|
||||
if (prevFont) {
|
||||
if (currFont != prevFont) {
|
||||
::SelectObject(mDC, prevFont->mFont);
|
||||
char str[1024];
|
||||
int len = WideCharToMultiByte(prevFont->mCodePage, 0, &aString[start],
|
||||
i - start, str, sizeof(str), nsnull, nsnull);
|
||||
if (len) {
|
||||
::GetTextExtentPoint32A(mDC, str, len, &size);
|
||||
width += size.cx;
|
||||
}
|
||||
else {
|
||||
// XXX failed
|
||||
printf("%d: WideCharToMultiByte failed\n", prevFont->mCodePage);
|
||||
}
|
||||
prevFont = currFont;
|
||||
start = i;
|
||||
}
|
||||
}
|
||||
else {
|
||||
prevFont = currFont;
|
||||
start = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (prevFont) {
|
||||
::SelectObject(mDC, prevFont->mFont);
|
||||
char str[1024];
|
||||
int len = WideCharToMultiByte(prevFont->mCodePage, 0, &aString[start],
|
||||
i - start, str, sizeof(str), nsnull, nsnull);
|
||||
if (len) {
|
||||
::GetTextExtentPoint32A(mDC, str, len, &size);
|
||||
width += size.cx;
|
||||
}
|
||||
else {
|
||||
// XXX failed
|
||||
printf("%d: WideCharToMultiByte failed\n", prevFont->mCodePage);
|
||||
}
|
||||
}
|
||||
|
||||
aWidth = NSToCoordRound(float(width) * mP2T);
|
||||
|
||||
::SelectObject(mDC, mCurrFont);
|
||||
|
||||
if (nsnull != aFontID)
|
||||
*aFontID = 0;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
else
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsRenderingContextWinA :: DrawString(const PRUnichar *aString, PRUint32 aLength,
|
||||
nscoord aX, nscoord aY,
|
||||
PRInt32 aFontID,
|
||||
const nscoord* aSpacing)
|
||||
{
|
||||
if (nsnull != mFontMetrics)
|
||||
{
|
||||
PRInt32 x = aX;
|
||||
PRInt32 y = aY;
|
||||
mTMatrix->TransformCoord(&x, &y);
|
||||
nsFontMetricsWinA* metrics = (nsFontMetricsWinA*) mFontMetrics;
|
||||
nsFontSubset* prevFont = nsnull;
|
||||
SIZE size;
|
||||
|
||||
SetupFontAndColor();
|
||||
|
||||
PRUint32 start = 0;
|
||||
for (PRUint32 i = 0; i < aLength; i++) {
|
||||
PRUnichar c = aString[i];
|
||||
nsFontSubset* currFont = nsnull;
|
||||
nsFontWinA** font = (nsFontWinA**) metrics->mLoadedFonts;
|
||||
nsFontWinA** end = (nsFontWinA**) &metrics->mLoadedFonts[metrics->mLoadedFontsCount];
|
||||
while (font < end) {
|
||||
if (FONT_HAS_GLYPH((*font)->mMap, c)) {
|
||||
nsFontSubset* subset = (*font)->mSubsets;
|
||||
nsFontSubset* endSubsets = &((*font)->mSubsets[(*font)->mSubsetsCount]);
|
||||
while (subset < endSubsets) {
|
||||
if (!subset->mMap) {
|
||||
if (!subset->Load(*font)) {
|
||||
subset++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (FONT_HAS_GLYPH(subset->mMap, c)) {
|
||||
currFont = subset;
|
||||
goto FoundFont; // for speed -- avoid "if" statement
|
||||
}
|
||||
subset++;
|
||||
}
|
||||
}
|
||||
font++;
|
||||
}
|
||||
currFont = (nsFontSubset*) metrics->FindFont(mDC, c);
|
||||
FoundFont:
|
||||
if (prevFont) {
|
||||
if (currFont != prevFont) {
|
||||
::SelectObject(mDC, prevFont->mFont);
|
||||
if (aSpacing) {
|
||||
// XXX Fix path to use a twips transform in the DC and use the
|
||||
// spacing values directly and let windows deal with the sub-pixel
|
||||
// positioning.
|
||||
|
||||
// Slow, but accurate rendering
|
||||
const PRUnichar* str = &aString[start];
|
||||
const PRUnichar* end = &aString[i];
|
||||
while (str < end) {
|
||||
// XXX can shave some cycles by inlining a version of transform
|
||||
// coord where y is constant and transformed once
|
||||
x = aX;
|
||||
y = aY;
|
||||
mTMatrix->TransformCoord(&x, &y);
|
||||
char mb[1024];
|
||||
int len = WideCharToMultiByte(prevFont->mCodePage, 0, str, 1, mb,
|
||||
sizeof(mb), nsnull, nsnull);
|
||||
if (len) {
|
||||
::ExtTextOutA(mDC, x, y, 0, NULL, mb, len, NULL);
|
||||
}
|
||||
else {
|
||||
// XXX failed
|
||||
printf("%d: WideCharToMultiByte failed\n", prevFont->mCodePage);
|
||||
}
|
||||
aX += *aSpacing++;
|
||||
str++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
char mb[1024];
|
||||
int len = WideCharToMultiByte(prevFont->mCodePage, 0,
|
||||
&aString[start], i - start, mb, sizeof(mb), nsnull, nsnull);
|
||||
if (len) {
|
||||
::ExtTextOutA(mDC, x, y, 0, NULL, mb, len, NULL);
|
||||
::GetTextExtentPoint32A(mDC, mb, len, &size);
|
||||
x += size.cx;
|
||||
}
|
||||
else {
|
||||
// XXX failed
|
||||
printf("%d: WideCharToMultiByte failed\n", prevFont->mCodePage);
|
||||
}
|
||||
}
|
||||
prevFont = currFont;
|
||||
start = i;
|
||||
}
|
||||
}
|
||||
else {
|
||||
prevFont = currFont;
|
||||
start = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (prevFont) {
|
||||
::SelectObject(mDC, prevFont->mFont);
|
||||
if (aSpacing) {
|
||||
// XXX Fix path to use a twips transform in the DC and use the
|
||||
// spacing values directly and let windows deal with the sub-pixel
|
||||
// positioning.
|
||||
|
||||
// Slow, but accurate rendering
|
||||
const PRUnichar* str = &aString[start];
|
||||
const PRUnichar* end = &aString[i];
|
||||
while (str < end) {
|
||||
// XXX can shave some cycles by inlining a version of transform
|
||||
// coord where y is constant and transformed once
|
||||
x = aX;
|
||||
y = aY;
|
||||
mTMatrix->TransformCoord(&x, &y);
|
||||
char mb[1024];
|
||||
int len = WideCharToMultiByte(prevFont->mCodePage, 0, str, 1, mb,
|
||||
sizeof(mb), nsnull, nsnull);
|
||||
if (len) {
|
||||
::ExtTextOutA(mDC, x, y, 0, NULL, mb, len, NULL);
|
||||
}
|
||||
else {
|
||||
// XXX failed
|
||||
printf("%d: WideCharToMultiByte failed\n", prevFont->mCodePage);
|
||||
}
|
||||
aX += *aSpacing++;
|
||||
str++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
char mb[1024];
|
||||
int len = WideCharToMultiByte(prevFont->mCodePage, 0,
|
||||
&aString[start], i - start, mb, sizeof(mb), nsnull, nsnull);
|
||||
if (len) {
|
||||
::ExtTextOutA(mDC, x, y, 0, NULL, mb, len, NULL);
|
||||
}
|
||||
else {
|
||||
// XXX failed
|
||||
printf("%d: WideCharToMultiByte failed\n", prevFont->mCodePage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
::SelectObject(mDC, mCurrFont);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
else
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
|
|
@ -162,6 +162,9 @@ public:
|
|||
// nsIRenderingContextWin
|
||||
NS_IMETHOD CreateDrawingSurface(HDC aDC, nsDrawingSurface &aSurface);
|
||||
|
||||
protected:
|
||||
void SetupFontAndColor(void);
|
||||
|
||||
private:
|
||||
~nsRenderingContextWin();
|
||||
|
||||
|
@ -172,7 +175,6 @@ private:
|
|||
HPEN SetupSolidPen(void);
|
||||
HPEN SetupDashedPen(void);
|
||||
HPEN SetupDottedPen(void);
|
||||
void SetupFontAndColor(void);
|
||||
void PushClipState(void);
|
||||
|
||||
protected:
|
||||
|
@ -218,4 +220,18 @@ protected:
|
|||
void* mScriptObject;
|
||||
};
|
||||
|
||||
|
||||
// The following is a workaround for a Japanese Windows 95 problem.
|
||||
|
||||
class nsRenderingContextWinA : public nsRenderingContextWin
|
||||
{
|
||||
public:
|
||||
NS_IMETHOD GetWidth(const PRUnichar* aString, PRUint32 aLength,
|
||||
nscoord& aWidth, PRInt32 *aFontID);
|
||||
NS_IMETHOD DrawString(const PRUnichar *aString, PRUint32 aLength,
|
||||
nscoord aX, nscoord aY,
|
||||
PRInt32 aFontID,
|
||||
const nscoord* aSpacing);
|
||||
};
|
||||
|
||||
#endif /* nsRenderingContextWin_h___ */
|
||||
|
|
Загрузка…
Ссылка в новой задаче