umwd-components 0.1.827 → 0.1.829

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (442) hide show
  1. package/dist/cjs/node_modules/object-assign/index.js +2 -2
  2. package/dist/cjs/node_modules/prop-types/factoryWithTypeCheckers.js +1 -1
  3. package/dist/cjs/node_modules/prop-types/index.js +1 -1
  4. package/dist/cjs/node_modules/prop-types/node_modules/react-is/index.js +1 -1
  5. package/dist/cjs/node_modules/safe-buffer/index.js +1 -1
  6. package/dist/cjs/src/components/e-commerce/products/EditReturnStockForm.js +1 -1
  7. package/dist/cjs/src/components/logistics/report/ReportMakingComponent.js +1 -1
  8. package/dist/cjs/src/components/logistics/vendor/EditVendorForm.js +1 -1
  9. package/dist/cjs/src/data/actions/e-commerce/lead/contactFormAction.js +7 -0
  10. package/dist/cjs/src/data/actions/logistics/note/createNoteAction.js +1 -1
  11. package/dist/cjs/src/data/actions/logistics/report/createReportAction.js +1 -1
  12. package/dist/cjs/src/index.js +1 -1
  13. package/dist/cjs/tsconfig.build.tsbuildinfo +1 -1
  14. package/dist/esm/_virtual/index2.js +2 -2
  15. package/dist/esm/_virtual/index3.js +2 -2
  16. package/dist/esm/_virtual/index4.js +2 -2
  17. package/dist/esm/node_modules/object-assign/index.js +74 -69
  18. package/dist/esm/node_modules/prop-types/factoryWithTypeCheckers.js +2 -2
  19. package/dist/esm/node_modules/prop-types/index.js +1 -1
  20. package/dist/esm/node_modules/prop-types/node_modules/react-is/index.js +1 -1
  21. package/dist/esm/node_modules/safe-buffer/index.js +1 -1
  22. package/dist/esm/src/components/e-commerce/products/EditReturnStockForm.js +11 -22
  23. package/dist/esm/src/components/logistics/report/ReportMakingComponent.js +0 -1
  24. package/dist/esm/src/components/logistics/vendor/EditVendorForm.js +0 -1
  25. package/dist/esm/src/data/actions/e-commerce/lead/contactFormAction.js +42 -0
  26. package/dist/esm/src/data/actions/logistics/note/createNoteAction.js +0 -2
  27. package/dist/esm/src/data/actions/logistics/report/createReportAction.js +0 -2
  28. package/dist/esm/src/index.js +1 -1
  29. package/dist/esm/tsconfig.build.tsbuildinfo +1 -1
  30. package/dist/esm/types/data/actions/e-commerce/lead/contactFormAction.d.ts +1 -0
  31. package/dist/esm/types/index.d.ts +1 -3
  32. package/package.json +1 -1
  33. package/dist/cjs/_virtual/_commonjs-dynamic-modules.js +0 -6
  34. package/dist/cjs/_virtual/aes.js +0 -6
  35. package/dist/cjs/_virtual/b64.js +0 -6
  36. package/dist/cjs/_virtual/blowfish.js +0 -6
  37. package/dist/cjs/_virtual/cipher-core.js +0 -6
  38. package/dist/cjs/_virtual/clone.js +0 -6
  39. package/dist/cjs/_virtual/common.js +0 -6
  40. package/dist/cjs/_virtual/context.js +0 -6
  41. package/dist/cjs/_virtual/core2.js +0 -6
  42. package/dist/cjs/_virtual/decode.js +0 -6
  43. package/dist/cjs/_virtual/deflate.js +0 -6
  44. package/dist/cjs/_virtual/dictionary-browser.js +0 -6
  45. package/dist/cjs/_virtual/dictionary.js +0 -6
  46. package/dist/cjs/_virtual/en-us.js +0 -6
  47. package/dist/cjs/_virtual/enc-base64.js +0 -6
  48. package/dist/cjs/_virtual/enc-base64url.js +0 -6
  49. package/dist/cjs/_virtual/enc-utf16.js +0 -6
  50. package/dist/cjs/_virtual/events.js +0 -6
  51. package/dist/cjs/_virtual/evpkdf.js +0 -6
  52. package/dist/cjs/_virtual/format-hex.js +0 -6
  53. package/dist/cjs/_virtual/hmac.js +0 -6
  54. package/dist/cjs/_virtual/huffman.js +0 -6
  55. package/dist/cjs/_virtual/hyphen.js +0 -6
  56. package/dist/cjs/_virtual/index10.js +0 -6
  57. package/dist/cjs/_virtual/index5.js +0 -6
  58. package/dist/cjs/_virtual/index6.js +0 -6
  59. package/dist/cjs/_virtual/index7.js +0 -6
  60. package/dist/cjs/_virtual/index8.js +0 -6
  61. package/dist/cjs/_virtual/index9.js +0 -6
  62. package/dist/cjs/_virtual/inflate.js +0 -6
  63. package/dist/cjs/_virtual/inherits_browser.js +0 -6
  64. package/dist/cjs/_virtual/lib-typedarrays.js +0 -6
  65. package/dist/cjs/_virtual/md5.js +0 -6
  66. package/dist/cjs/_virtual/mode-cfb.js +0 -6
  67. package/dist/cjs/_virtual/mode-ctr-gladman.js +0 -6
  68. package/dist/cjs/_virtual/mode-ctr.js +0 -6
  69. package/dist/cjs/_virtual/mode-ecb.js +0 -6
  70. package/dist/cjs/_virtual/mode-ofb.js +0 -6
  71. package/dist/cjs/_virtual/pad-ansix923.js +0 -6
  72. package/dist/cjs/_virtual/pad-iso10126.js +0 -6
  73. package/dist/cjs/_virtual/pad-iso97971.js +0 -6
  74. package/dist/cjs/_virtual/pad-nopadding.js +0 -6
  75. package/dist/cjs/_virtual/pad-zeropadding.js +0 -6
  76. package/dist/cjs/_virtual/pbkdf2.js +0 -6
  77. package/dist/cjs/_virtual/prefix.js +0 -6
  78. package/dist/cjs/_virtual/rabbit-legacy.js +0 -6
  79. package/dist/cjs/_virtual/rabbit.js +0 -6
  80. package/dist/cjs/_virtual/rc4.js +0 -6
  81. package/dist/cjs/_virtual/ripemd160.js +0 -6
  82. package/dist/cjs/_virtual/scheduler.development.js +0 -6
  83. package/dist/cjs/_virtual/scheduler.production.js +0 -6
  84. package/dist/cjs/_virtual/sha1.js +0 -6
  85. package/dist/cjs/_virtual/sha224.js +0 -6
  86. package/dist/cjs/_virtual/sha256.js +0 -6
  87. package/dist/cjs/_virtual/sha3.js +0 -6
  88. package/dist/cjs/_virtual/sha384.js +0 -6
  89. package/dist/cjs/_virtual/sha512.js +0 -6
  90. package/dist/cjs/_virtual/streams.js +0 -6
  91. package/dist/cjs/_virtual/transform.js +0 -6
  92. package/dist/cjs/_virtual/trees.js +0 -6
  93. package/dist/cjs/_virtual/tripledes.js +0 -6
  94. package/dist/cjs/_virtual/x64-core.js +0 -6
  95. package/dist/cjs/node_modules/@react-pdf/fns/lib/index.js +0 -6
  96. package/dist/cjs/node_modules/@react-pdf/font/lib/index.browser.js +0 -6
  97. package/dist/cjs/node_modules/@react-pdf/image/lib/index.browser.js +0 -6
  98. package/dist/cjs/node_modules/@react-pdf/layout/lib/index.js +0 -6
  99. package/dist/cjs/node_modules/@react-pdf/pdfkit/lib/pdfkit.browser.js +0 -6
  100. package/dist/cjs/node_modules/@react-pdf/png-js/lib/png-js.browser.js +0 -6
  101. package/dist/cjs/node_modules/@react-pdf/primitives/lib/index.js +0 -6
  102. package/dist/cjs/node_modules/@react-pdf/reconciler/lib/index.js +0 -6
  103. package/dist/cjs/node_modules/@react-pdf/reconciler/lib/reconciler-23.js +0 -14
  104. package/dist/cjs/node_modules/@react-pdf/reconciler/lib/reconciler-31.js +0 -26
  105. package/dist/cjs/node_modules/@react-pdf/render/lib/index.js +0 -6
  106. package/dist/cjs/node_modules/@react-pdf/renderer/lib/react-pdf.browser.js +0 -6
  107. package/dist/cjs/node_modules/@react-pdf/stylesheet/lib/index.js +0 -6
  108. package/dist/cjs/node_modules/@react-pdf/textkit/lib/textkit.js +0 -13
  109. package/dist/cjs/node_modules/@swc/helpers/esm/_define_property.js +0 -6
  110. package/dist/cjs/node_modules/abs-svg-path/index.js +0 -6
  111. package/dist/cjs/node_modules/base64-js/index.js +0 -6
  112. package/dist/cjs/node_modules/bidi-js/dist/bidi.js +0 -6
  113. package/dist/cjs/node_modules/brotli/dec/bit_reader.js +0 -6
  114. package/dist/cjs/node_modules/brotli/dec/context.js +0 -6
  115. package/dist/cjs/node_modules/brotli/dec/decode.js +0 -6
  116. package/dist/cjs/node_modules/brotli/dec/dictionary-browser.js +0 -6
  117. package/dist/cjs/node_modules/brotli/dec/dictionary.bin.js +0 -6
  118. package/dist/cjs/node_modules/brotli/dec/dictionary.js +0 -6
  119. package/dist/cjs/node_modules/brotli/dec/huffman.js +0 -6
  120. package/dist/cjs/node_modules/brotli/dec/prefix.js +0 -6
  121. package/dist/cjs/node_modules/brotli/dec/streams.js +0 -6
  122. package/dist/cjs/node_modules/brotli/dec/transform.js +0 -6
  123. package/dist/cjs/node_modules/brotli/decompress.js +0 -6
  124. package/dist/cjs/node_modules/clone/clone.js +0 -6
  125. package/dist/cjs/node_modules/color-name/index.js +0 -6
  126. package/dist/cjs/node_modules/color-string/index.js +0 -6
  127. package/dist/cjs/node_modules/crypto-js/aes.js +0 -6
  128. package/dist/cjs/node_modules/crypto-js/blowfish.js +0 -6
  129. package/dist/cjs/node_modules/crypto-js/cipher-core.js +0 -6
  130. package/dist/cjs/node_modules/crypto-js/core.js +0 -6
  131. package/dist/cjs/node_modules/crypto-js/enc-base64.js +0 -6
  132. package/dist/cjs/node_modules/crypto-js/enc-base64url.js +0 -6
  133. package/dist/cjs/node_modules/crypto-js/enc-utf16.js +0 -6
  134. package/dist/cjs/node_modules/crypto-js/evpkdf.js +0 -6
  135. package/dist/cjs/node_modules/crypto-js/format-hex.js +0 -6
  136. package/dist/cjs/node_modules/crypto-js/hmac.js +0 -6
  137. package/dist/cjs/node_modules/crypto-js/index.js +0 -6
  138. package/dist/cjs/node_modules/crypto-js/lib-typedarrays.js +0 -6
  139. package/dist/cjs/node_modules/crypto-js/md5.js +0 -6
  140. package/dist/cjs/node_modules/crypto-js/mode-cfb.js +0 -6
  141. package/dist/cjs/node_modules/crypto-js/mode-ctr-gladman.js +0 -12
  142. package/dist/cjs/node_modules/crypto-js/mode-ctr.js +0 -6
  143. package/dist/cjs/node_modules/crypto-js/mode-ecb.js +0 -6
  144. package/dist/cjs/node_modules/crypto-js/mode-ofb.js +0 -6
  145. package/dist/cjs/node_modules/crypto-js/pad-ansix923.js +0 -6
  146. package/dist/cjs/node_modules/crypto-js/pad-iso10126.js +0 -6
  147. package/dist/cjs/node_modules/crypto-js/pad-iso97971.js +0 -6
  148. package/dist/cjs/node_modules/crypto-js/pad-nopadding.js +0 -6
  149. package/dist/cjs/node_modules/crypto-js/pad-zeropadding.js +0 -6
  150. package/dist/cjs/node_modules/crypto-js/pbkdf2.js +0 -6
  151. package/dist/cjs/node_modules/crypto-js/rabbit-legacy.js +0 -6
  152. package/dist/cjs/node_modules/crypto-js/rabbit.js +0 -6
  153. package/dist/cjs/node_modules/crypto-js/rc4.js +0 -6
  154. package/dist/cjs/node_modules/crypto-js/ripemd160.js +0 -17
  155. package/dist/cjs/node_modules/crypto-js/sha1.js +0 -6
  156. package/dist/cjs/node_modules/crypto-js/sha224.js +0 -6
  157. package/dist/cjs/node_modules/crypto-js/sha256.js +0 -6
  158. package/dist/cjs/node_modules/crypto-js/sha3.js +0 -6
  159. package/dist/cjs/node_modules/crypto-js/sha384.js +0 -6
  160. package/dist/cjs/node_modules/crypto-js/sha512.js +0 -6
  161. package/dist/cjs/node_modules/crypto-js/tripledes.js +0 -6
  162. package/dist/cjs/node_modules/crypto-js/x64-core.js +0 -6
  163. package/dist/cjs/node_modules/dfa/index.js +0 -6
  164. package/dist/cjs/node_modules/emoji-regex/index.js +0 -6
  165. package/dist/cjs/node_modules/events/events.js +0 -6
  166. package/dist/cjs/node_modules/fast-deep-equal/index.js +0 -6
  167. package/dist/cjs/node_modules/fontkit/dist/browser-module.js +0 -6
  168. package/dist/cjs/node_modules/hsl-to-hex/index.js +0 -6
  169. package/dist/cjs/node_modules/hsl-to-rgb-for-reals/converter.js +0 -6
  170. package/dist/cjs/node_modules/hyphen/hyphen.js +0 -6
  171. package/dist/cjs/node_modules/hyphen/patterns/en-us.js +0 -6
  172. package/dist/cjs/node_modules/inherits/inherits_browser.js +0 -6
  173. package/dist/cjs/node_modules/jay-peg/src/index.js +0 -6
  174. package/dist/cjs/node_modules/jay-peg/src/markers/dac.js +0 -6
  175. package/dist/cjs/node_modules/jay-peg/src/markers/dht.js +0 -6
  176. package/dist/cjs/node_modules/jay-peg/src/markers/dqt.js +0 -6
  177. package/dist/cjs/node_modules/jay-peg/src/markers/dri.js +0 -6
  178. package/dist/cjs/node_modules/jay-peg/src/markers/eoi.js +0 -6
  179. package/dist/cjs/node_modules/jay-peg/src/markers/exif.js +0 -6
  180. package/dist/cjs/node_modules/jay-peg/src/markers/jfif.js +0 -6
  181. package/dist/cjs/node_modules/jay-peg/src/markers/sof.js +0 -6
  182. package/dist/cjs/node_modules/jay-peg/src/markers/soi.js +0 -6
  183. package/dist/cjs/node_modules/jay-peg/src/markers/sos.js +0 -6
  184. package/dist/cjs/node_modules/jay-peg/src/markers/utils.js +0 -6
  185. package/dist/cjs/node_modules/linebreak/dist/module.js +0 -6
  186. package/dist/cjs/node_modules/linebreak/node_modules/base64-js/lib/b64.js +0 -6
  187. package/dist/cjs/node_modules/media-engine/src/index.js +0 -6
  188. package/dist/cjs/node_modules/media-engine/src/operators.js +0 -6
  189. package/dist/cjs/node_modules/media-engine/src/parser.js +0 -6
  190. package/dist/cjs/node_modules/media-engine/src/queries.js +0 -6
  191. package/dist/cjs/node_modules/normalize-svg-path/index.js +0 -6
  192. package/dist/cjs/node_modules/pako/lib/utils/common.js +0 -6
  193. package/dist/cjs/node_modules/pako/lib/zlib/adler32.js +0 -6
  194. package/dist/cjs/node_modules/pako/lib/zlib/constants.js +0 -6
  195. package/dist/cjs/node_modules/pako/lib/zlib/crc32.js +0 -6
  196. package/dist/cjs/node_modules/pako/lib/zlib/deflate.js +0 -6
  197. package/dist/cjs/node_modules/pako/lib/zlib/inffast.js +0 -6
  198. package/dist/cjs/node_modules/pako/lib/zlib/inflate.js +0 -6
  199. package/dist/cjs/node_modules/pako/lib/zlib/inftrees.js +0 -6
  200. package/dist/cjs/node_modules/pako/lib/zlib/messages.js +0 -6
  201. package/dist/cjs/node_modules/pako/lib/zlib/trees.js +0 -6
  202. package/dist/cjs/node_modules/pako/lib/zlib/zstream.js +0 -6
  203. package/dist/cjs/node_modules/parse-svg-path/index.js +0 -6
  204. package/dist/cjs/node_modules/postcss-value-parser/lib/parse.js +0 -6
  205. package/dist/cjs/node_modules/postcss-value-parser/lib/unit.js +0 -6
  206. package/dist/cjs/node_modules/queue/index.js +0 -6
  207. package/dist/cjs/node_modules/restructure/src/Array.js +0 -6
  208. package/dist/cjs/node_modules/restructure/src/Base.js +0 -6
  209. package/dist/cjs/node_modules/restructure/src/Bitfield.js +0 -6
  210. package/dist/cjs/node_modules/restructure/src/Buffer.js +0 -6
  211. package/dist/cjs/node_modules/restructure/src/DecodeStream.js +0 -6
  212. package/dist/cjs/node_modules/restructure/src/EncodeStream.js +0 -6
  213. package/dist/cjs/node_modules/restructure/src/LazyArray.js +0 -6
  214. package/dist/cjs/node_modules/restructure/src/Number.js +0 -6
  215. package/dist/cjs/node_modules/restructure/src/Optional.js +0 -6
  216. package/dist/cjs/node_modules/restructure/src/Pointer.js +0 -6
  217. package/dist/cjs/node_modules/restructure/src/Reserved.js +0 -6
  218. package/dist/cjs/node_modules/restructure/src/String.js +0 -6
  219. package/dist/cjs/node_modules/restructure/src/Struct.js +0 -6
  220. package/dist/cjs/node_modules/restructure/src/VersionedStruct.js +0 -6
  221. package/dist/cjs/node_modules/restructure/src/utils.js +0 -6
  222. package/dist/cjs/node_modules/scheduler/cjs/scheduler.development.js +0 -15
  223. package/dist/cjs/node_modules/scheduler/cjs/scheduler.production.js +0 -15
  224. package/dist/cjs/node_modules/scheduler/index.js +0 -6
  225. package/dist/cjs/node_modules/simple-swizzle/index.js +0 -6
  226. package/dist/cjs/node_modules/simple-swizzle/node_modules/is-arrayish/index.js +0 -6
  227. package/dist/cjs/node_modules/svg-arc-to-cubic-bezier/modules/index.js +0 -6
  228. package/dist/cjs/node_modules/tiny-inflate/index.js +0 -6
  229. package/dist/cjs/node_modules/tslib/tslib.es6.js +0 -6
  230. package/dist/cjs/node_modules/unicode-properties/dist/module.js +0 -6
  231. package/dist/cjs/node_modules/unicode-trie/index.js +0 -6
  232. package/dist/cjs/node_modules/unicode-trie/swap.js +0 -6
  233. package/dist/cjs/node_modules/yoga-layout/dist/binaries/yoga-wasm-base64-esm.js +0 -6
  234. package/dist/cjs/node_modules/yoga-layout/dist/src/generated/YGEnums.js +0 -6
  235. package/dist/cjs/node_modules/yoga-layout/dist/src/load.js +0 -6
  236. package/dist/cjs/node_modules/yoga-layout/dist/src/wrapAssembly.js +0 -6
  237. package/dist/cjs/src/components/e-commerce/invoice/InvoicePDF.js +0 -7
  238. package/dist/esm/_virtual/_commonjs-dynamic-modules.js +0 -11
  239. package/dist/esm/_virtual/aes.js +0 -9
  240. package/dist/esm/_virtual/b64.js +0 -9
  241. package/dist/esm/_virtual/blowfish.js +0 -9
  242. package/dist/esm/_virtual/cipher-core.js +0 -9
  243. package/dist/esm/_virtual/clone.js +0 -9
  244. package/dist/esm/_virtual/common.js +0 -9
  245. package/dist/esm/_virtual/context.js +0 -9
  246. package/dist/esm/_virtual/core2.js +0 -9
  247. package/dist/esm/_virtual/decode.js +0 -9
  248. package/dist/esm/_virtual/deflate.js +0 -9
  249. package/dist/esm/_virtual/dictionary-browser.js +0 -9
  250. package/dist/esm/_virtual/dictionary.js +0 -9
  251. package/dist/esm/_virtual/en-us.js +0 -9
  252. package/dist/esm/_virtual/enc-base64.js +0 -9
  253. package/dist/esm/_virtual/enc-base64url.js +0 -9
  254. package/dist/esm/_virtual/enc-utf16.js +0 -9
  255. package/dist/esm/_virtual/events.js +0 -9
  256. package/dist/esm/_virtual/evpkdf.js +0 -9
  257. package/dist/esm/_virtual/format-hex.js +0 -9
  258. package/dist/esm/_virtual/hmac.js +0 -9
  259. package/dist/esm/_virtual/huffman.js +0 -9
  260. package/dist/esm/_virtual/hyphen.js +0 -9
  261. package/dist/esm/_virtual/index10.js +0 -9
  262. package/dist/esm/_virtual/index5.js +0 -9
  263. package/dist/esm/_virtual/index6.js +0 -9
  264. package/dist/esm/_virtual/index7.js +0 -9
  265. package/dist/esm/_virtual/index8.js +0 -9
  266. package/dist/esm/_virtual/index9.js +0 -9
  267. package/dist/esm/_virtual/inflate.js +0 -9
  268. package/dist/esm/_virtual/inherits_browser.js +0 -9
  269. package/dist/esm/_virtual/lib-typedarrays.js +0 -9
  270. package/dist/esm/_virtual/md5.js +0 -9
  271. package/dist/esm/_virtual/mode-cfb.js +0 -9
  272. package/dist/esm/_virtual/mode-ctr-gladman.js +0 -9
  273. package/dist/esm/_virtual/mode-ctr.js +0 -9
  274. package/dist/esm/_virtual/mode-ecb.js +0 -9
  275. package/dist/esm/_virtual/mode-ofb.js +0 -9
  276. package/dist/esm/_virtual/pad-ansix923.js +0 -9
  277. package/dist/esm/_virtual/pad-iso10126.js +0 -9
  278. package/dist/esm/_virtual/pad-iso97971.js +0 -9
  279. package/dist/esm/_virtual/pad-nopadding.js +0 -9
  280. package/dist/esm/_virtual/pad-zeropadding.js +0 -9
  281. package/dist/esm/_virtual/pbkdf2.js +0 -9
  282. package/dist/esm/_virtual/prefix.js +0 -9
  283. package/dist/esm/_virtual/rabbit-legacy.js +0 -9
  284. package/dist/esm/_virtual/rabbit.js +0 -9
  285. package/dist/esm/_virtual/rc4.js +0 -9
  286. package/dist/esm/_virtual/ripemd160.js +0 -9
  287. package/dist/esm/_virtual/scheduler.development.js +0 -9
  288. package/dist/esm/_virtual/scheduler.production.js +0 -9
  289. package/dist/esm/_virtual/sha1.js +0 -9
  290. package/dist/esm/_virtual/sha224.js +0 -9
  291. package/dist/esm/_virtual/sha256.js +0 -9
  292. package/dist/esm/_virtual/sha3.js +0 -9
  293. package/dist/esm/_virtual/sha384.js +0 -9
  294. package/dist/esm/_virtual/sha512.js +0 -9
  295. package/dist/esm/_virtual/streams.js +0 -9
  296. package/dist/esm/_virtual/transform.js +0 -9
  297. package/dist/esm/_virtual/trees.js +0 -9
  298. package/dist/esm/_virtual/tripledes.js +0 -9
  299. package/dist/esm/_virtual/x64-core.js +0 -9
  300. package/dist/esm/node_modules/@react-pdf/fns/lib/index.js +0 -254
  301. package/dist/esm/node_modules/@react-pdf/font/lib/index.browser.js +0 -481
  302. package/dist/esm/node_modules/@react-pdf/image/lib/index.browser.js +0 -2217
  303. package/dist/esm/node_modules/@react-pdf/layout/lib/index.js +0 -2982
  304. package/dist/esm/node_modules/@react-pdf/pdfkit/lib/pdfkit.browser.js +0 -47429
  305. package/dist/esm/node_modules/@react-pdf/png-js/lib/png-js.browser.js +0 -12606
  306. package/dist/esm/node_modules/@react-pdf/primitives/lib/index.js +0 -37
  307. package/dist/esm/node_modules/@react-pdf/reconciler/lib/index.js +0 -16
  308. package/dist/esm/node_modules/@react-pdf/reconciler/lib/reconciler-23.js +0 -22
  309. package/dist/esm/node_modules/@react-pdf/reconciler/lib/reconciler-31.js +0 -30
  310. package/dist/esm/node_modules/@react-pdf/render/lib/index.js +0 -2081
  311. package/dist/esm/node_modules/@react-pdf/renderer/lib/react-pdf.browser.js +0 -472
  312. package/dist/esm/node_modules/@react-pdf/stylesheet/lib/index.js +0 -771
  313. package/dist/esm/node_modules/@react-pdf/textkit/lib/textkit.js +0 -2854
  314. package/dist/esm/node_modules/@swc/helpers/esm/_define_property.js +0 -15
  315. package/dist/esm/node_modules/abs-svg-path/index.js +0 -78
  316. package/dist/esm/node_modules/base64-js/index.js +0 -158
  317. package/dist/esm/node_modules/bidi-js/dist/bidi.js +0 -1008
  318. package/dist/esm/node_modules/brotli/dec/bit_reader.js +0 -132
  319. package/dist/esm/node_modules/brotli/dec/context.js +0 -255
  320. package/dist/esm/node_modules/brotli/dec/decode.js +0 -965
  321. package/dist/esm/node_modules/brotli/dec/dictionary-browser.js +0 -35
  322. package/dist/esm/node_modules/brotli/dec/dictionary.bin.js +0 -17
  323. package/dist/esm/node_modules/brotli/dec/dictionary.js +0 -54
  324. package/dist/esm/node_modules/brotli/dec/huffman.js +0 -133
  325. package/dist/esm/node_modules/brotli/dec/prefix.js +0 -70
  326. package/dist/esm/node_modules/brotli/dec/streams.js +0 -44
  327. package/dist/esm/node_modules/brotli/dec/transform.js +0 -264
  328. package/dist/esm/node_modules/brotli/decompress.js +0 -14
  329. package/dist/esm/node_modules/clone/clone.js +0 -272
  330. package/dist/esm/node_modules/color-name/index.js +0 -158
  331. package/dist/esm/node_modules/color-string/index.js +0 -259
  332. package/dist/esm/node_modules/crypto-js/aes.js +0 -251
  333. package/dist/esm/node_modules/crypto-js/blowfish.js +0 -488
  334. package/dist/esm/node_modules/crypto-js/cipher-core.js +0 -909
  335. package/dist/esm/node_modules/crypto-js/core.js +0 -820
  336. package/dist/esm/node_modules/crypto-js/enc-base64.js +0 -149
  337. package/dist/esm/node_modules/crypto-js/enc-base64url.js +0 -161
  338. package/dist/esm/node_modules/crypto-js/enc-utf16.js +0 -162
  339. package/dist/esm/node_modules/crypto-js/evpkdf.js +0 -149
  340. package/dist/esm/node_modules/crypto-js/format-hex.js +0 -80
  341. package/dist/esm/node_modules/crypto-js/hmac.js +0 -156
  342. package/dist/esm/node_modules/crypto-js/index.js +0 -61
  343. package/dist/esm/node_modules/crypto-js/lib-typedarrays.js +0 -89
  344. package/dist/esm/node_modules/crypto-js/md5.js +0 -277
  345. package/dist/esm/node_modules/crypto-js/mode-cfb.js +0 -94
  346. package/dist/esm/node_modules/crypto-js/mode-ctr-gladman.js +0 -130
  347. package/dist/esm/node_modules/crypto-js/mode-ctr.js +0 -72
  348. package/dist/esm/node_modules/crypto-js/mode-ecb.js +0 -54
  349. package/dist/esm/node_modules/crypto-js/mode-ofb.js +0 -68
  350. package/dist/esm/node_modules/crypto-js/pad-ansix923.js +0 -63
  351. package/dist/esm/node_modules/crypto-js/pad-iso10126.js +0 -58
  352. package/dist/esm/node_modules/crypto-js/pad-iso97971.js +0 -54
  353. package/dist/esm/node_modules/crypto-js/pad-nopadding.js +0 -44
  354. package/dist/esm/node_modules/crypto-js/pad-zeropadding.js +0 -61
  355. package/dist/esm/node_modules/crypto-js/pbkdf2.js +0 -160
  356. package/dist/esm/node_modules/crypto-js/rabbit-legacy.js +0 -207
  357. package/dist/esm/node_modules/crypto-js/rabbit.js +0 -209
  358. package/dist/esm/node_modules/crypto-js/rc4.js +0 -156
  359. package/dist/esm/node_modules/crypto-js/ripemd160.js +0 -280
  360. package/dist/esm/node_modules/crypto-js/sha1.js +0 -163
  361. package/dist/esm/node_modules/crypto-js/sha224.js +0 -94
  362. package/dist/esm/node_modules/crypto-js/sha256.js +0 -212
  363. package/dist/esm/node_modules/crypto-js/sha3.js +0 -340
  364. package/dist/esm/node_modules/crypto-js/sha384.js +0 -98
  365. package/dist/esm/node_modules/crypto-js/sha512.js +0 -340
  366. package/dist/esm/node_modules/crypto-js/tripledes.js +0 -796
  367. package/dist/esm/node_modules/crypto-js/x64-core.js +0 -317
  368. package/dist/esm/node_modules/dfa/index.js +0 -101
  369. package/dist/esm/node_modules/emoji-regex/index.js +0 -12
  370. package/dist/esm/node_modules/events/events.js +0 -485
  371. package/dist/esm/node_modules/fast-deep-equal/index.js +0 -56
  372. package/dist/esm/node_modules/fontkit/dist/browser-module.js +0 -13295
  373. package/dist/esm/node_modules/hsl-to-hex/index.js +0 -72
  374. package/dist/esm/node_modules/hsl-to-rgb-for-reals/converter.js +0 -66
  375. package/dist/esm/node_modules/hyphen/hyphen.js +0 -424
  376. package/dist/esm/node_modules/hyphen/patterns/en-us.js +0 -48
  377. package/dist/esm/node_modules/inherits/inherits_browser.js +0 -39
  378. package/dist/esm/node_modules/jay-peg/src/index.js +0 -68
  379. package/dist/esm/node_modules/jay-peg/src/markers/dac.js +0 -25
  380. package/dist/esm/node_modules/jay-peg/src/markers/dht.js +0 -52
  381. package/dist/esm/node_modules/jay-peg/src/markers/dqt.js +0 -26
  382. package/dist/esm/node_modules/jay-peg/src/markers/dri.js +0 -17
  383. package/dist/esm/node_modules/jay-peg/src/markers/eoi.js +0 -17
  384. package/dist/esm/node_modules/jay-peg/src/markers/exif.js +0 -327
  385. package/dist/esm/node_modules/jay-peg/src/markers/jfif.js +0 -24
  386. package/dist/esm/node_modules/jay-peg/src/markers/sof.js +0 -32
  387. package/dist/esm/node_modules/jay-peg/src/markers/soi.js +0 -11
  388. package/dist/esm/node_modules/jay-peg/src/markers/sos.js +0 -57
  389. package/dist/esm/node_modules/jay-peg/src/markers/utils.js +0 -71
  390. package/dist/esm/node_modules/linebreak/dist/module.js +0 -1340
  391. package/dist/esm/node_modules/linebreak/node_modules/base64-js/lib/b64.js +0 -137
  392. package/dist/esm/node_modules/media-engine/src/index.js +0 -26
  393. package/dist/esm/node_modules/media-engine/src/operators.js +0 -36
  394. package/dist/esm/node_modules/media-engine/src/parser.js +0 -147
  395. package/dist/esm/node_modules/media-engine/src/queries.js +0 -64
  396. package/dist/esm/node_modules/normalize-svg-path/index.js +0 -126
  397. package/dist/esm/node_modules/pako/lib/utils/common.js +0 -114
  398. package/dist/esm/node_modules/pako/lib/zlib/adler32.js +0 -57
  399. package/dist/esm/node_modules/pako/lib/zlib/constants.js +0 -78
  400. package/dist/esm/node_modules/pako/lib/zlib/crc32.js +0 -65
  401. package/dist/esm/node_modules/pako/lib/zlib/deflate.js +0 -1880
  402. package/dist/esm/node_modules/pako/lib/zlib/inffast.js +0 -351
  403. package/dist/esm/node_modules/pako/lib/zlib/inflate.js +0 -1557
  404. package/dist/esm/node_modules/pako/lib/zlib/inftrees.js +0 -352
  405. package/dist/esm/node_modules/pako/lib/zlib/messages.js +0 -38
  406. package/dist/esm/node_modules/pako/lib/zlib/trees.js +0 -1232
  407. package/dist/esm/node_modules/pako/lib/zlib/zstream.js +0 -57
  408. package/dist/esm/node_modules/parse-svg-path/index.js +0 -68
  409. package/dist/esm/node_modules/postcss-value-parser/lib/parse.js +0 -333
  410. package/dist/esm/node_modules/postcss-value-parser/lib/unit.js +0 -132
  411. package/dist/esm/node_modules/queue/index.js +0 -211
  412. package/dist/esm/node_modules/restructure/src/Array.js +0 -112
  413. package/dist/esm/node_modules/restructure/src/Base.js +0 -25
  414. package/dist/esm/node_modules/restructure/src/Bitfield.js +0 -47
  415. package/dist/esm/node_modules/restructure/src/Buffer.js +0 -44
  416. package/dist/esm/node_modules/restructure/src/DecodeStream.js +0 -93
  417. package/dist/esm/node_modules/restructure/src/EncodeStream.js +0 -137
  418. package/dist/esm/node_modules/restructure/src/LazyArray.js +0 -82
  419. package/dist/esm/node_modules/restructure/src/Number.js +0 -80
  420. package/dist/esm/node_modules/restructure/src/Optional.js +0 -52
  421. package/dist/esm/node_modules/restructure/src/Pointer.js +0 -175
  422. package/dist/esm/node_modules/restructure/src/Reserved.js +0 -31
  423. package/dist/esm/node_modules/restructure/src/String.js +0 -161
  424. package/dist/esm/node_modules/restructure/src/Struct.js +0 -121
  425. package/dist/esm/node_modules/restructure/src/VersionedStruct.js +0 -147
  426. package/dist/esm/node_modules/restructure/src/utils.js +0 -42
  427. package/dist/esm/node_modules/scheduler/cjs/scheduler.development.js +0 -382
  428. package/dist/esm/node_modules/scheduler/cjs/scheduler.production.js +0 -359
  429. package/dist/esm/node_modules/scheduler/index.js +0 -21
  430. package/dist/esm/node_modules/simple-swizzle/index.js +0 -40
  431. package/dist/esm/node_modules/simple-swizzle/node_modules/is-arrayish/index.js +0 -17
  432. package/dist/esm/node_modules/svg-arc-to-cubic-bezier/modules/index.js +0 -189
  433. package/dist/esm/node_modules/tiny-inflate/index.js +0 -387
  434. package/dist/esm/node_modules/tslib/tslib.es6.js +0 -36
  435. package/dist/esm/node_modules/unicode-properties/dist/module.js +0 -132
  436. package/dist/esm/node_modules/unicode-trie/index.js +0 -150
  437. package/dist/esm/node_modules/unicode-trie/swap.js +0 -33
  438. package/dist/esm/node_modules/yoga-layout/dist/binaries/yoga-wasm-base64-esm.js +0 -81
  439. package/dist/esm/node_modules/yoga-layout/dist/src/generated/YGEnums.js +0 -217
  440. package/dist/esm/node_modules/yoga-layout/dist/src/load.js +0 -24
  441. package/dist/esm/node_modules/yoga-layout/dist/src/wrapAssembly.js +0 -130
  442. package/dist/esm/src/components/e-commerce/invoice/InvoicePDF.js +0 -181
