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