1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is Mozilla MathML Project.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * The University Of Queensland.
19 : * Portions created by the Initial Developer are Copyright (C) 1999
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Roger B. Sidje <rbs@maths.uq.edu.au>
24 : * Frederic Wang <fred.wang@free.fr>
25 : *
26 : * Alternatively, the contents of this file may be used under the terms of
27 : * either of the GNU General Public License Version 2 or later (the "GPL"),
28 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 : * in which case the provisions of the GPL or the LGPL are applicable instead
30 : * of those above. If you wish to allow use of your version of this file only
31 : * under the terms of either the GPL or the LGPL, and not to allow others to
32 : * use your version of this file under the terms of the MPL, indicate your
33 : * decision by deleting the provisions above and replace them with the notice
34 : * and other provisions required by the GPL or the LGPL. If you do not delete
35 : * the provisions above, a recipient may use your version of this file under
36 : * the terms of any one of the MPL, the GPL or the LGPL.
37 : *
38 : * ***** END LICENSE BLOCK ***** */
39 : //#define SHOW_BOUNDING_BOX 1
40 : #ifndef nsIMathMLFrame_h___
41 : #define nsIMathMLFrame_h___
42 :
43 : #include "nsIFrame.h"
44 :
45 : struct nsPresentationData;
46 : struct nsEmbellishData;
47 : struct nsHTMLReflowMetrics;
48 : class nsRenderingContext;
49 :
50 : // For MathML, this 'type' will be used to determine the spacing between frames
51 : // Subclasses can return a 'type' that will give them a particular spacing
52 : enum eMathMLFrameType {
53 : eMathMLFrameType_UNKNOWN = -1,
54 : eMathMLFrameType_Ordinary,
55 : eMathMLFrameType_OperatorOrdinary,
56 : eMathMLFrameType_OperatorInvisible,
57 : eMathMLFrameType_OperatorUserDefined,
58 : eMathMLFrameType_Inner,
59 : eMathMLFrameType_ItalicIdentifier,
60 : eMathMLFrameType_UprightIdentifier,
61 : eMathMLFrameType_COUNT
62 : };
63 :
64 : // Abstract base class that provides additional methods for MathML frames
65 : class nsIMathMLFrame
66 0 : {
67 : public:
68 : NS_DECL_QUERYFRAME_TARGET(nsIMathMLFrame)
69 :
70 : // helper to check whether the frame is "space-like", as defined by the spec.
71 : virtual bool IsSpaceLike() = 0;
72 :
73 : /* SUPPORT FOR PRECISE POSITIONING */
74 : /*====================================================================*/
75 :
76 : /* Metrics that _exactly_ enclose the text of the frame.
77 : * The frame *must* have *already* being reflowed, before you can call
78 : * the GetBoundingMetrics() method.
79 : * Note that for a frame with nested children, the bounding metrics
80 : * will exactly enclose its children. For example, the bounding metrics
81 : * of msub is the smallest rectangle that exactly encloses both the
82 : * base and the subscript.
83 : */
84 : NS_IMETHOD
85 : GetBoundingMetrics(nsBoundingMetrics& aBoundingMetrics) = 0;
86 :
87 : NS_IMETHOD
88 : SetBoundingMetrics(const nsBoundingMetrics& aBoundingMetrics) = 0;
89 :
90 : NS_IMETHOD
91 : SetReference(const nsPoint& aReference) = 0;
92 :
93 : virtual eMathMLFrameType GetMathMLFrameType() = 0;
94 :
95 : /* SUPPORT FOR STRETCHY ELEMENTS */
96 : /*====================================================================*/
97 :
98 : /* Stretch :
99 : * Called to ask a stretchy MathML frame to stretch itself depending
100 : * on its context.
101 : *
102 : * An embellished frame is treated in a special way. When it receives a
103 : * Stretch() command, it passes the command to its embellished child and
104 : * the stretched size is bubbled up from the inner-most <mo> frame. In other
105 : * words, the stretch command descend through the embellished hierarchy.
106 : *
107 : * @param aStretchDirection [in] the direction where to attempt to
108 : * stretch.
109 : * @param aContainerSize [in] struct that suggests the maximumn size for
110 : * the stretched frame. Only member data of the struct that are
111 : * relevant to the direction are used (the rest is ignored).
112 : * @param aDesiredStretchSize [in/out] On input the current size
113 : * of the frame, on output the size after stretching.
114 : */
115 : NS_IMETHOD
116 : Stretch(nsRenderingContext& aRenderingContext,
117 : nsStretchDirection aStretchDirection,
118 : nsBoundingMetrics& aContainerSize,
119 : nsHTMLReflowMetrics& aDesiredStretchSize) = 0;
120 :
121 : /* Get the mEmbellishData member variable. */
122 :
123 : NS_IMETHOD
124 : GetEmbellishData(nsEmbellishData& aEmbellishData) = 0;
125 :
126 :
127 : /* SUPPORT FOR SCRIPTING ELEMENTS */
128 : /*====================================================================*/
129 :
130 : /* Get the mPresentationData member variable. */
131 :
132 : NS_IMETHOD
133 : GetPresentationData(nsPresentationData& aPresentationData) = 0;
134 :
135 : /* InheritAutomaticData() / TransmitAutomaticData() :
136 : * There are precise rules governing each MathML frame and its children.
137 : * Properties such as the scriptlevel or the embellished nature of a frame
138 : * depend on those rules. Also, certain properties that we use to emulate
139 : * TeX rendering rules are frame-dependent too. These two methods are meant
140 : * to be implemented by frame classes that need to assert specific properties
141 : * within their subtrees.
142 : *
143 : * InheritAutomaticData() is called in a top-down manner [like nsIFrame::Init],
144 : * as we descend the frame tree, whereas TransmitAutomaticData() is called in a
145 : * bottom-up manner, as we ascend the tree [like nsIFrame::SetInitialChildList].
146 : * However, unlike Init() and SetInitialChildList() which are called only once
147 : * during the life-time of a frame (when initially constructing the frame tree),
148 : * these two methods are called to build automatic data after the <math>...</math>
149 : * subtree has been constructed fully, and are called again as we walk a child's
150 : * subtree to handle dynamic changes that happen in the content model.
151 : *
152 : * As a rule of thumb:
153 : *
154 : * 1. Use InheritAutomaticData() to set properties related to your ancestors:
155 : * - set properties that are intrinsic to yourself
156 : * - set properties that depend on the state that you expect your ancestors
157 : * to have already reached in their own InheritAutomaticData().
158 : * - set properties that your descendants assume that you would have set in
159 : * your InheritAutomaticData() -- this way, they can safely query them and
160 : * the process will feed upon itself.
161 : *
162 : * 2. Use TransmitAutomaticData() to set properties related to your descendants:
163 : * - set properties that depend on the state that you expect your descendants
164 : * to have reached upon processing their own TransmitAutomaticData().
165 : * - transmit properties that your descendants expect that you will transmit to
166 : * them in your TransmitAutomaticData() -- this way, they remain up-to-date.
167 : * - set properties that your ancestors expect that you would set in your
168 : * TransmitAutomaticData() -- this way, they can safely query them and the
169 : * process will feed upon itself.
170 : */
171 :
172 : NS_IMETHOD
173 : InheritAutomaticData(nsIFrame* aParent) = 0;
174 :
175 : NS_IMETHOD
176 : TransmitAutomaticData() = 0;
177 :
178 : /* UpdatePresentationData :
179 : * Updates the frame's displaystyle and compression flags. The displaystyle
180 : * flag of an environment gets updated according to the MathML specification.
181 : * A frame becomes "compressed" (or "cramped") according to TeX rendering
182 : * rules (TeXBook, Ch.17, p.140-141).
183 : *
184 : * Note that <mstyle> is the only tag which allows to set
185 : * <mstyle displaystyle="true|false">
186 : * Therefore <mstyle> has its own peculiar version of this method.
187 : *
188 : * @param aFlagsValues [in]
189 : * The new values (e.g., display, compress) that are going to be
190 : * updated.
191 : *
192 : * @param aWhichFlags [in]
193 : * The flags that are relevant to this call. Since not all calls
194 : * are meant to update all flags at once, aWhichFlags is used
195 : * to distinguish flags that need to retain their existing values
196 : * from flags that need to be turned on (or turned off). If a bit
197 : * is set in aWhichFlags, then the corresponding value (which
198 : * can be 0 or 1) is taken from aFlagsValues and applied to the
199 : * frame. Therefore, by setting their bits in aWhichFlags, and
200 : * setting their desired values in aFlagsValues, it is possible to
201 : * update some flags in the frame, leaving the other flags unchanged.
202 : */
203 : NS_IMETHOD
204 : UpdatePresentationData(PRUint32 aFlagsValues,
205 : PRUint32 aWhichFlags) = 0;
206 :
207 : /* UpdatePresentationDataFromChildAt :
208 : * Sets displaystyle and compression flags on the whole tree. For child frames
209 : * at aFirstIndex up to aLastIndex, this method sets their displaystyle and
210 : * compression flags. The update is propagated down the subtrees of each of
211 : * these child frames.
212 : *
213 : * Note that <mstyle> is the only tag which allows
214 : * <mstyle displaystyle="true|false">
215 : * Therefore <mstyle> has its own peculiar version of this method.
216 : *
217 : * @param aFirstIndex [in]
218 : * Index of the first child from where the update is propagated.
219 : *
220 : * @param aLastIndex [in]
221 : * Index of the last child where to stop the update.
222 : * A value of -1 means up to last existing child.
223 : *
224 : * @param aFlagsValues [in]
225 : * The new values (e.g., display, compress) that are going to be
226 : * assigned in the whole sub-trees.
227 : *
228 : * @param aWhichFlags [in]
229 : * The flags that are relevant to this call. See UpdatePresentationData()
230 : * for more details about this parameter.
231 : */
232 : NS_IMETHOD
233 : UpdatePresentationDataFromChildAt(PRInt32 aFirstIndex,
234 : PRInt32 aLastIndex,
235 : PRUint32 aFlagsValues,
236 : PRUint32 aWhichFlags) = 0;
237 : };
238 :
239 : // struct used by a container frame to keep track of its embellishments.
240 : // By convention, the data that we keep here is bubbled from the embellished
241 : // hierarchy, and it remains unchanged unless we have to recover from a change
242 : // that occurs in the embellished hierarchy. The struct remains in its nil
243 : // state in those frames that are not part of the embellished hierarchy.
244 : struct nsEmbellishData {
245 : // bits used to mark certain properties of our embellishments
246 : PRUint32 flags;
247 :
248 : // pointer on the <mo> frame at the core of the embellished hierarchy
249 : nsIFrame* coreFrame;
250 :
251 : // stretchy direction that the nsMathMLChar owned by the core <mo> supports
252 : nsStretchDirection direction;
253 :
254 : // spacing that may come from <mo> depending on its 'form'. Since
255 : // the 'form' may also depend on the position of the outermost
256 : // embellished ancestor, the set up of these values may require
257 : // looking up the position of our ancestors.
258 : nscoord leadingSpace;
259 : nscoord trailingSpace;
260 :
261 0 : nsEmbellishData() {
262 0 : flags = 0;
263 0 : coreFrame = nsnull;
264 0 : direction = NS_STRETCH_DIRECTION_UNSUPPORTED;
265 0 : leadingSpace = 0;
266 0 : trailingSpace = 0;
267 0 : }
268 : };
269 :
270 : // struct used by a container frame to modulate its presentation.
271 : // By convention, the data that we keep in this struct can change depending
272 : // on any of our ancestors and/or descendants. If a data can be resolved
273 : // solely from the embellished hierarchy, and it remains immutable once
274 : // resolved, we put it in |nsEmbellishData|. If it can be affected by other
275 : // things, it comes here. This struct is updated as we receive information
276 : // transmitted by our ancestors and is kept in sync with changes in our
277 : // descendants that affects us.
278 : struct nsPresentationData {
279 : // bits for: displaystyle, compressed, etc
280 : PRUint32 flags;
281 :
282 : // handy pointer on our base child (the 'nucleus' in TeX), but it may be
283 : // null here (e.g., tags like <mrow>, <mfrac>, <mtable>, etc, won't
284 : // pick a particular child in their child list to be the base)
285 : nsIFrame* baseFrame;
286 :
287 : // up-pointer on the mstyle frame, if any, that defines the scope
288 : nsIFrame* mstyle;
289 :
290 0 : nsPresentationData() {
291 0 : flags = 0;
292 0 : baseFrame = nsnull;
293 0 : mstyle = nsnull;
294 0 : }
295 : };
296 :
297 : // ==========================================================================
298 : // Bits used for the presentation flags -- these bits are set
299 : // in their relevant situation as they become available
300 :
301 : // This bit is set if the frame is in the *context* of displaystyle=true.
302 : // Note: This doesn't mean that the frame has displaystyle=true as attribute,
303 : // the displaystyle attribute is only allowed on <mstyle> and <mtable>.
304 : // The bit merely tells the context of the frame. In the context of
305 : // displaystyle="false", it is intended to slightly alter how the
306 : // rendering is done in inline mode.
307 : #define NS_MATHML_DISPLAYSTYLE 0x00000001U
308 :
309 : // This bit is used to emulate TeX rendering.
310 : // Internal use only, cannot be set by the user with an attribute.
311 : #define NS_MATHML_COMPRESSED 0x00000002U
312 :
313 : // This bit is set if the frame will fire a vertical stretch
314 : // command on all its (non-empty) children.
315 : // Tags like <mrow> (or an inferred mrow), mpadded, etc, will fire a
316 : // vertical stretch command on all their non-empty children
317 : #define NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY 0x00000004U
318 :
319 : // This bit is set if the frame will fire a horizontal stretch
320 : // command on all its (non-empty) children.
321 : // Tags like munder, mover, munderover, will fire a
322 : // horizontal stretch command on all their non-empty children
323 : #define NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY 0x00000008U
324 :
325 : // This bit is set if the frame has the explicit attribute
326 : // displaystyle="true" or "false". It is only relevant to <mstyle> and <mtable>
327 : // because they are the only tags where the attribute is allowed by the spec.
328 : #define NS_MATHML_EXPLICIT_DISPLAYSTYLE 0x00000020U
329 :
330 : // This bit is set if the frame is "space-like", as defined by the spec.
331 : #define NS_MATHML_SPACE_LIKE 0x00000040U
332 :
333 : // This bit is set if the directionality of the frame is right-to-left
334 : #define NS_MATHML_RTL 0x00000080U
335 :
336 : // This bit is set when the frame cannot be formatted due to an
337 : // error (e.g., invalid markup such as a <msup> without an overscript).
338 : // When set, a visual feedback will be provided to the user.
339 : #define NS_MATHML_ERROR 0x80000000U
340 :
341 : // a bit used for debug
342 : #define NS_MATHML_STRETCH_DONE 0x20000000U
343 :
344 : // This bit is used for visual debug. When set, the bounding box
345 : // of your frame is painted. This visual debug enable to ensure that
346 : // you have properly filled your mReference and mBoundingMetrics in
347 : // Place().
348 : #define NS_MATHML_SHOW_BOUNDING_METRICS 0x10000000U
349 :
350 : // Macros that retrieve those bits
351 :
352 : #define NS_MATHML_IS_DISPLAYSTYLE(_flags) \
353 : (NS_MATHML_DISPLAYSTYLE == ((_flags) & NS_MATHML_DISPLAYSTYLE))
354 :
355 : #define NS_MATHML_IS_COMPRESSED(_flags) \
356 : (NS_MATHML_COMPRESSED == ((_flags) & NS_MATHML_COMPRESSED))
357 :
358 : #define NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(_flags) \
359 : (NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY == ((_flags) & NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY))
360 :
361 : #define NS_MATHML_WILL_STRETCH_ALL_CHILDREN_HORIZONTALLY(_flags) \
362 : (NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY == ((_flags) & NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY))
363 :
364 : #define NS_MATHML_HAS_EXPLICIT_DISPLAYSTYLE(_flags) \
365 : (NS_MATHML_EXPLICIT_DISPLAYSTYLE == ((_flags) & NS_MATHML_EXPLICIT_DISPLAYSTYLE))
366 :
367 : #define NS_MATHML_IS_SPACE_LIKE(_flags) \
368 : (NS_MATHML_SPACE_LIKE == ((_flags) & NS_MATHML_SPACE_LIKE))
369 :
370 : #define NS_MATHML_IS_RTL(_flags) \
371 : (NS_MATHML_RTL == ((_flags) & NS_MATHML_RTL))
372 :
373 : #define NS_MATHML_HAS_ERROR(_flags) \
374 : (NS_MATHML_ERROR == ((_flags) & NS_MATHML_ERROR))
375 :
376 : #define NS_MATHML_STRETCH_WAS_DONE(_flags) \
377 : (NS_MATHML_STRETCH_DONE == ((_flags) & NS_MATHML_STRETCH_DONE))
378 :
379 : #define NS_MATHML_PAINT_BOUNDING_METRICS(_flags) \
380 : (NS_MATHML_SHOW_BOUNDING_METRICS == ((_flags) & NS_MATHML_SHOW_BOUNDING_METRICS))
381 :
382 : // ==========================================================================
383 : // Bits used for the embellish flags -- these bits are set
384 : // in their relevant situation as they become available
385 :
386 : // This bit is set if the frame is an embellished operator.
387 : #define NS_MATHML_EMBELLISH_OPERATOR 0x00000001
388 :
389 : // This bit is set if the frame is an <mo> frame or an embellihsed
390 : // operator for which the core <mo> has movablelimits="true"
391 : #define NS_MATHML_EMBELLISH_MOVABLELIMITS 0x00000002
392 :
393 : // This bit is set if the frame is an <mo> frame or an embellihsed
394 : // operator for which the core <mo> has accent="true"
395 : #define NS_MATHML_EMBELLISH_ACCENT 0x00000004
396 :
397 : // This bit is set if the frame is an <mover> or <munderover> with
398 : // an accent frame
399 : #define NS_MATHML_EMBELLISH_ACCENTOVER 0x00000008
400 :
401 : // This bit is set if the frame is an <munder> or <munderover> with
402 : // an accentunder frame
403 : #define NS_MATHML_EMBELLISH_ACCENTUNDER 0x00000010
404 :
405 : // Macros that retrieve those bits
406 :
407 : #define NS_MATHML_IS_EMBELLISH_OPERATOR(_flags) \
408 : (NS_MATHML_EMBELLISH_OPERATOR == ((_flags) & NS_MATHML_EMBELLISH_OPERATOR))
409 :
410 : #define NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(_flags) \
411 : (NS_MATHML_EMBELLISH_MOVABLELIMITS == ((_flags) & NS_MATHML_EMBELLISH_MOVABLELIMITS))
412 :
413 : #define NS_MATHML_EMBELLISH_IS_ACCENT(_flags) \
414 : (NS_MATHML_EMBELLISH_ACCENT == ((_flags) & NS_MATHML_EMBELLISH_ACCENT))
415 :
416 : #define NS_MATHML_EMBELLISH_IS_ACCENTOVER(_flags) \
417 : (NS_MATHML_EMBELLISH_ACCENTOVER == ((_flags) & NS_MATHML_EMBELLISH_ACCENTOVER))
418 :
419 : #define NS_MATHML_EMBELLISH_IS_ACCENTUNDER(_flags) \
420 : (NS_MATHML_EMBELLISH_ACCENTUNDER == ((_flags) & NS_MATHML_EMBELLISH_ACCENTUNDER))
421 :
422 : #endif /* nsIMathMLFrame_h___ */
|