#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
Родитель 8d58c0f3eb
Коммит 3a04cd4ddd
2 изменённых файлов: 113 добавлений и 20 удалений

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

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

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

@ -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__ */