/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
eMathMLFrameType nsMathMLmfracFrame::GetMathMLFrameType() { // frac is "inner" in TeXBook, Appendix G, rule 15e. See also page 170. return eMathMLFrameType_Inner;
}
NS_IMETHODIMP
nsMathMLmfracFrame::TransmitAutomaticData() { // The TeXbook (Ch 17. p.141) says the numerator inherits the compression // while the denominator is compressed
UpdatePresentationDataFromChildAt(1, 1, NS_MATHML_COMPRESSED,
NS_MATHML_COMPRESSED);
// If displaystyle is false, then scriptlevel is incremented, so notify the // children of this. if (StyleFont()->mMathStyle == StyleMathStyle::Compact) {
PropagateFrameFlagFor(mFrames.FirstChild(),
NS_FRAME_MATHML_SCRIPT_DESCENDANT);
PropagateFrameFlagFor(mFrames.LastChild(),
NS_FRAME_MATHML_SCRIPT_DESCENDANT);
}
// if our numerator is an embellished operator, let its state bubble to us
GetEmbellishDataFrom(mFrames.FirstChild(), mEmbellishData); if (NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData.flags)) { // even when embellished, we need to record that <mfrac> won't fire // Stretch() on its embellished child
mEmbellishData.direction = NS_STRETCH_DIRECTION_UNSUPPORTED;
}
// linethickness // https://w3c.github.io/mathml-core/#dfn-linethickness if (!aThicknessAttribute.IsEmpty()) {
lineThickness = defaultThickness;
ParseNumericValue(aThicknessAttribute, &lineThickness,
dom::MathMLElement::PARSE_ALLOW_NEGATIVE, aPresContext,
aComputedStyle, aFontSizeInflation); // MathML Core says a negative value is interpreted as 0. if (lineThickness < 0) {
lineThickness = 0;
}
} // use minimum if the lineThickness is a non-zero value less than minimun if (lineThickness && lineThickness < minimumThickness) {
lineThickness = minimumThickness;
}
return lineThickness;
}
void nsMathMLmfracFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsDisplayListSet& aLists) { ///////////// // paint the numerator and denominator
nsMathMLContainerFrame::BuildDisplayList(aBuilder, aLists);
///////////// // paint the fraction line
DisplayBar(aBuilder, this, mLineRect, aLists);
}
nsresult nsMathMLmfracFrame::AttributeChanged(int32_t aNameSpaceID,
nsAtom* aAttribute,
int32_t aModType) { if (aNameSpaceID == kNameSpaceID_None &&
nsGkAtoms::linethickness_ == aAttribute) { // The thickness changes, so a repaint of the bar is needed.
InvalidateFrame(); // The thickness affects vertical offsets.
PresShell()->FrameNeedsReflow(this, IntrinsicDirty::None,
NS_FRAME_IS_DIRTY); return NS_OK;
} return nsMathMLContainerFrame::AttributeChanged(aNameSpaceID, aAttribute,
aModType);
}
nscoord nsMathMLmfracFrame::FixInterFrameSpacing(ReflowOutput& aDesiredSize) {
nscoord gap = nsMathMLContainerFrame::FixInterFrameSpacing(aDesiredSize); if (!gap) { return 0;
}
mLineRect.MoveBy(gap, 0); return gap;
}
/* virtual */
nsresult nsMathMLmfracFrame::Place(DrawTarget* aDrawTarget, const PlaceFlags& aFlags,
ReflowOutput& aDesiredSize) { //////////////////////////////////// // Get the children's desired sizes
nsBoundingMetrics bmNum, bmDen;
ReflowOutput sizeNum(aDesiredSize.GetWritingMode());
ReflowOutput sizeDen(aDesiredSize.GetWritingMode());
nsIFrame* frameDen = nullptr;
nsIFrame* frameNum = mFrames.FirstChild(); if (frameNum) {
frameDen = frameNum->GetNextSibling();
} if (!frameNum || !frameDen || frameDen->GetNextSibling()) { // report an error, encourage people to get their markups in order if (!aFlags.contains(PlaceFlag::MeasureOnly)) {
ReportChildCountError();
} return PlaceAsMrow(aDrawTarget, aFlags, aDesiredSize);
}
GetReflowAndBoundingMetricsFor(frameNum, sizeNum, bmNum);
GetReflowAndBoundingMetricsFor(frameDen, sizeDen, bmDen);
// see if the linethickness attribute is there
nsAutoString value;
mContent->AsElement()->GetAttr(nsGkAtoms::linethickness_, value);
mLineThickness =
CalcLineThickness(presContext, mComputedStyle, value, onePixel,
defaultRuleThickness, fontSizeInflation);
// Add lspace & rspace that may come from <mo> if we are an outermost // embellished container (we fetch values from the core since they may use // units that depend on style data, and style changes could have occurred // in the core since our last visit there)
nscoord leftSpace = 0;
nscoord rightSpace = 0; if (outermostEmbellished) { constbool isRTL = StyleVisibility()->mDirection == StyleDirection::Rtl;
nsEmbellishData coreData;
GetEmbellishDataFrom(mEmbellishData.coreFrame, coreData);
leftSpace += isRTL ? coreData.trailingSpace : coreData.leadingSpace;
rightSpace += isRTL ? coreData.leadingSpace : coreData.trailingSpace;
}
// min clearance between numerator or denominator and middle of bar
// TeX has a different interpretation of the thickness. // Try $a \above10pt b$ to see. Here is what TeX does: // minClearance = displayStyle ? // 3 * actualRuleThickness : actualRuleThickness;
// we slightly depart from TeX here. We use the defaultRuleThickness // instead of the value coming from the linethickness attribute, i.e., we // recover what TeX does if the user hasn't set linethickness. But when // the linethickness is set, we avoid the wide gap problem.
nscoord minClearanceNum = displayStyle ? 3 * defaultRuleThickness
: defaultRuleThickness + onePixel;
nscoord minClearanceDen = minClearanceNum; if (mathFont) {
minClearanceNum = mathFont->MathTable()->Constant(
displayStyle ? gfxMathTable::FractionNumDisplayStyleGapMin
: gfxMathTable::FractionNumeratorGapMin,
oneDevPixel);
minClearanceDen = mathFont->MathTable()->Constant(
displayStyle ? gfxMathTable::FractionDenomDisplayStyleGapMin
: gfxMathTable::FractionDenominatorGapMin,
oneDevPixel);
}
// Apply width/height to math content box. auto sizes = GetWidthAndHeightForPlaceAdjustment(aFlags); auto shiftX = ApplyAdjustmentForWidthAndHeight(aFlags, sizes, aDesiredSize,
mBoundingMetrics); if (sizes.width) { // MathML Core says the math content box is horizontally centered // but the fraction bar still takes the full width of the content box.
dxNum += shiftX;
dxDen += shiftX;
width = *sizes.width;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.