Backed out 2 changesets (bug 1943998) for causing wd failures @ phases.py CLOSED...
[gecko.git] / layout / mathml / nsMathMLmspaceFrame.cpp
blobed4945ed4605c7980739fcec0647432d22766513
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "nsMathMLmspaceFrame.h"
9 #include "mozilla/dom/MathMLElement.h"
10 #include "mozilla/PresShell.h"
11 #include "mozilla/gfx/2D.h"
12 #include "nsLayoutUtils.h"
13 #include <algorithm>
15 using namespace mozilla;
18 // <mspace> -- space - implementation
21 nsIFrame* NS_NewMathMLmspaceFrame(PresShell* aPresShell,
22 ComputedStyle* aStyle) {
23 return new (aPresShell)
24 nsMathMLmspaceFrame(aStyle, aPresShell->GetPresContext());
27 NS_IMPL_FRAMEARENA_HELPERS(nsMathMLmspaceFrame)
29 nsMathMLmspaceFrame::~nsMathMLmspaceFrame() = default;
31 nsresult nsMathMLmspaceFrame::AttributeChanged(int32_t aNameSpaceID,
32 nsAtom* aAttribute,
33 int32_t aModType) {
34 if (aNameSpaceID == kNameSpaceID_None) {
35 bool hasDirtyAttributes = false;
36 IntrinsicDirty intrinsicDirty = IntrinsicDirty::None;
37 if (aAttribute == nsGkAtoms::width) {
38 mWidth.mState = Attribute::ParsingState::Dirty;
39 hasDirtyAttributes = true;
40 intrinsicDirty = IntrinsicDirty::FrameAndAncestors;
41 } else if (aAttribute == nsGkAtoms::height) {
42 mHeight.mState = Attribute::ParsingState::Dirty;
43 hasDirtyAttributes = true;
44 } else if (aAttribute == nsGkAtoms::depth_) {
45 mDepth.mState = Attribute::ParsingState::Dirty;
46 hasDirtyAttributes = true;
48 if (hasDirtyAttributes) {
49 PresShell()->FrameNeedsReflow(this, intrinsicDirty, NS_FRAME_IS_DIRTY);
51 return NS_OK;
53 return nsMathMLContainerFrame::AttributeChanged(aNameSpaceID, aAttribute,
54 aModType);
57 nscoord nsMathMLmspaceFrame::CalculateAttributeValue(nsAtom* aAtom,
58 Attribute& aAttribute,
59 uint32_t aFlags,
60 float aFontSizeInflation) {
61 if (aAttribute.mState == Attribute::ParsingState::Dirty) {
62 nsAutoString value;
63 aAttribute.mState = Attribute::ParsingState::Invalid;
64 mContent->AsElement()->GetAttr(aAtom, value);
65 if (!value.IsEmpty()) {
66 if (dom::MathMLElement::ParseNumericValue(
67 value, aAttribute.mValue, aFlags, PresContext()->Document())) {
68 aAttribute.mState = Attribute::ParsingState::Valid;
69 } else {
70 ReportParseError(aAtom->GetUTF16String(), value.get());
74 // Invalid is interpreted as the default which is 0.
75 // Percentages are interpreted as a multiple of the default value.
76 if (aAttribute.mState == Attribute::ParsingState::Invalid ||
77 aAttribute.mValue.GetUnit() == eCSSUnit_Percent) {
78 return 0;
80 return CalcLength(PresContext(), mComputedStyle, aAttribute.mValue,
81 aFontSizeInflation);
84 nsresult nsMathMLmspaceFrame::Place(DrawTarget* aDrawTarget,
85 const PlaceFlags& aFlags,
86 ReflowOutput& aDesiredSize) {
87 float fontSizeInflation = nsLayoutUtils::FontSizeInflationFor(this);
89 // <mspace/> is listed among MathML elements allowing negative spacing and
90 // the MathML test suite contains "Presentation/TokenElements/mspace/mspace2"
91 // as an example. Hence we allow negative values.
92 nscoord width = CalculateAttributeValue(
93 nsGkAtoms::width, mWidth, dom::MathMLElement::PARSE_ALLOW_NEGATIVE,
94 fontSizeInflation);
96 // We do not allow negative values for height and depth attributes. See bug
97 // 716349.
98 nscoord height =
99 CalculateAttributeValue(nsGkAtoms::height, mHeight, 0, fontSizeInflation);
100 nscoord depth =
101 CalculateAttributeValue(nsGkAtoms::depth_, mDepth, 0, fontSizeInflation);
103 mBoundingMetrics = nsBoundingMetrics();
104 mBoundingMetrics.width = width;
105 mBoundingMetrics.ascent = height;
106 mBoundingMetrics.descent = depth;
107 mBoundingMetrics.leftBearing = 0;
108 mBoundingMetrics.rightBearing = mBoundingMetrics.width;
110 aDesiredSize.SetBlockStartAscent(mBoundingMetrics.ascent);
111 aDesiredSize.Width() = std::max(0, mBoundingMetrics.width);
112 aDesiredSize.Height() = mBoundingMetrics.ascent + mBoundingMetrics.descent;
113 // Also return our bounding metrics
114 aDesiredSize.mBoundingMetrics = mBoundingMetrics;
116 // Apply width/height to math content box.
117 const PlaceFlags flags;
118 auto sizes = GetWidthAndHeightForPlaceAdjustment(flags);
119 ApplyAdjustmentForWidthAndHeight(flags, sizes, aDesiredSize,
120 mBoundingMetrics);
122 // Add padding+border.
123 auto borderPadding = GetBorderPaddingForPlace(aFlags);
124 InflateReflowAndBoundingMetrics(borderPadding, aDesiredSize,
125 mBoundingMetrics);
126 return NS_OK;