/src/mozilla-central/layout/mathml/nsMathMLSelectedFrame.cpp
Line | Count | Source (jump to first uncovered line) |
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/. */ |
6 | | |
7 | | #include "nsMathMLSelectedFrame.h" |
8 | | #include "nsDisplayList.h" |
9 | | |
10 | | using namespace mozilla; |
11 | | |
12 | | nsMathMLSelectedFrame::~nsMathMLSelectedFrame() |
13 | 0 | { |
14 | 0 | } |
15 | | |
16 | | NS_IMETHODIMP |
17 | | nsMathMLSelectedFrame::TransmitAutomaticData() |
18 | 0 | { |
19 | 0 | // Note that to determine space-like and embellished op properties: |
20 | 0 | // - <semantics> behaves the same as <maction> |
21 | 0 | // - <annotation-xml> behaves the same as <mrow> |
22 | 0 |
|
23 | 0 | // The REC defines the following element to be space-like: |
24 | 0 | // * an maction element whose selected sub-expression exists and is |
25 | 0 | // space-like; |
26 | 0 | nsIMathMLFrame* mathMLFrame = do_QueryFrame(mSelectedFrame); |
27 | 0 | if (mathMLFrame && mathMLFrame->IsSpaceLike()) { |
28 | 0 | mPresentationData.flags |= NS_MATHML_SPACE_LIKE; |
29 | 0 | } else { |
30 | 0 | mPresentationData.flags &= ~NS_MATHML_SPACE_LIKE; |
31 | 0 | } |
32 | 0 |
|
33 | 0 | // The REC defines the following element to be an embellished operator: |
34 | 0 | // * an maction element whose selected sub-expression exists and is an |
35 | 0 | // embellished operator; |
36 | 0 | mPresentationData.baseFrame = mSelectedFrame; |
37 | 0 | GetEmbellishDataFrom(mSelectedFrame, mEmbellishData); |
38 | 0 |
|
39 | 0 | return NS_OK; |
40 | 0 | } |
41 | | |
42 | | nsresult |
43 | | nsMathMLSelectedFrame::ChildListChanged(int32_t aModType) |
44 | 0 | { |
45 | 0 | GetSelectedFrame(); |
46 | 0 | return nsMathMLContainerFrame::ChildListChanged(aModType); |
47 | 0 | } |
48 | | |
49 | | void |
50 | | nsMathMLSelectedFrame::SetInitialChildList(ChildListID aListID, |
51 | | nsFrameList& aChildList) |
52 | 0 | { |
53 | 0 | nsMathMLContainerFrame::SetInitialChildList(aListID, aChildList); |
54 | 0 | // This very first call to GetSelectedFrame() will cause us to be marked as an |
55 | 0 | // embellished operator if the selected child is an embellished operator |
56 | 0 | GetSelectedFrame(); |
57 | 0 | } |
58 | | |
59 | | // Only paint the selected child... |
60 | | void |
61 | | nsMathMLSelectedFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, |
62 | | const nsDisplayListSet& aLists) |
63 | 0 | { |
64 | 0 | // Report an error if something wrong was found in this frame. |
65 | 0 | // We can't call nsDisplayMathMLError from here, |
66 | 0 | // so ask nsMathMLContainerFrame to do the work for us. |
67 | 0 | if (NS_MATHML_HAS_ERROR(mPresentationData.flags)) { |
68 | 0 | nsMathMLContainerFrame::BuildDisplayList(aBuilder, aLists); |
69 | 0 | return; |
70 | 0 | } |
71 | 0 | |
72 | 0 | DisplayBorderBackgroundOutline(aBuilder, aLists); |
73 | 0 |
|
74 | 0 | nsIFrame* childFrame = GetSelectedFrame(); |
75 | 0 | if (childFrame) { |
76 | 0 | // Put the child's background directly onto the content list |
77 | 0 | nsDisplayListSet set(aLists, aLists.Content()); |
78 | 0 | // The children should be in content order |
79 | 0 | BuildDisplayListForChild(aBuilder, childFrame, set); |
80 | 0 | } |
81 | 0 |
|
82 | | #if defined(DEBUG) && defined(SHOW_BOUNDING_BOX) |
83 | | // visual debug |
84 | | DisplayBoundingMetrics(aBuilder, this, mReference, mBoundingMetrics, aLists); |
85 | | #endif |
86 | | } |
87 | | |
88 | | /* virtual */ |
89 | | LogicalSize |
90 | | nsMathMLSelectedFrame::ComputeSize(gfxContext *aRenderingContext, |
91 | | WritingMode aWM, |
92 | | const LogicalSize& aCBSize, |
93 | | nscoord aAvailableISize, |
94 | | const LogicalSize& aMargin, |
95 | | const LogicalSize& aBorder, |
96 | | const LogicalSize& aPadding, |
97 | | ComputeSizeFlags aFlags) |
98 | 0 | { |
99 | 0 | nsIFrame* childFrame = GetSelectedFrame(); |
100 | 0 | if (childFrame) { |
101 | 0 | // Delegate size computation to the child frame. |
102 | 0 | // Try to account for border/padding/margin on this frame and the child, |
103 | 0 | // though we don't really support them during reflow anyway... |
104 | 0 | nscoord availableISize = aAvailableISize - aBorder.ISize(aWM) - |
105 | 0 | aPadding.ISize(aWM) - aMargin.ISize(aWM); |
106 | 0 | LogicalSize cbSize = aCBSize - aBorder - aPadding - aMargin; |
107 | 0 | SizeComputationInput offsetState(childFrame, aRenderingContext, aWM, |
108 | 0 | availableISize); |
109 | 0 | LogicalSize size = |
110 | 0 | childFrame->ComputeSize(aRenderingContext, aWM, cbSize, |
111 | 0 | availableISize, offsetState.ComputedLogicalMargin().Size(aWM), |
112 | 0 | offsetState.ComputedLogicalBorderPadding().Size(aWM) - |
113 | 0 | offsetState.ComputedLogicalPadding().Size(aWM), |
114 | 0 | offsetState.ComputedLogicalPadding().Size(aWM), |
115 | 0 | aFlags); |
116 | 0 | return size + offsetState.ComputedLogicalBorderPadding().Size(aWM); |
117 | 0 | } |
118 | 0 | return LogicalSize(aWM); |
119 | 0 | } |
120 | | |
121 | | // Only reflow the selected child ... |
122 | | void |
123 | | nsMathMLSelectedFrame::Reflow(nsPresContext* aPresContext, |
124 | | ReflowOutput& aDesiredSize, |
125 | | const ReflowInput& aReflowInput, |
126 | | nsReflowStatus& aStatus) |
127 | 0 | { |
128 | 0 | MarkInReflow(); |
129 | 0 | MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!"); |
130 | 0 |
|
131 | 0 | mPresentationData.flags &= ~NS_MATHML_ERROR; |
132 | 0 | aDesiredSize.ClearSize(); |
133 | 0 | aDesiredSize.SetBlockStartAscent(0); |
134 | 0 | mBoundingMetrics = nsBoundingMetrics(); |
135 | 0 | nsIFrame* childFrame = GetSelectedFrame(); |
136 | 0 | if (childFrame) { |
137 | 0 | WritingMode wm = childFrame->GetWritingMode(); |
138 | 0 | LogicalSize availSize = aReflowInput.ComputedSize(wm); |
139 | 0 | availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE; |
140 | 0 | ReflowInput childReflowInput(aPresContext, aReflowInput, |
141 | 0 | childFrame, availSize); |
142 | 0 | ReflowChild(childFrame, aPresContext, aDesiredSize, |
143 | 0 | childReflowInput, aStatus); |
144 | 0 | SaveReflowAndBoundingMetricsFor(childFrame, aDesiredSize, |
145 | 0 | aDesiredSize.mBoundingMetrics); |
146 | 0 | mBoundingMetrics = aDesiredSize.mBoundingMetrics; |
147 | 0 | } |
148 | 0 | FinalizeReflow(aReflowInput.mRenderingContext->GetDrawTarget(), aDesiredSize); |
149 | 0 | NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize); |
150 | 0 | } |
151 | | |
152 | | // Only place the selected child ... |
153 | | /* virtual */ nsresult |
154 | | nsMathMLSelectedFrame::Place(DrawTarget* aDrawTarget, |
155 | | bool aPlaceOrigin, |
156 | | ReflowOutput& aDesiredSize) |
157 | 0 | { |
158 | 0 | nsIFrame* childFrame = GetSelectedFrame(); |
159 | 0 |
|
160 | 0 | if (mInvalidMarkup) { |
161 | 0 | return ReflowError(aDrawTarget, aDesiredSize); |
162 | 0 | } |
163 | 0 | |
164 | 0 | aDesiredSize.ClearSize(); |
165 | 0 | aDesiredSize.SetBlockStartAscent(0); |
166 | 0 | mBoundingMetrics = nsBoundingMetrics(); |
167 | 0 | if (childFrame) { |
168 | 0 | GetReflowAndBoundingMetricsFor(childFrame, aDesiredSize, mBoundingMetrics); |
169 | 0 | if (aPlaceOrigin) { |
170 | 0 | FinishReflowChild(childFrame, PresContext(), aDesiredSize, nullptr, 0, 0, 0); |
171 | 0 | } |
172 | 0 | mReference.x = 0; |
173 | 0 | mReference.y = aDesiredSize.BlockStartAscent(); |
174 | 0 | } |
175 | 0 | aDesiredSize.mBoundingMetrics = mBoundingMetrics; |
176 | 0 | return NS_OK; |
177 | 0 | } |