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