Get*Width for nsMathMLContainerFrame base class. b=363240 r+sr=roc

This commit is contained in:
karlt+@karlt.net 2008-02-27 02:45:36 -08:00
Родитель e226a0a21c
Коммит dd2fa836ab
4 изменённых файлов: 115 добавлений и 36 удалений

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

@ -1020,6 +1020,62 @@ nsMathMLContainerFrame::Reflow(nsPresContext* aPresContext,
return NS_OK;
}
/* virtual */ nscoord
nsMathMLContainerFrame::GetMinWidth(nsIRenderingContext *aRenderingContext)
{
nscoord result;
DISPLAY_MIN_WIDTH(this, result);
result = GetIntrinsicWidth(aRenderingContext);
return result;
}
/* virtual */ nscoord
nsMathMLContainerFrame::GetPrefWidth(nsIRenderingContext *aRenderingContext)
{
nscoord result;
DISPLAY_MIN_WIDTH(this, result);
result = GetIntrinsicWidth(aRenderingContext);
return result;
}
/* virtual */ nscoord
nsMathMLContainerFrame::GetIntrinsicWidth(nsIRenderingContext *aRenderingContext)
{
// Get child widths
nsIFrame* childFrame = mFrames.FirstChild();
while (childFrame) {
// XXX This includes margin while Reflow currently doesn't consider
// margin, so we may end up with too much space, but, with stretchy
// characters, this is an approximation anyway.
nscoord width =
nsLayoutUtils::IntrinsicForContainer(aRenderingContext, childFrame,
nsLayoutUtils::PREF_WIDTH);
nsHTMLReflowMetrics childDesiredSize;
childDesiredSize.width = width;
childDesiredSize.mBoundingMetrics.width = width;
// TODO: we need nsIFrame::GetIntrinsicHBounds() for better values here.
childDesiredSize.mBoundingMetrics.leftBearing = 0;
childDesiredSize.mBoundingMetrics.rightBearing = width;
SaveReflowAndBoundingMetricsFor(childFrame, childDesiredSize,
childDesiredSize.mBoundingMetrics);
childFrame = childFrame->GetNextSibling();
}
// Measure
nsHTMLReflowMetrics desiredSize;
nsresult rv = Place(*aRenderingContext, PR_FALSE, desiredSize);
if (NS_FAILED(rv)) {
ReflowError(*aRenderingContext, desiredSize);
}
ClearSavedChildMetrics();
return desiredSize.width;
}
// see spacing table in Chapter 18, TeXBook (p.170)
// Our table isn't quite identical to TeX because operators have
// built-in values for lspace & rspace in the Operator Dictionary.

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

