munderover.ts 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. /*************************************************************
  2. *
  3. * Copyright (c) 2017-2022 The MathJax Consortium
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. /**
  18. * @fileoverview Implements the CommonMunderover wrapper mixin for the MmlMunderover object
  19. * and the special cases CommonMunder and CommonMsup
  20. *
  21. * @author dpvc@mathjax.org (Davide Cervone)
  22. */
  23. import {AnyWrapper, Constructor} from '../Wrapper.js';
  24. import {CommonScriptbase, ScriptbaseConstructor} from './scriptbase.js';
  25. import {MmlMunderover, MmlMunder, MmlMover} from '../../../core/MmlTree/MmlNodes/munderover.js';
  26. import {BBox} from '../../../util/BBox.js';
  27. /*****************************************************************/
  28. /**
  29. * The CommonMunder interface
  30. *
  31. * @template W The child-node Wrapper class
  32. */
  33. export interface CommonMunder<W extends AnyWrapper> extends CommonScriptbase<W> {
  34. }
  35. /**
  36. * Shorthand for the CommonMunder constructor
  37. *
  38. * @template W The child-node Wrapper class
  39. */
  40. export type MunderConstructor<W extends AnyWrapper> = Constructor<CommonMunder<W>>;
  41. /*****************************************************************/
  42. /**
  43. * The CommonMunder wrapper mixin for the MmlMunder object
  44. *
  45. * @template W The child-node Wrapper class
  46. * @template T The Wrapper class constructor type
  47. */
  48. export function CommonMunderMixin<
  49. W extends AnyWrapper,
  50. T extends ScriptbaseConstructor<W>
  51. >(Base: T): MunderConstructor<W> & T {
  52. return class extends Base {
  53. /**
  54. * @override
  55. */
  56. public get scriptChild() {
  57. return this.childNodes[(this.node as MmlMunder).under];
  58. }
  59. /**
  60. * @override
  61. * @constructor
  62. */
  63. constructor(...args: any[]) {
  64. super(...args);
  65. this.stretchChildren();
  66. }
  67. /**
  68. * @override
  69. */
  70. public computeBBox(bbox: BBox, recompute: boolean = false) {
  71. if (this.hasMovableLimits()) {
  72. super.computeBBox(bbox, recompute);
  73. return;
  74. }
  75. bbox.empty();
  76. const basebox = this.baseChild.getOuterBBox();
  77. const underbox = this.scriptChild.getOuterBBox();
  78. const v = this.getUnderKV(basebox, underbox)[1];
  79. const delta = (this.isLineBelow ? 0 : this.getDelta(true));
  80. const [bw, uw] = this.getDeltaW([basebox, underbox], [0, -delta]);
  81. bbox.combine(basebox, bw, 0);
  82. bbox.combine(underbox, uw, v);
  83. bbox.d += this.font.params.big_op_spacing5;
  84. bbox.clean();
  85. this.setChildPWidths(recompute);
  86. }
  87. };
  88. }
  89. /*****************************************************************/
  90. /**
  91. * The CommonMover interface
  92. *
  93. * @template W The child-node Wrapper class
  94. */
  95. export interface CommonMover<W extends AnyWrapper> extends CommonScriptbase<W> {
  96. }
  97. /**
  98. * Shorthand for the CommonMover constructor
  99. *
  100. * @template W The child-node Wrapper class
  101. */
  102. export type MoverConstructor<W extends AnyWrapper> = Constructor<CommonMover<W>>;
  103. /*****************************************************************/
  104. /**
  105. * The CommonMover wrapper mixin for the MmlMover object
  106. *
  107. * @template W The child-node Wrapper class
  108. * @template T The Wrapper class constructor type
  109. */
  110. export function CommonMoverMixin<
  111. W extends AnyWrapper,
  112. T extends ScriptbaseConstructor<W>
  113. >(Base: T): MoverConstructor<W> & T {
  114. return class extends Base {
  115. /**
  116. * @override
  117. */
  118. public get scriptChild() {
  119. return this.childNodes[(this.node as MmlMover).over];
  120. }
  121. /**
  122. * @override
  123. * @constructor
  124. */
  125. constructor(...args: any[]) {
  126. super(...args);
  127. this.stretchChildren();
  128. }
  129. /**
  130. * @override
  131. */
  132. public computeBBox(bbox: BBox) {
  133. if (this.hasMovableLimits()) {
  134. super.computeBBox(bbox);
  135. return;
  136. }
  137. bbox.empty();
  138. const basebox = this.baseChild.getOuterBBox();
  139. const overbox = this.scriptChild.getOuterBBox();
  140. if (this.node.attributes.get('accent')) {
  141. basebox.h = Math.max(basebox.h, this.font.params.x_height * basebox.scale);
  142. }
  143. const u = this.getOverKU(basebox, overbox)[1];
  144. const delta = (this.isLineAbove ? 0 : this.getDelta());
  145. const [bw, ow] = this.getDeltaW([basebox, overbox], [0, delta]);
  146. bbox.combine(basebox, bw, 0);
  147. bbox.combine(overbox, ow, u);
  148. bbox.h += this.font.params.big_op_spacing5;
  149. bbox.clean();
  150. }
  151. };
  152. }
  153. /*****************************************************************/
  154. /**
  155. * The CommonMunderover interface
  156. *
  157. * @template W The child-node Wrapper class
  158. */
  159. export interface CommonMunderover<W extends AnyWrapper> extends CommonScriptbase<W> {
  160. /*
  161. * The wrapped under node
  162. */
  163. readonly underChild: W;
  164. /*
  165. * The wrapped overder node
  166. */
  167. readonly overChild: W;
  168. }
  169. /**
  170. * Shorthand for the CommonMunderover constructor
  171. *
  172. * @template W The child-node Wrapper class
  173. */
  174. export type MunderoverConstructor<W extends AnyWrapper> = Constructor<CommonMunderover<W>>;
  175. /*****************************************************************/
  176. /*
  177. * The CommonMunderover wrapper for the MmlMunderover object
  178. *
  179. * @template W The child-node Wrapper class
  180. * @template T The Wrapper class constructor type
  181. */
  182. export function CommonMunderoverMixin<
  183. W extends AnyWrapper,
  184. T extends ScriptbaseConstructor<W>
  185. >(Base: T): MunderoverConstructor<W> & T {
  186. return class extends Base {
  187. /*
  188. * @return {W} The wrapped under node
  189. */
  190. public get underChild() {
  191. return this.childNodes[(this.node as MmlMunderover).under];
  192. }
  193. /*
  194. * @return {W} The wrapped overder node
  195. */
  196. public get overChild() {
  197. return this.childNodes[(this.node as MmlMunderover).over];
  198. }
  199. /*
  200. * Needed for movablelimits
  201. *
  202. * @override
  203. */
  204. public get subChild() {
  205. return this.underChild;
  206. }
  207. /*
  208. * Needed for movablelimits
  209. *
  210. * @override
  211. */
  212. public get supChild() {
  213. return this.overChild;
  214. }
  215. /**
  216. * @override
  217. * @constructor
  218. */
  219. constructor(...args: any[]) {
  220. super(...args);
  221. this.stretchChildren();
  222. }
  223. /**
  224. * @override
  225. */
  226. public computeBBox(bbox: BBox) {
  227. if (this.hasMovableLimits()) {
  228. super.computeBBox(bbox);
  229. return;
  230. }
  231. bbox.empty();
  232. const overbox = this.overChild.getOuterBBox();
  233. const basebox = this.baseChild.getOuterBBox();
  234. const underbox = this.underChild.getOuterBBox();
  235. if (this.node.attributes.get('accent')) {
  236. basebox.h = Math.max(basebox.h, this.font.params.x_height * basebox.scale);
  237. }
  238. const u = this.getOverKU(basebox, overbox)[1];
  239. const v = this.getUnderKV(basebox, underbox)[1];
  240. const delta = this.getDelta();
  241. const [bw, uw, ow] = this.getDeltaW([basebox, underbox, overbox],
  242. [0, this.isLineBelow ? 0 : -delta, this.isLineAbove ? 0 : delta]);
  243. bbox.combine(basebox, bw, 0);
  244. bbox.combine(overbox, ow, u);
  245. bbox.combine(underbox, uw, v);
  246. const z = this.font.params.big_op_spacing5;
  247. bbox.h += z;
  248. bbox.d += z;
  249. bbox.clean();
  250. }
  251. };
  252. }