summaryrefslogtreecommitdiffstats
path: root/layout/mathml/nsMathMLmspaceFrame.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'layout/mathml/nsMathMLmspaceFrame.cpp')
-rw-r--r--layout/mathml/nsMathMLmspaceFrame.cpp124
1 files changed, 124 insertions, 0 deletions
diff --git a/layout/mathml/nsMathMLmspaceFrame.cpp b/layout/mathml/nsMathMLmspaceFrame.cpp
new file mode 100644
index 0000000000..9b6e54ae13
--- /dev/null
+++ b/layout/mathml/nsMathMLmspaceFrame.cpp
@@ -0,0 +1,124 @@
+/* -*- 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/. */
+
+#include "nsMathMLmspaceFrame.h"
+
+#include "mozilla/dom/MathMLElement.h"
+#include "mozilla/PresShell.h"
+#include "mozilla/gfx/2D.h"
+#include "nsLayoutUtils.h"
+#include <algorithm>
+
+using namespace mozilla;
+
+//
+// <mspace> -- space - implementation
+//
+
+nsIFrame* NS_NewMathMLmspaceFrame(PresShell* aPresShell,
+ ComputedStyle* aStyle) {
+ return new (aPresShell)
+ nsMathMLmspaceFrame(aStyle, aPresShell->GetPresContext());
+}
+
+NS_IMPL_FRAMEARENA_HELPERS(nsMathMLmspaceFrame)
+
+nsMathMLmspaceFrame::~nsMathMLmspaceFrame() = default;
+
+void nsMathMLmspaceFrame::ProcessAttributes(nsPresContext* aPresContext) {
+ nsAutoString value;
+ float fontSizeInflation = nsLayoutUtils::FontSizeInflationFor(this);
+
+ // width
+ //
+ // "Specifies the desired width of the space."
+ //
+ // values: length
+ // default: 0em
+ //
+ // The default value is "0em", so unitless values can be ignored.
+ // <mspace/> is listed among MathML elements allowing negative spacing and
+ // the MathML test suite contains "Presentation/TokenElements/mspace/mspace2"
+ // as an example. Hence we allow negative values.
+ //
+ mWidth = 0;
+ mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::width, value);
+ if (!value.IsEmpty()) {
+ ParseNumericValue(value, &mWidth, dom::MathMLElement::PARSE_ALLOW_NEGATIVE,
+ aPresContext, mComputedStyle, fontSizeInflation);
+ }
+
+ // height
+ //
+ // "Specifies the desired height (above the baseline) of the space."
+ //
+ // values: length
+ // default: 0ex
+ //
+ // The default value is "0ex", so unitless values can be ignored.
+ // We do not allow negative values. See bug 716349.
+ //
+ mHeight = 0;
+ mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::height, value);
+ if (!value.IsEmpty()) {
+ ParseNumericValue(value, &mHeight, 0, aPresContext, mComputedStyle,
+ fontSizeInflation);
+ }
+
+ // depth
+ //
+ // "Specifies the desired depth (below the baseline) of the space."
+ //
+ // values: length
+ // default: 0ex
+ //
+ // The default value is "0ex", so unitless values can be ignored.
+ // We do not allow negative values. See bug 716349.
+ //
+ mDepth = 0;
+ mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::depth_, value);
+ if (!value.IsEmpty()) {
+ ParseNumericValue(value, &mDepth, 0, aPresContext, mComputedStyle,
+ fontSizeInflation);
+ }
+}
+
+void nsMathMLmspaceFrame::Reflow(nsPresContext* aPresContext,
+ ReflowOutput& aDesiredSize,
+ const ReflowInput& aReflowInput,
+ nsReflowStatus& aStatus) {
+ MarkInReflow();
+ MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
+
+ mPresentationData.flags &= ~NS_MATHML_ERROR;
+ ProcessAttributes(aPresContext);
+
+ auto borderPadding = aReflowInput.ComputedPhysicalBorderPadding();
+ mBoundingMetrics = nsBoundingMetrics();
+ mBoundingMetrics.width = mWidth + borderPadding.LeftRight();
+ mBoundingMetrics.ascent = mHeight + borderPadding.Side(eSideTop);
+ mBoundingMetrics.descent = mDepth + borderPadding.Side(eSideBottom);
+ mBoundingMetrics.leftBearing = 0;
+ mBoundingMetrics.rightBearing = mBoundingMetrics.width;
+
+ aDesiredSize.SetBlockStartAscent(mBoundingMetrics.ascent);
+ aDesiredSize.Width() = std::max(0, mBoundingMetrics.width);
+ aDesiredSize.Height() = mBoundingMetrics.ascent + mBoundingMetrics.descent;
+ // Also return our bounding metrics
+ aDesiredSize.mBoundingMetrics = mBoundingMetrics;
+}
+
+/* virtual */
+nsresult nsMathMLmspaceFrame::MeasureForWidth(DrawTarget* aDrawTarget,
+ ReflowOutput& aDesiredSize) {
+ ProcessAttributes(PresContext());
+ mBoundingMetrics = nsBoundingMetrics();
+ auto offsets = IntrinsicISizeOffsets();
+ mBoundingMetrics.width = mWidth + offsets.padding + offsets.border;
+ aDesiredSize.Width() = std::max(0, mBoundingMetrics.width);
+ aDesiredSize.mBoundingMetrics = mBoundingMetrics;
+ return NS_OK;
+}