Coverage Report

Created: 2018-09-25 14:53

/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___ */