#### Source code

#### Revision control

#### Copy as Markdown

#### Other Tools

```
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
```

```
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
```

```
/* This Source Code Form is subject to the terms of the Mozilla Public
```

```
* License, v. 2.0. If a copy of the MPL was not distributed with this
```

```
//#define SHOW_BOUNDING_BOX 1
```

```
#ifndef nsIMathMLFrame_h___
```

```
#define nsIMathMLFrame_h___
```

```
```

```
#include "nsQueryFrame.h"
```

```
#include "nsMathMLOperators.h"
```

```
```

```
struct nsPresentationData;
```

```
struct nsEmbellishData;
```

```
class gfxContext;
```

```
class nsIFrame;
```

```
namespace mozilla {
```

```
class ReflowOutput;
```

```
} // namespace mozilla
```

```
```

```
// For MathML, this 'type' will be used to determine the spacing between frames
```

```
// Subclasses can return a 'type' that will give them a particular spacing
```

```
enum eMathMLFrameType {
```

```
eMathMLFrameType_UNKNOWN = -1,
```

```
eMathMLFrameType_Ordinary,
```

```
eMathMLFrameType_OperatorOrdinary,
```

```
eMathMLFrameType_OperatorInvisible,
```

```
eMathMLFrameType_OperatorUserDefined,
```

```
eMathMLFrameType_Inner,
```

```
eMathMLFrameType_ItalicIdentifier,
```

```
eMathMLFrameType_UprightIdentifier,
```

```
eMathMLFrameType_COUNT
```

```
};
```

```
```

```
// Abstract base class that provides additional methods for MathML frames
```

```
class nsIMathMLFrame {
```

```
public:
```

```
NS_DECL_QUERYFRAME_TARGET(nsIMathMLFrame)
```

```
```

```
// helper to check whether the frame is "space-like", as defined by the spec.
```

```
virtual bool IsSpaceLike() = 0;
```

```
```

```
/* SUPPORT FOR PRECISE POSITIONING */
```

```
/*====================================================================*/
```

```
```

```
/* Metrics that _exactly_ enclose the text of the frame.
```

```
* The frame *must* have *already* being reflowed, before you can call
```

```
* the GetBoundingMetrics() method.
```

```
* Note that for a frame with nested children, the bounding metrics
```

```
* will exactly enclose its children. For example, the bounding metrics
```

```
* of msub is the smallest rectangle that exactly encloses both the
```

```
* base and the subscript.
```

```
*/
```

```
NS_IMETHOD
```

```
GetBoundingMetrics(nsBoundingMetrics& aBoundingMetrics) = 0;
```

```
```

```
NS_IMETHOD
```

```
SetBoundingMetrics(const nsBoundingMetrics& aBoundingMetrics) = 0;
```

```
```

```
NS_IMETHOD
```

```
SetReference(const nsPoint& aReference) = 0;
```

```
```

```
virtual eMathMLFrameType GetMathMLFrameType() = 0;
```

```
```

```
/* SUPPORT FOR STRETCHY ELEMENTS */
```

```
/*====================================================================*/
```

```
```

```
/* Stretch :
```

```
* Called to ask a stretchy MathML frame to stretch itself depending
```

```
* on its context.
```

```
*
```

```
* An embellished frame is treated in a special way. When it receives a
```

```
* Stretch() command, it passes the command to its embellished child and
```

```
* the stretched size is bubbled up from the inner-most <mo> frame. In other
```

```
* words, the stretch command descend through the embellished hierarchy.
```

```
*
```

```
* @param aStretchDirection [in] the direction where to attempt to
```

```
* stretch.
```

```
* @param aContainerSize [in] struct that suggests the maximumn size for
```

```
* the stretched frame. Only member data of the struct that are
```

```
* relevant to the direction are used (the rest is ignored).
```

```
* @param aDesiredStretchSize [in/out] On input the current size
```

```
* of the frame, on output the size after stretching.
```

```
*/
```

```
NS_IMETHOD
```

