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