nsIMathMLFrame.h 16 KB

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