tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsIMathMLFrame.h (12940B)


      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 #ifndef nsIMathMLFrame_h___
      7 #define nsIMathMLFrame_h___
      8 
      9 #include "nsMathMLOperators.h"
     10 #include "nsQueryFrame.h"
     11 
     12 struct nsPresentationData;
     13 struct nsEmbellishData;
     14 class gfxContext;
     15 class nsIFrame;
     16 namespace mozilla {
     17 class ReflowOutput;
     18 }  // namespace mozilla
     19 
     20 // For MathML, this 'type' will be used to determine the spacing between frames
     21 // Subclasses can return a 'type' that will give them a particular spacing
     22 enum class MathMLFrameType {
     23  Unknown = -1,
     24  Ordinary,
     25  OperatorOrdinary,
     26  OperatorInvisible,
     27  OperatorUserDefined,
     28  Inner,
     29  ItalicIdentifier,
     30  UprightIdentifier,
     31  Count
     32 };
     33 
     34 // Bits used for the presentation flags -- these bits are set
     35 // in their relevant situation as they become available
     36 enum class MathMLPresentationFlag : uint8_t {
     37  // This bit is used to emulate TeX rendering.
     38  // Internal use only, cannot be set by the user with an attribute.
     39  Compressed,
     40 
     41  // This bit is set if the frame will fire a vertical stretch
     42  // command on all its (non-empty) children.
     43  // Tags like <mrow> (or an inferred mrow), mpadded, etc, will fire a
     44  // vertical stretch command on all their non-empty children
     45  StretchAllChildrenVertically,
     46 
     47  // This bit is set if the frame will fire a horizontal stretch
     48  // command on all its (non-empty) children.
     49  // Tags like munder, mover, munderover, will fire a
     50  // horizontal stretch command on all their non-empty children
     51  StretchAllChildrenHorizontally,
     52 
     53  // This bit is set if the frame is "space-like", as defined by the spec.
     54  SpaceLike,
     55 
     56  // This bit is set if a token frame should be rendered with the dtls font
     57  // feature setting.
     58  Dtls,
     59 
     60  // a bit used for debug
     61  StretchDone,
     62 };
     63 using MathMLPresentationFlags = mozilla::EnumSet<MathMLPresentationFlag>;
     64 
     65 // Bits used for the embellish flags -- these bits are set
     66 // in their relevant situation as they become available
     67 enum class MathMLEmbellishFlag : uint8_t {
     68  // This bit is set if the frame is an embellished operator.
     69  EmbellishedOperator,
     70 
     71  // This bit is set if the frame is an <mo> frame or an embellihsed
     72  // operator for which the core <mo> has movablelimits="true"
     73  MovableLimits,
     74 
     75  // This bit is set if the frame is an <mo> frame or an embellihsed
     76  // operator for which the core <mo> has accent="true"
     77  Accent,
     78 
     79  // This bit is set if the frame is an <mover> or <munderover> with
     80  // an accent frame
     81  AccentOver,
     82 
     83  // This bit is set if the frame is an <munder> or <munderover> with
     84  // an accentunder frame
     85  AccentUnder,
     86 
     87  // This bit is set on the core if it is a fence operator.
     88  Fence,
     89 
     90  // This bit is set on the core if it is a separator operator.
     91  Separator,
     92 };
     93 using MathMLEmbellishFlags = mozilla::EnumSet<MathMLEmbellishFlag>;
     94 
     95 // Abstract base class that provides additional methods for MathML frames
     96 class nsIMathMLFrame {
     97 public:
     98  NS_DECL_QUERYFRAME_TARGET(nsIMathMLFrame)
     99 
    100  // helper to check whether the frame is "space-like", as defined by the spec.
    101  virtual bool IsSpaceLike() = 0;
    102 
    103  /* SUPPORT FOR PRECISE POSITIONING */
    104  /*====================================================================*/
    105 
    106  /* Metrics that _exactly_ enclose the text of the frame.
    107   * The frame *must* have *already* being reflowed, before you can call
    108   * the GetBoundingMetrics() method.
    109   * Note that for a frame with nested children, the bounding metrics
    110   * will exactly enclose its children. For example, the bounding metrics
    111   * of msub is the smallest rectangle that exactly encloses both the
    112   * base and the subscript.
    113   */
    114  NS_IMETHOD
    115  GetBoundingMetrics(nsBoundingMetrics& aBoundingMetrics) = 0;
    116 
    117  NS_IMETHOD
    118  SetBoundingMetrics(const nsBoundingMetrics& aBoundingMetrics) = 0;
    119 
    120  NS_IMETHOD
    121  SetReference(const nsPoint& aReference) = 0;
    122 
    123  virtual MathMLFrameType GetMathMLFrameType() = 0;
    124 
    125  /* SUPPORT FOR STRETCHY ELEMENTS */
    126  /*====================================================================*/
    127 
    128  /* Stretch :
    129   * Called to ask a stretchy MathML frame to stretch itself depending
    130   * on its context.
    131   *
    132   * An embellished frame is treated in a special way. When it receives a
    133   * Stretch() command, it passes the command to its embellished child and
    134   * the stretched size is bubbled up from the inner-most <mo> frame. In other
    135   * words, the stretch command descend through the embellished hierarchy.
    136   *
    137   * @param aStretchDirection [in] the direction where to attempt to
    138   *        stretch.
    139   * @param aContainerSize [in] struct that suggests the maximumn size for
    140   *        the stretched frame. Only member data of the struct that are
    141   *        relevant to the direction are used (the rest is ignored).
    142   * @param aDesiredStretchSize [in/out] On input the current size
    143   *        of the frame, on output the size after stretching.
    144   */
    145  NS_IMETHOD
    146  Stretch(mozilla::gfx::DrawTarget* aDrawTarget,
    147          nsStretchDirection aStretchDirection,
    148          nsBoundingMetrics& aContainerSize,
    149          mozilla::ReflowOutput& aDesiredStretchSize) = 0;
    150 
    151  /* Get the mEmbellishData member variable. */
    152 
    153  NS_IMETHOD
    154  GetEmbellishData(nsEmbellishData& aEmbellishData) = 0;
    155 
    156  /* SUPPORT FOR SCRIPTING ELEMENTS */
    157  /*====================================================================*/
    158 
    159  /* Get the mPresentationData member variable. */
    160 
    161  NS_IMETHOD
    162  GetPresentationData(nsPresentationData& aPresentationData) = 0;
    163 
    164  /* InheritAutomaticData() / TransmitAutomaticData() :
    165   * There are precise rules governing each MathML frame and its children.
    166   * Properties such as the scriptlevel or the embellished nature of a frame
    167   * depend on those rules. Also, certain properties that we use to emulate
    168   * TeX rendering rules are frame-dependent too. These two methods are meant
    169   * to be implemented by frame classes that need to assert specific properties
    170   * within their subtrees.
    171   *
    172   * InheritAutomaticData() is called in a top-down manner [like
    173   * nsIFrame::Init], as we descend the frame tree, whereas
    174   * TransmitAutomaticData() is called in a bottom-up manner, as we ascend the
    175   * tree [like nsIFrame::SetInitialChildList]. However, unlike Init() and
    176   * SetInitialChildList() which are called only once during the life-time of a
    177   * frame (when initially constructing the frame tree), these two methods are
    178   * called to build automatic data after the <math>...</math> subtree has been
    179   * constructed fully, and are called again as we walk a child's subtree to
    180   * handle dynamic changes that happen in the content model.
    181   *
    182   * As a rule of thumb:
    183   *
    184   * 1. Use InheritAutomaticData() to set properties related to your ancestors:
    185   *    - set properties that are intrinsic to yourself
    186   *    - set properties that depend on the state that you expect your ancestors
    187   *      to have already reached in their own InheritAutomaticData().
    188   *    - set properties that your descendants assume that you would have set in
    189   *      your InheritAutomaticData() -- this way, they can safely query them
    190   *      and the process will feed upon itself.
    191   *
    192   * 2. Use TransmitAutomaticData() to set properties related to your
    193   *    descendants:
    194   *    - set properties that depend on the state that you expect your
    195   *      descendants to have reached upon processing their own
    196   *      TransmitAutomaticData().
    197   *    - transmit properties that your descendants expect that you will
    198   *      transmit to them in your TransmitAutomaticData() -- this way, they
    199   *      remain up-to-date.
    200   *    - set properties that your ancestors expect that you would set in your
    201   *      TransmitAutomaticData() -- this way, they can safely query them and
    202   *      the process will feed upon itself.
    203   */
    204 
    205  NS_IMETHOD
    206  InheritAutomaticData(nsIFrame* aParent) = 0;
    207 
    208  NS_IMETHOD
    209  TransmitAutomaticData() = 0;
    210 
    211  /* UpdatePresentationData:
    212   * Updates the frame's compression flag.
    213   * A frame becomes "compressed" (or "cramped") according to TeX rendering
    214   * rules (TeXBook, Ch.17, p.140-141).
    215   *
    216   * @param aFlagsValues [in]
    217   *        The new values (e.g., compress) that are going to be
    218   *        updated.
    219   *
    220   * @param aWhichFlags [in]
    221   *        The flags that are relevant to this call. Since not all calls
    222   *        are meant to update all flags at once, aWhichFlags is used
    223   *        to distinguish flags that need to retain their existing values
    224   *        from flags that need to be turned on (or turned off). If a bit
    225   *        is set in aWhichFlags, then the corresponding value (which
    226   *        can be 0 or 1) is taken from aFlagsValues and applied to the
    227   *        frame. Therefore, by setting their bits in aWhichFlags, and
    228   *        setting their desired values in aFlagsValues, it is possible to
    229   *        update some flags in the frame, leaving the other flags unchanged.
    230   */
    231  NS_IMETHOD
    232  UpdatePresentationData(MathMLPresentationFlags aFlagsValues,
    233                         MathMLPresentationFlags aWhichFlags) = 0;
    234 
    235  /* UpdatePresentationDataFromChildAt :
    236   * Sets compression flag on the whole tree. For child frames
    237   * at aFirstIndex up to aLastIndex, this method sets their
    238   * compression flags. The update is propagated down the subtrees of each of
    239   * these child frames.
    240   *
    241   * @param aFirstIndex [in]
    242   *        Index of the first child from where the update is propagated.
    243   *
    244   * @param aLastIndex [in]
    245   *        Index of the last child where to stop the update.
    246   *        A value of -1 means up to last existing child.
    247   *
    248   * @param aFlagsValues [in]
    249   *        The new values (e.g., compress) that are going to be
    250   *        assigned in the whole sub-trees.
    251   *
    252   * @param aWhichFlags [in]
    253   *        The flags that are relevant to this call. See
    254   * UpdatePresentationData() for more details about this parameter.
    255   */
    256  NS_IMETHOD
    257  UpdatePresentationDataFromChildAt(int32_t aFirstIndex, int32_t aLastIndex,
    258                                    MathMLPresentationFlags aFlagsValues,
    259                                    MathMLPresentationFlags aWhichFlags) = 0;
    260 
    261  // If aFrame is a child frame, returns the script increment which this frame
    262  // imposes on the specified frame, ignoring any artificial adjustments to
    263  // scriptlevel.
    264  // Returns 0 if the specified frame isn't a child frame.
    265  virtual uint8_t ScriptIncrement(nsIFrame* aFrame) = 0;
    266 
    267  // Returns true if the frame is considered to be an mrow for layout purposes.
    268  // This includes inferred mrows, but excludes <mrow> elements with a single
    269  // child.  In the latter case, the child is to be treated as if it wasn't
    270  // within an mrow, so we pretend the mrow isn't mrow-like.
    271  virtual bool IsMrowLike() = 0;
    272 };
    273 
    274 // struct used by a container frame to keep track of its embellishments.
    275 // By convention, the data that we keep here is bubbled from the embellished
    276 // hierarchy, and it remains unchanged unless we have to recover from a change
    277 // that occurs in the embellished hierarchy. The struct remains in its nil
    278 // state in those frames that are not part of the embellished hierarchy.
    279 struct nsEmbellishData {
    280  // bits used to mark certain properties of our embellishments
    281  MathMLEmbellishFlags flags;
    282 
    283  // pointer on the <mo> frame at the core of the embellished hierarchy
    284  nsIFrame* coreFrame = nullptr;
    285 
    286  // stretchy direction that the nsMathMLChar owned by the core <mo> supports
    287  nsStretchDirection direction = NS_STRETCH_DIRECTION_UNSUPPORTED;
    288 
    289  // spacing that may come from <mo> depending on its 'form'. Since
    290  // the 'form' may also depend on the position of the outermost
    291  // embellished ancestor, the set up of these values may require
    292  // looking up the position of our ancestors.
    293  nscoord leadingSpace = 0;
    294  nscoord trailingSpace = 0;
    295 };
    296 
    297 // struct used by a container frame to modulate its presentation.
    298 // By convention, the data that we keep in this struct can change depending
    299 // on any of our ancestors and/or descendants. If a data can be resolved
    300 // solely from the embellished hierarchy, and it remains immutable once
    301 // resolved, we put it in |nsEmbellishData|. If it can be affected by other
    302 // things, it comes here. This struct is updated as we receive information
    303 // transmitted by our ancestors and is kept in sync with changes in our
    304 // descendants that affects us.
    305 struct nsPresentationData {
    306  // bits for: compressed, etc
    307  MathMLPresentationFlags flags;
    308 
    309  // handy pointer on our base child (the 'nucleus' in TeX), but it may be
    310  // null here (e.g., tags like <mrow>, <mfrac>, <mtable>, etc, won't
    311  // pick a particular child in their child list to be the base)
    312  nsIFrame* baseFrame = nullptr;
    313 };
    314 
    315 #endif /* nsIMathMLFrame_h___ */