зеркало из https://github.com/mozilla/pjs.git
#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:
Родитель
8d58c0f3eb
Коммит
3a04cd4ddd
|
@ -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__ */
|
||||
|
|
Загрузка…
Ссылка в новой задаче