layout/mathml/nsIMathMLFrame.h

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

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

mercurial