umwd-components 0.1.826 → 0.1.828
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.
- package/dist/cjs/node_modules/object-assign/index.js +2 -2
- package/dist/cjs/node_modules/prop-types/factoryWithTypeCheckers.js +1 -1
- package/dist/cjs/node_modules/prop-types/index.js +1 -1
- package/dist/cjs/node_modules/prop-types/node_modules/react-is/index.js +1 -1
- package/dist/cjs/node_modules/safe-buffer/index.js +1 -1
- package/dist/cjs/src/components/e-commerce/products/EditReturnStockForm.js +1 -1
- package/dist/cjs/src/components/logistics/report/ReportMakingComponent.js +1 -1
- package/dist/cjs/src/components/logistics/vendor/EditVendorForm.js +1 -1
- package/dist/cjs/src/data/actions/logistics/note/createNoteAction.js +1 -1
- package/dist/cjs/src/data/actions/logistics/report/createReportAction.js +1 -1
- package/dist/cjs/src/index.js +1 -1
- package/dist/cjs/tsconfig.build.tsbuildinfo +1 -1
- package/dist/esm/_virtual/index2.js +2 -2
- package/dist/esm/_virtual/index3.js +2 -2
- package/dist/esm/_virtual/index4.js +2 -2
- package/dist/esm/node_modules/object-assign/index.js +74 -69
- package/dist/esm/node_modules/prop-types/factoryWithTypeCheckers.js +2 -2
- package/dist/esm/node_modules/prop-types/index.js +1 -1
- package/dist/esm/node_modules/prop-types/node_modules/react-is/index.js +1 -1
- package/dist/esm/node_modules/safe-buffer/index.js +1 -1
- package/dist/esm/src/components/e-commerce/products/EditReturnStockForm.js +11 -22
- package/dist/esm/src/components/logistics/report/ReportMakingComponent.js +0 -1
- package/dist/esm/src/components/logistics/vendor/EditVendorForm.js +0 -1
- package/dist/esm/src/data/actions/logistics/note/createNoteAction.js +0 -2
- package/dist/esm/src/data/actions/logistics/report/createReportAction.js +0 -2
- package/dist/esm/src/index.js +0 -1
- package/dist/esm/tsconfig.build.tsbuildinfo +1 -1
- package/dist/esm/types/data/actions/e-commerce/lead/contactFormAction.d.ts +1 -0
- package/dist/esm/types/index.d.ts +0 -3
- package/package.json +1 -1
- package/dist/cjs/_virtual/_commonjs-dynamic-modules.js +0 -6
- package/dist/cjs/_virtual/aes.js +0 -6
- package/dist/cjs/_virtual/b64.js +0 -6
- package/dist/cjs/_virtual/blowfish.js +0 -6
- package/dist/cjs/_virtual/cipher-core.js +0 -6
- package/dist/cjs/_virtual/clone.js +0 -6
- package/dist/cjs/_virtual/common.js +0 -6
- package/dist/cjs/_virtual/context.js +0 -6
- package/dist/cjs/_virtual/core2.js +0 -6
- package/dist/cjs/_virtual/decode.js +0 -6
- package/dist/cjs/_virtual/deflate.js +0 -6
- package/dist/cjs/_virtual/dictionary-browser.js +0 -6
- package/dist/cjs/_virtual/dictionary.js +0 -6
- package/dist/cjs/_virtual/en-us.js +0 -6
- package/dist/cjs/_virtual/enc-base64.js +0 -6
- package/dist/cjs/_virtual/enc-base64url.js +0 -6
- package/dist/cjs/_virtual/enc-utf16.js +0 -6
- package/dist/cjs/_virtual/events.js +0 -6
- package/dist/cjs/_virtual/evpkdf.js +0 -6
- package/dist/cjs/_virtual/format-hex.js +0 -6
- package/dist/cjs/_virtual/hmac.js +0 -6
- package/dist/cjs/_virtual/huffman.js +0 -6
- package/dist/cjs/_virtual/hyphen.js +0 -6
- package/dist/cjs/_virtual/index10.js +0 -6
- package/dist/cjs/_virtual/index5.js +0 -6
- package/dist/cjs/_virtual/index6.js +0 -6
- package/dist/cjs/_virtual/index7.js +0 -6
- package/dist/cjs/_virtual/index8.js +0 -6
- package/dist/cjs/_virtual/index9.js +0 -6
- package/dist/cjs/_virtual/inflate.js +0 -6
- package/dist/cjs/_virtual/inherits_browser.js +0 -6
- package/dist/cjs/_virtual/lib-typedarrays.js +0 -6
- package/dist/cjs/_virtual/md5.js +0 -6
- package/dist/cjs/_virtual/mode-cfb.js +0 -6
- package/dist/cjs/_virtual/mode-ctr-gladman.js +0 -6
- package/dist/cjs/_virtual/mode-ctr.js +0 -6
- package/dist/cjs/_virtual/mode-ecb.js +0 -6
- package/dist/cjs/_virtual/mode-ofb.js +0 -6
- package/dist/cjs/_virtual/pad-ansix923.js +0 -6
- package/dist/cjs/_virtual/pad-iso10126.js +0 -6
- package/dist/cjs/_virtual/pad-iso97971.js +0 -6
- package/dist/cjs/_virtual/pad-nopadding.js +0 -6
- package/dist/cjs/_virtual/pad-zeropadding.js +0 -6
- package/dist/cjs/_virtual/pbkdf2.js +0 -6
- package/dist/cjs/_virtual/prefix.js +0 -6
- package/dist/cjs/_virtual/rabbit-legacy.js +0 -6
- package/dist/cjs/_virtual/rabbit.js +0 -6
- package/dist/cjs/_virtual/rc4.js +0 -6
- package/dist/cjs/_virtual/ripemd160.js +0 -6
- package/dist/cjs/_virtual/scheduler.development.js +0 -6
- package/dist/cjs/_virtual/scheduler.production.js +0 -6
- package/dist/cjs/_virtual/sha1.js +0 -6
- package/dist/cjs/_virtual/sha224.js +0 -6
- package/dist/cjs/_virtual/sha256.js +0 -6
- package/dist/cjs/_virtual/sha3.js +0 -6
- package/dist/cjs/_virtual/sha384.js +0 -6
- package/dist/cjs/_virtual/sha512.js +0 -6
- package/dist/cjs/_virtual/streams.js +0 -6
- package/dist/cjs/_virtual/transform.js +0 -6
- package/dist/cjs/_virtual/trees.js +0 -6
- package/dist/cjs/_virtual/tripledes.js +0 -6
- package/dist/cjs/_virtual/x64-core.js +0 -6
- package/dist/cjs/node_modules/@react-pdf/fns/lib/index.js +0 -6
- package/dist/cjs/node_modules/@react-pdf/font/lib/index.browser.js +0 -6
- package/dist/cjs/node_modules/@react-pdf/image/lib/index.browser.js +0 -6
- package/dist/cjs/node_modules/@react-pdf/layout/lib/index.js +0 -6
- package/dist/cjs/node_modules/@react-pdf/pdfkit/lib/pdfkit.browser.js +0 -6
- package/dist/cjs/node_modules/@react-pdf/png-js/lib/png-js.browser.js +0 -6
- package/dist/cjs/node_modules/@react-pdf/primitives/lib/index.js +0 -6
- package/dist/cjs/node_modules/@react-pdf/reconciler/lib/index.js +0 -6
- package/dist/cjs/node_modules/@react-pdf/reconciler/lib/reconciler-23.js +0 -14
- package/dist/cjs/node_modules/@react-pdf/reconciler/lib/reconciler-31.js +0 -26
- package/dist/cjs/node_modules/@react-pdf/render/lib/index.js +0 -6
- package/dist/cjs/node_modules/@react-pdf/renderer/lib/react-pdf.browser.js +0 -6
- package/dist/cjs/node_modules/@react-pdf/stylesheet/lib/index.js +0 -6
- package/dist/cjs/node_modules/@react-pdf/textkit/lib/textkit.js +0 -13
- package/dist/cjs/node_modules/@swc/helpers/esm/_define_property.js +0 -6
- package/dist/cjs/node_modules/abs-svg-path/index.js +0 -6
- package/dist/cjs/node_modules/base64-js/index.js +0 -6
- package/dist/cjs/node_modules/bidi-js/dist/bidi.js +0 -6
- package/dist/cjs/node_modules/brotli/dec/bit_reader.js +0 -6
- package/dist/cjs/node_modules/brotli/dec/context.js +0 -6
- package/dist/cjs/node_modules/brotli/dec/decode.js +0 -6
- package/dist/cjs/node_modules/brotli/dec/dictionary-browser.js +0 -6
- package/dist/cjs/node_modules/brotli/dec/dictionary.bin.js +0 -6
- package/dist/cjs/node_modules/brotli/dec/dictionary.js +0 -6
- package/dist/cjs/node_modules/brotli/dec/huffman.js +0 -6
- package/dist/cjs/node_modules/brotli/dec/prefix.js +0 -6
- package/dist/cjs/node_modules/brotli/dec/streams.js +0 -6
- package/dist/cjs/node_modules/brotli/dec/transform.js +0 -6
- package/dist/cjs/node_modules/brotli/decompress.js +0 -6
- package/dist/cjs/node_modules/clone/clone.js +0 -6
- package/dist/cjs/node_modules/color-name/index.js +0 -6
- package/dist/cjs/node_modules/color-string/index.js +0 -6
- package/dist/cjs/node_modules/crypto-js/aes.js +0 -6
- package/dist/cjs/node_modules/crypto-js/blowfish.js +0 -6
- package/dist/cjs/node_modules/crypto-js/cipher-core.js +0 -6
- package/dist/cjs/node_modules/crypto-js/core.js +0 -6
- package/dist/cjs/node_modules/crypto-js/enc-base64.js +0 -6
- package/dist/cjs/node_modules/crypto-js/enc-base64url.js +0 -6
- package/dist/cjs/node_modules/crypto-js/enc-utf16.js +0 -6
- package/dist/cjs/node_modules/crypto-js/evpkdf.js +0 -6
- package/dist/cjs/node_modules/crypto-js/format-hex.js +0 -6
- package/dist/cjs/node_modules/crypto-js/hmac.js +0 -6
- package/dist/cjs/node_modules/crypto-js/index.js +0 -6
- package/dist/cjs/node_modules/crypto-js/lib-typedarrays.js +0 -6
- package/dist/cjs/node_modules/crypto-js/md5.js +0 -6
- package/dist/cjs/node_modules/crypto-js/mode-cfb.js +0 -6
- package/dist/cjs/node_modules/crypto-js/mode-ctr-gladman.js +0 -12
- package/dist/cjs/node_modules/crypto-js/mode-ctr.js +0 -6
- package/dist/cjs/node_modules/crypto-js/mode-ecb.js +0 -6
- package/dist/cjs/node_modules/crypto-js/mode-ofb.js +0 -6
- package/dist/cjs/node_modules/crypto-js/pad-ansix923.js +0 -6
- package/dist/cjs/node_modules/crypto-js/pad-iso10126.js +0 -6
- package/dist/cjs/node_modules/crypto-js/pad-iso97971.js +0 -6
- package/dist/cjs/node_modules/crypto-js/pad-nopadding.js +0 -6
- package/dist/cjs/node_modules/crypto-js/pad-zeropadding.js +0 -6
- package/dist/cjs/node_modules/crypto-js/pbkdf2.js +0 -6
- package/dist/cjs/node_modules/crypto-js/rabbit-legacy.js +0 -6
- package/dist/cjs/node_modules/crypto-js/rabbit.js +0 -6
- package/dist/cjs/node_modules/crypto-js/rc4.js +0 -6
- package/dist/cjs/node_modules/crypto-js/ripemd160.js +0 -17
- package/dist/cjs/node_modules/crypto-js/sha1.js +0 -6
- package/dist/cjs/node_modules/crypto-js/sha224.js +0 -6
- package/dist/cjs/node_modules/crypto-js/sha256.js +0 -6
- package/dist/cjs/node_modules/crypto-js/sha3.js +0 -6
- package/dist/cjs/node_modules/crypto-js/sha384.js +0 -6
- package/dist/cjs/node_modules/crypto-js/sha512.js +0 -6
- package/dist/cjs/node_modules/crypto-js/tripledes.js +0 -6
- package/dist/cjs/node_modules/crypto-js/x64-core.js +0 -6
- package/dist/cjs/node_modules/dfa/index.js +0 -6
- package/dist/cjs/node_modules/emoji-regex/index.js +0 -6
- package/dist/cjs/node_modules/events/events.js +0 -6
- package/dist/cjs/node_modules/fast-deep-equal/index.js +0 -6
- package/dist/cjs/node_modules/fontkit/dist/browser-module.js +0 -6
- package/dist/cjs/node_modules/hsl-to-hex/index.js +0 -6
- package/dist/cjs/node_modules/hsl-to-rgb-for-reals/converter.js +0 -6
- package/dist/cjs/node_modules/hyphen/hyphen.js +0 -6
- package/dist/cjs/node_modules/hyphen/patterns/en-us.js +0 -6
- package/dist/cjs/node_modules/inherits/inherits_browser.js +0 -6
- package/dist/cjs/node_modules/jay-peg/src/index.js +0 -6
- package/dist/cjs/node_modules/jay-peg/src/markers/dac.js +0 -6
- package/dist/cjs/node_modules/jay-peg/src/markers/dht.js +0 -6
- package/dist/cjs/node_modules/jay-peg/src/markers/dqt.js +0 -6
- package/dist/cjs/node_modules/jay-peg/src/markers/dri.js +0 -6
- package/dist/cjs/node_modules/jay-peg/src/markers/eoi.js +0 -6
- package/dist/cjs/node_modules/jay-peg/src/markers/exif.js +0 -6
- package/dist/cjs/node_modules/jay-peg/src/markers/jfif.js +0 -6
- package/dist/cjs/node_modules/jay-peg/src/markers/sof.js +0 -6
- package/dist/cjs/node_modules/jay-peg/src/markers/soi.js +0 -6
- package/dist/cjs/node_modules/jay-peg/src/markers/sos.js +0 -6
- package/dist/cjs/node_modules/jay-peg/src/markers/utils.js +0 -6
- package/dist/cjs/node_modules/linebreak/dist/module.js +0 -6
- package/dist/cjs/node_modules/linebreak/node_modules/base64-js/lib/b64.js +0 -6
- package/dist/cjs/node_modules/media-engine/src/index.js +0 -6
- package/dist/cjs/node_modules/media-engine/src/operators.js +0 -6
- package/dist/cjs/node_modules/media-engine/src/parser.js +0 -6
- package/dist/cjs/node_modules/media-engine/src/queries.js +0 -6
- package/dist/cjs/node_modules/normalize-svg-path/index.js +0 -6
- package/dist/cjs/node_modules/pako/lib/utils/common.js +0 -6
- package/dist/cjs/node_modules/pako/lib/zlib/adler32.js +0 -6
- package/dist/cjs/node_modules/pako/lib/zlib/constants.js +0 -6
- package/dist/cjs/node_modules/pako/lib/zlib/crc32.js +0 -6
- package/dist/cjs/node_modules/pako/lib/zlib/deflate.js +0 -6
- package/dist/cjs/node_modules/pako/lib/zlib/inffast.js +0 -6
- package/dist/cjs/node_modules/pako/lib/zlib/inflate.js +0 -6
- package/dist/cjs/node_modules/pako/lib/zlib/inftrees.js +0 -6
- package/dist/cjs/node_modules/pako/lib/zlib/messages.js +0 -6
- package/dist/cjs/node_modules/pako/lib/zlib/trees.js +0 -6
- package/dist/cjs/node_modules/pako/lib/zlib/zstream.js +0 -6
- package/dist/cjs/node_modules/parse-svg-path/index.js +0 -6
- package/dist/cjs/node_modules/postcss-value-parser/lib/parse.js +0 -6
- package/dist/cjs/node_modules/postcss-value-parser/lib/unit.js +0 -6
- package/dist/cjs/node_modules/queue/index.js +0 -6
- package/dist/cjs/node_modules/restructure/src/Array.js +0 -6
- package/dist/cjs/node_modules/restructure/src/Base.js +0 -6
- package/dist/cjs/node_modules/restructure/src/Bitfield.js +0 -6
- package/dist/cjs/node_modules/restructure/src/Buffer.js +0 -6
- package/dist/cjs/node_modules/restructure/src/DecodeStream.js +0 -6
- package/dist/cjs/node_modules/restructure/src/EncodeStream.js +0 -6
- package/dist/cjs/node_modules/restructure/src/LazyArray.js +0 -6
- package/dist/cjs/node_modules/restructure/src/Number.js +0 -6
- package/dist/cjs/node_modules/restructure/src/Optional.js +0 -6
- package/dist/cjs/node_modules/restructure/src/Pointer.js +0 -6
- package/dist/cjs/node_modules/restructure/src/Reserved.js +0 -6
- package/dist/cjs/node_modules/restructure/src/String.js +0 -6
- package/dist/cjs/node_modules/restructure/src/Struct.js +0 -6
- package/dist/cjs/node_modules/restructure/src/VersionedStruct.js +0 -6
- package/dist/cjs/node_modules/restructure/src/utils.js +0 -6
- package/dist/cjs/node_modules/scheduler/cjs/scheduler.development.js +0 -15
- package/dist/cjs/node_modules/scheduler/cjs/scheduler.production.js +0 -15
- package/dist/cjs/node_modules/scheduler/index.js +0 -6
- package/dist/cjs/node_modules/simple-swizzle/index.js +0 -6
- package/dist/cjs/node_modules/simple-swizzle/node_modules/is-arrayish/index.js +0 -6
- package/dist/cjs/node_modules/svg-arc-to-cubic-bezier/modules/index.js +0 -6
- package/dist/cjs/node_modules/tiny-inflate/index.js +0 -6
- package/dist/cjs/node_modules/tslib/tslib.es6.js +0 -6
- package/dist/cjs/node_modules/unicode-properties/dist/module.js +0 -6
- package/dist/cjs/node_modules/unicode-trie/index.js +0 -6
- package/dist/cjs/node_modules/unicode-trie/swap.js +0 -6
- package/dist/cjs/node_modules/yoga-layout/dist/binaries/yoga-wasm-base64-esm.js +0 -6
- package/dist/cjs/node_modules/yoga-layout/dist/src/generated/YGEnums.js +0 -6
- package/dist/cjs/node_modules/yoga-layout/dist/src/load.js +0 -6
- package/dist/cjs/node_modules/yoga-layout/dist/src/wrapAssembly.js +0 -6
- package/dist/cjs/src/components/e-commerce/invoice/InvoicePDF.js +0 -7
- package/dist/esm/_virtual/_commonjs-dynamic-modules.js +0 -11
- package/dist/esm/_virtual/aes.js +0 -9
- package/dist/esm/_virtual/b64.js +0 -9
- package/dist/esm/_virtual/blowfish.js +0 -9
- package/dist/esm/_virtual/cipher-core.js +0 -9
- package/dist/esm/_virtual/clone.js +0 -9
- package/dist/esm/_virtual/common.js +0 -9
- package/dist/esm/_virtual/context.js +0 -9
- package/dist/esm/_virtual/core2.js +0 -9
- package/dist/esm/_virtual/decode.js +0 -9
- package/dist/esm/_virtual/deflate.js +0 -9
- package/dist/esm/_virtual/dictionary-browser.js +0 -9
- package/dist/esm/_virtual/dictionary.js +0 -9
- package/dist/esm/_virtual/en-us.js +0 -9
- package/dist/esm/_virtual/enc-base64.js +0 -9
- package/dist/esm/_virtual/enc-base64url.js +0 -9
- package/dist/esm/_virtual/enc-utf16.js +0 -9
- package/dist/esm/_virtual/events.js +0 -9
- package/dist/esm/_virtual/evpkdf.js +0 -9
- package/dist/esm/_virtual/format-hex.js +0 -9
- package/dist/esm/_virtual/hmac.js +0 -9
- package/dist/esm/_virtual/huffman.js +0 -9
- package/dist/esm/_virtual/hyphen.js +0 -9
- package/dist/esm/_virtual/index10.js +0 -9
- package/dist/esm/_virtual/index5.js +0 -9
- package/dist/esm/_virtual/index6.js +0 -9
- package/dist/esm/_virtual/index7.js +0 -9
- package/dist/esm/_virtual/index8.js +0 -9
- package/dist/esm/_virtual/index9.js +0 -9
- package/dist/esm/_virtual/inflate.js +0 -9
- package/dist/esm/_virtual/inherits_browser.js +0 -9
- package/dist/esm/_virtual/lib-typedarrays.js +0 -9
- package/dist/esm/_virtual/md5.js +0 -9
- package/dist/esm/_virtual/mode-cfb.js +0 -9
- package/dist/esm/_virtual/mode-ctr-gladman.js +0 -9
- package/dist/esm/_virtual/mode-ctr.js +0 -9
- package/dist/esm/_virtual/mode-ecb.js +0 -9
- package/dist/esm/_virtual/mode-ofb.js +0 -9
- package/dist/esm/_virtual/pad-ansix923.js +0 -9
- package/dist/esm/_virtual/pad-iso10126.js +0 -9
- package/dist/esm/_virtual/pad-iso97971.js +0 -9
- package/dist/esm/_virtual/pad-nopadding.js +0 -9
- package/dist/esm/_virtual/pad-zeropadding.js +0 -9
- package/dist/esm/_virtual/pbkdf2.js +0 -9
- package/dist/esm/_virtual/prefix.js +0 -9
- package/dist/esm/_virtual/rabbit-legacy.js +0 -9
- package/dist/esm/_virtual/rabbit.js +0 -9
- package/dist/esm/_virtual/rc4.js +0 -9
- package/dist/esm/_virtual/ripemd160.js +0 -9
- package/dist/esm/_virtual/scheduler.development.js +0 -9
- package/dist/esm/_virtual/scheduler.production.js +0 -9
- package/dist/esm/_virtual/sha1.js +0 -9
- package/dist/esm/_virtual/sha224.js +0 -9
- package/dist/esm/_virtual/sha256.js +0 -9
- package/dist/esm/_virtual/sha3.js +0 -9
- package/dist/esm/_virtual/sha384.js +0 -9
- package/dist/esm/_virtual/sha512.js +0 -9
- package/dist/esm/_virtual/streams.js +0 -9
- package/dist/esm/_virtual/transform.js +0 -9
- package/dist/esm/_virtual/trees.js +0 -9
- package/dist/esm/_virtual/tripledes.js +0 -9
- package/dist/esm/_virtual/x64-core.js +0 -9
- package/dist/esm/node_modules/@react-pdf/fns/lib/index.js +0 -254
- package/dist/esm/node_modules/@react-pdf/font/lib/index.browser.js +0 -481
- package/dist/esm/node_modules/@react-pdf/image/lib/index.browser.js +0 -2217
- package/dist/esm/node_modules/@react-pdf/layout/lib/index.js +0 -2982
- package/dist/esm/node_modules/@react-pdf/pdfkit/lib/pdfkit.browser.js +0 -47429
- package/dist/esm/node_modules/@react-pdf/png-js/lib/png-js.browser.js +0 -12606
- package/dist/esm/node_modules/@react-pdf/primitives/lib/index.js +0 -37
- package/dist/esm/node_modules/@react-pdf/reconciler/lib/index.js +0 -16
- package/dist/esm/node_modules/@react-pdf/reconciler/lib/reconciler-23.js +0 -22
- package/dist/esm/node_modules/@react-pdf/reconciler/lib/reconciler-31.js +0 -30
- package/dist/esm/node_modules/@react-pdf/render/lib/index.js +0 -2081
- package/dist/esm/node_modules/@react-pdf/renderer/lib/react-pdf.browser.js +0 -472
- package/dist/esm/node_modules/@react-pdf/stylesheet/lib/index.js +0 -771
- package/dist/esm/node_modules/@react-pdf/textkit/lib/textkit.js +0 -2854
- package/dist/esm/node_modules/@swc/helpers/esm/_define_property.js +0 -15
- package/dist/esm/node_modules/abs-svg-path/index.js +0 -78
- package/dist/esm/node_modules/base64-js/index.js +0 -158
- package/dist/esm/node_modules/bidi-js/dist/bidi.js +0 -1008
- package/dist/esm/node_modules/brotli/dec/bit_reader.js +0 -132
- package/dist/esm/node_modules/brotli/dec/context.js +0 -255
- package/dist/esm/node_modules/brotli/dec/decode.js +0 -965
- package/dist/esm/node_modules/brotli/dec/dictionary-browser.js +0 -35
- package/dist/esm/node_modules/brotli/dec/dictionary.bin.js +0 -17
- package/dist/esm/node_modules/brotli/dec/dictionary.js +0 -54
- package/dist/esm/node_modules/brotli/dec/huffman.js +0 -133
- package/dist/esm/node_modules/brotli/dec/prefix.js +0 -70
- package/dist/esm/node_modules/brotli/dec/streams.js +0 -44
- package/dist/esm/node_modules/brotli/dec/transform.js +0 -264
- package/dist/esm/node_modules/brotli/decompress.js +0 -14
- package/dist/esm/node_modules/clone/clone.js +0 -272
- package/dist/esm/node_modules/color-name/index.js +0 -158
- package/dist/esm/node_modules/color-string/index.js +0 -259
- package/dist/esm/node_modules/crypto-js/aes.js +0 -251
- package/dist/esm/node_modules/crypto-js/blowfish.js +0 -488
- package/dist/esm/node_modules/crypto-js/cipher-core.js +0 -909
- package/dist/esm/node_modules/crypto-js/core.js +0 -820
- package/dist/esm/node_modules/crypto-js/enc-base64.js +0 -149
- package/dist/esm/node_modules/crypto-js/enc-base64url.js +0 -161
- package/dist/esm/node_modules/crypto-js/enc-utf16.js +0 -162
- package/dist/esm/node_modules/crypto-js/evpkdf.js +0 -149
- package/dist/esm/node_modules/crypto-js/format-hex.js +0 -80
- package/dist/esm/node_modules/crypto-js/hmac.js +0 -156
- package/dist/esm/node_modules/crypto-js/index.js +0 -61
- package/dist/esm/node_modules/crypto-js/lib-typedarrays.js +0 -89
- package/dist/esm/node_modules/crypto-js/md5.js +0 -277
- package/dist/esm/node_modules/crypto-js/mode-cfb.js +0 -94
- package/dist/esm/node_modules/crypto-js/mode-ctr-gladman.js +0 -130
- package/dist/esm/node_modules/crypto-js/mode-ctr.js +0 -72
- package/dist/esm/node_modules/crypto-js/mode-ecb.js +0 -54
- package/dist/esm/node_modules/crypto-js/mode-ofb.js +0 -68
- package/dist/esm/node_modules/crypto-js/pad-ansix923.js +0 -63
- package/dist/esm/node_modules/crypto-js/pad-iso10126.js +0 -58
- package/dist/esm/node_modules/crypto-js/pad-iso97971.js +0 -54
- package/dist/esm/node_modules/crypto-js/pad-nopadding.js +0 -44
- package/dist/esm/node_modules/crypto-js/pad-zeropadding.js +0 -61
- package/dist/esm/node_modules/crypto-js/pbkdf2.js +0 -160
- package/dist/esm/node_modules/crypto-js/rabbit-legacy.js +0 -207
- package/dist/esm/node_modules/crypto-js/rabbit.js +0 -209
- package/dist/esm/node_modules/crypto-js/rc4.js +0 -156
- package/dist/esm/node_modules/crypto-js/ripemd160.js +0 -280
- package/dist/esm/node_modules/crypto-js/sha1.js +0 -163
- package/dist/esm/node_modules/crypto-js/sha224.js +0 -94
- package/dist/esm/node_modules/crypto-js/sha256.js +0 -212
- package/dist/esm/node_modules/crypto-js/sha3.js +0 -340
- package/dist/esm/node_modules/crypto-js/sha384.js +0 -98
- package/dist/esm/node_modules/crypto-js/sha512.js +0 -340
- package/dist/esm/node_modules/crypto-js/tripledes.js +0 -796
- package/dist/esm/node_modules/crypto-js/x64-core.js +0 -317
- package/dist/esm/node_modules/dfa/index.js +0 -101
- package/dist/esm/node_modules/emoji-regex/index.js +0 -12
- package/dist/esm/node_modules/events/events.js +0 -485
- package/dist/esm/node_modules/fast-deep-equal/index.js +0 -56
- package/dist/esm/node_modules/fontkit/dist/browser-module.js +0 -13295
- package/dist/esm/node_modules/hsl-to-hex/index.js +0 -72
- package/dist/esm/node_modules/hsl-to-rgb-for-reals/converter.js +0 -66
- package/dist/esm/node_modules/hyphen/hyphen.js +0 -424
- package/dist/esm/node_modules/hyphen/patterns/en-us.js +0 -48
- package/dist/esm/node_modules/inherits/inherits_browser.js +0 -39
- package/dist/esm/node_modules/jay-peg/src/index.js +0 -68
- package/dist/esm/node_modules/jay-peg/src/markers/dac.js +0 -25
- package/dist/esm/node_modules/jay-peg/src/markers/dht.js +0 -52
- package/dist/esm/node_modules/jay-peg/src/markers/dqt.js +0 -26
- package/dist/esm/node_modules/jay-peg/src/markers/dri.js +0 -17
- package/dist/esm/node_modules/jay-peg/src/markers/eoi.js +0 -17
- package/dist/esm/node_modules/jay-peg/src/markers/exif.js +0 -327
- package/dist/esm/node_modules/jay-peg/src/markers/jfif.js +0 -24
- package/dist/esm/node_modules/jay-peg/src/markers/sof.js +0 -32
- package/dist/esm/node_modules/jay-peg/src/markers/soi.js +0 -11
- package/dist/esm/node_modules/jay-peg/src/markers/sos.js +0 -57
- package/dist/esm/node_modules/jay-peg/src/markers/utils.js +0 -71
- package/dist/esm/node_modules/linebreak/dist/module.js +0 -1340
- package/dist/esm/node_modules/linebreak/node_modules/base64-js/lib/b64.js +0 -137
- package/dist/esm/node_modules/media-engine/src/index.js +0 -26
- package/dist/esm/node_modules/media-engine/src/operators.js +0 -36
- package/dist/esm/node_modules/media-engine/src/parser.js +0 -147
- package/dist/esm/node_modules/media-engine/src/queries.js +0 -64
- package/dist/esm/node_modules/normalize-svg-path/index.js +0 -126
- package/dist/esm/node_modules/pako/lib/utils/common.js +0 -114
- package/dist/esm/node_modules/pako/lib/zlib/adler32.js +0 -57
- package/dist/esm/node_modules/pako/lib/zlib/constants.js +0 -78
- package/dist/esm/node_modules/pako/lib/zlib/crc32.js +0 -65
- package/dist/esm/node_modules/pako/lib/zlib/deflate.js +0 -1880
- package/dist/esm/node_modules/pako/lib/zlib/inffast.js +0 -351
- package/dist/esm/node_modules/pako/lib/zlib/inflate.js +0 -1557
- package/dist/esm/node_modules/pako/lib/zlib/inftrees.js +0 -352
- package/dist/esm/node_modules/pako/lib/zlib/messages.js +0 -38
- package/dist/esm/node_modules/pako/lib/zlib/trees.js +0 -1232
- package/dist/esm/node_modules/pako/lib/zlib/zstream.js +0 -57
- package/dist/esm/node_modules/parse-svg-path/index.js +0 -68
- package/dist/esm/node_modules/postcss-value-parser/lib/parse.js +0 -333
- package/dist/esm/node_modules/postcss-value-parser/lib/unit.js +0 -132
- package/dist/esm/node_modules/queue/index.js +0 -211
- package/dist/esm/node_modules/restructure/src/Array.js +0 -112
- package/dist/esm/node_modules/restructure/src/Base.js +0 -25
- package/dist/esm/node_modules/restructure/src/Bitfield.js +0 -47
- package/dist/esm/node_modules/restructure/src/Buffer.js +0 -44
- package/dist/esm/node_modules/restructure/src/DecodeStream.js +0 -93
- package/dist/esm/node_modules/restructure/src/EncodeStream.js +0 -137
- package/dist/esm/node_modules/restructure/src/LazyArray.js +0 -82
- package/dist/esm/node_modules/restructure/src/Number.js +0 -80
- package/dist/esm/node_modules/restructure/src/Optional.js +0 -52
- package/dist/esm/node_modules/restructure/src/Pointer.js +0 -175
- package/dist/esm/node_modules/restructure/src/Reserved.js +0 -31
- package/dist/esm/node_modules/restructure/src/String.js +0 -161
- package/dist/esm/node_modules/restructure/src/Struct.js +0 -121
- package/dist/esm/node_modules/restructure/src/VersionedStruct.js +0 -147
- package/dist/esm/node_modules/restructure/src/utils.js +0 -42
- package/dist/esm/node_modules/scheduler/cjs/scheduler.development.js +0 -382
- package/dist/esm/node_modules/scheduler/cjs/scheduler.production.js +0 -359
- package/dist/esm/node_modules/scheduler/index.js +0 -21
- package/dist/esm/node_modules/simple-swizzle/index.js +0 -40
- package/dist/esm/node_modules/simple-swizzle/node_modules/is-arrayish/index.js +0 -17
- package/dist/esm/node_modules/svg-arc-to-cubic-bezier/modules/index.js +0 -189
- package/dist/esm/node_modules/tiny-inflate/index.js +0 -387
- package/dist/esm/node_modules/tslib/tslib.es6.js +0 -36
- package/dist/esm/node_modules/unicode-properties/dist/module.js +0 -132
- package/dist/esm/node_modules/unicode-trie/index.js +0 -150
- package/dist/esm/node_modules/unicode-trie/swap.js +0 -33
- package/dist/esm/node_modules/yoga-layout/dist/binaries/yoga-wasm-base64-esm.js +0 -81
- package/dist/esm/node_modules/yoga-layout/dist/src/generated/YGEnums.js +0 -217
- package/dist/esm/node_modules/yoga-layout/dist/src/load.js +0 -24
- package/dist/esm/node_modules/yoga-layout/dist/src/wrapAssembly.js +0 -130
- package/dist/esm/src/components/e-commerce/invoice/InvoicePDF.js +0 -181
|
@@ -1,2081 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* UMWD-Components
|
|
3
|
-
* @copyright Jelle Paulus
|
|
4
|
-
* @license MIT
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { Page, Text, Svg, Link, Canvas, List, Checkbox, Select, TextInput, FieldSet, Image, Note, Polyline, Polygon, Ellipse, Circle, G, Line, Rect, Path, TextInstance, Tspan, LinearGradient, RadialGradient } from '../../primitives/lib/index.js';
|
|
8
|
-
import { isNil, matchPercent } from '../../fns/lib/index.js';
|
|
9
|
-
import absPath from '../../../abs-svg-path/index.js';
|
|
10
|
-
import parsePath from '../../../parse-svg-path/index.js';
|
|
11
|
-
import normalize from '../../../normalize-svg-path/index.js';
|
|
12
|
-
import colorString from '../../../color-string/index.js';
|
|
13
|
-
|
|
14
|
-
const renderPath = (ctx, node) => {
|
|
15
|
-
const d = node.props?.d;
|
|
16
|
-
if (d)
|
|
17
|
-
ctx.path(node.props.d);
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
const KAPPA$3 = 4.0 * ((Math.sqrt(2) - 1.0) / 3.0);
|
|
21
|
-
const renderRect = (ctx, node) => {
|
|
22
|
-
const x = node.props?.x || 0;
|
|
23
|
-
const y = node.props?.y || 0;
|
|
24
|
-
const rx = node.props?.rx || 0;
|
|
25
|
-
const ry = node.props?.ry || 0;
|
|
26
|
-
const width = node.props?.width || 0;
|
|
27
|
-
const height = node.props?.height || 0;
|
|
28
|
-
if (!width || !height)
|
|
29
|
-
return;
|
|
30
|
-
if (rx && ry) {
|
|
31
|
-
const krx = rx * KAPPA$3;
|
|
32
|
-
const kry = ry * KAPPA$3;
|
|
33
|
-
ctx.moveTo(x + rx, y);
|
|
34
|
-
ctx.lineTo(x - rx + width, y);
|
|
35
|
-
ctx.bezierCurveTo(x - rx + width + krx, y, x + width, y + ry - kry, x + width, y + ry);
|
|
36
|
-
ctx.lineTo(x + width, y + height - ry);
|
|
37
|
-
ctx.bezierCurveTo(x + width, y + height - ry + kry, x - rx + width + krx, y + height, x - rx + width, y + height);
|
|
38
|
-
ctx.lineTo(x + rx, y + height);
|
|
39
|
-
ctx.bezierCurveTo(x + rx - krx, y + height, x, y + height - ry + kry, x, y + height - ry);
|
|
40
|
-
ctx.lineTo(x, y + ry);
|
|
41
|
-
ctx.bezierCurveTo(x, y + ry - kry, x + rx - krx, y, x + rx, y);
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
44
|
-
ctx.moveTo(x, y);
|
|
45
|
-
ctx.lineTo(x + width, y);
|
|
46
|
-
ctx.lineTo(x + width, y + height);
|
|
47
|
-
ctx.lineTo(x, y + height);
|
|
48
|
-
}
|
|
49
|
-
ctx.closePath();
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
const renderLine$1 = (ctx, node) => {
|
|
53
|
-
const { x1, x2, y1, y2 } = node.props || {};
|
|
54
|
-
ctx.moveTo(x1, y1);
|
|
55
|
-
ctx.lineTo(x2, y2);
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
const renderGroup = () => {
|
|
59
|
-
// noop
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
const KAPPA$2 = 4.0 * ((Math.sqrt(2) - 1.0) / 3.0);
|
|
63
|
-
const drawEllipse = (ctx, rx, ry, cx = 0, cy = 0) => {
|
|
64
|
-
const x = cx - rx;
|
|
65
|
-
const y = cy - ry;
|
|
66
|
-
const ox = rx * KAPPA$2;
|
|
67
|
-
const oy = ry * KAPPA$2;
|
|
68
|
-
const xe = x + rx * 2;
|
|
69
|
-
const ye = y + ry * 2;
|
|
70
|
-
const xm = x + rx;
|
|
71
|
-
const ym = y + ry;
|
|
72
|
-
ctx.moveTo(x, ym);
|
|
73
|
-
ctx.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
|
|
74
|
-
ctx.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
|
|
75
|
-
ctx.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
|
|
76
|
-
ctx.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
|
|
77
|
-
ctx.closePath();
|
|
78
|
-
};
|
|
79
|
-
const renderEllipse = (ctx, node) => {
|
|
80
|
-
const { cx, cy, rx, ry } = node.props || {};
|
|
81
|
-
drawEllipse(ctx, rx, ry, cx, cy);
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
const renderCircle = (ctx, node) => {
|
|
85
|
-
const cx = node.props?.cx;
|
|
86
|
-
const cy = node.props?.cy;
|
|
87
|
-
const r = node.props?.r;
|
|
88
|
-
drawEllipse(ctx, r, r, cx, cy);
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
/* eslint-disable no-return-assign */
|
|
92
|
-
const number = (n) => {
|
|
93
|
-
if (n > -1e21 && n < 1e21) {
|
|
94
|
-
return Math.round(n * 1e6) / 1e6;
|
|
95
|
-
}
|
|
96
|
-
throw new Error(`unsupported number: ${n}`);
|
|
97
|
-
};
|
|
98
|
-
const _renderGlyphs = (ctx, encoded, positions, x, y) => {
|
|
99
|
-
const commands = [];
|
|
100
|
-
const scale = ctx._fontSize / 1000;
|
|
101
|
-
let i;
|
|
102
|
-
let last = 0;
|
|
103
|
-
let hadOffset = false;
|
|
104
|
-
ctx.save();
|
|
105
|
-
// flip coordinate system
|
|
106
|
-
ctx.transform(1, 0, 0, -1, 0, ctx.page.height);
|
|
107
|
-
y = ctx.page.height - y;
|
|
108
|
-
// add current font to page if necessary
|
|
109
|
-
if (ctx.page.fonts[ctx._font.id] == null) {
|
|
110
|
-
ctx.page.fonts[ctx._font.id] = ctx._font.ref();
|
|
111
|
-
}
|
|
112
|
-
// begin the text object
|
|
113
|
-
ctx.addContent('BT');
|
|
114
|
-
// text position
|
|
115
|
-
ctx.addContent(`1 0 0 1 ${number(x)} ${number(y)} Tm`);
|
|
116
|
-
// font and font size
|
|
117
|
-
ctx.addContent(`/${ctx._font.id} ${number(ctx._fontSize)} Tf`);
|
|
118
|
-
// Adds a segment of text to the TJ command buffer
|
|
119
|
-
const addSegment = (cur) => {
|
|
120
|
-
if (last < cur) {
|
|
121
|
-
const hex = encoded.slice(last, cur).join('');
|
|
122
|
-
const advance = positions[cur - 1].xAdvance - positions[cur - 1].advanceWidth;
|
|
123
|
-
commands.push(`<${hex}> ${number(-advance)}`);
|
|
124
|
-
}
|
|
125
|
-
return (last = cur);
|
|
126
|
-
};
|
|
127
|
-
// Flushes the current TJ commands to the output stream
|
|
128
|
-
const flush = (s) => {
|
|
129
|
-
addSegment(s);
|
|
130
|
-
if (commands.length > 0) {
|
|
131
|
-
ctx.addContent(`[${commands.join(' ')}] TJ`);
|
|
132
|
-
return (commands.length = 0);
|
|
133
|
-
}
|
|
134
|
-
};
|
|
135
|
-
for (i = 0; i < positions.length; i += 1) {
|
|
136
|
-
// If we have an x or y offset, we have to break out of the current TJ command
|
|
137
|
-
// so we can move the text position.
|
|
138
|
-
const pos = positions[i];
|
|
139
|
-
if (pos.xOffset || pos.yOffset) {
|
|
140
|
-
// Flush the current buffer
|
|
141
|
-
flush(i);
|
|
142
|
-
// Move the text position and flush just the current character
|
|
143
|
-
ctx.addContent(`1 0 0 1 ${number(x + pos.xOffset * scale)} ${number(y + pos.yOffset * scale)} Tm`);
|
|
144
|
-
flush(i + 1);
|
|
145
|
-
hadOffset = true;
|
|
146
|
-
}
|
|
147
|
-
else {
|
|
148
|
-
// If the last character had an offset, reset the text position
|
|
149
|
-
if (hadOffset) {
|
|
150
|
-
ctx.addContent(`1 0 0 1 ${number(x)} ${number(y)} Tm`);
|
|
151
|
-
hadOffset = false;
|
|
152
|
-
}
|
|
153
|
-
// Group segments that don't have any advance adjustments
|
|
154
|
-
if (pos.xAdvance - pos.advanceWidth !== 0) {
|
|
155
|
-
addSegment(i + 1);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
x += pos.xAdvance * scale;
|
|
159
|
-
}
|
|
160
|
-
// Flush any remaining commands
|
|
161
|
-
flush(i);
|
|
162
|
-
// end the text object
|
|
163
|
-
ctx.addContent('ET');
|
|
164
|
-
// restore flipped coordinate system
|
|
165
|
-
return ctx.restore();
|
|
166
|
-
};
|
|
167
|
-
const renderGlyphs = (ctx, glyphs, positions, x, y) => {
|
|
168
|
-
const scale = 1000 / ctx._fontSize;
|
|
169
|
-
const unitsPerEm = ctx._font.font.unitsPerEm || 1000;
|
|
170
|
-
const advanceWidthScale = 1000 / unitsPerEm;
|
|
171
|
-
// Glyph encoding and positioning
|
|
172
|
-
const encodedGlyphs = ctx._font.encodeGlyphs(glyphs);
|
|
173
|
-
const encodedPositions = positions.map((pos, i) => ({
|
|
174
|
-
xAdvance: pos.xAdvance * scale,
|
|
175
|
-
yAdvance: pos.yAdvance * scale,
|
|
176
|
-
xOffset: pos.xOffset,
|
|
177
|
-
yOffset: pos.yOffset,
|
|
178
|
-
advanceWidth: glyphs[i].advanceWidth * advanceWidthScale,
|
|
179
|
-
}));
|
|
180
|
-
return _renderGlyphs(ctx, encodedGlyphs, encodedPositions, x, y);
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
const renderRun$1 = (ctx, run) => {
|
|
184
|
-
if (!run.glyphs)
|
|
185
|
-
return;
|
|
186
|
-
if (!run.positions)
|
|
187
|
-
return;
|
|
188
|
-
const runAdvanceWidth = run.xAdvance;
|
|
189
|
-
const font = run.attributes.font?.[0];
|
|
190
|
-
const { fontSize, color, opacity } = run.attributes;
|
|
191
|
-
if (color)
|
|
192
|
-
ctx.fillColor(color);
|
|
193
|
-
ctx.fillOpacity(opacity);
|
|
194
|
-
if (font) {
|
|
195
|
-
ctx.font(font.type === 'STANDARD' ? font.fullName : font, fontSize);
|
|
196
|
-
}
|
|
197
|
-
try {
|
|
198
|
-
renderGlyphs(ctx, run.glyphs, run.positions, 0, 0);
|
|
199
|
-
}
|
|
200
|
-
catch (error) {
|
|
201
|
-
console.log(error);
|
|
202
|
-
}
|
|
203
|
-
ctx.translate(runAdvanceWidth, 0);
|
|
204
|
-
};
|
|
205
|
-
const renderSpan = (ctx, line, textAnchor, dominantBaseline) => {
|
|
206
|
-
ctx.save();
|
|
207
|
-
const x = line.box?.x || 0;
|
|
208
|
-
const y = line.box?.y || 0;
|
|
209
|
-
const font = line.runs[0]?.attributes.font?.[0];
|
|
210
|
-
const scale = line.runs[0]?.attributes?.scale || 1;
|
|
211
|
-
const width = line.xAdvance;
|
|
212
|
-
if (!font)
|
|
213
|
-
return;
|
|
214
|
-
const ascent = font.ascent * scale;
|
|
215
|
-
const xHeight = font.xHeight * scale;
|
|
216
|
-
const descent = font.descent * scale;
|
|
217
|
-
const capHeight = font.capHeight * scale;
|
|
218
|
-
let xTranslate = x;
|
|
219
|
-
let yTranslate = y;
|
|
220
|
-
switch (textAnchor) {
|
|
221
|
-
case 'middle':
|
|
222
|
-
xTranslate = x - width / 2;
|
|
223
|
-
break;
|
|
224
|
-
case 'end':
|
|
225
|
-
xTranslate = x - width;
|
|
226
|
-
break;
|
|
227
|
-
default:
|
|
228
|
-
xTranslate = x;
|
|
229
|
-
break;
|
|
230
|
-
}
|
|
231
|
-
switch (dominantBaseline) {
|
|
232
|
-
case 'middle':
|
|
233
|
-
case 'central':
|
|
234
|
-
yTranslate = y + capHeight / 2;
|
|
235
|
-
break;
|
|
236
|
-
case 'hanging':
|
|
237
|
-
yTranslate = y + capHeight;
|
|
238
|
-
break;
|
|
239
|
-
case 'mathematical':
|
|
240
|
-
yTranslate = y + xHeight;
|
|
241
|
-
break;
|
|
242
|
-
case 'text-after-edge':
|
|
243
|
-
yTranslate = y + descent;
|
|
244
|
-
break;
|
|
245
|
-
case 'text-before-edge':
|
|
246
|
-
yTranslate = y + ascent;
|
|
247
|
-
break;
|
|
248
|
-
default:
|
|
249
|
-
yTranslate = y;
|
|
250
|
-
break;
|
|
251
|
-
}
|
|
252
|
-
ctx.translate(xTranslate, yTranslate);
|
|
253
|
-
line.runs.forEach((run) => renderRun$1(ctx, run));
|
|
254
|
-
ctx.restore();
|
|
255
|
-
};
|
|
256
|
-
const renderSvgText = (ctx, node) => {
|
|
257
|
-
const children = node.children;
|
|
258
|
-
children.forEach((span) => renderSpan(ctx, span.lines[0], span.props.textAnchor, span.props.dominantBaseline));
|
|
259
|
-
};
|
|
260
|
-
|
|
261
|
-
const pairs = (values) => {
|
|
262
|
-
const result = [];
|
|
263
|
-
for (let i = 0; i < values.length; i += 2) {
|
|
264
|
-
result.push([values[i], values[i + 1]]);
|
|
265
|
-
}
|
|
266
|
-
return result;
|
|
267
|
-
};
|
|
268
|
-
/**
|
|
269
|
-
* Parse svg-like points into number arrays
|
|
270
|
-
*
|
|
271
|
-
* @param points string ex. "20,30 50,60"
|
|
272
|
-
* @returns points array ex. [[20, 30], [50, 60]]
|
|
273
|
-
*/
|
|
274
|
-
const parsePoints = (points) => {
|
|
275
|
-
let values = (points || '')
|
|
276
|
-
.trim()
|
|
277
|
-
.replace(/,/g, ' ')
|
|
278
|
-
.replace(/(\d)-(\d)/g, '$1 -$2')
|
|
279
|
-
.split(/\s+/);
|
|
280
|
-
if (values.length % 2 !== 0) {
|
|
281
|
-
values = values.slice(0, -1);
|
|
282
|
-
}
|
|
283
|
-
const mappedValues = values.map(parseFloat);
|
|
284
|
-
return pairs(mappedValues);
|
|
285
|
-
};
|
|
286
|
-
|
|
287
|
-
const drawPolyline = (ctx, points) => {
|
|
288
|
-
if (points.length > 0) {
|
|
289
|
-
ctx.moveTo(points[0][0], points[0][1]);
|
|
290
|
-
points.slice(1).forEach((p) => ctx.lineTo(p[0], p[1]));
|
|
291
|
-
}
|
|
292
|
-
};
|
|
293
|
-
const renderPolyline = (ctx, node) => {
|
|
294
|
-
const points = parsePoints(node.props.points || '');
|
|
295
|
-
drawPolyline(ctx, points);
|
|
296
|
-
};
|
|
297
|
-
|
|
298
|
-
const renderPolygon = (ctx, node) => {
|
|
299
|
-
const points = parsePoints(node.props.points || '');
|
|
300
|
-
drawPolyline(ctx, points);
|
|
301
|
-
ctx.closePath();
|
|
302
|
-
};
|
|
303
|
-
|
|
304
|
-
const renderImage$1 = (ctx, node) => {
|
|
305
|
-
if (!node.box)
|
|
306
|
-
return;
|
|
307
|
-
if (!node.image?.data)
|
|
308
|
-
return;
|
|
309
|
-
const { x = 0, y = 0 } = node.props;
|
|
310
|
-
const { width, height, opacity } = node.style;
|
|
311
|
-
const paddingTop = node.box.paddingLeft || 0;
|
|
312
|
-
const paddingLeft = node.box.paddingLeft || 0;
|
|
313
|
-
if (width === 0 || height === 0) {
|
|
314
|
-
console.warn(`Image with src '${node.props.href}' skipped due to invalid dimensions`);
|
|
315
|
-
return;
|
|
316
|
-
}
|
|
317
|
-
if (typeof width === 'string' || typeof height === 'string') {
|
|
318
|
-
console.warn(`Image with src '${node.props.href}' skipped due to percentage width or height`);
|
|
319
|
-
return;
|
|
320
|
-
}
|
|
321
|
-
ctx.save();
|
|
322
|
-
ctx
|
|
323
|
-
.fillOpacity(opacity || 1)
|
|
324
|
-
.image(node.image.data, x + paddingLeft, y + paddingTop, {
|
|
325
|
-
width,
|
|
326
|
-
height,
|
|
327
|
-
});
|
|
328
|
-
ctx.restore();
|
|
329
|
-
};
|
|
330
|
-
|
|
331
|
-
// This constant is used to approximate a symmetrical arc using a cubic
|
|
332
|
-
// Bezier curve.
|
|
333
|
-
const KAPPA$1 = 4.0 * ((Math.sqrt(2) - 1.0) / 3.0);
|
|
334
|
-
const clipNode = (ctx, node) => {
|
|
335
|
-
if (!node.box)
|
|
336
|
-
return;
|
|
337
|
-
if (!node.style)
|
|
338
|
-
return;
|
|
339
|
-
const { top, left, width, height } = node.box;
|
|
340
|
-
const { borderTopLeftRadius = 0, borderTopRightRadius = 0, borderBottomRightRadius = 0, borderBottomLeftRadius = 0, } = node.style;
|
|
341
|
-
// Border top
|
|
342
|
-
// @ts-expect-error this is always a number due to resolve border radius step
|
|
343
|
-
const rtr = Math.min(borderTopRightRadius, 0.5 * width, 0.5 * height);
|
|
344
|
-
const ctr = rtr * (1.0 - KAPPA$1);
|
|
345
|
-
ctx.moveTo(left + rtr, top);
|
|
346
|
-
ctx.lineTo(left + width - rtr, top);
|
|
347
|
-
ctx.bezierCurveTo(left + width - ctr, top, left + width, top + ctr, left + width, top + rtr);
|
|
348
|
-
// Border right
|
|
349
|
-
// @ts-expect-error this is always a number due to resolve border radius step
|
|
350
|
-
const rbr = Math.min(borderBottomRightRadius, 0.5 * width, 0.5 * height);
|
|
351
|
-
const cbr = rbr * (1.0 - KAPPA$1);
|
|
352
|
-
ctx.lineTo(left + width, top + height - rbr);
|
|
353
|
-
ctx.bezierCurveTo(left + width, top + height - cbr, left + width - cbr, top + height, left + width - rbr, top + height);
|
|
354
|
-
// Border bottom
|
|
355
|
-
// @ts-expect-error this is always a number due to resolve border radius step
|
|
356
|
-
const rbl = Math.min(borderBottomLeftRadius, 0.5 * width, 0.5 * height);
|
|
357
|
-
const cbl = rbl * (1.0 - KAPPA$1);
|
|
358
|
-
ctx.lineTo(left + rbl, top + height);
|
|
359
|
-
ctx.bezierCurveTo(left + cbl, top + height, left, top + height - cbl, left, top + height - rbl);
|
|
360
|
-
// Border left
|
|
361
|
-
// @ts-expect-error this is always a number due to resolve border radius step
|
|
362
|
-
const rtl = Math.min(borderTopLeftRadius, 0.5 * width, 0.5 * height);
|
|
363
|
-
const ctl = rtl * (1.0 - KAPPA$1);
|
|
364
|
-
ctx.lineTo(left, top + rtl);
|
|
365
|
-
ctx.bezierCurveTo(left, top + ctl, left + ctl, top, left + rtl, top);
|
|
366
|
-
ctx.closePath();
|
|
367
|
-
ctx.clip();
|
|
368
|
-
};
|
|
369
|
-
|
|
370
|
-
const applySingleTransformation = (ctx, transform, origin) => {
|
|
371
|
-
const { operation, value } = transform;
|
|
372
|
-
switch (operation) {
|
|
373
|
-
case 'scale': {
|
|
374
|
-
const [scaleX, scaleY] = value;
|
|
375
|
-
ctx.scale(scaleX, scaleY, { origin });
|
|
376
|
-
break;
|
|
377
|
-
}
|
|
378
|
-
case 'rotate': {
|
|
379
|
-
const [angle] = value;
|
|
380
|
-
ctx.rotate(angle, { origin });
|
|
381
|
-
break;
|
|
382
|
-
}
|
|
383
|
-
case 'translate': {
|
|
384
|
-
const [x, y = 0] = value;
|
|
385
|
-
ctx.translate(x, y, { origin });
|
|
386
|
-
break;
|
|
387
|
-
}
|
|
388
|
-
case 'skew': {
|
|
389
|
-
const [xAngle = 0, yAngle = 0] = value;
|
|
390
|
-
const radx = (xAngle * Math.PI) / 180;
|
|
391
|
-
const rady = (yAngle * Math.PI) / 180;
|
|
392
|
-
const tanx = Math.tan(radx);
|
|
393
|
-
const tany = Math.tan(rady);
|
|
394
|
-
let x = 0;
|
|
395
|
-
let y = 0;
|
|
396
|
-
if (origin != null) {
|
|
397
|
-
[x, y] = Array.from(origin);
|
|
398
|
-
const x1 = x + tanx * y;
|
|
399
|
-
const y1 = y + tany * x;
|
|
400
|
-
x -= x1;
|
|
401
|
-
y -= y1;
|
|
402
|
-
}
|
|
403
|
-
ctx.transform(1, tany, tanx, 1, x, y);
|
|
404
|
-
break;
|
|
405
|
-
}
|
|
406
|
-
case 'matrix': {
|
|
407
|
-
ctx.transform(...value);
|
|
408
|
-
break;
|
|
409
|
-
}
|
|
410
|
-
default: {
|
|
411
|
-
console.error(`Transform operation: '${operation}' doesn't supported`);
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
};
|
|
415
|
-
const applyTransformations = (ctx, node) => {
|
|
416
|
-
if (!node.origin)
|
|
417
|
-
return;
|
|
418
|
-
const { props, style } = node;
|
|
419
|
-
const origin = [node.origin.left, node.origin.top];
|
|
420
|
-
const propsTransform = 'transform' in props ? props.transform : undefined;
|
|
421
|
-
const operations = style?.transform || propsTransform || [];
|
|
422
|
-
operations.forEach((operation) => {
|
|
423
|
-
applySingleTransformation(ctx, operation, origin);
|
|
424
|
-
});
|
|
425
|
-
};
|
|
426
|
-
|
|
427
|
-
// From https://github.com/dy/svg-path-bounds/blob/master/index.js
|
|
428
|
-
const getPathBoundingBox = (node) => {
|
|
429
|
-
const path = normalize(absPath(parsePath(node.props?.d || '')));
|
|
430
|
-
if (!path.length)
|
|
431
|
-
return [0, 0, 0, 0];
|
|
432
|
-
const bounds = [Infinity, Infinity, -Infinity, -Infinity];
|
|
433
|
-
for (let i = 0, l = path.length; i < l; i += 1) {
|
|
434
|
-
const points = path[i].slice(1);
|
|
435
|
-
for (let j = 0; j < points.length; j += 2) {
|
|
436
|
-
if (points[j + 0] < bounds[0])
|
|
437
|
-
bounds[0] = points[j + 0];
|
|
438
|
-
if (points[j + 1] < bounds[1])
|
|
439
|
-
bounds[1] = points[j + 1];
|
|
440
|
-
if (points[j + 0] > bounds[2])
|
|
441
|
-
bounds[2] = points[j + 0];
|
|
442
|
-
if (points[j + 1] > bounds[3])
|
|
443
|
-
bounds[3] = points[j + 1];
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
return bounds;
|
|
447
|
-
};
|
|
448
|
-
const getCircleBoundingBox = (node) => {
|
|
449
|
-
const r = node.props?.r || 0;
|
|
450
|
-
const cx = node.props?.cx || 0;
|
|
451
|
-
const cy = node.props?.cy || 0;
|
|
452
|
-
return [cx - r, cy - r, cx + r, cy + r];
|
|
453
|
-
};
|
|
454
|
-
const getEllipseBoundingBox = (node) => {
|
|
455
|
-
const cx = node.props?.cx || 0;
|
|
456
|
-
const cy = node.props?.cy || 0;
|
|
457
|
-
const rx = node.props?.rx || 0;
|
|
458
|
-
const ry = node.props?.ry || 0;
|
|
459
|
-
return [cx - rx, cy - ry, cx + rx, cy + ry];
|
|
460
|
-
};
|
|
461
|
-
const getLineBoundingBox = (node) => {
|
|
462
|
-
const x1 = node.props?.x1 || 0;
|
|
463
|
-
const y1 = node.props?.y1 || 0;
|
|
464
|
-
const x2 = node.props?.x2 || 0;
|
|
465
|
-
const y2 = node.props?.y2 || 0;
|
|
466
|
-
return [
|
|
467
|
-
Math.min(x1, x2),
|
|
468
|
-
Math.min(y1, y2),
|
|
469
|
-
Math.max(x1, x2),
|
|
470
|
-
Math.max(y1, y2),
|
|
471
|
-
];
|
|
472
|
-
};
|
|
473
|
-
const getRectBoundingBox = (node) => {
|
|
474
|
-
const x = node.props?.x || 0;
|
|
475
|
-
const y = node.props?.y || 0;
|
|
476
|
-
const width = node.props?.width || 0;
|
|
477
|
-
const height = node.props?.height || 0;
|
|
478
|
-
return [x, y, x + width, y + height];
|
|
479
|
-
};
|
|
480
|
-
const max = (values) => Math.max(-Infinity, ...values);
|
|
481
|
-
const min = (values) => Math.min(Infinity, ...values);
|
|
482
|
-
const getPolylineBoundingBox = (node) => {
|
|
483
|
-
const points = parsePoints(node.props?.points);
|
|
484
|
-
const xValues = points.map((p) => p[0]);
|
|
485
|
-
const yValues = points.map((p) => p[1]);
|
|
486
|
-
return [min(xValues), min(yValues), max(xValues), max(yValues)];
|
|
487
|
-
};
|
|
488
|
-
const boundingBoxFns = {
|
|
489
|
-
[Rect]: getRectBoundingBox,
|
|
490
|
-
[Line]: getLineBoundingBox,
|
|
491
|
-
[Path]: getPathBoundingBox,
|
|
492
|
-
[Circle]: getCircleBoundingBox,
|
|
493
|
-
[Ellipse]: getEllipseBoundingBox,
|
|
494
|
-
[Polygon]: getPolylineBoundingBox,
|
|
495
|
-
[Polyline]: getPolylineBoundingBox,
|
|
496
|
-
};
|
|
497
|
-
const getBoundingBox = (node) => {
|
|
498
|
-
const boundingBoxFn = boundingBoxFns[node.type];
|
|
499
|
-
return boundingBoxFn ? boundingBoxFn(node) : [0, 0, 0, 0];
|
|
500
|
-
};
|
|
501
|
-
|
|
502
|
-
const setStrokeWidth = (ctx, node) => {
|
|
503
|
-
if (!node.props)
|
|
504
|
-
return;
|
|
505
|
-
if (!('strokeWidth' in node.props))
|
|
506
|
-
return;
|
|
507
|
-
const lineWidth = node.props.strokeWidth;
|
|
508
|
-
if (lineWidth)
|
|
509
|
-
ctx.lineWidth(lineWidth);
|
|
510
|
-
};
|
|
511
|
-
const setStrokeColor = (ctx, node) => {
|
|
512
|
-
if (!node.props)
|
|
513
|
-
return;
|
|
514
|
-
if (!('stroke' in node.props))
|
|
515
|
-
return;
|
|
516
|
-
const strokeColor = node.props.stroke;
|
|
517
|
-
if (strokeColor)
|
|
518
|
-
ctx.strokeColor(strokeColor);
|
|
519
|
-
};
|
|
520
|
-
const setOpacity = (ctx, node) => {
|
|
521
|
-
if (!node.props)
|
|
522
|
-
return;
|
|
523
|
-
if (!('opacity' in node.props))
|
|
524
|
-
return;
|
|
525
|
-
const opacity = node.props.opacity;
|
|
526
|
-
if (!isNil(opacity))
|
|
527
|
-
ctx.opacity(opacity);
|
|
528
|
-
};
|
|
529
|
-
const setFillOpacity = (ctx, node) => {
|
|
530
|
-
if (!node.props)
|
|
531
|
-
return;
|
|
532
|
-
if (!('fillOpacity' in node.props))
|
|
533
|
-
return;
|
|
534
|
-
const fillOpacity = node.props.fillOpacity || null;
|
|
535
|
-
if (!isNil(fillOpacity))
|
|
536
|
-
ctx.fillOpacity(fillOpacity);
|
|
537
|
-
};
|
|
538
|
-
const setStrokeOpacity = (ctx, node) => {
|
|
539
|
-
if (!node.props)
|
|
540
|
-
return;
|
|
541
|
-
if (!('strokeOpacity' in node.props))
|
|
542
|
-
return;
|
|
543
|
-
const strokeOpacity = node.props?.strokeOpacity;
|
|
544
|
-
if (!isNil(strokeOpacity))
|
|
545
|
-
ctx.strokeOpacity(strokeOpacity);
|
|
546
|
-
};
|
|
547
|
-
const setLineJoin = (ctx, node) => {
|
|
548
|
-
if (!node.props)
|
|
549
|
-
return;
|
|
550
|
-
if (!('strokeLinejoin' in node.props))
|
|
551
|
-
return;
|
|
552
|
-
const lineJoin = node.props.strokeLinejoin;
|
|
553
|
-
if (lineJoin)
|
|
554
|
-
ctx.lineJoin(lineJoin);
|
|
555
|
-
};
|
|
556
|
-
const setLineCap = (ctx, node) => {
|
|
557
|
-
if (!node.props)
|
|
558
|
-
return;
|
|
559
|
-
if (!('strokeLinecap' in node.props))
|
|
560
|
-
return;
|
|
561
|
-
const lineCap = node.props?.strokeLinecap;
|
|
562
|
-
if (lineCap)
|
|
563
|
-
ctx.lineCap(lineCap);
|
|
564
|
-
};
|
|
565
|
-
const setLineDash = (ctx, node) => {
|
|
566
|
-
if (!node.props)
|
|
567
|
-
return;
|
|
568
|
-
if (!('strokeDasharray' in node.props))
|
|
569
|
-
return;
|
|
570
|
-
const value = node.props?.strokeDasharray || null;
|
|
571
|
-
// @ts-expect-error check this works as expected
|
|
572
|
-
if (value)
|
|
573
|
-
ctx.dash(value.split(/[\s,]+/).map(Number));
|
|
574
|
-
};
|
|
575
|
-
const hasLinearGradientFill = (node) => {
|
|
576
|
-
if (!node.props)
|
|
577
|
-
return false;
|
|
578
|
-
if (!('fill' in node.props))
|
|
579
|
-
return false;
|
|
580
|
-
if (typeof node.props.fill === 'string')
|
|
581
|
-
return false;
|
|
582
|
-
return node.props.fill?.type === LinearGradient;
|
|
583
|
-
};
|
|
584
|
-
const hasRadialGradientFill = (node) => {
|
|
585
|
-
if (!node.props)
|
|
586
|
-
return false;
|
|
587
|
-
if (!('fill' in node.props))
|
|
588
|
-
return false;
|
|
589
|
-
if (typeof node.props.fill === 'string')
|
|
590
|
-
return false;
|
|
591
|
-
return node.props.fill?.type === RadialGradient;
|
|
592
|
-
};
|
|
593
|
-
function multiplyMatrices(m1, m2) {
|
|
594
|
-
const a = m1[0] * m2[0] + m1[2] * m2[1];
|
|
595
|
-
const b = m1[1] * m2[0] + m1[3] * m2[1];
|
|
596
|
-
const c = m1[0] * m2[2] + m1[2] * m2[3];
|
|
597
|
-
const d = m1[1] * m2[2] + m1[3] * m2[3];
|
|
598
|
-
const e = m1[0] * m2[4] + m1[2] * m2[5] + m1[4];
|
|
599
|
-
const f = m1[1] * m2[4] + m1[3] * m2[5] + m1[5];
|
|
600
|
-
return [a, b, c, d, e, f];
|
|
601
|
-
}
|
|
602
|
-
const transformGradient = (grad, transforms, bbox, units) => {
|
|
603
|
-
const matrices = transforms.map((transform) => {
|
|
604
|
-
switch (transform.operation) {
|
|
605
|
-
case 'scale': {
|
|
606
|
-
const value = transform.value;
|
|
607
|
-
return [value[0], 0, 0, value[1], 0, 0];
|
|
608
|
-
}
|
|
609
|
-
case 'translate': {
|
|
610
|
-
const value = transform.value;
|
|
611
|
-
let x = value[0] || 0;
|
|
612
|
-
let y = value[1] || 0;
|
|
613
|
-
if (units === 'objectBoundingBox') {
|
|
614
|
-
x = (bbox[2] - bbox[0]) * x;
|
|
615
|
-
y = (bbox[3] - bbox[1]) * y;
|
|
616
|
-
}
|
|
617
|
-
return [1, 0, 0, 1, x, y];
|
|
618
|
-
}
|
|
619
|
-
case 'rotate': {
|
|
620
|
-
const value = transform.value;
|
|
621
|
-
const cos = Math.cos(value[0]);
|
|
622
|
-
const sin = Math.sin(value[0]);
|
|
623
|
-
return [cos, sin, -sin, cos, 0, 0];
|
|
624
|
-
}
|
|
625
|
-
case 'skew': {
|
|
626
|
-
const value = transform.value;
|
|
627
|
-
return [1, Math.tan(value[0]), Math.tan(value[1]), 1, 0, 0];
|
|
628
|
-
}
|
|
629
|
-
case 'matrix': {
|
|
630
|
-
const value = transform.value;
|
|
631
|
-
let x = value[4] || 0;
|
|
632
|
-
let y = value[5] || 0;
|
|
633
|
-
if (units === 'objectBoundingBox') {
|
|
634
|
-
x = (bbox[2] - bbox[0]) * x;
|
|
635
|
-
y = (bbox[3] - bbox[1]) * y;
|
|
636
|
-
}
|
|
637
|
-
return [value[0], value[1], value[2], value[3], x, y];
|
|
638
|
-
}
|
|
639
|
-
default:
|
|
640
|
-
return [1, 0, 0, 1, 0, 0];
|
|
641
|
-
}
|
|
642
|
-
});
|
|
643
|
-
const matrix = matrices.reduce(multiplyMatrices, [1, 0, 0, 1, 0, 0]);
|
|
644
|
-
grad.setTransform(...matrix);
|
|
645
|
-
};
|
|
646
|
-
// Math simplified from https://github.com/devongovett/svgkit/blob/master/src/elements/SVGGradient.js#L104
|
|
647
|
-
const setLinearGradientFill = (ctx, node) => {
|
|
648
|
-
if (!node.props)
|
|
649
|
-
return;
|
|
650
|
-
if (!('fill' in node.props))
|
|
651
|
-
return;
|
|
652
|
-
const bbox = getBoundingBox(node);
|
|
653
|
-
const gradient = node.props?.fill;
|
|
654
|
-
if (!gradient)
|
|
655
|
-
return;
|
|
656
|
-
const units = gradient.props.gradientUnits || 'objectBoundingBox';
|
|
657
|
-
const transforms = gradient.props.gradientTransform || [];
|
|
658
|
-
let x1 = gradient.props.x1 || 0;
|
|
659
|
-
let y1 = gradient.props.y1 || 0;
|
|
660
|
-
let x2 = gradient.props.x2 || 1;
|
|
661
|
-
let y2 = gradient.props.y2 || 0;
|
|
662
|
-
if (units === 'objectBoundingBox') {
|
|
663
|
-
const m0 = bbox[2] - bbox[0];
|
|
664
|
-
const m3 = bbox[3] - bbox[1];
|
|
665
|
-
const m4 = bbox[0];
|
|
666
|
-
const m5 = bbox[1];
|
|
667
|
-
x1 = m0 * x1 + m4;
|
|
668
|
-
y1 = m3 * y1 + m5;
|
|
669
|
-
x2 = m0 * x2 + m4;
|
|
670
|
-
y2 = m3 * y2 + m5;
|
|
671
|
-
}
|
|
672
|
-
const grad = ctx.linearGradient(x1, y1, x2, y2);
|
|
673
|
-
transformGradient(grad, transforms, bbox, units);
|
|
674
|
-
gradient.children?.forEach((stop) => {
|
|
675
|
-
grad.stop(stop.props.offset, stop.props.stopColor, stop.props.stopOpacity);
|
|
676
|
-
});
|
|
677
|
-
ctx.fill(grad);
|
|
678
|
-
};
|
|
679
|
-
// Math simplified from https://github.com/devongovett/svgkit/blob/master/src/elements/SVGGradient.js#L155
|
|
680
|
-
const setRadialGradientFill = (ctx, node) => {
|
|
681
|
-
if (!node.props)
|
|
682
|
-
return;
|
|
683
|
-
if (!('fill' in node.props))
|
|
684
|
-
return;
|
|
685
|
-
const bbox = getBoundingBox(node);
|
|
686
|
-
const gradient = node.props?.fill;
|
|
687
|
-
if (!gradient)
|
|
688
|
-
return;
|
|
689
|
-
const units = gradient.props.gradientUnits || 'objectBoundingBox';
|
|
690
|
-
const transforms = gradient.props.gradientTransform || [];
|
|
691
|
-
let r = gradient.props.r || 0.5;
|
|
692
|
-
let cx = gradient.props.cx || 0.5;
|
|
693
|
-
let cy = gradient.props.cy || 0.5;
|
|
694
|
-
let fx = gradient.props.fx || cx;
|
|
695
|
-
let fy = gradient.props.fy || cy;
|
|
696
|
-
if (units === 'objectBoundingBox') {
|
|
697
|
-
const m0 = bbox[2] - bbox[0];
|
|
698
|
-
const m3 = bbox[3] - bbox[1];
|
|
699
|
-
const m4 = bbox[0];
|
|
700
|
-
const m5 = bbox[1];
|
|
701
|
-
r = r * m0;
|
|
702
|
-
cx = m0 * cx + m4;
|
|
703
|
-
cy = m3 * cy + m5;
|
|
704
|
-
fx = m0 * fx + m4;
|
|
705
|
-
fy = m3 * fy + m5;
|
|
706
|
-
}
|
|
707
|
-
const grad = ctx.radialGradient(cx, cy, 0, fx, fy, r);
|
|
708
|
-
transformGradient(grad, transforms, bbox, units);
|
|
709
|
-
gradient.children?.forEach((stop) => {
|
|
710
|
-
grad.stop(stop.props.offset, stop.props.stopColor, stop.props.stopOpacity);
|
|
711
|
-
});
|
|
712
|
-
ctx.fill(grad);
|
|
713
|
-
};
|
|
714
|
-
const setFillColor = (ctx, node) => {
|
|
715
|
-
if (!node.props)
|
|
716
|
-
return;
|
|
717
|
-
if (!('fill' in node.props))
|
|
718
|
-
return;
|
|
719
|
-
const fillColor = node.props?.fill;
|
|
720
|
-
if (fillColor)
|
|
721
|
-
ctx.fillColor(fillColor);
|
|
722
|
-
};
|
|
723
|
-
const setFill = (ctx, node) => {
|
|
724
|
-
if (hasLinearGradientFill(node))
|
|
725
|
-
return setLinearGradientFill(ctx, node);
|
|
726
|
-
if (hasRadialGradientFill(node))
|
|
727
|
-
return setRadialGradientFill(ctx, node);
|
|
728
|
-
return setFillColor(ctx, node);
|
|
729
|
-
};
|
|
730
|
-
const draw = (ctx, node) => {
|
|
731
|
-
const props = node.props || {};
|
|
732
|
-
if ('fill' in props && 'stroke' in props && props.fill && props.stroke) {
|
|
733
|
-
ctx.fillAndStroke(props.fillRule);
|
|
734
|
-
}
|
|
735
|
-
else if ('fill' in props && props.fill) {
|
|
736
|
-
ctx.fill(props.fillRule);
|
|
737
|
-
}
|
|
738
|
-
else if ('stroke' in props && props.stroke) {
|
|
739
|
-
ctx.stroke();
|
|
740
|
-
}
|
|
741
|
-
else {
|
|
742
|
-
ctx.save();
|
|
743
|
-
ctx.opacity(0);
|
|
744
|
-
ctx.fill(null);
|
|
745
|
-
ctx.restore();
|
|
746
|
-
}
|
|
747
|
-
};
|
|
748
|
-
const noop = () => { };
|
|
749
|
-
const renderFns$1 = {
|
|
750
|
-
[Tspan]: noop,
|
|
751
|
-
[TextInstance]: noop,
|
|
752
|
-
[Path]: renderPath,
|
|
753
|
-
[Rect]: renderRect,
|
|
754
|
-
[Line]: renderLine$1,
|
|
755
|
-
[G]: renderGroup,
|
|
756
|
-
[Text]: renderSvgText,
|
|
757
|
-
[Circle]: renderCircle,
|
|
758
|
-
[Image]: renderImage$1,
|
|
759
|
-
[Ellipse]: renderEllipse,
|
|
760
|
-
[Polygon]: renderPolygon,
|
|
761
|
-
[Polyline]: renderPolyline,
|
|
762
|
-
};
|
|
763
|
-
const renderNode$1 = (ctx, node) => {
|
|
764
|
-
const renderFn = renderFns$1[node.type];
|
|
765
|
-
if (renderFn) {
|
|
766
|
-
renderFn(ctx, node);
|
|
767
|
-
}
|
|
768
|
-
else {
|
|
769
|
-
console.warn(`SVG node of type ${node.type} is not currently supported`);
|
|
770
|
-
}
|
|
771
|
-
};
|
|
772
|
-
const drawNode = (ctx, node) => {
|
|
773
|
-
setLineCap(ctx, node);
|
|
774
|
-
setLineDash(ctx, node);
|
|
775
|
-
setLineJoin(ctx, node);
|
|
776
|
-
setStrokeWidth(ctx, node);
|
|
777
|
-
setStrokeColor(ctx, node);
|
|
778
|
-
setFill(ctx, node);
|
|
779
|
-
setStrokeOpacity(ctx, node);
|
|
780
|
-
setFillOpacity(ctx, node);
|
|
781
|
-
setOpacity(ctx, node);
|
|
782
|
-
applyTransformations(ctx, node);
|
|
783
|
-
renderNode$1(ctx, node);
|
|
784
|
-
draw(ctx, node);
|
|
785
|
-
};
|
|
786
|
-
const clipPath = (ctx, node) => {
|
|
787
|
-
if (!node.props)
|
|
788
|
-
return;
|
|
789
|
-
if (!('clipPath' in node.props))
|
|
790
|
-
return;
|
|
791
|
-
const value = node.props.clipPath;
|
|
792
|
-
if (value) {
|
|
793
|
-
const children = value.children || [];
|
|
794
|
-
children.forEach((child) => renderNode$1(ctx, child));
|
|
795
|
-
ctx.clip();
|
|
796
|
-
}
|
|
797
|
-
};
|
|
798
|
-
const drawChildren = (ctx, node) => {
|
|
799
|
-
const children = node.children || [];
|
|
800
|
-
children.forEach((child) => {
|
|
801
|
-
ctx.save();
|
|
802
|
-
clipPath(ctx, child);
|
|
803
|
-
drawNode(ctx, child);
|
|
804
|
-
drawChildren(ctx, child);
|
|
805
|
-
ctx.restore();
|
|
806
|
-
});
|
|
807
|
-
};
|
|
808
|
-
const resolveAspectRatio = (ctx, node) => {
|
|
809
|
-
if (!node.box)
|
|
810
|
-
return;
|
|
811
|
-
const { width, height } = node.box;
|
|
812
|
-
const { viewBox, preserveAspectRatio } = node.props;
|
|
813
|
-
const { meetOrSlice = 'meet', align = 'xMidYMid' } = preserveAspectRatio || {};
|
|
814
|
-
if (viewBox == null || width == null || height == null)
|
|
815
|
-
return;
|
|
816
|
-
const x = viewBox?.minX || 0;
|
|
817
|
-
const y = viewBox?.minY || 0;
|
|
818
|
-
const logicalWidth = viewBox?.maxX || width;
|
|
819
|
-
const logicalHeight = viewBox?.maxY || height;
|
|
820
|
-
const logicalRatio = logicalWidth / logicalHeight;
|
|
821
|
-
const physicalRatio = width / height;
|
|
822
|
-
const scaleX = width / logicalWidth;
|
|
823
|
-
const scaleY = height / logicalHeight;
|
|
824
|
-
if (align === 'none') {
|
|
825
|
-
ctx.scale(scaleX, scaleY);
|
|
826
|
-
ctx.translate(-x, -y);
|
|
827
|
-
return;
|
|
828
|
-
}
|
|
829
|
-
if ((logicalRatio < physicalRatio && meetOrSlice === 'meet') ||
|
|
830
|
-
(logicalRatio >= physicalRatio && meetOrSlice === 'slice')) {
|
|
831
|
-
ctx.scale(scaleY, scaleY);
|
|
832
|
-
switch (align) {
|
|
833
|
-
case 'xMinYMin':
|
|
834
|
-
case 'xMinYMid':
|
|
835
|
-
case 'xMinYMax':
|
|
836
|
-
ctx.translate(-x, -y);
|
|
837
|
-
break;
|
|
838
|
-
case 'xMidYMin':
|
|
839
|
-
case 'xMidYMid':
|
|
840
|
-
case 'xMidYMax':
|
|
841
|
-
ctx.translate(-x - (logicalWidth - (width * logicalHeight) / height) / 2, -y);
|
|
842
|
-
break;
|
|
843
|
-
default:
|
|
844
|
-
ctx.translate(-x - (logicalWidth - (width * logicalHeight) / height), -y);
|
|
845
|
-
}
|
|
846
|
-
}
|
|
847
|
-
else {
|
|
848
|
-
ctx.scale(scaleX, scaleX);
|
|
849
|
-
switch (align) {
|
|
850
|
-
case 'xMinYMin':
|
|
851
|
-
case 'xMidYMin':
|
|
852
|
-
case 'xMaxYMin':
|
|
853
|
-
ctx.translate(-x, -y);
|
|
854
|
-
break;
|
|
855
|
-
case 'xMinYMid':
|
|
856
|
-
case 'xMidYMid':
|
|
857
|
-
case 'xMaxYMid':
|
|
858
|
-
ctx.translate(-x, -y - (logicalHeight - (height * logicalWidth) / width) / 2);
|
|
859
|
-
break;
|
|
860
|
-
default:
|
|
861
|
-
ctx.translate(-x, -y - (logicalHeight - (height * logicalWidth) / width));
|
|
862
|
-
}
|
|
863
|
-
}
|
|
864
|
-
};
|
|
865
|
-
const moveToOrigin = (ctx, node) => {
|
|
866
|
-
if (!node.box)
|
|
867
|
-
return;
|
|
868
|
-
const { top, left } = node.box;
|
|
869
|
-
const paddingLeft = node.box.paddingLeft || 0;
|
|
870
|
-
const paddingTop = node.box.paddingTop || 0;
|
|
871
|
-
ctx.translate(left + paddingLeft, top + paddingTop);
|
|
872
|
-
};
|
|
873
|
-
const renderSvg = (ctx, node) => {
|
|
874
|
-
ctx.save();
|
|
875
|
-
clipNode(ctx, node);
|
|
876
|
-
moveToOrigin(ctx, node);
|
|
877
|
-
resolveAspectRatio(ctx, node);
|
|
878
|
-
drawChildren(ctx, node);
|
|
879
|
-
ctx.restore();
|
|
880
|
-
};
|
|
881
|
-
|
|
882
|
-
const black = { value: '#000', opacity: 1 };
|
|
883
|
-
// TODO: parse to number[] in layout to avoid this step
|
|
884
|
-
const parseColor = (hex) => {
|
|
885
|
-
if (!hex)
|
|
886
|
-
return black;
|
|
887
|
-
const parsed = colorString.get(hex);
|
|
888
|
-
if (!parsed)
|
|
889
|
-
return black;
|
|
890
|
-
const value = colorString.to.hex(parsed.value.slice(0, 3));
|
|
891
|
-
const opacity = parsed.value[3];
|
|
892
|
-
return { value, opacity };
|
|
893
|
-
};
|
|
894
|
-
|
|
895
|
-
const DEST_REGEXP = /^#.+/;
|
|
896
|
-
const isSrcId$1 = (src) => src.match(DEST_REGEXP);
|
|
897
|
-
const renderAttachment = (ctx, attachment) => {
|
|
898
|
-
const { xOffset = 0, yOffset = 0, width, height, image } = attachment;
|
|
899
|
-
ctx.translate(-width + xOffset, -height + yOffset);
|
|
900
|
-
ctx.image(image, 0, 0, {
|
|
901
|
-
fit: [width, height],
|
|
902
|
-
align: 'center',
|
|
903
|
-
valign: 'bottom',
|
|
904
|
-
});
|
|
905
|
-
};
|
|
906
|
-
const renderAttachments = (ctx, run) => {
|
|
907
|
-
if (!run.glyphs)
|
|
908
|
-
return;
|
|
909
|
-
if (!run.positions)
|
|
910
|
-
return;
|
|
911
|
-
const font = run.attributes.font?.[0];
|
|
912
|
-
if (!font)
|
|
913
|
-
return;
|
|
914
|
-
ctx.save();
|
|
915
|
-
const space = font.glyphForCodePoint(0x20);
|
|
916
|
-
const objectReplacement = font.glyphForCodePoint(0xfffc);
|
|
917
|
-
let attachmentAdvance = 0;
|
|
918
|
-
for (let i = 0; i < run.glyphs.length; i += 1) {
|
|
919
|
-
const position = run.positions[i];
|
|
920
|
-
const glyph = run.glyphs[i];
|
|
921
|
-
attachmentAdvance += position.xAdvance || 0;
|
|
922
|
-
if (glyph.id === objectReplacement.id && run.attributes.attachment) {
|
|
923
|
-
ctx.translate(attachmentAdvance, position.yOffset || 0);
|
|
924
|
-
renderAttachment(ctx, run.attributes.attachment);
|
|
925
|
-
run.glyphs[i] = space;
|
|
926
|
-
attachmentAdvance = 0;
|
|
927
|
-
}
|
|
928
|
-
}
|
|
929
|
-
ctx.restore();
|
|
930
|
-
};
|
|
931
|
-
const renderRun = (ctx, run) => {
|
|
932
|
-
if (!run.glyphs)
|
|
933
|
-
return;
|
|
934
|
-
if (!run.positions)
|
|
935
|
-
return;
|
|
936
|
-
const font = run.attributes.font?.[0];
|
|
937
|
-
if (!font)
|
|
938
|
-
return;
|
|
939
|
-
const { fontSize, link } = run.attributes;
|
|
940
|
-
const color = parseColor(run.attributes.color);
|
|
941
|
-
const opacity = isNil(run.attributes.opacity)
|
|
942
|
-
? color.opacity
|
|
943
|
-
: run.attributes.opacity;
|
|
944
|
-
const { height = 0, descent = 0, xAdvance = 0 } = run;
|
|
945
|
-
ctx.fillColor(color.value);
|
|
946
|
-
ctx.fillOpacity(opacity);
|
|
947
|
-
if (link) {
|
|
948
|
-
if (isSrcId$1(link)) {
|
|
949
|
-
ctx.goTo(0, -height - descent, xAdvance, height, link.slice(1));
|
|
950
|
-
}
|
|
951
|
-
else {
|
|
952
|
-
ctx.link(0, -height - descent, xAdvance, height, link);
|
|
953
|
-
}
|
|
954
|
-
}
|
|
955
|
-
renderAttachments(ctx, run);
|
|
956
|
-
ctx.font(font.type === 'STANDARD' ? font.fullName : font, fontSize);
|
|
957
|
-
try {
|
|
958
|
-
renderGlyphs(ctx, run.glyphs, run.positions, 0, 0);
|
|
959
|
-
}
|
|
960
|
-
catch (error) {
|
|
961
|
-
console.log(error);
|
|
962
|
-
}
|
|
963
|
-
ctx.translate(xAdvance, 0);
|
|
964
|
-
};
|
|
965
|
-
const renderBackground$1 = (ctx, rect, backgroundColor) => {
|
|
966
|
-
const color = parseColor(backgroundColor);
|
|
967
|
-
ctx.save();
|
|
968
|
-
ctx.fillOpacity(color.opacity);
|
|
969
|
-
ctx.rect(rect.x, rect.y, rect.width, rect.height);
|
|
970
|
-
ctx.fill(color.value);
|
|
971
|
-
ctx.restore();
|
|
972
|
-
};
|
|
973
|
-
const renderDecorationLine = (ctx, decorationLine) => {
|
|
974
|
-
ctx.save();
|
|
975
|
-
ctx.lineWidth(decorationLine.rect.height);
|
|
976
|
-
ctx.strokeOpacity(decorationLine.opacity);
|
|
977
|
-
if (/dashed/.test(decorationLine.style)) {
|
|
978
|
-
ctx.dash(3 * decorationLine.rect.height, {});
|
|
979
|
-
}
|
|
980
|
-
else if (/dotted/.test(decorationLine.style)) {
|
|
981
|
-
ctx.dash(decorationLine.rect.height, {});
|
|
982
|
-
}
|
|
983
|
-
if (/wavy/.test(decorationLine.style)) {
|
|
984
|
-
const dist = Math.max(2, decorationLine.rect.height);
|
|
985
|
-
let step = 1.1 * dist;
|
|
986
|
-
const stepCount = Math.floor(decorationLine.rect.width / (2 * step));
|
|
987
|
-
// Adjust step to fill entire width
|
|
988
|
-
const remainingWidth = decorationLine.rect.width - stepCount * 2 * step;
|
|
989
|
-
const adjustment = remainingWidth / stepCount / 2;
|
|
990
|
-
step += adjustment;
|
|
991
|
-
const cp1y = decorationLine.rect.y + dist;
|
|
992
|
-
const cp2y = decorationLine.rect.y - dist;
|
|
993
|
-
let { x } = decorationLine.rect;
|
|
994
|
-
ctx.moveTo(decorationLine.rect.x, decorationLine.rect.y);
|
|
995
|
-
for (let i = 0; i < stepCount; i += 1) {
|
|
996
|
-
ctx.bezierCurveTo(x + step, cp1y, x + step, cp2y, x + 2 * step, decorationLine.rect.y);
|
|
997
|
-
x += 2 * step;
|
|
998
|
-
}
|
|
999
|
-
}
|
|
1000
|
-
else {
|
|
1001
|
-
ctx.moveTo(decorationLine.rect.x, decorationLine.rect.y);
|
|
1002
|
-
ctx.lineTo(decorationLine.rect.x + decorationLine.rect.width, decorationLine.rect.y);
|
|
1003
|
-
if (/double/.test(decorationLine.style)) {
|
|
1004
|
-
ctx.moveTo(decorationLine.rect.x, decorationLine.rect.y + decorationLine.rect.height * 2);
|
|
1005
|
-
ctx.lineTo(decorationLine.rect.x + decorationLine.rect.width, decorationLine.rect.y + decorationLine.rect.height * 2);
|
|
1006
|
-
}
|
|
1007
|
-
}
|
|
1008
|
-
ctx.stroke(decorationLine.color);
|
|
1009
|
-
ctx.restore();
|
|
1010
|
-
};
|
|
1011
|
-
const renderLine = (ctx, line) => {
|
|
1012
|
-
if (!line.box)
|
|
1013
|
-
return;
|
|
1014
|
-
const lineAscent = line.ascent || 0;
|
|
1015
|
-
ctx.save();
|
|
1016
|
-
ctx.translate(line.box.x, line.box.y + lineAscent);
|
|
1017
|
-
for (let i = 0; i < line.runs.length; i += 1) {
|
|
1018
|
-
const run = line.runs[i];
|
|
1019
|
-
const isLastRun = i === line.runs.length - 1;
|
|
1020
|
-
if (run.attributes.backgroundColor) {
|
|
1021
|
-
const xAdvance = run.xAdvance ?? 0;
|
|
1022
|
-
const overflowRight = isLastRun ? line.overflowRight ?? 0 : 0;
|
|
1023
|
-
const backgroundRect = {
|
|
1024
|
-
x: 0,
|
|
1025
|
-
y: -lineAscent,
|
|
1026
|
-
height: line.box.height,
|
|
1027
|
-
width: xAdvance - overflowRight,
|
|
1028
|
-
};
|
|
1029
|
-
renderBackground$1(ctx, backgroundRect, run.attributes.backgroundColor);
|
|
1030
|
-
}
|
|
1031
|
-
renderRun(ctx, run);
|
|
1032
|
-
}
|
|
1033
|
-
ctx.restore();
|
|
1034
|
-
ctx.save();
|
|
1035
|
-
ctx.translate(line.box.x, line.box.y);
|
|
1036
|
-
if (line.decorationLines) {
|
|
1037
|
-
for (let i = 0; i < line.decorationLines.length; i += 1) {
|
|
1038
|
-
const decorationLine = line.decorationLines[i];
|
|
1039
|
-
renderDecorationLine(ctx, decorationLine);
|
|
1040
|
-
}
|
|
1041
|
-
}
|
|
1042
|
-
ctx.restore();
|
|
1043
|
-
};
|
|
1044
|
-
const renderBlock = (ctx, block) => {
|
|
1045
|
-
block.forEach((line) => {
|
|
1046
|
-
renderLine(ctx, line);
|
|
1047
|
-
});
|
|
1048
|
-
};
|
|
1049
|
-
const renderText = (ctx, node) => {
|
|
1050
|
-
if (!node.box)
|
|
1051
|
-
return;
|
|
1052
|
-
if (!node.lines)
|
|
1053
|
-
return;
|
|
1054
|
-
const { top, left } = node.box;
|
|
1055
|
-
const blocks = [node.lines];
|
|
1056
|
-
const paddingTop = node.box?.paddingTop || 0;
|
|
1057
|
-
const paddingLeft = node.box?.paddingLeft || 0;
|
|
1058
|
-
const initialY = node.lines[0] ? node.lines[0].box.y : 0;
|
|
1059
|
-
const offsetX = node.alignOffset || 0;
|
|
1060
|
-
ctx.save();
|
|
1061
|
-
ctx.translate(left + paddingLeft - offsetX, top + paddingTop - initialY);
|
|
1062
|
-
blocks.forEach((block) => {
|
|
1063
|
-
renderBlock(ctx, block);
|
|
1064
|
-
});
|
|
1065
|
-
ctx.restore();
|
|
1066
|
-
};
|
|
1067
|
-
|
|
1068
|
-
const renderPage = (ctx, node) => {
|
|
1069
|
-
if (!node.box)
|
|
1070
|
-
return;
|
|
1071
|
-
const { width, height } = node.box;
|
|
1072
|
-
const dpi = node.props?.dpi || 72;
|
|
1073
|
-
const userUnit = dpi / 72;
|
|
1074
|
-
ctx.addPage({ size: [width, height], margin: 0, userUnit });
|
|
1075
|
-
};
|
|
1076
|
-
|
|
1077
|
-
const renderNote = (ctx, node) => {
|
|
1078
|
-
if (!node.box)
|
|
1079
|
-
return;
|
|
1080
|
-
const { top, left } = node.box;
|
|
1081
|
-
const value = node?.children?.[0].value || '';
|
|
1082
|
-
const color = node.style?.backgroundColor;
|
|
1083
|
-
ctx.note(left, top, 0, 0, value, { color });
|
|
1084
|
-
};
|
|
1085
|
-
|
|
1086
|
-
const embedImage = (ctx, node) => {
|
|
1087
|
-
const src = node.image.data;
|
|
1088
|
-
let image;
|
|
1089
|
-
if (typeof src === 'string') {
|
|
1090
|
-
image = ctx._imageRegistry[src];
|
|
1091
|
-
}
|
|
1092
|
-
if (!image) {
|
|
1093
|
-
image = ctx.openImage(src);
|
|
1094
|
-
}
|
|
1095
|
-
if (!image.obj) {
|
|
1096
|
-
image.embed(ctx);
|
|
1097
|
-
}
|
|
1098
|
-
return image;
|
|
1099
|
-
};
|
|
1100
|
-
|
|
1101
|
-
const isNumeric = (n) => {
|
|
1102
|
-
return !Number.isNaN(parseFloat(n)) && Number.isFinite(n);
|
|
1103
|
-
};
|
|
1104
|
-
const applyContainObjectFit = (cw, ch, iw, ih, px, py) => {
|
|
1105
|
-
const cr = cw / ch;
|
|
1106
|
-
const ir = iw / ih;
|
|
1107
|
-
const pxp = matchPercent(px ?? null);
|
|
1108
|
-
const pyp = matchPercent(py ?? null);
|
|
1109
|
-
const pxv = pxp ? pxp.percent : 0.5;
|
|
1110
|
-
const pyv = pyp ? pyp.percent : 0.5;
|
|
1111
|
-
if (cr > ir) {
|
|
1112
|
-
const height = ch;
|
|
1113
|
-
const width = height * ir;
|
|
1114
|
-
const yOffset = isNumeric(py) ? py : 0;
|
|
1115
|
-
const xOffset = isNumeric(px) ? px : (cw - width) * pxv;
|
|
1116
|
-
return { width, height, xOffset, yOffset };
|
|
1117
|
-
}
|
|
1118
|
-
const width = cw;
|
|
1119
|
-
const height = width / ir;
|
|
1120
|
-
const xOffset = isNumeric(px) ? px : 0;
|
|
1121
|
-
const yOffset = isNumeric(py) ? py : (ch - height) * pyv;
|
|
1122
|
-
return { width, height, yOffset, xOffset };
|
|
1123
|
-
};
|
|
1124
|
-
const applyNoneObjectFit = (cw, ch, iw, ih, px, py) => {
|
|
1125
|
-
const width = iw;
|
|
1126
|
-
const height = ih;
|
|
1127
|
-
const pxp = matchPercent(px ?? null);
|
|
1128
|
-
const pyp = matchPercent(py ?? null);
|
|
1129
|
-
const pxv = pxp ? pxp.percent : 0.5;
|
|
1130
|
-
const pyv = pyp ? pyp.percent : 0.5;
|
|
1131
|
-
const xOffset = isNumeric(px) ? px : (cw - width) * pxv;
|
|
1132
|
-
const yOffset = isNumeric(py) ? py : (ch - height) * pyv;
|
|
1133
|
-
return { width, height, xOffset, yOffset };
|
|
1134
|
-
};
|
|
1135
|
-
const applyCoverObjectFit = (cw, ch, iw, ih, px, py) => {
|
|
1136
|
-
const ir = iw / ih;
|
|
1137
|
-
const cr = cw / ch;
|
|
1138
|
-
const pxp = matchPercent(px ?? null);
|
|
1139
|
-
const pyp = matchPercent(py ?? null);
|
|
1140
|
-
const pxv = pxp ? pxp.percent : 0.5;
|
|
1141
|
-
const pyv = pyp ? pyp.percent : 0.5;
|
|
1142
|
-
if (cr > ir) {
|
|
1143
|
-
const width = cw;
|
|
1144
|
-
const height = width / ir;
|
|
1145
|
-
const xOffset = isNumeric(px) ? px : 0;
|
|
1146
|
-
const yOffset = isNumeric(py) ? py : (ch - height) * pyv;
|
|
1147
|
-
return { width, height, yOffset, xOffset };
|
|
1148
|
-
}
|
|
1149
|
-
const height = ch;
|
|
1150
|
-
const width = height * ir;
|
|
1151
|
-
const xOffset = isNumeric(px) ? px : (cw - width) * pxv;
|
|
1152
|
-
const yOffset = isNumeric(py) ? py : 0;
|
|
1153
|
-
return { width, height, xOffset, yOffset };
|
|
1154
|
-
};
|
|
1155
|
-
const applyScaleDownObjectFit = (cw, ch, iw, ih, px, py) => {
|
|
1156
|
-
const containDimension = applyContainObjectFit(cw, ch, iw, ih, px, py);
|
|
1157
|
-
const noneDimension = applyNoneObjectFit(cw, ch, iw, ih, px, py);
|
|
1158
|
-
return containDimension.width < noneDimension.width
|
|
1159
|
-
? containDimension
|
|
1160
|
-
: noneDimension;
|
|
1161
|
-
};
|
|
1162
|
-
const applyFillObjectFit = (cw, ch, px, py) => {
|
|
1163
|
-
return {
|
|
1164
|
-
width: cw,
|
|
1165
|
-
height: ch,
|
|
1166
|
-
xOffset: matchPercent(px ?? null) ? 0 : px || 0,
|
|
1167
|
-
yOffset: matchPercent(py ?? null) ? 0 : py || 0,
|
|
1168
|
-
};
|
|
1169
|
-
};
|
|
1170
|
-
const resolveObjectFit = (type = 'fill', cw, ch, iw, ih, px, py) => {
|
|
1171
|
-
switch (type) {
|
|
1172
|
-
case 'contain':
|
|
1173
|
-
return applyContainObjectFit(cw, ch, iw, ih, px, py);
|
|
1174
|
-
case 'cover':
|
|
1175
|
-
return applyCoverObjectFit(cw, ch, iw, ih, px, py);
|
|
1176
|
-
case 'none':
|
|
1177
|
-
return applyNoneObjectFit(cw, ch, iw, ih, px, py);
|
|
1178
|
-
case 'scale-down':
|
|
1179
|
-
return applyScaleDownObjectFit(cw, ch, iw, ih, px, py);
|
|
1180
|
-
default:
|
|
1181
|
-
return applyFillObjectFit(cw, ch, px, py);
|
|
1182
|
-
}
|
|
1183
|
-
};
|
|
1184
|
-
|
|
1185
|
-
const drawImage = (ctx, node, options) => {
|
|
1186
|
-
if (!node.box)
|
|
1187
|
-
return;
|
|
1188
|
-
if (!node.image)
|
|
1189
|
-
return;
|
|
1190
|
-
const { left, top } = node.box;
|
|
1191
|
-
const opacity = node.style?.opacity;
|
|
1192
|
-
const objectFit = node.style?.objectFit;
|
|
1193
|
-
const objectPositionX = node.style?.objectPositionX;
|
|
1194
|
-
const objectPositionY = node.style?.objectPositionY;
|
|
1195
|
-
const paddingTop = node.box.paddingTop || 0;
|
|
1196
|
-
const paddingRight = node.box.paddingRight || 0;
|
|
1197
|
-
const paddingBottom = node.box.paddingBottom || 0;
|
|
1198
|
-
const paddingLeft = node.box.paddingLeft || 0;
|
|
1199
|
-
const imageCache = options.imageCache || new Map();
|
|
1200
|
-
const { width, height, xOffset, yOffset } = resolveObjectFit(objectFit, node.box.width - paddingLeft - paddingRight, node.box.height - paddingTop - paddingBottom, node.image.width, node.image.height, objectPositionX, objectPositionY);
|
|
1201
|
-
if (node.image.data) {
|
|
1202
|
-
if (width !== 0 && height !== 0) {
|
|
1203
|
-
const cacheKey = node.image.key;
|
|
1204
|
-
const image = imageCache.get(cacheKey) || embedImage(ctx, node);
|
|
1205
|
-
if (cacheKey)
|
|
1206
|
-
imageCache.set(cacheKey, image);
|
|
1207
|
-
const imageOpacity = isNil(opacity) ? 1 : opacity;
|
|
1208
|
-
ctx
|
|
1209
|
-
.fillOpacity(imageOpacity)
|
|
1210
|
-
.image(image, left + paddingLeft + xOffset, top + paddingTop + yOffset, {
|
|
1211
|
-
width,
|
|
1212
|
-
height,
|
|
1213
|
-
});
|
|
1214
|
-
}
|
|
1215
|
-
else {
|
|
1216
|
-
console.warn(`Image with src '${JSON.stringify(node.props.src || node.props.source)}' skipped due to invalid dimensions`);
|
|
1217
|
-
}
|
|
1218
|
-
}
|
|
1219
|
-
};
|
|
1220
|
-
const renderImage = (ctx, node, options) => {
|
|
1221
|
-
ctx.save();
|
|
1222
|
-
clipNode(ctx, node);
|
|
1223
|
-
drawImage(ctx, node, options);
|
|
1224
|
-
ctx.restore();
|
|
1225
|
-
};
|
|
1226
|
-
|
|
1227
|
-
const CONTENT_COLOR = '#a1c6e7';
|
|
1228
|
-
const PADDING_COLOR = '#c4deb9';
|
|
1229
|
-
const MARGIN_COLOR = '#f8cca1';
|
|
1230
|
-
// TODO: Draw debug boxes using clipping to enhance quality
|
|
1231
|
-
const debugContent = (ctx, node) => {
|
|
1232
|
-
if (!node.box)
|
|
1233
|
-
return;
|
|
1234
|
-
const { left, top, width, height, paddingLeft = 0, paddingTop = 0, paddingRight = 0, paddingBottom = 0, borderLeftWidth = 0, borderTopWidth = 0, borderRightWidth = 0, borderBottomWidth = 0, } = node.box;
|
|
1235
|
-
ctx
|
|
1236
|
-
.fillColor(CONTENT_COLOR)
|
|
1237
|
-
.opacity(0.5)
|
|
1238
|
-
.rect(left + paddingLeft + borderLeftWidth, top + paddingTop + borderTopWidth, width - paddingLeft - paddingRight - borderRightWidth - borderLeftWidth, height - paddingTop - paddingBottom - borderTopWidth - borderBottomWidth)
|
|
1239
|
-
.fill();
|
|
1240
|
-
};
|
|
1241
|
-
const debugPadding = (ctx, node) => {
|
|
1242
|
-
if (!node.box)
|
|
1243
|
-
return;
|
|
1244
|
-
const { left, top, width, height, paddingLeft = 0, paddingTop = 0, paddingRight = 0, paddingBottom = 0, borderLeftWidth = 0, borderTopWidth = 0, borderRightWidth = 0, borderBottomWidth = 0, } = node.box;
|
|
1245
|
-
ctx.fillColor(PADDING_COLOR).opacity(0.5);
|
|
1246
|
-
// Padding top
|
|
1247
|
-
ctx
|
|
1248
|
-
.rect(left + paddingLeft + borderLeftWidth, top + borderTopWidth, width - paddingRight - paddingLeft - borderLeftWidth - borderRightWidth, paddingTop)
|
|
1249
|
-
.fill();
|
|
1250
|
-
// Padding left
|
|
1251
|
-
ctx
|
|
1252
|
-
.rect(left + borderLeftWidth, top + borderTopWidth, paddingLeft, height - borderTopWidth - borderBottomWidth)
|
|
1253
|
-
.fill();
|
|
1254
|
-
// Padding right
|
|
1255
|
-
ctx
|
|
1256
|
-
.rect(left + width - paddingRight - borderRightWidth, top + borderTopWidth, paddingRight, height - borderTopWidth - borderBottomWidth)
|
|
1257
|
-
.fill();
|
|
1258
|
-
// Padding bottom
|
|
1259
|
-
ctx
|
|
1260
|
-
.rect(left + paddingLeft + borderLeftWidth, top + height - paddingBottom - borderBottomWidth, width - paddingRight - paddingLeft - borderLeftWidth - borderRightWidth, paddingBottom)
|
|
1261
|
-
.fill();
|
|
1262
|
-
};
|
|
1263
|
-
const debugMargin = (ctx, node) => {
|
|
1264
|
-
if (!node.box)
|
|
1265
|
-
return;
|
|
1266
|
-
const { left, top, width, height } = node.box;
|
|
1267
|
-
const { marginLeft = 0, marginTop = 0, marginRight = 0, marginBottom = 0, } = node.box;
|
|
1268
|
-
ctx.fillColor(MARGIN_COLOR).opacity(0.5);
|
|
1269
|
-
// Margin top
|
|
1270
|
-
ctx.rect(left, top - marginTop, width, marginTop).fill();
|
|
1271
|
-
// Margin left
|
|
1272
|
-
ctx
|
|
1273
|
-
.rect(left - marginLeft, top - marginTop, marginLeft, height + marginTop + marginBottom)
|
|
1274
|
-
.fill();
|
|
1275
|
-
// Margin right
|
|
1276
|
-
ctx
|
|
1277
|
-
.rect(left + width, top - marginTop, marginRight, height + marginTop + marginBottom)
|
|
1278
|
-
.fill();
|
|
1279
|
-
// Margin bottom
|
|
1280
|
-
ctx.rect(left, top + height, width, marginBottom).fill();
|
|
1281
|
-
};
|
|
1282
|
-
const debugText = (ctx, node) => {
|
|
1283
|
-
if (!node.box)
|
|
1284
|
-
return;
|
|
1285
|
-
const { left, top, width, height } = node.box;
|
|
1286
|
-
const { marginLeft = 0, marginTop = 0, marginRight = 0, marginBottom = 0, } = node.box;
|
|
1287
|
-
const roundedWidth = Math.round(width + marginLeft + marginRight);
|
|
1288
|
-
const roundedHeight = Math.round(height + marginTop + marginBottom);
|
|
1289
|
-
ctx
|
|
1290
|
-
.fontSize(6)
|
|
1291
|
-
.opacity(1)
|
|
1292
|
-
.fillColor('black')
|
|
1293
|
-
.text(`${roundedWidth} x ${roundedHeight}`, left - marginLeft, Math.max(top - marginTop - 4, 1), { width: Infinity });
|
|
1294
|
-
};
|
|
1295
|
-
const debugOrigin = (ctx, node) => {
|
|
1296
|
-
if (node.origin) {
|
|
1297
|
-
ctx
|
|
1298
|
-
.circle(node.origin.left, node.origin.top, 3)
|
|
1299
|
-
.fill('red')
|
|
1300
|
-
.circle(node.origin.left, node.origin.top, 5)
|
|
1301
|
-
.stroke('red');
|
|
1302
|
-
}
|
|
1303
|
-
};
|
|
1304
|
-
const renderDebug = (ctx, node) => {
|
|
1305
|
-
if (!node.props)
|
|
1306
|
-
return;
|
|
1307
|
-
if (!('debug' in node.props) || !node.props.debug)
|
|
1308
|
-
return;
|
|
1309
|
-
ctx.save();
|
|
1310
|
-
debugContent(ctx, node);
|
|
1311
|
-
debugPadding(ctx, node);
|
|
1312
|
-
debugMargin(ctx, node);
|
|
1313
|
-
debugText(ctx, node);
|
|
1314
|
-
debugOrigin(ctx, node);
|
|
1315
|
-
ctx.restore();
|
|
1316
|
-
};
|
|
1317
|
-
|
|
1318
|
-
const availableMethods = [
|
|
1319
|
-
'dash',
|
|
1320
|
-
'clip',
|
|
1321
|
-
'save',
|
|
1322
|
-
'path',
|
|
1323
|
-
'fill',
|
|
1324
|
-
'font',
|
|
1325
|
-
'text',
|
|
1326
|
-
'rect',
|
|
1327
|
-
'scale',
|
|
1328
|
-
'moveTo',
|
|
1329
|
-
'lineTo',
|
|
1330
|
-
'stroke',
|
|
1331
|
-
'rotate',
|
|
1332
|
-
'circle',
|
|
1333
|
-
'lineCap',
|
|
1334
|
-
'opacity',
|
|
1335
|
-
'ellipse',
|
|
1336
|
-
'polygon',
|
|
1337
|
-
'restore',
|
|
1338
|
-
'lineJoin',
|
|
1339
|
-
'fontSize',
|
|
1340
|
-
'fillColor',
|
|
1341
|
-
'lineWidth',
|
|
1342
|
-
'translate',
|
|
1343
|
-
'miterLimit',
|
|
1344
|
-
'strokeColor',
|
|
1345
|
-
'fillOpacity',
|
|
1346
|
-
'roundedRect',
|
|
1347
|
-
'fillAndStroke',
|
|
1348
|
-
'strokeOpacity',
|
|
1349
|
-
'bezierCurveTo',
|
|
1350
|
-
'quadraticCurveTo',
|
|
1351
|
-
'linearGradient',
|
|
1352
|
-
'radialGradient',
|
|
1353
|
-
];
|
|
1354
|
-
const painter = (ctx) => {
|
|
1355
|
-
const p = availableMethods.reduce((acc, prop) => ({
|
|
1356
|
-
...acc,
|
|
1357
|
-
[prop]: (...args) => {
|
|
1358
|
-
// @ts-expect-error ctx[prop] is a function
|
|
1359
|
-
ctx[prop](...args);
|
|
1360
|
-
return p;
|
|
1361
|
-
},
|
|
1362
|
-
}), {});
|
|
1363
|
-
return p;
|
|
1364
|
-
};
|
|
1365
|
-
const renderCanvas = (ctx, node) => {
|
|
1366
|
-
if (!node.box)
|
|
1367
|
-
return;
|
|
1368
|
-
const { top, left, width, height } = node.box;
|
|
1369
|
-
const paddingTop = node.box.paddingTop || 0;
|
|
1370
|
-
const paddingLeft = node.box.paddingLeft || 0;
|
|
1371
|
-
const paddingRight = node.box.paddingRight || 0;
|
|
1372
|
-
const paddingBottom = node.box.paddingBottom || 0;
|
|
1373
|
-
const availableWidth = width - paddingLeft - paddingRight;
|
|
1374
|
-
const availableHeight = height - paddingTop - paddingBottom;
|
|
1375
|
-
if (!availableWidth || !availableHeight) {
|
|
1376
|
-
console.warn('Canvas element has null width or height. Please provide valid values via the `style` prop in order to correctly render it.');
|
|
1377
|
-
}
|
|
1378
|
-
ctx.save().translate(left + paddingLeft, top + paddingTop);
|
|
1379
|
-
if (node.props.paint) {
|
|
1380
|
-
node.props.paint(painter(ctx), availableWidth, availableHeight);
|
|
1381
|
-
}
|
|
1382
|
-
ctx.restore();
|
|
1383
|
-
};
|
|
1384
|
-
|
|
1385
|
-
// Ref: https://www.w3.org/TR/css-backgrounds-3/#borders
|
|
1386
|
-
// This constant is used to approximate a symmetrical arc using a cubic Bezier curve.
|
|
1387
|
-
const KAPPA = 4.0 * ((Math.sqrt(2) - 1.0) / 3.0);
|
|
1388
|
-
const clipBorderTop = (ctx, layout, style, rtr, rtl) => {
|
|
1389
|
-
const { top, left, width, height } = layout;
|
|
1390
|
-
const { borderTopWidth, borderRightWidth, borderLeftWidth } = style;
|
|
1391
|
-
// Clip outer top border edge
|
|
1392
|
-
ctx.moveTo(left + rtl, top);
|
|
1393
|
-
ctx.lineTo(left + width - rtr, top);
|
|
1394
|
-
// Ellipse coefficients outer top right cap
|
|
1395
|
-
const c0 = rtr * (1.0 - KAPPA);
|
|
1396
|
-
// Clip outer top right cap
|
|
1397
|
-
ctx.bezierCurveTo(left + width - c0, top, left + width, top + c0, left + width, top + rtr);
|
|
1398
|
-
// Move down in case the margin exceedes the radius
|
|
1399
|
-
const topRightYCoord = top + Math.max(borderTopWidth, rtr);
|
|
1400
|
-
ctx.lineTo(left + width, topRightYCoord);
|
|
1401
|
-
// Clip inner top right cap
|
|
1402
|
-
ctx.lineTo(left + width - borderRightWidth, topRightYCoord);
|
|
1403
|
-
// Ellipse coefficients inner top right cap
|
|
1404
|
-
const innerTopRightRadiusX = Math.max(rtr - borderRightWidth, 0);
|
|
1405
|
-
const innerTopRightRadiusY = Math.max(rtr - borderTopWidth, 0);
|
|
1406
|
-
const c1 = innerTopRightRadiusX * (1.0 - KAPPA);
|
|
1407
|
-
const c2 = innerTopRightRadiusY * (1.0 - KAPPA);
|
|
1408
|
-
// Clip inner top right cap
|
|
1409
|
-
ctx.bezierCurveTo(left + width - borderRightWidth, top + borderTopWidth + c2, left + width - borderRightWidth - c1, top + borderTopWidth, left + width - borderRightWidth - innerTopRightRadiusX, top + borderTopWidth);
|
|
1410
|
-
// Clip inner top border edge
|
|
1411
|
-
ctx.lineTo(left + Math.max(rtl, borderLeftWidth), top + borderTopWidth);
|
|
1412
|
-
// Ellipse coefficients inner top left cap
|
|
1413
|
-
const innerTopLeftRadiusX = Math.max(rtl - borderLeftWidth, 0);
|
|
1414
|
-
const innerTopLeftRadiusY = Math.max(rtl - borderTopWidth, 0);
|
|
1415
|
-
const c3 = innerTopLeftRadiusX * (1.0 - KAPPA);
|
|
1416
|
-
const c4 = innerTopLeftRadiusY * (1.0 - KAPPA);
|
|
1417
|
-
const topLeftYCoord = top + Math.max(borderTopWidth, rtl);
|
|
1418
|
-
// Clip inner top left cap
|
|
1419
|
-
ctx.bezierCurveTo(left + borderLeftWidth + c3, top + borderTopWidth, left + borderLeftWidth, top + borderTopWidth + c4, left + borderLeftWidth, topLeftYCoord);
|
|
1420
|
-
ctx.lineTo(left, topLeftYCoord);
|
|
1421
|
-
// Move down in case the margin exceedes the radius
|
|
1422
|
-
ctx.lineTo(left, top + rtl);
|
|
1423
|
-
// Ellipse coefficients outer top left cap
|
|
1424
|
-
const c5 = rtl * (1.0 - KAPPA);
|
|
1425
|
-
// Clip outer top left cap
|
|
1426
|
-
ctx.bezierCurveTo(left, top + c5, left + c5, top, left + rtl, top);
|
|
1427
|
-
ctx.closePath();
|
|
1428
|
-
ctx.clip();
|
|
1429
|
-
// Clip border top cap joins
|
|
1430
|
-
if (borderRightWidth) {
|
|
1431
|
-
const trSlope = -borderTopWidth / borderRightWidth;
|
|
1432
|
-
ctx.moveTo(left + width / 2, trSlope * (-width / 2) + top);
|
|
1433
|
-
ctx.lineTo(left + width, top);
|
|
1434
|
-
ctx.lineTo(left, top);
|
|
1435
|
-
ctx.lineTo(left, top + height);
|
|
1436
|
-
ctx.closePath();
|
|
1437
|
-
ctx.clip();
|
|
1438
|
-
}
|
|
1439
|
-
if (borderLeftWidth) {
|
|
1440
|
-
const trSlope = -borderTopWidth / borderLeftWidth;
|
|
1441
|
-
ctx.moveTo(left + width / 2, trSlope * (-width / 2) + top);
|
|
1442
|
-
ctx.lineTo(left, top);
|
|
1443
|
-
ctx.lineTo(left + width, top);
|
|
1444
|
-
ctx.lineTo(left + width, top + height);
|
|
1445
|
-
ctx.closePath();
|
|
1446
|
-
ctx.clip();
|
|
1447
|
-
}
|
|
1448
|
-
};
|
|
1449
|
-
const fillBorderTop = (ctx, layout, style, rtr, rtl) => {
|
|
1450
|
-
const { top, left, width } = layout;
|
|
1451
|
-
const { borderTopColor, borderTopWidth, borderTopStyle, borderRightWidth, borderLeftWidth, } = style;
|
|
1452
|
-
const c0 = rtl * (1.0 - KAPPA);
|
|
1453
|
-
const c1 = rtr * (1.0 - KAPPA);
|
|
1454
|
-
ctx.moveTo(left, top + Math.max(rtl, borderTopWidth));
|
|
1455
|
-
ctx.bezierCurveTo(left, top + c0, left + c0, top, left + rtl, top);
|
|
1456
|
-
ctx.lineTo(left + width - rtr, top);
|
|
1457
|
-
ctx.bezierCurveTo(left + width - c1, top, left + width, top + c1, left + width, top + rtr);
|
|
1458
|
-
ctx.strokeColor(borderTopColor);
|
|
1459
|
-
ctx.lineWidth(Math.max(borderRightWidth, borderTopWidth, borderLeftWidth) * 2);
|
|
1460
|
-
if (borderTopStyle === 'dashed') {
|
|
1461
|
-
ctx.dash(borderTopWidth * 2, { space: borderTopWidth * 1.2 });
|
|
1462
|
-
}
|
|
1463
|
-
else if (borderTopStyle === 'dotted') {
|
|
1464
|
-
ctx.dash(borderTopWidth, { space: borderTopWidth * 1.2 });
|
|
1465
|
-
}
|
|
1466
|
-
ctx.stroke();
|
|
1467
|
-
ctx.undash();
|
|
1468
|
-
};
|
|
1469
|
-
const clipBorderRight = (ctx, layout, style, rtr, rbr) => {
|
|
1470
|
-
const { top, left, width, height } = layout;
|
|
1471
|
-
const { borderTopWidth, borderRightWidth, borderBottomWidth } = style;
|
|
1472
|
-
// Clip outer right border edge
|
|
1473
|
-
ctx.moveTo(left + width, top + rtr);
|
|
1474
|
-
ctx.lineTo(left + width, top + height - rbr);
|
|
1475
|
-
// Ellipse coefficients outer bottom right cap
|
|
1476
|
-
const c0 = rbr * (1.0 - KAPPA);
|
|
1477
|
-
// Clip outer top right cap
|
|
1478
|
-
ctx.bezierCurveTo(left + width, top + height - c0, left + width - c0, top + height, left + width - rbr, top + height);
|
|
1479
|
-
// Move left in case the margin exceedes the radius
|
|
1480
|
-
const topBottomXCoord = left + width - Math.max(borderRightWidth, rbr);
|
|
1481
|
-
ctx.lineTo(topBottomXCoord, top + height);
|
|
1482
|
-
// Clip inner bottom right cap
|
|
1483
|
-
ctx.lineTo(topBottomXCoord, top + height - borderBottomWidth);
|
|
1484
|
-
// Ellipse coefficients inner bottom right cap
|
|
1485
|
-
const innerBottomRightRadiusX = Math.max(rbr - borderRightWidth, 0);
|
|
1486
|
-
const innerBottomRightRadiusY = Math.max(rbr - borderBottomWidth, 0);
|
|
1487
|
-
const c1 = innerBottomRightRadiusX * (1.0 - KAPPA);
|
|
1488
|
-
const c2 = innerBottomRightRadiusY * (1.0 - KAPPA);
|
|
1489
|
-
// Clip inner top right cap
|
|
1490
|
-
ctx.bezierCurveTo(left + width - borderRightWidth - c1, top + height - borderBottomWidth, left + width - borderRightWidth, top + height - borderBottomWidth - c2, left + width - borderRightWidth, top + height - Math.max(rbr, borderBottomWidth));
|
|
1491
|
-
// Clip inner right border edge
|
|
1492
|
-
ctx.lineTo(left + width - borderRightWidth, top + Math.max(rtr, borderTopWidth));
|
|
1493
|
-
// Ellipse coefficients inner top right cap
|
|
1494
|
-
const innerTopRightRadiusX = Math.max(rtr - borderRightWidth, 0);
|
|
1495
|
-
const innerTopRightRadiusY = Math.max(rtr - borderTopWidth, 0);
|
|
1496
|
-
const c3 = innerTopRightRadiusX * (1.0 - KAPPA);
|
|
1497
|
-
const c4 = innerTopRightRadiusY * (1.0 - KAPPA);
|
|
1498
|
-
const topRightXCoord = left + width - Math.max(rtr, borderRightWidth);
|
|
1499
|
-
// Clip inner top left cap
|
|
1500
|
-
ctx.bezierCurveTo(left + width - borderRightWidth, top + borderTopWidth + c4, left + width - borderRightWidth - c3, top + borderTopWidth, topRightXCoord, top + borderTopWidth);
|
|
1501
|
-
ctx.lineTo(topRightXCoord, top);
|
|
1502
|
-
// Move right in case the margin exceedes the radius
|
|
1503
|
-
ctx.lineTo(left + width - rtr, top);
|
|
1504
|
-
// Ellipse coefficients outer top right cap
|
|
1505
|
-
const c5 = rtr * (1.0 - KAPPA);
|
|
1506
|
-
// Clip outer top right cap
|
|
1507
|
-
ctx.bezierCurveTo(left + width - c5, top, left + width, top + c5, left + width, top + rtr);
|
|
1508
|
-
ctx.closePath();
|
|
1509
|
-
ctx.clip();
|
|
1510
|
-
// Clip border right cap joins
|
|
1511
|
-
if (borderTopWidth) {
|
|
1512
|
-
const trSlope = -borderTopWidth / borderRightWidth;
|
|
1513
|
-
ctx.moveTo(left + width / 2, trSlope * (-width / 2) + top);
|
|
1514
|
-
ctx.lineTo(left + width, top);
|
|
1515
|
-
ctx.lineTo(left + width, top + height);
|
|
1516
|
-
ctx.lineTo(left, top + height);
|
|
1517
|
-
ctx.closePath();
|
|
1518
|
-
ctx.clip();
|
|
1519
|
-
}
|
|
1520
|
-
if (borderBottomWidth) {
|
|
1521
|
-
const brSlope = borderBottomWidth / borderRightWidth;
|
|
1522
|
-
ctx.moveTo(left + width / 2, brSlope * (-width / 2) + top + height);
|
|
1523
|
-
ctx.lineTo(left + width, top + height);
|
|
1524
|
-
ctx.lineTo(left + width, top);
|
|
1525
|
-
ctx.lineTo(left, top);
|
|
1526
|
-
ctx.closePath();
|
|
1527
|
-
ctx.clip();
|
|
1528
|
-
}
|
|
1529
|
-
};
|
|
1530
|
-
const fillBorderRight = (ctx, layout, style, rtr, rbr) => {
|
|
1531
|
-
const { top, left, width, height } = layout;
|
|
1532
|
-
const { borderRightColor, borderRightStyle, borderRightWidth, borderTopWidth, borderBottomWidth, } = style;
|
|
1533
|
-
const c0 = rbr * (1.0 - KAPPA);
|
|
1534
|
-
const c1 = rtr * (1.0 - KAPPA);
|
|
1535
|
-
ctx.moveTo(left + width - rtr, top);
|
|
1536
|
-
ctx.bezierCurveTo(left + width - c1, top, left + width, top + c1, left + width, top + rtr);
|
|
1537
|
-
ctx.lineTo(left + width, top + height - rbr);
|
|
1538
|
-
ctx.bezierCurveTo(left + width, top + height - c0, left + width - c0, top + height, left + width - rbr, top + height);
|
|
1539
|
-
ctx.strokeColor(borderRightColor);
|
|
1540
|
-
ctx.lineWidth(Math.max(borderRightWidth, borderTopWidth, borderBottomWidth) * 2);
|
|
1541
|
-
if (borderRightStyle === 'dashed') {
|
|
1542
|
-
ctx.dash(borderRightWidth * 2, { space: borderRightWidth * 1.2 });
|
|
1543
|
-
}
|
|
1544
|
-
else if (borderRightStyle === 'dotted') {
|
|
1545
|
-
ctx.dash(borderRightWidth, { space: borderRightWidth * 1.2 });
|
|
1546
|
-
}
|
|
1547
|
-
ctx.stroke();
|
|
1548
|
-
ctx.undash();
|
|
1549
|
-
};
|
|
1550
|
-
const clipBorderBottom = (ctx, layout, style, rbl, rbr) => {
|
|
1551
|
-
const { top, left, width, height } = layout;
|
|
1552
|
-
const { borderBottomWidth, borderRightWidth, borderLeftWidth } = style;
|
|
1553
|
-
// Clip outer top border edge
|
|
1554
|
-
ctx.moveTo(left + width - rbr, top + height);
|
|
1555
|
-
ctx.lineTo(left + rbl, top + height);
|
|
1556
|
-
// Ellipse coefficients outer top right cap
|
|
1557
|
-
const c0 = rbl * (1.0 - KAPPA);
|
|
1558
|
-
// Clip outer top right cap
|
|
1559
|
-
ctx.bezierCurveTo(left + c0, top + height, left, top + height - c0, left, top + height - rbl);
|
|
1560
|
-
// Move up in case the margin exceedes the radius
|
|
1561
|
-
const bottomLeftYCoord = top + height - Math.max(borderBottomWidth, rbl);
|
|
1562
|
-
ctx.lineTo(left, bottomLeftYCoord);
|
|
1563
|
-
// Clip inner bottom left cap
|
|
1564
|
-
ctx.lineTo(left + borderLeftWidth, bottomLeftYCoord);
|
|
1565
|
-
// Ellipse coefficients inner top right cap
|
|
1566
|
-
const innerBottomLeftRadiusX = Math.max(rbl - borderLeftWidth, 0);
|
|
1567
|
-
const innerBottomLeftRadiusY = Math.max(rbl - borderBottomWidth, 0);
|
|
1568
|
-
const c1 = innerBottomLeftRadiusX * (1.0 - KAPPA);
|
|
1569
|
-
const c2 = innerBottomLeftRadiusY * (1.0 - KAPPA);
|
|
1570
|
-
// Clip inner bottom left cap
|
|
1571
|
-
ctx.bezierCurveTo(left + borderLeftWidth, top + height - borderBottomWidth - c2, left + borderLeftWidth + c1, top + height - borderBottomWidth, left + borderLeftWidth + innerBottomLeftRadiusX, top + height - borderBottomWidth);
|
|
1572
|
-
// Clip inner bottom border edge
|
|
1573
|
-
ctx.lineTo(left + width - Math.max(rbr, borderRightWidth), top + height - borderBottomWidth);
|
|
1574
|
-
// Ellipse coefficients inner top left cap
|
|
1575
|
-
const innerBottomRightRadiusX = Math.max(rbr - borderRightWidth, 0);
|
|
1576
|
-
const innerBottomRightRadiusY = Math.max(rbr - borderBottomWidth, 0);
|
|
1577
|
-
const c3 = innerBottomRightRadiusX * (1.0 - KAPPA);
|
|
1578
|
-
const c4 = innerBottomRightRadiusY * (1.0 - KAPPA);
|
|
1579
|
-
const bottomRightYCoord = top + height - Math.max(borderBottomWidth, rbr);
|
|
1580
|
-
// Clip inner top left cap
|
|
1581
|
-
ctx.bezierCurveTo(left + width - borderRightWidth - c3, top + height - borderBottomWidth, left + width - borderRightWidth, top + height - borderBottomWidth - c4, left + width - borderRightWidth, bottomRightYCoord);
|
|
1582
|
-
ctx.lineTo(left + width, bottomRightYCoord);
|
|
1583
|
-
// Move down in case the margin exceedes the radius
|
|
1584
|
-
ctx.lineTo(left + width, top + height - rbr);
|
|
1585
|
-
// Ellipse coefficients outer top left cap
|
|
1586
|
-
const c5 = rbr * (1.0 - KAPPA);
|
|
1587
|
-
// Clip outer top left cap
|
|
1588
|
-
ctx.bezierCurveTo(left + width, top + height - c5, left + width - c5, top + height, left + width - rbr, top + height);
|
|
1589
|
-
ctx.closePath();
|
|
1590
|
-
ctx.clip();
|
|
1591
|
-
// Clip border bottom cap joins
|
|
1592
|
-
if (borderRightWidth) {
|
|
1593
|
-
const brSlope = borderBottomWidth / borderRightWidth;
|
|
1594
|
-
ctx.moveTo(left + width / 2, brSlope * (-width / 2) + top + height);
|
|
1595
|
-
ctx.lineTo(left + width, top + height);
|
|
1596
|
-
ctx.lineTo(left, top + height);
|
|
1597
|
-
ctx.lineTo(left, top);
|
|
1598
|
-
ctx.closePath();
|
|
1599
|
-
ctx.clip();
|
|
1600
|
-
}
|
|
1601
|
-
if (borderLeftWidth) {
|
|
1602
|
-
const trSlope = -borderBottomWidth / borderLeftWidth;
|
|
1603
|
-
ctx.moveTo(left + width / 2, trSlope * (width / 2) + top + height);
|
|
1604
|
-
ctx.lineTo(left, top + height);
|
|
1605
|
-
ctx.lineTo(left + width, top + height);
|
|
1606
|
-
ctx.lineTo(left + width, top);
|
|
1607
|
-
ctx.closePath();
|
|
1608
|
-
ctx.clip();
|
|
1609
|
-
}
|
|
1610
|
-
};
|
|
1611
|
-
const fillBorderBottom = (ctx, layout, style, rbl, rbr) => {
|
|
1612
|
-
const { top, left, width, height } = layout;
|
|
1613
|
-
const { borderBottomColor, borderBottomStyle, borderBottomWidth, borderRightWidth, borderLeftWidth, } = style;
|
|
1614
|
-
const c0 = rbl * (1.0 - KAPPA);
|
|
1615
|
-
const c1 = rbr * (1.0 - KAPPA);
|
|
1616
|
-
ctx.moveTo(left + width, top + height - rbr);
|
|
1617
|
-
ctx.bezierCurveTo(left + width, top + height - c1, left + width - c1, top + height, left + width - rbr, top + height);
|
|
1618
|
-
ctx.lineTo(left + rbl, top + height);
|
|
1619
|
-
ctx.bezierCurveTo(left + c0, top + height, left, top + height - c0, left, top + height - rbl);
|
|
1620
|
-
ctx.strokeColor(borderBottomColor);
|
|
1621
|
-
ctx.lineWidth(Math.max(borderBottomWidth, borderRightWidth, borderLeftWidth) * 2);
|
|
1622
|
-
if (borderBottomStyle === 'dashed') {
|
|
1623
|
-
ctx.dash(borderBottomWidth * 2, { space: borderBottomWidth * 1.2 });
|
|
1624
|
-
}
|
|
1625
|
-
else if (borderBottomStyle === 'dotted') {
|
|
1626
|
-
ctx.dash(borderBottomWidth, { space: borderBottomWidth * 1.2 });
|
|
1627
|
-
}
|
|
1628
|
-
ctx.stroke();
|
|
1629
|
-
ctx.undash();
|
|
1630
|
-
};
|
|
1631
|
-
const clipBorderLeft = (ctx, layout, style, rbl, rtl) => {
|
|
1632
|
-
const { top, left, width, height } = layout;
|
|
1633
|
-
const { borderTopWidth, borderLeftWidth, borderBottomWidth } = style;
|
|
1634
|
-
// Clip outer left border edge
|
|
1635
|
-
ctx.moveTo(left, top + height - rbl);
|
|
1636
|
-
ctx.lineTo(left, top + rtl);
|
|
1637
|
-
// Ellipse coefficients outer top left cap
|
|
1638
|
-
const c0 = rtl * (1.0 - KAPPA);
|
|
1639
|
-
// Clip outer top left cap
|
|
1640
|
-
ctx.bezierCurveTo(left, top + c0, left + c0, top, left + rtl, top);
|
|
1641
|
-
// Move right in case the margin exceedes the radius
|
|
1642
|
-
const topLeftCoordX = left + Math.max(borderLeftWidth, rtl);
|
|
1643
|
-
ctx.lineTo(topLeftCoordX, top);
|
|
1644
|
-
// Clip inner top left cap
|
|
1645
|
-
ctx.lineTo(topLeftCoordX, top + borderTopWidth);
|
|
1646
|
-
// Ellipse coefficients inner top left cap
|
|
1647
|
-
const innerTopLeftRadiusX = Math.max(rtl - borderLeftWidth, 0);
|
|
1648
|
-
const innerTopLeftRadiusY = Math.max(rtl - borderTopWidth, 0);
|
|
1649
|
-
const c1 = innerTopLeftRadiusX * (1.0 - KAPPA);
|
|
1650
|
-
const c2 = innerTopLeftRadiusY * (1.0 - KAPPA);
|
|
1651
|
-
// Clip inner top right cap
|
|
1652
|
-
ctx.bezierCurveTo(left + borderLeftWidth + c1, top + borderTopWidth, left + borderLeftWidth, top + borderTopWidth + c2, left + borderLeftWidth, top + Math.max(rtl, borderTopWidth));
|
|
1653
|
-
// Clip inner left border edge
|
|
1654
|
-
ctx.lineTo(left + borderLeftWidth, top + height - Math.max(rbl, borderBottomWidth));
|
|
1655
|
-
// Ellipse coefficients inner bottom left cap
|
|
1656
|
-
const innerBottomLeftRadiusX = Math.max(rbl - borderLeftWidth, 0);
|
|
1657
|
-
const innerBottomLeftRadiusY = Math.max(rbl - borderBottomWidth, 0);
|
|
1658
|
-
const c3 = innerBottomLeftRadiusX * (1.0 - KAPPA);
|
|
1659
|
-
const c4 = innerBottomLeftRadiusY * (1.0 - KAPPA);
|
|
1660
|
-
const bottomLeftXCoord = left + Math.max(rbl, borderLeftWidth);
|
|
1661
|
-
// Clip inner top left cap
|
|
1662
|
-
ctx.bezierCurveTo(left + borderLeftWidth, top + height - borderBottomWidth - c4, left + borderLeftWidth + c3, top + height - borderBottomWidth, bottomLeftXCoord, top + height - borderBottomWidth);
|
|
1663
|
-
ctx.lineTo(bottomLeftXCoord, top + height);
|
|
1664
|
-
// Move left in case the margin exceedes the radius
|
|
1665
|
-
ctx.lineTo(left + rbl, top + height);
|
|
1666
|
-
// Ellipse coefficients outer top right cap
|
|
1667
|
-
const c5 = rbl * (1.0 - KAPPA);
|
|
1668
|
-
// Clip outer top right cap
|
|
1669
|
-
ctx.bezierCurveTo(left + c5, top + height, left, top + height - c5, left, top + height - rbl);
|
|
1670
|
-
ctx.closePath();
|
|
1671
|
-
ctx.clip();
|
|
1672
|
-
// Clip border right cap joins
|
|
1673
|
-
if (borderBottomWidth) {
|
|
1674
|
-
const trSlope = -borderBottomWidth / borderLeftWidth;
|
|
1675
|
-
ctx.moveTo(left + width / 2, trSlope * (width / 2) + top + height);
|
|
1676
|
-
ctx.lineTo(left, top + height);
|
|
1677
|
-
ctx.lineTo(left, top);
|
|
1678
|
-
ctx.lineTo(left + width, top);
|
|
1679
|
-
ctx.closePath();
|
|
1680
|
-
ctx.clip();
|
|
1681
|
-
}
|
|
1682
|
-
if (borderBottomWidth) {
|
|
1683
|
-
const trSlope = -borderTopWidth / borderLeftWidth;
|
|
1684
|
-
ctx.moveTo(left + width / 2, trSlope * (-width / 2) + top);
|
|
1685
|
-
ctx.lineTo(left, top);
|
|
1686
|
-
ctx.lineTo(left, top + height);
|
|
1687
|
-
ctx.lineTo(left + width, top + height);
|
|
1688
|
-
ctx.closePath();
|
|
1689
|
-
ctx.clip();
|
|
1690
|
-
}
|
|
1691
|
-
};
|
|
1692
|
-
const fillBorderLeft = (ctx, layout, style, rbl, rtl) => {
|
|
1693
|
-
const { top, left, height } = layout;
|
|
1694
|
-
const { borderLeftColor, borderLeftStyle, borderLeftWidth, borderTopWidth, borderBottomWidth, } = style;
|
|
1695
|
-
const c0 = rbl * (1.0 - KAPPA);
|
|
1696
|
-
const c1 = rtl * (1.0 - KAPPA);
|
|
1697
|
-
ctx.moveTo(left + rbl, top + height);
|
|
1698
|
-
ctx.bezierCurveTo(left + c0, top + height, left, top + height - c0, left, top + height - rbl);
|
|
1699
|
-
ctx.lineTo(left, top + rtl);
|
|
1700
|
-
ctx.bezierCurveTo(left, top + c1, left + c1, top, left + rtl, top);
|
|
1701
|
-
ctx.strokeColor(borderLeftColor);
|
|
1702
|
-
ctx.lineWidth(Math.max(borderLeftWidth, borderTopWidth, borderBottomWidth) * 2);
|
|
1703
|
-
if (borderLeftStyle === 'dashed') {
|
|
1704
|
-
ctx.dash(borderLeftWidth * 2, { space: borderLeftWidth * 1.2 });
|
|
1705
|
-
}
|
|
1706
|
-
else if (borderLeftStyle === 'dotted') {
|
|
1707
|
-
ctx.dash(borderLeftWidth, { space: borderLeftWidth * 1.2 });
|
|
1708
|
-
}
|
|
1709
|
-
ctx.stroke();
|
|
1710
|
-
ctx.undash();
|
|
1711
|
-
};
|
|
1712
|
-
const shouldRenderBorders = (node) => node.box &&
|
|
1713
|
-
(node.box.borderTopWidth ||
|
|
1714
|
-
node.box.borderRightWidth ||
|
|
1715
|
-
node.box.borderBottomWidth ||
|
|
1716
|
-
node.box.borderLeftWidth);
|
|
1717
|
-
const renderBorders = (ctx, node) => {
|
|
1718
|
-
if (!node.box)
|
|
1719
|
-
return;
|
|
1720
|
-
if (!shouldRenderBorders(node))
|
|
1721
|
-
return;
|
|
1722
|
-
const { width, height, borderTopWidth = 0, borderLeftWidth = 0, borderRightWidth = 0, borderBottomWidth = 0, } = node.box;
|
|
1723
|
-
const { opacity = 1, borderTopColor = 'black', borderTopStyle = 'solid', borderLeftColor = 'black', borderLeftStyle = 'solid', borderRightColor = 'black', borderRightStyle = 'solid', borderBottomColor = 'black', borderBottomStyle = 'solid', } = node.style;
|
|
1724
|
-
// @ts-expect-error this is always a number due to resolve border radius step
|
|
1725
|
-
const borderTopLeftRadius = node.style.borderTopLeftRadius || 0;
|
|
1726
|
-
// @ts-expect-error this is always a number due to resolve border radius step
|
|
1727
|
-
const borderTopRightRadius = node.style.borderTopRightRadius || 0;
|
|
1728
|
-
// @ts-expect-error this is always a number due to resolve border radius step
|
|
1729
|
-
const borderBottomLeftRadius = node.style.borderBottomLeftRadius || 0;
|
|
1730
|
-
// @ts-expect-error this is always a number due to resolve border radius step
|
|
1731
|
-
const borderBottomRightRadius = node.style.borderBottomRightRadius || 0;
|
|
1732
|
-
const style = {
|
|
1733
|
-
borderTopColor,
|
|
1734
|
-
borderTopWidth,
|
|
1735
|
-
borderTopStyle,
|
|
1736
|
-
borderLeftColor,
|
|
1737
|
-
borderLeftWidth,
|
|
1738
|
-
borderLeftStyle,
|
|
1739
|
-
borderRightColor,
|
|
1740
|
-
borderRightWidth,
|
|
1741
|
-
borderRightStyle,
|
|
1742
|
-
borderBottomColor,
|
|
1743
|
-
borderBottomWidth,
|
|
1744
|
-
borderBottomStyle};
|
|
1745
|
-
const rtr = Math.min(borderTopRightRadius, 0.5 * width, 0.5 * height);
|
|
1746
|
-
const rtl = Math.min(borderTopLeftRadius, 0.5 * width, 0.5 * height);
|
|
1747
|
-
const rbr = Math.min(borderBottomRightRadius, 0.5 * width, 0.5 * height);
|
|
1748
|
-
const rbl = Math.min(borderBottomLeftRadius, 0.5 * width, 0.5 * height);
|
|
1749
|
-
ctx.save();
|
|
1750
|
-
ctx.strokeOpacity(opacity);
|
|
1751
|
-
if (borderTopWidth) {
|
|
1752
|
-
ctx.save();
|
|
1753
|
-
clipBorderTop(ctx, node.box, style, rtr, rtl);
|
|
1754
|
-
fillBorderTop(ctx, node.box, style, rtr, rtl);
|
|
1755
|
-
ctx.restore();
|
|
1756
|
-
}
|
|
1757
|
-
if (borderRightWidth) {
|
|
1758
|
-
ctx.save();
|
|
1759
|
-
clipBorderRight(ctx, node.box, style, rtr, rbr);
|
|
1760
|
-
fillBorderRight(ctx, node.box, style, rtr, rbr);
|
|
1761
|
-
ctx.restore();
|
|
1762
|
-
}
|
|
1763
|
-
if (borderBottomWidth) {
|
|
1764
|
-
ctx.save();
|
|
1765
|
-
clipBorderBottom(ctx, node.box, style, rbl, rbr);
|
|
1766
|
-
fillBorderBottom(ctx, node.box, style, rbl, rbr);
|
|
1767
|
-
ctx.restore();
|
|
1768
|
-
}
|
|
1769
|
-
if (borderLeftWidth) {
|
|
1770
|
-
ctx.save();
|
|
1771
|
-
clipBorderLeft(ctx, node.box, style, rbl, rtl);
|
|
1772
|
-
fillBorderLeft(ctx, node.box, style, rbl, rtl);
|
|
1773
|
-
ctx.restore();
|
|
1774
|
-
}
|
|
1775
|
-
ctx.restore();
|
|
1776
|
-
};
|
|
1777
|
-
|
|
1778
|
-
const drawBackground = (ctx, node) => {
|
|
1779
|
-
if (!node.box)
|
|
1780
|
-
return;
|
|
1781
|
-
const { top, left, width, height } = node.box;
|
|
1782
|
-
const color = parseColor(node.style.backgroundColor);
|
|
1783
|
-
const nodeOpacity = isNil(node.style?.opacity) ? 1 : node.style.opacity;
|
|
1784
|
-
const opacity = Math.min(color.opacity, nodeOpacity);
|
|
1785
|
-
ctx
|
|
1786
|
-
.fillOpacity(opacity)
|
|
1787
|
-
.fillColor(color.value)
|
|
1788
|
-
.rect(left, top, width, height)
|
|
1789
|
-
.fill();
|
|
1790
|
-
};
|
|
1791
|
-
const renderBackground = (ctx, node) => {
|
|
1792
|
-
const hasBackground = !!node.box && !!node.style?.backgroundColor;
|
|
1793
|
-
if (hasBackground) {
|
|
1794
|
-
ctx.save();
|
|
1795
|
-
clipNode(ctx, node);
|
|
1796
|
-
drawBackground(ctx, node);
|
|
1797
|
-
ctx.restore();
|
|
1798
|
-
}
|
|
1799
|
-
};
|
|
1800
|
-
|
|
1801
|
-
const isString = (value) => typeof value === 'string';
|
|
1802
|
-
const isSrcId = (value) => /^#.+/.test(value);
|
|
1803
|
-
const renderLink = (ctx, node, src) => {
|
|
1804
|
-
if (!src || !node.box)
|
|
1805
|
-
return;
|
|
1806
|
-
const isId = isSrcId(src);
|
|
1807
|
-
const method = isId ? 'goTo' : 'link';
|
|
1808
|
-
const value = isId ? src.slice(1) : src;
|
|
1809
|
-
const { top, left, width, height } = node.box;
|
|
1810
|
-
ctx[method](left, top, width, height, value);
|
|
1811
|
-
};
|
|
1812
|
-
const setLink = (ctx, node) => {
|
|
1813
|
-
const props = node.props || {};
|
|
1814
|
-
if ('src' in props && isString(props.src))
|
|
1815
|
-
return renderLink(ctx, node, props.src);
|
|
1816
|
-
if ('href' in props && isString(props.href))
|
|
1817
|
-
return renderLink(ctx, node, props.href);
|
|
1818
|
-
};
|
|
1819
|
-
|
|
1820
|
-
const setDestination = (ctx, node) => {
|
|
1821
|
-
if (!node.box)
|
|
1822
|
-
return;
|
|
1823
|
-
if (!node.props)
|
|
1824
|
-
return;
|
|
1825
|
-
if ('id' in node.props) {
|
|
1826
|
-
ctx.addNamedDestination(node.props.id, 'XYZ', null, node.box.top, null);
|
|
1827
|
-
}
|
|
1828
|
-
};
|
|
1829
|
-
|
|
1830
|
-
const clean = (options) => {
|
|
1831
|
-
const opt = { ...options };
|
|
1832
|
-
// We need to ensure the elements are no present if not true
|
|
1833
|
-
Object.entries(opt).forEach((pair) => {
|
|
1834
|
-
if (!pair[1]) {
|
|
1835
|
-
delete opt[pair[0]];
|
|
1836
|
-
}
|
|
1837
|
-
});
|
|
1838
|
-
return opt;
|
|
1839
|
-
};
|
|
1840
|
-
const parseCommonFormOptions = (node) => {
|
|
1841
|
-
// Common Options
|
|
1842
|
-
return {
|
|
1843
|
-
required: node.props?.required || false,
|
|
1844
|
-
noExport: node.props?.noExport || false,
|
|
1845
|
-
readOnly: node.props?.readOnly || false,
|
|
1846
|
-
value: node.props?.value || undefined,
|
|
1847
|
-
defaultValue: node.props?.defaultValue || undefined,
|
|
1848
|
-
};
|
|
1849
|
-
};
|
|
1850
|
-
const parseTextInputOptions = (node, fieldSet) => {
|
|
1851
|
-
return clean({
|
|
1852
|
-
...parseCommonFormOptions(node),
|
|
1853
|
-
parent: fieldSet || undefined,
|
|
1854
|
-
align: node.props?.align || 'left',
|
|
1855
|
-
multiline: node.props?.multiline || undefined,
|
|
1856
|
-
password: node.props?.password || false,
|
|
1857
|
-
noSpell: node.props?.noSpell || false,
|
|
1858
|
-
format: node.props?.format || undefined,
|
|
1859
|
-
fontSize: node.props?.fontSize || undefined,
|
|
1860
|
-
MaxLen: node.props?.maxLength || undefined,
|
|
1861
|
-
});
|
|
1862
|
-
};
|
|
1863
|
-
const parseSelectAndListFieldOptions = (node) => {
|
|
1864
|
-
return clean({
|
|
1865
|
-
...parseCommonFormOptions(node),
|
|
1866
|
-
sort: node.props?.sort || false,
|
|
1867
|
-
edit: node.props?.edit || false,
|
|
1868
|
-
multiSelect: node.props?.multiSelect || false,
|
|
1869
|
-
noSpell: node.props?.noSpell || false,
|
|
1870
|
-
select: node.props?.select || [''],
|
|
1871
|
-
});
|
|
1872
|
-
};
|
|
1873
|
-
const getAppearance = (ctx, codepoint, width, height) => {
|
|
1874
|
-
const appearance = ctx.ref({
|
|
1875
|
-
Type: 'XObject',
|
|
1876
|
-
Subtype: 'Form',
|
|
1877
|
-
BBox: [0, 0, width, height],
|
|
1878
|
-
Resources: {
|
|
1879
|
-
ProcSet: ['PDF', 'Text', 'ImageB', 'ImageC', 'ImageI'],
|
|
1880
|
-
Font: {
|
|
1881
|
-
ZaDi: ctx._acroform.fonts.ZaDi,
|
|
1882
|
-
},
|
|
1883
|
-
},
|
|
1884
|
-
});
|
|
1885
|
-
appearance.initDeflate();
|
|
1886
|
-
appearance.write(`/Tx BMC\nq\n/ZaDi ${height * 0.8} Tf\nBT\n${width * 0.45} ${height / 4} Td (${codepoint}) Tj\nET\nQ\nEMC`);
|
|
1887
|
-
appearance.end(null);
|
|
1888
|
-
return appearance;
|
|
1889
|
-
};
|
|
1890
|
-
const parseCheckboxOptions = (ctx, node, fieldSet) => {
|
|
1891
|
-
const { width, height } = node.box || {};
|
|
1892
|
-
const onOption = node.props?.onState || 'Yes';
|
|
1893
|
-
const offOption = node.props?.offState || 'Off';
|
|
1894
|
-
const xMark = node.props?.xMark || false;
|
|
1895
|
-
if (!Object.prototype.hasOwnProperty.call(ctx._acroform.fonts, 'ZaDi')) {
|
|
1896
|
-
const ref = ctx.ref({
|
|
1897
|
-
Type: 'Font',
|
|
1898
|
-
Subtype: 'Type1',
|
|
1899
|
-
BaseFont: 'ZapfDingbats',
|
|
1900
|
-
});
|
|
1901
|
-
ctx._acroform.fonts.ZaDi = ref;
|
|
1902
|
-
ref.end(null);
|
|
1903
|
-
}
|
|
1904
|
-
const normalAppearance = {
|
|
1905
|
-
[onOption]: getAppearance(ctx, xMark ? '8' : '4', width, height),
|
|
1906
|
-
[offOption]: getAppearance(ctx, xMark ? ' ' : '8', width, height),
|
|
1907
|
-
};
|
|
1908
|
-
return clean({
|
|
1909
|
-
...parseCommonFormOptions(node),
|
|
1910
|
-
backgroundColor: node.props?.backgroundColor || undefined,
|
|
1911
|
-
borderColor: node.props?.borderColor || undefined,
|
|
1912
|
-
parent: fieldSet || undefined,
|
|
1913
|
-
value: `/${node.props?.checked === true ? onOption : offOption}`,
|
|
1914
|
-
defaultValue: `/${node.props?.checked === true ? onOption : offOption}`,
|
|
1915
|
-
AS: node.props?.checked === true ? onOption : offOption,
|
|
1916
|
-
AP: { N: normalAppearance, D: normalAppearance },
|
|
1917
|
-
});
|
|
1918
|
-
};
|
|
1919
|
-
|
|
1920
|
-
const renderTextInput = (ctx, node, options) => {
|
|
1921
|
-
if (!node.box)
|
|
1922
|
-
return;
|
|
1923
|
-
const { top, left, width, height } = node.box;
|
|
1924
|
-
// Element's name
|
|
1925
|
-
const name = node.props?.name || '';
|
|
1926
|
-
const fieldSetOptions = options.fieldSets?.at(0);
|
|
1927
|
-
if (!ctx._root.data.AcroForm) {
|
|
1928
|
-
ctx.initForm();
|
|
1929
|
-
}
|
|
1930
|
-
ctx.formText(name, left, top, width, height, parseTextInputOptions(node, fieldSetOptions));
|
|
1931
|
-
};
|
|
1932
|
-
|
|
1933
|
-
const renderSelect = (ctx, node) => {
|
|
1934
|
-
if (!node.box)
|
|
1935
|
-
return;
|
|
1936
|
-
const { top, left, width, height } = node.box;
|
|
1937
|
-
// Element's name
|
|
1938
|
-
const name = node.props?.name || '';
|
|
1939
|
-
if (!ctx._root.data.AcroForm) {
|
|
1940
|
-
ctx.initForm();
|
|
1941
|
-
}
|
|
1942
|
-
ctx.formCombo(name, left, top, width, height, parseSelectAndListFieldOptions(node));
|
|
1943
|
-
};
|
|
1944
|
-
|
|
1945
|
-
const renderFieldSet = (ctx, node, options) => {
|
|
1946
|
-
const name = node.props?.name || '';
|
|
1947
|
-
if (!ctx._root.data.AcroForm) {
|
|
1948
|
-
ctx.initForm();
|
|
1949
|
-
}
|
|
1950
|
-
const formField = ctx.formField(name);
|
|
1951
|
-
const option = options;
|
|
1952
|
-
if (!option.fieldSets) {
|
|
1953
|
-
option.fieldSets = [formField];
|
|
1954
|
-
}
|
|
1955
|
-
else {
|
|
1956
|
-
option.fieldSets.push(formField);
|
|
1957
|
-
}
|
|
1958
|
-
};
|
|
1959
|
-
const cleanUpFieldSet = (_ctx, _node, options) => {
|
|
1960
|
-
options.fieldSets.pop();
|
|
1961
|
-
};
|
|
1962
|
-
|
|
1963
|
-
const renderList = (ctx, node) => {
|
|
1964
|
-
if (!node.box)
|
|
1965
|
-
return;
|
|
1966
|
-
const { top, left, width, height } = node.box || {};
|
|
1967
|
-
// Element's name
|
|
1968
|
-
const name = ('name' in node.props ? node.props.name || '' : '');
|
|
1969
|
-
if (!ctx._root.data.AcroForm) {
|
|
1970
|
-
ctx.initForm();
|
|
1971
|
-
}
|
|
1972
|
-
ctx.formList(name, left, top, width, height, parseSelectAndListFieldOptions(node));
|
|
1973
|
-
};
|
|
1974
|
-
|
|
1975
|
-
const renderCheckbox = (ctx, node, options) => {
|
|
1976
|
-
if (!node.box)
|
|
1977
|
-
return;
|
|
1978
|
-
const { top, left, width, height } = node.box;
|
|
1979
|
-
// Element's name
|
|
1980
|
-
const name = node.props?.name || '';
|
|
1981
|
-
const fieldSetOptions = options.fieldSets?.at(0);
|
|
1982
|
-
if (!ctx._root.data.AcroForm) {
|
|
1983
|
-
ctx.initForm();
|
|
1984
|
-
}
|
|
1985
|
-
ctx.formCheckbox(name, left, top, width, height, parseCheckboxOptions(ctx, node, fieldSetOptions));
|
|
1986
|
-
};
|
|
1987
|
-
|
|
1988
|
-
const isRecursiveNode = (node) => node.type !== Text && node.type !== Svg;
|
|
1989
|
-
const renderChildren = (ctx, node, options) => {
|
|
1990
|
-
ctx.save();
|
|
1991
|
-
if (node.box) {
|
|
1992
|
-
ctx.translate(node.box.left, node.box.top);
|
|
1993
|
-
}
|
|
1994
|
-
const children = node.children || [];
|
|
1995
|
-
const renderChild = (child) => renderNode(ctx, child, options);
|
|
1996
|
-
children.forEach(renderChild);
|
|
1997
|
-
ctx.restore();
|
|
1998
|
-
};
|
|
1999
|
-
const renderFns = {
|
|
2000
|
-
[Text]: renderText,
|
|
2001
|
-
[Note]: renderNote,
|
|
2002
|
-
[Image]: renderImage,
|
|
2003
|
-
[FieldSet]: renderFieldSet,
|
|
2004
|
-
[TextInput]: renderTextInput,
|
|
2005
|
-
[Select]: renderSelect,
|
|
2006
|
-
[Checkbox]: renderCheckbox,
|
|
2007
|
-
[List]: renderList,
|
|
2008
|
-
[Canvas]: renderCanvas,
|
|
2009
|
-
[Svg]: renderSvg,
|
|
2010
|
-
[Link]: setLink,
|
|
2011
|
-
};
|
|
2012
|
-
const cleanUpFns = {
|
|
2013
|
-
[FieldSet]: cleanUpFieldSet,
|
|
2014
|
-
};
|
|
2015
|
-
const renderNode = (ctx, node, options) => {
|
|
2016
|
-
const overflowHidden = node.style?.overflow === 'hidden';
|
|
2017
|
-
const shouldRenderChildren = isRecursiveNode(node);
|
|
2018
|
-
if (node.type === Page)
|
|
2019
|
-
renderPage(ctx, node);
|
|
2020
|
-
ctx.save();
|
|
2021
|
-
if (overflowHidden)
|
|
2022
|
-
clipNode(ctx, node);
|
|
2023
|
-
applyTransformations(ctx, node);
|
|
2024
|
-
renderBackground(ctx, node);
|
|
2025
|
-
renderBorders(ctx, node);
|
|
2026
|
-
const renderFn = renderFns[node.type];
|
|
2027
|
-
if (renderFn)
|
|
2028
|
-
renderFn(ctx, node, options);
|
|
2029
|
-
if (shouldRenderChildren)
|
|
2030
|
-
renderChildren(ctx, node, options);
|
|
2031
|
-
const cleanUpFn = cleanUpFns[node.type];
|
|
2032
|
-
if (cleanUpFn)
|
|
2033
|
-
cleanUpFn(ctx, node, options);
|
|
2034
|
-
setDestination(ctx, node);
|
|
2035
|
-
renderDebug(ctx, node);
|
|
2036
|
-
ctx.restore();
|
|
2037
|
-
};
|
|
2038
|
-
|
|
2039
|
-
const addNodeBookmark = (ctx, node, pageNumber, registry) => {
|
|
2040
|
-
if (!node.box)
|
|
2041
|
-
return;
|
|
2042
|
-
if (!node.props)
|
|
2043
|
-
return;
|
|
2044
|
-
if ('bookmark' in node.props && node.props.bookmark) {
|
|
2045
|
-
const bookmark = node.props.bookmark;
|
|
2046
|
-
const { title, parent, expanded, zoom, fit } = bookmark;
|
|
2047
|
-
const outline = registry[parent] || ctx.outline;
|
|
2048
|
-
const top = bookmark.top || node.box.top;
|
|
2049
|
-
const left = bookmark.left || node.box.left;
|
|
2050
|
-
const instance = outline.addItem(title, {
|
|
2051
|
-
pageNumber,
|
|
2052
|
-
expanded,
|
|
2053
|
-
top,
|
|
2054
|
-
left,
|
|
2055
|
-
zoom,
|
|
2056
|
-
fit,
|
|
2057
|
-
});
|
|
2058
|
-
registry[bookmark.ref] = instance;
|
|
2059
|
-
}
|
|
2060
|
-
if (!node.children)
|
|
2061
|
-
return;
|
|
2062
|
-
node.children.forEach((child) => addNodeBookmark(ctx, child, pageNumber, registry));
|
|
2063
|
-
};
|
|
2064
|
-
const addBookmarks = (ctx, root) => {
|
|
2065
|
-
const registry = {};
|
|
2066
|
-
const pages = root.children || [];
|
|
2067
|
-
pages.forEach((page, i) => {
|
|
2068
|
-
addNodeBookmark(ctx, page, i, registry);
|
|
2069
|
-
});
|
|
2070
|
-
};
|
|
2071
|
-
|
|
2072
|
-
const render = (ctx, doc) => {
|
|
2073
|
-
const pages = doc.children || [];
|
|
2074
|
-
const options = { imageCache: new Map(), fieldSets: [] };
|
|
2075
|
-
pages.forEach((page) => renderNode(ctx, page, options));
|
|
2076
|
-
addBookmarks(ctx, doc);
|
|
2077
|
-
ctx.end();
|
|
2078
|
-
return ctx;
|
|
2079
|
-
};
|
|
2080
|
-
|
|
2081
|
-
export { render as default };
|