@@ -1,2854 +0,0 @@
1
- /*
2
- * UMWD-Components
3
- * @copyright Jelle Paulus
4
- * @license MIT
5
- */
6
-
7
- import { compose, isNil, repeat, last, dropLast as dropLast$2, adjust, reverse } from '../../fns/lib/index.js';
8
- import bidiFactory from '../../../bidi-js/dist/bidi.js';
9
- import $747425b437e121da$export$2e2bcd8739ae039 from '../../../unicode-properties/dist/module.js';
10
- import hyphen from '../../../hyphen/hyphen.js';
11
- import pattern from '../../../hyphen/patterns/en-us.js';
12
-
13
- /**
14
- * Create attributed string from text fragments
15
- *
16
- * @param fragments - Fragments
17
- * @returns Attributed string
18
- */
19
- const fromFragments = (fragments) => {
20
- let offset = 0;
21
- let string = '';
22
- const runs = [];
23
- fragments.forEach((fragment) => {
24
- string += fragment.string;
25
- runs.push({
26
- ...fragment,
27
- start: offset,
28
- end: offset + fragment.string.length,
29
- attributes: fragment.attributes || {},
30
- });
31
- offset += fragment.string.length;
32
- });
33
- return { string, runs };
34
- };
35
-
36
- /**
37
- * Default word hyphenation engine used when no one provided.
38
- * Does not perform word hyphenation at all
39
- *
40
- * @param word
41
- * @returns Same word
42
- */
43
- const defaultHyphenationEngine = (word) => [word];
44
- /**
45
- * Wrap words of attribute string
46
- *
47
- * @param engines layout engines
48
- * @param options layout options
49
- */
50
- const wrapWords = (engines = {}, options = {}) => {
51
- /**
52
- * @param attributedString - Attributed string
53
- * @returns Attributed string including syllables
54
- */
55
- return (attributedString) => {
56
- const syllables = [];
57
- const fragments = [];
58
- const hyphenateWord = options.hyphenationCallback ||
59
- engines.wordHyphenation?.() ||
60
- defaultHyphenationEngine;
61
- for (let i = 0; i < attributedString.runs.length; i += 1) {
62
- let string = '';
63
- const run = attributedString.runs[i];
64
- const words = attributedString.string
65
- .slice(run.start, run.end)
66
- .split(/([ ]+)/g)
67
- .filter(Boolean);
68
- for (let j = 0; j < words.length; j += 1) {
69
- const word = words[j];
70
- const parts = hyphenateWord(word);
71
- syllables.push(...parts);
72
- string += parts.join('');
73
- }
74
- fragments.push({ ...run, string });
75
- }
76
- const result = { ...fromFragments(fragments), syllables };
77
- return result;
78
- };
79
- };
80
-
81
- /**
82
- * Clone rect
83
- *
84
- * @param rect - Rect
85
- * @returns Cloned rect
86
- */
87
- const copy = (rect) => {
88
- return Object.assign({}, rect);
89
- };
90
-
91
- /**
92
- * Partition rect in two in the vertical direction
93
- *
94
- * @param rect - Rect
95
- * @param height - Height
96
- * @returns Partitioned rects
97
- */
98
- const partition = (rect, height) => {
99
- const a = Object.assign({}, rect, { height });
100
- const b = Object.assign({}, rect, {
101
- y: rect.y + height,
102
- height: rect.height - height,
103
- });
104
- return [a, b];
105
- };
106
-
107
- /**
108
- * Crop upper section of rect
109
- *
110
- * @param height - Height
111
- * @param rect - Rect
112
- * @returns Cropped rect
113
- */
114
- const crop = (height, rect) => {
115
- const [, result] = partition(rect, height);
116
- return result;
117
- };
118
-
119
- /**
120
- * Get paragraph block height
121
- *
122
- * @param paragraph - Paragraph
123
- * @returns Paragraph block height
124
- */
125
- const height$2 = (paragraph) => {
126
- return paragraph.reduce((acc, block) => acc + block.box.height, 0);
127
- };
128
-
129
- /**
130
- * Calculate run scale
131
- *
132
- * @param run - Run
133
- * @returns Scale
134
- */
135
- const calculateScale = (run) => {
136
- const attributes = run.attributes || {};
137
- const fontSize = attributes.fontSize || 12;
138
- const font = attributes.font;
139
- const unitsPerEm = typeof font === 'string' ? null : font?.[0]?.unitsPerEm;
140
- return unitsPerEm ? fontSize / unitsPerEm : 0;
141
- };
142
- /**
143
- * Get run scale
144
- *
145
- * @param run
146
- * @returns Scale
147
- */
148
- const scale = (run) => {
149
- return run.attributes?.scale || calculateScale(run);
150
- };
151
-
152
- /**
153
- * Get ligature offset by index
154
- *
155
- * Ex. ffi ligature
156
- *
157
- * glyphs: l o f f i m
158
- * glyphIndices: 0 1 2 2 2 3
159
- * offset: 0 0 0 1 2 0
160
- *
161
- * @param index
162
- * @param run - Run
163
- * @returns Ligature offset
164
- */
165
- const offset = (index, run) => {
166
- if (!run)
167
- return 0;
168
- const glyphIndices = run.glyphIndices || [];
169
- const value = glyphIndices[index];
170
- return glyphIndices.slice(0, index).filter((i) => i === value).length;
171
- };
172
-
173
- /**
174
- * Get run font
175
- *
176
- * @param run - Run
177
- * @returns Font
178
- */
179
- const getFont = (run) => {
180
- return run.attributes?.font?.[0] || null;
181
- };
182
-
183
- /**
184
- * Slice glyph between codePoints range
185
- * Util for breaking ligatures
186
- *
187
- * @param start - Start code point index
188
- * @param end - End code point index
189
- * @param font - Font to generate new glyph
190
- * @param glyph - Glyph to be sliced
191
- * @returns Sliced glyph parts
192
- */
193
- const slice$2 = (start, end, font, glyph) => {
194
- if (!glyph)
195
- return [];
196
- if (start === end)
197
- return [];
198
- if (start === 0 && end === glyph.codePoints.length)
199
- return [glyph];
200
- const codePoints = glyph.codePoints.slice(start, end);
201
- const string = String.fromCodePoint(...codePoints);
202
- // passing LTR To force fontkit to not reverse the string
203
- return font
204
- ? font.layout(string, undefined, undefined, undefined, 'ltr').glyphs
205
- : [glyph];
206
- };
207
-
208
- /**
209
- * Return glyph index at string index, if glyph indices present.
210
- * Otherwise return string index
211
- *
212
- * @param index - Index
213
- * @param run - Run
214
- * @returns Glyph index
215
- */
216
- const glyphIndexAt = (index, run) => {
217
- const result = run?.glyphIndices?.[index];
218
- return isNil(result) ? index : result;
219
- };
220
-
221
- /**
222
- * Returns new array starting with zero, and keeping same relation between consecutive values
223
- *
224
- * @param array - List
225
- * @returns Normalized array
226
- */
227
- const normalize = (array) => {
228
- const head = array[0];
229
- return array.map((value) => value - head);
230
- };
231
-
232
- /**
233
- * Slice run between glyph indices range
234
- *
235
- * @param start - Glyph index
236
- * @param end - Glyph index
237
- * @param run - Run
238
- * @returns Sliced run
239
- */
240
- const slice$1 = (start, end, run) => {
241
- const runScale = scale(run);
242
- const font = getFont(run);
243
- // Get glyph start and end indices
244
- const startIndex = glyphIndexAt(start, run);
245
- const endIndex = glyphIndexAt(end, run);
246
- // Get start and end glyph
247
- const startGlyph = run.glyphs?.[startIndex];
248
- const endGlyph = run.glyphs?.[endIndex];
249
- // Get start ligature chunks (if any)
250
- const startOffset = offset(start, run);
251
- const startGlyphs = startOffset > 0 ? slice$2(startOffset, Infinity, font, startGlyph) : [];
252
- // Get end ligature chunks (if any)
253
- const endOffset = offset(end, run);
254
- const endGlyphs = slice$2(0, endOffset, font, endGlyph);
255
- // Compute new glyphs
256
- const sliceStart = startIndex + Math.min(1, startOffset);
257
- const glyphs = (run.glyphs || []).slice(sliceStart, endIndex);
258
- // Compute new positions
259
- const glyphPosition = (g) => ({
260
- xAdvance: g.advanceWidth * runScale,
261
- yAdvance: 0,
262
- xOffset: 0,
263
- yOffset: 0,
264
- });
265
- const startPositions = startGlyphs.map(glyphPosition);
266
- const positions = (run.positions || []).slice(sliceStart, endIndex);
267
- const endPositions = endGlyphs.map(glyphPosition);
268
- return Object.assign({}, run, {
269
- start: run.start + start,
270
- end: Math.min(run.end, run.start + end),
271
- glyphIndices: normalize((run.glyphIndices || []).slice(start, end)),
272
- glyphs: [startGlyphs, glyphs, endGlyphs].flat(),
273
- positions: [startPositions, positions, endPositions].flat(),
274
- });
275
- };
276
-
277
- /**
278
- * Get run index that contains passed index
279
- *
280
- * @param index - Index
281
- * @param runs - Runs
282
- * @returns Run index
283
- */
284
- const runIndexAt$1 = (index, runs) => {
285
- if (!runs)
286
- return -1;
287
- return runs.findIndex((run) => run.start <= index && index < run.end);
288
- };
289
-
290
- /**
291
- * Filter runs contained between start and end
292
- *
293
- * @param start
294
- * @param end
295
- * @param runs
296
- * @returns Filtered runs
297
- */
298
- const filter = (start, end, runs) => {
299
- const startIndex = runIndexAt$1(start, runs);
300
- const endIndex = Math.max(runIndexAt$1(end - 1, runs), startIndex);
301
- return runs.slice(startIndex, endIndex + 1);
302
- };
303
-
304
- /**
305
- * Subtract scalar to run
306
- *
307
- * @param index - Scalar
308
- * @param run - Run
309
- * @returns Subtracted run
310
- */
311
- const subtract = (index, run) => {
312
- const start = run.start - index;
313
- const end = run.end - index;
314
- return Object.assign({}, run, { start, end });
315
- };
316
-
317
- /**
318
- * Slice array of runs
319
- *
320
- * @param start - Offset
321
- * @param end - Offset
322
- * @param runs
323
- * @returns Sliced runs
324
- */
325
- const sliceRuns = (start, end, runs) => {
326
- const sliceFirstRun = (a) => slice$1(start - a.start, end - a.start, a);
327
- const sliceLastRun = (a) => slice$1(0, end - a.start, a);
328
- return runs.map((run, i) => {
329
- let result = run;
330
- const isFirst = i === 0;
331
- const isLast = !isFirst && i === runs.length - 1;
332
- if (isFirst)
333
- result = sliceFirstRun(run);
334
- if (isLast)
335
- result = sliceLastRun(run);
336
- return subtract(start, result);
337
- });
338
- };
339
- /**
340
- * Slice attributed string between two indices
341
- *
342
- * @param start - Offset
343
- * @param end - Offset
344
- * @param attributedString - Attributed string
345
- * @returns Attributed string
346
- */
347
- const slice = (start, end, attributedString) => {
348
- if (attributedString.string.length === 0)
349
- return attributedString;
350
- const string = attributedString.string.slice(start, end);
351
- const filteredRuns = filter(start, end, attributedString.runs);
352
- const slicedRuns = sliceRuns(start, end, filteredRuns);
353
- return Object.assign({}, attributedString, { string, runs: slicedRuns });
354
- };
355
-
356
- const findCharIndex = (string) => {
357
- return string.search(/\S/g);
358
- };
359
- const findLastCharIndex = (string) => {
360
- const match = string.match(/\S/g);
361
- return match ? string.lastIndexOf(match[match.length - 1]) : -1;
362
- };
363
- /**
364
- * Removes (strips) whitespace from both ends of the attributted string.
365
- *
366
- * @param attributedString - Attributed string
367
- * @returns Attributed string
368
- */
369
- const trim = (attributedString) => {
370
- const start = findCharIndex(attributedString.string);
371
- const end = findLastCharIndex(attributedString.string);
372
- return slice(start, end + 1, attributedString);
373
- };
374
-
375
- /**
376
- * Returns empty run
377
- *
378
- * @returns Empty run
379
- */
380
- const empty$1 = () => {
381
- return {
382
- start: 0,
383
- end: 0,
384
- glyphIndices: [],
385
- glyphs: [],
386
- positions: [],
387
- attributes: {},
388
- };
389
- };
390
-
391
- /**
392
- * Check if value is a number
393
- *
394
- * @param value - Value to check
395
- * @returns Whether value is a number
396
- */
397
- const isNumber = (value) => {
398
- return typeof value === 'number';
399
- };
400
-
401
- /**
402
- * Append glyph indices with given length
403
- *
404
- * Ex. appendIndices(3, [0, 1, 2, 2]) => [0, 1, 2, 2, 3, 3, 3]
405
- *
406
- * @param length - Length
407
- * @param indices - Glyph indices
408
- * @returns Extended glyph indices
409
- */
410
- const appendIndices = (length, indices) => {
411
- const lastIndex = last(indices);
412
- const value = isNil(lastIndex) ? 0 : lastIndex + 1;
413
- const newIndices = Array(length).fill(value);
414
- return indices.concat(newIndices);
415
- };
416
-
417
- /**
418
- * Get glyph for a given code point
419
- *
420
- * @param value - CodePoint
421
- * @param font - Font
422
- * @returns Glyph
423
- * */
424
- const fromCodePoint = (value, font) => {
425
- if (typeof font === 'string')
426
- return null;
427
- return font && value ? font.glyphForCodePoint(value) : null;
428
- };
429
-
430
- /**
431
- * Append glyph to run
432
- *
433
- * @param glyph - Glyph
434
- * @param run - Run
435
- * @returns Run with glyph
436
- */
437
- const appendGlyph = (glyph, run) => {
438
- const glyphLength = glyph.codePoints?.length || 0;
439
- const end = run.end + glyphLength;
440
- const glyphs = run.glyphs.concat(glyph);
441
- const glyphIndices = appendIndices(glyphLength, run.glyphIndices);
442
- if (!run.positions)
443
- return Object.assign({}, run, { end, glyphs, glyphIndices });
444
- const positions = run.positions.concat({
445
- xAdvance: glyph.advanceWidth * scale(run),
446
- yAdvance: 0,
447
- xOffset: 0,
448
- yOffset: 0,
449
- });
450
- return Object.assign({}, run, { end, glyphs, glyphIndices, positions });
451
- };
452
- /**
453
- * Append glyph or code point to run
454
- *
455
- * @param value - Glyph or codePoint
456
- * @param run - Run
457
- * @returns Run with glyph
458
- */
459
- const append$1 = (value, run) => {
460
- if (!value)
461
- return run;
462
- const font = getFont(run);
463
- const glyph = isNumber(value) ? fromCodePoint(value, font) : value;
464
- return appendGlyph(glyph, run);
465
- };
466
-
467
- /**
468
- * Get string from array of code points
469
- *
470
- * @param codePoints - Points
471
- * @returns String
472
- */
473
- const stringFromCodePoints = (codePoints) => {
474
- return String.fromCodePoint(...(codePoints || []));
475
- };
476
-
477
- /**
478
- * Append glyph into last run of attributed string
479
- *
480
- * @param glyph - Glyph or code point
481
- * @param attributedString - Attributed string
482
- * @returns Attributed string with new glyph
483
- */
484
- const append = (glyph, attributedString) => {
485
- const codePoints = typeof glyph === 'number' ? [glyph] : glyph?.codePoints;
486
- const codePointsString = stringFromCodePoints(codePoints || []);
487
- const string = attributedString.string + codePointsString;
488
- const firstRuns = attributedString.runs.slice(0, -1);
489
- const lastRun = last(attributedString.runs) || empty$1();
490
- const runs = firstRuns.concat(append$1(glyph, lastRun));
491
- return Object.assign({}, attributedString, { string, runs });
492
- };
493
-
494
- const ELLIPSIS_UNICODE = 8230;
495
- const ELLIPSIS_STRING = String.fromCharCode(ELLIPSIS_UNICODE);
496
- /**
497
- * Get ellipsis codepoint. This may be different in standard and embedded fonts
498
- *
499
- * @param font
500
- * @returns Ellipsis codepoint
501
- */
502
- const getEllipsisCodePoint = (font) => {
503
- if (!font.encode)
504
- return ELLIPSIS_UNICODE;
505
- const [codePoints] = font.encode(ELLIPSIS_STRING);
506
- return parseInt(codePoints[0], 16);
507
- };
508
- /**
509
- * Trucante block with ellipsis
510
- *
511
- * @param paragraph - Paragraph
512
- * @returns Sliced paragraph
513
- */
514
- const truncate = (paragraph) => {
515
- const runs = last(paragraph)?.runs || [];
516
- const font = last(runs)?.attributes?.font[0];
517
- if (font) {
518
- const index = paragraph.length - 1;
519
- const codePoint = getEllipsisCodePoint(font);
520
- const glyph = font.glyphForCodePoint(codePoint);
521
- const lastBlock = append(glyph, trim(paragraph[index]));
522
- return Object.assign([], paragraph, { [index]: lastBlock });
523
- }
524
- return paragraph;
525
- };
526
-
527
- /**
528
- * Omit attribute from run
529
- *
530
- * @param value - Attribute key
531
- * @param run - Run
532
- * @returns Run without ommited attribute
533
- */
534
- const omit = (value, run) => {
535
- const attributes = Object.assign({}, run.attributes);
536
- delete attributes[value];
537
- return Object.assign({}, run, { attributes });
538
- };
539
-
540
- /**
541
- * Get run ascent
542
- *
543
- * @param run - Run
544
- * @returns Ascent
545
- */
546
- const ascent$1 = (run) => {
547
- const { font, attachment } = run.attributes;
548
- const attachmentHeight = attachment?.height || 0;
549
- const fontAscent = typeof font === 'string' ? 0 : font?.[0]?.ascent || 0;
550
- return Math.max(attachmentHeight, fontAscent * scale(run));
551
- };
552
-
553
- /**
554
- * Get run descent
555
- *
556
- * @param run - Run
557
- * @returns Descent
558
- */
559
- const descent = (run) => {
560
- const font = run.attributes?.font;
561
- const fontDescent = typeof font === 'string' ? 0 : font?.[0]?.descent || 0;
562
- return scale(run) * fontDescent;
563
- };
564
-
565
- /**
566
- * Get run lineGap
567
- *
568
- * @param run - Run
569
- * @returns LineGap
570
- */
571
- const lineGap = (run) => {
572
- const font = run.attributes?.font;
573
- const lineGap = typeof font === 'string' ? 0 : font?.[0]?.lineGap || 0;
574
- return lineGap * scale(run);
575
- };
576
-
577
- /**
578
- * Get run height
579
- *
580
- * @param run - Run
581
- * @returns Height
582
- */
583
- const height$1 = (run) => {
584
- const lineHeight = run.attributes?.lineHeight;
585
- return lineHeight || lineGap(run) + ascent$1(run) - descent(run);
586
- };
587
-
588
- /**
589
- * Returns attributed string height
590
- *
591
- * @param attributedString - Attributed string
592
- * @returns Height
593
- */
594
- const height = (attributedString) => {
595
- const reducer = (acc, run) => Math.max(acc, height$1(run));
596
- return attributedString.runs.reduce(reducer, 0);
597
- };
598
-
599
- /**
600
- * Checks if two rects intersect each other
601
- *
602
- * @param a - Rect A
603
- * @param b - Rect B
604
- * @returns Whether rects intersect
605
- */
606
- const intersects = (a, b) => {
607
- const x = Math.max(a.x, b.x);
608
- const num1 = Math.min(a.x + a.width, b.x + b.width);
609
- const y = Math.max(a.y, b.y);
610
- const num2 = Math.min(a.y + a.height, b.y + b.height);
611
- return num1 >= x && num2 >= y;
612
- };
613
-
614
- const getLineFragment = (lineRect, excludeRect) => {
615
- if (!intersects(excludeRect, lineRect))
616
- return [lineRect];
617
- const eStart = excludeRect.x;
618
- const eEnd = excludeRect.x + excludeRect.width;
619
- const lStart = lineRect.x;
620
- const lEnd = lineRect.x + lineRect.width;
621
- const a = Object.assign({}, lineRect, { width: eStart - lStart });
622
- const b = Object.assign({}, lineRect, { x: eEnd, width: lEnd - eEnd });
623
- return [a, b].filter((r) => r.width > 0);
624
- };
625
- const getLineFragments = (rect, excludeRects) => {
626
- let fragments = [rect];
627
- for (let i = 0; i < excludeRects.length; i += 1) {
628
- const excludeRect = excludeRects[i];
629
- fragments = fragments.reduce((acc, fragment) => {
630
- const pieces = getLineFragment(fragment, excludeRect);
631
- return acc.concat(pieces);
632
- }, []);
633
- }
634
- return fragments;
635
- };
636
- const generateLineRects = (container, height) => {
637
- const { excludeRects, ...rect } = container;
638
- if (!excludeRects)
639
- return [rect];
640
- const lineRects = [];
641
- const maxY = Math.max(...excludeRects.map((r) => r.y + r.height));
642
- let currentRect = rect;
643
- while (currentRect.y < maxY) {
644
- const [lineRect, rest] = partition(currentRect, height);
645
- const lineRectFragments = getLineFragments(lineRect, excludeRects);
646
- currentRect = rest;
647
- lineRects.push(...lineRectFragments);
648
- }
649
- return [...lineRects, currentRect];
650
- };
651
-
652
- const ATTACHMENT_CODE$1 = '\ufffc'; // 65532
653
- /**
654
- * Remove attachment attribute if no char present
655
- *
656
- * @param line - Line
657
- * @returns Line
658
- */
659
- const purgeAttachments = (line) => {
660
- const shouldPurge = !line.string.includes(ATTACHMENT_CODE$1);
661
- if (!shouldPurge)
662
- return line;
663
- const runs = line.runs.map((run) => omit('attachment', run));
664
- return Object.assign({}, line, { runs });
665
- };
666
- /**
667
- * Layout paragraphs inside rectangle
668
- *
669
- * @param rects - Rects
670
- * @param lines - Attributed strings
671
- * @param indent
672
- * @returns layout blocks
673
- */
674
- const layoutLines = (rects, lines, indent) => {
675
- let rect = rects.shift();
676
- let currentY = rect.y;
677
- return lines.map((line, i) => {
678
- const lineIndent = i === 0 ? indent : 0;
679
- const style = line.runs?.[0]?.attributes || {};
680
- const height$1 = Math.max(height(line), style.lineHeight);
681
- if (currentY + height$1 > rect.y + rect.height && rects.length > 0) {
682
- rect = rects.shift();
683
- currentY = rect.y;
684
- }
685
- const newLine = {
686
- string: line.string,
687
- runs: line.runs,
688
- box: {
689
- x: rect.x + lineIndent,
690
- y: currentY,
691
- width: rect.width - lineIndent,
692
- height: height$1,
693
- },
694
- };
695
- currentY += height$1;
696
- return purgeAttachments(newLine);
697
- });
698
- };
699
- /**
700
- * Performs line breaking and layout
701
- *
702
- * @param engines - Engines
703
- * @param options - Layout options
704
- */
705
- const layoutParagraph = (engines, options = {}) => {
706
- /**
707
- * @param container - Container
708
- * @param paragraph - Attributed string
709
- * @returns Layout block
710
- */
711
- return (container, paragraph) => {
712
- const height$1 = height(paragraph);
713
- const indent = paragraph.runs?.[0]?.attributes?.indent || 0;
714
- const rects = generateLineRects(container, height$1);
715
- const availableWidths = rects.map((r) => r.width);
716
- availableWidths.unshift(availableWidths[0] - indent);
717
- const lines = engines.linebreaker(options)(paragraph, availableWidths);
718
- return layoutLines(rects, lines, indent);
719
- };
720
- };
721
-
722
- /**
723
- * Slice block at given height
724
- *
725
- * @param height - Height
726
- * @param paragraph - Paragraph
727
- * @returns Sliced paragraph
728
- */
729
- const sliceAtHeight = (height, paragraph) => {
730
- const newBlock = [];
731
- let counter = 0;
732
- for (let i = 0; i < paragraph.length; i += 1) {
733
- const line = paragraph[i];
734
- counter += line.box.height;
735
- if (counter < height) {
736
- newBlock.push(line);
737
- }
738
- else {
739
- break;
740
- }
741
- }
742
- return newBlock;
743
- };
744
-
745
- /**
746
- * Layout paragraphs inside container until it does not
747
- * fit anymore, performing line wrapping in the process.
748
- *
749
- * @param engines - Engines
750
- * @param options - Layout options
751
- * @param container - Container
752
- */
753
- const typesetter = (engines, options, container) => {
754
- /**
755
- * @param attributedStrings - Attributed strings (paragraphs)
756
- * @returns Paragraph blocks
757
- */
758
- return (attributedStrings) => {
759
- const result = [];
760
- const paragraphs = [...attributedStrings];
761
- const layout = layoutParagraph(engines, options);
762
- const maxLines = isNil(container.maxLines) ? Infinity : container.maxLines;
763
- const truncateEllipsis = container.truncateMode === 'ellipsis';
764
- let linesCount = maxLines;
765
- let paragraphRect = copy(container);
766
- let nextParagraph = paragraphs.shift();
767
- while (linesCount > 0 && nextParagraph) {
768
- const paragraph = layout(paragraphRect, nextParagraph);
769
- const slicedBlock = paragraph.slice(0, linesCount);
770
- const linesHeight = height$2(slicedBlock);
771
- const shouldTruncate = truncateEllipsis && paragraph.length !== slicedBlock.length;
772
- linesCount -= slicedBlock.length;
773
- if (paragraphRect.height >= linesHeight) {
774
- result.push(shouldTruncate ? truncate(slicedBlock) : slicedBlock);
775
- paragraphRect = crop(linesHeight, paragraphRect);
776
- nextParagraph = paragraphs.shift();
777
- }
778
- else {
779
- result.push(truncate(sliceAtHeight(paragraphRect.height, slicedBlock)));
780
- break;
781
- }
782
- }
783
- return result;
784
- };
785
- };
786
-
787
- /**
788
- * Get attributed string start value
789
- *
790
- * @param attributedString - Attributed string
791
- * @returns Start
792
- */
793
- const start = (attributedString) => {
794
- const { runs } = attributedString;
795
- return runs.length === 0 ? 0 : runs[0].start;
796
- };
797
-
798
- /**
799
- * Get attributed string end value
800
- *
801
- * @param attributedString - Attributed string
802
- * @returns End
803
- */
804
- const end = (attributedString) => {
805
- const { runs } = attributedString;
806
- return runs.length === 0 ? 0 : last(runs).end;
807
- };
808
-
809
- /**
810
- * Get attributed string length
811
- *
812
- * @param attributedString - Attributed string
813
- * @returns End
814
- */
815
- const length$1 = (attributedString) => {
816
- return end(attributedString) - start(attributedString);
817
- };
818
-
819
- const bidi$2 = bidiFactory();
820
- const getBidiLevels$1 = (runs) => {
821
- return runs.reduce((acc, run) => {
822
- const length = run.end - run.start;
823
- const levels = repeat(run.attributes.bidiLevel, length);
824
- return acc.concat(levels);
825
- }, []);
826
- };
827
- const getReorderedIndices = (string, segments) => {
828
- // Fill an array with indices
829
- const indices = [];
830
- for (let i = 0; i < string.length; i += 1) {
831
- indices[i] = i;
832
- }
833
- // Reverse each segment in order
834
- segments.forEach(([start, end]) => {
835
- const slice = indices.slice(start, end + 1);
836
- for (let i = slice.length - 1; i >= 0; i -= 1) {
837
- indices[end - i] = slice[i];
838
- }
839
- });
840
- return indices;
841
- };
842
- const getItemAtIndex = (runs, objectName, index) => {
843
- for (let i = 0; i < runs.length; i += 1) {
844
- const run = runs[i];
845
- const updatedIndex = run.glyphIndices[index - run.start];
846
- if (index >= run.start && index < run.end) {
847
- return run[objectName][updatedIndex];
848
- }
849
- }
850
- throw new Error(`index ${index} out of range`);
851
- };
852
- const reorderLine = (line) => {
853
- const levels = getBidiLevels$1(line.runs);
854
- const direction = line.runs[0]?.attributes.direction;
855
- const level = direction === 'rtl' ? 1 : 0;
856
- const end = length$1(line) - 1;
857
- const paragraphs = [{ start: 0, end, level }];
858
- const embeddingLevels = { paragraphs, levels };
859
- const segments = bidi$2.getReorderSegments(line.string, embeddingLevels);
860
- // No need for bidi reordering
861
- if (segments.length === 0)
862
- return line;
863
- const indices = getReorderedIndices(line.string, segments);
864
- const updatedString = bidi$2.getReorderedString(line.string, embeddingLevels);
865
- const updatedRuns = line.runs.map((run) => {
866
- const selectedIndices = indices.slice(run.start, run.end);
867
- const updatedGlyphs = [];
868
- const updatedPositions = [];
869
- const addedGlyphs = new Set();
870
- for (let i = 0; i < selectedIndices.length; i += 1) {
871
- const index = selectedIndices[i];
872
- const glyph = getItemAtIndex(line.runs, 'glyphs', index);
873
- if (addedGlyphs.has(glyph.id))
874
- continue;
875
- updatedGlyphs.push(glyph);
876
- updatedPositions.push(getItemAtIndex(line.runs, 'positions', index));
877
- if (glyph.isLigature) {
878
- addedGlyphs.add(glyph.id);
879
- }
880
- }
881
- return {
882
- ...run,
883
- glyphs: updatedGlyphs,
884
- positions: updatedPositions,
885
- };
886
- });
887
- return {
888
- box: line.box,
889
- runs: updatedRuns,
890
- string: updatedString,
891
- };
892
- };
893
- const reorderParagraph = (paragraph) => paragraph.map(reorderLine);
894
- /**
895
- * Perform bidi reordering
896
- *
897
- * @returns Reordered paragraphs
898
- */
899
- const bidiReordering = () => {
900
- /**
901
- * @param paragraphs - Paragraphs
902
- * @returns Reordered paragraphs
903
- */
904
- return (paragraphs) => paragraphs.map(reorderParagraph);
905
- };
906
-
907
- const DUMMY_CODEPOINT = 123;
908
- /**
909
- * Resolve string indices based on glyphs code points
910
- *
911
- * @param glyphs
912
- * @returns Glyph indices
913
- */
914
- const resolve = (glyphs = []) => {
915
- return glyphs.reduce((acc, glyph) => {
916
- const codePoints = glyph?.codePoints || [DUMMY_CODEPOINT];
917
- if (acc.length === 0)
918
- return codePoints.map(() => 0);
919
- const last = acc[acc.length - 1];
920
- const next = codePoints.map(() => last + 1);
921
- return [...acc, ...next];
922
- }, []);
923
- };
924
-
925
- const getCharacterSpacing = (run) => {
926
- return run.attributes?.characterSpacing || 0;
927
- };
928
- /**
929
- * Scale run positions
930
- *
931
- * @param run
932
- * @param positions
933
- * @returns Scaled positions
934
- */
935
- const scalePositions = (run, positions) => {
936
- const runScale = scale(run);
937
- const characterSpacing = getCharacterSpacing(run);
938
- return positions.map((position, i) => {
939
- const isLast = i === positions.length;
940
- const xSpacing = isLast ? 0 : characterSpacing;
941
- return Object.assign({}, position, {
942
- xAdvance: position.xAdvance * runScale + xSpacing,
943
- yAdvance: position.yAdvance * runScale,
944
- xOffset: position.xOffset * runScale,
945
- yOffset: position.yOffset * runScale,
946
- });
947
- });
948
- };
949
- /**
950
- * Create glyph run
951
- *
952
- * @param string string
953
- */
954
- const layoutRun = (string) => {
955
- /**
956
- * @param run - Run
957
- * @returns Glyph run
958
- */
959
- return (run) => {
960
- const { start, end, attributes = {} } = run;
961
- const { font } = attributes;
962
- if (!font)
963
- return { ...run, glyphs: [], glyphIndices: [], positions: [] };
964
- const runString = string.slice(start, end);
965
- if (typeof font === 'string')
966
- throw new Error('Invalid font');
967
- // passing LTR To force fontkit to not reverse the string
968
- const glyphRun = font[0].layout(runString, undefined, undefined, undefined, 'ltr');
969
- const positions = scalePositions(run, glyphRun.positions);
970
- const glyphIndices = resolve(glyphRun.glyphs);
971
- const result = {
972
- ...run,
973
- positions,
974
- glyphIndices,
975
- glyphs: glyphRun.glyphs,
976
- };
977
- return result;
978
- };
979
- };
980
- /**
981
- * Generate glyphs for single attributed string
982
- */
983
- const generateGlyphs = () => {
984
- /**
985
- * @param attributedString - Attributed string
986
- * @returns Attributed string with glyphs
987
- */
988
- return (attributedString) => {
989
- const runs = attributedString.runs.map(layoutRun(attributedString.string));
990
- const res = Object.assign({}, attributedString, { runs });
991
- return res;
992
- };
993
- };
994
-
995
- /**
996
- * Resolves yOffset for run
997
- *
998
- * @param run - Run
999
- * @returns Run
1000
- */
1001
- const resolveRunYOffset = (run) => {
1002
- if (!run.positions)
1003
- return run;
1004
- const unitsPerEm = run.attributes?.font?.[0]?.unitsPerEm || 0;
1005
- const yOffset = (run.attributes?.yOffset || 0) * unitsPerEm;
1006
- const positions = run.positions.map((p) => Object.assign({}, p, { yOffset }));
1007
- return Object.assign({}, run, { positions });
1008
- };
1009
- /**
1010
- * Resolves yOffset for multiple paragraphs
1011
- */
1012
- const resolveYOffset = () => {
1013
- /**
1014
- * @param attributedString - Attributed string
1015
- * @returns Attributed string
1016
- */
1017
- return (attributedString) => {
1018
- const runs = attributedString.runs.map(resolveRunYOffset);
1019
- const res = Object.assign({}, attributedString, { runs });
1020
- return res;
1021
- };
1022
- };
1023
-
1024
- /**
1025
- * Sort runs in ascending order
1026
- *
1027
- * @param runs
1028
- * @returns Sorted runs
1029
- */
1030
- const sort = (runs) => {
1031
- return runs.sort((a, b) => a.start - b.start || a.end - b.end);
1032
- };
1033
-
1034
- /**
1035
- * Is run empty (start === end)
1036
- *
1037
- * @param run - Run
1038
- * @returns Is run empty
1039
- */
1040
- const isEmpty = (run) => {
1041
- return run.start === run.end;
1042
- };
1043
-
1044
- /**
1045
- * Sort points in ascending order
1046
- * @param a - First point
1047
- * @param b - Second point
1048
- * @returns Sort order
1049
- */
1050
- const sortPoints = (a, b) => {
1051
- return a[1] - b[1] || a[3] - b[3];
1052
- };
1053
- /**
1054
- * @param runs
1055
- * @returns Points
1056
- */
1057
- const generatePoints = (runs) => {
1058
- const result = runs.reduce((acc, run, i) => {
1059
- return acc.concat([
1060
- ['start', run.start, run.attributes, i],
1061
- ['end', run.end, run.attributes, i],
1062
- ]);
1063
- }, []);
1064
- return result.sort(sortPoints);
1065
- };
1066
- /**
1067
- * @param runs
1068
- * @returns Merged runs
1069
- */
1070
- const mergeRuns = (runs) => {
1071
- return runs.reduce((acc, run) => {
1072
- const attributes = Object.assign({}, acc.attributes, run.attributes);
1073
- return Object.assign({}, run, { attributes });
1074
- }, {});
1075
- };
1076
- /**
1077
- * @param runs
1078
- * @returns Grouped runs
1079
- */
1080
- const groupEmptyRuns = (runs) => {
1081
- const groups = runs.reduce((acc, run) => {
1082
- if (!acc[run.start])
1083
- acc[run.start] = [];
1084
- acc[run.start].push(run);
1085
- return acc;
1086
- }, []);
1087
- return Object.values(groups);
1088
- };
1089
- /**
1090
- * @param runs
1091
- * @returns Flattened runs
1092
- */
1093
- const flattenEmptyRuns = (runs) => {
1094
- return groupEmptyRuns(runs).map(mergeRuns);
1095
- };
1096
- /**
1097
- * @param runs
1098
- * @returns Flattened runs
1099
- */
1100
- const flattenRegularRuns = (runs) => {
1101
- const res = [];
1102
- const points = generatePoints(runs);
1103
- let start = -1;
1104
- let attrs = {};
1105
- const stack = [];
1106
- for (let i = 0; i < points.length; i += 1) {
1107
- const [type, offset, attributes] = points[i];
1108
- if (start !== -1 && start < offset) {
1109
- res.push({
1110
- start,
1111
- end: offset,
1112
- attributes: attrs,
1113
- glyphIndices: [],
1114
- glyphs: [],
1115
- positions: [],
1116
- });
1117
- }
1118
- if (type === 'start') {
1119
- stack.push(attributes);
1120
- attrs = Object.assign({}, attrs, attributes);
1121
- }
1122
- else {
1123
- attrs = {};
1124
- for (let j = 0; j < stack.length; j += 1) {
1125
- if (stack[j] === attributes) {
1126
- stack.splice(j--, 1);
1127
- }
1128
- else {
1129
- attrs = Object.assign({}, attrs, stack[j]);
1130
- }
1131
- }
1132
- }
1133
- start = offset;
1134
- }
1135
- return res;
1136
- };
1137
- /**
1138
- * Flatten many runs
1139
- *
1140
- * @param runs
1141
- * @returns Flattened runs
1142
- */
1143
- const flatten = (runs = []) => {
1144
- const emptyRuns = flattenEmptyRuns(runs.filter((run) => isEmpty(run)));
1145
- const regularRuns = flattenRegularRuns(runs.filter((run) => !isEmpty(run)));
1146
- return sort(emptyRuns.concat(regularRuns));
1147
- };
1148
-
1149
- /**
1150
- * Returns empty attributed string
1151
- *
1152
- * @returns Empty attributed string
1153
- */
1154
- const empty = () => ({ string: '', runs: [] });
1155
-
1156
- /**
1157
- *
1158
- * @param attributedString
1159
- * @returns Attributed string without font
1160
- */
1161
- const omitFont = (attributedString) => {
1162
- const runs = attributedString.runs.map((run) => omit('font', run));
1163
- return Object.assign({}, attributedString, { runs });
1164
- };
1165
- /**
1166
- * Performs font substitution and script itemization on attributed string
1167
- *
1168
- * @param engines - engines
1169
- */
1170
- const preprocessRuns = (engines) => {
1171
- /**
1172
- * @param attributedString - Attributed string
1173
- * @returns Processed attributed string
1174
- */
1175
- return (attributedString) => {
1176
- if (isNil(attributedString))
1177
- return empty();
1178
- const { string } = attributedString;
1179
- const { fontSubstitution, scriptItemizer, bidi } = engines;
1180
- const { runs: omittedFontRuns } = omitFont(attributedString);
1181
- const { runs: itemizationRuns } = scriptItemizer()(attributedString);
1182
- const { runs: substitutedRuns } = fontSubstitution()(attributedString);
1183
- const { runs: bidiRuns } = bidi()(attributedString);
1184
- const runs = bidiRuns
1185
- .concat(substitutedRuns)
1186
- .concat(itemizationRuns)
1187
- .concat(omittedFontRuns);
1188
- return { string, runs: flatten(runs) };
1189
- };
1190
- };
1191
-
1192
- /**
1193
- * Breaks attributed string into paragraphs
1194
- */
1195
- const splitParagraphs = () => {
1196
- /**
1197
- * @param attributedString - Attributed string
1198
- * @returns Paragraphs attributed strings
1199
- */
1200
- return (attributedString) => {
1201
- const paragraphs = [];
1202
- let start = 0;
1203
- let breakPoint = attributedString.string.indexOf('\n') + 1;
1204
- while (breakPoint > 0) {
1205
- paragraphs.push(slice(start, breakPoint, attributedString));
1206
- start = breakPoint;
1207
- breakPoint = attributedString.string.indexOf('\n', breakPoint) + 1;
1208
- }
1209
- if (start === 0) {
1210
- paragraphs.push(attributedString);
1211
- }
1212
- else if (start < attributedString.string.length) {
1213
- paragraphs.push(slice(start, length$1(attributedString), attributedString));
1214
- }
1215
- return paragraphs;
1216
- };
1217
- };
1218
-
1219
- /**
1220
- * Return positions advance width
1221
- *
1222
- * @param positions - Positions
1223
- * @returns {number} advance width
1224
- */
1225
- const advanceWidth$2 = (positions) => {
1226
- return positions.reduce((acc, pos) => acc + (pos.xAdvance || 0), 0);
1227
- };
1228
-
1229
- /**
1230
- * Return run advance width
1231
- *
1232
- * @param run - Run
1233
- * @returns Advance width
1234
- */
1235
- const advanceWidth$1 = (run) => {
1236
- return advanceWidth$2(run.positions || []);
1237
- };
1238
-
1239
- /**
1240
- * Returns attributed string advancewidth
1241
- *
1242
- * @param attributedString - Attributed string
1243
- * @returns Advance width
1244
- */
1245
- const advanceWidth = (attributedString) => {
1246
- const reducer = (acc, run) => acc + advanceWidth$1(run);
1247
- return attributedString.runs.reduce(reducer, 0);
1248
- };
1249
-
1250
- const WHITE_SPACES_CODE = 32;
1251
- /**
1252
- * Check if glyph is white space
1253
- *
1254
- * @param glyph - Glyph
1255
- * @returns Whether glyph is white space
1256
- * */
1257
- const isWhiteSpace = (glyph) => {
1258
- const codePoints = glyph?.codePoints || [];
1259
- return codePoints.includes(WHITE_SPACES_CODE);
1260
- };
1261
-
1262
- /**
1263
- * Get white space leading positions
1264
- *
1265
- * @param run - Run
1266
- * @returns White space leading positions
1267
- */
1268
- const leadingPositions = (run) => {
1269
- const glyphs = run.glyphs || [];
1270
- const positions = run.positions || [];
1271
- const leadingWhitespaces = glyphs.findIndex((g) => !isWhiteSpace(g));
1272
- return positions.slice(0, leadingWhitespaces);
1273
- };
1274
- /**
1275
- * Get run leading white space offset
1276
- *
1277
- * @param run - Run
1278
- * @returns Leading white space offset
1279
- */
1280
- const leadingOffset$1 = (run) => {
1281
- const positions = leadingPositions(run);
1282
- return positions.reduce((acc, pos) => acc + (pos.xAdvance || 0), 0);
1283
- };
1284
-
1285
- /**
1286
- * Get attributed string leading white space offset
1287
- *
1288
- * @param attributedString - Attributed string
1289
- * @returns Leading white space offset
1290
- */
1291
- const leadingOffset = (attributedString) => {
1292
- const runs = attributedString.runs || [];
1293
- return leadingOffset$1(runs[0]);
1294
- };
1295
-
1296
- /**
1297
- * Get white space trailing positions
1298
- *
1299
- * @param run run
1300
- * @returns White space trailing positions
1301
- */
1302
- const trailingPositions = (run) => {
1303
- const glyphs = reverse(run.glyphs || []);
1304
- const positions = reverse(run.positions || []);
1305
- const leadingWhitespaces = glyphs.findIndex((g) => !isWhiteSpace(g));
1306
- return positions.slice(0, leadingWhitespaces);
1307
- };
1308
- /**
1309
- * Get run trailing white space offset
1310
- *
1311
- * @param run - Run
1312
- * @returns Trailing white space offset
1313
- */
1314
- const trailingOffset$1 = (run) => {
1315
- const positions = trailingPositions(run);
1316
- return positions.reduce((acc, pos) => acc + (pos.xAdvance || 0), 0);
1317
- };
1318
-
1319
- /**
1320
- * Get attributed string trailing white space offset
1321
- *
1322
- * @param attributedString - Attributed string
1323
- * @returns Trailing white space offset
1324
- */
1325
- const trailingOffset = (attributedString) => {
1326
- const runs = attributedString.runs || [];
1327
- return trailingOffset$1(last(runs));
1328
- };
1329
-
1330
- /**
1331
- * Drop last char of run
1332
- *
1333
- * @param run - Run
1334
- * @returns Run without last char
1335
- */
1336
- const dropLast$1 = (run) => {
1337
- return slice$1(0, run.end - run.start - 1, run);
1338
- };
1339
-
1340
- /**
1341
- * Drop last glyph
1342
- *
1343
- * @param attributedString - Attributed string
1344
- * @returns Attributed string with new glyph
1345
- */
1346
- const dropLast = (attributedString) => {
1347
- const string = dropLast$2(attributedString.string);
1348
- const runs = adjust(-1, dropLast$1, attributedString.runs);
1349
- return Object.assign({}, attributedString, { string, runs });
1350
- };
1351
-
1352
- const ALIGNMENT_FACTORS = { center: 0.5, right: 1 };
1353
- /**
1354
- * Remove new line char at the end of line if present
1355
- *
1356
- * @param line
1357
- * @returns Line
1358
- */
1359
- const removeNewLine = (line) => {
1360
- return last(line.string) === '\n' ? dropLast(line) : line;
1361
- };
1362
- const getOverflowLeft = (line) => {
1363
- return leadingOffset(line) + (line.overflowLeft || 0);
1364
- };
1365
- const getOverflowRight = (line) => {
1366
- return trailingOffset(line) + (line.overflowRight || 0);
1367
- };
1368
- /**
1369
- * Ignore whitespace at the start and end of a line for alignment
1370
- *
1371
- * @param line
1372
- * @returns Line
1373
- */
1374
- const adjustOverflow = (line) => {
1375
- const overflowLeft = getOverflowLeft(line);
1376
- const overflowRight = getOverflowRight(line);
1377
- const x = line.box.x - overflowLeft;
1378
- const width = line.box.width + overflowLeft + overflowRight;
1379
- const box = Object.assign({}, line.box, { x, width });
1380
- return Object.assign({}, line, { box, overflowLeft, overflowRight });
1381
- };
1382
- /**
1383
- * Performs line justification by calling appropiate engine
1384
- *
1385
- * @param engines - Engines
1386
- * @param options - Layout options
1387
- * @param align - Text align
1388
- */
1389
- const justifyLine$1 = (engines, options, align) => {
1390
- /**
1391
- * @param line - Line
1392
- * @returns Line
1393
- */
1394
- return (line) => {
1395
- const lineWidth = advanceWidth(line);
1396
- const alignFactor = ALIGNMENT_FACTORS[align] || 0;
1397
- const remainingWidth = Math.max(0, line.box.width - lineWidth);
1398
- const shouldJustify = align === 'justify' || lineWidth > line.box.width;
1399
- const x = line.box.x + remainingWidth * alignFactor;
1400
- const box = Object.assign({}, line.box, { x });
1401
- const newLine = Object.assign({}, line, { box });
1402
- return shouldJustify ? engines.justification(options)(newLine) : newLine;
1403
- };
1404
- };
1405
- const finalizeLine = (line) => {
1406
- let lineAscent = 0;
1407
- let lineDescent = 0;
1408
- let lineHeight = 0;
1409
- let lineXAdvance = 0;
1410
- const runs = line.runs.map((run) => {
1411
- const height = height$1(run);
1412
- const ascent = ascent$1(run);
1413
- const descent$1 = descent(run);
1414
- const xAdvance = advanceWidth$1(run);
1415
- lineHeight = Math.max(lineHeight, height);
1416
- lineAscent = Math.max(lineAscent, ascent);
1417
- lineDescent = Math.max(lineDescent, descent$1);
1418
- lineXAdvance += xAdvance;
1419
- return Object.assign({}, run, { height, ascent, descent: descent$1, xAdvance });
1420
- });
1421
- return Object.assign({}, line, {
1422
- runs,
1423
- height: lineHeight,
1424
- ascent: lineAscent,
1425
- descent: lineDescent,
1426
- xAdvance: lineXAdvance,
1427
- });
1428
- };
1429
- /**
1430
- * Finalize line by performing line justification
1431
- * and text decoration (using appropiate engines)
1432
- *
1433
- * @param engines - Engines
1434
- * @param options - Layout options
1435
- */
1436
- const finalizeBlock = (engines, options) => {
1437
- /**
1438
- * @param line - Line
1439
- * @param i - Line index
1440
- * @param lines - Total lines
1441
- * @returns Line
1442
- */
1443
- return (line, index, lines) => {
1444
- const isLastFragment = index === lines.length - 1;
1445
- const style = line.runs?.[0]?.attributes || {};
1446
- const align = isLastFragment ? style.alignLastLine : style.align;
1447
- return compose(finalizeLine, engines.textDecoration(), justifyLine$1(engines, options, align), adjustOverflow, removeNewLine)(line);
1448
- };
1449
- };
1450
- /**
1451
- * Finalize line block by performing line justification
1452
- * and text decoration (using appropiate engines)
1453
- *
1454
- * @param engines - Engines
1455
- * @param options - Layout options
1456
- */
1457
- const finalizeFragments = (engines, options) => {
1458
- /**
1459
- * @param paragraphs - Paragraphs
1460
- * @returns Paragraphs
1461
- */
1462
- return (paragraphs) => {
1463
- const blockFinalizer = finalizeBlock(engines, options);
1464
- return paragraphs.map((paragraph) => paragraph.map(blockFinalizer));
1465
- };
1466
- };
1467
-
1468
- const ATTACHMENT_CODE = 0xfffc; // 65532
1469
- const isReplaceGlyph = (glyph) => glyph.codePoints.includes(ATTACHMENT_CODE);
1470
- /**
1471
- * Resolve attachments of run
1472
- *
1473
- * @param run
1474
- * @returns Run
1475
- */
1476
- const resolveRunAttachments = (run) => {
1477
- if (!run.positions)
1478
- return run;
1479
- const glyphs = run.glyphs || [];
1480
- const attachment = run.attributes?.attachment;
1481
- if (!attachment)
1482
- return run;
1483
- const positions = run.positions.map((position, i) => {
1484
- const glyph = glyphs[i];
1485
- if (attachment.width && isReplaceGlyph(glyph)) {
1486
- return Object.assign({}, position, { xAdvance: attachment.width });
1487
- }
1488
- return Object.assign({}, position);
1489
- });
1490
- return Object.assign({}, run, { positions });
1491
- };
1492
- /**
1493
- * Resolve attachments for multiple paragraphs
1494
- */
1495
- const resolveAttachments = () => {
1496
- /**
1497
- * @param attributedString - Attributed string
1498
- * @returns Attributed string
1499
- */
1500
- return (attributedString) => {
1501
- const runs = attributedString.runs.map(resolveRunAttachments);
1502
- const res = Object.assign({}, attributedString, { runs });
1503
- return res;
1504
- };
1505
- };
1506
-
1507
- /**
1508
- * @param attributes - Attributes
1509
- * @returns Attributes with defaults
1510
- */
1511
- const applyAttributes = (a) => {
1512
- return {
1513
- align: a.align || (a.direction === 'rtl' ? 'right' : 'left'),
1514
- alignLastLine: a.alignLastLine || (a.align === 'justify' ? 'left' : a.align || 'left'),
1515
- attachment: a.attachment || null,
1516
- backgroundColor: a.backgroundColor || null,
1517
- bullet: a.bullet || null,
1518
- characterSpacing: a.characterSpacing || 0,
1519
- color: a.color || 'black',
1520
- direction: a.direction || 'ltr',
1521
- features: a.features || [],
1522
- fill: a.fill !== false,
1523
- font: a.font || [],
1524
- fontSize: a.fontSize || 12,
1525
- hangingPunctuation: a.hangingPunctuation || false,
1526
- hyphenationFactor: a.hyphenationFactor || 0,
1527
- indent: a.indent || 0,
1528
- justificationFactor: a.justificationFactor || 1,
1529
- lineHeight: a.lineHeight || null,
1530
- lineSpacing: a.lineSpacing || 0,
1531
- link: a.link || null,
1532
- marginLeft: a.marginLeft || a.margin || 0,
1533
- marginRight: a.marginRight || a.margin || 0,
1534
- opacity: a.opacity,
1535
- paddingTop: a.paddingTop || a.padding || 0,
1536
- paragraphSpacing: a.paragraphSpacing || 0,
1537
- script: a.script || null,
1538
- shrinkFactor: a.shrinkFactor || 0,
1539
- strike: a.strike || false,
1540
- strikeColor: a.strikeColor || a.color || 'black',
1541
- strikeStyle: a.strikeStyle || 'solid',
1542
- stroke: a.stroke || false,
1543
- underline: a.underline || false,
1544
- underlineColor: a.underlineColor || a.color || 'black',
1545
- underlineStyle: a.underlineStyle || 'solid',
1546
- verticalAlign: a.verticalAlign || null,
1547
- wordSpacing: a.wordSpacing || 0,
1548
- yOffset: a.yOffset || 0,
1549
- };
1550
- };
1551
- /**
1552
- * Apply default style to run
1553
- *
1554
- * @param run - Run
1555
- * @returns Run with default styles
1556
- */
1557
- const applyRunStyles = (run) => {
1558
- const attributes = applyAttributes(run.attributes);
1559
- return Object.assign({}, run, { attributes });
1560
- };
1561
- /**
1562
- * Apply default attributes for an attributed string
1563
- */
1564
- const applyDefaultStyles = () => {
1565
- return (attributedString) => {
1566
- const string = attributedString.string || '';
1567
- const runs = (attributedString.runs || []).map(applyRunStyles);
1568
- return { string, runs };
1569
- };
1570
- };
1571
-
1572
- /**
1573
- * Apply scaling and yOffset for verticalAlign 'sub' and 'super'.
1574
- */
1575
- const verticalAlignment = () => {
1576
- /**
1577
- * @param attributedString - Attributed string
1578
- * @returns Attributed string
1579
- */
1580
- return (attributedString) => {
1581
- attributedString.runs.forEach((run) => {
1582
- const { attributes } = run;
1583
- const { verticalAlign } = attributes;
1584
- if (verticalAlign === 'sub') {
1585
- attributes.yOffset = -0.2;
1586
- }
1587
- else if (verticalAlign === 'super') {
1588
- attributes.yOffset = 0.4;
1589
- }
1590
- });
1591
- return attributedString;
1592
- };
1593
- };
1594
-
1595
- const bidi$1 = bidiFactory();
1596
- /**
1597
- * @param runs
1598
- * @returns Bidi levels
1599
- */
1600
- const getBidiLevels = (runs) => {
1601
- return runs.reduce((acc, run) => {
1602
- const length = run.end - run.start;
1603
- const levels = repeat(run.attributes.bidiLevel, length);
1604
- return acc.concat(levels);
1605
- }, []);
1606
- };
1607
- /**
1608
- * Perform bidi mirroring
1609
- */
1610
- const mirrorString = () => {
1611
- /**
1612
- * @param attributedString - Attributed string
1613
- * @returns Attributed string
1614
- */
1615
- return (attributedString) => {
1616
- const levels = getBidiLevels(attributedString.runs);
1617
- let updatedString = '';
1618
- attributedString.string.split('').forEach((char, index) => {
1619
- const isRTL = levels[index] % 2 === 1;
1620
- const mirroredChar = isRTL
1621
- ? bidi$1.getMirroredCharacter(attributedString.string.charAt(index))
1622
- : null;
1623
- updatedString += mirroredChar || char;
1624
- });
1625
- const result = {
1626
- ...attributedString,
1627
- string: updatedString,
1628
- };
1629
- return result;
1630
- };
1631
- };
1632
-
1633
- /**
1634
- * A LayoutEngine is the main object that performs text layout.
1635
- * It accepts an AttributedString and a Container object
1636
- * to layout text into, and uses several helper objects to perform
1637
- * various layout tasks. These objects can be overridden to customize
1638
- * layout behavior.
1639
- */
1640
- const layoutEngine = (engines) => {
1641
- return (attributedString, container, options = {}) => {
1642
- const processParagraph = compose(resolveYOffset(), resolveAttachments(), verticalAlignment(), wrapWords(engines, options), generateGlyphs(), mirrorString(), preprocessRuns(engines));
1643
- const processParagraphs = (paragraphs) => paragraphs.map(processParagraph);
1644
- return compose(finalizeFragments(engines, options), bidiReordering(), typesetter(engines, options, container), processParagraphs, splitParagraphs(), applyDefaultStyles())(attributedString);
1645
- };
1646
- };
1647
-
1648
- const bidi = bidiFactory();
1649
- const bidiEngine = () => {
1650
- /**
1651
- * @param attributedString - Attributed string
1652
- * @returns Attributed string
1653
- */
1654
- return (attributedString) => {
1655
- const { string } = attributedString;
1656
- const direction = attributedString.runs[0]?.attributes.direction;
1657
- const { levels } = bidi.getEmbeddingLevels(string, direction);
1658
- let lastLevel = null;
1659
- let lastIndex = 0;
1660
- let index = 0;
1661
- const runs = [];
1662
- for (let i = 0; i < levels.length; i += 1) {
1663
- const level = levels[i];
1664
- if (level !== lastLevel) {
1665
- if (lastLevel !== null) {
1666
- runs.push({
1667
- start: lastIndex,
1668
- end: index,
1669
- attributes: { bidiLevel: lastLevel },
1670
- });
1671
- }
1672
- lastIndex = index;
1673
- lastLevel = level;
1674
- }
1675
- index += 1;
1676
- }
1677
- if (lastIndex < string.length) {
1678
- runs.push({
1679
- start: lastIndex,
1680
- end: string.length,
1681
- attributes: { bidiLevel: lastLevel },
1682
- });
1683
- }
1684
- const result = { string, runs };
1685
- return result;
1686
- };
1687
- };
1688
-
1689
- const INFINITY = 10000;
1690
- const getNextBreakpoint = (subnodes, widths, lineNumber) => {
1691
- let position = null;
1692
- let minimumBadness = Infinity;
1693
- const sum = { width: 0, stretch: 0, shrink: 0 };
1694
- const lineLength = widths[Math.min(lineNumber, widths.length - 1)];
1695
- const calculateRatio = (node) => {
1696
- const stretch = 'stretch' in node ? node.stretch : null;
1697
- if (sum.width < lineLength) {
1698
- if (!stretch)
1699
- return INFINITY;
1700
- return sum.stretch - stretch > 0
1701
- ? (lineLength - sum.width) / sum.stretch
1702
- : INFINITY;
1703
- }
1704
- const shrink = 'shrink' in node ? node.shrink : null;
1705
- if (sum.width > lineLength) {
1706
- if (!shrink)
1707
- return INFINITY;
1708
- return sum.shrink - shrink > 0
1709
- ? (lineLength - sum.width) / sum.shrink
1710
- : INFINITY;
1711
- }
1712
- return 0;
1713
- };
1714
- for (let i = 0; i < subnodes.length; i += 1) {
1715
- const node = subnodes[i];
1716
- if (node.type === 'box') {
1717
- sum.width += node.width;
1718
- }
1719
- if (node.type === 'glue') {
1720
- sum.width += node.width;
1721
- sum.stretch += node.stretch;
1722
- sum.shrink += node.shrink;
1723
- }
1724
- if (sum.width - sum.shrink > lineLength) {
1725
- if (position === null) {
1726
- let j = i === 0 ? i + 1 : i;
1727
- while (j < subnodes.length &&
1728
- (subnodes[j].type === 'glue' || subnodes[j].type === 'penalty')) {
1729
- j++;
1730
- }
1731
- position = j - 1;
1732
- }
1733
- break;
1734
- }
1735
- if (node.type === 'penalty' || node.type === 'glue') {
1736
- const ratio = calculateRatio(node);
1737
- const penalty = node.type === 'penalty' ? node.penalty : 0;
1738
- const badness = 100 * Math.abs(ratio) ** 3 + penalty;
1739
- if (minimumBadness >= badness) {
1740
- position = i;
1741
- minimumBadness = badness;
1742
- }
1743
- }
1744
- }
1745
- return sum.width - sum.shrink > lineLength ? position : null;
1746
- };
1747
- const applyBestFit = (nodes, widths) => {
1748
- let count = 0;
1749
- let lineNumber = 0;
1750
- let subnodes = nodes;
1751
- const breakpoints = [0];
1752
- while (subnodes.length > 0) {
1753
- const breakpoint = getNextBreakpoint(subnodes, widths, lineNumber);
1754
- if (breakpoint !== null) {
1755
- count += breakpoint;
1756
- breakpoints.push(count);
1757
- subnodes = subnodes.slice(breakpoint + 1, subnodes.length);
1758
- count++;
1759
- lineNumber++;
1760
- }
1761
- else {
1762
- subnodes = [];
1763
- }
1764
- }
1765
- return breakpoints;
1766
- };
1767
-
1768
- /* eslint-disable max-classes-per-file */
1769
- class LinkedListNode {
1770
- data;
1771
- prev;
1772
- next;
1773
- constructor(data) {
1774
- this.data = data;
1775
- this.prev = null;
1776
- this.next = null;
1777
- }
1778
- }
1779
- class LinkedList {
1780
- static Node = LinkedListNode;
1781
- head;
1782
- tail;
1783
- listSize;
1784
- listLength;
1785
- constructor() {
1786
- this.head = null;
1787
- this.tail = null;
1788
- this.listSize = 0;
1789
- this.listLength = 0;
1790
- }
1791
- isLinked(node) {
1792
- return !((node &&
1793
- node.prev === null &&
1794
- node.next === null &&
1795
- this.tail !== node &&
1796
- this.head !== node) ||
1797
- this.isEmpty());
1798
- }
1799
- size() {
1800
- return this.listSize;
1801
- }
1802
- isEmpty() {
1803
- return this.listSize === 0;
1804
- }
1805
- first() {
1806
- return this.head;
1807
- }
1808
- last() {
1809
- return this.last;
1810
- }
1811
- forEach(callback) {
1812
- let node = this.head;
1813
- while (node !== null) {
1814
- callback(node);
1815
- node = node.next;
1816
- }
1817
- }
1818
- at(i) {
1819
- let node = this.head;
1820
- let index = 0;
1821
- if (i >= this.listLength || i < 0) {
1822
- return null;
1823
- }
1824
- while (node !== null) {
1825
- if (i === index) {
1826
- return node;
1827
- }
1828
- node = node.next;
1829
- index += 1;
1830
- }
1831
- return null;
1832
- }
1833
- insertAfter(node, newNode) {
1834
- if (!this.isLinked(node))
1835
- return this;
1836
- newNode.prev = node;
1837
- newNode.next = node.next;
1838
- if (node.next === null) {
1839
- this.tail = newNode;
1840
- }
1841
- else {
1842
- node.next.prev = newNode;
1843
- }
1844
- node.next = newNode;
1845
- this.listSize += 1;
1846
- return this;
1847
- }
1848
- insertBefore(node, newNode) {
1849
- if (!this.isLinked(node))
1850
- return this;
1851
- newNode.prev = node.prev;
1852
- newNode.next = node;
1853
- if (node.prev === null) {
1854
- this.head = newNode;
1855
- }
1856
- else {
1857
- node.prev.next = newNode;
1858
- }
1859
- node.prev = newNode;
1860
- this.listSize += 1;
1861
- return this;
1862
- }
1863
- push(node) {
1864
- if (this.head === null) {
1865
- this.unshift(node);
1866
- }
1867
- else {
1868
- this.insertAfter(this.tail, node);
1869
- }
1870
- return this;
1871
- }
1872
- unshift(node) {
1873
- if (this.head === null) {
1874
- this.head = node;
1875
- this.tail = node;
1876
- node.prev = null;
1877
- node.next = null;
1878
- this.listSize += 1;
1879
- }
1880
- else {
1881
- this.insertBefore(this.head, node);
1882
- }
1883
- return this;
1884
- }
1885
- remove(node) {
1886
- if (!this.isLinked(node))
1887
- return this;
1888
- if (node.prev === null) {
1889
- this.head = node.next;
1890
- }
1891
- else {
1892
- node.prev.next = node.next;
1893
- }
1894
- if (node.next === null) {
1895
- this.tail = node.prev;
1896
- }
1897
- else {
1898
- node.next.prev = node.prev;
1899
- }
1900
- this.listSize -= 1;
1901
- return this;
1902
- }
1903
- }
1904
-
1905
- /**
1906
- * Licensed under the new BSD License.
1907
- * Copyright 2009-2010, Bram Stein
1908
- * All rights reserved.
1909
- */
1910
- function breakpoint(position, demerits, line, fitnessClass, totals, previous) {
1911
- return {
1912
- position,
1913
- demerits,
1914
- line,
1915
- fitnessClass,
1916
- totals: totals || {
1917
- width: 0,
1918
- stretch: 0,
1919
- shrink: 0,
1920
- },
1921
- previous,
1922
- };
1923
- }
1924
- function computeCost(nodes, lineLengths, sum, end, active, currentLine) {
1925
- let width = sum.width - active.totals.width;
1926
- let stretch = 0;
1927
- let shrink = 0;
1928
- // If the current line index is within the list of linelengths, use it, otherwise use
1929
- // the last line length of the list.
1930
- const lineLength = currentLine < lineLengths.length
1931
- ? lineLengths[currentLine - 1]
1932
- : lineLengths[lineLengths.length - 1];
1933
- if (nodes[end].type === 'penalty') {
1934
- width += nodes[end].width;
1935
- }
1936
- // Calculate the stretch ratio
1937
- if (width < lineLength) {
1938
- stretch = sum.stretch - active.totals.stretch;
1939
- if (stretch > 0) {
1940
- return (lineLength - width) / stretch;
1941
- }
1942
- return linebreak.infinity;
1943
- }
1944
- // Calculate the shrink ratio
1945
- if (width > lineLength) {
1946
- shrink = sum.shrink - active.totals.shrink;
1947
- if (shrink > 0) {
1948
- return (lineLength - width) / shrink;
1949
- }
1950
- return linebreak.infinity;
1951
- }
1952
- // perfect match
1953
- return 0;
1954
- }
1955
- // Add width, stretch and shrink values from the current
1956
- // break point up to the next box or forced penalty.
1957
- function computeSum(nodes, sum, breakPointIndex) {
1958
- const result = {
1959
- width: sum.width,
1960
- stretch: sum.stretch,
1961
- shrink: sum.shrink,
1962
- };
1963
- for (let i = breakPointIndex; i < nodes.length; i += 1) {
1964
- const node = nodes[i];
1965
- if (node.type === 'glue') {
1966
- result.width += node.width;
1967
- result.stretch += node.stretch;
1968
- result.shrink += node.shrink;
1969
- }
1970
- else if (node.type === 'box' ||
1971
- (node.type === 'penalty' &&
1972
- node.penalty === -linebreak.infinity &&
1973
- i > breakPointIndex)) {
1974
- break;
1975
- }
1976
- }
1977
- return result;
1978
- }
1979
- function findBestBreakpoints(activeNodes) {
1980
- const breakpoints = [];
1981
- if (activeNodes.size() === 0)
1982
- return [];
1983
- let tmp = { data: { demerits: Infinity } };
1984
- // Find the best active node (the one with the least total demerits.)
1985
- activeNodes.forEach((node) => {
1986
- if (node.data.demerits < tmp.data.demerits) {
1987
- tmp = node;
1988
- }
1989
- });
1990
- while (tmp !== null) {
1991
- breakpoints.push(tmp.data.position);
1992
- tmp = tmp.data.previous;
1993
- }
1994
- return breakpoints.reverse();
1995
- }
1996
- /**
1997
- * @param nodes
1998
- * @param availableWidths
1999
- * @param tolerance
2000
- * @preserve Knuth and Plass line breaking algorithm in JavaScript
2001
- */
2002
- const linebreak = (nodes, availableWidths, tolerance) => {
2003
- // Demerits are used as a way to penalize bad line breaks
2004
- // - line: applied to each line, depending on how much spaces need to stretch or shrink
2005
- // - flagged: applied when consecutive lines end in hyphenation
2006
- // - fitness: algorithm groups lines into fitness classes based on how loose or tight the spacing is.
2007
- // if a paragraph has consecutive lines from different fitness classes,
2008
- // a fitness demerit is applied to maintain visual consistency.
2009
- const options = {
2010
- demerits: { line: 10, flagged: 100, fitness: 3000 },
2011
- tolerance: tolerance || 3,
2012
- };
2013
- const activeNodes = new LinkedList();
2014
- const sum = { width: 0, stretch: 0, shrink: 0 };
2015
- const lineLengths = availableWidths;
2016
- // Add an active node for the start of the paragraph.
2017
- activeNodes.push(new LinkedList.Node(breakpoint(0, 0, 0, 0, undefined, null)));
2018
- // The main loop of the algorithm
2019
- function mainLoop(node, index, nodes) {
2020
- let active = activeNodes.first();
2021
- // The inner loop iterates through all the active nodes with line < currentLine and then
2022
- // breaks out to insert the new active node candidates before looking at the next active
2023
- // nodes for the next lines. The result of this is that the active node list is always
2024
- // sorted by line number.
2025
- while (active !== null) {
2026
- let currentLine = 0;
2027
- // Candidates fo each fitness class
2028
- const candidates = [
2029
- { active: undefined, demerits: Infinity },
2030
- { active: undefined, demerits: Infinity },
2031
- { active: undefined, demerits: Infinity },
2032
- { active: undefined, demerits: Infinity },
2033
- ];
2034
- // Iterate through the linked list of active nodes to find new potential active nodes and deactivate current active nodes.
2035
- while (active !== null) {
2036
- currentLine = active.data.line + 1;
2037
- const ratio = computeCost(nodes, lineLengths, sum, index, active.data, currentLine);
2038
- // Deactive nodes when the distance between the current active node and the
2039
- // current node becomes too large (i.e. it exceeds the stretch limit and the stretch
2040
- // ratio becomes negative) or when the current node is a forced break (i.e. the end
2041
- // of the paragraph when we want to remove all active nodes, but possibly have a final
2042
- // candidate active node---if the paragraph can be set using the given tolerance value.)
2043
- if (ratio < -1 ||
2044
- (node.type === 'penalty' && node.penalty === -linebreak.infinity)) {
2045
- activeNodes.remove(active);
2046
- }
2047
- // If the ratio is within the valid range of -1 <= ratio <= tolerance calculate the
2048
- // total demerits and record a candidate active node.
2049
- if (ratio >= -1 && ratio <= options.tolerance) {
2050
- const badness = 100 * Math.pow(Math.abs(ratio), 3);
2051
- let demerits = 0;
2052
- // Positive penalty
2053
- if (node.type === 'penalty' && node.penalty >= 0) {
2054
- demerits =
2055
- Math.pow(options.demerits.line + badness, 2) +
2056
- Math.pow(node.penalty, 2);
2057
- // Negative penalty but not a forced break
2058
- }
2059
- else if (node.type === 'penalty' &&
2060
- node.penalty !== -linebreak.infinity) {
2061
- demerits =
2062
- Math.pow(options.demerits.line + badness, 2) -
2063
- Math.pow(node.penalty, 2);
2064
- // All other cases
2065
- }
2066
- else {
2067
- demerits = Math.pow(options.demerits.line + badness, 2);
2068
- }
2069
- if (node.type === 'penalty' &&
2070
- nodes[active.data.position].type === 'penalty') {
2071
- demerits +=
2072
- options.demerits.flagged *
2073
- node.flagged *
2074
- // @ts-expect-error node is penalty here
2075
- nodes[active.data.position].flagged;
2076
- }
2077
- // Calculate the fitness class for this candidate active node.
2078
- let currentClass;
2079
- if (ratio < -0.5) {
2080
- currentClass = 0;
2081
- }
2082
- else if (ratio <= 0.5) {
2083
- currentClass = 1;
2084
- }
2085
- else if (ratio <= 1) {
2086
- currentClass = 2;
2087
- }
2088
- else {
2089
- currentClass = 3;
2090
- }
2091
- // Add a fitness penalty to the demerits if the fitness classes of two adjacent lines differ too much.
2092
- if (Math.abs(currentClass - active.data.fitnessClass) > 1) {
2093
- demerits += options.demerits.fitness;
2094
- }
2095
- // Add the total demerits of the active node to get the total demerits of this candidate node.
2096
- demerits += active.data.demerits;
2097
- // Only store the best candidate for each fitness class
2098
- if (demerits < candidates[currentClass].demerits) {
2099
- candidates[currentClass] = { active, demerits };
2100
- }
2101
- }
2102
- active = active.next;
2103
- // Stop iterating through active nodes to insert new candidate active nodes in the active list
2104
- // before moving on to the active nodes for the next line.
2105
- // TODO: The Knuth and Plass paper suggests a conditional for currentLine < j0. This means paragraphs
2106
- // with identical line lengths will not be sorted by line number. Find out if that is a desirable outcome.
2107
- // For now I left this out, as it only adds minimal overhead to the algorithm and keeping the active node
2108
- // list sorted has a higher priority.
2109
- if (active !== null && active.data.line >= currentLine) {
2110
- break;
2111
- }
2112
- }
2113
- const tmpSum = computeSum(nodes, sum, index);
2114
- for (let fitnessClass = 0; fitnessClass < candidates.length; fitnessClass += 1) {
2115
- const candidate = candidates[fitnessClass];
2116
- if (candidate.demerits === Infinity)
2117
- continue;
2118
- const newNode = new LinkedList.Node(breakpoint(index, candidate.demerits, candidate.active.data.line + 1, fitnessClass, tmpSum, candidate.active));
2119
- if (active !== null) {
2120
- activeNodes.insertBefore(active, newNode);
2121
- }
2122
- else {
2123
- activeNodes.push(newNode);
2124
- }
2125
- }
2126
- }
2127
- }
2128
- nodes.forEach((node, index, nodes) => {
2129
- if (node.type === 'box') {
2130
- sum.width += node.width;
2131
- return;
2132
- }
2133
- if (node.type === 'glue') {
2134
- const precedesBox = index > 0 && nodes[index - 1].type === 'box';
2135
- if (precedesBox)
2136
- mainLoop(node, index, nodes);
2137
- sum.width += node.width;
2138
- sum.stretch += node.stretch;
2139
- sum.shrink += node.shrink;
2140
- return;
2141
- }
2142
- if (node.type === 'penalty' && node.penalty !== linebreak.infinity) {
2143
- mainLoop(node, index, nodes);
2144
- }
2145
- });
2146
- return findBestBreakpoints(activeNodes);
2147
- };
2148
- linebreak.infinity = 10000;
2149
- linebreak.glue = (width, start, end, stretch, shrink) => ({
2150
- type: 'glue',
2151
- start,
2152
- end,
2153
- width,
2154
- stretch,
2155
- shrink,
2156
- });
2157
- linebreak.box = (width, start, end, hyphenated = false) => ({
2158
- type: 'box',
2159
- width,
2160
- start,
2161
- end,
2162
- hyphenated,
2163
- });
2164
- linebreak.penalty = (width, penalty, flagged) => ({
2165
- type: 'penalty',
2166
- width,
2167
- penalty,
2168
- flagged,
2169
- });
2170
-
2171
- /**
2172
- * Add scalar to run
2173
- *
2174
- * @param index - Scalar
2175
- * @param run - Run
2176
- * @returns Added run
2177
- */
2178
- const add = (index, run) => {
2179
- const start = run.start + index;
2180
- const end = run.end + index;
2181
- return Object.assign({}, run, { start, end });
2182
- };
2183
-
2184
- /**
2185
- * Get run length
2186
- *
2187
- * @param run - Run
2188
- * @returns Length
2189
- */
2190
- const length = (run) => {
2191
- return run.end - run.start;
2192
- };
2193
-
2194
- /**
2195
- * Concats two runs into one
2196
- *
2197
- * @param runA - First run
2198
- * @param runB - Second run
2199
- * @returns Concatenated run
2200
- */
2201
- const concat = (runA, runB) => {
2202
- const end = runA.end + length(runB);
2203
- const glyphs = (runA.glyphs || []).concat(runB.glyphs || []);
2204
- const positions = (runA.positions || []).concat(runB.positions || []);
2205
- const attributes = Object.assign({}, runA.attributes, runB.attributes);
2206
- const runAIndices = runA.glyphIndices || [];
2207
- const runALastIndex = last(runAIndices) || 0;
2208
- const runBIndices = (runB.glyphIndices || []).map((i) => i + runALastIndex + 1);
2209
- const glyphIndices = normalize(runAIndices.concat(runBIndices));
2210
- return Object.assign({}, runA, {
2211
- end,
2212
- glyphs,
2213
- positions,
2214
- attributes,
2215
- glyphIndices,
2216
- });
2217
- };
2218
-
2219
- /**
2220
- * Insert glyph to run in the given index
2221
- *
2222
- * @param index - Index
2223
- * @param glyph - Glyph
2224
- * @param run - Run
2225
- * @returns Run with glyph
2226
- */
2227
- const insertGlyph$1 = (index, glyph, run) => {
2228
- if (!glyph)
2229
- return run;
2230
- // Split resolves ligature splitting in case new glyph breaks some
2231
- const leadingRun = slice$1(0, index, run);
2232
- const trailingRun = slice$1(index, Infinity, run);
2233
- return concat(append$1(glyph, leadingRun), trailingRun);
2234
- };
2235
- /**
2236
- * Insert either glyph or code point to run in the given index
2237
- *
2238
- * @param index - Index
2239
- * @param value - Glyph or codePoint
2240
- * @param run - Run
2241
- * @returns Run with glyph
2242
- */
2243
- const insert = (index, value, run) => {
2244
- const font = getFont(run);
2245
- const glyph = isNumber(value) ? fromCodePoint(value, font) : value;
2246
- return insertGlyph$1(index, glyph, run);
2247
- };
2248
-
2249
- /**
2250
- * Get run index at char index
2251
- *
2252
- * @param index - Char index
2253
- * @param attributedString - Attributed string
2254
- * @returns Run index
2255
- */
2256
- const runIndexAt = (index, attributedString) => {
2257
- return runIndexAt$1(index, attributedString.runs);
2258
- };
2259
-
2260
- /**
2261
- * Insert glyph into attributed string
2262
- *
2263
- * @param index - Index
2264
- * @param glyph - Glyph or code point
2265
- * @param attributedString - Attributed string
2266
- * @returns Attributed string with new glyph
2267
- */
2268
- const insertGlyph = (index, glyph, attributedString) => {
2269
- const runIndex = runIndexAt(index, attributedString);
2270
- // Add glyph to the end if run index invalid
2271
- if (runIndex === -1)
2272
- return append(glyph, attributedString);
2273
- const codePoints = [glyph] ;
2274
- const string = attributedString.string.slice(0, index) +
2275
- stringFromCodePoints(codePoints) +
2276
- attributedString.string.slice(index);
2277
- const runs = attributedString.runs.map((run, i) => {
2278
- if (i === runIndex)
2279
- return insert(index - run.start, glyph, run);
2280
- if (i > runIndex)
2281
- return add(codePoints.length, run);
2282
- return run;
2283
- });
2284
- return Object.assign({}, attributedString, { string, runs });
2285
- };
2286
-
2287
- /**
2288
- * Advance width between two string indices
2289
- *
2290
- * @param start - Glyph index
2291
- * @param end - Glyph index
2292
- * @param run - Run
2293
- * @returns Advanced width run
2294
- */
2295
- const advanceWidthBetween$1 = (start, end, run) => {
2296
- const runStart = run.start || 0;
2297
- const glyphStartIndex = Math.max(0, glyphIndexAt(start - runStart, run));
2298
- const glyphEndIndex = Math.max(0, glyphIndexAt(end - runStart, run));
2299
- const positions = (run.positions || []).slice(glyphStartIndex, glyphEndIndex);
2300
- return advanceWidth$2(positions);
2301
- };
2302
-
2303
- /**
2304
- * Advance width between start and end
2305
- * Does not consider ligature splitting for the moment.
2306
- * Check performance impact on supporting this
2307
- *
2308
- * @param start - Start offset
2309
- * @param end - End offset
2310
- * @param attributedString
2311
- * @returns Advance width
2312
- */
2313
- const advanceWidthBetween = (start, end, attributedString) => {
2314
- const runs = filter(start, end, attributedString.runs);
2315
- return runs.reduce((acc, run) => acc + advanceWidthBetween$1(start, end, run), 0);
2316
- };
2317
-
2318
- const HYPHEN = 0x002d;
2319
- const TOLERANCE_STEPS = 5;
2320
- const TOLERANCE_LIMIT = 50;
2321
- const opts = {
2322
- width: 3,
2323
- stretch: 6,
2324
- shrink: 9,
2325
- };
2326
- /**
2327
- * Slice attributed string to many lines
2328
- *
2329
- * @param attributedString - Attributed string
2330
- * @param nodes
2331
- * @param breaks
2332
- * @returns Attributed strings
2333
- */
2334
- const breakLines = (attributedString, nodes, breaks) => {
2335
- let start = 0;
2336
- let end = null;
2337
- const lines = breaks.reduce((acc, breakPoint) => {
2338
- const node = nodes[breakPoint];
2339
- const prevNode = nodes[breakPoint - 1];
2340
- // Last breakpoint corresponds to K&P mandatory final glue
2341
- if (breakPoint === nodes.length - 1)
2342
- return acc;
2343
- let line;
2344
- if (node.type === 'penalty') {
2345
- // @ts-expect-error penalty node will always preceed box or glue node
2346
- end = prevNode.end;
2347
- line = slice(start, end, attributedString);
2348
- line = insertGlyph(line.string.length, HYPHEN, line);
2349
- }
2350
- else {
2351
- end = node.end;
2352
- line = slice(start, end, attributedString);
2353
- }
2354
- start = end;
2355
- return [...acc, line];
2356
- }, []);
2357
- // Last line
2358
- lines.push(slice(start, attributedString.string.length, attributedString));
2359
- return lines;
2360
- };
2361
- /**
2362
- * Return Knuth & Plass nodes based on line and previously calculated syllables
2363
- *
2364
- * @param attributedString - Attributed string
2365
- * @param attributes - Attributes
2366
- * @param options - Layout options
2367
- * @returns ?
2368
- */
2369
- const getNodes = (attributedString, { align }, options) => {
2370
- let start = 0;
2371
- const hyphenWidth = 5;
2372
- const { syllables } = attributedString;
2373
- const hyphenPenalty = options.hyphenationPenalty || (align === 'justify' ? 100 : 600);
2374
- const result = syllables.reduce((acc, s, index) => {
2375
- const width = advanceWidthBetween(start, start + s.length, attributedString);
2376
- if (s.trim() === '') {
2377
- const stretch = (width * opts.width) / opts.stretch;
2378
- const shrink = (width * opts.width) / opts.shrink;
2379
- const end = start + s.length;
2380
- // Add glue node. Glue nodes are used to fill the space between words.
2381
- acc.push(linebreak.glue(width, start, end, stretch, shrink));
2382
- }
2383
- else {
2384
- const hyphenated = syllables[index + 1] !== ' ';
2385
- const end = start + s.length;
2386
- // Add box node. Box nodes are used to represent words.
2387
- acc.push(linebreak.box(width, start, end, hyphenated));
2388
- if (syllables[index + 1] && hyphenated) {
2389
- // Add penalty node. Penalty nodes are used to represent hyphenation points.
2390
- acc.push(linebreak.penalty(hyphenWidth, hyphenPenalty, 1));
2391
- }
2392
- }
2393
- start += s.length;
2394
- return acc;
2395
- }, []);
2396
- // Add mandatory final glue
2397
- result.push(linebreak.glue(0, start, start, linebreak.infinity, 0));
2398
- result.push(linebreak.penalty(0, -linebreak.infinity, 1));
2399
- return result;
2400
- };
2401
- /**
2402
- * @param attributedString - Attributed string
2403
- * @returns Attributes
2404
- */
2405
- const getAttributes = (attributedString) => {
2406
- return attributedString.runs?.[0]?.attributes || {};
2407
- };
2408
- /**
2409
- * Performs Knuth & Plass line breaking algorithm
2410
- * Fallbacks to best fit algorithm if latter not successful
2411
- *
2412
- * @param options - Layout options
2413
- */
2414
- const linebreaker = (options) => {
2415
- /**
2416
- * @param attributedString - Attributed string
2417
- * @param availableWidths - Available widths
2418
- * @returns Attributed string
2419
- */
2420
- return (attributedString, availableWidths) => {
2421
- let tolerance = options.tolerance || 4;
2422
- const attributes = getAttributes(attributedString);
2423
- const nodes = getNodes(attributedString, attributes, options);
2424
- let breaks = linebreak(nodes, availableWidths, tolerance);
2425
- // Try again with a higher tolerance if the line breaking failed.
2426
- while (breaks.length === 0 && tolerance < TOLERANCE_LIMIT) {
2427
- tolerance += TOLERANCE_STEPS;
2428
- breaks = linebreak(nodes, availableWidths, tolerance);
2429
- }
2430
- if (breaks.length === 0 || (breaks.length === 1 && breaks[0] === 0)) {
2431
- breaks = applyBestFit(nodes, availableWidths);
2432
- }
2433
- return breakLines(attributedString, nodes, breaks.slice(1));
2434
- };
2435
- };
2436
-
2437
- var Direction;
2438
- (function (Direction) {
2439
- Direction[Direction["GROW"] = 0] = "GROW";
2440
- Direction[Direction["SHRINK"] = 1] = "SHRINK";
2441
- })(Direction || (Direction = {}));
2442
- const WHITESPACE_PRIORITY = 1;
2443
- const LETTER_PRIORITY = 2;
2444
- const EXPAND_WHITESPACE_FACTOR = {
2445
- before: 0.5,
2446
- after: 0.5,
2447
- priority: WHITESPACE_PRIORITY,
2448
- unconstrained: false,
2449
- };
2450
- const EXPAND_CHAR_FACTOR = {
2451
- before: 0.14453125, // 37/256
2452
- after: 0.14453125,
2453
- priority: LETTER_PRIORITY,
2454
- unconstrained: false,
2455
- };
2456
- const SHRINK_WHITESPACE_FACTOR = {
2457
- before: -0.04296875, // -11/256
2458
- after: -0.04296875,
2459
- priority: WHITESPACE_PRIORITY,
2460
- unconstrained: false,
2461
- };
2462
- const SHRINK_CHAR_FACTOR = {
2463
- before: -0.04296875,
2464
- after: -0.04296875,
2465
- priority: LETTER_PRIORITY,
2466
- unconstrained: false,
2467
- };
2468
- const getCharFactor = (direction, options) => {
2469
- const expandCharFactor = options.expandCharFactor || {};
2470
- const shrinkCharFactor = options.shrinkCharFactor || {};
2471
- return direction === Direction.GROW
2472
- ? Object.assign({}, EXPAND_CHAR_FACTOR, expandCharFactor)
2473
- : Object.assign({}, SHRINK_CHAR_FACTOR, shrinkCharFactor);
2474
- };
2475
- const getWhitespaceFactor = (direction, options) => {
2476
- const expandWhitespaceFactor = options.expandWhitespaceFactor || {};
2477
- const shrinkWhitespaceFactor = options.shrinkWhitespaceFactor || {};
2478
- return direction === Direction.GROW
2479
- ? Object.assign({}, EXPAND_WHITESPACE_FACTOR, expandWhitespaceFactor)
2480
- : Object.assign({}, SHRINK_WHITESPACE_FACTOR, shrinkWhitespaceFactor);
2481
- };
2482
- const factor = (direction, options) => (glyphs) => {
2483
- const charFactor = getCharFactor(direction, options);
2484
- const whitespaceFactor = getWhitespaceFactor(direction, options);
2485
- const factors = [];
2486
- for (let index = 0; index < glyphs.length; index += 1) {
2487
- let f;
2488
- const glyph = glyphs[index];
2489
- if (isWhiteSpace(glyph)) {
2490
- f = Object.assign({}, whitespaceFactor);
2491
- if (index === glyphs.length - 1) {
2492
- f.before = 0;
2493
- if (index > 0) {
2494
- factors[index - 1].after = 0;
2495
- }
2496
- }
2497
- }
2498
- else if (glyph.isMark && index > 0) {
2499
- f = Object.assign({}, factors[index - 1]);
2500
- f.before = 0;
2501
- factors[index - 1].after = 0;
2502
- }
2503
- else {
2504
- f = Object.assign({}, charFactor);
2505
- }
2506
- factors.push(f);
2507
- }
2508
- return factors;
2509
- };
2510
- const getFactors = (gap, line, options) => {
2511
- const direction = gap > 0 ? Direction.GROW : Direction.SHRINK;
2512
- const getFactor = factor(direction, options);
2513
- const factors = line.runs.reduce((acc, run) => {
2514
- return acc.concat(getFactor(run.glyphs));
2515
- }, []);
2516
- factors[0].before = 0;
2517
- factors[factors.length - 1].after = 0;
2518
- return factors;
2519
- };
2520
-
2521
- const KASHIDA_PRIORITY = 0;
2522
- const NULL_PRIORITY = 3;
2523
- const getDistances = (gap, factors) => {
2524
- let total = 0;
2525
- const priorities = [];
2526
- const unconstrained = [];
2527
- for (let priority = KASHIDA_PRIORITY; priority <= NULL_PRIORITY; priority += 1) {
2528
- priorities[priority] = unconstrained[priority] = 0;
2529
- }
2530
- // sum the factors at each priority
2531
- for (let j = 0; j < factors.length; j += 1) {
2532
- const f = factors[j];
2533
- const sum = f.before + f.after;
2534
- total += sum;
2535
- priorities[f.priority] += sum;
2536
- if (f.unconstrained) {
2537
- unconstrained[f.priority] += sum;
2538
- }
2539
- }
2540
- // choose the priorities that need to be applied
2541
- let highestPriority = -1;
2542
- let highestPrioritySum = 0;
2543
- let remainingGap = gap;
2544
- let priority;
2545
- for (priority = KASHIDA_PRIORITY; priority <= NULL_PRIORITY; priority += 1) {
2546
- const prioritySum = priorities[priority];
2547
- if (prioritySum !== 0) {
2548
- if (highestPriority === -1) {
2549
- highestPriority = priority;
2550
- highestPrioritySum = prioritySum;
2551
- }
2552
- // if this priority covers the remaining gap, we're done
2553
- if (Math.abs(remainingGap) <= Math.abs(prioritySum)) {
2554
- priorities[priority] = remainingGap / prioritySum;
2555
- unconstrained[priority] = 0;
2556
- remainingGap = 0;
2557
- break;
2558
- }
2559
- // mark that we need to use 100% of the adjustment from
2560
- // this priority, and subtract the space that it consumes
2561
- priorities[priority] = 1;
2562
- remainingGap -= prioritySum;
2563
- // if this priority has unconstrained glyphs, let them consume the remaining space
2564
- if (unconstrained[priority] !== 0) {
2565
- unconstrained[priority] = remainingGap / unconstrained[priority];
2566
- remainingGap = 0;
2567
- break;
2568
- }
2569
- }
2570
- }
2571
- // zero out remaining priorities (if any)
2572
- for (let p = priority + 1; p <= NULL_PRIORITY; p += 1) {
2573
- priorities[p] = 0;
2574
- unconstrained[p] = 0;
2575
- }
2576
- // if there is still space left over, assign it to the highest priority that we saw.
2577
- // this violates their factors, but it only happens in extreme cases
2578
- if (remainingGap > 0 && highestPriority > -1) {
2579
- priorities[highestPriority] =
2580
- (highestPrioritySum + (gap - total)) / highestPrioritySum;
2581
- }
2582
- // create and return an array of distances to add to each glyph's advance
2583
- const distances = [];
2584
- for (let index = 0; index < factors.length; index += 1) {
2585
- // the distance to add to this glyph is the sum of the space to add
2586
- // after this glyph, and the space to add before the next glyph
2587
- const f = factors[index];
2588
- const next = factors[index + 1];
2589
- let dist = f.after * priorities[f.priority];
2590
- if (next) {
2591
- dist += next.before * priorities[next.priority];
2592
- }
2593
- // if this glyph is unconstrained, add the unconstrained distance as well
2594
- if (f.unconstrained) {
2595
- dist += f.after * unconstrained[f.priority];
2596
- if (next) {
2597
- dist += next.before * unconstrained[next.priority];
2598
- }
2599
- }
2600
- distances.push(dist);
2601
- }
2602
- return distances;
2603
- };
2604
-
2605
- /**
2606
- * Adjust run positions by given distances
2607
- *
2608
- * @param distances
2609
- * @param line
2610
- * @returns Line
2611
- */
2612
- const justifyLine = (distances, line) => {
2613
- let index = 0;
2614
- for (const run of line.runs) {
2615
- for (const position of run.positions) {
2616
- position.xAdvance += distances[index++];
2617
- }
2618
- }
2619
- return line;
2620
- };
2621
- /**
2622
- * A JustificationEngine is used by a Typesetter to perform line fragment
2623
- * justification. This implementation is based on a description of Apple's
2624
- * justification algorithm from a PDF in the Apple Font Tools package.
2625
- *
2626
- * @param options - Layout options
2627
- */
2628
- const justification = (options) => {
2629
- /**
2630
- * @param line
2631
- * @returns Line
2632
- */
2633
- return (line) => {
2634
- const gap = line.box.width - advanceWidth(line);
2635
- if (gap === 0)
2636
- return line; // Exact fit
2637
- const factors = getFactors(gap, line, options);
2638
- const distances = getDistances(gap, factors);
2639
- return justifyLine(distances, line);
2640
- };
2641
- };
2642
-
2643
- /**
2644
- * Returns attributed string ascent
2645
- *
2646
- * @param attributedString - Attributed string
2647
- * @returns Ascent
2648
- */
2649
- const ascent = (attributedString) => {
2650
- const reducer = (acc, run) => Math.max(acc, ascent$1(run));
2651
- return attributedString.runs.reduce(reducer, 0);
2652
- };
2653
-
2654
- // The base font size used for calculating underline thickness.
2655
- const BASE_FONT_SIZE = 12;
2656
- /**
2657
- * A TextDecorationEngine is used by a Typesetter to generate
2658
- * DecorationLines for a line fragment, including underlines
2659
- * and strikes.
2660
- */
2661
- const textDecoration = () => (line) => {
2662
- let x = line.overflowLeft || 0;
2663
- const overflowRight = line.overflowRight || 0;
2664
- const maxX = advanceWidth(line) - overflowRight;
2665
- line.decorationLines = [];
2666
- for (let i = 0; i < line.runs.length; i += 1) {
2667
- const run = line.runs[i];
2668
- const width = Math.min(maxX - x, advanceWidth$1(run));
2669
- const thickness = Math.max(0.5, Math.floor(run.attributes.fontSize / BASE_FONT_SIZE));
2670
- if (run.attributes.underline) {
2671
- const rect = {
2672
- x,
2673
- y: ascent(line) + thickness * 2,
2674
- width,
2675
- height: thickness,
2676
- };
2677
- const decorationLine = {
2678
- rect,
2679
- opacity: run.attributes.opacity,
2680
- color: run.attributes.underlineColor || 'black',
2681
- style: run.attributes.underlineStyle || 'solid',
2682
- };
2683
- line.decorationLines.push(decorationLine);
2684
- }
2685
- if (run.attributes.strike) {
2686
- const y = ascent(line) - ascent$1(run) / 3;
2687
- const rect = { x, y, width, height: thickness };
2688
- const decorationLine = {
2689
- rect,
2690
- opacity: run.attributes.opacity,
2691
- color: run.attributes.strikeColor || 'black',
2692
- style: run.attributes.strikeStyle || 'solid',
2693
- };
2694
- line.decorationLines.push(decorationLine);
2695
- }
2696
- x += width;
2697
- }
2698
- return line;
2699
- };
2700
-
2701
- const ignoredScripts = ['Common', 'Inherited', 'Unknown'];
2702
- /**
2703
- * Resolves unicode script in runs, grouping equal runs together
2704
- */
2705
- const scriptItemizer = () => {
2706
- /**
2707
- * @param attributedString - Attributed string
2708
- * @returns Attributed string
2709
- */
2710
- return (attributedString) => {
2711
- const { string } = attributedString;
2712
- let lastScript = 'Unknown';
2713
- let lastIndex = 0;
2714
- let index = 0;
2715
- const runs = [];
2716
- if (!string)
2717
- return empty();
2718
- for (let i = 0; i < string.length; i += 1) {
2719
- const char = string[i];
2720
- const codePoint = char.codePointAt(0);
2721
- const script = $747425b437e121da$export$2e2bcd8739ae039.getScript(codePoint);
2722
- if (script !== lastScript && !ignoredScripts.includes(script)) {
2723
- if (lastScript !== 'Unknown') {
2724
- runs.push({
2725
- start: lastIndex,
2726
- end: index,
2727
- attributes: { script: lastScript },
2728
- });
2729
- }
2730
- lastIndex = index;
2731
- lastScript = script;
2732
- }
2733
- index += char.length;
2734
- }
2735
- if (lastIndex < string.length) {
2736
- runs.push({
2737
- start: lastIndex,
2738
- end: string.length,
2739
- attributes: { script: lastScript },
2740
- });
2741
- }
2742
- const result = { string, runs: runs };
2743
- return result;
2744
- };
2745
- };
2746
-
2747
- const SOFT_HYPHEN = '\u00ad';
2748
- const hyphenator = hyphen(pattern);
2749
- /**
2750
- * @param word
2751
- * @returns Word parts
2752
- */
2753
- const splitHyphen = (word) => {
2754
- return word.split(SOFT_HYPHEN);
2755
- };
2756
- const cache = {};
2757
- /**
2758
- * @param word
2759
- * @returns Word parts
2760
- */
2761
- const getParts = (word) => {
2762
- const base = word.includes(SOFT_HYPHEN) ? word : hyphenator(word);
2763
- return splitHyphen(base);
2764
- };
2765
- const wordHyphenation = () => {
2766
- /**
2767
- * @param word - Word
2768
- * @returns Word parts
2769
- */
2770
- return (word) => {
2771
- const cacheKey = `_${word}`;
2772
- if (isNil(word))
2773
- return [];
2774
- if (cache[cacheKey])
2775
- return cache[cacheKey];
2776
- cache[cacheKey] = getParts(word);
2777
- return cache[cacheKey];
2778
- };
2779
- };
2780
-
2781
- const IGNORED_CODE_POINTS = [173];
2782
- const getFontSize = (run) => run.attributes.fontSize || 12;
2783
- const pickFontFromFontStack = (codePoint, fontStack, lastFont) => {
2784
- const fontStackWithFallback = [...fontStack, lastFont];
2785
- for (let i = 0; i < fontStackWithFallback.length; i += 1) {
2786
- const font = fontStackWithFallback[i];
2787
- if (!IGNORED_CODE_POINTS.includes(codePoint) &&
2788
- font &&
2789
- font.hasGlyphForCodePoint &&
2790
- font.hasGlyphForCodePoint(codePoint)) {
2791
- return font;
2792
- }
2793
- }
2794
- return fontStack.at(-1);
2795
- };
2796
- const fontSubstitution = () => ({ string, runs }) => {
2797
- let lastFont = null;
2798
- let lastFontSize = null;
2799
- let lastIndex = 0;
2800
- let index = 0;
2801
- const res = [];
2802
- for (let i = 0; i < runs.length; i += 1) {
2803
- const run = runs[i];
2804
- if (string.length === 0) {
2805
- res.push({
2806
- start: 0,
2807
- end: 0,
2808
- attributes: { font: run.attributes.font },
2809
- });
2810
- break;
2811
- }
2812
- const chars = string.slice(run.start, run.end);
2813
- for (let j = 0; j < chars.length; j += 1) {
2814
- const char = chars[j];
2815
- const codePoint = char.codePointAt(0);
2816
- // If the default font does not have a glyph and the fallback font does, we use it
2817
- const font = pickFontFromFontStack(codePoint, run.attributes.font, lastFont);
2818
- const fontSize = getFontSize(run);
2819
- // If anything that would impact res has changed, update it
2820
- if (font !== lastFont ||
2821
- fontSize !== lastFontSize ||
2822
- font.unitsPerEm !== lastFont.unitsPerEm) {
2823
- if (lastFont) {
2824
- res.push({
2825
- start: lastIndex,
2826
- end: index,
2827
- attributes: {
2828
- font: [lastFont],
2829
- scale: lastFontSize / lastFont.unitsPerEm,
2830
- },
2831
- });
2832
- }
2833
- lastFont = font;
2834
- lastFontSize = fontSize;
2835
- lastIndex = index;
2836
- }
2837
- index += char.length;
2838
- }
2839
- }
2840
- if (lastIndex < string.length) {
2841
- const fontSize = getFontSize(last(runs));
2842
- res.push({
2843
- start: lastIndex,
2844
- end: string.length,
2845
- attributes: {
2846
- font: [lastFont],
2847
- scale: fontSize / lastFont.unitsPerEm,
2848
- },
2849
- });
2850
- }
2851
- return { string, runs: res };
2852
- };
2853
-
2854
- export { bidiEngine as bidi, layoutEngine as default, fontSubstitution, fromFragments, justification, linebreaker, scriptItemizer, textDecoration, wordHyphenation };