@ -134,6 +134,18 @@ public:
RemoveFrame(nsIAtom* aListName,
nsIFrame* aOldFrame);
/**
* Both GetMinWidth and GetPrefWidth return whatever
* GetIntrinsicWidth returns.
*/
virtual nscoord GetMinWidth(nsIRenderingContext *aRenderingContext);
virtual nscoord GetPrefWidth(nsIRenderingContext *aRenderingContext);
/**
* Return the intrinsic width of the frame's content area.
*/
virtual nscoord GetIntrinsicWidth(nsIRenderingContext *aRenderingContext);
NS_IMETHOD
Reflow(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,

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

@ -147,14 +147,10 @@ nsMathMLTokenFrame::Reflow(nsPresContext* aPresContext,
SaveReflowAndBoundingMetricsFor(childFrame, childDesiredSize,
childDesiredSize.mBoundingMetrics);
// compute and cache the bounding metrics
aDesiredSize.mBoundingMetrics += childDesiredSize.mBoundingMetrics;
childFrame = childFrame->GetNextSibling();
}
// cache the frame's mBoundingMetrics
mBoundingMetrics = aDesiredSize.mBoundingMetrics;
// place and size children
FinalizeReflow(*aReflowState.rendContext, aDesiredSize);
@ -172,6 +168,18 @@ nsMathMLTokenFrame::Place(nsIRenderingContext& aRenderingContext,
PRBool aPlaceOrigin,
nsHTMLReflowMetrics& aDesiredSize)
{
mBoundingMetrics.Clear();
nsIFrame* childFrame = GetFirstChild(nsnull);
while (childFrame) {
nsHTMLReflowMetrics childSize;
GetReflowAndBoundingMetricsFor(childFrame, childSize,
childSize.mBoundingMetrics, nsnull);
// compute and cache the bounding metrics
mBoundingMetrics += childSize.mBoundingMetrics;
childFrame = childFrame->GetNextSibling();
}
nsCOMPtr<nsIFontMetrics> fm =
PresContext()->GetMetricsFor(GetStyleFont()->mFont);
nscoord ascent, descent;

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

@ -613,11 +613,11 @@ nsMathMLmoFrame::Stretch(nsIRenderingContext& aRenderingContext,
NS_MATHML_OPERATOR_IS_INVISIBLE(mFlags);
nsBoundingMetrics charSize;
nsBoundingMetrics container = aDesiredStretchSize.mBoundingMetrics;
PRBool isVertical = PR_FALSE;
if (useMathMLChar) {
nsBoundingMetrics initialSize = aDesiredStretchSize.mBoundingMetrics;
nsBoundingMetrics container = initialSize;
PRBool isVertical = PR_FALSE;
PRUint32 stretchHint = NS_STRETCH_NORMAL;
// see if it is okay to stretch, starting from what the Operator Dictionary said
@ -756,35 +756,6 @@ nsMathMLmoFrame::Stretch(nsIRenderingContext& aRenderingContext,
mFlags &= ~NS_MATHML_OPERATOR_FORM;
useMathMLChar = PR_FALSE;
}
else {
// update our bounding metrics... it becomes that of our MathML char
mBoundingMetrics = charSize;
// if the returned direction is 'unsupported', the char didn't actually change.
// So we do the centering only if necessary
if (mMathMLChar.GetStretchDirection() != NS_STRETCH_DIRECTION_UNSUPPORTED ||
NS_MATHML_OPERATOR_IS_CENTERED(mFlags)) {
if (isVertical || NS_MATHML_OPERATOR_IS_CENTERED(mFlags)) {
// 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) ||
NS_MATHML_OPERATOR_IS_CENTERED(mFlags)) {
// For symmetric and vertical operators, or for operators that are always
// centered ('+', '*', etc) 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;
}
}
}
}
// Place our children using the default method
@ -795,6 +766,36 @@ nsMathMLmoFrame::Stretch(nsIRenderingContext& aRenderingContext,
DidReflowChildren(mFrames.FirstChild());
}
if (useMathMLChar) {
// update our bounding metrics... it becomes that of our MathML char
mBoundingMetrics = charSize;
// if the returned direction is 'unsupported', the char didn't actually change.
// So we do the centering only if necessary
if (mMathMLChar.GetStretchDirection() != NS_STRETCH_DIRECTION_UNSUPPORTED ||
NS_MATHML_OPERATOR_IS_CENTERED(mFlags)) {
if (isVertical || NS_MATHML_OPERATOR_IS_CENTERED(mFlags)) {
// 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) ||
NS_MATHML_OPERATOR_IS_CENTERED(mFlags)) {
// For symmetric and vertical operators, or for operators that are always
// centered ('+', '*', etc) 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;
}
}
}
// Fixup for the final height.
// On one hand, our stretchy height can sometimes be shorter than surrounding
// ASCII chars, e.g., arrow symbols have |mBoundingMetrics.ascent + leading|
@ -874,7 +875,7 @@ nsMathMLmoFrame::Stretch(nsIRenderingContext& aRenderingContext,
aDesiredStretchSize.mBoundingMetrics.rightBearing += leftSpace;
if (useMathMLChar) {
nsRect rect;
nsRect rect;
mMathMLChar.GetRect(rect);
mMathMLChar.SetRect(nsRect(rect.x + leftSpace, rect.y, rect.width, rect.height));
}
@ -889,6 +890,8 @@ nsMathMLmoFrame::Stretch(nsIRenderingContext& aRenderingContext,
}
}
// Finished with these:
ClearSavedChildMetrics();
// Set our overflow area
GatherAndStoreOverflow(&aDesiredStretchSize);