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 : //#define SHOW_BOUNDING_BOX 1
6 : #ifndef nsIMathMLFrame_h___
7 : #define nsIMathMLFrame_h___
8 :
9 : #include "nsQueryFrame.h"
10 : #include "nsMathMLOperators.h"
11 :
12 : struct nsPresentationData;
13 : struct nsEmbellishData;
14 : class gfxContext;
15 : class nsIFrame;
16 : namespace mozilla {
17 : class ReflowOutput;
18 : } // namespace mozilla
19 :
20 : // For MathML, this 'type' will be used to determine the spacing between frames
21 : // Subclasses can return a 'type' that will give them a particular spacing
22 : enum eMathMLFrameType {
23 : eMathMLFrameType_UNKNOWN = -1,
24 : eMathMLFrameType_Ordinary,
25 : eMathMLFrameType_OperatorOrdinary,
26 : eMathMLFrameType_OperatorInvisible,
27 : eMathMLFrameType_OperatorUserDefined,
28 : eMathMLFrameType_Inner,
29 : eMathMLFrameType_ItalicIdentifier,
30 : eMathMLFrameType_UprightIdentifier,
31 : eMathMLFrameType_COUNT
32 : };
33 :
34 : // Abstract base class that provides additional methods for MathML frames
35 0 : class nsIMathMLFrame
36 : {
37 : public:
38 : NS_DECL_QUERYFRAME_TARGET(nsIMathMLFrame)
39 :
40 : // helper to check whether the frame is "space-like", as defined by the spec.
41 : virtual bool IsSpaceLike() = 0;
42 :
43 : /* SUPPORT FOR PRECISE POSITIONING */
44 : /*====================================================================*/
45 :
46 : /* Metrics that _exactly_ enclose the text of the frame.
47 : * The frame *must* have *already* being reflowed, before you can call
48 : * the GetBoundingMetrics() method.
49 : * Note that for a frame with nested children, the bounding metrics
50 : * will exactly enclose its children. For example, the bounding metrics
51 : * of msub is the smallest rectangle that exactly encloses both the
52 : * base and the subscript.
53 : */
54 : NS_IMETHOD
55 : GetBoundingMetrics(nsBoundingMetrics& aBoundingMetrics) = 0;
56 :
57 : NS_IMETHOD
58 : SetBoundingMetrics(const nsBoundingMetrics& aBoundingMetrics) = 0;
59 :
60 : NS_IMETHOD
61 : SetReference(const nsPoint& aReference) = 0;
62 :
63 : virtual eMathMLFrameType GetMathMLFrameType() = 0;
64 :
65 : /* SUPPORT FOR STRETCHY ELEMENTS */
66 : /*====================================================================*/
67 :
68 : /* Stretch :
69 : * Called to ask a stretchy MathML frame to stretch itself depending
70 : * on its context.
71 : *
72 : * An embellished frame is treated in a special way. When it receives a
73 : * Stretch() command, it passes the command to its embellished child and
74 : * the stretched size is bubbled up from the inner-most <mo> frame. In other
75 : * words, the stretch command descend through the embellished hierarchy.
76 : *
77 : * @param aStretchDirection [in] the direction where to attempt to
78 : * stretch.
79 : * @param aContainerSize [in] struct that suggests the maximumn size for
80 : * the stretched frame. Only member data of the struct that are
81 : * relevant to the direction are used (the rest is ignored).
82 : * @param aDesiredStretchSize [in/out] On input the current size
83 : * of the frame, on output the size after stretching.
84 : */
85 : NS_IMETHOD
86 : Stretch(mozilla::gfx::DrawTarget* aDrawTarget,
87 : nsStretchDirection aStretchDirection,
88 : nsBoundingMetrics& aContainerSize,
89 : mozilla::ReflowOutput& aDesiredStretchSize) = 0;
90 :
91 : /* Get the mEmbellishData member variable. */
92 :
93 : NS_IMETHOD
94 : GetEmbellishData(nsEmbellishData& aEmbellishData) = 0;
95 :
96 :
97 : /* SUPPORT FOR SCRIPTING ELEMENTS */
98 : /*====================================================================*/
99 :
100 : /* Get the mPresentationData member variable. */
101 :
102 : NS_IMETHOD
103 : GetPresentationData(nsPresentationData& aPresentationData) = 0;
104 :
105 : /* InheritAutomaticData() / TransmitAutomaticData() :
106 : * There are precise rules governing each MathML frame and its children.
107 : * Properties such as the scriptlevel or the embellished nature of a frame
108 : * depend on those rules. Also, certain properties that we use to emulate
109 : * TeX rendering rules are frame-dependent too. These two methods are meant
110 : * to be implemented by frame classes that need to assert specific properties
111 : * within their subtrees.
112 : *
113 : * InheritAutomaticData() is called in a top-down manner [like nsIFrame::Init],
114 : * as we descend the frame tree, whereas TransmitAutomaticData() is called in a
115 : * bottom-up manner, as we ascend the tree [like nsIFrame::SetInitialChildList].
116 : * However, unlike Init() and SetInitialChildList() which are called only once
117 : * during the life-time of a frame (when initially constructing the frame tree),
118 : * these two methods are called to build automatic data after the <math>...</math>
119 : * subtree has been constructed fully, and are called again as we walk a child's
120 : * subtree to handle dynamic changes that happen in the content model.
121 : *
122 : * As a rule of thumb:
123 : *
124 : * 1. Use InheritAutomaticData() to set properties related to your ancestors:
125 : * - set properties that are intrinsic to yourself
126 : * - set properties that depend on the state that you expect your ancestors
127 : * to have already reached in their own InheritAutomaticData().
128 : * - set properties that your descendants assume that you would have set in
129 : * your InheritAutomaticData() -- this way, they can safely query them and
130 : * the process will feed upon itself.
131 : *
132 : * 2. Use TransmitAutomaticData() to set properties related to your descendants:
133 : * - set properties that depend on the state that you expect your descendants
134 : * to have reached upon processing their own TransmitAutomaticData().
135 : * - transmit properties that your descendants expect that you will transmit to
136 : * them in your TransmitAutomaticData() -- this way, they remain up-to-date.
137 : * - set properties that your ancestors expect that you would set in your
138 : * TransmitAutomaticData() -- this way, they can safely query them and the
139 : * process will feed upon itself.
140 : */
141 :
142 : NS_IMETHOD
143 : InheritAutomaticData(nsIFrame* aParent) = 0;
144 :
145 : NS_IMETHOD
146 : TransmitAutomaticData() = 0;
147 :
148 : /* UpdatePresentationData:
149 : * Updates the frame's compression flag.
150 : * A frame becomes "compressed" (or "cramped") according to TeX rendering
151 : * rules (TeXBook, Ch.17, p.140-141).
152 : *
153 : * @param aFlagsValues [in]
154 : * The new values (e.g., compress) that are going to be
155 : * updated.
156 : *
157 : * @param aWhichFlags [in]
158 : * The flags that are relevant to this call. Since not all calls
159 : * are meant to update all flags at once, aWhichFlags is used
160 : * to distinguish flags that need to retain their existing values
161 : * from flags that need to be turned on (or turned off). If a bit
162 : * is set in aWhichFlags, then the corresponding value (which
163 : * can be 0 or 1) is taken from aFlagsValues and applied to the
164 : * frame. Therefore, by setting their bits in aWhichFlags, and
165 : * setting their desired values in aFlagsValues, it is possible to
166 : * update some flags in the frame, leaving the other flags unchanged.
167 : */
168 : NS_IMETHOD
169 : UpdatePresentationData(uint32_t aFlagsValues,
170 : uint32_t aWhichFlags) = 0;
171 :
172 : /* UpdatePresentationDataFromChildAt :
173 : * Sets compression flag on the whole tree. For child frames
174 : * at aFirstIndex up to aLastIndex, this method sets their
175 : * compression flags. The update is propagated down the subtrees of each of
176 : * these child frames.
177 : *
178 : * @param aFirstIndex [in]
179 : * Index of the first child from where the update is propagated.
180 : *
181 : * @param aLastIndex [in]
182 : * Index of the last child where to stop the update.
183 : * A value of -1 means up to last existing child.
184 : *
185 : * @param aFlagsValues [in]
186 : * The new values (e.g., compress) that are going to be
187 : * assigned in the whole sub-trees.
188 : *
189 : * @param aWhichFlags [in]
190 : * The flags that are relevant to this call. See UpdatePresentationData()
191 : * for more details about this parameter.
192 : */
193 : NS_IMETHOD
194 : UpdatePresentationDataFromChildAt(int32_t aFirstIndex,
195 : int32_t aLastIndex,
196 : uint32_t aFlagsValues,
197 : uint32_t aWhichFlags) = 0;
198 :
199 : // If aFrame is a child frame, returns the script increment which this frame
200 : // imposes on the specified frame, ignoring any artificial adjustments to
201 : // scriptlevel.
202 : // Returns 0 if the specified frame isn't a child frame.
203 : virtual uint8_t
204 : ScriptIncrement(nsIFrame* aFrame) = 0;
205 :
206 : // Returns true if the frame is considered to be an mrow for layout purposes.
207 : // This includes inferred mrows, but excludes <mrow> elements with a single
208 : // child. In the latter case, the child is to be treated as if it wasn't
209 : // within an mrow, so we pretend the mrow isn't mrow-like.
210 : virtual bool
211 : IsMrowLike() = 0;
212 : };
213 :
214 : // struct used by a container frame to keep track of its embellishments.
215 : // By convention, the data that we keep here is bubbled from the embellished
216 : // hierarchy, and it remains unchanged unless we have to recover from a change
217 : // that occurs in the embellished hierarchy. The struct remains in its nil
218 : // state in those frames that are not part of the embellished hierarchy.
219 : struct nsEmbellishData {
220 : // bits used to mark certain properties of our embellishments
221 : uint32_t flags;
222 :
223 : // pointer on the <mo> frame at the core of the embellished hierarchy
224 : nsIFrame* coreFrame;
225 :
226 : // stretchy direction that the nsMathMLChar owned by the core <mo> supports
227 : nsStretchDirection direction;
228 :
229 : // spacing that may come from <mo> depending on its 'form'. Since
230 : // the 'form' may also depend on the position of the outermost
231 : // embellished ancestor, the set up of these values may require
232 : // looking up the position of our ancestors.
233 : nscoord leadingSpace;
234 : nscoord trailingSpace;
235 :
236 0 : nsEmbellishData() {
237 0 : flags = 0;
238 0 : coreFrame = nullptr;
239 0 : direction = NS_STRETCH_DIRECTION_UNSUPPORTED;
240 0 : leadingSpace = 0;
241 0 : trailingSpace = 0;
242 0 : }
243 : };
244 :
245 : // struct used by a container frame to modulate its presentation.
246 : // By convention, the data that we keep in this struct can change depending
247 : // on any of our ancestors and/or descendants. If a data can be resolved
248 : // solely from the embellished hierarchy, and it remains immutable once
249 : // resolved, we put it in |nsEmbellishData|. If it can be affected by other
250 : // things, it comes here. This struct is updated as we receive information
251 : // transmitted by our ancestors and is kept in sync with changes in our
252 : // descendants that affects us.
253 : struct nsPresentationData {
254 : // bits for: compressed, etc
255 : uint32_t flags;
256 :
257 : // handy pointer on our base child (the 'nucleus' in TeX), but it may be
258 : // null here (e.g., tags like <mrow>, <mfrac>, <mtable>, etc, won't
259 : // pick a particular child in their child list to be the base)
260 : nsIFrame* baseFrame;
261 :
262 0 : nsPresentationData() {
263 0 : flags = 0;
264 0 : baseFrame = nullptr;
265 0 : }
266 : };
267 :
268 : // ==========================================================================
269 : // Bits used for the presentation flags -- these bits are set
270 : // in their relevant situation as they become available
271 :
272 : // This bit is used to emulate TeX rendering.
273 : // Internal use only, cannot be set by the user with an attribute.
274 : #define NS_MATHML_COMPRESSED 0x00000002U
275 :
276 : // This bit is set if the frame will fire a vertical stretch
277 : // command on all its (non-empty) children.
278 : // Tags like <mrow> (or an inferred mrow), mpadded, etc, will fire a
279 : // vertical stretch command on all their non-empty children
280 : #define NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY 0x00000004U
281 :
282 : // This bit is set if the frame will fire a horizontal stretch
283 : // command on all its (non-empty) children.
284 : // Tags like munder, mover, munderover, will fire a
285 : // horizontal stretch command on all their non-empty children
286 : #define NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY 0x00000008U
287 :
288 : // This bit is set if the frame is "space-like", as defined by the spec.
289 : #define NS_MATHML_SPACE_LIKE 0x00000040U
290 :
291 : // This bit is set if a token frame should be rendered with the dtls font
292 : // feature setting.
293 : #define NS_MATHML_DTLS 0x00000080U
294 :
295 : // This bit is set when the frame cannot be formatted due to an
296 : // error (e.g., invalid markup such as a <msup> without an overscript).
297 : // When set, a visual feedback will be provided to the user.
298 : #define NS_MATHML_ERROR 0x80000000U
299 :
300 : // a bit used for debug
301 : #define NS_MATHML_STRETCH_DONE 0x20000000U
302 :
303 : // This bit is used for visual debug. When set, the bounding box
304 : // of your frame is painted. This visual debug enable to ensure that
305 : // you have properly filled your mReference and mBoundingMetrics in
306 : // Place().
307 : #define NS_MATHML_SHOW_BOUNDING_METRICS 0x10000000U
308 :
309 : // Macros that retrieve those bits
310 :
311 : #define NS_MATHML_IS_COMPRESSED(_flags) \
312 : (NS_MATHML_COMPRESSED == ((_flags) & NS_MATHML_COMPRESSED))
313 :
314 : #define NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(_flags) \
315 : (NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY == ((_flags) & NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY))
316 :
317 : #define NS_MATHML_WILL_STRETCH_ALL_CHILDREN_HORIZONTALLY(_flags) \
318 : (NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY == ((_flags) & NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY))
319 :
320 : #define NS_MATHML_IS_SPACE_LIKE(_flags) \
321 : (NS_MATHML_SPACE_LIKE == ((_flags) & NS_MATHML_SPACE_LIKE))
322 :
323 : #define NS_MATHML_IS_DTLS_SET(_flags) \
324 : (NS_MATHML_DTLS == ((_flags) & NS_MATHML_DTLS))
325 :
326 : #define NS_MATHML_HAS_ERROR(_flags) \
327 : (NS_MATHML_ERROR == ((_flags) & NS_MATHML_ERROR))
328 :
329 : #define NS_MATHML_STRETCH_WAS_DONE(_flags) \
330 : (NS_MATHML_STRETCH_DONE == ((_flags) & NS_MATHML_STRETCH_DONE))
331 :
332 : #define NS_MATHML_PAINT_BOUNDING_METRICS(_flags) \
333 : (NS_MATHML_SHOW_BOUNDING_METRICS == ((_flags) & NS_MATHML_SHOW_BOUNDING_METRICS))
334 :
335 : // ==========================================================================
336 : // Bits used for the embellish flags -- these bits are set
337 : // in their relevant situation as they become available
338 :
339 : // This bit is set if the frame is an embellished operator.
340 : #define NS_MATHML_EMBELLISH_OPERATOR 0x00000001
341 :
342 : // This bit is set if the frame is an <mo> frame or an embellihsed
343 : // operator for which the core <mo> has movablelimits="true"
344 : #define NS_MATHML_EMBELLISH_MOVABLELIMITS 0x00000002
345 :
346 : // This bit is set if the frame is an <mo> frame or an embellihsed
347 : // operator for which the core <mo> has accent="true"
348 : #define NS_MATHML_EMBELLISH_ACCENT 0x00000004
349 :
350 : // This bit is set if the frame is an <mover> or <munderover> with
351 : // an accent frame
352 : #define NS_MATHML_EMBELLISH_ACCENTOVER 0x00000008
353 :
354 : // This bit is set if the frame is an <munder> or <munderover> with
355 : // an accentunder frame
356 : #define NS_MATHML_EMBELLISH_ACCENTUNDER 0x00000010
357 :
358 : // This bit is set on the core if it is a fence operator.
359 : #define NS_MATHML_EMBELLISH_FENCE 0x00000020
360 :
361 : // This bit is set on the core if it is a separator operator.
362 : #define NS_MATHML_EMBELLISH_SEPARATOR 0x00000040
363 :
364 : // Macros that retrieve those bits
365 :
366 : #define NS_MATHML_IS_EMBELLISH_OPERATOR(_flags) \
367 : (NS_MATHML_EMBELLISH_OPERATOR == ((_flags) & NS_MATHML_EMBELLISH_OPERATOR))
368 :
369 : #define NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(_flags) \
370 : (NS_MATHML_EMBELLISH_MOVABLELIMITS == ((_flags) & NS_MATHML_EMBELLISH_MOVABLELIMITS))
371 :
372 : #define NS_MATHML_EMBELLISH_IS_ACCENT(_flags) \
373 : (NS_MATHML_EMBELLISH_ACCENT == ((_flags) & NS_MATHML_EMBELLISH_ACCENT))
374 :
375 : #define NS_MATHML_EMBELLISH_IS_ACCENTOVER(_flags) \
376 : (NS_MATHML_EMBELLISH_ACCENTOVER == ((_flags) & NS_MATHML_EMBELLISH_ACCENTOVER))
377 :
378 : #define NS_MATHML_EMBELLISH_IS_ACCENTUNDER(_flags) \
379 : (NS_MATHML_EMBELLISH_ACCENTUNDER == ((_flags) & NS_MATHML_EMBELLISH_ACCENTUNDER))
380 :
381 : #define NS_MATHML_EMBELLISH_IS_FENCE(_flags) \
382 : (NS_MATHML_EMBELLISH_FENCE == ((_flags) & NS_MATHML_EMBELLISH_FENCE))
383 :
384 : #define NS_MATHML_EMBELLISH_IS_SEPARATOR(_flags) \
385 : (NS_MATHML_EMBELLISH_SEPARATOR == ((_flags) & NS_MATHML_EMBELLISH_SEPARATOR))
386 :
387 : #endif /* nsIMathMLFrame_h___ */
|