lengths.ts 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  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 Utility functions for handling dimensions (lengths)
  19. *
  20. * @author dpvc@mathjax.org (Davide Cervone)
  21. */
  22. /**
  23. * A very large number
  24. */
  25. export const BIGDIMEN = 1000000;
  26. /**
  27. * Sizes of various units in pixels
  28. */
  29. export const UNITS: {[unit: string]: number} = {
  30. px: 1,
  31. 'in': 96, // 96 px to an inch
  32. cm: 96 / 2.54, // 2.54 cm to an inch
  33. mm: 96 / 25.4 // 10 mm to a cm
  34. };
  35. /**
  36. * Sizes of various relative units in em's
  37. */
  38. export const RELUNITS: {[unit: string]: number} = {
  39. em: 1,
  40. ex: .431, // this.TEX.x_height;
  41. pt: 1 / 10, // 10 pt to an em
  42. pc: 12 / 10, // 12 pc to a pt
  43. mu: 1 / 18 // 18mu to an em for the scriptlevel
  44. };
  45. /**
  46. * The various named spaces
  47. */
  48. export const MATHSPACE: {[name: string]: number} = {
  49. /* tslint:disable:whitespace */
  50. veryverythinmathspace: 1/18,
  51. verythinmathspace: 2/18,
  52. thinmathspace: 3/18,
  53. mediummathspace: 4/18,
  54. thickmathspace: 5/18,
  55. verythickmathspace: 6/18,
  56. veryverythickmathspace: 7/18,
  57. negativeveryverythinmathspace: -1/18,
  58. negativeverythinmathspace: -2/18,
  59. negativethinmathspace: -3/18,
  60. negativemediummathspace: -4/18,
  61. negativethickmathspace: -5/18,
  62. negativeverythickmathspace: -6/18,
  63. negativeveryverythickmathspace: -7/18,
  64. /* tslint:enable */
  65. thin: .04,
  66. medium: .06,
  67. thick: .1,
  68. normal: 1,
  69. big: 2,
  70. small: 1 / Math.sqrt(2),
  71. infinity: BIGDIMEN
  72. };
  73. /**
  74. * @param {string|number} length A dimension (giving number and units) to be converted to ems
  75. * @param {number} size The default size of the dimension (for percentage values)
  76. * @param {number} scale The current scaling factor (to handle absolute units)
  77. * @param {number} em The size of an em in pixels
  78. * @return {number} The dimension converted to ems
  79. */
  80. export function length2em(length: string | number, size: number = 0, scale: number = 1, em: number = 16): number {
  81. if (typeof length !== 'string') {
  82. length = String(length);
  83. }
  84. if (length === '' || length == null) {
  85. return size;
  86. }
  87. if (MATHSPACE[length]) {
  88. return MATHSPACE[length];
  89. }
  90. let match = length.match(/^\s*([-+]?(?:\.\d+|\d+(?:\.\d*)?))?(pt|em|ex|mu|px|pc|in|mm|cm|%)?/);
  91. if (!match) {
  92. return size;
  93. }
  94. let m = parseFloat(match[1] || '1'), unit = match[2];
  95. if (UNITS.hasOwnProperty(unit)) {
  96. return m * UNITS[unit] / em / scale;
  97. }
  98. if (RELUNITS.hasOwnProperty(unit)) {
  99. return m * RELUNITS[unit];
  100. }
  101. if (unit === '%') {
  102. return m / 100 * size; // percentage of the size
  103. }
  104. return m * size; // relative to size
  105. }
  106. /**
  107. * @param {number} m A number to be shown as a percent
  108. * @return {string} The number m as a percent
  109. */
  110. export function percent(m: number): string {
  111. return (100 * m).toFixed(1).replace(/\.?0+$/, '') + '%';
  112. }
  113. /**
  114. * @param {number} m A number to be shown in ems
  115. * @return {string} The number with units of ems
  116. */
  117. export function em(m: number): string {
  118. if (Math.abs(m) < .001) return '0';
  119. return (m.toFixed(3).replace(/\.?0+$/, '')) + 'em';
  120. }
  121. /**
  122. * @param {number} m A number to be shown in ems, but rounded to pixel boundaries
  123. * @param {number} em The number of pixels in an em
  124. * @return {string} The number with units of em
  125. */
  126. export function emRounded(m: number, em: number = 16): string {
  127. m = (Math.round(m * em) + .05) / em;
  128. if (Math.abs(m) < .001) return '0em';
  129. return m.toFixed(3).replace(/\.?0+$/, '') + 'em';
  130. }
  131. /**
  132. * @param {number} m A number of em's to be shown as pixels
  133. * @param {number} M The minimum number of pixels to allow
  134. * @param {number} em The number of pixels in an em
  135. * @return {string} The number with units of px
  136. */
  137. export function px(m: number, M: number = -BIGDIMEN, em: number = 16): string {
  138. m *= em;
  139. if (M && m < M) m = M;
  140. if (Math.abs(m) < .1) return '0';
  141. return m.toFixed(1).replace(/\.0$/, '') + 'px';
  142. }