mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 04:41:11 +00:00
Bug 1908069 - Introduce PlaceFlags parameter to MathML layout methods. r=emilio
MathML classes has a few Place*() methods used for layout and intrinsic size calculation. These methods have a parameter "aPlaceOrigin" indicating whether the children and other painted objects should have their final positions set, or if the method is only called for measuring. This parameter is typically set to false when doing intrinsic size calculation or when performing some non-final measurement for operator stretching. For intrinsic size calculation, it is generally enough to perform placement with aPlaceOrigin=false and ignoring the vertical metrics. Some Place*() methods also have a parameter "aWidthOnly" for special handling. For example, msqrt stretches a radical symbol vertically to match the height of the content but when doing intrinsic size calculation this is approximated to nsMathMLChar::GetMaxWidth() instead. When we implement border/padding/margin we should also be able to choose between using IntrinsicISizeOffsets() or GetUsed*() methods. Finally, some Place*() methods initially call a place routing of a parent class before further tweaking the layout. For example, msqrt uses mrow layout on children and adds some radical symbol on top of them. When we implement border/padding, we should make sure we don't add the border/padding before the final result. In order to handle all these placement behaviors, a new EnumSet is introduced. This commit does not change behavior. Handling of padding, border and margin will be handled in follow-up patches. Differential Revision: https://phabricator.services.mozilla.com/D216669
This commit is contained in:
parent
7a1a9c40a3
commit
bcc3be9085
@ -103,9 +103,10 @@ void nsMathMLContainerFrame::GetPreferredStretchSize(
|
||||
// when our actual size is ok, just use it
|
||||
aPreferredStretchSize = mBoundingMetrics;
|
||||
} else if (aOptions & STRETCH_CONSIDER_EMBELLISHMENTS) {
|
||||
// compute our up-to-date size using Place()
|
||||
// compute our up-to-date size using Place(), without border/padding.
|
||||
ReflowOutput reflowOutput(GetWritingMode());
|
||||
Place(aDrawTarget, false, reflowOutput);
|
||||
PlaceFlags flags(PlaceFlag::MeasureOnly, PlaceFlag::IgnoreBorderPadding);
|
||||
Place(aDrawTarget, flags, reflowOutput);
|
||||
aPreferredStretchSize = reflowOutput.mBoundingMetrics;
|
||||
} else {
|
||||
// compute a size that includes embellishments iff the container stretches
|
||||
@ -296,7 +297,8 @@ nsMathMLContainerFrame::Stretch(DrawTarget* aDrawTarget,
|
||||
}
|
||||
|
||||
// re-position all our children
|
||||
nsresult rv = Place(aDrawTarget, true, aDesiredStretchSize);
|
||||
PlaceFlags flags;
|
||||
nsresult rv = Place(aDrawTarget, flags, aDesiredStretchSize);
|
||||
if (NS_FAILED(rv)) {
|
||||
// Make sure the child frames get their DidReflow() calls.
|
||||
DidReflowChildren(mFrames.FirstChild());
|
||||
@ -378,14 +380,18 @@ nsresult nsMathMLContainerFrame::FinalizeReflow(DrawTarget* aDrawTarget,
|
||||
!NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData.flags) ||
|
||||
(mEmbellishData.coreFrame != this && !mPresentationData.baseFrame &&
|
||||
mEmbellishData.direction == NS_STRETCH_DIRECTION_UNSUPPORTED);
|
||||
nsresult rv = Place(aDrawTarget, placeOrigin, aDesiredSize);
|
||||
PlaceFlags flags;
|
||||
if (!placeOrigin) {
|
||||
flags += PlaceFlag::MeasureOnly;
|
||||
}
|
||||
nsresult rv = Place(aDrawTarget, flags, aDesiredSize);
|
||||
|
||||
// Place() will call FinishReflowChild() when placeOrigin is true but if
|
||||
// it returns before reaching FinishReflowChild() due to errors we need
|
||||
// to fulfill the reflow protocol by calling DidReflow for the child frames
|
||||
// that still needs it here (or we may crash - bug 366012).
|
||||
// If placeOrigin is false we should reach Place() with aPlaceOrigin == true
|
||||
// through Stretch() eventually.
|
||||
// If placeOrigin is false we should reach Place() with
|
||||
// PlaceFlag::MeasureOnly unset through Stretch() eventually.
|
||||
if (NS_FAILED(rv)) {
|
||||
GatherAndStoreOverflow(&aDesiredSize);
|
||||
DidReflowChildren(PrincipalChildList().FirstChild());
|
||||
@ -865,9 +871,6 @@ void nsMathMLContainerFrame::GetIntrinsicISizeMetrics(
|
||||
containerFrame->GetIntrinsicISizeMetrics(aRenderingContext,
|
||||
childDesiredSize);
|
||||
} else {
|
||||
// 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, IntrinsicISizeType::PrefISize);
|
||||
|
||||
@ -894,7 +897,8 @@ void nsMathMLContainerFrame::GetIntrinsicISizeMetrics(
|
||||
nsresult rv =
|
||||
MeasureForWidth(aRenderingContext->GetDrawTarget(), aDesiredSize);
|
||||
if (NS_FAILED(rv)) {
|
||||
PlaceAsMrow(aRenderingContext->GetDrawTarget(), false, aDesiredSize);
|
||||
PlaceFlags flags(PlaceFlag::IntrinsicSize, PlaceFlag::MeasureOnly);
|
||||
PlaceAsMrow(aRenderingContext->GetDrawTarget(), flags, aDesiredSize);
|
||||
}
|
||||
|
||||
ClearSavedChildMetrics();
|
||||
@ -903,7 +907,8 @@ void nsMathMLContainerFrame::GetIntrinsicISizeMetrics(
|
||||
/* virtual */
|
||||
nsresult nsMathMLContainerFrame::MeasureForWidth(DrawTarget* aDrawTarget,
|
||||
ReflowOutput& aDesiredSize) {
|
||||
return Place(aDrawTarget, false, aDesiredSize);
|
||||
PlaceFlags flags(PlaceFlag::IntrinsicSize, PlaceFlag::MeasureOnly);
|
||||
return Place(aDrawTarget, flags, aDesiredSize);
|
||||
}
|
||||
|
||||
// see spacing table in Chapter 18, TeXBook (p.170)
|
||||
@ -1107,7 +1112,7 @@ class nsMathMLContainerFrame::RowChildFrameIterator {
|
||||
|
||||
/* virtual */
|
||||
nsresult nsMathMLContainerFrame::Place(DrawTarget* aDrawTarget,
|
||||
bool aPlaceOrigin,
|
||||
const PlaceFlags& aFlags,
|
||||
ReflowOutput& aDesiredSize) {
|
||||
// This is needed in case this frame is empty (i.e., no child frames)
|
||||
mBoundingMetrics = nsBoundingMetrics();
|
||||
@ -1139,7 +1144,7 @@ nsresult nsMathMLContainerFrame::Place(DrawTarget* aDrawTarget,
|
||||
//////////////////
|
||||
// Place Children
|
||||
|
||||
if (aPlaceOrigin) {
|
||||
if (!aFlags.contains(PlaceFlag::MeasureOnly)) {
|
||||
PositionRowChildFrames(0, aDesiredSize.BlockStartAscent());
|
||||
}
|
||||
|
||||
@ -1147,9 +1152,9 @@ nsresult nsMathMLContainerFrame::Place(DrawTarget* aDrawTarget,
|
||||
}
|
||||
|
||||
nsresult nsMathMLContainerFrame::PlaceAsMrow(DrawTarget* aDrawTarget,
|
||||
bool aPlaceOrigin,
|
||||
const PlaceFlags& aFlags,
|
||||
ReflowOutput& aDesiredSize) {
|
||||
return nsMathMLContainerFrame::Place(aDrawTarget, aPlaceOrigin, aDesiredSize);
|
||||
return nsMathMLContainerFrame::Place(aDrawTarget, aFlags, aDesiredSize);
|
||||
}
|
||||
|
||||
void nsMathMLContainerFrame::PositionRowChildFrames(nscoord aOffsetX,
|
||||
|
@ -133,11 +133,37 @@ class nsMathMLContainerFrame : public nsContainerFrame, public nsMathMLFrame {
|
||||
// Additional methods
|
||||
|
||||
protected:
|
||||
enum class PlaceFlag : uint8_t {
|
||||
// If MeasureOnly is set, compute your desired size using the information
|
||||
// from GetReflowAndBoundingMetricsFor. However, child frames or other
|
||||
// elements should not be repositioned.
|
||||
// If MeasureOnly is not set, reflow is finished. You should position all
|
||||
// your children, and return your desired size. You should now use
|
||||
// FinishReflowChild() on your children to complete post-reflow operations.
|
||||
MeasureOnly,
|
||||
|
||||
// If IntrinsicSize is set, the function is actually used to determine
|
||||
// intrinsic size (and consequently MeasureOnly is expected to be set too).
|
||||
// - It will use nsMathMLChar::GetMaxWidth instead of nsMathMLChar::Stretch.
|
||||
// - It will use IntrinsicISizeOffsets() for padding/border/margin instead
|
||||
// of GetUsedBorder/Padding/Margin().
|
||||
// - etc
|
||||
IntrinsicSize,
|
||||
|
||||
// If IgnoreBorderPadding is set, the function will complete without
|
||||
// adding the border/padding around the math layout. This can be used for
|
||||
// elements like <msqrt> that first layout their children as an <mrow>,
|
||||
// place some radical symbol on top of them and finally add its
|
||||
// padding/border around that radical symbol.
|
||||
IgnoreBorderPadding,
|
||||
};
|
||||
using PlaceFlags = mozilla::EnumSet<PlaceFlag>;
|
||||
|
||||
/* Place :
|
||||
* This method is used to measure or position child frames and other
|
||||
* elements. It may be called any number of times with aPlaceOrigin
|
||||
* false to measure, and the final call of the Reflow process before
|
||||
* returning from Reflow() or Stretch() will have aPlaceOrigin true
|
||||
* elements. It may be called any number of times with MeasureOnly
|
||||
* true, and the final call of the Reflow process before
|
||||
* returning from Reflow() or Stretch() will have MeasureOnly false
|
||||
* to position the elements.
|
||||
*
|
||||
* IMPORTANT: This method uses GetReflowAndBoundingMetricsFor() which must
|
||||
@ -146,15 +172,8 @@ class nsMathMLContainerFrame : public nsContainerFrame, public nsMathMLFrame {
|
||||
* The Place() method will use this information to compute the desired size
|
||||
* of the frame.
|
||||
*
|
||||
* @param aPlaceOrigin [in]
|
||||
* If aPlaceOrigin is false, compute your desired size using the
|
||||
* information from GetReflowAndBoundingMetricsFor. However, child
|
||||
* frames or other elements should not be repositioned.
|
||||
*
|
||||
* If aPlaceOrigin is true, reflow is finished. You should position
|
||||
* all your children, and return your desired size. You should now
|
||||
* use FinishReflowChild() on your children to complete post-reflow
|
||||
* operations.
|
||||
* @param aFlags [in] Flags to indicate the way the Place method should
|
||||
* behave. See document for PlaceFlag above.
|
||||
*
|
||||
* @param aDesiredSize [out] parameter where you should return your desired
|
||||
* size and your ascent/descent info. Compute your desired size using
|
||||
@ -162,7 +181,7 @@ class nsMathMLContainerFrame : public nsContainerFrame, public nsMathMLFrame {
|
||||
* any space you want for border/padding in the desired size you
|
||||
* return.
|
||||
*/
|
||||
virtual nsresult Place(DrawTarget* aDrawTarget, bool aPlaceOrigin,
|
||||
virtual nsresult Place(DrawTarget* aDrawTarget, const PlaceFlags& aFlags,
|
||||
ReflowOutput& aDesiredSize);
|
||||
|
||||
// MeasureForWidth:
|
||||
@ -197,7 +216,7 @@ class nsMathMLContainerFrame : public nsContainerFrame, public nsMathMLFrame {
|
||||
* (typically invalid markup) was encountered during reflow. Parameters are
|
||||
* the same as Place().
|
||||
*/
|
||||
nsresult PlaceAsMrow(DrawTarget* aDrawTarget, bool aPlaceOrigin,
|
||||
nsresult PlaceAsMrow(DrawTarget* aDrawTarget, const PlaceFlags& aFlags,
|
||||
ReflowOutput& aDesiredSize);
|
||||
|
||||
/*
|
||||
|
@ -149,7 +149,8 @@ void nsMathMLTokenFrame::Reflow(nsPresContext* aPresContext,
|
||||
// pass, it is not computed here because our children may be text frames
|
||||
// that do not implement the GetBoundingMetrics() interface.
|
||||
/* virtual */
|
||||
nsresult nsMathMLTokenFrame::Place(DrawTarget* aDrawTarget, bool aPlaceOrigin,
|
||||
nsresult nsMathMLTokenFrame::Place(DrawTarget* aDrawTarget,
|
||||
const PlaceFlags& aFlags,
|
||||
ReflowOutput& aDesiredSize) {
|
||||
mBoundingMetrics = nsBoundingMetrics();
|
||||
for (nsIFrame* childFrame : PrincipalChildList()) {
|
||||
@ -171,7 +172,7 @@ nsresult nsMathMLTokenFrame::Place(DrawTarget* aDrawTarget, bool aPlaceOrigin,
|
||||
aDesiredSize.Height() = aDesiredSize.BlockStartAscent() +
|
||||
std::max(mBoundingMetrics.descent, descent);
|
||||
|
||||
if (aPlaceOrigin) {
|
||||
if (!aFlags.contains(PlaceFlag::MeasureOnly)) {
|
||||
nscoord dy, dx = 0;
|
||||
for (nsIFrame* childFrame : PrincipalChildList()) {
|
||||
ReflowOutput childSize(aDesiredSize.GetWritingMode());
|
||||
|
@ -53,8 +53,8 @@ class nsMathMLTokenFrame : public nsMathMLContainerFrame {
|
||||
const ReflowInput& aReflowInput,
|
||||
nsReflowStatus& aStatus) override;
|
||||
|
||||
virtual nsresult Place(DrawTarget* aDrawTarget, bool aPlaceOrigin,
|
||||
ReflowOutput& aDesiredSize) override;
|
||||
nsresult Place(DrawTarget* aDrawTarget, const PlaceFlags& aFlags,
|
||||
ReflowOutput& aDesiredSize) override;
|
||||
|
||||
protected:
|
||||
explicit nsMathMLTokenFrame(ComputedStyle* aStyle,
|
||||
|
@ -299,26 +299,28 @@ void nsMathMLmencloseFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
/* virtual */
|
||||
nsresult nsMathMLmencloseFrame::MeasureForWidth(DrawTarget* aDrawTarget,
|
||||
ReflowOutput& aDesiredSize) {
|
||||
return PlaceInternal(aDrawTarget, false, aDesiredSize, true);
|
||||
PlaceFlags flags(PlaceFlag::IntrinsicSize, PlaceFlag::MeasureOnly);
|
||||
return PlaceInternal(aDrawTarget, flags, aDesiredSize);
|
||||
}
|
||||
|
||||
/* virtual */
|
||||
nsresult nsMathMLmencloseFrame::Place(DrawTarget* aDrawTarget,
|
||||
bool aPlaceOrigin,
|
||||
const PlaceFlags& aFlags,
|
||||
ReflowOutput& aDesiredSize) {
|
||||
return PlaceInternal(aDrawTarget, aPlaceOrigin, aDesiredSize, false);
|
||||
return PlaceInternal(aDrawTarget, aFlags, aDesiredSize);
|
||||
}
|
||||
|
||||
/* virtual */
|
||||
nsresult nsMathMLmencloseFrame::PlaceInternal(DrawTarget* aDrawTarget,
|
||||
bool aPlaceOrigin,
|
||||
ReflowOutput& aDesiredSize,
|
||||
bool aWidthOnly) {
|
||||
const PlaceFlags& aFlags,
|
||||
ReflowOutput& aDesiredSize) {
|
||||
///////////////
|
||||
// Measure the size of our content using the base class to format like an
|
||||
// inferred mrow.
|
||||
// inferred mrow, without border/padding.
|
||||
ReflowOutput baseSize(aDesiredSize.GetWritingMode());
|
||||
nsresult rv = nsMathMLContainerFrame::Place(aDrawTarget, false, baseSize);
|
||||
PlaceFlags flags =
|
||||
aFlags + PlaceFlag::MeasureOnly + PlaceFlag::IgnoreBorderPadding;
|
||||
nsresult rv = nsMathMLContainerFrame::Place(aDrawTarget, flags, baseSize);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
DidReflowChildren(PrincipalChildList().FirstChild());
|
||||
@ -461,7 +463,7 @@ nsresult nsMathMLmencloseFrame::PlaceInternal(DrawTarget* aDrawTarget,
|
||||
///////////////
|
||||
// longdiv notation:
|
||||
if (IsToDraw(NOTATION_LONGDIV)) {
|
||||
if (aWidthOnly) {
|
||||
if (aFlags.contains(PlaceFlag::IntrinsicSize)) {
|
||||
nscoord longdiv_width = mMathMLChar[mLongDivCharIndex].GetMaxWidth(
|
||||
this, aDrawTarget, fontSizeInflation);
|
||||
|
||||
@ -503,7 +505,7 @@ nsresult nsMathMLmencloseFrame::PlaceInternal(DrawTarget* aDrawTarget,
|
||||
? &dx_right
|
||||
: &dx_left;
|
||||
|
||||
if (aWidthOnly) {
|
||||
if (aFlags.contains(PlaceFlag::IntrinsicSize)) {
|
||||
nscoord radical_width = mMathMLChar[mRadicalCharIndex].GetMaxWidth(
|
||||
this, aDrawTarget, fontSizeInflation);
|
||||
|
||||
@ -627,7 +629,7 @@ nsresult nsMathMLmencloseFrame::PlaceInternal(DrawTarget* aDrawTarget,
|
||||
mReference.x = 0;
|
||||
mReference.y = aDesiredSize.BlockStartAscent();
|
||||
|
||||
if (aPlaceOrigin) {
|
||||
if (!aFlags.contains(PlaceFlag::MeasureOnly)) {
|
||||
//////////////////
|
||||
// Set position and size of MathMLChars
|
||||
if (IsToDraw(NOTATION_LONGDIV))
|
||||
|
@ -54,8 +54,8 @@ class nsMathMLmencloseFrame : public nsMathMLContainerFrame {
|
||||
friend nsIFrame* NS_NewMathMLmencloseFrame(mozilla::PresShell* aPresShell,
|
||||
ComputedStyle* aStyle);
|
||||
|
||||
virtual nsresult Place(DrawTarget* aDrawTarget, bool aPlaceOrigin,
|
||||
ReflowOutput& aDesiredSize) override;
|
||||
nsresult Place(DrawTarget* aDrawTarget, const PlaceFlags& aFlags,
|
||||
ReflowOutput& aDesiredSize) override;
|
||||
|
||||
virtual nsresult MeasureForWidth(DrawTarget* aDrawTarget,
|
||||
ReflowOutput& aDesiredSize) override;
|
||||
@ -86,8 +86,8 @@ class nsMathMLmencloseFrame : public nsMathMLContainerFrame {
|
||||
ClassID aID = kClassID);
|
||||
virtual ~nsMathMLmencloseFrame();
|
||||
|
||||
nsresult PlaceInternal(DrawTarget* aDrawTarget, bool aPlaceOrigin,
|
||||
ReflowOutput& aDesiredSize, bool aWidthOnly);
|
||||
nsresult PlaceInternal(DrawTarget* aDrawTarget, const PlaceFlags& aFlags,
|
||||
ReflowOutput& aDesiredSize);
|
||||
|
||||
// functions to parse the "notation" attribute.
|
||||
nsresult AddNotation(const nsAString& aNotation);
|
||||
|
@ -130,7 +130,8 @@ nsresult nsMathMLmfracFrame::AttributeChanged(int32_t aNameSpaceID,
|
||||
/* virtual */
|
||||
nsresult nsMathMLmfracFrame::MeasureForWidth(DrawTarget* aDrawTarget,
|
||||
ReflowOutput& aDesiredSize) {
|
||||
return PlaceInternal(aDrawTarget, false, aDesiredSize, true);
|
||||
PlaceFlags flags(PlaceFlag::IntrinsicSize, PlaceFlag::MeasureOnly);
|
||||
return PlaceInternal(aDrawTarget, flags, aDesiredSize);
|
||||
}
|
||||
|
||||
nscoord nsMathMLmfracFrame::FixInterFrameSpacing(ReflowOutput& aDesiredSize) {
|
||||
@ -142,15 +143,15 @@ nscoord nsMathMLmfracFrame::FixInterFrameSpacing(ReflowOutput& aDesiredSize) {
|
||||
}
|
||||
|
||||
/* virtual */
|
||||
nsresult nsMathMLmfracFrame::Place(DrawTarget* aDrawTarget, bool aPlaceOrigin,
|
||||
nsresult nsMathMLmfracFrame::Place(DrawTarget* aDrawTarget,
|
||||
const PlaceFlags& aFlags,
|
||||
ReflowOutput& aDesiredSize) {
|
||||
return PlaceInternal(aDrawTarget, aPlaceOrigin, aDesiredSize, false);
|
||||
return PlaceInternal(aDrawTarget, aFlags, aDesiredSize);
|
||||
}
|
||||
|
||||
nsresult nsMathMLmfracFrame::PlaceInternal(DrawTarget* aDrawTarget,
|
||||
bool aPlaceOrigin,
|
||||
ReflowOutput& aDesiredSize,
|
||||
bool aWidthOnly) {
|
||||
const PlaceFlags& aFlags,
|
||||
ReflowOutput& aDesiredSize) {
|
||||
////////////////////////////////////
|
||||
// Get the children's desired sizes
|
||||
nsBoundingMetrics bmNum, bmDen;
|
||||
@ -161,10 +162,10 @@ nsresult nsMathMLmfracFrame::PlaceInternal(DrawTarget* aDrawTarget,
|
||||
if (frameNum) frameDen = frameNum->GetNextSibling();
|
||||
if (!frameNum || !frameDen || frameDen->GetNextSibling()) {
|
||||
// report an error, encourage people to get their markups in order
|
||||
if (aPlaceOrigin) {
|
||||
if (!aFlags.contains(PlaceFlag::MeasureOnly)) {
|
||||
ReportChildCountError();
|
||||
}
|
||||
return PlaceAsMrow(aDrawTarget, aPlaceOrigin, aDesiredSize);
|
||||
return PlaceAsMrow(aDrawTarget, aFlags, aDesiredSize);
|
||||
}
|
||||
GetReflowAndBoundingMetricsFor(frameNum, sizeNum, bmNum);
|
||||
GetReflowAndBoundingMetricsFor(frameDen, sizeDen, bmDen);
|
||||
@ -356,7 +357,7 @@ nsresult nsMathMLmfracFrame::PlaceInternal(DrawTarget* aDrawTarget,
|
||||
mReference.x = 0;
|
||||
mReference.y = aDesiredSize.BlockStartAscent();
|
||||
|
||||
if (aPlaceOrigin) {
|
||||
if (!aFlags.contains(PlaceFlag::MeasureOnly)) {
|
||||
nscoord dy;
|
||||
// place numerator
|
||||
dy = 0;
|
||||
|
@ -66,8 +66,8 @@ class nsMathMLmfracFrame final : public nsMathMLContainerFrame {
|
||||
virtual nsresult MeasureForWidth(DrawTarget* aDrawTarget,
|
||||
ReflowOutput& aDesiredSize) override;
|
||||
|
||||
virtual nsresult Place(DrawTarget* aDrawTarget, bool aPlaceOrigin,
|
||||
ReflowOutput& aDesiredSize) override;
|
||||
nsresult Place(DrawTarget* aDrawTarget, const PlaceFlags& aFlags,
|
||||
ReflowOutput& aDesiredSize) override;
|
||||
|
||||
virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
const nsDisplayListSet& aLists) override;
|
||||
@ -98,8 +98,8 @@ class nsMathMLmfracFrame final : public nsMathMLContainerFrame {
|
||||
mLineThickness(0) {}
|
||||
virtual ~nsMathMLmfracFrame();
|
||||
|
||||
nsresult PlaceInternal(DrawTarget* aDrawTarget, bool aPlaceOrigin,
|
||||
ReflowOutput& aDesiredSize, bool aWidthOnly);
|
||||
nsresult PlaceInternal(DrawTarget* aDrawTarget, const PlaceFlags& aFlags,
|
||||
ReflowOutput& aDesiredSize);
|
||||
|
||||
// Display a slash
|
||||
void DisplaySlash(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
|
@ -93,24 +93,24 @@ nsMathMLmmultiscriptsFrame::TransmitAutomaticData() {
|
||||
|
||||
/* virtual */
|
||||
nsresult nsMathMLmmultiscriptsFrame::Place(DrawTarget* aDrawTarget,
|
||||
bool aPlaceOrigin,
|
||||
const PlaceFlags& aFlags,
|
||||
ReflowOutput& aDesiredSize) {
|
||||
nscoord subScriptShift = 0;
|
||||
nscoord supScriptShift = 0;
|
||||
float fontSizeInflation = nsLayoutUtils::FontSizeInflationFor(this);
|
||||
|
||||
return PlaceMultiScript(PresContext(), aDrawTarget, aPlaceOrigin,
|
||||
aDesiredSize, this, subScriptShift, supScriptShift,
|
||||
return PlaceMultiScript(PresContext(), aDrawTarget, aFlags, aDesiredSize,
|
||||
this, subScriptShift, supScriptShift,
|
||||
fontSizeInflation);
|
||||
}
|
||||
|
||||
// exported routine that both munderover and mmultiscripts share.
|
||||
// munderover uses this when movablelimits is set.
|
||||
nsresult nsMathMLmmultiscriptsFrame::PlaceMultiScript(
|
||||
nsPresContext* aPresContext, DrawTarget* aDrawTarget, bool aPlaceOrigin,
|
||||
ReflowOutput& aDesiredSize, nsMathMLContainerFrame* aFrame,
|
||||
nscoord aUserSubScriptShift, nscoord aUserSupScriptShift,
|
||||
float aFontSizeInflation) {
|
||||
nsPresContext* aPresContext, DrawTarget* aDrawTarget,
|
||||
const PlaceFlags& aFlags, ReflowOutput& aDesiredSize,
|
||||
nsMathMLContainerFrame* aFrame, nscoord aUserSubScriptShift,
|
||||
nscoord aUserSupScriptShift, float aFontSizeInflation) {
|
||||
nsAtom* tag = aFrame->GetContent()->NodeInfo()->NameAtom();
|
||||
|
||||
// This function deals with both munderover etc. as well as msubsup etc.
|
||||
@ -139,7 +139,7 @@ nsresult nsMathMLmmultiscriptsFrame::PlaceMultiScript(
|
||||
aFrame->ReportErrorToConsole("NoBase");
|
||||
else
|
||||
aFrame->ReportChildCountError();
|
||||
return aFrame->PlaceAsMrow(aDrawTarget, aPlaceOrigin, aDesiredSize);
|
||||
return aFrame->PlaceAsMrow(aDrawTarget, aFlags, aDesiredSize);
|
||||
}
|
||||
|
||||
// get x-height (an ex)
|
||||
@ -290,24 +290,24 @@ nsresult nsMathMLmmultiscriptsFrame::PlaceMultiScript(
|
||||
while (childFrame) {
|
||||
if (childFrame->GetContent()->IsMathMLElement(nsGkAtoms::mprescripts_)) {
|
||||
if (tag != nsGkAtoms::mmultiscripts_) {
|
||||
if (aPlaceOrigin) {
|
||||
if (!aFlags.contains(PlaceFlag::MeasureOnly)) {
|
||||
aFrame->ReportInvalidChildError(nsGkAtoms::mprescripts_);
|
||||
}
|
||||
return aFrame->PlaceAsMrow(aDrawTarget, aPlaceOrigin, aDesiredSize);
|
||||
return aFrame->PlaceAsMrow(aDrawTarget, aFlags, aDesiredSize);
|
||||
}
|
||||
if (prescriptsFrame) {
|
||||
// duplicate <mprescripts/> found
|
||||
// report an error, encourage people to get their markups in order
|
||||
if (aPlaceOrigin) {
|
||||
if (!aFlags.contains(PlaceFlag::MeasureOnly)) {
|
||||
aFrame->ReportErrorToConsole("DuplicateMprescripts");
|
||||
}
|
||||
return aFrame->PlaceAsMrow(aDrawTarget, aPlaceOrigin, aDesiredSize);
|
||||
return aFrame->PlaceAsMrow(aDrawTarget, aFlags, aDesiredSize);
|
||||
}
|
||||
if (!isSubScript) {
|
||||
if (aPlaceOrigin) {
|
||||
if (!aFlags.contains(PlaceFlag::MeasureOnly)) {
|
||||
aFrame->ReportErrorToConsole("SubSupMismatch");
|
||||
}
|
||||
return aFrame->PlaceAsMrow(aDrawTarget, aPlaceOrigin, aDesiredSize);
|
||||
return aFrame->PlaceAsMrow(aDrawTarget, aFlags, aDesiredSize);
|
||||
}
|
||||
|
||||
prescriptsFrame = childFrame;
|
||||
@ -481,7 +481,7 @@ nsresult nsMathMLmmultiscriptsFrame::PlaceMultiScript(
|
||||
(count != 3 && tag == nsGkAtoms::msubsup_) || !baseFrame ||
|
||||
(!isSubScript && tag == nsGkAtoms::mmultiscripts_)) {
|
||||
// report an error, encourage people to get their markups in order
|
||||
if (aPlaceOrigin) {
|
||||
if (!aFlags.contains(PlaceFlag::MeasureOnly)) {
|
||||
if ((count != 2 &&
|
||||
(tag == nsGkAtoms::msup_ || tag == nsGkAtoms::msub_)) ||
|
||||
(count != 3 && tag == nsGkAtoms::msubsup_)) {
|
||||
@ -492,7 +492,7 @@ nsresult nsMathMLmmultiscriptsFrame::PlaceMultiScript(
|
||||
aFrame->ReportErrorToConsole("SubSupMismatch");
|
||||
}
|
||||
}
|
||||
return aFrame->PlaceAsMrow(aDrawTarget, aPlaceOrigin, aDesiredSize);
|
||||
return aFrame->PlaceAsMrow(aDrawTarget, aFlags, aDesiredSize);
|
||||
}
|
||||
|
||||
// we left out the width of prescripts, so ...
|
||||
@ -543,7 +543,7 @@ nsresult nsMathMLmmultiscriptsFrame::PlaceMultiScript(
|
||||
// The list of frames is in the order: {base} {postscripts} {prescripts}
|
||||
// We go over the list in a circular manner, starting at <prescripts/>
|
||||
|
||||
if (aPlaceOrigin) {
|
||||
if (!aFlags.contains(PlaceFlag::MeasureOnly)) {
|
||||
nscoord dx = 0, dy = 0;
|
||||
|
||||
// With msub and msup there is only one element and
|
||||
|
@ -31,16 +31,14 @@ class nsMathMLmmultiscriptsFrame final : public nsMathMLContainerFrame {
|
||||
NS_IMETHOD
|
||||
TransmitAutomaticData() override;
|
||||
|
||||
virtual nsresult Place(DrawTarget* aDrawTarget, bool aPlaceOrigin,
|
||||
ReflowOutput& aDesiredSize) override;
|
||||
nsresult Place(DrawTarget* aDrawTarget, const PlaceFlags& aFlags,
|
||||
ReflowOutput& aDesiredSize) override;
|
||||
|
||||
static nsresult PlaceMultiScript(nsPresContext* aPresContext,
|
||||
DrawTarget* aDrawTarget, bool aPlaceOrigin,
|
||||
ReflowOutput& aDesiredSize,
|
||||
nsMathMLContainerFrame* aForFrame,
|
||||
nscoord aUserSubScriptShift,
|
||||
nscoord aUserSupScriptShift,
|
||||
float aFontSizeInflation);
|
||||
static nsresult PlaceMultiScript(
|
||||
nsPresContext* aPresContext, DrawTarget* aDrawTarget,
|
||||
const PlaceFlags& aFlags, ReflowOutput& aDesiredSize,
|
||||
nsMathMLContainerFrame* aFrame, nscoord aUserSubScriptShift,
|
||||
nscoord aUserSupScriptShift, float aFontSizeInflation);
|
||||
|
||||
uint8_t ScriptIncrement(nsIFrame* aFrame) override;
|
||||
|
||||
|
@ -738,9 +738,10 @@ nsMathMLmoFrame::Stretch(DrawTarget* aDrawTarget,
|
||||
}
|
||||
}
|
||||
|
||||
// Place our children using the default method
|
||||
// Place our children using the default method and no border/padding.
|
||||
// This will allow our child text frame to get its DidReflow()
|
||||
nsresult rv = Place(aDrawTarget, true, aDesiredStretchSize);
|
||||
PlaceFlags flags = PlaceFlag::IgnoreBorderPadding;
|
||||
nsresult rv = Place(aDrawTarget, flags, aDesiredStretchSize);
|
||||
if (NS_FAILED(rv)) {
|
||||
// Make sure the child frames get their DidReflow() calls.
|
||||
DidReflowChildren(mFrames.FirstChild());
|
||||
@ -930,10 +931,10 @@ void nsMathMLmoFrame::Reflow(nsPresContext* aPresContext,
|
||||
nsMathMLTokenFrame::Reflow(aPresContext, aDesiredSize, aReflowInput, aStatus);
|
||||
}
|
||||
|
||||
nsresult nsMathMLmoFrame::Place(DrawTarget* aDrawTarget, bool aPlaceOrigin,
|
||||
nsresult nsMathMLmoFrame::Place(DrawTarget* aDrawTarget,
|
||||
const PlaceFlags& aFlags,
|
||||
ReflowOutput& aDesiredSize) {
|
||||
nsresult rv =
|
||||
nsMathMLTokenFrame::Place(aDrawTarget, aPlaceOrigin, aDesiredSize);
|
||||
nsresult rv = nsMathMLTokenFrame::Place(aDrawTarget, aFlags, aDesiredSize);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
@ -950,7 +951,8 @@ nsresult nsMathMLmoFrame::Place(DrawTarget* aDrawTarget, bool aPlaceOrigin,
|
||||
Stretch() method.
|
||||
*/
|
||||
|
||||
if (!aPlaceOrigin && StyleFont()->mMathStyle == StyleMathStyle::Normal &&
|
||||
if (aFlags.contains(PlaceFlag::MeasureOnly) &&
|
||||
StyleFont()->mMathStyle == StyleMathStyle::Normal &&
|
||||
NS_MATHML_OPERATOR_IS_LARGEOP(mFlags) && UseMathMLChar()) {
|
||||
nsBoundingMetrics newMetrics;
|
||||
rv = mMathMLChar.Stretch(
|
||||
|
@ -46,8 +46,8 @@ class nsMathMLmoFrame final : public nsMathMLTokenFrame {
|
||||
const ReflowInput& aReflowInput,
|
||||
nsReflowStatus& aStatus) override;
|
||||
|
||||
virtual nsresult Place(DrawTarget* aDrawTarget, bool aPlaceOrigin,
|
||||
ReflowOutput& aDesiredSize) override;
|
||||
nsresult Place(DrawTarget* aDrawTarget, const PlaceFlags& aFlags,
|
||||
ReflowOutput& aDesiredSize) override;
|
||||
|
||||
virtual void MarkIntrinsicISizesDirty() override;
|
||||
|
||||
|
@ -313,9 +313,13 @@ void nsMathMLmpaddedFrame::Reflow(nsPresContext* aPresContext,
|
||||
}
|
||||
|
||||
/* virtual */
|
||||
nsresult nsMathMLmpaddedFrame::Place(DrawTarget* aDrawTarget, bool aPlaceOrigin,
|
||||
nsresult nsMathMLmpaddedFrame::Place(DrawTarget* aDrawTarget,
|
||||
const PlaceFlags& aFlags,
|
||||
ReflowOutput& aDesiredSize) {
|
||||
nsresult rv = nsMathMLContainerFrame::Place(aDrawTarget, false, aDesiredSize);
|
||||
// First perform normal row layout without border/padding.
|
||||
PlaceFlags flags =
|
||||
aFlags + PlaceFlag::MeasureOnly + PlaceFlag::IgnoreBorderPadding;
|
||||
nsresult rv = nsMathMLContainerFrame::Place(aDrawTarget, flags, aDesiredSize);
|
||||
if (NS_FAILED(rv)) {
|
||||
DidReflowChildren(PrincipalChildList().FirstChild());
|
||||
return rv;
|
||||
@ -424,7 +428,7 @@ nsresult nsMathMLmpaddedFrame::Place(DrawTarget* aDrawTarget, bool aPlaceOrigin,
|
||||
mReference.x = 0;
|
||||
mReference.y = aDesiredSize.BlockStartAscent();
|
||||
|
||||
if (aPlaceOrigin) {
|
||||
if (!aFlags.contains(PlaceFlag::MeasureOnly)) {
|
||||
// Finish reflowing child frames, positioning their origins.
|
||||
PositionRowChildFrames(dx, aDesiredSize.BlockStartAscent() - voffset);
|
||||
}
|
||||
@ -436,5 +440,6 @@ nsresult nsMathMLmpaddedFrame::Place(DrawTarget* aDrawTarget, bool aPlaceOrigin,
|
||||
nsresult nsMathMLmpaddedFrame::MeasureForWidth(DrawTarget* aDrawTarget,
|
||||
ReflowOutput& aDesiredSize) {
|
||||
ProcessAttributes();
|
||||
return Place(aDrawTarget, false, aDesiredSize);
|
||||
PlaceFlags flags(PlaceFlag::IntrinsicSize, PlaceFlag::MeasureOnly);
|
||||
return Place(aDrawTarget, flags, aDesiredSize);
|
||||
}
|
||||
|
@ -38,8 +38,8 @@ class nsMathMLmpaddedFrame final : public nsMathMLContainerFrame {
|
||||
const ReflowInput& aReflowInput,
|
||||
nsReflowStatus& aStatus) override;
|
||||
|
||||
virtual nsresult Place(DrawTarget* aDrawTarget, bool aPlaceOrigin,
|
||||
ReflowOutput& aDesiredSize) override;
|
||||
nsresult Place(DrawTarget* aDrawTarget, const PlaceFlags& aFlags,
|
||||
ReflowOutput& aDesiredSize) override;
|
||||
|
||||
bool IsMrowLike() override {
|
||||
return mFrames.FirstChild() != mFrames.LastChild() || !mFrames.FirstChild();
|
||||
|
@ -95,11 +95,11 @@ void nsMathMLmspaceFrame::Reflow(nsPresContext* aPresContext,
|
||||
|
||||
ProcessAttributes(aPresContext);
|
||||
|
||||
auto borderPadding = aReflowInput.ComputedPhysicalBorderPadding();
|
||||
const auto& borderPadding = GetUsedBorderAndPadding();
|
||||
mBoundingMetrics = nsBoundingMetrics();
|
||||
mBoundingMetrics.width = mWidth + borderPadding.LeftRight();
|
||||
mBoundingMetrics.ascent = mHeight + borderPadding.Side(eSideTop);
|
||||
mBoundingMetrics.descent = mDepth + borderPadding.Side(eSideBottom);
|
||||
mBoundingMetrics.ascent = mHeight + borderPadding.top;
|
||||
mBoundingMetrics.descent = mDepth + borderPadding.bottom;
|
||||
mBoundingMetrics.leftBearing = 0;
|
||||
mBoundingMetrics.rightBearing = mBoundingMetrics.width;
|
||||
|
||||
@ -116,7 +116,7 @@ nsresult nsMathMLmspaceFrame::MeasureForWidth(DrawTarget* aDrawTarget,
|
||||
ProcessAttributes(PresContext());
|
||||
mBoundingMetrics = nsBoundingMetrics();
|
||||
auto offsets = IntrinsicISizeOffsets();
|
||||
mBoundingMetrics.width = mWidth + offsets.padding + offsets.border;
|
||||
mBoundingMetrics.width = mWidth + offsets.BorderPadding();
|
||||
aDesiredSize.Width() = std::max(0, mBoundingMetrics.width);
|
||||
aDesiredSize.mBoundingMetrics = mBoundingMetrics;
|
||||
return NS_OK;
|
||||
|
@ -358,7 +358,7 @@ i.e.,:
|
||||
|
||||
/* virtual */
|
||||
nsresult nsMathMLmunderoverFrame::Place(DrawTarget* aDrawTarget,
|
||||
bool aPlaceOrigin,
|
||||
const PlaceFlags& aFlags,
|
||||
ReflowOutput& aDesiredSize) {
|
||||
float fontSizeInflation = nsLayoutUtils::FontSizeInflationFor(this);
|
||||
if (NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(mEmbellishData.flags) &&
|
||||
@ -366,17 +366,17 @@ nsresult nsMathMLmunderoverFrame::Place(DrawTarget* aDrawTarget,
|
||||
// place like sub sup or subsup
|
||||
if (mContent->IsMathMLElement(nsGkAtoms::munderover_)) {
|
||||
return nsMathMLmmultiscriptsFrame::PlaceMultiScript(
|
||||
PresContext(), aDrawTarget, aPlaceOrigin, aDesiredSize, this, 0, 0,
|
||||
PresContext(), aDrawTarget, aFlags, aDesiredSize, this, 0, 0,
|
||||
fontSizeInflation);
|
||||
} else if (mContent->IsMathMLElement(nsGkAtoms::munder_)) {
|
||||
return nsMathMLmmultiscriptsFrame::PlaceMultiScript(
|
||||
PresContext(), aDrawTarget, aPlaceOrigin, aDesiredSize, this, 0, 0,
|
||||
PresContext(), aDrawTarget, aFlags, aDesiredSize, this, 0, 0,
|
||||
fontSizeInflation);
|
||||
} else {
|
||||
NS_ASSERTION(mContent->IsMathMLElement(nsGkAtoms::mover_),
|
||||
"mContent->NodeInfo()->NameAtom() not recognized");
|
||||
return nsMathMLmmultiscriptsFrame::PlaceMultiScript(
|
||||
PresContext(), aDrawTarget, aPlaceOrigin, aDesiredSize, this, 0, 0,
|
||||
PresContext(), aDrawTarget, aFlags, aDesiredSize, this, 0, 0,
|
||||
fontSizeInflation);
|
||||
}
|
||||
}
|
||||
@ -426,10 +426,10 @@ nsresult nsMathMLmunderoverFrame::Place(DrawTarget* aDrawTarget,
|
||||
}
|
||||
}
|
||||
if (haveError) {
|
||||
if (aPlaceOrigin) {
|
||||
if (!aFlags.contains(PlaceFlag::MeasureOnly)) {
|
||||
ReportChildCountError();
|
||||
}
|
||||
return PlaceAsMrow(aDrawTarget, aPlaceOrigin, aDesiredSize);
|
||||
return PlaceAsMrow(aDrawTarget, aFlags, aDesiredSize);
|
||||
}
|
||||
GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase);
|
||||
if (underFrame) {
|
||||
@ -672,7 +672,7 @@ nsresult nsMathMLmunderoverFrame::Place(DrawTarget* aDrawTarget,
|
||||
mReference.x = 0;
|
||||
mReference.y = aDesiredSize.BlockStartAscent();
|
||||
|
||||
if (aPlaceOrigin) {
|
||||
if (!aFlags.contains(PlaceFlag::MeasureOnly)) {
|
||||
nscoord dy;
|
||||
// place overscript
|
||||
if (overFrame) {
|
||||
|
@ -27,7 +27,7 @@ class nsMathMLmunderoverFrame final : public nsMathMLContainerFrame,
|
||||
friend nsIFrame* NS_NewMathMLmunderoverFrame(mozilla::PresShell* aPresShell,
|
||||
ComputedStyle* aStyle);
|
||||
|
||||
nsresult Place(DrawTarget* aDrawTarget, bool aPlaceOrigin,
|
||||
nsresult Place(DrawTarget* aDrawTarget, const PlaceFlags& aFlags,
|
||||
ReflowOutput& aDesiredSize) override;
|
||||
|
||||
NS_IMETHOD InheritAutomaticData(nsIFrame* aParent) override;
|
||||
|
Loading…
Reference in New Issue
Block a user