layout/mathml/nsMathMLSelectedFrame.cpp

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:2def3cc0fe7a
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 "nsMathMLSelectedFrame.h"
7 #include "nsDisplayList.h"
8
9 nsMathMLSelectedFrame::~nsMathMLSelectedFrame()
10 {
11 }
12
13 void
14 nsMathMLSelectedFrame::Init(nsIContent* aContent,
15 nsIFrame* aParent,
16 nsIFrame* aPrevInFlow)
17 {
18 // Init our local attributes
19 mInvalidMarkup = false;
20 mSelectedFrame = nullptr;
21
22 // Let the base class do the rest
23 nsMathMLContainerFrame::Init(aContent, aParent, aPrevInFlow);
24 }
25
26 NS_IMETHODIMP
27 nsMathMLSelectedFrame::TransmitAutomaticData()
28 {
29 // Note that to determine space-like and embellished op properties:
30 // - <semantics> behaves the same as <maction>
31 // - <annotation-xml> behaves the same as <mrow>
32
33 // The REC defines the following element to be space-like:
34 // * an maction element whose selected sub-expression exists and is
35 // space-like;
36 nsIMathMLFrame* mathMLFrame = do_QueryFrame(mSelectedFrame);
37 if (mathMLFrame && mathMLFrame->IsSpaceLike()) {
38 mPresentationData.flags |= NS_MATHML_SPACE_LIKE;
39 } else {
40 mPresentationData.flags &= ~NS_MATHML_SPACE_LIKE;
41 }
42
43 // The REC defines the following element to be an embellished operator:
44 // * an maction element whose selected sub-expression exists and is an
45 // embellished operator;
46 mPresentationData.baseFrame = mSelectedFrame;
47 GetEmbellishDataFrom(mSelectedFrame, mEmbellishData);
48
49 return NS_OK;
50 }
51
52 nsresult
53 nsMathMLSelectedFrame::ChildListChanged(int32_t aModType)
54 {
55 GetSelectedFrame();
56 return nsMathMLContainerFrame::ChildListChanged(aModType);
57 }
58
59 nsresult
60 nsMathMLSelectedFrame::SetInitialChildList(ChildListID aListID,
61 nsFrameList& aChildList)
62 {
63 nsresult rv = nsMathMLContainerFrame::SetInitialChildList(aListID,
64 aChildList);
65 // This very first call to GetSelectedFrame() will cause us to be marked as an
66 // embellished operator if the selected child is an embellished operator
67 GetSelectedFrame();
68 return rv;
69 }
70
71 // Only paint the selected child...
72 void
73 nsMathMLSelectedFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
74 const nsRect& aDirtyRect,
75 const nsDisplayListSet& aLists)
76 {
77 // Report an error if something wrong was found in this frame.
78 // We can't call nsDisplayMathMLError from here,
79 // so ask nsMathMLContainerFrame to do the work for us.
80 if (NS_MATHML_HAS_ERROR(mPresentationData.flags)) {
81 nsMathMLContainerFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists);
82 return;
83 }
84
85 DisplayBorderBackgroundOutline(aBuilder, aLists);
86
87 nsIFrame* childFrame = GetSelectedFrame();
88 if (childFrame) {
89 // Put the child's background directly onto the content list
90 nsDisplayListSet set(aLists, aLists.Content());
91 // The children should be in content order
92 BuildDisplayListForChild(aBuilder, childFrame, aDirtyRect, set);
93 }
94
95 #if defined(DEBUG) && defined(SHOW_BOUNDING_BOX)
96 // visual debug
97 DisplayBoundingMetrics(aBuilder, this, mReference, mBoundingMetrics, aLists);
98 #endif
99 }
100
101 // Only reflow the selected child ...
102 nsresult
103 nsMathMLSelectedFrame::Reflow(nsPresContext* aPresContext,
104 nsHTMLReflowMetrics& aDesiredSize,
105 const nsHTMLReflowState& aReflowState,
106 nsReflowStatus& aStatus)
107 {
108 nsresult rv = NS_OK;
109 aStatus = NS_FRAME_COMPLETE;
110 aDesiredSize.Width() = aDesiredSize.Height() = 0;
111 aDesiredSize.SetTopAscent(0);
112 mBoundingMetrics = nsBoundingMetrics();
113 nsIFrame* childFrame = GetSelectedFrame();
114 if (childFrame) {
115 nsSize availSize(aReflowState.ComputedWidth(), NS_UNCONSTRAINEDSIZE);
116 nsHTMLReflowState childReflowState(aPresContext, aReflowState,
117 childFrame, availSize);
118 rv = ReflowChild(childFrame, aPresContext, aDesiredSize,
119 childReflowState, aStatus);
120 SaveReflowAndBoundingMetricsFor(childFrame, aDesiredSize,
121 aDesiredSize.mBoundingMetrics);
122 mBoundingMetrics = aDesiredSize.mBoundingMetrics;
123 }
124 FinalizeReflow(*aReflowState.rendContext, aDesiredSize);
125 NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
126 return rv;
127 }
128
129 // Only place the selected child ...
130 /* virtual */ nsresult
131 nsMathMLSelectedFrame::Place(nsRenderingContext& aRenderingContext,
132 bool aPlaceOrigin,
133 nsHTMLReflowMetrics& aDesiredSize)
134 {
135 nsIFrame* childFrame = GetSelectedFrame();
136
137 if (mInvalidMarkup) {
138 return ReflowError(aRenderingContext, aDesiredSize);
139 }
140
141 aDesiredSize.Width() = aDesiredSize.Height() = 0;
142 aDesiredSize.SetTopAscent(0);
143 mBoundingMetrics = nsBoundingMetrics();
144 if (childFrame) {
145 GetReflowAndBoundingMetricsFor(childFrame, aDesiredSize, mBoundingMetrics);
146 if (aPlaceOrigin) {
147 FinishReflowChild(childFrame, PresContext(), aDesiredSize, nullptr, 0, 0, 0);
148 }
149 mReference.x = 0;
150 mReference.y = aDesiredSize.TopAscent();
151 }
152 aDesiredSize.mBoundingMetrics = mBoundingMetrics;
153 return NS_OK;
154 }

mercurial