```
Stretch(mozilla::gfx::DrawTarget* aDrawTarget,
```

```
nsStretchDirection aStretchDirection,
```

```
nsBoundingMetrics& aContainerSize,
```

```
mozilla::ReflowOutput& aDesiredStretchSize) = 0;
```

```
```

```
/* Get the mEmbellishData member variable. */
```

```
```

```
NS_IMETHOD
```

```
GetEmbellishData(nsEmbellishData& aEmbellishData) = 0;
```

```
```

```
/* SUPPORT FOR SCRIPTING ELEMENTS */
```

```
/*====================================================================*/
```

```
```

```
/* Get the mPresentationData member variable. */
```

```
```

```
NS_IMETHOD
```

```
GetPresentationData(nsPresentationData& aPresentationData) = 0;
```

```
```

```
/* InheritAutomaticData() / TransmitAutomaticData() :
```

```
* There are precise rules governing each MathML frame and its children.
```

```
* Properties such as the scriptlevel or the embellished nature of a frame
```

```
* depend on those rules. Also, certain properties that we use to emulate
```

```
* TeX rendering rules are frame-dependent too. These two methods are meant
```

```
* to be implemented by frame classes that need to assert specific properties
```

```
* within their subtrees.
```

```
*
```

```
* InheritAutomaticData() is called in a top-down manner [like
```

```
* nsIFrame::Init], as we descend the frame tree, whereas
```

```
* TransmitAutomaticData() is called in a bottom-up manner, as we ascend the
```

```
* tree [like nsIFrame::SetInitialChildList]. However, unlike Init() and
```

```
* SetInitialChildList() which are called only once during the life-time of a
```

```
* frame (when initially constructing the frame tree), these two methods are
```

```
* called to build automatic data after the <math>...</math> subtree has been
```

```
* constructed fully, and are called again as we walk a child's subtree to
```

```
* handle dynamic changes that happen in the content model.
```

```
*
```

```
* As a rule of thumb:
```

```
*
```

```
* 1. Use InheritAutomaticData() to set properties related to your ancestors:
```

```
* - set properties that are intrinsic to yourself
```

```
* - set properties that depend on the state that you expect your ancestors
```

```
* to have already reached in their own InheritAutomaticData().
```

```
* - set properties that your descendants assume that you would have set in
```

```
* your InheritAutomaticData() -- this way, they can safely query them
```

```
* and the process will feed upon itself.
```

```
*
```

```
* 2. Use TransmitAutomaticData() to set properties related to your
```

```
* descendants:
```

```
* - set properties that depend on the state that you expect your
```

```
* descendants to have reached upon processing their own
```

```
* TransmitAutomaticData().
```

```
* - transmit properties that your descendants expect that you will
```

```
* transmit to them in your TransmitAutomaticData() -- this way, they
```

```
* remain up-to-date.
```

```
* - set properties that your ancestors expect that you would set in your
```

```
* TransmitAutomaticData() -- this way, they can safely query them and
```

```
* the process will feed upon itself.
```

```
*/
```

```
```

```
NS_IMETHOD
```

```
InheritAutomaticData(nsIFrame* aParent) = 0;
```

```
```

```
NS_IMETHOD
```

```
TransmitAutomaticData() = 0;
```

```
```

```
/* UpdatePresentationData:
```

```
* Updates the frame's compression flag.
```

```
* A frame becomes "compressed" (or "cramped") according to TeX rendering
```

```
* rules (TeXBook, Ch.17, p.140-141).
```

```
*
```

```
* @param aFlagsValues [in]
```

```
* The new values (e.g., compress) that are going to be
```

```
* updated.
```

```
*
```

```
* @param aWhichFlags [in]
```

```
* The flags that are relevant to this call. Since not all calls
```

```
* are meant to update all flags at once, aWhichFlags is used
```

```
* to distinguish flags that need to retain their existing values
```

```
* from flags that need to be turned on (or turned off). If a bit
```

