зеркало из https://github.com/mozilla/gecko-dev.git
[not part of default build] gracefully handle cases where stretching failed to avoid jamming chars. a:waterson@mozilla.org
This commit is contained in:
Родитель
1616385ac6
Коммит
e1acbfa6ef
|
@ -468,9 +468,9 @@ nsMathMLmfencedFrame::ReflowChar(nsIPresContext* aPresContext,
|
|||
// stretch the char to the appropriate height if it is not big enough.
|
||||
nsBoundingMetrics charSize;
|
||||
charSize.Clear(); // this will tell stretch that we don't know the default size
|
||||
aMathMLChar->Stretch(aPresContext, aRenderingContext,
|
||||
NS_STRETCH_DIRECTION_VERTICAL,
|
||||
aContainerSize, charSize);
|
||||
nsresult res = aMathMLChar->Stretch(aPresContext, aRenderingContext,
|
||||
NS_STRETCH_DIRECTION_VERTICAL,
|
||||
aContainerSize, charSize);
|
||||
|
||||
if (eMathMLChar_DONT_STRETCH != aMathMLChar->GetEnum())
|
||||
{
|
||||
|
@ -482,6 +482,13 @@ nsMathMLmfencedFrame::ReflowChar(nsIPresContext* aPresContext,
|
|||
else {
|
||||
charSize.ascent = fontAscent;
|
||||
charSize.descent = fontDescent;
|
||||
if (NS_FAILED(res) && charSize.width == 0) {
|
||||
// gracefully handle cases where stretching the char failed (i.e., GetBoundingMetrics failed)
|
||||
// we need to get the width
|
||||
aRenderingContext.GetWidth(aData, charSize.width);
|
||||
// XXX the bounding metrics of the MathMLChar is not updated, but PlaceChar()
|
||||
// will do the right thing by leaving the necessary room to paint the char.
|
||||
}
|
||||
}
|
||||
|
||||
if (aDesiredSize.ascent < charSize.ascent)
|
||||
|
@ -511,7 +518,7 @@ nsMathMLmfencedFrame::PlaceChar(nsMathMLChar* aMathMLChar,
|
|||
aMathMLChar->GetBoundingMetrics(bm);
|
||||
|
||||
// the char's x-origin was used to store lspace ...
|
||||
// the char's y-origin was used to stored the ascent ...
|
||||
// the char's y-origin was used to store the ascent ...
|
||||
nsRect rect;
|
||||
aMathMLChar->GetRect(rect);
|
||||
|
||||
|
|
|
@ -614,13 +614,7 @@ nsMathMLmoFrame::Stretch(nsIPresContext* aPresContext,
|
|||
|
||||
// Operators that exist in the dictionary are handled by the MathMLChar
|
||||
|
||||
if (!NS_MATHML_OPERATOR_GET_FORM(mFlags)) {
|
||||
// Place our children
|
||||
Place(aPresContext, aRenderingContext, PR_TRUE, aDesiredStretchSize);
|
||||
}
|
||||
else {
|
||||
// The rendering will be handled by our MathML char
|
||||
|
||||
if (NS_MATHML_OPERATOR_GET_FORM(mFlags)) {
|
||||
nsBoundingMetrics charSize;
|
||||
nsBoundingMetrics initialSize = aDesiredStretchSize.mBoundingMetrics;
|
||||
nsBoundingMetrics container = initialSize;
|
||||
|
@ -726,51 +720,64 @@ nsMathMLmoFrame::Stretch(nsIPresContext* aPresContext,
|
|||
|
||||
// let the MathMLChar stretch itself...
|
||||
charSize.Clear(); // this will tell stretch that we don't know the default size
|
||||
mMathMLChar.Stretch(aPresContext, aRenderingContext,
|
||||
aStretchDirection, container, charSize, stretchHint);
|
||||
// update our bounding metrics... it becomes that of our MathML char
|
||||
mMathMLChar.GetBoundingMetrics(mBoundingMetrics);
|
||||
|
||||
if (isVertical)
|
||||
{
|
||||
// the desired size returned by mMathMLChar maybe different
|
||||
// from the size of the container.
|
||||
// the mMathMLChar.mRect.y calculation is subtle, watch out!!!
|
||||
|
||||
height = mBoundingMetrics.ascent + mBoundingMetrics.descent;
|
||||
if (NS_MATHML_OPERATOR_IS_SYMMETRIC(mFlags)) {
|
||||
// For symmetric and vertical operators,
|
||||
// we want to center about the axis of the container
|
||||
mBoundingMetrics.descent = height/2 - axisHeight;
|
||||
}
|
||||
else {
|
||||
// Otherwise, align the char with the bottom of the container
|
||||
mBoundingMetrics.descent = container.descent;
|
||||
}
|
||||
mBoundingMetrics.ascent = height - mBoundingMetrics.descent;
|
||||
nsresult res = mMathMLChar.Stretch(aPresContext, aRenderingContext,
|
||||
aStretchDirection, container, charSize, stretchHint);
|
||||
if (NS_FAILED(res)) {
|
||||
// gracefully handle cases where stretching the char failed (i.e., GetBoundingMetrics failed)
|
||||
// clear our 'form' to behave as if the operator wasn't in the dictionary
|
||||
mFlags &= ~0x3;
|
||||
}
|
||||
else {
|
||||
// update our bounding metrics... it becomes that of our MathML char
|
||||
mMathMLChar.GetBoundingMetrics(mBoundingMetrics);
|
||||
|
||||
// Prepare the metrics to return
|
||||
aDesiredStretchSize.ascent = PR_MAX(fontAscent, mBoundingMetrics.ascent); /* + delta1*/
|
||||
aDesiredStretchSize.descent = PR_MAX(fontDescent, mBoundingMetrics.descent); /* + delta2*/
|
||||
aDesiredStretchSize.width = mBoundingMetrics.width;
|
||||
aDesiredStretchSize.height = aDesiredStretchSize.ascent + aDesiredStretchSize.descent;
|
||||
aDesiredStretchSize.mBoundingMetrics = mBoundingMetrics;
|
||||
if (isVertical)
|
||||
{
|
||||
// the desired size returned by mMathMLChar maybe different
|
||||
// from the size of the container.
|
||||
// the mMathMLChar.mRect.y calculation is subtle, watch out!!!
|
||||
|
||||
nscoord dy = aDesiredStretchSize.ascent - mBoundingMetrics.ascent;
|
||||
if (mMathMLChar.GetEnum() == eMathMLChar_DONT_STRETCH)
|
||||
{
|
||||
// reset
|
||||
dy = aDesiredStretchSize.ascent - charSize.ascent;
|
||||
aDesiredStretchSize.mBoundingMetrics = mBoundingMetrics = charSize;
|
||||
height = mBoundingMetrics.ascent + mBoundingMetrics.descent;
|
||||
if (NS_MATHML_OPERATOR_IS_SYMMETRIC(mFlags)) {
|
||||
// For symmetric and vertical operators,
|
||||
// we want to center about the axis of the container
|
||||
mBoundingMetrics.descent = height/2 - axisHeight;
|
||||
}
|
||||
else {
|
||||
// Otherwise, align the char with the bottom of the container
|
||||
mBoundingMetrics.descent = container.descent;
|
||||
}
|
||||
mBoundingMetrics.ascent = height - mBoundingMetrics.descent;
|
||||
}
|
||||
|
||||
// Prepare the metrics to return
|
||||
aDesiredStretchSize.ascent = PR_MAX(fontAscent, mBoundingMetrics.ascent); /* + delta1*/
|
||||
aDesiredStretchSize.descent = PR_MAX(fontDescent, mBoundingMetrics.descent); /* + delta2*/
|
||||
aDesiredStretchSize.width = mBoundingMetrics.width;
|
||||
aDesiredStretchSize.height = aDesiredStretchSize.ascent + aDesiredStretchSize.descent;
|
||||
aDesiredStretchSize.mBoundingMetrics = mBoundingMetrics;
|
||||
|
||||
nscoord dy = aDesiredStretchSize.ascent - mBoundingMetrics.ascent;
|
||||
if (mMathMLChar.GetEnum() == eMathMLChar_DONT_STRETCH)
|
||||
{
|
||||
// reset
|
||||
dy = aDesiredStretchSize.ascent - charSize.ascent;
|
||||
aDesiredStretchSize.mBoundingMetrics = mBoundingMetrics = charSize;
|
||||
}
|
||||
|
||||
mMathMLChar.SetRect(
|
||||
nsRect(0, dy, charSize.width,
|
||||
charSize.ascent + charSize.descent));
|
||||
|
||||
mReference.x = 0;
|
||||
mReference.y = aDesiredStretchSize.ascent;
|
||||
}
|
||||
}
|
||||
|
||||
mMathMLChar.SetRect(
|
||||
nsRect(0, dy, charSize.width,
|
||||
charSize.ascent + charSize.descent));
|
||||
|
||||
mReference.x = 0;
|
||||
mReference.y = aDesiredStretchSize.ascent;
|
||||
if (!NS_MATHML_OPERATOR_GET_FORM(mFlags)) {
|
||||
// Place our children using the default method
|
||||
Place(aPresContext, aRenderingContext, PR_TRUE, aDesiredStretchSize);
|
||||
}
|
||||
|
||||
// Before we leave... there is a last item in the check-list:
|
||||
|
|
Загрузка…
Ссылка в новой задаче