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