Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #include "nsMathMLmspaceFrame.h"
7 : #include "nsMathMLElement.h"
8 : #include "mozilla/gfx/2D.h"
9 : #include <algorithm>
10 :
11 :
12 : //
13 : // <mspace> -- space - implementation
14 : //
15 :
16 : nsIFrame*
17 0 : NS_NewMathMLmspaceFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
18 : {
19 0 : return new (aPresShell) nsMathMLmspaceFrame(aContext);
20 : }
21 :
22 0 : NS_IMPL_FRAMEARENA_HELPERS(nsMathMLmspaceFrame)
23 :
24 0 : nsMathMLmspaceFrame::~nsMathMLmspaceFrame()
25 : {
26 0 : }
27 :
28 : void
29 0 : nsMathMLmspaceFrame::ProcessAttributes(nsPresContext* aPresContext)
30 : {
31 0 : nsAutoString value;
32 0 : float fontSizeInflation = nsLayoutUtils::FontSizeInflationFor(this);
33 :
34 : // width
35 : //
36 : // "Specifies the desired width of the space."
37 : //
38 : // values: length
39 : // default: 0em
40 : //
41 : // The default value is "0em", so unitless values can be ignored.
42 : // <mspace/> is listed among MathML elements allowing negative spacing and
43 : // the MathML test suite contains "Presentation/TokenElements/mspace/mspace2"
44 : // as an example. Hence we allow negative values.
45 : //
46 0 : mWidth = 0;
47 0 : mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::width, value);
48 0 : if (!value.IsEmpty()) {
49 0 : ParseNumericValue(value, &mWidth,
50 : nsMathMLElement::PARSE_ALLOW_NEGATIVE,
51 0 : aPresContext, mStyleContext, fontSizeInflation);
52 : }
53 :
54 : // height
55 : //
56 : // "Specifies the desired height (above the baseline) of the space."
57 : //
58 : // values: length
59 : // default: 0ex
60 : //
61 : // The default value is "0ex", so unitless values can be ignored.
62 : // We do not allow negative values. See bug 716349.
63 : //
64 0 : mHeight = 0;
65 0 : mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::height, value);
66 0 : if (!value.IsEmpty()) {
67 0 : ParseNumericValue(value, &mHeight, 0,
68 0 : aPresContext, mStyleContext, fontSizeInflation);
69 : }
70 :
71 : // depth
72 : //
73 : // "Specifies the desired depth (below the baseline) of the space."
74 : //
75 : // values: length
76 : // default: 0ex
77 : //
78 : // The default value is "0ex", so unitless values can be ignored.
79 : // We do not allow negative values. See bug 716349.
80 : //
81 0 : mDepth = 0;
82 0 : mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::depth_, value);
83 0 : if (!value.IsEmpty()) {
84 0 : ParseNumericValue(value, &mDepth, 0,
85 0 : aPresContext, mStyleContext, fontSizeInflation);
86 : }
87 0 : }
88 :
89 : void
90 0 : nsMathMLmspaceFrame::Reflow(nsPresContext* aPresContext,
91 : ReflowOutput& aDesiredSize,
92 : const ReflowInput& aReflowInput,
93 : nsReflowStatus& aStatus)
94 : {
95 0 : MarkInReflow();
96 0 : mPresentationData.flags &= ~NS_MATHML_ERROR;
97 0 : ProcessAttributes(aPresContext);
98 :
99 0 : mBoundingMetrics = nsBoundingMetrics();
100 0 : mBoundingMetrics.width = mWidth;
101 0 : mBoundingMetrics.ascent = mHeight;
102 0 : mBoundingMetrics.descent = mDepth;
103 0 : mBoundingMetrics.leftBearing = 0;
104 0 : mBoundingMetrics.rightBearing = mBoundingMetrics.width;
105 :
106 0 : aDesiredSize.SetBlockStartAscent(mHeight);
107 0 : aDesiredSize.Width() = std::max(0, mBoundingMetrics.width);
108 0 : aDesiredSize.Height() = aDesiredSize.BlockStartAscent() + mDepth;
109 : // Also return our bounding metrics
110 0 : aDesiredSize.mBoundingMetrics = mBoundingMetrics;
111 :
112 0 : aStatus.Reset();
113 0 : NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize);
114 0 : }
115 :
116 : /* virtual */ nsresult
117 0 : nsMathMLmspaceFrame::MeasureForWidth(DrawTarget* aDrawTarget,
118 : ReflowOutput& aDesiredSize)
119 : {
120 0 : ProcessAttributes(PresContext());
121 0 : mBoundingMetrics = nsBoundingMetrics();
122 0 : mBoundingMetrics.width = mWidth;
123 0 : aDesiredSize.Width() = std::max(0, mBoundingMetrics.width);
124 0 : aDesiredSize.mBoundingMetrics = mBoundingMetrics;
125 0 : return NS_OK;
126 : }
|