layout/mathml/nsIMathMLFrame.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/layout/mathml/nsIMathMLFrame.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,366 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +//#define SHOW_BOUNDING_BOX 1
     1.9 +#ifndef nsIMathMLFrame_h___
    1.10 +#define nsIMathMLFrame_h___
    1.11 +
    1.12 +#include "nsQueryFrame.h"
    1.13 +#include "nsMathMLOperators.h"
    1.14 +
    1.15 +struct nsPresentationData;
    1.16 +struct nsEmbellishData;
    1.17 +struct nsHTMLReflowMetrics;
    1.18 +class nsRenderingContext;
    1.19 +class nsIFrame;
    1.20 +
    1.21 +// For MathML, this 'type' will be used to determine the spacing between frames
    1.22 +// Subclasses can return a 'type' that will give them a particular spacing
    1.23 +enum eMathMLFrameType {
    1.24 +  eMathMLFrameType_UNKNOWN = -1,
    1.25 +  eMathMLFrameType_Ordinary,
    1.26 +  eMathMLFrameType_OperatorOrdinary,
    1.27 +  eMathMLFrameType_OperatorInvisible,
    1.28 +  eMathMLFrameType_OperatorUserDefined,
    1.29 +  eMathMLFrameType_Inner,
    1.30 +  eMathMLFrameType_ItalicIdentifier,
    1.31 +  eMathMLFrameType_UprightIdentifier,
    1.32 +  eMathMLFrameType_COUNT
    1.33 +};
    1.34 +
    1.35 +// Abstract base class that provides additional methods for MathML frames
    1.36 +class nsIMathMLFrame
    1.37 +{
    1.38 +public:
    1.39 +  NS_DECL_QUERYFRAME_TARGET(nsIMathMLFrame)
    1.40 +
    1.41 +  // helper to check whether the frame is "space-like", as defined by the spec.
    1.42 +  virtual bool IsSpaceLike() = 0;
    1.43 +
    1.44 + /* SUPPORT FOR PRECISE POSITIONING */
    1.45 + /*====================================================================*/
    1.46 + 
    1.47 + /* Metrics that _exactly_ enclose the text of the frame.
    1.48 +  * The frame *must* have *already* being reflowed, before you can call
    1.49 +  * the GetBoundingMetrics() method.
    1.50 +  * Note that for a frame with nested children, the bounding metrics
    1.51 +  * will exactly enclose its children. For example, the bounding metrics
    1.52 +  * of msub is the smallest rectangle that exactly encloses both the 
    1.53 +  * base and the subscript.
    1.54 +  */
    1.55 +  NS_IMETHOD
    1.56 +  GetBoundingMetrics(nsBoundingMetrics& aBoundingMetrics) = 0;
    1.57 +
    1.58 +  NS_IMETHOD
    1.59 +  SetBoundingMetrics(const nsBoundingMetrics& aBoundingMetrics) = 0;
    1.60 +
    1.61 +  NS_IMETHOD
    1.62 +  SetReference(const nsPoint& aReference) = 0;
    1.63 +
    1.64 +  virtual eMathMLFrameType GetMathMLFrameType() = 0;
    1.65 +
    1.66 + /* SUPPORT FOR STRETCHY ELEMENTS */
    1.67 + /*====================================================================*/
    1.68 +
    1.69 + /* Stretch :
    1.70 +  * Called to ask a stretchy MathML frame to stretch itself depending
    1.71 +  * on its context.
    1.72 +  *
    1.73 +  * An embellished frame is treated in a special way. When it receives a
    1.74 +  * Stretch() command, it passes the command to its embellished child and
    1.75 +  * the stretched size is bubbled up from the inner-most <mo> frame. In other
    1.76 +  * words, the stretch command descend through the embellished hierarchy.
    1.77 +  *
    1.78 +  * @param aStretchDirection [in] the direction where to attempt to
    1.79 +  *        stretch.
    1.80 +  * @param aContainerSize [in] struct that suggests the maximumn size for
    1.81 +  *        the stretched frame. Only member data of the struct that are 
    1.82 +  *        relevant to the direction are used (the rest is ignored). 
    1.83 +  * @param aDesiredStretchSize [in/out] On input the current size
    1.84 +  *        of the frame, on output the size after stretching.
    1.85 +  */
    1.86 +  NS_IMETHOD 
    1.87 +  Stretch(nsRenderingContext& aRenderingContext,
    1.88 +          nsStretchDirection   aStretchDirection,
    1.89 +          nsBoundingMetrics&   aContainerSize,
    1.90 +          nsHTMLReflowMetrics& aDesiredStretchSize) = 0;
    1.91 +
    1.92 + /* Get the mEmbellishData member variable. */
    1.93 + 
    1.94 +  NS_IMETHOD
    1.95 +  GetEmbellishData(nsEmbellishData& aEmbellishData) = 0;
    1.96 +
    1.97 +
    1.98 + /* SUPPORT FOR SCRIPTING ELEMENTS */
    1.99 + /*====================================================================*/
   1.100 +
   1.101 + /* Get the mPresentationData member variable. */
   1.102 +
   1.103 +  NS_IMETHOD
   1.104 +  GetPresentationData(nsPresentationData& aPresentationData) = 0;
   1.105 +
   1.106 +  /* InheritAutomaticData() / TransmitAutomaticData() :
   1.107 +   * There are precise rules governing each MathML frame and its children.
   1.108 +   * Properties such as the scriptlevel or the embellished nature of a frame
   1.109 +   * depend on those rules. Also, certain properties that we use to emulate
   1.110 +   * TeX rendering rules are frame-dependent too. These two methods are meant
   1.111 +   * to be implemented by frame classes that need to assert specific properties
   1.112 +   * within their subtrees.
   1.113 +   *
   1.114 +   * InheritAutomaticData() is called in a top-down manner [like nsIFrame::Init],
   1.115 +   * as we descend the frame tree, whereas TransmitAutomaticData() is called in a
   1.116 +   * bottom-up manner, as we ascend the tree [like nsIFrame::SetInitialChildList].
   1.117 +   * However, unlike Init() and SetInitialChildList() which are called only once
   1.118 +   * during the life-time of a frame (when initially constructing the frame tree),
   1.119 +   * these two methods are called to build automatic data after the <math>...</math>
   1.120 +   * subtree has been constructed fully, and are called again as we walk a child's
   1.121 +   * subtree to handle dynamic changes that happen in the content model.
   1.122 +   *
   1.123 +   * As a rule of thumb:
   1.124 +   *
   1.125 +   * 1. Use InheritAutomaticData() to set properties related to your ancestors:
   1.126 +   *    - set properties that are intrinsic to yourself
   1.127 +   *    - set properties that depend on the state that you expect your ancestors
   1.128 +   *      to have already reached in their own InheritAutomaticData().
   1.129 +   *    - set properties that your descendants assume that you would have set in
   1.130 +   *      your InheritAutomaticData() -- this way, they can safely query them and
   1.131 +   *      the process will feed upon itself.
   1.132 +   *
   1.133 +   * 2. Use TransmitAutomaticData() to set properties related to your descendants:
   1.134 +   *    - set properties that depend on the state that you expect your descendants
   1.135 +   *      to have reached upon processing their own TransmitAutomaticData().
   1.136 +   *    - transmit properties that your descendants expect that you will transmit to
   1.137 +   *      them in your TransmitAutomaticData() -- this way, they remain up-to-date.
   1.138 +   *    - set properties that your ancestors expect that you would set in your
   1.139 +   *      TransmitAutomaticData() -- this way, they can safely query them and the
   1.140 +   *      process will feed upon itself.
   1.141 +   */
   1.142 +
   1.143 +  NS_IMETHOD
   1.144 +  InheritAutomaticData(nsIFrame* aParent) = 0;
   1.145 +
   1.146 +  NS_IMETHOD
   1.147 +  TransmitAutomaticData() = 0;
   1.148 +
   1.149 + /* UpdatePresentationData:
   1.150 +  * Updates the frame's compression flag.
   1.151 +  * A frame becomes "compressed" (or "cramped") according to TeX rendering
   1.152 +  * rules (TeXBook, Ch.17, p.140-141).
   1.153 +  *
   1.154 +  * @param aFlagsValues [in]
   1.155 +  *        The new values (e.g., compress) that are going to be
   1.156 +  *        updated.
   1.157 +  *
   1.158 +  * @param aWhichFlags [in]
   1.159 +  *        The flags that are relevant to this call. Since not all calls
   1.160 +  *        are meant to update all flags at once, aWhichFlags is used
   1.161 +  *        to distinguish flags that need to retain their existing values
   1.162 +  *        from flags that need to be turned on (or turned off). If a bit
   1.163 +  *        is set in aWhichFlags, then the corresponding value (which
   1.164 +  *        can be 0 or 1) is taken from aFlagsValues and applied to the
   1.165 +  *        frame. Therefore, by setting their bits in aWhichFlags, and
   1.166 +  *        setting their desired values in aFlagsValues, it is possible to
   1.167 +  *        update some flags in the frame, leaving the other flags unchanged.
   1.168 +  */
   1.169 +  NS_IMETHOD
   1.170 +  UpdatePresentationData(uint32_t        aFlagsValues,
   1.171 +                         uint32_t        aWhichFlags) = 0;
   1.172 +
   1.173 + /* UpdatePresentationDataFromChildAt :
   1.174 +  * Sets compression flag on the whole tree. For child frames
   1.175 +  * at aFirstIndex up to aLastIndex, this method sets their
   1.176 +  * compression flags. The update is propagated down the subtrees of each of
   1.177 +  * these child frames. 
   1.178 +  *
   1.179 +  * @param aFirstIndex [in]
   1.180 +  *        Index of the first child from where the update is propagated.
   1.181 +  *
   1.182 +  * @param aLastIndex [in]
   1.183 +  *        Index of the last child where to stop the update.
   1.184 +  *        A value of -1 means up to last existing child.
   1.185 +  *
   1.186 +  * @param aFlagsValues [in]
   1.187 +  *        The new values (e.g., compress) that are going to be
   1.188 +  *        assigned in the whole sub-trees.
   1.189 +  *
   1.190 +  * @param aWhichFlags [in]
   1.191 +  *        The flags that are relevant to this call. See UpdatePresentationData()
   1.192 +  *        for more details about this parameter.
   1.193 +  */
   1.194 +  NS_IMETHOD
   1.195 +  UpdatePresentationDataFromChildAt(int32_t         aFirstIndex,
   1.196 +                                    int32_t         aLastIndex,
   1.197 +                                    uint32_t        aFlagsValues,
   1.198 +                                    uint32_t        aWhichFlags) = 0;
   1.199 +
   1.200 +  // If aFrame is a child frame, returns the script increment which this frame
   1.201 +  // imposes on the specified frame, ignoring any artificial adjustments to
   1.202 +  // scriptlevel.
   1.203 +  // Returns 0 if the specified frame isn't a child frame.
   1.204 +  virtual uint8_t
   1.205 +  ScriptIncrement(nsIFrame* aFrame) = 0;
   1.206 +
   1.207 +  // Returns true if the frame is considered to be an mrow for layout purposes.
   1.208 +  // This includes inferred mrows, but excludes <mrow> elements with a single
   1.209 +  // child.  In the latter case, the child is to be treated as if it wasn't
   1.210 +  // within an mrow, so we pretend the mrow isn't mrow-like.
   1.211 +  virtual bool
   1.212 +  IsMrowLike() = 0;
   1.213 +};
   1.214 +
   1.215 +// struct used by a container frame to keep track of its embellishments.
   1.216 +// By convention, the data that we keep here is bubbled from the embellished
   1.217 +// hierarchy, and it remains unchanged unless we have to recover from a change
   1.218 +// that occurs in the embellished hierarchy. The struct remains in its nil
   1.219 +// state in those frames that are not part of the embellished hierarchy.
   1.220 +struct nsEmbellishData {
   1.221 +  // bits used to mark certain properties of our embellishments 
   1.222 +  uint32_t flags;
   1.223 +
   1.224 +  // pointer on the <mo> frame at the core of the embellished hierarchy
   1.225 +  nsIFrame* coreFrame;
   1.226 +
   1.227 +  // stretchy direction that the nsMathMLChar owned by the core <mo> supports
   1.228 +  nsStretchDirection direction;
   1.229 +
   1.230 +  // spacing that may come from <mo> depending on its 'form'. Since
   1.231 +  // the 'form' may also depend on the position of the outermost
   1.232 +  // embellished ancestor, the set up of these values may require
   1.233 +  // looking up the position of our ancestors.
   1.234 +  nscoord leadingSpace;
   1.235 +  nscoord trailingSpace;
   1.236 +
   1.237 +  nsEmbellishData() {
   1.238 +    flags = 0;
   1.239 +    coreFrame = nullptr;
   1.240 +    direction = NS_STRETCH_DIRECTION_UNSUPPORTED;
   1.241 +    leadingSpace = 0;
   1.242 +    trailingSpace = 0;
   1.243 +  }
   1.244 +};
   1.245 +
   1.246 +// struct used by a container frame to modulate its presentation.
   1.247 +// By convention, the data that we keep in this struct can change depending
   1.248 +// on any of our ancestors and/or descendants. If a data can be resolved
   1.249 +// solely from the embellished hierarchy, and it remains immutable once
   1.250 +// resolved, we put it in |nsEmbellishData|. If it can be affected by other
   1.251 +// things, it comes here. This struct is updated as we receive information
   1.252 +// transmitted by our ancestors and is kept in sync with changes in our
   1.253 +// descendants that affects us.
   1.254 +struct nsPresentationData {
   1.255 +  // bits for: compressed, etc
   1.256 +  uint32_t flags;
   1.257 +
   1.258 +  // handy pointer on our base child (the 'nucleus' in TeX), but it may be
   1.259 +  // null here (e.g., tags like <mrow>, <mfrac>, <mtable>, etc, won't
   1.260 +  // pick a particular child in their child list to be the base)
   1.261 +  nsIFrame* baseFrame;
   1.262 +
   1.263 +  nsPresentationData() {
   1.264 +    flags = 0;
   1.265 +    baseFrame = nullptr;
   1.266 +  }
   1.267 +};
   1.268 +
   1.269 +// ==========================================================================
   1.270 +// Bits used for the presentation flags -- these bits are set
   1.271 +// in their relevant situation as they become available
   1.272 +
   1.273 +// This bit is used to emulate TeX rendering. 
   1.274 +// Internal use only, cannot be set by the user with an attribute.
   1.275 +#define NS_MATHML_COMPRESSED                          0x00000002U
   1.276 +
   1.277 +// This bit is set if the frame will fire a vertical stretch
   1.278 +// command on all its (non-empty) children.
   1.279 +// Tags like <mrow> (or an inferred mrow), mpadded, etc, will fire a
   1.280 +// vertical stretch command on all their non-empty children
   1.281 +#define NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY     0x00000004U
   1.282 +
   1.283 +// This bit is set if the frame will fire a horizontal stretch
   1.284 +// command on all its (non-empty) children.
   1.285 +// Tags like munder, mover, munderover, will fire a 
   1.286 +// horizontal stretch command on all their non-empty children
   1.287 +#define NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY   0x00000008U
   1.288 +
   1.289 +// This bit is set if the frame is "space-like", as defined by the spec.
   1.290 +#define NS_MATHML_SPACE_LIKE                          0x00000040U
   1.291 +
   1.292 +// This bit is set when the frame cannot be formatted due to an
   1.293 +// error (e.g., invalid markup such as a <msup> without an overscript).
   1.294 +// When set, a visual feedback will be provided to the user.
   1.295 +#define NS_MATHML_ERROR                               0x80000000U
   1.296 +
   1.297 +// a bit used for debug
   1.298 +#define NS_MATHML_STRETCH_DONE                        0x20000000U
   1.299 +
   1.300 +// This bit is used for visual debug. When set, the bounding box
   1.301 +// of your frame is painted. This visual debug enable to ensure that
   1.302 +// you have properly filled your mReference and mBoundingMetrics in
   1.303 +// Place().
   1.304 +#define NS_MATHML_SHOW_BOUNDING_METRICS               0x10000000U
   1.305 +
   1.306 +// Macros that retrieve those bits
   1.307 +
   1.308 +#define NS_MATHML_IS_COMPRESSED(_flags) \
   1.309 +  (NS_MATHML_COMPRESSED == ((_flags) & NS_MATHML_COMPRESSED))
   1.310 +
   1.311 +#define NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(_flags) \
   1.312 +  (NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY == ((_flags) & NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY))
   1.313 +
   1.314 +#define NS_MATHML_WILL_STRETCH_ALL_CHILDREN_HORIZONTALLY(_flags) \
   1.315 +  (NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY == ((_flags) & NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY))
   1.316 +
   1.317 +#define NS_MATHML_IS_SPACE_LIKE(_flags) \
   1.318 +  (NS_MATHML_SPACE_LIKE == ((_flags) & NS_MATHML_SPACE_LIKE))
   1.319 +
   1.320 +#define NS_MATHML_HAS_ERROR(_flags) \
   1.321 +  (NS_MATHML_ERROR == ((_flags) & NS_MATHML_ERROR))
   1.322 +
   1.323 +#define NS_MATHML_STRETCH_WAS_DONE(_flags) \
   1.324 +  (NS_MATHML_STRETCH_DONE == ((_flags) & NS_MATHML_STRETCH_DONE))
   1.325 +
   1.326 +#define NS_MATHML_PAINT_BOUNDING_METRICS(_flags) \
   1.327 +  (NS_MATHML_SHOW_BOUNDING_METRICS == ((_flags) & NS_MATHML_SHOW_BOUNDING_METRICS))
   1.328 +
   1.329 +// ==========================================================================
   1.330 +// Bits used for the embellish flags -- these bits are set
   1.331 +// in their relevant situation as they become available
   1.332 +
   1.333 +// This bit is set if the frame is an embellished operator. 
   1.334 +#define NS_MATHML_EMBELLISH_OPERATOR                0x00000001
   1.335 +
   1.336 +// This bit is set if the frame is an <mo> frame or an embellihsed
   1.337 +// operator for which the core <mo> has movablelimits="true"
   1.338 +#define NS_MATHML_EMBELLISH_MOVABLELIMITS           0x00000002
   1.339 +
   1.340 +// This bit is set if the frame is an <mo> frame or an embellihsed
   1.341 +// operator for which the core <mo> has accent="true"
   1.342 +#define NS_MATHML_EMBELLISH_ACCENT                  0x00000004
   1.343 +
   1.344 +// This bit is set if the frame is an <mover> or <munderover> with
   1.345 +// an accent frame
   1.346 +#define NS_MATHML_EMBELLISH_ACCENTOVER              0x00000008
   1.347 +
   1.348 +// This bit is set if the frame is an <munder> or <munderover> with
   1.349 +// an accentunder frame
   1.350 +#define NS_MATHML_EMBELLISH_ACCENTUNDER             0x00000010
   1.351 +
   1.352 +// Macros that retrieve those bits
   1.353 +
   1.354 +#define NS_MATHML_IS_EMBELLISH_OPERATOR(_flags) \
   1.355 +  (NS_MATHML_EMBELLISH_OPERATOR == ((_flags) & NS_MATHML_EMBELLISH_OPERATOR))
   1.356 +
   1.357 +#define NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(_flags) \
   1.358 +  (NS_MATHML_EMBELLISH_MOVABLELIMITS == ((_flags) & NS_MATHML_EMBELLISH_MOVABLELIMITS))
   1.359 +
   1.360 +#define NS_MATHML_EMBELLISH_IS_ACCENT(_flags) \
   1.361 +  (NS_MATHML_EMBELLISH_ACCENT == ((_flags) & NS_MATHML_EMBELLISH_ACCENT))
   1.362 +
   1.363 +#define NS_MATHML_EMBELLISH_IS_ACCENTOVER(_flags) \
   1.364 +  (NS_MATHML_EMBELLISH_ACCENTOVER == ((_flags) & NS_MATHML_EMBELLISH_ACCENTOVER))
   1.365 +
   1.366 +#define NS_MATHML_EMBELLISH_IS_ACCENTUNDER(_flags) \
   1.367 +  (NS_MATHML_EMBELLISH_ACCENTUNDER == ((_flags) & NS_MATHML_EMBELLISH_ACCENTUNDER))
   1.368 +
   1.369 +#endif /* nsIMathMLFrame_h___ */

mercurial