```
* is set in aWhichFlags, then the corresponding value (which
```

```
* can be 0 or 1) is taken from aFlagsValues and applied to the
```

```
* frame. Therefore, by setting their bits in aWhichFlags, and
```

```
* setting their desired values in aFlagsValues, it is possible to
```

```
* update some flags in the frame, leaving the other flags unchanged.
```

```
*/
```

```
NS_IMETHOD
```

```
UpdatePresentationData(uint32_t aFlagsValues, uint32_t aWhichFlags) = 0;
```

```
```

```
/* UpdatePresentationDataFromChildAt :
```

```
* Sets compression flag on the whole tree. For child frames
```

```
* at aFirstIndex up to aLastIndex, this method sets their
```

```
* compression flags. The update is propagated down the subtrees of each of
```

```
* these child frames.
```

```
*
```

```
* @param aFirstIndex [in]
```

```
* Index of the first child from where the update is propagated.
```

```
*
```

```
* @param aLastIndex [in]
```

```
* Index of the last child where to stop the update.
```

```
* A value of -1 means up to last existing child.
```

```
*
```

```
* @param aFlagsValues [in]
```

```
* The new values (e.g., compress) that are going to be
```

```
* assigned in the whole sub-trees.
```

```
*
```

```
* @param aWhichFlags [in]
```

```
* The flags that are relevant to this call. See
```

```
* UpdatePresentationData() for more details about this parameter.
```

```
*/
```

```
NS_IMETHOD
```

```
UpdatePresentationDataFromChildAt(int32_t aFirstIndex, int32_t aLastIndex,
```

```
uint32_t aFlagsValues,
```

```
uint32_t aWhichFlags) = 0;
```

```
```

```
// If aFrame is a child frame, returns the script increment which this frame
```

```
// imposes on the specified frame, ignoring any artificial adjustments to
```

```
// scriptlevel.
```

```
// Returns 0 if the specified frame isn't a child frame.
```

```
virtual uint8_t ScriptIncrement(nsIFrame* aFrame) = 0;
```

```
```

```
// Returns true if the frame is considered to be an mrow for layout purposes.
```

```
// This includes inferred mrows, but excludes <mrow> elements with a single
```

```
// child. In the latter case, the child is to be treated as if it wasn't
```

```
// within an mrow, so we pretend the mrow isn't mrow-like.
```

```
virtual bool IsMrowLike() = 0;
```

```
};
```

```
```

```
// struct used by a container frame to keep track of its embellishments.
```

```
// By convention, the data that we keep here is bubbled from the embellished
```

```
// hierarchy, and it remains unchanged unless we have to recover from a change
```

```
// that occurs in the embellished hierarchy. The struct remains in its nil
```

```
// state in those frames that are not part of the embellished hierarchy.
```

```
struct nsEmbellishData {
```

```
// bits used to mark certain properties of our embellishments
```

```
uint32_t flags;
```

```
```

```
// pointer on the <mo> frame at the core of the embellished hierarchy
```

```
nsIFrame* coreFrame;
```

```
```

```
// stretchy direction that the nsMathMLChar owned by the core <mo> supports
```

```
nsStretchDirection direction;
```

```
```

```
// spacing that may come from <mo> depending on its 'form'. Since
```

```
// the 'form' may also depend on the position of the outermost
```

```
// embellished ancestor, the set up of these values may require
```

```
// looking up the position of our ancestors.
```

```
nscoord leadingSpace;
```

```
nscoord trailingSpace;
```

```
```

```
nsEmbellishData() {
```

```
flags = 0;
```

```
coreFrame = nullptr;
```

```
direction = NS_STRETCH_DIRECTION_UNSUPPORTED;
```

```
leadingSpace = 0;
```

```
trailingSpace = 0;
```

```
}
```

```
};
```

```
```

```
// struct used by a container frame to modulate its presentation.
```

```
// By convention, the data that we keep in this struct can change depending
```

```
// on any of our ancestors and/or descendants. If a data can be resolved
```

