#63965 crashed under Simplified Chinese Win2000 OS when scroll bar is dragged

r = nhotta,  sr=blizzard

"LoadGlobalFont" function is added to both "nsFontMetricsWin"
and "nsFontMetricsWinA" class to replace existing "LoadFont" call.
This function will use the "LOGFONT" stored in global font list to
create new font, that include charset parameter. CMAP is created
again for "mLoadedFont", but copied from global font item.

When enumerating the font, true type font is put in priority order
so that it will be searched first. This is done inside "enumProc"
function.
This commit is contained in:
shanjian%netscape.com 2001-04-18 00:30:46 +00:00
parent 3cb9428b20
commit b739eb1ec6
2 changed files with 113 additions and 20 deletions

View File

@ -1977,16 +1977,53 @@ nsFontMetricsWin::LoadFont(HDC aDC, nsString* aName)
return nsnull;
}
nsFontWin*
nsFontMetricsWin::LoadGlobalFont(HDC aDC, nsGlobalFont* aGlobalFontItem)
{
HFONT hfont = ::CreateFontIndirect(&(aGlobalFontItem->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;
}
}
nsFontWin* font = nsnull;
if (mIsUserDefined) {
font = new nsFontWinNonUnicode(&(aGlobalFontItem->logFont), hfont, gUserDefinedMap,
gUserDefinedConverter);
}
else if (NS_FONT_TYPE_UNICODE == aGlobalFontItem->fonttype) {
font = new nsFontWinUnicode(&(aGlobalFontItem->logFont), hfont, aGlobalFontItem->map);
}
else if (NS_FONT_TYPE_NON_UNICODE == aGlobalFontItem->fonttype) {
nsIUnicodeEncoder* converter = GetConverter(aGlobalFontItem->logFont.lfFaceName);
if (converter) {
font = new nsFontWinNonUnicode(&(aGlobalFontItem->logFont), hfont, aGlobalFontItem->map, converter);
}
}
mLoadedFonts[mLoadedFontsCount++] = font;
return font;
}
return nsnull;
}
static int CALLBACK enumProc(const LOGFONT* logFont, const TEXTMETRIC* metrics,
DWORD fontType, LPARAM closure)
{
#ifdef MOZ_MATHML
// XXX need a better way to deal with non-TrueType fonts?
if (!(fontType & TRUETYPE_FONTTYPE)) {
//printf("rejecting %s\n", logFont->lfFaceName);
return 1;
}
#endif
// XXX ignore vertical fonts
if (logFont->lfFaceName[0] == '@') {
return 1;
@ -2021,30 +2058,38 @@ static int CALLBACK enumProc(const LOGFONT* logFont, const TEXTMETRIC* metrics,
return 0;
}
}
nsGlobalFont* font =
&nsFontMetricsWin::gGlobalFonts[nsFontMetricsWin::gGlobalFontsCount++];
nsGlobalFont font;
PRUnichar name[LF_FACESIZE];
name[0] = 0;
MultiByteToWideChar(CP_ACP, 0, logFont->lfFaceName,
strlen(logFont->lfFaceName) + 1, name, sizeof(name)/sizeof(name[0]));
font->name = new nsString(name);
if (!font->name) {
nsFontMetricsWin::gGlobalFontsCount--;
font.name = new nsString(name);
if (!font.name) {
return 0;
}
font->map = nsnull;
font->logFont = *logFont;
font->skip = 0;
font->signature.fsCsb[0] = 0;
font->signature.fsCsb[1] = 0;
font.map = nsnull;
font.logFont = *logFont;
font.skip = 0;
font.signature.fsCsb[0] = 0;
font.signature.fsCsb[1] = 0;
int charSetSigBit = charSetToBit[gCharSetToIndex[logFont->lfCharSet]];
if (charSetSigBit >= 0) {
DWORD charsetSigAdd = 1 << charSetSigBit;
nsFontMetricsWin::gGlobalFonts[i].signature.fsCsb[0] |= charsetSigAdd;
font.signature.fsCsb[0] |= charsetSigAdd;
}
static int lastTtfFont = 0;
if (fontType & TRUETYPE_FONTTYPE) {
nsFontMetricsWin::gGlobalFonts[nsFontMetricsWin::gGlobalFontsCount++] =
nsFontMetricsWin::gGlobalFonts[lastTtfFont];
nsFontMetricsWin::gGlobalFonts[lastTtfFont++] = font;
}
else
nsFontMetricsWin::gGlobalFonts[nsFontMetricsWin::gGlobalFontsCount++] = font;
return 1;
}
@ -2099,6 +2144,7 @@ nsFontMetricsWin::SameAsPreviousMap(int aIndex)
nsFontWin*
nsFontMetricsWin::FindGlobalFont(HDC aDC, PRUnichar c)
{
//now try global font
if (!gGlobalFonts) {
if (!InitializeGlobalFonts(aDC)) {
return nsnull;
@ -2113,7 +2159,7 @@ nsFontMetricsWin::FindGlobalFont(HDC aDC, PRUnichar c)
}
HFONT oldFont = (HFONT) ::SelectObject(aDC, font);
gGlobalFonts[i].map = GetCMAP(aDC, gGlobalFonts[i].logFont.lfFaceName,
nsnull, nsnull);
&(gGlobalFonts[i].fonttype), nsnull);
::SelectObject(aDC, oldFont);
::DeleteObject(font);
if (!gGlobalFonts[i].map) {
@ -2125,7 +2171,8 @@ nsFontMetricsWin::FindGlobalFont(HDC aDC, PRUnichar c)
}
}
if (FONT_HAS_GLYPH(gGlobalFonts[i].map, c)) {
return LoadFont(aDC, gGlobalFonts[i].name);
//return LoadFont(aDC, gGlobalFonts[i].name);
return LoadGlobalFont(aDC, &(gGlobalFonts[i]));
}
}
}
@ -4150,6 +4197,47 @@ nsFontMetricsWinA::LoadFont(HDC aDC, nsString* aName)
return nsnull;
}
nsFontWin*
nsFontMetricsWinA::LoadGlobalFont(HDC aDC, nsGlobalFont* aGlobalFontItem)
{
/*
* According to http://msdn.microsoft.com/library/
* CreateFontIndirectW is only supported on NT/2000
*/
HFONT hfont = ::CreateFontIndirect(&(aGlobalFontItem->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(&(aGlobalFontItem->logFont), hfont, aGlobalFontItem->map);
if (!font)
return nsnull;
if (!font->GetSubsets(aDC)) {
delete font;
return nsnull;
}
mLoadedFonts[mLoadedFontsCount++] = font;
return font;
}
return nsnull;
}
int
nsFontSubset::Load(nsFontWinA* aFont)
{

View File

@ -88,6 +88,7 @@ typedef struct nsGlobalFont
PRUint32* map;
PRUint8 skip;
FONTSIGNATURE signature;
int fonttype;
} nsGlobalFont;
class nsFontMetricsWin : public nsIFontMetrics
@ -137,6 +138,8 @@ public:
virtual nsFontWin* LoadSubstituteFont(HDC aDC, nsString* aName);
virtual nsFontWin* FindSubstituteFont(HDC aDC, PRUnichar aChar);
virtual nsFontWin* LoadGlobalFont(HDC aDC, nsGlobalFont* aGlobalFontItem);
int SameAsPreviousMap(int aIndex);
nsFontWin **mLoadedFonts;
@ -300,6 +303,8 @@ public:
virtual nsFontWin* LoadSubstituteFont(HDC aDC, nsString* aName);
virtual nsFontWin* FindSubstituteFont(HDC aDC, PRUnichar aChar);
virtual nsFontWin* LoadGlobalFont(HDC aDC, nsGlobalFont* aGlobalFontItem);
};
#endif /* nsFontMetricsWin_h__ */