pagyra-js 0.0.1
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/.eslintrc.json +30 -0
- package/CHANGELOG.md +13 -0
- package/README.md +275 -0
- package/UA_Styles_Chromium.md +93 -0
- package/_ext/woff2_conversion/brotli-decode.d.ts +139 -0
- package/_ext/woff2_conversion/brotli-encode.d.ts +129 -0
- package/_ext/woff2_conversion/brotli-port.d.ts +12 -0
- package/_ext/woff2_conversion/brotli-shared-dictionary.d.ts +25 -0
- package/_ext/woff2_conversion/brotli-types.d.ts +15 -0
- package/_ext/woff2_conversion/woff2-common.d.ts +37 -0
- package/_ext/woff2_conversion/woff2-decode.d.ts +32 -0
- package/_ext/woff2_conversion/woff2-encode.d.ts +31 -0
- package/_ext/woff2_conversion/woff2-output.d.ts +39 -0
- package/_ext/woff2_original_cpp/brotli/brotli.c +1559 -0
- package/_ext/woff2_original_cpp/brotli/brotli.md +116 -0
- package/_ext/woff2_original_cpp/brotli/decode.h +409 -0
- package/_ext/woff2_original_cpp/brotli/encode.h +505 -0
- package/_ext/woff2_original_cpp/brotli/port.h +302 -0
- package/_ext/woff2_original_cpp/brotli/shared_dictionary.h +100 -0
- package/_ext/woff2_original_cpp/brotli/types.h +83 -0
- package/_ext/woff2_original_cpp/cmake/FindBrotliDec.cmake +35 -0
- package/_ext/woff2_original_cpp/cmake/FindBrotliEnc.cmake +35 -0
- package/_ext/woff2_original_cpp/include/woff2/decode.h +36 -0
- package/_ext/woff2_original_cpp/include/woff2/encode.h +43 -0
- package/_ext/woff2_original_cpp/include/woff2/output.h +86 -0
- package/_ext/woff2_original_cpp/src/buffer.h +164 -0
- package/_ext/woff2_original_cpp/src/convert_woff2ttf_fuzzer.cc +13 -0
- package/_ext/woff2_original_cpp/src/convert_woff2ttf_fuzzer_new_entry.cc +12 -0
- package/_ext/woff2_original_cpp/src/file.h +30 -0
- package/_ext/woff2_original_cpp/src/font.cc +400 -0
- package/_ext/woff2_original_cpp/src/font.h +105 -0
- package/_ext/woff2_original_cpp/src/glyph.cc +383 -0
- package/_ext/woff2_original_cpp/src/glyph.h +71 -0
- package/_ext/woff2_original_cpp/src/normalize.cc +314 -0
- package/_ext/woff2_original_cpp/src/normalize.h +39 -0
- package/_ext/woff2_original_cpp/src/port.h +66 -0
- package/_ext/woff2_original_cpp/src/round.h +27 -0
- package/_ext/woff2_original_cpp/src/store_bytes.h +55 -0
- package/_ext/woff2_original_cpp/src/table_tags.cc +82 -0
- package/_ext/woff2_original_cpp/src/table_tags.h +30 -0
- package/_ext/woff2_original_cpp/src/transform.cc +430 -0
- package/_ext/woff2_original_cpp/src/transform.h +26 -0
- package/_ext/woff2_original_cpp/src/variable_length.cc +129 -0
- package/_ext/woff2_original_cpp/src/variable_length.h +30 -0
- package/_ext/woff2_original_cpp/src/woff2_common.cc +50 -0
- package/_ext/woff2_original_cpp/src/woff2_common.h +64 -0
- package/_ext/woff2_original_cpp/src/woff2_compress.cc +43 -0
- package/_ext/woff2_original_cpp/src/woff2_dec.cc +1398 -0
- package/_ext/woff2_original_cpp/src/woff2_decompress.cc +41 -0
- package/_ext/woff2_original_cpp/src/woff2_enc.cc +458 -0
- package/_ext/woff2_original_cpp/src/woff2_info.cc +142 -0
- package/_ext/woff2_original_cpp/src/woff2_out.cc +63 -0
- package/assets/fonts/ttf/arimo/Arimo-Bold.ttf +0 -0
- package/assets/fonts/ttf/arimo/Arimo-BoldItalic.ttf +0 -0
- package/assets/fonts/ttf/arimo/Arimo-Italic.ttf +0 -0
- package/assets/fonts/ttf/arimo/Arimo-Regular.ttf +0 -0
- package/assets/fonts/ttf/cinzeldecorative/CinzelDecorative-Black.ttf +0 -0
- package/assets/fonts/ttf/cinzeldecorative/CinzelDecorative-Bold.ttf +0 -0
- package/assets/fonts/ttf/cinzeldecorative/CinzelDecorative-Regular.ttf +0 -0
- package/assets/fonts/ttf/dejavu/DejaVuSans.ttf +0 -0
- package/assets/fonts/ttf/firecode/FiraCode-Bold.ttf +0 -0
- package/assets/fonts/ttf/firecode/FiraCode-Light.ttf +0 -0
- package/assets/fonts/ttf/firecode/FiraCode-Medium.ttf +0 -0
- package/assets/fonts/ttf/firecode/FiraCode-Regular.ttf +0 -0
- package/assets/fonts/ttf/firecode/FiraCode-SemiBold.ttf +0 -0
- package/assets/fonts/ttf/notoemoji/NotoEmoji-Bold.ttf +0 -0
- package/assets/fonts/ttf/notoemoji/NotoEmoji-Light.ttf +0 -0
- package/assets/fonts/ttf/notoemoji/NotoEmoji-Medium.ttf +0 -0
- package/assets/fonts/ttf/notoemoji/NotoEmoji-Regular.ttf +0 -0
- package/assets/fonts/ttf/notoemoji/NotoEmoji-SemiBold.ttf +0 -0
- package/assets/fonts/ttf/notosans/NotoSans-Regular.ttf +0 -0
- package/assets/fonts/ttf/roboto/Roboto-Bold.ttf +0 -0
- package/assets/fonts/ttf/roboto/Roboto-BoldItalic.ttf +0 -0
- package/assets/fonts/ttf/roboto/Roboto-Italic.ttf +0 -0
- package/assets/fonts/ttf/roboto/Roboto-Regular.ttf +0 -0
- package/assets/fonts/ttf/stixtwomath/STIXTwoMath-Regular.ttf +0 -0
- package/assets/fonts/ttf/tinos/Tinos-Bold.ttf +0 -0
- package/assets/fonts/ttf/tinos/Tinos-BoldItalic.ttf +0 -0
- package/assets/fonts/ttf/tinos/Tinos-Italic.ttf +0 -0
- package/assets/fonts/ttf/tinos/Tinos-Regular.ttf +0 -0
- package/assets/fonts/woff/lato/lato-latin-400-italic.woff +0 -0
- package/assets/fonts/woff/lato/lato-latin-400-normal.woff +0 -0
- package/assets/fonts/woff/lato/lato-latin-700-italic.woff +0 -0
- package/assets/fonts/woff/lato/lato-latin-700-normal.woff +0 -0
- package/assets/fonts/woff2/caveat/Caveat-Bold.woff2 +0 -0
- package/assets/fonts/woff2/caveat/Caveat-Regular.woff2 +0 -0
- package/assets/fonts/woff2/lato/lato-latin-400-italic.woff2 +0 -0
- package/assets/fonts/woff2/lato/lato-latin-400-normal.woff2 +0 -0
- package/assets/fonts/woff2/lato/lato-latin-700-italic.woff2 +0 -0
- package/assets/fonts/woff2/lato/lato-latin-700-normal.woff2 +0 -0
- package/docs/AGENTS.md +288 -0
- package/docs/BACKGROUND-REPEAT-IMPLEMENTATION.md +127 -0
- package/docs/BACKGROUND-REPEAT-REFERENCE.md +127 -0
- package/docs/BACKGROUND-REPEAT-SPACE-ROUND.md +164 -0
- package/docs/css-properties-support.md +256 -0
- package/docs/src_modules_table.md +172 -0
- package/docs/text-overlap-fix.md +85 -0
- package/docs/text-overlap-investigation.md +27 -0
- package/eslint.config.js +36 -0
- package/glyph_measure.htm +1458 -0
- package/package.json +50 -0
- package/playground/browser-entry.ts +2 -0
- package/playground/exports/background-text-debug.pdf +0 -0
- package/playground/public/app.js +875 -0
- package/playground/public/assets/1.webp +0 -0
- package/playground/public/examples/accents-test.html +24 -0
- package/playground/public/examples/advanced-selectors-demo.html +118 -0
- package/playground/public/examples/background-advanced-showcase.html +82 -0
- package/playground/public/examples/background-clip-text.html +36 -0
- package/playground/public/examples/background-origin-showcase.html +137 -0
- package/playground/public/examples/background-position-showcase.html +83 -0
- package/playground/public/examples/background-repeat-showcase.html +83 -0
- package/playground/public/examples/background-repeat-space-round.html +348 -0
- package/playground/public/examples/background-size-showcase.html +82 -0
- package/playground/public/examples/background-text-debug.html +18 -0
- package/playground/public/examples/baseline-test.html +24 -0
- package/playground/public/examples/bold-showcase.html +150 -0
- package/playground/public/examples/bold-strike-example.html +12 -0
- package/playground/public/examples/border-collapse-test.html +23 -0
- package/playground/public/examples/centered-shadow-div.html +72 -0
- package/playground/public/examples/css-variables.html +50 -0
- package/playground/public/examples/debug-accents.html +11 -0
- package/playground/public/examples/debug-text-overlap.html +46 -0
- package/playground/public/examples/flex-gap-column.html +130 -0
- package/playground/public/examples/flex-gap-row.html +137 -0
- package/playground/public/examples/flex-padding-test.html +29 -0
- package/playground/public/examples/flexbox-text-test.html +193 -0
- package/playground/public/examples/fonts-demo.html +126 -0
- package/playground/public/examples/footer-example.html +4 -0
- package/playground/public/examples/gradient-text.html +54 -0
- package/playground/public/examples/grid-gap-demo.html +156 -0
- package/playground/public/examples/header-example.html +4 -0
- package/playground/public/examples/header-footer-example.html +27 -0
- package/playground/public/examples/image-showcase.html +33 -0
- package/playground/public/examples/justify-text.html +22 -0
- package/playground/public/examples/linear-gradient-example.html +38 -0
- package/playground/public/examples/lorem-span.html +14 -0
- package/playground/public/examples/margin-block-showcase.html +21 -0
- package/playground/public/examples/margin-inline-showcase.html +21 -0
- package/playground/public/examples/monthly-summary.html +95 -0
- package/playground/public/examples/multi-page-lorem.html +190 -0
- package/playground/public/examples/opacity-debug.html +39 -0
- package/playground/public/examples/opacity-example.html +70 -0
- package/playground/public/examples/png-image-example.html +13 -0
- package/playground/public/examples/red-rectangle.html +18 -0
- package/playground/public/examples/repro.html +24 -0
- package/playground/public/examples/rounded-borders-test.html +24 -0
- package/playground/public/examples/simple-list.html +89 -0
- package/playground/public/examples/simple-svg.html +37 -0
- package/playground/public/examples/simple-table.html +52 -0
- package/playground/public/examples/skew-div.html +138 -0
- package/playground/public/examples/skew-text.html +21 -0
- package/playground/public/examples/starter-report.css +51 -0
- package/playground/public/examples/starter-report.html +23 -0
- package/playground/public/examples/svg-aspect-ratio-showcase.html +116 -0
- package/playground/public/examples/svg-gradients-linear.html +28 -0
- package/playground/public/examples/svg-gradients-radial.html +29 -0
- package/playground/public/examples/svg-gradients-showcase.html +66 -0
- package/playground/public/examples/svg-image-path-test.html +43 -0
- package/playground/public/examples/svg-images-clipping.html +27 -0
- package/playground/public/examples/svg-path-gallery.html +118 -0
- package/playground/public/examples/svg-radial-transform-demo.html +78 -0
- package/playground/public/examples/svg-transform-stack.html +103 -0
- package/playground/public/examples/svg-transforms-demo.html +127 -0
- package/playground/public/examples/table-merge-test.html +34 -0
- package/playground/public/examples/text-decoration-showcase.html +138 -0
- package/playground/public/examples/text-indent-showcase.html +137 -0
- package/playground/public/examples/text-shadow-example.html +29 -0
- package/playground/public/examples/very-complex-css.html +293 -0
- package/playground/public/examples/webp-example.html +13 -0
- package/playground/public/examples/z-index-demo.html +93 -0
- package/playground/public/examples.json +240 -0
- package/playground/public/images/dice.png +0 -0
- package/playground/public/images/duck.jpg +0 -0
- package/playground/public/index.html +149 -0
- package/playground/public/mode.js +1 -0
- package/playground/public/styles.css +382 -0
- package/playground/public/tmp-h2-debug.html +33 -0
- package/playground/public/tmp-italic-debug.html +32 -0
- package/playground/public/vendor/codemirror/codemirror.min.css +1 -0
- package/playground/public/vendor/codemirror/codemirror.min.js +1 -0
- package/playground/public/vendor/codemirror/css.min.js +1 -0
- package/playground/public/vendor/codemirror/darcula.min.css +1 -0
- package/playground/public/vendor/codemirror/htmlmixed.min.js +1 -0
- package/playground/public/vendor/codemirror/javascript.min.js +1 -0
- package/playground/public/vendor/codemirror/xml.min.js +1 -0
- package/playground/public/vendor/pagyra-playground-browser.js +165966 -0
- package/playground/public/vendor/pagyra-playground-browser.js.map +7 -0
- package/playground/server.d.ts +1 -0
- package/playground/server.js +68 -0
- package/playground/server.ts +128 -0
- package/scripts/browser-build.ts +101 -0
- package/scripts/build-browser-bundle.ts +52 -0
- package/scripts/glyph-comparison/simulate.ts +744 -0
- package/scripts/playground-browser-server.ts +57 -0
- package/scripts/probe-roboto.ts +6 -0
- package/scripts/render-playground-example.ts +121 -0
- package/scripts/run-glyph-atlas-tuner-runner.mjs +113 -0
- package/scripts/run-glyph-atlas-tuner.ts +141 -0
- package/scripts/top-ts-files.ps1 +39 -0
- package/scripts/top-ts-files.sh +37 -0
- package/scripts/woff2_info.ps1 +132 -0
- package/src/browser-entry.ts +14 -0
- package/src/compression/adler32.ts +45 -0
- package/src/compression/brotli/brotli.ts +463 -0
- package/src/compression/brotli/index.ts +15 -0
- package/src/compression/brotli/transform.ts +184 -0
- package/src/compression/brotli/types.ts +58 -0
- package/src/compression/brotli/utils.ts +157 -0
- package/src/compression/brotli/vendor/bit_reader.js +124 -0
- package/src/compression/brotli/vendor/context.js +250 -0
- package/src/compression/brotli/vendor/decode.d.ts +2 -0
- package/src/compression/brotli/vendor/decode.js +938 -0
- package/src/compression/brotli/vendor/dictionary-data.js +9469 -0
- package/src/compression/brotli/vendor/dictionary.js +36 -0
- package/src/compression/brotli/vendor/huffman.js +123 -0
- package/src/compression/brotli/vendor/package.json +3 -0
- package/src/compression/brotli/vendor/prefix.js +60 -0
- package/src/compression/brotli/vendor/streams.js +31 -0
- package/src/compression/brotli/vendor/transform.js +247 -0
- package/src/compression/brotli/vendor-decode.d.ts +4 -0
- package/src/compression/brotli/woff2-glyf-transform.ts +623 -0
- package/src/compression/decompress.ts +16 -0
- package/src/compression/deflate.ts +295 -0
- package/src/compression/index.ts +4 -0
- package/src/compression/types.ts +26 -0
- package/src/compression/utils.ts +107 -0
- package/src/core.ts +18 -0
- package/src/css/apply-declarations.ts +86 -0
- package/src/css/background-types.ts +65 -0
- package/src/css/browser-defaults.ts +16 -0
- package/src/css/clip-path-types.ts +13 -0
- package/src/css/compute-style.ts +494 -0
- package/src/css/css-unit-resolver.ts +65 -0
- package/src/css/custom-properties.ts +215 -0
- package/src/css/enums.ts +127 -0
- package/src/css/font-face-parser.ts +233 -0
- package/src/css/font-weight.ts +65 -0
- package/src/css/inline-style-parser.ts +27 -0
- package/src/css/layout-property-resolver.ts +75 -0
- package/src/css/length.ts +141 -0
- package/src/css/line-height.ts +96 -0
- package/src/css/named-colors.ts +150 -0
- package/src/css/parsers/background-parser-extended.ts +111 -0
- package/src/css/parsers/background-parser.ts +456 -0
- package/src/css/parsers/border-block-parser.ts +26 -0
- package/src/css/parsers/border-inline-parser.ts +26 -0
- package/src/css/parsers/border-parser-extended.ts +256 -0
- package/src/css/parsers/border-parser.ts +175 -0
- package/src/css/parsers/box-shadow-parser.ts +106 -0
- package/src/css/parsers/clip-path-parser.ts +92 -0
- package/src/css/parsers/color-parser.ts +14 -0
- package/src/css/parsers/dimension-parser.ts +117 -0
- package/src/css/parsers/display-flex-parser.ts +59 -0
- package/src/css/parsers/flex-parser.ts +144 -0
- package/src/css/parsers/font-parser.ts +40 -0
- package/src/css/parsers/gradient-parser.ts +366 -0
- package/src/css/parsers/grid-parser-extended.ts +55 -0
- package/src/css/parsers/grid-parser.ts +218 -0
- package/src/css/parsers/length-parser.ts +95 -0
- package/src/css/parsers/list-style-parser.ts +39 -0
- package/src/css/parsers/margin-block-parser.ts +12 -0
- package/src/css/parsers/margin-inline-parser.ts +12 -0
- package/src/css/parsers/margin-parser.ts +30 -0
- package/src/css/parsers/opacity-parser.ts +32 -0
- package/src/css/parsers/overflow-wrap-parser.ts +38 -0
- package/src/css/parsers/padding-block-parser.ts +12 -0
- package/src/css/parsers/padding-inline-parser.ts +12 -0
- package/src/css/parsers/padding-parser.ts +30 -0
- package/src/css/parsers/position-parser.ts +75 -0
- package/src/css/parsers/register-parsers.ts +302 -0
- package/src/css/parsers/registry.ts +18 -0
- package/src/css/parsers/text-parser-extended.ts +144 -0
- package/src/css/parsers/text-parser.ts +25 -0
- package/src/css/parsers/text-shadow-parser.ts +94 -0
- package/src/css/properties/box-model.ts +82 -0
- package/src/css/properties/flexbox.ts +44 -0
- package/src/css/properties/gap.ts +14 -0
- package/src/css/properties/grid.ts +94 -0
- package/src/css/properties/layout.ts +59 -0
- package/src/css/properties/misc.ts +44 -0
- package/src/css/properties/typography.ts +71 -0
- package/src/css/properties/visual.ts +68 -0
- package/src/css/selectors/matcher.ts +219 -0
- package/src/css/selectors/parser.ts +163 -0
- package/src/css/selectors/simple-key.ts +31 -0
- package/src/css/selectors/specificity.ts +41 -0
- package/src/css/selectors/types.ts +31 -0
- package/src/css/shorthands/border-shorthand.ts +68 -0
- package/src/css/shorthands/box-shorthand.ts +33 -0
- package/src/css/style-inheritance.ts +50 -0
- package/src/css/style.ts +402 -0
- package/src/css/ua-defaults/base-defaults.ts +266 -0
- package/src/css/ua-defaults/browser-defaults.ts +134 -0
- package/src/css/ua-defaults/element-defaults.ts +374 -0
- package/src/css/ua-defaults/types.ts +43 -0
- package/src/css/unit-conversion.ts +24 -0
- package/src/css/utils.ts +108 -0
- package/src/css/viewport.ts +17 -0
- package/src/debug/audit.ts +20 -0
- package/src/debug/ids.ts +13 -0
- package/src/debug/log.js +28 -0
- package/src/debug/log.ts +52 -0
- package/src/debug/tree.ts +57 -0
- package/src/dom/node.ts +133 -0
- package/src/environment/browser-environment.ts +78 -0
- package/src/environment/environment.ts +35 -0
- package/src/environment/global.ts +13 -0
- package/src/environment/node-environment.browser.ts +28 -0
- package/src/environment/node-environment.ts +64 -0
- package/src/fonts/detector.ts +28 -0
- package/src/fonts/engines/ttf-engine.ts +28 -0
- package/src/fonts/engines/woff-engine.ts +38 -0
- package/src/fonts/engines/woff2-engine.ts +41 -0
- package/src/fonts/extractors/metrics-extractor.ts +362 -0
- package/src/fonts/font-registry-resolver.ts +132 -0
- package/src/fonts/index.ts +3 -0
- package/src/fonts/orchestrator.ts +92 -0
- package/src/fonts/parsers/base-parser.ts +23 -0
- package/src/fonts/types.ts +85 -0
- package/src/fonts/utils/ttf-reconstructor.ts +120 -0
- package/src/fonts/woff/decoder.ts +105 -0
- package/src/fonts/woff2/buffer.ts +106 -0
- package/src/fonts/woff2/decoder.ts +981 -0
- package/src/geometry/box.ts +48 -0
- package/src/geometry/matrix.ts +59 -0
- package/src/html/css/parse-css.ts +85 -0
- package/src/html/dom-converter.ts +433 -0
- package/src/html/image-converter.ts +200 -0
- package/src/html-to-pdf.ts +410 -0
- package/src/image/base-decoder.ts +149 -0
- package/src/image/image-service.ts +188 -0
- package/src/image/jpeg-decoder.ts +73 -0
- package/src/image/png-decoder.ts +550 -0
- package/src/image/types.ts +20 -0
- package/src/image/webp-decoder.ts +242 -0
- package/src/image/webp-huffman.ts +218 -0
- package/src/image/webp-riff-parser.ts +54 -0
- package/src/image/webp-vp8l-decoder.ts +199 -0
- package/src/index.ts +35 -0
- package/src/layout/context/float-context.ts +62 -0
- package/src/layout/context/layout-environment.ts +29 -0
- package/src/layout/debug.ts +18 -0
- package/src/layout/inline/bounding-box-calculator.ts +132 -0
- package/src/layout/inline/font-baseline-calculator.ts +76 -0
- package/src/layout/inline/inline-utils.ts +94 -0
- package/src/layout/inline/layout.ts +285 -0
- package/src/layout/inline/line_breaker.ts +109 -0
- package/src/layout/inline/measurement.ts +144 -0
- package/src/layout/inline/run-placer.ts +139 -0
- package/src/layout/inline/text-alignment.ts +70 -0
- package/src/layout/inline/tokenizer.ts +195 -0
- package/src/layout/inline/types.ts +76 -0
- package/src/layout/pipeline/context-factory.ts +16 -0
- package/src/layout/pipeline/default-engine.ts +24 -0
- package/src/layout/pipeline/engine.ts +59 -0
- package/src/layout/pipeline/layout-tree.ts +13 -0
- package/src/layout/pipeline/out-of-flow-manager.ts +73 -0
- package/src/layout/pipeline/strategy.ts +12 -0
- package/src/layout/pipeline/text-metrics-initializer.ts +13 -0
- package/src/layout/strategies/block.ts +236 -0
- package/src/layout/strategies/display-none.ts +14 -0
- package/src/layout/strategies/fallback.ts +15 -0
- package/src/layout/strategies/flex.ts +477 -0
- package/src/layout/strategies/fragmentation.ts +17 -0
- package/src/layout/strategies/grid.ts +247 -0
- package/src/layout/strategies/image.ts +342 -0
- package/src/layout/strategies/inline.ts +128 -0
- package/src/layout/strategies/table.ts +595 -0
- package/src/layout/table/cell_layout.ts +31 -0
- package/src/layout/table/diagnostics.ts +19 -0
- package/src/layout/text-run.ts +42 -0
- package/src/layout/utils/content-measurer.ts +117 -0
- package/src/layout/utils/display-utils.ts +24 -0
- package/src/layout/utils/floats.ts +98 -0
- package/src/layout/utils/gap-calculator.ts +167 -0
- package/src/layout/utils/inline-formatter.ts +31 -0
- package/src/layout/utils/inline-formatting.ts +9 -0
- package/src/layout/utils/margin.ts +140 -0
- package/src/layout/utils/node-math.ts +237 -0
- package/src/layout/utils/overflow.ts +14 -0
- package/src/layout/utils/sizing.ts +12 -0
- package/src/layout/utils/text-metrics.ts +361 -0
- package/src/logging/debug.ts +58 -0
- package/src/pdf/font/base14/widths-courier-bold.ts +159 -0
- package/src/pdf/font/base14/widths-courier.ts +159 -0
- package/src/pdf/font/base14/widths-helvetica-bold.ts +158 -0
- package/src/pdf/font/base14/widths-helvetica.ts +158 -0
- package/src/pdf/font/base14/widths-times-bold.ts +158 -0
- package/src/pdf/font/base14/widths-times-roman.ts +158 -0
- package/src/pdf/font/base14/widths-types.ts +25 -0
- package/src/pdf/font/base14-widths.ts +32 -0
- package/src/pdf/font/blur.ts +81 -0
- package/src/pdf/font/builtin-fonts.browser.ts +262 -0
- package/src/pdf/font/builtin-fonts.ts +126 -0
- package/src/pdf/font/composite-glyph-parser.ts +242 -0
- package/src/pdf/font/embedder.ts +395 -0
- package/src/pdf/font/font-config.ts +190 -0
- package/src/pdf/font/font-registry.ts +263 -0
- package/src/pdf/font/font-subset.ts +258 -0
- package/src/pdf/font/glyph-atlas-maxrects.ts +305 -0
- package/src/pdf/font/glyph-atlas-tuner.ts +98 -0
- package/src/pdf/font/glyph-atlas.ts +226 -0
- package/src/pdf/font/glyph-cache.ts +127 -0
- package/src/pdf/font/loca-reader.ts +109 -0
- package/src/pdf/font/managers/font-resource-manager.ts +73 -0
- package/src/pdf/font/managers/subset-resource-manager.ts +164 -0
- package/src/pdf/font/rasterizer.ts +270 -0
- package/src/pdf/font/resolvers/base-font-mapper.ts +77 -0
- package/src/pdf/font/resolvers/family-resolver.ts +33 -0
- package/src/pdf/font/resolvers/weight-style-applicator.ts +63 -0
- package/src/pdf/font/simple-glyph-parser.ts +289 -0
- package/src/pdf/font/to-unicode.ts +109 -0
- package/src/pdf/font/transformation-matrix.ts +136 -0
- package/src/pdf/font/ttf-cmap.ts +180 -0
- package/src/pdf/font/ttf-global-metrics.ts +58 -0
- package/src/pdf/font/ttf-glyf.ts +125 -0
- package/src/pdf/font/ttf-glyph-metrics.ts +43 -0
- package/src/pdf/font/ttf-lite.ts +269 -0
- package/src/pdf/font/ttf-table-parser.ts +132 -0
- package/src/pdf/font/ttf-table-provider.ts +61 -0
- package/src/pdf/font/widths.ts +79 -0
- package/src/pdf/font-subset/font-registry.ts +127 -0
- package/src/pdf/header-footer-layout.ts +153 -0
- package/src/pdf/header-footer-painter.ts +209 -0
- package/src/pdf/header-footer-renderer.ts +357 -0
- package/src/pdf/header-footer-tokens.ts +55 -0
- package/src/pdf/header-footer.ts +25 -0
- package/src/pdf/layout-tree-builder.ts +261 -0
- package/src/pdf/page-painter.ts +241 -0
- package/src/pdf/pagination.ts +155 -0
- package/src/pdf/primitives/pdf-builder.ts +378 -0
- package/src/pdf/primitives/pdf-bytes.ts +40 -0
- package/src/pdf/primitives/pdf-document.ts +108 -0
- package/src/pdf/primitives/pdf-reference-manager.ts +47 -0
- package/src/pdf/primitives/pdf-resource-registries.ts +255 -0
- package/src/pdf/primitives/pdf-serializers.ts +194 -0
- package/src/pdf/primitives/pdf-types.ts +73 -0
- package/src/pdf/render.ts +210 -0
- package/src/pdf/renderer/box-painter.ts +236 -0
- package/src/pdf/renderer/page-paint.ts +102 -0
- package/src/pdf/renderer/paint-box-shadows.ts +218 -0
- package/src/pdf/renderer/radius.ts +58 -0
- package/src/pdf/renderers/graphics-state-manager.ts +40 -0
- package/src/pdf/renderers/image-renderer.ts +127 -0
- package/src/pdf/renderers/radius-utils.ts +80 -0
- package/src/pdf/renderers/rectangle-renderer.ts +129 -0
- package/src/pdf/renderers/rounded-rect-path.ts +120 -0
- package/src/pdf/renderers/shape-renderer.ts +563 -0
- package/src/pdf/renderers/shape-utils.ts +194 -0
- package/src/pdf/renderers/text-decoration-renderer.ts +313 -0
- package/src/pdf/renderers/text-encoder.ts +41 -0
- package/src/pdf/renderers/text-font-resolver.ts +75 -0
- package/src/pdf/renderers/text-renderer-utils.ts +28 -0
- package/src/pdf/renderers/text-renderer.ts +391 -0
- package/src/pdf/renderers/text-shadow-renderer.ts +300 -0
- package/src/pdf/shading/gradient-service.ts +525 -0
- package/src/pdf/shading/index.ts +1 -0
- package/src/pdf/stacking/build-stacking-contexts.ts +93 -0
- package/src/pdf/stacking/resolve-paint-order.ts +157 -0
- package/src/pdf/stacking/types.ts +40 -0
- package/src/pdf/svg/aspect-ratio.ts +81 -0
- package/src/pdf/svg/coordinate-mapper.ts +81 -0
- package/src/pdf/svg/geometry-builder.ts +45 -0
- package/src/pdf/svg/render-svg.ts +296 -0
- package/src/pdf/svg/shape-renderer.ts +463 -0
- package/src/pdf/svg/style-computer.ts +246 -0
- package/src/pdf/transform-adapter.ts +26 -0
- package/src/pdf/types.ts +377 -0
- package/src/pdf/utils/background-layer-resolver.ts +439 -0
- package/src/pdf/utils/background-tiles.ts +192 -0
- package/src/pdf/utils/border-dashes.ts +109 -0
- package/src/pdf/utils/border-radius-utils.ts +86 -0
- package/src/pdf/utils/box-dimensions-utils.ts +47 -0
- package/src/pdf/utils/clip-path-resolver.ts +50 -0
- package/src/pdf/utils/clipping-path-builder.ts +190 -0
- package/src/pdf/utils/color-utils.ts +102 -0
- package/src/pdf/utils/coordinate-transformer.ts +30 -0
- package/src/pdf/utils/drop-shadow-raster.ts +233 -0
- package/src/pdf/utils/encoding.ts +98 -0
- package/src/pdf/utils/glyph-atlas-registrar.ts +13 -0
- package/src/pdf/utils/glyph-run-renderer.ts +129 -0
- package/src/pdf/utils/image-command-partitioner.ts +28 -0
- package/src/pdf/utils/image-matrix-builder.ts +31 -0
- package/src/pdf/utils/image-utils.ts +26 -0
- package/src/pdf/utils/list-utils.ts +194 -0
- package/src/pdf/utils/node-text-run-factory.ts +202 -0
- package/src/pdf/utils/page-resource-registrar.ts +46 -0
- package/src/pdf/utils/result-combiner.ts +102 -0
- package/src/pdf/utils/shadow-utils.ts +127 -0
- package/src/pdf/utils/text-alignment-resolver.ts +76 -0
- package/src/pdf/utils/text-decoration-utils.ts +64 -0
- package/src/pdf/utils/text-layout-adjuster.ts +185 -0
- package/src/pdf/utils/text-utils.ts +193 -0
- package/src/pdf/utils/transform-scope-manager.ts +69 -0
- package/src/render/offset.ts +170 -0
- package/src/shim/empty.ts +2 -0
- package/src/shim/fs-empty.ts +5 -0
- package/src/shim/url-empty.ts +7 -0
- package/src/shim/zlib-empty.ts +9 -0
- package/src/style/shorthands/index.ts +19 -0
- package/src/style/ua/defaults.ts +69 -0
- package/src/svg/index.ts +4 -0
- package/src/svg/parser-registry.ts +71 -0
- package/src/svg/parser.ts +486 -0
- package/src/svg/path-data.ts +515 -0
- package/src/svg/types.ts +194 -0
- package/src/text/line-breaker.ts +321 -0
- package/src/text/text-transform.ts +43 -0
- package/src/text/text.ts +33 -0
- package/src/transform/css-parser.ts +95 -0
- package/src/types/fonts.ts +62 -0
- package/src/types/public.ts +19 -0
- package/src/units/page-utils.ts +58 -0
- package/src/units/units.ts +50 -0
- package/src/utils/base64.ts +24 -0
- package/test-output.txt +79 -0
- package/tests/css/background-parser.spec.ts +14 -0
- package/tests/css/clip-path-parser.spec.ts +66 -0
- package/tests/environment/path-resolution.spec.ts +104 -0
- package/tests/helpers/ai-layout-diagnostics.ts +141 -0
- package/tests/helpers/render-utils.ts +52 -0
- package/tests/helpers/text-geometry.ts +56 -0
- package/tests/layout/custom-properties.test.ts +38 -0
- package/tests/layout/gap-calculator.spec.ts +196 -0
- package/tests/layout/inline-background-alignment.spec.ts +93 -0
- package/tests/layout/inline-fragments.spec.ts +26 -0
- package/tests/layout/run-placer-baseline.spec.ts +108 -0
- package/tests/pdf/alignments.spec.ts +26 -0
- package/tests/pdf/background-clip.spec.ts +57 -0
- package/tests/pdf/background-repeat-space-round.spec.ts +35 -0
- package/tests/pdf/background-repeat.spec.ts +137 -0
- package/tests/pdf/border-radius.spec.ts +151 -0
- package/tests/pdf/clip-path.spec.ts +92 -0
- package/tests/pdf/radial-gradient.spec.ts +50 -0
- package/tests/pdf/svg-stroke-dash.spec.ts +81 -0
- package/tests/pdf/text-transform-matrix.spec.ts +43 -0
- package/tsconfig.json +17 -0
- package/types/fonts.js +10 -0
- package/vitest.config.ts +9 -0
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
import type { GlyphOutlineCmd } from "../../types/fonts.js";
|
|
2
|
+
import type { DataViewReader } from "./ttf-table-provider.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Represents a point in a glyph contour.
|
|
6
|
+
*/
|
|
7
|
+
interface Point {
|
|
8
|
+
x: number;
|
|
9
|
+
y: number;
|
|
10
|
+
onCurve: boolean;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Parses simple (non-composite) TrueType glyphs.
|
|
15
|
+
*
|
|
16
|
+
* Simple glyphs consist of one or more contours made up of on-curve and off-curve points.
|
|
17
|
+
* Off-curve points are quadratic Bezier control points.
|
|
18
|
+
*/
|
|
19
|
+
export class SimpleGlyphParser {
|
|
20
|
+
constructor(private readonly reader: DataViewReader) { }
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Parses a simple glyph from a DataView.
|
|
24
|
+
* @param view - DataView containing the glyph data starting at the glyph header
|
|
25
|
+
* @returns Array of glyph outline commands, or null if parsing fails
|
|
26
|
+
*/
|
|
27
|
+
parse(view: DataView): GlyphOutlineCmd[] | null {
|
|
28
|
+
const contours = this.parseContours(view);
|
|
29
|
+
if (!contours) return null;
|
|
30
|
+
|
|
31
|
+
return this.buildOutlineCommands(contours);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Parses glyph contours from the DataView.
|
|
36
|
+
* @param view - DataView containing the glyph data
|
|
37
|
+
* @returns Array of contours (each contour is an array of points), or null if parsing fails
|
|
38
|
+
*/
|
|
39
|
+
private parseContours(view: DataView): Point[][] | null {
|
|
40
|
+
if (view.byteLength < 10) return null;
|
|
41
|
+
|
|
42
|
+
// Read glyph header
|
|
43
|
+
const numberOfContours = view.getInt16(0, false);
|
|
44
|
+
if (numberOfContours < 0) return null; // Composite glyph, shouldn't happen here
|
|
45
|
+
|
|
46
|
+
// Read endPtsOfContours array
|
|
47
|
+
const endPtsOffset = 10;
|
|
48
|
+
const endPts: number[] = [];
|
|
49
|
+
for (let i = 0; i < numberOfContours; i++) {
|
|
50
|
+
if (endPtsOffset + i * 2 + 2 > view.byteLength) return null;
|
|
51
|
+
endPts.push(this.reader.getUint16(view, endPtsOffset + i * 2));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Read instruction length and skip instructions
|
|
55
|
+
const instrLenOffset = endPtsOffset + numberOfContours * 2;
|
|
56
|
+
if (instrLenOffset + 2 > view.byteLength) return null;
|
|
57
|
+
const instructionLength = this.reader.getUint16(view, instrLenOffset);
|
|
58
|
+
const flagsOffset = instrLenOffset + 2 + instructionLength;
|
|
59
|
+
if (flagsOffset > view.byteLength) return null;
|
|
60
|
+
|
|
61
|
+
// Calculate number of points
|
|
62
|
+
const nPoints = endPts.length === 0 ? 0 : endPts[endPts.length - 1] + 1;
|
|
63
|
+
if (nPoints <= 0) return [];
|
|
64
|
+
|
|
65
|
+
// Parse flags
|
|
66
|
+
const flagsResult = this.parseFlags(view, nPoints, flagsOffset);
|
|
67
|
+
if (!flagsResult) return null;
|
|
68
|
+
const { flags, nextOffset: xCoordOffset } = flagsResult;
|
|
69
|
+
|
|
70
|
+
// Parse coordinates
|
|
71
|
+
const coordsResult = this.parseCoordinates(view, flags, xCoordOffset);
|
|
72
|
+
if (!coordsResult) return null;
|
|
73
|
+
const { points } = coordsResult;
|
|
74
|
+
|
|
75
|
+
// Split points into contours
|
|
76
|
+
const contours: Point[][] = [];
|
|
77
|
+
let startIndex = 0;
|
|
78
|
+
for (let c = 0; c < numberOfContours; c++) {
|
|
79
|
+
const endIndex = endPts[c];
|
|
80
|
+
if (endIndex < startIndex || endIndex >= points.length) return null;
|
|
81
|
+
contours.push(points.slice(startIndex, endIndex + 1));
|
|
82
|
+
startIndex = endIndex + 1;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return contours;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Parses glyph flags with run-length encoding.
|
|
90
|
+
* @param view - DataView containing the glyph data
|
|
91
|
+
* @param nPoints - Number of points to read
|
|
92
|
+
* @param offset - Starting offset for flags
|
|
93
|
+
* @returns Flags array and next offset, or null if parsing fails
|
|
94
|
+
*/
|
|
95
|
+
private parseFlags(
|
|
96
|
+
view: DataView,
|
|
97
|
+
nPoints: number,
|
|
98
|
+
offset: number
|
|
99
|
+
): { flags: number[]; nextOffset: number } | null {
|
|
100
|
+
const flags: number[] = [];
|
|
101
|
+
let p = offset;
|
|
102
|
+
|
|
103
|
+
try {
|
|
104
|
+
while (flags.length < nPoints) {
|
|
105
|
+
if (p >= view.byteLength) return null;
|
|
106
|
+
const flag = this.reader.getUint8(view, p++);
|
|
107
|
+
flags.push(flag);
|
|
108
|
+
|
|
109
|
+
// Repeat flag (bit 3 set)
|
|
110
|
+
if (flag & 0x08) {
|
|
111
|
+
if (p >= view.byteLength) return null;
|
|
112
|
+
const repeatCount = this.reader.getUint8(view, p++);
|
|
113
|
+
for (let r = 0; r < repeatCount; r++) {
|
|
114
|
+
flags.push(flag);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
} catch {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return { flags, nextOffset: p };
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Parses glyph X and Y coordinates from delta values.
|
|
127
|
+
* @param view - DataView containing the glyph data
|
|
128
|
+
* @param flags - Flag array for each point
|
|
129
|
+
* @param offset - Starting offset for coordinates
|
|
130
|
+
* @returns Points array and next offset, or null if parsing fails
|
|
131
|
+
*/
|
|
132
|
+
private parseCoordinates(
|
|
133
|
+
view: DataView,
|
|
134
|
+
flags: number[],
|
|
135
|
+
offset: number
|
|
136
|
+
): { points: Point[]; nextOffset: number } | null {
|
|
137
|
+
const nPoints = flags.length;
|
|
138
|
+
const xs: number[] = new Array(nPoints);
|
|
139
|
+
const ys: number[] = new Array(nPoints);
|
|
140
|
+
|
|
141
|
+
let p = offset;
|
|
142
|
+
|
|
143
|
+
// Parse X coordinates (deltas)
|
|
144
|
+
try {
|
|
145
|
+
for (let i = 0; i < nPoints; i++) {
|
|
146
|
+
const f = flags[i];
|
|
147
|
+
if (f & 0x02) {
|
|
148
|
+
// X-Short Vector: 1-byte delta
|
|
149
|
+
if (p >= view.byteLength) return null;
|
|
150
|
+
const val = this.reader.getUint8(view, p++);
|
|
151
|
+
xs[i] = (f & 0x10) ? val : -val; // Bit 4: positive if set
|
|
152
|
+
} else {
|
|
153
|
+
if (f & 0x10) {
|
|
154
|
+
// X is same as previous (zero delta)
|
|
155
|
+
xs[i] = 0;
|
|
156
|
+
} else {
|
|
157
|
+
// 2-byte signed delta
|
|
158
|
+
if (p + 2 > view.byteLength) return null;
|
|
159
|
+
xs[i] = this.reader.getInt16(view, p);
|
|
160
|
+
p += 2;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
} catch {
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Parse Y coordinates (deltas)
|
|
169
|
+
try {
|
|
170
|
+
for (let i = 0; i < nPoints; i++) {
|
|
171
|
+
const f = flags[i];
|
|
172
|
+
if (f & 0x04) {
|
|
173
|
+
// Y-Short Vector: 1-byte delta
|
|
174
|
+
if (p >= view.byteLength) return null;
|
|
175
|
+
const val = this.reader.getUint8(view, p++);
|
|
176
|
+
ys[i] = (f & 0x20) ? val : -val; // Bit 5: positive if set
|
|
177
|
+
} else {
|
|
178
|
+
if (f & 0x20) {
|
|
179
|
+
// Y is same as previous (zero delta)
|
|
180
|
+
ys[i] = 0;
|
|
181
|
+
} else {
|
|
182
|
+
// 2-byte signed delta
|
|
183
|
+
if (p + 2 > view.byteLength) return null;
|
|
184
|
+
ys[i] = this.reader.getInt16(view, p);
|
|
185
|
+
p += 2;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
} catch {
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Convert deltas to absolute coordinates
|
|
194
|
+
const points: Point[] = new Array(nPoints);
|
|
195
|
+
let curX = 0;
|
|
196
|
+
let curY = 0;
|
|
197
|
+
for (let i = 0; i < nPoints; i++) {
|
|
198
|
+
curX += xs[i];
|
|
199
|
+
curY += ys[i];
|
|
200
|
+
points[i] = {
|
|
201
|
+
x: curX,
|
|
202
|
+
y: curY,
|
|
203
|
+
onCurve: !!(flags[i] & 0x01) // Bit 0: on-curve flag
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return { points, nextOffset: p };
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Converts contour points into glyph outline commands.
|
|
212
|
+
* Handles quadratic Bezier curves with consecutive off-curve points.
|
|
213
|
+
* @param contours - Array of contours
|
|
214
|
+
* @returns Array of glyph outline commands
|
|
215
|
+
*/
|
|
216
|
+
private buildOutlineCommands(contours: Point[][]): GlyphOutlineCmd[] {
|
|
217
|
+
const cmds: GlyphOutlineCmd[] = [];
|
|
218
|
+
|
|
219
|
+
for (const contour of contours) {
|
|
220
|
+
if (contour.length === 0) continue;
|
|
221
|
+
|
|
222
|
+
const n = contour.length;
|
|
223
|
+
const getIdx = (i: number) => ((i % n) + n) % n; // Wrap-around index
|
|
224
|
+
|
|
225
|
+
// Find a starting on-curve point, if any
|
|
226
|
+
let startPtIndex = -1;
|
|
227
|
+
for (let i = 0; i < n; i++) {
|
|
228
|
+
if (contour[i].onCurve) {
|
|
229
|
+
startPtIndex = i;
|
|
230
|
+
break;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
let firstPoint: Point;
|
|
235
|
+
let curIndex: number;
|
|
236
|
+
|
|
237
|
+
if (startPtIndex === -1) {
|
|
238
|
+
// No on-curve points: create implied on-curve between last and first off-curve
|
|
239
|
+
const p0 = contour[0];
|
|
240
|
+
const plast = contour[n - 1];
|
|
241
|
+
firstPoint = {
|
|
242
|
+
x: (plast.x + p0.x) / 2,
|
|
243
|
+
y: (plast.y + p0.y) / 2,
|
|
244
|
+
onCurve: true
|
|
245
|
+
};
|
|
246
|
+
curIndex = 0;
|
|
247
|
+
} else {
|
|
248
|
+
firstPoint = contour[startPtIndex];
|
|
249
|
+
curIndex = startPtIndex;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
cmds.push({ type: "moveTo", x: firstPoint.x, y: firstPoint.y });
|
|
253
|
+
|
|
254
|
+
// Walk through contour points
|
|
255
|
+
let i = curIndex + 1;
|
|
256
|
+
let steps = 0;
|
|
257
|
+
while (steps < n) {
|
|
258
|
+
const idx = getIdx(i);
|
|
259
|
+
const pt = contour[idx];
|
|
260
|
+
const next = contour[getIdx(i + 1)];
|
|
261
|
+
|
|
262
|
+
if (pt.onCurve) {
|
|
263
|
+
// Straight line to on-curve point
|
|
264
|
+
cmds.push({ type: "lineTo", x: pt.x, y: pt.y });
|
|
265
|
+
} else {
|
|
266
|
+
// Off-curve point (quadratic control point)
|
|
267
|
+
if (next.onCurve) {
|
|
268
|
+
// Single control point -> quadratic curve
|
|
269
|
+
cmds.push({ type: "quadTo", cx: pt.x, cy: pt.y, x: next.x, y: next.y });
|
|
270
|
+
i++; // Consume next point
|
|
271
|
+
steps++;
|
|
272
|
+
} else {
|
|
273
|
+
// Consecutive off-curve points: create implied on-curve midpoint
|
|
274
|
+
const midx = (pt.x + next.x) / 2;
|
|
275
|
+
const midy = (pt.y + next.y) / 2;
|
|
276
|
+
cmds.push({ type: "quadTo", cx: pt.x, cy: pt.y, x: midx, y: midy });
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
i++;
|
|
281
|
+
steps++;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
cmds.push({ type: "close" });
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
return cmds;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build ToUnicode CMap text from explicit gid->unicode mappings.
|
|
3
|
+
* Entries should be pre-sorted by gid for best compression but ordering is not required.
|
|
4
|
+
*/
|
|
5
|
+
export function createToUnicodeCMapText(entries: { gid: number; unicode: number }[]): string {
|
|
6
|
+
if (!entries || entries.length === 0) {
|
|
7
|
+
return `/CIDInit /ProcSet findresource begin
|
|
8
|
+
12 dict begin
|
|
9
|
+
begincmap
|
|
10
|
+
/CIDSystemInfo <<
|
|
11
|
+
/Registry (Adobe)
|
|
12
|
+
/Ordering (UCS)
|
|
13
|
+
/Supplement 0
|
|
14
|
+
>> def
|
|
15
|
+
/CMapName /Adobe-Identity-UCS def
|
|
16
|
+
/CMapType 2 def
|
|
17
|
+
1 begincodespacerange
|
|
18
|
+
<0000> <FFFF>
|
|
19
|
+
endcodespacerange
|
|
20
|
+
endcmap
|
|
21
|
+
CMapName currentdict /CMap defineresource pop
|
|
22
|
+
end
|
|
23
|
+
end`;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const es = entries.slice().sort((a, b) => a.gid - b.gid);
|
|
27
|
+
|
|
28
|
+
const uniToUtf16Hex = (cp: number): string => {
|
|
29
|
+
if (cp <= 0xffff) {
|
|
30
|
+
return cp.toString(16).padStart(4, "0").toUpperCase();
|
|
31
|
+
}
|
|
32
|
+
const v = cp - 0x10000;
|
|
33
|
+
const hi = 0xd800 + (v >> 10);
|
|
34
|
+
const lo = 0xdc00 + (v & 0x3ff);
|
|
35
|
+
return hi.toString(16).padStart(4, "0").toUpperCase() + lo.toString(16).padStart(4, "0").toUpperCase();
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// Build mapping directives (group consecutive linear runs into ranges)
|
|
39
|
+
type Mapping = { type: "range"; startG: number; endG: number; startU: number } | { type: "char"; gid: number; unicode: number };
|
|
40
|
+
const mappings: Mapping[] = [];
|
|
41
|
+
let i = 0;
|
|
42
|
+
while (i < es.length) {
|
|
43
|
+
const start = es[i];
|
|
44
|
+
let j = i + 1;
|
|
45
|
+
while (
|
|
46
|
+
j < es.length &&
|
|
47
|
+
es[j].gid === es[j - 1].gid + 1 &&
|
|
48
|
+
es[j].unicode === es[j - 1].unicode + 1
|
|
49
|
+
) {
|
|
50
|
+
j++;
|
|
51
|
+
}
|
|
52
|
+
const runLen = j - i;
|
|
53
|
+
if (runLen >= 2) {
|
|
54
|
+
mappings.push({ type: "range", startG: start.gid, endG: es[j - 1].gid, startU: start.unicode });
|
|
55
|
+
i = j;
|
|
56
|
+
} else {
|
|
57
|
+
mappings.push({ type: "char", gid: start.gid, unicode: start.unicode });
|
|
58
|
+
i++;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const lines: string[] = [];
|
|
63
|
+
lines.push("/CIDInit /ProcSet findresource begin");
|
|
64
|
+
lines.push("12 dict begin");
|
|
65
|
+
lines.push("begincmap");
|
|
66
|
+
lines.push("/CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def");
|
|
67
|
+
lines.push("/CMapName /Adobe-Identity-UCS def");
|
|
68
|
+
lines.push("/CMapType 2 def");
|
|
69
|
+
lines.push("1 begincodespacerange");
|
|
70
|
+
lines.push("<0000> <FFFF>");
|
|
71
|
+
lines.push("endcodespacerange");
|
|
72
|
+
|
|
73
|
+
const CHUNK = 100;
|
|
74
|
+
let p = 0;
|
|
75
|
+
while (p < mappings.length) {
|
|
76
|
+
const currentType = mappings[p].type;
|
|
77
|
+
const group: Mapping[] = [];
|
|
78
|
+
while (p < mappings.length && mappings[p].type === currentType && group.length < CHUNK) {
|
|
79
|
+
group.push(mappings[p]);
|
|
80
|
+
p++;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (currentType === "char") {
|
|
84
|
+
lines.push(`${group.length} beginbfchar`);
|
|
85
|
+
for (const m of group as { type: "char"; gid: number; unicode: number }[]) {
|
|
86
|
+
const cid = m.gid.toString(16).padStart(4, "0").toUpperCase();
|
|
87
|
+
const uniHex = uniToUtf16Hex(m.unicode);
|
|
88
|
+
lines.push(`<${cid}> <${uniHex}>`);
|
|
89
|
+
}
|
|
90
|
+
lines.push("endbfchar");
|
|
91
|
+
} else {
|
|
92
|
+
lines.push(`${group.length} beginbfrange`);
|
|
93
|
+
for (const m of group as { type: "range"; startG: number; endG: number; startU: number }[]) {
|
|
94
|
+
const startCid = m.startG.toString(16).padStart(4, "0").toUpperCase();
|
|
95
|
+
const endCid = m.endG.toString(16).padStart(4, "0").toUpperCase();
|
|
96
|
+
const startUniHex = uniToUtf16Hex(m.startU);
|
|
97
|
+
lines.push(`<${startCid}> <${endCid}> <${startUniHex}>`);
|
|
98
|
+
}
|
|
99
|
+
lines.push("endbfrange");
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
lines.push("endcmap");
|
|
104
|
+
lines.push("CMapName currentdict /CMap defineresource pop");
|
|
105
|
+
lines.push("end");
|
|
106
|
+
lines.push("end");
|
|
107
|
+
|
|
108
|
+
return lines.join("\n");
|
|
109
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import type { GlyphOutlineCmd } from "../../types/fonts.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Represents a 2D affine transformation matrix with translation.
|
|
5
|
+
* Used for transforming composite glyph components in TrueType fonts.
|
|
6
|
+
*
|
|
7
|
+
* Matrix form:
|
|
8
|
+
* | mxx myx tx |
|
|
9
|
+
* | mxy myy ty |
|
|
10
|
+
* | 0 0 1 |
|
|
11
|
+
*/
|
|
12
|
+
export class TransformationMatrix {
|
|
13
|
+
constructor(
|
|
14
|
+
public readonly mxx: number = 1,
|
|
15
|
+
public readonly mxy: number = 0,
|
|
16
|
+
public readonly myx: number = 0,
|
|
17
|
+
public readonly myy: number = 1,
|
|
18
|
+
public readonly tx: number = 0,
|
|
19
|
+
public readonly ty: number = 0
|
|
20
|
+
) { }
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Creates an identity transformation matrix (no transformation).
|
|
24
|
+
*/
|
|
25
|
+
static identity(): TransformationMatrix {
|
|
26
|
+
return new TransformationMatrix();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Creates a uniform scale transformation matrix.
|
|
31
|
+
* @param s - Scale factor for both X and Y axes
|
|
32
|
+
*/
|
|
33
|
+
static scale(s: number): TransformationMatrix {
|
|
34
|
+
return new TransformationMatrix(s, 0, 0, s, 0, 0);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Creates a non-uniform scale transformation matrix.
|
|
39
|
+
* @param sx - Scale factor for X axis
|
|
40
|
+
* @param sy - Scale factor for Y axis
|
|
41
|
+
*/
|
|
42
|
+
static scaleXY(sx: number, sy: number): TransformationMatrix {
|
|
43
|
+
return new TransformationMatrix(sx, 0, 0, sy, 0, 0);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Creates a translation transformation matrix.
|
|
48
|
+
* @param tx - Translation along X axis
|
|
49
|
+
* @param ty - Translation along Y axis
|
|
50
|
+
*/
|
|
51
|
+
static translate(tx: number, ty: number): TransformationMatrix {
|
|
52
|
+
return new TransformationMatrix(1, 0, 0, 1, tx, ty);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Creates a transformation matrix from TrueType component transform data.
|
|
57
|
+
* @param tx - Translation X
|
|
58
|
+
* @param ty - Translation Y
|
|
59
|
+
* @param mxx - Matrix element (1,1)
|
|
60
|
+
* @param mxy - Matrix element (1,2)
|
|
61
|
+
* @param myx - Matrix element (2,1)
|
|
62
|
+
* @param myy - Matrix element (2,2)
|
|
63
|
+
*/
|
|
64
|
+
static fromComponents(
|
|
65
|
+
tx: number,
|
|
66
|
+
ty: number,
|
|
67
|
+
mxx: number = 1,
|
|
68
|
+
mxy: number = 0,
|
|
69
|
+
myx: number = 0,
|
|
70
|
+
myy: number = 1
|
|
71
|
+
): TransformationMatrix {
|
|
72
|
+
return new TransformationMatrix(mxx, mxy, myx, myy, tx, ty);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Transforms a single point using this matrix.
|
|
77
|
+
* @param x - X coordinate
|
|
78
|
+
* @param y - Y coordinate
|
|
79
|
+
* @returns Transformed coordinates
|
|
80
|
+
*/
|
|
81
|
+
transformPoint(x: number, y: number): { x: number; y: number } {
|
|
82
|
+
return {
|
|
83
|
+
x: x * this.mxx + y * this.myx + this.tx,
|
|
84
|
+
y: x * this.mxy + y * this.myy + this.ty
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Applies this transformation to a list of glyph outline commands.
|
|
90
|
+
* Creates new command objects with transformed coordinates.
|
|
91
|
+
* @param cmds - Original glyph outline commands
|
|
92
|
+
* @returns New array of transformed commands
|
|
93
|
+
*/
|
|
94
|
+
applyToCommands(cmds: GlyphOutlineCmd[]): GlyphOutlineCmd[] {
|
|
95
|
+
const out: GlyphOutlineCmd[] = [];
|
|
96
|
+
|
|
97
|
+
for (const c of cmds) {
|
|
98
|
+
switch (c.type) {
|
|
99
|
+
case "moveTo": {
|
|
100
|
+
const { x, y } = this.transformPoint(c.x, c.y);
|
|
101
|
+
out.push({ type: "moveTo", x, y });
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
case "lineTo": {
|
|
105
|
+
const { x, y } = this.transformPoint(c.x, c.y);
|
|
106
|
+
out.push({ type: "lineTo", x, y });
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
case "quadTo": {
|
|
110
|
+
const cp = this.transformPoint(c.cx, c.cy);
|
|
111
|
+
const ep = this.transformPoint(c.x, c.y);
|
|
112
|
+
out.push({ type: "quadTo", cx: cp.x, cy: cp.y, x: ep.x, y: ep.y });
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
case "cubicTo": {
|
|
116
|
+
const cp1 = this.transformPoint(c.cx1, c.cy1);
|
|
117
|
+
const cp2 = this.transformPoint(c.cx2, c.cy2);
|
|
118
|
+
const ep = this.transformPoint(c.x, c.y);
|
|
119
|
+
out.push({
|
|
120
|
+
type: "cubicTo",
|
|
121
|
+
cx1: cp1.x, cy1: cp1.y,
|
|
122
|
+
cx2: cp2.x, cy2: cp2.y,
|
|
123
|
+
x: ep.x, y: ep.y
|
|
124
|
+
});
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
case "close": {
|
|
128
|
+
out.push({ type: "close" });
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return out;
|
|
135
|
+
}
|
|
136
|
+
}
|