```
// solely from the embellished hierarchy, and it remains immutable once
```

```
// resolved, we put it in |nsEmbellishData|. If it can be affected by other
```

```
// things, it comes here. This struct is updated as we receive information
```

```
// transmitted by our ancestors and is kept in sync with changes in our
```

```
// descendants that affects us.
```

```
struct nsPresentationData {
```

```
// bits for: compressed, etc
```

```
uint32_t flags;
```

```
```

```
// handy pointer on our base child (the 'nucleus' in TeX), but it may be
```

```
// null here (e.g., tags like <mrow>, <mfrac>, <mtable>, etc, won't
```

```
// pick a particular child in their child list to be the base)
```

```
nsIFrame* baseFrame;
```

```
```

```
nsPresentationData() {
```

```
flags = 0;
```

```
baseFrame = nullptr;
```

```
}
```

```
};
```

```
```

```
// ==========================================================================
```

```
// Bits used for the presentation flags -- these bits are set
```

```
// in their relevant situation as they become available
```

```
```

```
// This bit is used to emulate TeX rendering.
```

```
// Internal use only, cannot be set by the user with an attribute.
```

```
#define NS_MATHML_COMPRESSED 0x00000002U
```

```
```

```
// This bit is set if the frame will fire a vertical stretch
```

```
// command on all its (non-empty) children.
```

```
// Tags like <mrow> (or an inferred mrow), mpadded, etc, will fire a
```

```
// vertical stretch command on all their non-empty children
```

```
#define NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY 0x00000004U
```

```
```

```
// This bit is set if the frame will fire a horizontal stretch
```

```
// command on all its (non-empty) children.
```

```
// Tags like munder, mover, munderover, will fire a
```

```
// horizontal stretch command on all their non-empty children
```

```
#define NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY 0x00000008U
```

```
```

```
// This bit is set if the frame is "space-like", as defined by the spec.
```

```
#define NS_MATHML_SPACE_LIKE 0x00000040U
```

```
```

```
// This bit is set if a token frame should be rendered with the dtls font
```

```
// feature setting.
```

```
#define NS_MATHML_DTLS 0x00000080U
```

```
```

```
// This bit is set when the frame cannot be formatted due to an
```

```
// error (e.g., invalid markup such as a <msup> without an overscript).
```

```
// When set, a visual feedback will be provided to the user.
```

```
#define NS_MATHML_ERROR 0x80000000U
```

```
```

```
// a bit used for debug
```

```
#define NS_MATHML_STRETCH_DONE 0x20000000U
```

```
```

```
// This bit is used for visual debug. When set, the bounding box
```

```
// of your frame is painted. This visual debug enable to ensure that
```

```
// you have properly filled your mReference and mBoundingMetrics in
```

```
// Place().
```

```
#define NS_MATHML_SHOW_BOUNDING_METRICS 0x10000000U
```

```
```

```
// Macros that retrieve those bits
```

```
```

```
#define NS_MATHML_IS_COMPRESSED(_flags) \
```

```
(NS_MATHML_COMPRESSED == ((_flags)&NS_MATHML_COMPRESSED))
```

```
```

```
#define NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(_flags) \
```

```
(NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY == \
```

```
((_flags)&NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY))
```

```
```

```
#define NS_MATHML_WILL_STRETCH_ALL_CHILDREN_HORIZONTALLY(_flags) \
```

```
(NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY == \
```

```
((_flags)&NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY))
```

```
```

```
#define NS_MATHML_IS_SPACE_LIKE(_flags) \
```

```
(NS_MATHML_SPACE_LIKE == ((_flags)&NS_MATHML_SPACE_LIKE))
```

```
```

```
#define NS_MATHML_IS_DTLS_SET(_flags) \
```

```
(NS_MATHML_DTLS == ((_flags)&NS_MATHML_DTLS))
```

```
```

```
#define NS_MATHML_HAS_ERROR(_flags) \
```

