Added yet another defense to make Mozilla really robust when font resources run out, the patch makes font metrics to be fail safe or at least very hard to break -- to the point that failure means that the system is barely working (testing showed that Mozilla stayed alive while other applications were dying). Per request of super-reviewer & driver, also removed wallpaper null-checks sprinkled in the past for the problem. b=136248, r=shanjian, sr=attinasi

This commit is contained in:
rbs%maths.uq.edu.au 2002-05-02 22:24:59 +00:00
parent b1e82db052
commit ca47d8b903
9 changed files with 38 additions and 78 deletions

View File

@ -223,17 +223,10 @@ nscoord CalcLength(const nsCSSValue& aValue,
case eCSSUnit_XHeight: {
aInherited = PR_TRUE;
const nsFont* font = aStyleContext ? &(((nsStyleFont*)aStyleContext->GetStyleData(eStyleStruct_Font))->mFont) : aFont;
nsIFontMetrics* fm;
aPresContext->GetMetricsFor(*font, &fm);
NS_ASSERTION(nsnull != fm, "can't get font metrics");
nsCOMPtr<nsIFontMetrics> fm;
aPresContext->GetMetricsFor(*font, getter_AddRefs(fm));
nscoord xHeight;
if (nsnull != fm) {
fm->GetXHeight(xHeight);
NS_RELEASE(fm);
}
else {
xHeight = ((font->size * 2) / 3);
}
fm->GetXHeight(xHeight);
return NSToCoordRound(aValue.GetFloatValue() * (float)xHeight);
}
case eCSSUnit_CapHeight: {

View File

@ -651,6 +651,7 @@ nsFontCache::GetMetricsFor(const nsFont& aFont, nsIAtom* aLangGroup,
return NS_OK;
}
NS_POSTCONDITION(NS_SUCCEEDED(rv), "font metrics should not be null - bug 136248");
return rv;
}

View File

@ -2400,7 +2400,15 @@ nsFontMetricsWin::FindSubstituteFont(HDC aDC, PRUint32 c)
}
}
// if we ever reach here, the replacement char should be changed to a more common char
// We are running out of resources if we reach here... Try a stock font
NS_ASSERTION(::GetMapMode(aDC) == MM_TEXT, "mapping mode needs to be MM_TEXT");
nsFontWin* font = LoadSubstituteFont(aDC, nsnull);
if (font) {
((nsFontWinSubstitute*)font)->SetRepresentable(c);
mSubstituteFont = font;
return font;
}
NS_ERROR("Could not provide a substititute font");
return nsnull;
}
@ -2409,12 +2417,15 @@ nsFontWin*
nsFontMetricsWin::LoadSubstituteFont(HDC aDC, nsString* aName)
{
LOGFONT logFont;
HFONT hfont = CreateFontHandle(aDC, aName, &logFont);
HFONT hfont = aName
? CreateFontHandle(aDC, aName, &logFont)
: (HFONT)::GetStockObject(SYSTEM_FONT);
if (hfont) {
// XXX 'displayUnicode' has to be initialized based on the desired rendering mode
PRBool displayUnicode = PR_FALSE;
/* substitute font does not need ccmap */
nsFontWinSubstitute* font = new nsFontWinSubstitute(&logFont, hfont, nsnull, displayUnicode);
LOGFONT* lfont = aName ? &logFont : nsnull;
nsFontWinSubstitute* font = new nsFontWinSubstitute(lfont, hfont, nsnull, displayUnicode);
if (font) {
HFONT oldFont = (HFONT)::SelectObject(aDC, (HGDIOBJ)hfont);
InitMetricsFor(aDC, font);

View File

@ -2287,11 +2287,6 @@ ComputeLineHeight(nsIPresContext* aPresContext,
}
nsCOMPtr<nsIFontMetrics> fm;
deviceContext->GetMetricsFor(font->mFont, langGroup, *getter_AddRefs(fm));
if (!fm) {
NS_WARNING( "null font metrics for the device context - we have to fix this someday...");
}
if (unit == eStyleUnit_Factor) {
// For factor units the computed value of the line-height property
// is found by multiplying the factor by the font's <b>actual</b>
@ -2305,7 +2300,7 @@ ComputeLineHeight(nsIPresContext* aPresContext,
// precise layout in the face of imprecise fonts.
nscoord emHeight = font->mFont.size;
#ifdef NEW_FONT_HEIGHT_APIS
if (!nsHTMLReflowState::UseComputedHeight() && fm) {
if (!nsHTMLReflowState::UseComputedHeight()) {
fm->GetEmHeight(emHeight);
}
#endif
@ -2314,7 +2309,7 @@ ComputeLineHeight(nsIPresContext* aPresContext,
NS_ASSERTION(eStyleUnit_Normal == unit, "bad unit");
lineHeight = font->mFont.size;
#ifdef NEW_FONT_HEIGHT_APIS
if (!nsHTMLReflowState::UseComputedHeight() && fm) {
if (!nsHTMLReflowState::UseComputedHeight()) {
lineHeight = GetNormalLineHeight(fm);
}
#endif

View File

@ -569,14 +569,11 @@ public:
}
mAveCharWidth = 0;
deviceContext->GetMetricsFor(*plainFont, langGroup, mNormalFont);
NS_ASSERTION(mNormalFont, "null normal font cannot be handled");
if (mNormalFont) {
aRenderingContext.SetFont(mNormalFont); // some users of the struct expect this state
mNormalFont->GetSpaceWidth(mSpaceWidth);
aRenderingContext.SetFont(mNormalFont); // some users of the struct expect this state
mNormalFont->GetSpaceWidth(mSpaceWidth);
#if defined(_WIN32) || defined(XP_OS2)
mNormalFont->GetAveCharWidth(mAveCharWidth);
mNormalFont->GetAveCharWidth(mAveCharWidth);
#endif
}
if (0 == mAveCharWidth) {
// provide a default if it could not be resolved
mAveCharWidth = 10;
@ -4612,18 +4609,8 @@ nsTextFrame::MeasureText(nsIPresContext* aPresContext,
aTextData.mX = 0;
if (aTextData.mMeasureText) {
// NOTE: in some cases, when font resources are exhausted, we end up with no normal font.
// This will cause a crash because we are not handling it at the source and everyplace else
// assumes the normal font is non-null.
// This bit of ASSERTION / Runtime checking is to prevent the crash, but is only wallpaper.
// We need to handle the problem when the font is being realized - currently that just throws
// an assertion and we continue on.
// See bug 117736
NS_ASSERTION(aTs.mNormalFont, "null normal font, probably ran out of font resources");
if (aTs.mNormalFont) {
aTs.mNormalFont->GetMaxAscent(aTextData.mAscent);
aTs.mNormalFont->GetMaxDescent(aTextData.mDescent);
}
aTs.mNormalFont->GetMaxAscent(aTextData.mAscent);
aTs.mNormalFont->GetMaxDescent(aTextData.mDescent);
}
for (;;firstThing = PR_FALSE) {
#ifdef IBMBIDI

View File

@ -2287,11 +2287,6 @@ ComputeLineHeight(nsIPresContext* aPresContext,
}
nsCOMPtr<nsIFontMetrics> fm;
deviceContext->GetMetricsFor(font->mFont, langGroup, *getter_AddRefs(fm));
if (!fm) {
NS_WARNING( "null font metrics for the device context - we have to fix this someday...");
}
if (unit == eStyleUnit_Factor) {
// For factor units the computed value of the line-height property
// is found by multiplying the factor by the font's <b>actual</b>
@ -2305,7 +2300,7 @@ ComputeLineHeight(nsIPresContext* aPresContext,
// precise layout in the face of imprecise fonts.
nscoord emHeight = font->mFont.size;
#ifdef NEW_FONT_HEIGHT_APIS
if (!nsHTMLReflowState::UseComputedHeight() && fm) {
if (!nsHTMLReflowState::UseComputedHeight()) {
fm->GetEmHeight(emHeight);
}
#endif
@ -2314,7 +2309,7 @@ ComputeLineHeight(nsIPresContext* aPresContext,
NS_ASSERTION(eStyleUnit_Normal == unit, "bad unit");
lineHeight = font->mFont.size;
#ifdef NEW_FONT_HEIGHT_APIS
if (!nsHTMLReflowState::UseComputedHeight() && fm) {
if (!nsHTMLReflowState::UseComputedHeight()) {
lineHeight = GetNormalLineHeight(fm);
}
#endif

View File

@ -569,14 +569,11 @@ public:
}
mAveCharWidth = 0;
deviceContext->GetMetricsFor(*plainFont, langGroup, mNormalFont);
NS_ASSERTION(mNormalFont, "null normal font cannot be handled");
if (mNormalFont) {
aRenderingContext.SetFont(mNormalFont); // some users of the struct expect this state
mNormalFont->GetSpaceWidth(mSpaceWidth);
aRenderingContext.SetFont(mNormalFont); // some users of the struct expect this state
mNormalFont->GetSpaceWidth(mSpaceWidth);
#if defined(_WIN32) || defined(XP_OS2)
mNormalFont->GetAveCharWidth(mAveCharWidth);
mNormalFont->GetAveCharWidth(mAveCharWidth);
#endif
}
if (0 == mAveCharWidth) {
// provide a default if it could not be resolved
mAveCharWidth = 10;
@ -4612,18 +4609,8 @@ nsTextFrame::MeasureText(nsIPresContext* aPresContext,
aTextData.mX = 0;
if (aTextData.mMeasureText) {
// NOTE: in some cases, when font resources are exhausted, we end up with no normal font.
// This will cause a crash because we are not handling it at the source and everyplace else
// assumes the normal font is non-null.
// This bit of ASSERTION / Runtime checking is to prevent the crash, but is only wallpaper.
// We need to handle the problem when the font is being realized - currently that just throws
// an assertion and we continue on.
// See bug 117736
NS_ASSERTION(aTs.mNormalFont, "null normal font, probably ran out of font resources");
if (aTs.mNormalFont) {
aTs.mNormalFont->GetMaxAscent(aTextData.mAscent);
aTs.mNormalFont->GetMaxDescent(aTextData.mDescent);
}
aTs.mNormalFont->GetMaxAscent(aTextData.mAscent);
aTs.mNormalFont->GetMaxDescent(aTextData.mDescent);
}
for (;;firstThing = PR_FALSE) {
#ifdef IBMBIDI

View File

@ -1174,11 +1174,9 @@ nsMathMLContainerFrame::PlaceTokenFor(nsIFrame* aFrame,
aFrame->GetStyleData(eStyleStruct_Font, (const nsStyleStruct*&)font);
nsCOMPtr<nsIFontMetrics> fm;
aPresContext->GetMetricsFor(font->mFont, getter_AddRefs(fm));
nscoord ascent = 0, descent = 0;
if (fm) {
fm->GetMaxAscent(ascent);
fm->GetMaxDescent(descent);
}
nscoord ascent, descent;
fm->GetMaxAscent(ascent);
fm->GetMaxDescent(descent);
nsBoundingMetrics bm;
NS_STATIC_CAST(nsMathMLContainerFrame*, aFrame)->GetBoundingMetrics(bm);

View File

@ -223,17 +223,10 @@ nscoord CalcLength(const nsCSSValue& aValue,
case eCSSUnit_XHeight: {
aInherited = PR_TRUE;
const nsFont* font = aStyleContext ? &(((nsStyleFont*)aStyleContext->GetStyleData(eStyleStruct_Font))->mFont) : aFont;
nsIFontMetrics* fm;
aPresContext->GetMetricsFor(*font, &fm);
NS_ASSERTION(nsnull != fm, "can't get font metrics");
nsCOMPtr<nsIFontMetrics> fm;
aPresContext->GetMetricsFor(*font, getter_AddRefs(fm));
nscoord xHeight;
if (nsnull != fm) {
fm->GetXHeight(xHeight);
NS_RELEASE(fm);
}
else {
xHeight = ((font->size * 2) / 3);
}
fm->GetXHeight(xHeight);
return NSToCoordRound(aValue.GetFloatValue() * (float)xHeight);
}
case eCSSUnit_CapHeight: {