TextNode.ts 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  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 CommonTextNode wrapper mixin for the TextNode object
  19. *
  20. * @author dpvc@mathjax.org (Davide Cervone)
  21. */
  22. import {AnyWrapper, WrapperConstructor, Constructor} from '../Wrapper.js';
  23. import {BBox} from '../../../util/BBox.js';
  24. import {TextNode} from '../../../core/MmlTree/MmlNode.js';
  25. /*****************************************************************/
  26. /**
  27. * The CommonTextNode interface
  28. */
  29. export interface CommonTextNode extends AnyWrapper {
  30. /**
  31. * @param {string} text The text to remap
  32. * @param {string} variant The variant for the character
  33. * @return {number[]} The unicode points for the (remapped) text
  34. */
  35. remappedText(text: string, variant: string): number[];
  36. }
  37. /**
  38. * Shorthand for the CommonTextNode constructor
  39. */
  40. export type TextNodeConstructor = Constructor<CommonTextNode>;
  41. /*****************************************************************/
  42. /**
  43. * The CommonTextNode wrapper mixin for the TextNode object
  44. *
  45. * @template T The Wrapper class constructor type
  46. */
  47. export function CommonTextNodeMixin<T extends WrapperConstructor>(Base: T): TextNodeConstructor & T {
  48. return class extends Base {
  49. /**
  50. * @override
  51. */
  52. public computeBBox(bbox: BBox, _recompute: boolean = false) {
  53. const variant = this.parent.variant;
  54. const text = (this.node as TextNode).getText();
  55. if (variant === '-explicitFont') {
  56. //
  57. // Measure the size of the text (using the DOM if possible)
  58. //
  59. const font = this.jax.getFontData(this.parent.styles);
  60. const {w, h, d} = this.jax.measureText(text, variant, font);
  61. bbox.h = h;
  62. bbox.d = d;
  63. bbox.w = w;
  64. } else {
  65. const chars = this.remappedText(text, variant);
  66. bbox.empty();
  67. //
  68. // Loop through the characters and add them in one by one
  69. //
  70. for (const char of chars) {
  71. let [h, d, w, data] = this.getVariantChar(variant, char);
  72. if (data.unknown) {
  73. //
  74. // Measure unknown characters using the DOM (if possible)
  75. //
  76. const cbox = this.jax.measureText(String.fromCodePoint(char), variant);
  77. w = cbox.w;
  78. h = cbox.h;
  79. d = cbox.d;
  80. }
  81. //
  82. // Update the bounding box
  83. //
  84. bbox.w += w;
  85. if (h > bbox.h) bbox.h = h;
  86. if (d > bbox.d) bbox.d = d;
  87. bbox.ic = data.ic || 0;
  88. bbox.sk = data.sk || 0;
  89. bbox.dx = data.dx || 0;
  90. }
  91. if (chars.length > 1) {
  92. bbox.sk = 0;
  93. }
  94. bbox.clean();
  95. }
  96. }
  97. /**
  98. * @param {string} text The text to remap
  99. * @param {string} variant The variant for the character
  100. * @return {number[]} The unicode points for the (remapped) text
  101. */
  102. public remappedText(text: string, variant: string): number[] {
  103. const c = this.parent.stretch.c;
  104. return (c ? [c] : this.parent.remapChars(this.unicodeChars(text, variant)));
  105. }
  106. /******************************************************/
  107. /*
  108. * TextNodes don't need these, since these properties
  109. * are inherited from the parent nodes
  110. */
  111. /**
  112. * @override
  113. */
  114. public getStyles() {}
  115. /**
  116. * @override
  117. */
  118. public getVariant() {}
  119. /**
  120. * @override
  121. */
  122. public getScale() {}
  123. /**
  124. * @override
  125. */
  126. public getSpace() {}
  127. };
  128. }