```
(NS_MATHML_ERROR == ((_flags)&NS_MATHML_ERROR))
```

```
```

```
#define NS_MATHML_STRETCH_WAS_DONE(_flags) \
```

```
(NS_MATHML_STRETCH_DONE == ((_flags)&NS_MATHML_STRETCH_DONE))
```

```
```

```
#define NS_MATHML_PAINT_BOUNDING_METRICS(_flags) \
```

```
(NS_MATHML_SHOW_BOUNDING_METRICS == \
```

```
((_flags)&NS_MATHML_SHOW_BOUNDING_METRICS))
```

```
```

```
// ==========================================================================
```

```
// Bits used for the embellish flags -- these bits are set
```

```
// in their relevant situation as they become available
```

```
```

```
// This bit is set if the frame is an embellished operator.
```

```
#define NS_MATHML_EMBELLISH_OPERATOR 0x00000001
```

```
```

```
// This bit is set if the frame is an <mo> frame or an embellihsed
```

```
// operator for which the core <mo> has movablelimits="true"
```

```
#define NS_MATHML_EMBELLISH_MOVABLELIMITS 0x00000002
```

```
```

```
// This bit is set if the frame is an <mo> frame or an embellihsed
```

```
// operator for which the core <mo> has accent="true"
```

```
#define NS_MATHML_EMBELLISH_ACCENT 0x00000004
```

```
```

```
// This bit is set if the frame is an <mover> or <munderover> with
```

```
// an accent frame
```

```
#define NS_MATHML_EMBELLISH_ACCENTOVER 0x00000008
```

```
```

```
// This bit is set if the frame is an <munder> or <munderover> with
```

```
// an accentunder frame
```

```
#define NS_MATHML_EMBELLISH_ACCENTUNDER 0x00000010
```

```
```

```
// This bit is set on the core if it is a fence operator.
```

```
#define NS_MATHML_EMBELLISH_FENCE 0x00000020
```

```
```

```
// This bit is set on the core if it is a separator operator.
```

```
#define NS_MATHML_EMBELLISH_SEPARATOR 0x00000040
```

```
```

```
// Macros that retrieve those bits
```

```
```

```
#define NS_MATHML_IS_EMBELLISH_OPERATOR(_flags) \
```

```
(NS_MATHML_EMBELLISH_OPERATOR == ((_flags)&NS_MATHML_EMBELLISH_OPERATOR))
```

```
```

```
#define NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(_flags) \
```

```
(NS_MATHML_EMBELLISH_MOVABLELIMITS == \
```

```
((_flags)&NS_MATHML_EMBELLISH_MOVABLELIMITS))
```

```
```

```
#define NS_MATHML_EMBELLISH_IS_ACCENT(_flags) \
```

```
(NS_MATHML_EMBELLISH_ACCENT == ((_flags)&NS_MATHML_EMBELLISH_ACCENT))
```

```
```

```
#define NS_MATHML_EMBELLISH_IS_ACCENTOVER(_flags) \
```

```
(NS_MATHML_EMBELLISH_ACCENTOVER == ((_flags)&NS_MATHML_EMBELLISH_ACCENTOVER))
```

```
```

```
#define NS_MATHML_EMBELLISH_IS_ACCENTUNDER(_flags) \
```

```
(NS_MATHML_EMBELLISH_ACCENTUNDER == \
```

```
((_flags)&NS_MATHML_EMBELLISH_ACCENTUNDER))
```

```
```

```
#define NS_MATHML_EMBELLISH_IS_FENCE(_flags) \
```

```
(NS_MATHML_EMBELLISH_FENCE == ((_flags)&NS_MATHML_EMBELLISH_FENCE))
```

```
```

```
#define NS_MATHML_EMBELLISH_IS_SEPARATOR(_flags) \
```

```
(NS_MATHML_EMBELLISH_SEPARATOR == ((_flags)&NS_MATHML_EMBELLISH_SEPARATOR))
```

```
```

```
#endif /* nsIMathMLFrame_h___ */
```