зеркало из https://github.com/mozilla/pjs.git
don't use frame origin offsets to store ascents. b=363240, r+sr=roc
This commit is contained in:
Родитель
b5aa7e530c
Коммит
166233b82f
|
@ -1491,6 +1491,9 @@ GK_ATOM(changeListProperty, "ChangeListProperty") // void*
|
||||||
GK_ATOM(collapseOffsetProperty, "CollapseOffsetProperty") // nsPoint*
|
GK_ATOM(collapseOffsetProperty, "CollapseOffsetProperty") // nsPoint*
|
||||||
GK_ATOM(computedOffsetProperty, "ComputedOffsetProperty") // nsPoint*
|
GK_ATOM(computedOffsetProperty, "ComputedOffsetProperty") // nsPoint*
|
||||||
GK_ATOM(generatedContent, "GeneratedContentProperty") // nsCOMArray<nsIContent>*
|
GK_ATOM(generatedContent, "GeneratedContentProperty") // nsCOMArray<nsIContent>*
|
||||||
|
#ifdef MOZ_MATHML
|
||||||
|
GK_ATOM(HTMLReflowMetricsProperty, "HTMLReflowMetricsProperty") // nsHTMLReflowMetrics*
|
||||||
|
#endif
|
||||||
GK_ATOM(IBSplitSpecialPrevSibling, "IBSplitSpecialPrevSibling")// nsIFrame*
|
GK_ATOM(IBSplitSpecialPrevSibling, "IBSplitSpecialPrevSibling")// nsIFrame*
|
||||||
GK_ATOM(IBSplitSpecialSibling, "IBSplitSpecialSibling") // nsIFrame*
|
GK_ATOM(IBSplitSpecialSibling, "IBSplitSpecialSibling") // nsIFrame*
|
||||||
GK_ATOM(lineCursorProperty, "LineCursorProperty") // nsLineBox*
|
GK_ATOM(lineCursorProperty, "LineCursorProperty") // nsLineBox*
|
||||||
|
|
|
@ -125,12 +125,13 @@ public:
|
||||||
|
|
||||||
/* Place :
|
/* Place :
|
||||||
* This method is used before returning from Reflow(), or when a MathML frame
|
* This method is used before returning from Reflow(), or when a MathML frame
|
||||||
* has just been stretched. It is called to fine-tune the positions of the elements.
|
* has just been stretched. It is called to fine-tune the positions of the
|
||||||
|
* child frames, and other elements.
|
||||||
|
*
|
||||||
|
* IMPORTANT: For nsMathMLContainerFrames this method uses
|
||||||
|
* GetReflowAndBoundingMetricsFor() which must have been set up with
|
||||||
|
* SaveReflowAndBoundingMetricsFor().
|
||||||
*
|
*
|
||||||
* IMPORTANT: This method uses the origin of child frames (rect.x and rect.y) as
|
|
||||||
* placeholders between calls: On invocation, child->GetRect(rect) should give a
|
|
||||||
* rect such that rect.x holds the child's descent, rect.y holds the child's ascent,
|
|
||||||
* (rect.width should give the width, and rect.height should give the height).
|
|
||||||
* The Place() method will use this information to compute the desired size
|
* The Place() method will use this information to compute the desired size
|
||||||
* of the frame.
|
* of the frame.
|
||||||
*
|
*
|
||||||
|
@ -357,42 +358,42 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIMathMLFrame, NS_IMATHMLFRAME_IID)
|
||||||
// The bit merely tells the context of the frame. In the context of
|
// The bit merely tells the context of the frame. In the context of
|
||||||
// displaystyle="false", it is intended to slightly alter how the
|
// displaystyle="false", it is intended to slightly alter how the
|
||||||
// rendering is done in inline mode.
|
// rendering is done in inline mode.
|
||||||
#define NS_MATHML_DISPLAYSTYLE 0x00000001
|
#define NS_MATHML_DISPLAYSTYLE 0x00000001U
|
||||||
|
|
||||||
// This bit is used to emulate TeX rendering.
|
// This bit is used to emulate TeX rendering.
|
||||||
// Internal use only, cannot be set by the user with an attribute.
|
// Internal use only, cannot be set by the user with an attribute.
|
||||||
#define NS_MATHML_COMPRESSED 0x00000002
|
#define NS_MATHML_COMPRESSED 0x00000002U
|
||||||
|
|
||||||
// This bit is set if the frame will fire a vertical stretch
|
// This bit is set if the frame will fire a vertical stretch
|
||||||
// command on all its (non-empty) children.
|
// command on all its (non-empty) children.
|
||||||
// Tags like <mrow> (or an inferred mrow), mpadded, etc, will fire a
|
// Tags like <mrow> (or an inferred mrow), mpadded, etc, will fire a
|
||||||
// vertical stretch command on all their non-empty children
|
// vertical stretch command on all their non-empty children
|
||||||
#define NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY 0x00000004
|
#define NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY 0x00000004U
|
||||||
|
|
||||||
// This bit is set if the frame will fire a horizontal stretch
|
// This bit is set if the frame will fire a horizontal stretch
|
||||||
// command on all its (non-empty) children.
|
// command on all its (non-empty) children.
|
||||||
// Tags like munder, mover, munderover, will fire a
|
// Tags like munder, mover, munderover, will fire a
|
||||||
// horizontal stretch command on all their non-empty children
|
// horizontal stretch command on all their non-empty children
|
||||||
#define NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY 0x00000008
|
#define NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY 0x00000008U
|
||||||
|
|
||||||
// This bit is set if the frame has the explicit attribute
|
// This bit is set if the frame has the explicit attribute
|
||||||
// displaystyle="true" or "false". It is only relevant to <mstyle> and <mtable>
|
// displaystyle="true" or "false". It is only relevant to <mstyle> and <mtable>
|
||||||
// because they are the only tags where the attribute is allowed by the spec.
|
// because they are the only tags where the attribute is allowed by the spec.
|
||||||
#define NS_MATHML_EXPLICIT_DISPLAYSTYLE 0x00000020
|
#define NS_MATHML_EXPLICIT_DISPLAYSTYLE 0x00000020U
|
||||||
|
|
||||||
// This bit is set when the frame cannot be formatted due to an
|
// This bit is set when the frame cannot be formatted due to an
|
||||||
// error (e.g., invalid markup such as a <msup> without an overscript).
|
// error (e.g., invalid markup such as a <msup> without an overscript).
|
||||||
// When set, a visual feedback will be provided to the user.
|
// When set, a visual feedback will be provided to the user.
|
||||||
#define NS_MATHML_ERROR 0x80000000
|
#define NS_MATHML_ERROR 0x80000000U
|
||||||
|
|
||||||
// a bit used for debug
|
// a bit used for debug
|
||||||
#define NS_MATHML_STRETCH_DONE 0x20000000
|
#define NS_MATHML_STRETCH_DONE 0x20000000U
|
||||||
|
|
||||||
// This bit is used for visual debug. When set, the bounding box
|
// This bit is used for visual debug. When set, the bounding box
|
||||||
// of your frame is painted. This visual debug enable to ensure that
|
// of your frame is painted. This visual debug enable to ensure that
|
||||||
// you have properly filled your mReference and mBoundingMetrics in
|
// you have properly filled your mReference and mBoundingMetrics in
|
||||||
// Place().
|
// Place().
|
||||||
#define NS_MATHML_SHOW_BOUNDING_METRICS 0x10000000
|
#define NS_MATHML_SHOW_BOUNDING_METRICS 0x10000000U
|
||||||
|
|
||||||
// Macros that retrieve those bits
|
// Macros that retrieve those bits
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,6 @@
|
||||||
|
|
||||||
#include "nsGkAtoms.h"
|
#include "nsGkAtoms.h"
|
||||||
#include "nsMathMLParts.h"
|
#include "nsMathMLParts.h"
|
||||||
#include "nsMathMLChar.h"
|
|
||||||
#include "nsMathMLContainerFrame.h"
|
#include "nsMathMLContainerFrame.h"
|
||||||
#include "nsAutoPtr.h"
|
#include "nsAutoPtr.h"
|
||||||
#include "nsStyleSet.h"
|
#include "nsStyleSet.h"
|
||||||
|
@ -166,8 +165,35 @@ void nsDisplayMathMLError::Paint(nsDisplayListBuilder* aBuilder,
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static PRBool
|
||||||
|
IsForeignChild(const nsIFrame* aFrame)
|
||||||
|
{
|
||||||
|
// This counts nsMathMLmathBlockFrame as a foreign child, because it
|
||||||
|
// uses block reflow
|
||||||
|
return !(aFrame->IsFrameOfType(nsIFrame::eMathML)) ||
|
||||||
|
aFrame->GetType() == nsGkAtoms::blockFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
DeleteHTMLReflowMetrics(void *aObject, nsIAtom *aPropertyName,
|
||||||
|
void *aPropertyValue, void *aData)
|
||||||
|
{
|
||||||
|
delete static_cast<nsHTMLReflowMetrics*>(aPropertyValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */ void
|
||||||
|
nsMathMLContainerFrame::SaveReflowAndBoundingMetricsFor(nsIFrame* aFrame,
|
||||||
|
const nsHTMLReflowMetrics& aReflowMetrics,
|
||||||
|
const nsBoundingMetrics& aBoundingMetrics)
|
||||||
|
{
|
||||||
|
nsHTMLReflowMetrics *metrics = new nsHTMLReflowMetrics(aReflowMetrics);
|
||||||
|
metrics->mBoundingMetrics = aBoundingMetrics;
|
||||||
|
aFrame->SetProperty(nsGkAtoms::HTMLReflowMetricsProperty, metrics,
|
||||||
|
DeleteHTMLReflowMetrics);
|
||||||
|
}
|
||||||
|
|
||||||
// helper method to facilitate getting the reflow and bounding metrics
|
// helper method to facilitate getting the reflow and bounding metrics
|
||||||
void
|
/* static */ void
|
||||||
nsMathMLContainerFrame::GetReflowAndBoundingMetricsFor(nsIFrame* aFrame,
|
nsMathMLContainerFrame::GetReflowAndBoundingMetricsFor(nsIFrame* aFrame,
|
||||||
nsHTMLReflowMetrics& aReflowMetrics,
|
nsHTMLReflowMetrics& aReflowMetrics,
|
||||||
nsBoundingMetrics& aBoundingMetrics,
|
nsBoundingMetrics& aBoundingMetrics,
|
||||||
|
@ -175,37 +201,42 @@ nsMathMLContainerFrame::GetReflowAndBoundingMetricsFor(nsIFrame* aFra
|
||||||
{
|
{
|
||||||
NS_PRECONDITION(aFrame, "null arg");
|
NS_PRECONDITION(aFrame, "null arg");
|
||||||
|
|
||||||
|
nsHTMLReflowMetrics *metrics = static_cast<nsHTMLReflowMetrics*>
|
||||||
|
(aFrame->GetProperty(nsGkAtoms::HTMLReflowMetricsProperty));
|
||||||
|
|
||||||
// IMPORTANT: This function is only meant to be called in Place() methods
|
// IMPORTANT: This function is only meant to be called in Place() methods
|
||||||
// where it is assumed that the frame's rect is still acting as place holder
|
// where it is assumed that SaveReflowAndBoundingMetricsFor has recorded the
|
||||||
// for the frame's ascent and descent information
|
// information.
|
||||||
|
NS_ASSERTION(metrics, "Didn't SaveReflowAndBoundingMetricsFor frame!");
|
||||||
|
if (metrics) {
|
||||||
|
aReflowMetrics = *metrics;
|
||||||
|
aBoundingMetrics = metrics->mBoundingMetrics;
|
||||||
|
}
|
||||||
|
|
||||||
nsRect rect = aFrame->GetRect();
|
if (aMathMLFrameType) {
|
||||||
aReflowMetrics.ascent = rect.y;
|
if (!IsForeignChild(aFrame)) {
|
||||||
aReflowMetrics.width = rect.width;
|
|
||||||
aReflowMetrics.height = rect.height;
|
|
||||||
nscoord descent = aReflowMetrics.height - aReflowMetrics.ascent;
|
|
||||||
|
|
||||||
if (aFrame->IsFrameOfType(nsIFrame::eMathML)) {
|
|
||||||
nsIMathMLFrame* mathMLFrame;
|
nsIMathMLFrame* mathMLFrame;
|
||||||
CallQueryInterface(aFrame, &mathMLFrame);
|
CallQueryInterface(aFrame, &mathMLFrame);
|
||||||
if (mathMLFrame) {
|
if (mathMLFrame) {
|
||||||
mathMLFrame->GetBoundingMetrics(aBoundingMetrics);
|
|
||||||
if (aMathMLFrameType)
|
|
||||||
*aMathMLFrameType = mathMLFrame->GetMathMLFrameType();
|
*aMathMLFrameType = mathMLFrame->GetMathMLFrameType();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// aFrame is not a MathML frame, just return the reflow metrics
|
|
||||||
aBoundingMetrics.descent = descent;
|
|
||||||
aBoundingMetrics.ascent = aReflowMetrics.ascent;
|
|
||||||
aBoundingMetrics.width = aReflowMetrics.width;
|
|
||||||
aBoundingMetrics.rightBearing = aReflowMetrics.width;
|
|
||||||
if (aMathMLFrameType)
|
|
||||||
*aMathMLFrameType = eMathMLFrameType_UNKNOWN;
|
*aMathMLFrameType = eMathMLFrameType_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsMathMLContainerFrame::ClearSavedChildMetrics()
|
||||||
|
{
|
||||||
|
nsIFrame* childFrame = mFrames.FirstChild();
|
||||||
|
while (childFrame) {
|
||||||
|
childFrame->DeleteProperty(nsGkAtoms::HTMLReflowMetricsProperty);
|
||||||
|
childFrame = childFrame->GetNextSibling();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// helper to get the preferred size that a container frame should use to fire
|
// helper to get the preferred size that a container frame should use to fire
|
||||||
// the stretch on its stretchy child frames.
|
// the stretch on its stretchy child frames.
|
||||||
void
|
void
|
||||||
|
@ -236,13 +267,6 @@ nsMathMLContainerFrame::GetPreferredStretchSize(nsIRenderingContext& aRenderingC
|
||||||
nsIFrame* childFrame = GetFirstChild(nsnull);
|
nsIFrame* childFrame = GetFirstChild(nsnull);
|
||||||
while (childFrame) {
|
while (childFrame) {
|
||||||
// initializations in case this child happens not to be a MathML frame
|
// initializations in case this child happens not to be a MathML frame
|
||||||
nsRect rect = childFrame->GetRect();
|
|
||||||
bmChild.ascent = rect.y;
|
|
||||||
bmChild.descent = rect.x;
|
|
||||||
bmChild.width = rect.width;
|
|
||||||
bmChild.rightBearing = rect.width;
|
|
||||||
bmChild.leftBearing = 0;
|
|
||||||
|
|
||||||
nsIMathMLFrame* mathMLFrame;
|
nsIMathMLFrame* mathMLFrame;
|
||||||
childFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame);
|
childFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame);
|
||||||
if (mathMLFrame) {
|
if (mathMLFrame) {
|
||||||
|
@ -254,6 +278,8 @@ nsMathMLContainerFrame::GetPreferredStretchSize(nsIRenderingContext& aRenderingC
|
||||||
embellishData.direction == aStretchDirection &&
|
embellishData.direction == aStretchDirection &&
|
||||||
presentationData.baseFrame) {
|
presentationData.baseFrame) {
|
||||||
// embellishements are not included, only consider the inner first child itself
|
// embellishements are not included, only consider the inner first child itself
|
||||||
|
// XXXkt Does that mean the core descendent frame should be used
|
||||||
|
// instead of the base child?
|
||||||
nsIMathMLFrame* mathMLchildFrame;
|
nsIMathMLFrame* mathMLchildFrame;
|
||||||
presentationData.baseFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLchildFrame);
|
presentationData.baseFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLchildFrame);
|
||||||
if (mathMLchildFrame) {
|
if (mathMLchildFrame) {
|
||||||
|
@ -262,6 +288,10 @@ nsMathMLContainerFrame::GetPreferredStretchSize(nsIRenderingContext& aRenderingC
|
||||||
}
|
}
|
||||||
mathMLFrame->GetBoundingMetrics(bmChild);
|
mathMLFrame->GetBoundingMetrics(bmChild);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
nsHTMLReflowMetrics unused;
|
||||||
|
GetReflowAndBoundingMetricsFor(childFrame, unused, bmChild);
|
||||||
|
}
|
||||||
|
|
||||||
if (firstTime) {
|
if (firstTime) {
|
||||||
firstTime = PR_FALSE;
|
firstTime = PR_FALSE;
|
||||||
|
@ -361,10 +391,9 @@ nsMathMLContainerFrame::Stretch(nsIRenderingContext& aRenderingContext,
|
||||||
// do the stretching...
|
// do the stretching...
|
||||||
mathMLFrame->Stretch(aRenderingContext,
|
mathMLFrame->Stretch(aRenderingContext,
|
||||||
mEmbellishData.direction, containerSize, childSize);
|
mEmbellishData.direction, containerSize, childSize);
|
||||||
|
|
||||||
// store the updated metrics
|
// store the updated metrics
|
||||||
baseFrame->SetRect(nsRect(0, childSize.ascent,
|
SaveReflowAndBoundingMetricsFor(baseFrame, childSize,
|
||||||
childSize.width, childSize.height));
|
childSize.mBoundingMetrics);
|
||||||
|
|
||||||
// Remember the siblings which were _deferred_.
|
// Remember the siblings which were _deferred_.
|
||||||
// Now that this embellished child may have changed, we need to
|
// Now that this embellished child may have changed, we need to
|
||||||
|
@ -391,8 +420,8 @@ nsMathMLContainerFrame::Stretch(nsIRenderingContext& aRenderingContext,
|
||||||
mathMLFrame->Stretch(aRenderingContext, stretchDir,
|
mathMLFrame->Stretch(aRenderingContext, stretchDir,
|
||||||
containerSize, childSize);
|
containerSize, childSize);
|
||||||
// store the updated metrics
|
// store the updated metrics
|
||||||
childFrame->SetRect(nsRect(0, childSize.ascent,
|
SaveReflowAndBoundingMetricsFor(childFrame, childSize,
|
||||||
childSize.width, childSize.height));
|
childSize.mBoundingMetrics);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
childFrame = childFrame->GetNextSibling();
|
childFrame = childFrame->GetNextSibling();
|
||||||
|
@ -441,6 +470,8 @@ nsMathMLContainerFrame::Stretch(nsIRenderingContext& aRenderingContext,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Finished with these:
|
||||||
|
ClearSavedChildMetrics();
|
||||||
// Set our overflow area
|
// Set our overflow area
|
||||||
GatherAndStoreOverflow(&aDesiredStretchSize);
|
GatherAndStoreOverflow(&aDesiredStretchSize);
|
||||||
}
|
}
|
||||||
|
@ -490,11 +521,11 @@ nsMathMLContainerFrame::FinalizeReflow(nsIRenderingContext& aRenderingContext,
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PRBool parentWillFireStretch = PR_FALSE;
|
||||||
if (!placeOrigin) {
|
if (!placeOrigin) {
|
||||||
// This means the rect.x and rect.y of our children were not set!!
|
// This means the rect.x and rect.y of our children were not set!!
|
||||||
// Don't go without checking to see if our parent will later fire a Stretch() command
|
// Don't go without checking to see if our parent will later fire a Stretch() command
|
||||||
// targeted at us. The Stretch() will cause the rect.x and rect.y to clear...
|
// targeted at us. The Stretch() will cause the rect.x and rect.y to clear...
|
||||||
PRBool parentWillFireStretch = PR_FALSE;
|
|
||||||
nsIMathMLFrame* mathMLFrame;
|
nsIMathMLFrame* mathMLFrame;
|
||||||
mParent->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame);
|
mParent->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame);
|
||||||
if (mathMLFrame) {
|
if (mathMLFrame) {
|
||||||
|
@ -550,8 +581,11 @@ nsMathMLContainerFrame::FinalizeReflow(nsIRenderingContext& aRenderingContext,
|
||||||
// Also return our bounding metrics
|
// Also return our bounding metrics
|
||||||
aDesiredSize.mBoundingMetrics = mBoundingMetrics;
|
aDesiredSize.mBoundingMetrics = mBoundingMetrics;
|
||||||
|
|
||||||
if (placeOrigin) {
|
if (!parentWillFireStretch) {
|
||||||
// Not expecting a stretch. Set our overflow area.
|
// Not expecting a stretch.
|
||||||
|
// Finished with these:
|
||||||
|
ClearSavedChildMetrics();
|
||||||
|
// Set our overflow area.
|
||||||
GatherAndStoreOverflow(&aDesiredSize);
|
GatherAndStoreOverflow(&aDesiredSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -844,15 +878,6 @@ nsMathMLContainerFrame::GatherAndStoreOverflow(nsHTMLReflowMetrics* aMetrics)
|
||||||
FinishAndStoreOverflow(aMetrics);
|
FinishAndStoreOverflow(aMetrics);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PRBool
|
|
||||||
IsForeignChild(nsIFrame* aFrame)
|
|
||||||
{
|
|
||||||
// This counts nsMathMLmathBlockFrame as a foreign child, because it
|
|
||||||
// uses block reflow
|
|
||||||
return !(aFrame->IsFrameOfType(nsIFrame::eMathML)) ||
|
|
||||||
aFrame->GetType() == nsGkAtoms::blockFrame;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsMathMLContainerFrame::ReflowChild(nsIFrame* aChildFrame,
|
nsMathMLContainerFrame::ReflowChild(nsIFrame* aChildFrame,
|
||||||
nsPresContext* aPresContext,
|
nsPresContext* aPresContext,
|
||||||
|
@ -876,13 +901,13 @@ nsMathMLContainerFrame::ReflowChild(nsIFrame* aChildFrame,
|
||||||
NS_ASSERTION(!inlineFrame, "Inline frames should be wrapped in blocks");
|
NS_ASSERTION(!inlineFrame, "Inline frames should be wrapped in blocks");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// XXX should we do something here to compute good bounding metrics for
|
|
||||||
// the child?
|
|
||||||
|
|
||||||
nsresult rv = nsHTMLContainerFrame::
|
nsresult rv = nsHTMLContainerFrame::
|
||||||
ReflowChild(aChildFrame, aPresContext, aDesiredSize, aReflowState,
|
ReflowChild(aChildFrame, aPresContext, aDesiredSize, aReflowState,
|
||||||
0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
|
0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
|
||||||
|
|
||||||
|
if (NS_FAILED(rv))
|
||||||
|
return rv;
|
||||||
|
|
||||||
if (aDesiredSize.ascent == nsHTMLReflowMetrics::ASK_FOR_BASELINE) {
|
if (aDesiredSize.ascent == nsHTMLReflowMetrics::ASK_FOR_BASELINE) {
|
||||||
// This will be suitable for inline frames, which are wrapped in a block.
|
// This will be suitable for inline frames, which are wrapped in a block.
|
||||||
if(!nsLayoutUtils::GetLastLineBaseline(aChildFrame,
|
if(!nsLayoutUtils::GetLastLineBaseline(aChildFrame,
|
||||||
|
@ -893,8 +918,7 @@ nsMathMLContainerFrame::ReflowChild(nsIFrame* aChildFrame,
|
||||||
aDesiredSize.ascent = aDesiredSize.height;
|
aDesiredSize.ascent = aDesiredSize.height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (IsForeignChild(aChildFrame) &&
|
if (IsForeignChild(aChildFrame)) {
|
||||||
(aDesiredSize.mFlags | NS_REFLOW_CALC_BOUNDING_METRICS)) {
|
|
||||||
// use ComputeTightBounds API as aDesiredSize.mBoundingMetrics is not set.
|
// use ComputeTightBounds API as aDesiredSize.mBoundingMetrics is not set.
|
||||||
nsRect r = aChildFrame->ComputeTightBounds(aReflowState.rendContext->ThebesContext());
|
nsRect r = aChildFrame->ComputeTightBounds(aReflowState.rendContext->ThebesContext());
|
||||||
aDesiredSize.mBoundingMetrics.leftBearing = r.x;
|
aDesiredSize.mBoundingMetrics.leftBearing = r.x;
|
||||||
|
@ -936,11 +960,8 @@ nsMathMLContainerFrame::Reflow(nsPresContext* aPresContext,
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
// At this stage, the origin points of the children have no use, so we will use the
|
SaveReflowAndBoundingMetricsFor(childFrame, childDesiredSize,
|
||||||
// origins as placeholders to store the child's ascent and descent. Later on,
|
childDesiredSize.mBoundingMetrics);
|
||||||
// we should set the origins so as to overwrite what we are storing there now.
|
|
||||||
childFrame->SetRect(nsRect(0, childDesiredSize.ascent,
|
|
||||||
childDesiredSize.width, childDesiredSize.height));
|
|
||||||
childFrame = childFrame->GetNextSibling();
|
childFrame = childFrame->GetNextSibling();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -983,8 +1004,8 @@ nsMathMLContainerFrame::Reflow(nsPresContext* aPresContext,
|
||||||
mathMLFrame->Stretch(*aReflowState.rendContext, stretchDir,
|
mathMLFrame->Stretch(*aReflowState.rendContext, stretchDir,
|
||||||
containerSize, childDesiredSize);
|
containerSize, childDesiredSize);
|
||||||
// store the updated metrics
|
// store the updated metrics
|
||||||
childFrame->SetRect(nsRect(0, childDesiredSize.ascent,
|
SaveReflowAndBoundingMetricsFor(childFrame, childDesiredSize,
|
||||||
childDesiredSize.width, childDesiredSize.height));
|
childDesiredSize.mBoundingMetrics);
|
||||||
}
|
}
|
||||||
childFrame = childFrame->GetNextSibling();
|
childFrame = childFrame->GetNextSibling();
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,6 +119,8 @@ public:
|
||||||
nsHTMLContainerFrame::IsFrameOfType(aFlags & ~(nsIFrame::eMathML));
|
nsHTMLContainerFrame::IsFrameOfType(aFlags & ~(nsIFrame::eMathML));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual PRIntn GetSkipSides() const { return 0; }
|
||||||
|
|
||||||
NS_IMETHOD
|
NS_IMETHOD
|
||||||
AppendFrames(nsIAtom* aListName,
|
AppendFrames(nsIAtom* aListName,
|
||||||
nsIFrame* aFrameList);
|
nsIFrame* aFrameList);
|
||||||
|
@ -229,18 +231,29 @@ public:
|
||||||
FinalizeReflow(nsIRenderingContext& aRenderingContext,
|
FinalizeReflow(nsIRenderingContext& aRenderingContext,
|
||||||
nsHTMLReflowMetrics& aDesiredSize);
|
nsHTMLReflowMetrics& aDesiredSize);
|
||||||
|
|
||||||
// helper method to facilitate getting the reflow and bounding metrics.
|
// Record metrics of a child frame for recovery through the following method
|
||||||
// The argument aMathMLFrameType, when non null, will return the 'type' of
|
static void
|
||||||
// the frame, which is used to determine the inter-frame spacing.
|
SaveReflowAndBoundingMetricsFor(nsIFrame* aFrame,
|
||||||
// IMPORTANT: This function is only meant to be called in Place() methods
|
const nsHTMLReflowMetrics& aReflowMetrics,
|
||||||
// where it is assumed that the frame's rect is still acting as place holder
|
const nsBoundingMetrics& aBoundingMetrics);
|
||||||
// for the frame's ascent and descent information
|
|
||||||
|
// helper method to facilitate getting the reflow and bounding metrics of a
|
||||||
|
// child frame. The argument aMathMLFrameType, when non null, will return
|
||||||
|
// the 'type' of the frame, which is used to determine the inter-frame
|
||||||
|
// spacing.
|
||||||
|
// IMPORTANT: This function is only meant to be called in Place() methods as
|
||||||
|
// the information is available only when set up with the above method
|
||||||
|
// during Reflow/Stretch() and GetPrefWidth().
|
||||||
static void
|
static void
|
||||||
GetReflowAndBoundingMetricsFor(nsIFrame* aFrame,
|
GetReflowAndBoundingMetricsFor(nsIFrame* aFrame,
|
||||||
nsHTMLReflowMetrics& aReflowMetrics,
|
nsHTMLReflowMetrics& aReflowMetrics,
|
||||||
nsBoundingMetrics& aBoundingMetrics,
|
nsBoundingMetrics& aBoundingMetrics,
|
||||||
eMathMLFrameType* aMathMLFrameType = nsnull);
|
eMathMLFrameType* aMathMLFrameType = nsnull);
|
||||||
|
|
||||||
|
// helper method to clear metrics saved with
|
||||||
|
// SaveReflowAndBoundingMetricsFor() from all child frames.
|
||||||
|
void ClearSavedChildMetrics();
|
||||||
|
|
||||||
// helper to let the update of presentation data pass through
|
// helper to let the update of presentation data pass through
|
||||||
// a subtree that may contain non-MathML container frames
|
// a subtree that may contain non-MathML container frames
|
||||||
static void
|
static void
|
||||||
|
@ -284,8 +297,6 @@ public:
|
||||||
ReLayoutChildren(nsIFrame* aParentFrame, nsFrameState aBits);
|
ReLayoutChildren(nsIFrame* aParentFrame, nsFrameState aBits);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual PRIntn GetSkipSides() const { return 0; }
|
|
||||||
|
|
||||||
// Helper method which positions child frames as an <mrow> on given baseline
|
// Helper method which positions child frames as an <mrow> on given baseline
|
||||||
// y = aBaseline starting from x = aOffsetX, calling FinishReflowChild()
|
// y = aBaseline starting from x = aOffsetX, calling FinishReflowChild()
|
||||||
// on the frames.
|
// on the frames.
|
||||||
|
|
|
@ -145,9 +145,8 @@ nsMathMLTokenFrame::Reflow(nsPresContext* aPresContext,
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
// origins are used as placeholders to store the child's ascent.
|
SaveReflowAndBoundingMetricsFor(childFrame, childDesiredSize,
|
||||||
childFrame->SetRect(nsRect(0, childDesiredSize.ascent,
|
childDesiredSize.mBoundingMetrics);
|
||||||
childDesiredSize.width, childDesiredSize.height));
|
|
||||||
// compute and cache the bounding metrics
|
// compute and cache the bounding metrics
|
||||||
aDesiredSize.mBoundingMetrics += childDesiredSize.mBoundingMetrics;
|
aDesiredSize.mBoundingMetrics += childDesiredSize.mBoundingMetrics;
|
||||||
|
|
||||||
|
@ -189,15 +188,14 @@ nsMathMLTokenFrame::Place(nsIRenderingContext& aRenderingContext,
|
||||||
nscoord dy, dx = 0;
|
nscoord dy, dx = 0;
|
||||||
nsIFrame* childFrame = GetFirstChild(nsnull);
|
nsIFrame* childFrame = GetFirstChild(nsnull);
|
||||||
while (childFrame) {
|
while (childFrame) {
|
||||||
nsRect rect = childFrame->GetRect();
|
|
||||||
nsHTMLReflowMetrics childSize;
|
nsHTMLReflowMetrics childSize;
|
||||||
childSize.width = rect.width;
|
GetReflowAndBoundingMetricsFor(childFrame, childSize,
|
||||||
childSize.height = rect.height;
|
childSize.mBoundingMetrics);
|
||||||
|
|
||||||
// place and size the child; (dx,0) makes the caret happy - bug 188146
|
// place and size the child; (dx,0) makes the caret happy - bug 188146
|
||||||
dy = rect.IsEmpty() ? 0 : aDesiredSize.ascent - rect.y;
|
dy = childSize.height == 0 ? 0 : aDesiredSize.ascent - childSize.ascent;
|
||||||
FinishReflowChild(childFrame, PresContext(), nsnull, childSize, dx, dy, 0);
|
FinishReflowChild(childFrame, PresContext(), nsnull, childSize, dx, dy, 0);
|
||||||
dx += rect.width;
|
dx += childSize.width;
|
||||||
childFrame = childFrame->GetNextSibling();
|
childFrame = childFrame->GetNextSibling();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -288,8 +288,8 @@ nsMathMLmactionFrame::Reflow(nsPresContext* aPresContext,
|
||||||
childFrame, availSize);
|
childFrame, availSize);
|
||||||
rv = ReflowChild(childFrame, aPresContext, aDesiredSize,
|
rv = ReflowChild(childFrame, aPresContext, aDesiredSize,
|
||||||
childReflowState, aStatus);
|
childReflowState, aStatus);
|
||||||
childFrame->SetRect(nsRect(0,aDesiredSize.ascent,
|
SaveReflowAndBoundingMetricsFor(childFrame, aDesiredSize,
|
||||||
aDesiredSize.width,aDesiredSize.height));
|
aDesiredSize.mBoundingMetrics);
|
||||||
mBoundingMetrics = aDesiredSize.mBoundingMetrics;
|
mBoundingMetrics = aDesiredSize.mBoundingMetrics;
|
||||||
}
|
}
|
||||||
FinalizeReflow(*aReflowState.rendContext, aDesiredSize);
|
FinalizeReflow(*aReflowState.rendContext, aDesiredSize);
|
||||||
|
|
|
@ -250,7 +250,7 @@ nsMathMLmfencedFrame::doReflow(nsPresContext* aPresContext,
|
||||||
const nsHTMLReflowState& aReflowState,
|
const nsHTMLReflowState& aReflowState,
|
||||||
nsHTMLReflowMetrics& aDesiredSize,
|
nsHTMLReflowMetrics& aDesiredSize,
|
||||||
nsReflowStatus& aStatus,
|
nsReflowStatus& aStatus,
|
||||||
nsIFrame* aForFrame,
|
nsMathMLContainerFrame* aForFrame,
|
||||||
nsMathMLChar* aOpenChar,
|
nsMathMLChar* aOpenChar,
|
||||||
nsMathMLChar* aCloseChar,
|
nsMathMLChar* aCloseChar,
|
||||||
nsMathMLChar* aSeparatorsChar,
|
nsMathMLChar* aSeparatorsChar,
|
||||||
|
@ -262,9 +262,6 @@ nsMathMLmfencedFrame::doReflow(nsPresContext* aPresContext,
|
||||||
aDesiredSize.ascent = 0;
|
aDesiredSize.ascent = 0;
|
||||||
aDesiredSize.mBoundingMetrics.Clear();
|
aDesiredSize.mBoundingMetrics.Clear();
|
||||||
|
|
||||||
nsMathMLContainerFrame* mathMLFrame =
|
|
||||||
static_cast<nsMathMLContainerFrame*>(aForFrame);
|
|
||||||
|
|
||||||
PRInt32 i;
|
PRInt32 i;
|
||||||
nsCOMPtr<nsIFontMetrics> fm;
|
nsCOMPtr<nsIFontMetrics> fm;
|
||||||
const nsStyleFont* font = aForFrame->GetStyleFont();
|
const nsStyleFont* font = aForFrame->GetStyleFont();
|
||||||
|
@ -304,20 +301,17 @@ nsMathMLmfencedFrame::doReflow(nsPresContext* aPresContext,
|
||||||
| NS_REFLOW_CALC_BOUNDING_METRICS);
|
| NS_REFLOW_CALC_BOUNDING_METRICS);
|
||||||
nsHTMLReflowState childReflowState(aPresContext, aReflowState,
|
nsHTMLReflowState childReflowState(aPresContext, aReflowState,
|
||||||
childFrame, availSize);
|
childFrame, availSize);
|
||||||
rv = mathMLFrame->ReflowChild(childFrame, aPresContext, childDesiredSize,
|
rv = aForFrame->ReflowChild(childFrame, aPresContext, childDesiredSize,
|
||||||
childReflowState, childStatus);
|
childReflowState, childStatus);
|
||||||
//NS_ASSERTION(NS_FRAME_IS_COMPLETE(childStatus), "bad status");
|
//NS_ASSERTION(NS_FRAME_IS_COMPLETE(childStatus), "bad status");
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
// Call DidReflow() for the child frames we successfully did reflow.
|
// Call DidReflow() for the child frames we successfully did reflow.
|
||||||
mathMLFrame->DidReflowChildren(firstChild, childFrame);
|
aForFrame->DidReflowChildren(firstChild, childFrame);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
// At this stage, the origin points of the children have no use, so we will use the
|
SaveReflowAndBoundingMetricsFor(childFrame, childDesiredSize,
|
||||||
// origins as placeholders to store the child's ascent and descent. Later on,
|
childDesiredSize.mBoundingMetrics);
|
||||||
// we should set the origins so as to overwrite what we are storing there now.
|
|
||||||
childFrame->SetRect(nsRect(0, childDesiredSize.ascent,
|
|
||||||
childDesiredSize.width, childDesiredSize.height));
|
|
||||||
|
|
||||||
// compute the bounding metrics right now for mfrac
|
// compute the bounding metrics right now for mfrac
|
||||||
nscoord childDescent = childDesiredSize.height - childDesiredSize.ascent;
|
nscoord childDescent = childDesiredSize.height - childDesiredSize.ascent;
|
||||||
|
@ -337,14 +331,14 @@ nsMathMLmfencedFrame::doReflow(nsPresContext* aPresContext,
|
||||||
nsStretchDirection stretchDir = NS_STRETCH_DIRECTION_VERTICAL;
|
nsStretchDirection stretchDir = NS_STRETCH_DIRECTION_VERTICAL;
|
||||||
|
|
||||||
nsPresentationData presentationData;
|
nsPresentationData presentationData;
|
||||||
mathMLFrame->GetPresentationData(presentationData);
|
aForFrame->GetPresentationData(presentationData);
|
||||||
if (!NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(presentationData.flags)) {
|
if (!NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(presentationData.flags)) {
|
||||||
// case when the call is made for mfrac, we only need to stretch the '/' separator
|
// case when the call is made for mfrac, we only need to stretch the '/' separator
|
||||||
containerSize = aDesiredSize.mBoundingMetrics; // computed earlier
|
containerSize = aDesiredSize.mBoundingMetrics; // computed earlier
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// case when the call is made for mfenced
|
// case when the call is made for mfenced
|
||||||
mathMLFrame->GetPreferredStretchSize(*aReflowState.rendContext,
|
aForFrame->GetPreferredStretchSize(*aReflowState.rendContext,
|
||||||
0, /* i.e., without embellishments */
|
0, /* i.e., without embellishments */
|
||||||
stretchDir, containerSize);
|
stretchDir, containerSize);
|
||||||
childFrame = firstChild;
|
childFrame = firstChild;
|
||||||
|
@ -354,13 +348,14 @@ nsMathMLmfencedFrame::doReflow(nsPresContext* aPresContext,
|
||||||
if (mathmlChild) {
|
if (mathmlChild) {
|
||||||
nsHTMLReflowMetrics childDesiredSize;
|
nsHTMLReflowMetrics childDesiredSize;
|
||||||
// retrieve the metrics that was stored at the previous pass
|
// retrieve the metrics that was stored at the previous pass
|
||||||
GetReflowAndBoundingMetricsFor(childFrame, childDesiredSize, childDesiredSize.mBoundingMetrics);
|
GetReflowAndBoundingMetricsFor(childFrame, childDesiredSize,
|
||||||
|
childDesiredSize.mBoundingMetrics);
|
||||||
|
|
||||||
mathmlChild->Stretch(*aReflowState.rendContext,
|
mathmlChild->Stretch(*aReflowState.rendContext,
|
||||||
stretchDir, containerSize, childDesiredSize);
|
stretchDir, containerSize, childDesiredSize);
|
||||||
// store the updated metrics
|
// store the updated metrics
|
||||||
childFrame->SetRect(nsRect(0, childDesiredSize.ascent,
|
SaveReflowAndBoundingMetricsFor(childFrame, childDesiredSize,
|
||||||
childDesiredSize.width, childDesiredSize.height));
|
childDesiredSize.mBoundingMetrics);
|
||||||
|
|
||||||
nscoord childDescent = childDesiredSize.height - childDesiredSize.ascent;
|
nscoord childDescent = childDesiredSize.height - childDesiredSize.ascent;
|
||||||
if (descent < childDescent)
|
if (descent < childDescent)
|
||||||
|
@ -371,7 +366,7 @@ nsMathMLmfencedFrame::doReflow(nsPresContext* aPresContext,
|
||||||
childFrame = childFrame->GetNextSibling();
|
childFrame = childFrame->GetNextSibling();
|
||||||
}
|
}
|
||||||
// bug 121748: for surrounding fences & separators, use a size that covers everything
|
// bug 121748: for surrounding fences & separators, use a size that covers everything
|
||||||
mathMLFrame->GetPreferredStretchSize(*aReflowState.rendContext,
|
aForFrame->GetPreferredStretchSize(*aReflowState.rendContext,
|
||||||
STRETCH_CONSIDER_EMBELLISHMENTS,
|
STRETCH_CONSIDER_EMBELLISHMENTS,
|
||||||
stretchDir, containerSize);
|
stretchDir, containerSize);
|
||||||
}
|
}
|
||||||
|
@ -431,7 +426,7 @@ nsMathMLmfencedFrame::doReflow(nsPresContext* aPresContext,
|
||||||
else
|
else
|
||||||
aDesiredSize.mBoundingMetrics += bm;
|
aDesiredSize.mBoundingMetrics += bm;
|
||||||
|
|
||||||
mathMLFrame->FinishReflowChild(childFrame, aPresContext, nsnull, childSize,
|
aForFrame->FinishReflowChild(childFrame, aPresContext, nsnull, childSize,
|
||||||
dx, ascent - childSize.ascent, 0);
|
dx, ascent - childSize.ascent, 0);
|
||||||
dx += childSize.width;
|
dx += childSize.width;
|
||||||
|
|
||||||
|
@ -456,14 +451,17 @@ nsMathMLmfencedFrame::doReflow(nsPresContext* aPresContext,
|
||||||
aDesiredSize.height = ascent + descent;
|
aDesiredSize.height = ascent + descent;
|
||||||
aDesiredSize.ascent = ascent;
|
aDesiredSize.ascent = ascent;
|
||||||
|
|
||||||
mathMLFrame->SetBoundingMetrics(aDesiredSize.mBoundingMetrics);
|
aForFrame->SetBoundingMetrics(aDesiredSize.mBoundingMetrics);
|
||||||
mathMLFrame->SetReference(nsPoint(0, aDesiredSize.ascent));
|
aForFrame->SetReference(nsPoint(0, aDesiredSize.ascent));
|
||||||
|
|
||||||
// see if we should fix the spacing
|
// see if we should fix the spacing
|
||||||
mathMLFrame->FixInterFrameSpacing(aDesiredSize);
|
aForFrame->FixInterFrameSpacing(aDesiredSize);
|
||||||
|
|
||||||
|
// Finished with these:
|
||||||
|
aForFrame->ClearSavedChildMetrics();
|
||||||
|
|
||||||
// Set our overflow area
|
// Set our overflow area
|
||||||
mathMLFrame->GatherAndStoreOverflow(&aDesiredSize);
|
aForFrame->GatherAndStoreOverflow(&aDesiredSize);
|
||||||
|
|
||||||
aStatus = NS_FRAME_COMPLETE;
|
aStatus = NS_FRAME_COMPLETE;
|
||||||
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
|
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
|
||||||
|
|
|
@ -94,7 +94,7 @@ public:
|
||||||
const nsHTMLReflowState& aReflowState,
|
const nsHTMLReflowState& aReflowState,
|
||||||
nsHTMLReflowMetrics& aDesiredSize,
|
nsHTMLReflowMetrics& aDesiredSize,
|
||||||
nsReflowStatus& aStatus,
|
nsReflowStatus& aStatus,
|
||||||
nsIFrame* aForFrame,
|
nsMathMLContainerFrame* aForFrame,
|
||||||
nsMathMLChar* aOpenChar,
|
nsMathMLChar* aOpenChar,
|
||||||
nsMathMLChar* aCloseChar,
|
nsMathMLChar* aCloseChar,
|
||||||
nsMathMLChar* aSeparatorsChar,
|
nsMathMLChar* aSeparatorsChar,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче