michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsMathMLmspaceFrame.h" michael@0: #include "nsMathMLElement.h" michael@0: #include "mozilla/gfx/2D.h" michael@0: #include michael@0: michael@0: michael@0: // michael@0: // -- space - implementation michael@0: // michael@0: michael@0: nsIFrame* michael@0: NS_NewMathMLmspaceFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) michael@0: { michael@0: return new (aPresShell) nsMathMLmspaceFrame(aContext); michael@0: } michael@0: michael@0: NS_IMPL_FRAMEARENA_HELPERS(nsMathMLmspaceFrame) michael@0: michael@0: nsMathMLmspaceFrame::~nsMathMLmspaceFrame() michael@0: { michael@0: } michael@0: michael@0: bool michael@0: nsMathMLmspaceFrame::IsLeaf() const michael@0: { michael@0: return true; michael@0: } michael@0: michael@0: void michael@0: nsMathMLmspaceFrame::ProcessAttributes(nsPresContext* aPresContext) michael@0: { michael@0: nsAutoString value; michael@0: michael@0: // width michael@0: // michael@0: // "Specifies the desired width of the space." michael@0: // michael@0: // values: length michael@0: // default: 0em michael@0: // michael@0: // The default value is "0em", so unitless values can be ignored. michael@0: // is listed among MathML elements allowing negative spacing and michael@0: // the MathML test suite contains "Presentation/TokenElements/mspace/mspace2" michael@0: // as an example. Hence we allow negative values. michael@0: // michael@0: mWidth = 0; michael@0: mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::width, value); michael@0: if (!value.IsEmpty()) { michael@0: ParseNumericValue(value, &mWidth, michael@0: nsMathMLElement::PARSE_ALLOW_NEGATIVE, michael@0: aPresContext, mStyleContext); michael@0: } michael@0: michael@0: // height michael@0: // michael@0: // "Specifies the desired height (above the baseline) of the space." michael@0: // michael@0: // values: length michael@0: // default: 0ex michael@0: // michael@0: // The default value is "0ex", so unitless values can be ignored. michael@0: // We do not allow negative values. See bug 716349. michael@0: // michael@0: mHeight = 0; michael@0: mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::height, value); michael@0: if (!value.IsEmpty()) { michael@0: ParseNumericValue(value, &mHeight, 0, michael@0: aPresContext, mStyleContext); michael@0: } michael@0: michael@0: // depth michael@0: // michael@0: // "Specifies the desired depth (below the baseline) of the space." michael@0: // michael@0: // values: length michael@0: // default: 0ex michael@0: // michael@0: // The default value is "0ex", so unitless values can be ignored. michael@0: // We do not allow negative values. See bug 716349. michael@0: // michael@0: mDepth = 0; michael@0: mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::depth_, value); michael@0: if (!value.IsEmpty()) { michael@0: ParseNumericValue(value, &mDepth, 0, michael@0: aPresContext, mStyleContext); michael@0: } michael@0: } michael@0: michael@0: nsresult michael@0: nsMathMLmspaceFrame::Reflow(nsPresContext* aPresContext, michael@0: nsHTMLReflowMetrics& aDesiredSize, michael@0: const nsHTMLReflowState& aReflowState, michael@0: nsReflowStatus& aStatus) michael@0: { michael@0: ProcessAttributes(aPresContext); michael@0: michael@0: mBoundingMetrics = nsBoundingMetrics(); michael@0: mBoundingMetrics.width = mWidth; michael@0: mBoundingMetrics.ascent = mHeight; michael@0: mBoundingMetrics.descent = mDepth; michael@0: mBoundingMetrics.leftBearing = 0; michael@0: mBoundingMetrics.rightBearing = mBoundingMetrics.width; michael@0: michael@0: aDesiredSize.SetTopAscent(mHeight); michael@0: aDesiredSize.Width() = std::max(0, mBoundingMetrics.width); michael@0: aDesiredSize.Height() = aDesiredSize.TopAscent() + mDepth; michael@0: // Also return our bounding metrics michael@0: aDesiredSize.mBoundingMetrics = mBoundingMetrics; michael@0: michael@0: aStatus = NS_FRAME_COMPLETE; michael@0: NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* virtual */ nsresult michael@0: nsMathMLmspaceFrame::MeasureForWidth(nsRenderingContext& aRenderingContext, michael@0: nsHTMLReflowMetrics& aDesiredSize) michael@0: { michael@0: ProcessAttributes(PresContext()); michael@0: mBoundingMetrics = nsBoundingMetrics(); michael@0: mBoundingMetrics.width = mWidth; michael@0: aDesiredSize.Width() = std::max(0, mBoundingMetrics.width); michael@0: aDesiredSize.mBoundingMetrics = mBoundingMetrics; michael@0: return NS_OK; michael@0: }