@ohos-ports/html2canvas-pro 0.0.0-stage → 2.3.2-beta.0
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/LICENSE +21 -0
- package/README.md +86 -2
- package/dist/html2canvas-pro.cjs +11191 -0
- package/dist/html2canvas-pro.cjs.map +1 -0
- package/dist/html2canvas-pro.esm.js +11182 -0
- package/dist/html2canvas-pro.esm.js.map +1 -0
- package/dist/html2canvas-pro.js +11196 -0
- package/dist/html2canvas-pro.js.map +1 -0
- package/dist/html2canvas-pro.min.js +10 -0
- package/dist/lib/config.js +49 -0
- package/dist/lib/core/abort-helper.js +20 -0
- package/dist/lib/core/background-parser.js +41 -0
- package/dist/lib/core/bitwise.js +5 -0
- package/dist/lib/core/cache-storage.js +268 -0
- package/dist/lib/core/config-assembler.js +88 -0
- package/dist/lib/core/constants.js +25 -0
- package/dist/lib/core/context.js +19 -0
- package/dist/lib/core/debugger.js +27 -0
- package/dist/lib/core/features.js +190 -0
- package/dist/lib/core/logger.js +56 -0
- package/dist/lib/core/lru-map.js +66 -0
- package/dist/lib/core/origin-checker.js +53 -0
- package/dist/lib/core/performance-monitor.js +185 -0
- package/dist/lib/core/render-element.js +132 -0
- package/dist/lib/core/util.js +4 -0
- package/dist/lib/core/validator.js +500 -0
- package/dist/lib/css/grouped/background-styles.js +36 -0
- package/dist/lib/css/grouped/border-styles.js +75 -0
- package/dist/lib/css/grouped/font-styles.js +93 -0
- package/dist/lib/css/grouped/layout-styles.js +127 -0
- package/dist/lib/css/index.js +330 -0
- package/dist/lib/css/layout/bounds.js +52 -0
- package/dist/lib/css/layout/text.js +133 -0
- package/dist/lib/css/property-descriptor.js +2 -0
- package/dist/lib/css/property-descriptors/background-blend-mode.js +41 -0
- package/dist/lib/css/property-descriptors/background-clip.js +23 -0
- package/dist/lib/css/property-descriptors/background-color.js +10 -0
- package/dist/lib/css/property-descriptors/background-image.js +24 -0
- package/dist/lib/css/property-descriptors/background-origin.js +23 -0
- package/dist/lib/css/property-descriptors/background-position.js +19 -0
- package/dist/lib/css/property-descriptors/background-repeat.js +33 -0
- package/dist/lib/css/property-descriptors/background-size.js +23 -0
- package/dist/lib/css/property-descriptors/border-color.js +14 -0
- package/dist/lib/css/property-descriptors/border-image-repeat.js +42 -0
- package/dist/lib/css/property-descriptors/border-image-slice.js +45 -0
- package/dist/lib/css/property-descriptors/border-image-source.js +22 -0
- package/dist/lib/css/property-descriptors/border-radius.js +15 -0
- package/dist/lib/css/property-descriptors/border-style.js +26 -0
- package/dist/lib/css/property-descriptors/border-width.js +20 -0
- package/dist/lib/css/property-descriptors/box-decoration-break.js +18 -0
- package/dist/lib/css/property-descriptors/box-shadow.js +54 -0
- package/dist/lib/css/property-descriptors/clip-path.js +189 -0
- package/dist/lib/css/property-descriptors/color.js +10 -0
- package/dist/lib/css/property-descriptors/content.js +19 -0
- package/dist/lib/css/property-descriptors/counter-increment.js +35 -0
- package/dist/lib/css/property-descriptors/counter-reset.js +18 -0
- package/dist/lib/css/property-descriptors/direction.js +18 -0
- package/dist/lib/css/property-descriptors/display.js +81 -0
- package/dist/lib/css/property-descriptors/duration.js +14 -0
- package/dist/lib/css/property-descriptors/filter.js +76 -0
- package/dist/lib/css/property-descriptors/float.js +22 -0
- package/dist/lib/css/property-descriptors/font-family.js +32 -0
- package/dist/lib/css/property-descriptors/font-size.js +10 -0
- package/dist/lib/css/property-descriptors/font-style.js +20 -0
- package/dist/lib/css/property-descriptors/font-variant-ligatures.js +34 -0
- package/dist/lib/css/property-descriptors/font-variant.js +13 -0
- package/dist/lib/css/property-descriptors/font-weight.js +25 -0
- package/dist/lib/css/property-descriptors/image-rendering.js +33 -0
- package/dist/lib/css/property-descriptors/letter-spacing.js +21 -0
- package/dist/lib/css/property-descriptors/line-break.js +23 -0
- package/dist/lib/css/property-descriptors/line-height.js +24 -0
- package/dist/lib/css/property-descriptors/list-style-image.js +17 -0
- package/dist/lib/css/property-descriptors/list-style-position.js +18 -0
- package/dist/lib/css/property-descriptors/list-style-type.js +122 -0
- package/dist/lib/css/property-descriptors/margin.js +13 -0
- package/dist/lib/css/property-descriptors/mix-blend-mode.js +31 -0
- package/dist/lib/css/property-descriptors/object-fit.js +28 -0
- package/dist/lib/css/property-descriptors/object-position.js +42 -0
- package/dist/lib/css/property-descriptors/opacity.js +16 -0
- package/dist/lib/css/property-descriptors/overflow-wrap.js +18 -0
- package/dist/lib/css/property-descriptors/overflow.js +27 -0
- package/dist/lib/css/property-descriptors/padding.js +14 -0
- package/dist/lib/css/property-descriptors/paint-order.js +33 -0
- package/dist/lib/css/property-descriptors/position.js +22 -0
- package/dist/lib/css/property-descriptors/quotes.js +41 -0
- package/dist/lib/css/property-descriptors/rotate.js +27 -0
- package/dist/lib/css/property-descriptors/text-align.js +21 -0
- package/dist/lib/css/property-descriptors/text-decoration-color.js +10 -0
- package/dist/lib/css/property-descriptors/text-decoration-line.js +28 -0
- package/dist/lib/css/property-descriptors/text-decoration-style.js +24 -0
- package/dist/lib/css/property-descriptors/text-decoration-thickness.js +26 -0
- package/dist/lib/css/property-descriptors/text-overflow.js +18 -0
- package/dist/lib/css/property-descriptors/text-shadow.js +46 -0
- package/dist/lib/css/property-descriptors/text-transform.js +20 -0
- package/dist/lib/css/property-descriptors/text-underline-offset.js +23 -0
- package/dist/lib/css/property-descriptors/transform-origin.js +24 -0
- package/dist/lib/css/property-descriptors/transform.js +57 -0
- package/dist/lib/css/property-descriptors/visibility.js +20 -0
- package/dist/lib/css/property-descriptors/webkit-line-clamp.js +26 -0
- package/dist/lib/css/property-descriptors/webkit-text-stroke-color.js +10 -0
- package/dist/lib/css/property-descriptors/webkit-text-stroke-width.js +16 -0
- package/dist/lib/css/property-descriptors/word-break.js +26 -0
- package/dist/lib/css/property-descriptors/writing-mode.js +28 -0
- package/dist/lib/css/property-descriptors/z-index.js +19 -0
- package/dist/lib/css/property-descriptors/zoom.js +18 -0
- package/dist/lib/css/syntax/parser.js +140 -0
- package/dist/lib/css/syntax/token-constants.js +214 -0
- package/dist/lib/css/syntax/token-singletons.js +36 -0
- package/dist/lib/css/syntax/token-types.js +10 -0
- package/dist/lib/css/syntax/tokenizer.js +502 -0
- package/dist/lib/css/type-descriptor.js +2 -0
- package/dist/lib/css/types/angle.js +80 -0
- package/dist/lib/css/types/color-math.js +25 -0
- package/dist/lib/css/types/color-spaces/a98.js +78 -0
- package/dist/lib/css/types/color-spaces/p3.js +86 -0
- package/dist/lib/css/types/color-spaces/pro-photo.js +83 -0
- package/dist/lib/css/types/color-spaces/rec2020.js +85 -0
- package/dist/lib/css/types/color-spaces/srgb.js +79 -0
- package/dist/lib/css/types/color-utilities.js +342 -0
- package/dist/lib/css/types/color.js +400 -0
- package/dist/lib/css/types/functions/-prefix-linear-gradient.js +32 -0
- package/dist/lib/css/types/functions/-prefix-radial-gradient.js +83 -0
- package/dist/lib/css/types/functions/-webkit-gradient.js +59 -0
- package/dist/lib/css/types/functions/counter.js +367 -0
- package/dist/lib/css/types/functions/gradient.js +163 -0
- package/dist/lib/css/types/functions/linear-gradient.js +27 -0
- package/dist/lib/css/types/functions/radial-gradient.js +90 -0
- package/dist/lib/css/types/functions/repeating-linear-gradient.js +9 -0
- package/dist/lib/css/types/image.js +62 -0
- package/dist/lib/css/types/index.js +2 -0
- package/dist/lib/css/types/length-percentage.js +197 -0
- package/dist/lib/css/types/length.js +5 -0
- package/dist/lib/css/types/safe-eval.js +80 -0
- package/dist/lib/css/types/time.js +17 -0
- package/dist/lib/dom/document-cloner.js +597 -0
- package/dist/lib/dom/dom-normalizer.js +115 -0
- package/dist/lib/dom/element-container.js +56 -0
- package/dist/lib/dom/elements/li-element-container.js +11 -0
- package/dist/lib/dom/elements/ol-element-container.js +12 -0
- package/dist/lib/dom/elements/select-element-container.js +12 -0
- package/dist/lib/dom/elements/textarea-element-container.js +11 -0
- package/dist/lib/dom/node-parser.js +112 -0
- package/dist/lib/dom/node-type-guards.js +81 -0
- package/dist/lib/dom/replaced-elements/canvas-element-container.js +13 -0
- package/dist/lib/dom/replaced-elements/iframe-element-container.js +38 -0
- package/dist/lib/dom/replaced-elements/image-element-container.js +14 -0
- package/dist/lib/dom/replaced-elements/index.js +2 -0
- package/dist/lib/dom/replaced-elements/input-element-container.js +89 -0
- package/dist/lib/dom/replaced-elements/svg-element-container.js +19 -0
- package/dist/lib/dom/slot-cloner.js +176 -0
- package/dist/lib/dom/text-container.js +35 -0
- package/dist/lib/index.js +49 -0
- package/dist/lib/options.js +2 -0
- package/dist/lib/render/background.js +188 -0
- package/dist/lib/render/bezier-curve.js +34 -0
- package/dist/lib/render/border.js +104 -0
- package/dist/lib/render/bound-curves.js +188 -0
- package/dist/lib/render/box-sizing.js +20 -0
- package/dist/lib/render/canvas/background-renderer.js +327 -0
- package/dist/lib/render/canvas/border-image-renderer.js +153 -0
- package/dist/lib/render/canvas/border-renderer.js +184 -0
- package/dist/lib/render/canvas/canvas-path.js +25 -0
- package/dist/lib/render/canvas/canvas-renderer.js +312 -0
- package/dist/lib/render/canvas/content-renderer.js +204 -0
- package/dist/lib/render/canvas/effects-renderer.js +171 -0
- package/dist/lib/render/canvas/font-utils.js +29 -0
- package/dist/lib/render/canvas/foreignobject-renderer.js +38 -0
- package/dist/lib/render/canvas/text/text-decoration-renderer.js +99 -0
- package/dist/lib/render/canvas/text-renderer.js +485 -0
- package/dist/lib/render/effects.js +231 -0
- package/dist/lib/render/font-metrics.js +53 -0
- package/dist/lib/render/object-fit.js +91 -0
- package/dist/lib/render/path.js +26 -0
- package/dist/lib/render/renderer-interface.js +2 -0
- package/dist/lib/render/stacking-context.js +340 -0
- package/dist/lib/render/vector.js +16 -0
- package/dist/types/config.d.ts +44 -0
- package/dist/types/core/abort-helper.d.ts +12 -0
- package/dist/types/core/background-parser.d.ts +16 -0
- package/dist/types/core/bitwise.d.ts +1 -0
- package/dist/types/core/cache-storage.d.ts +68 -0
- package/dist/types/core/config-assembler.d.ts +28 -0
- package/dist/types/core/constants.d.ts +22 -0
- package/dist/types/core/context.d.ts +22 -0
- package/dist/types/core/debugger.d.ts +8 -0
- package/dist/types/core/features.d.ts +12 -0
- package/dist/types/core/logger.d.ts +18 -0
- package/dist/types/core/lru-map.d.ts +37 -0
- package/dist/types/core/origin-checker.d.ts +33 -0
- package/dist/types/core/performance-monitor.d.ts +120 -0
- package/dist/types/core/render-element.d.ts +3 -0
- package/dist/types/core/util.d.ts +1 -0
- package/dist/types/core/validator.d.ts +130 -0
- package/dist/types/css/grouped/background-styles.d.ts +16 -0
- package/dist/types/css/grouped/border-styles.d.ts +31 -0
- package/dist/types/css/grouped/font-styles.d.ts +35 -0
- package/dist/types/css/grouped/layout-styles.d.ts +46 -0
- package/dist/types/css/index.d.ts +185 -0
- package/dist/types/css/layout/bounds.d.ts +14 -0
- package/dist/types/css/layout/text.d.ts +10 -0
- package/dist/types/css/property-descriptor.d.ts +40 -0
- package/dist/types/css/property-descriptors/background-blend-mode.d.ts +23 -0
- package/dist/types/css/property-descriptors/background-clip.d.ts +8 -0
- package/dist/types/css/property-descriptors/background-color.d.ts +2 -0
- package/dist/types/css/property-descriptors/background-image.d.ts +3 -0
- package/dist/types/css/property-descriptors/background-origin.d.ts +8 -0
- package/dist/types/css/property-descriptors/background-position.d.ts +5 -0
- package/dist/types/css/property-descriptors/background-repeat.d.ts +9 -0
- package/dist/types/css/property-descriptors/background-size.d.ts +11 -0
- package/dist/types/css/property-descriptors/border-color.d.ts +5 -0
- package/dist/types/css/property-descriptors/border-image-repeat.d.ts +12 -0
- package/dist/types/css/property-descriptors/border-image-slice.d.ts +10 -0
- package/dist/types/css/property-descriptors/border-image-source.d.ts +4 -0
- package/dist/types/css/property-descriptors/border-radius.d.ts +7 -0
- package/dist/types/css/property-descriptors/border-style.d.ts +12 -0
- package/dist/types/css/property-descriptors/border-width.d.ts +5 -0
- package/dist/types/css/property-descriptors/box-decoration-break.d.ts +6 -0
- package/dist/types/css/property-descriptors/box-shadow.d.ts +14 -0
- package/dist/types/css/property-descriptors/clip-path.d.ts +62 -0
- package/dist/types/css/property-descriptors/color.d.ts +2 -0
- package/dist/types/css/property-descriptors/content.d.ts +4 -0
- package/dist/types/css/property-descriptors/counter-increment.d.ts +10 -0
- package/dist/types/css/property-descriptors/counter-reset.d.ts +7 -0
- package/dist/types/css/property-descriptors/direction.d.ts +6 -0
- package/dist/types/css/property-descriptors/display.d.ts +35 -0
- package/dist/types/css/property-descriptors/duration.d.ts +2 -0
- package/dist/types/css/property-descriptors/filter.d.ts +3 -0
- package/dist/types/css/property-descriptors/float.d.ts +9 -0
- package/dist/types/css/property-descriptors/font-family.d.ts +4 -0
- package/dist/types/css/property-descriptors/font-size.d.ts +2 -0
- package/dist/types/css/property-descriptors/font-style.d.ts +7 -0
- package/dist/types/css/property-descriptors/font-variant-ligatures.d.ts +14 -0
- package/dist/types/css/property-descriptors/font-variant.d.ts +2 -0
- package/dist/types/css/property-descriptors/font-weight.d.ts +2 -0
- package/dist/types/css/property-descriptors/image-rendering.d.ts +8 -0
- package/dist/types/css/property-descriptors/letter-spacing.d.ts +2 -0
- package/dist/types/css/property-descriptors/line-break.d.ts +6 -0
- package/dist/types/css/property-descriptors/line-height.d.ts +4 -0
- package/dist/types/css/property-descriptors/list-style-image.d.ts +3 -0
- package/dist/types/css/property-descriptors/list-style-position.d.ts +6 -0
- package/dist/types/css/property-descriptors/list-style-type.d.ts +58 -0
- package/dist/types/css/property-descriptors/margin.d.ts +5 -0
- package/dist/types/css/property-descriptors/mix-blend-mode.d.ts +21 -0
- package/dist/types/css/property-descriptors/object-fit.d.ts +10 -0
- package/dist/types/css/property-descriptors/object-position.d.ts +4 -0
- package/dist/types/css/property-descriptors/opacity.d.ts +2 -0
- package/dist/types/css/property-descriptors/overflow-wrap.d.ts +6 -0
- package/dist/types/css/property-descriptors/overflow.d.ts +9 -0
- package/dist/types/css/property-descriptors/padding.d.ts +5 -0
- package/dist/types/css/property-descriptors/paint-order.d.ts +8 -0
- package/dist/types/css/property-descriptors/position.d.ts +9 -0
- package/dist/types/css/property-descriptors/quotes.d.ts +8 -0
- package/dist/types/css/property-descriptors/rotate.d.ts +3 -0
- package/dist/types/css/property-descriptors/text-align.d.ts +7 -0
- package/dist/types/css/property-descriptors/text-decoration-color.d.ts +2 -0
- package/dist/types/css/property-descriptors/text-decoration-line.d.ts +10 -0
- package/dist/types/css/property-descriptors/text-decoration-style.d.ts +9 -0
- package/dist/types/css/property-descriptors/text-decoration-thickness.d.ts +3 -0
- package/dist/types/css/property-descriptors/text-overflow.d.ts +6 -0
- package/dist/types/css/property-descriptors/text-shadow.d.ts +12 -0
- package/dist/types/css/property-descriptors/text-transform.d.ts +8 -0
- package/dist/types/css/property-descriptors/text-underline-offset.d.ts +3 -0
- package/dist/types/css/property-descriptors/transform-origin.d.ts +4 -0
- package/dist/types/css/property-descriptors/transform.d.ts +4 -0
- package/dist/types/css/property-descriptors/visibility.d.ts +7 -0
- package/dist/types/css/property-descriptors/webkit-line-clamp.d.ts +7 -0
- package/dist/types/css/property-descriptors/webkit-text-stroke-color.d.ts +2 -0
- package/dist/types/css/property-descriptors/webkit-text-stroke-width.d.ts +2 -0
- package/dist/types/css/property-descriptors/word-break.d.ts +7 -0
- package/dist/types/css/property-descriptors/writing-mode.d.ts +11 -0
- package/dist/types/css/property-descriptors/z-index.d.ts +7 -0
- package/dist/types/css/property-descriptors/zoom.d.ts +3 -0
- package/dist/types/css/syntax/parser.d.ts +34 -0
- package/dist/types/css/syntax/token-constants.d.ts +74 -0
- package/dist/types/css/syntax/token-singletons.d.ts +22 -0
- package/dist/types/css/syntax/token-types.d.ts +72 -0
- package/dist/types/css/syntax/tokenizer.d.ts +32 -0
- package/dist/types/css/type-descriptor.d.ts +6 -0
- package/dist/types/css/types/angle.d.ts +7 -0
- package/dist/types/css/types/color-math.d.ts +12 -0
- package/dist/types/css/types/color-spaces/a98.d.ts +39 -0
- package/dist/types/css/types/color-spaces/p3.d.ts +45 -0
- package/dist/types/css/types/color-spaces/pro-photo.d.ts +45 -0
- package/dist/types/css/types/color-spaces/rec2020.d.ts +45 -0
- package/dist/types/css/types/color-spaces/srgb.d.ts +38 -0
- package/dist/types/css/types/color-utilities.d.ts +107 -0
- package/dist/types/css/types/color.d.ts +8 -0
- package/dist/types/css/types/functions/-prefix-linear-gradient.d.ts +4 -0
- package/dist/types/css/types/functions/-prefix-radial-gradient.d.ts +4 -0
- package/dist/types/css/types/functions/-webkit-gradient.d.ts +4 -0
- package/dist/types/css/types/functions/counter.d.ts +10 -0
- package/dist/types/css/types/functions/gradient.d.ts +7 -0
- package/dist/types/css/types/functions/linear-gradient.d.ts +4 -0
- package/dist/types/css/types/functions/radial-gradient.d.ts +12 -0
- package/dist/types/css/types/functions/repeating-linear-gradient.d.ts +4 -0
- package/dist/types/css/types/image.d.ts +56 -0
- package/dist/types/css/types/index.d.ts +1 -0
- package/dist/types/css/types/length-percentage.d.ts +62 -0
- package/dist/types/css/types/length.d.ts +4 -0
- package/dist/types/css/types/safe-eval.d.ts +8 -0
- package/dist/types/css/types/time.d.ts +2 -0
- package/dist/types/dom/document-cloner.d.ts +57 -0
- package/dist/types/dom/dom-normalizer.d.ts +62 -0
- package/dist/types/dom/element-container.d.ts +31 -0
- package/dist/types/dom/elements/li-element-container.d.ts +6 -0
- package/dist/types/dom/elements/ol-element-container.d.ts +7 -0
- package/dist/types/dom/elements/select-element-container.d.ts +6 -0
- package/dist/types/dom/elements/textarea-element-container.d.ts +6 -0
- package/dist/types/dom/node-parser.d.ts +3 -0
- package/dist/types/dom/node-type-guards.d.ts +32 -0
- package/dist/types/dom/replaced-elements/canvas-element-container.d.ts +8 -0
- package/dist/types/dom/replaced-elements/iframe-element-container.d.ts +14 -0
- package/dist/types/dom/replaced-elements/image-element-container.d.ts +8 -0
- package/dist/types/dom/replaced-elements/index.d.ts +4 -0
- package/dist/types/dom/replaced-elements/input-element-container.d.ts +14 -0
- package/dist/types/dom/replaced-elements/svg-element-container.d.ts +8 -0
- package/dist/types/dom/slot-cloner.d.ts +66 -0
- package/dist/types/dom/text-container.d.ts +8 -0
- package/dist/types/index.d.ts +36 -0
- package/dist/types/options.d.ts +62 -0
- package/dist/types/render/background.d.ts +16 -0
- package/dist/types/render/bezier-curve.d.ts +14 -0
- package/dist/types/render/border.d.ts +6 -0
- package/dist/types/render/bound-curves.d.ts +32 -0
- package/dist/types/render/box-sizing.d.ts +4 -0
- package/dist/types/render/canvas/background-renderer.d.ts +94 -0
- package/dist/types/render/canvas/border-image-renderer.d.ts +18 -0
- package/dist/types/render/canvas/border-renderer.d.ts +67 -0
- package/dist/types/render/canvas/canvas-path.d.ts +3 -0
- package/dist/types/render/canvas/canvas-renderer.d.ts +60 -0
- package/dist/types/render/canvas/content-renderer.d.ts +43 -0
- package/dist/types/render/canvas/effects-renderer.d.ts +90 -0
- package/dist/types/render/canvas/font-utils.d.ts +19 -0
- package/dist/types/render/canvas/foreignobject-renderer.d.ts +10 -0
- package/dist/types/render/canvas/text/text-decoration-renderer.d.ts +18 -0
- package/dist/types/render/canvas/text-renderer.d.ts +103 -0
- package/dist/types/render/effects.d.ts +112 -0
- package/dist/types/render/font-metrics.d.ts +11 -0
- package/dist/types/render/object-fit.d.ts +19 -0
- package/dist/types/render/path.d.ts +13 -0
- package/dist/types/render/renderer-interface.d.ts +28 -0
- package/dist/types/render/stacking-context.d.ts +49 -0
- package/dist/types/render/vector.d.ts +9 -0
- package/package.json +139 -4
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Border Image Renderer
|
|
4
|
+
*
|
|
5
|
+
* Renders CSS border-image using 9-slice scaling.
|
|
6
|
+
* The source image is divided into 9 regions (4 corners, 4 edges, 1 center)
|
|
7
|
+
* based on border-image-slice values, then each region is drawn to the
|
|
8
|
+
* corresponding area of the element's border box.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.BorderImageRenderer = void 0;
|
|
12
|
+
const border_image_repeat_1 = require("../../css/property-descriptors/border-image-repeat");
|
|
13
|
+
class BorderImageRenderer {
|
|
14
|
+
constructor(ctx) {
|
|
15
|
+
this.ctx = ctx;
|
|
16
|
+
}
|
|
17
|
+
renderBorderImage(bounds, image, slice, repeat, borderTopWidth, borderRightWidth, borderBottomWidth, borderLeftWidth) {
|
|
18
|
+
const imgW = image.naturalWidth || image.width;
|
|
19
|
+
const imgH = image.naturalHeight || image.height;
|
|
20
|
+
if (imgW <= 0 || imgH <= 0) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
// Calculate source slice positions in image pixel space
|
|
24
|
+
const sT = Math.min(slice.unit === 'percent' ? (slice.top / 100) * imgH : Math.min(slice.top, imgH), imgH);
|
|
25
|
+
const sR = Math.min(slice.unit === 'percent' ? (slice.right / 100) * imgW : Math.min(slice.right, imgW), imgW);
|
|
26
|
+
const sB = Math.min(slice.unit === 'percent' ? (slice.bottom / 100) * imgH : Math.min(slice.bottom, imgH), imgH);
|
|
27
|
+
const sL = Math.min(slice.unit === 'percent' ? (slice.left / 100) * imgW : Math.min(slice.left, imgW), imgW);
|
|
28
|
+
const { left, top, width, height } = bounds;
|
|
29
|
+
if (width <= 0 || height <= 0) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
// Clamp border widths to available box dimensions
|
|
33
|
+
const dT = Math.min(borderTopWidth, height);
|
|
34
|
+
const dR = Math.min(borderRightWidth, width);
|
|
35
|
+
const dB = Math.min(borderBottomWidth, height - dT);
|
|
36
|
+
const dL = Math.min(borderLeftWidth, width - dR);
|
|
37
|
+
// Draw corners
|
|
38
|
+
this.drawRegion(image, 0, 0, sL, sT, left, top, dL, dT);
|
|
39
|
+
this.drawRegion(image, imgW - sR, 0, sR, sT, left + width - dR, top, dR, dT);
|
|
40
|
+
this.drawRegion(image, imgW - sR, imgH - sB, sR, sB, left + width - dR, top + height - dB, dR, dB);
|
|
41
|
+
this.drawRegion(image, 0, imgH - sB, sL, sB, left, top + height - dB, dL, dB);
|
|
42
|
+
// Draw edges
|
|
43
|
+
const edges = [
|
|
44
|
+
{
|
|
45
|
+
sx: sL,
|
|
46
|
+
sy: 0,
|
|
47
|
+
sw: imgW - sL - sR,
|
|
48
|
+
sh: sT,
|
|
49
|
+
dx: left + dL,
|
|
50
|
+
dy: top,
|
|
51
|
+
dw: width - dL - dR,
|
|
52
|
+
dh: dT,
|
|
53
|
+
repeat: repeat.horizontal
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
sx: imgW - sR,
|
|
57
|
+
sy: sT,
|
|
58
|
+
sw: sR,
|
|
59
|
+
sh: imgH - sT - sB,
|
|
60
|
+
dx: left + width - dR,
|
|
61
|
+
dy: top + dT,
|
|
62
|
+
dw: dR,
|
|
63
|
+
dh: height - dT - dB,
|
|
64
|
+
repeat: repeat.vertical
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
sx: sL,
|
|
68
|
+
sy: imgH - sB,
|
|
69
|
+
sw: imgW - sL - sR,
|
|
70
|
+
sh: sB,
|
|
71
|
+
dx: left + dL,
|
|
72
|
+
dy: top + height - dB,
|
|
73
|
+
dw: width - dL - dR,
|
|
74
|
+
dh: dB,
|
|
75
|
+
repeat: repeat.horizontal
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
sx: 0,
|
|
79
|
+
sy: sT,
|
|
80
|
+
sw: sL,
|
|
81
|
+
sh: imgH - sT - sB,
|
|
82
|
+
dx: left,
|
|
83
|
+
dy: top + dT,
|
|
84
|
+
dw: dL,
|
|
85
|
+
dh: height - dT - dB,
|
|
86
|
+
repeat: repeat.vertical
|
|
87
|
+
}
|
|
88
|
+
];
|
|
89
|
+
for (const edge of edges) {
|
|
90
|
+
if (edge.sw <= 0 || edge.sh <= 0 || edge.dw <= 0 || edge.dh <= 0)
|
|
91
|
+
continue;
|
|
92
|
+
const isHorizontal = edge.dw >= edge.dh;
|
|
93
|
+
if (edge.repeat === border_image_repeat_1.BORDER_IMAGE_REPEAT.STRETCH) {
|
|
94
|
+
this.ctx.drawImage(image, edge.sx, edge.sy, edge.sw, edge.sh, edge.dx, edge.dy, edge.dw, edge.dh);
|
|
95
|
+
}
|
|
96
|
+
else if (edge.repeat === border_image_repeat_1.BORDER_IMAGE_REPEAT.REPEAT || edge.repeat === border_image_repeat_1.BORDER_IMAGE_REPEAT.ROUND) {
|
|
97
|
+
this.drawRepeatedEdge(image, edge, isHorizontal, edge.repeat === border_image_repeat_1.BORDER_IMAGE_REPEAT.ROUND);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// Draw center if fill is specified
|
|
101
|
+
if (slice.fill) {
|
|
102
|
+
const cx = sL;
|
|
103
|
+
const cy = sT;
|
|
104
|
+
const cw = imgW - sL - sR;
|
|
105
|
+
const ch = imgH - sT - sB;
|
|
106
|
+
const tcx = left + dL;
|
|
107
|
+
const tcy = top + dT;
|
|
108
|
+
const tcw = width - dL - dR;
|
|
109
|
+
const tch = height - dT - dB;
|
|
110
|
+
this.drawRegion(image, cx, cy, cw, ch, tcx, tcy, tcw, tch);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
drawRegion(image, sx, sy, sw, sh, dx, dy, dw, dh) {
|
|
114
|
+
if (sw > 0 && sh > 0 && dw > 0 && dh > 0) {
|
|
115
|
+
this.ctx.drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
drawRepeatedEdge(image, edge, isHorizontal, round) {
|
|
119
|
+
const srcLength = isHorizontal ? edge.sw : edge.sh;
|
|
120
|
+
const tgLength = isHorizontal ? edge.dw : edge.dh;
|
|
121
|
+
if (srcLength <= 0 || tgLength <= 0)
|
|
122
|
+
return;
|
|
123
|
+
let tileSize;
|
|
124
|
+
let tileCount;
|
|
125
|
+
if (round) {
|
|
126
|
+
tileCount = Math.max(1, Math.round(tgLength / srcLength));
|
|
127
|
+
tileSize = tgLength / tileCount;
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
tileSize = srcLength;
|
|
131
|
+
tileCount = Math.ceil(tgLength / tileSize);
|
|
132
|
+
}
|
|
133
|
+
this.ctx.save();
|
|
134
|
+
this.ctx.beginPath();
|
|
135
|
+
this.ctx.rect(edge.dx, edge.dy, edge.dw, edge.dh);
|
|
136
|
+
this.ctx.clip();
|
|
137
|
+
for (let i = 0; i < tileCount; i++) {
|
|
138
|
+
const offset = i * tileSize;
|
|
139
|
+
const remaining = tgLength - offset;
|
|
140
|
+
const clampedSize = Math.min(tileSize, remaining);
|
|
141
|
+
if (clampedSize <= 0)
|
|
142
|
+
break;
|
|
143
|
+
if (isHorizontal) {
|
|
144
|
+
this.ctx.drawImage(image, edge.sx, edge.sy, edge.sw, edge.sh, edge.dx + offset, edge.dy, clampedSize, edge.dh);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
this.ctx.drawImage(image, edge.sx, edge.sy, edge.sw, edge.sh, edge.dx, edge.dy + offset, edge.dw, clampedSize);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
this.ctx.restore();
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
exports.BorderImageRenderer = BorderImageRenderer;
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Border Renderer
|
|
4
|
+
*
|
|
5
|
+
* Handles rendering of element borders including:
|
|
6
|
+
* - Solid borders
|
|
7
|
+
* - Double borders
|
|
8
|
+
* - Dashed borders
|
|
9
|
+
* - Dotted borders
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.BorderRenderer = void 0;
|
|
13
|
+
const color_utilities_1 = require("../../css/types/color-utilities");
|
|
14
|
+
const border_1 = require("../border");
|
|
15
|
+
const bezier_curve_1 = require("../bezier-curve");
|
|
16
|
+
const vector_1 = require("../vector");
|
|
17
|
+
/**
|
|
18
|
+
* Border Renderer
|
|
19
|
+
*
|
|
20
|
+
* Specialized renderer for element borders.
|
|
21
|
+
* Extracted from CanvasRenderer to improve code organization and maintainability.
|
|
22
|
+
*/
|
|
23
|
+
class BorderRenderer {
|
|
24
|
+
constructor(deps, pathCallbacks) {
|
|
25
|
+
this.ctx = deps.ctx;
|
|
26
|
+
this.pathCallbacks = pathCallbacks;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Render a solid border
|
|
30
|
+
*
|
|
31
|
+
* @param color - Border color
|
|
32
|
+
* @param side - Border side (0=top, 1=right, 2=bottom, 3=left)
|
|
33
|
+
* @param curvePoints - Border curve points
|
|
34
|
+
*/
|
|
35
|
+
async renderSolidBorder(color, side, curvePoints) {
|
|
36
|
+
this.pathCallbacks.path((0, border_1.parsePathForBorder)(curvePoints, side));
|
|
37
|
+
this.ctx.fillStyle = (0, color_utilities_1.asString)(color);
|
|
38
|
+
this.ctx.fill();
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Render a double border
|
|
42
|
+
* Falls back to solid border if width is too small
|
|
43
|
+
*
|
|
44
|
+
* @param color - Border color
|
|
45
|
+
* @param width - Border width
|
|
46
|
+
* @param side - Border side (0=top, 1=right, 2=bottom, 3=left)
|
|
47
|
+
* @param curvePoints - Border curve points
|
|
48
|
+
*/
|
|
49
|
+
async renderDoubleBorder(color, width, side, curvePoints) {
|
|
50
|
+
if (width < 3) {
|
|
51
|
+
await this.renderSolidBorder(color, side, curvePoints);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const outerPaths = (0, border_1.parsePathForBorderDoubleOuter)(curvePoints, side);
|
|
55
|
+
this.pathCallbacks.path(outerPaths);
|
|
56
|
+
this.ctx.fillStyle = (0, color_utilities_1.asString)(color);
|
|
57
|
+
this.ctx.fill();
|
|
58
|
+
const innerPaths = (0, border_1.parsePathForBorderDoubleInner)(curvePoints, side);
|
|
59
|
+
this.pathCallbacks.path(innerPaths);
|
|
60
|
+
this.ctx.fill();
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Render a dashed or dotted border
|
|
64
|
+
*
|
|
65
|
+
* @param color - Border color
|
|
66
|
+
* @param width - Border width
|
|
67
|
+
* @param side - Border side (0=top, 1=right, 2=bottom, 3=left)
|
|
68
|
+
* @param curvePoints - Border curve points
|
|
69
|
+
* @param style - Border style (DASHED or DOTTED)
|
|
70
|
+
*/
|
|
71
|
+
async renderDashedDottedBorder(color, width, side, curvePoints, style) {
|
|
72
|
+
this.ctx.save();
|
|
73
|
+
const strokePaths = (0, border_1.parsePathForBorderStroke)(curvePoints, side);
|
|
74
|
+
const boxPaths = (0, border_1.parsePathForBorder)(curvePoints, side);
|
|
75
|
+
if (style === 2 /* BORDER_STYLE.DASHED */) {
|
|
76
|
+
this.pathCallbacks.path(boxPaths);
|
|
77
|
+
this.ctx.clip();
|
|
78
|
+
}
|
|
79
|
+
// Extract start and end coordinates
|
|
80
|
+
let startX, startY, endX, endY;
|
|
81
|
+
if ((0, bezier_curve_1.isBezierCurve)(boxPaths[0])) {
|
|
82
|
+
startX = boxPaths[0].start.x;
|
|
83
|
+
startY = boxPaths[0].start.y;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
startX = boxPaths[0].x;
|
|
87
|
+
startY = boxPaths[0].y;
|
|
88
|
+
}
|
|
89
|
+
if ((0, bezier_curve_1.isBezierCurve)(boxPaths[1])) {
|
|
90
|
+
endX = boxPaths[1].end.x;
|
|
91
|
+
endY = boxPaths[1].end.y;
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
endX = boxPaths[1].x;
|
|
95
|
+
endY = boxPaths[1].y;
|
|
96
|
+
}
|
|
97
|
+
// Calculate border length
|
|
98
|
+
let length;
|
|
99
|
+
if (side === 0 || side === 2) {
|
|
100
|
+
length = Math.abs(startX - endX);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
length = Math.abs(startY - endY);
|
|
104
|
+
}
|
|
105
|
+
this.ctx.beginPath();
|
|
106
|
+
if (style === 3 /* BORDER_STYLE.DOTTED */) {
|
|
107
|
+
this.pathCallbacks.formatPath(strokePaths);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
this.pathCallbacks.formatPath(boxPaths.slice(0, 2));
|
|
111
|
+
}
|
|
112
|
+
// Calculate dash and space lengths
|
|
113
|
+
let dashLength = width < 3 ? width * 3 : width * 2;
|
|
114
|
+
let spaceLength = width < 3 ? width * 2 : width;
|
|
115
|
+
if (style === 3 /* BORDER_STYLE.DOTTED */) {
|
|
116
|
+
dashLength = width;
|
|
117
|
+
spaceLength = width;
|
|
118
|
+
}
|
|
119
|
+
// Adjust dash pattern for border length
|
|
120
|
+
let useLineDash = true;
|
|
121
|
+
if (length <= dashLength * 2) {
|
|
122
|
+
useLineDash = false;
|
|
123
|
+
}
|
|
124
|
+
else if (length <= dashLength * 2 + spaceLength) {
|
|
125
|
+
const multiplier = length / (2 * dashLength + spaceLength);
|
|
126
|
+
dashLength *= multiplier;
|
|
127
|
+
spaceLength *= multiplier;
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
const numberOfDashes = Math.floor((length + spaceLength) / (dashLength + spaceLength));
|
|
131
|
+
const minSpace = (length - numberOfDashes * dashLength) / (numberOfDashes - 1);
|
|
132
|
+
const maxSpace = (length - (numberOfDashes + 1) * dashLength) / numberOfDashes;
|
|
133
|
+
spaceLength =
|
|
134
|
+
maxSpace <= 0 || Math.abs(spaceLength - minSpace) < Math.abs(spaceLength - maxSpace)
|
|
135
|
+
? minSpace
|
|
136
|
+
: maxSpace;
|
|
137
|
+
}
|
|
138
|
+
// Apply line dash pattern
|
|
139
|
+
if (useLineDash) {
|
|
140
|
+
if (style === 3 /* BORDER_STYLE.DOTTED */) {
|
|
141
|
+
this.ctx.setLineDash([0, dashLength + spaceLength]);
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
this.ctx.setLineDash([dashLength, spaceLength]);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
// Set line style and stroke
|
|
148
|
+
if (style === 3 /* BORDER_STYLE.DOTTED */) {
|
|
149
|
+
this.ctx.lineCap = 'round';
|
|
150
|
+
this.ctx.lineWidth = width;
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
this.ctx.lineWidth = width * 2 + 1.1;
|
|
154
|
+
}
|
|
155
|
+
this.ctx.strokeStyle = (0, color_utilities_1.asString)(color);
|
|
156
|
+
this.ctx.stroke();
|
|
157
|
+
this.ctx.setLineDash([]);
|
|
158
|
+
// Fill dashed round edge gaps
|
|
159
|
+
if (style === 2 /* BORDER_STYLE.DASHED */) {
|
|
160
|
+
if ((0, bezier_curve_1.isBezierCurve)(boxPaths[0])) {
|
|
161
|
+
const path1 = boxPaths[3];
|
|
162
|
+
const path2 = boxPaths[0];
|
|
163
|
+
this.ctx.beginPath();
|
|
164
|
+
this.pathCallbacks.formatPath([
|
|
165
|
+
new vector_1.Vector(path1.end.x, path1.end.y),
|
|
166
|
+
new vector_1.Vector(path2.start.x, path2.start.y)
|
|
167
|
+
]);
|
|
168
|
+
this.ctx.stroke();
|
|
169
|
+
}
|
|
170
|
+
if ((0, bezier_curve_1.isBezierCurve)(boxPaths[1])) {
|
|
171
|
+
const path1 = boxPaths[1];
|
|
172
|
+
const path2 = boxPaths[2];
|
|
173
|
+
this.ctx.beginPath();
|
|
174
|
+
this.pathCallbacks.formatPath([
|
|
175
|
+
new vector_1.Vector(path1.end.x, path1.end.y),
|
|
176
|
+
new vector_1.Vector(path2.start.x, path2.start.y)
|
|
177
|
+
]);
|
|
178
|
+
this.ctx.stroke();
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
this.ctx.restore();
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
exports.BorderRenderer = BorderRenderer;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createCanvasPath = exports.formatCanvasPath = void 0;
|
|
4
|
+
const bezier_curve_1 = require("../bezier-curve");
|
|
5
|
+
const formatCanvasPath = (ctx, paths) => {
|
|
6
|
+
paths.forEach((point, index) => {
|
|
7
|
+
const start = (0, bezier_curve_1.isBezierCurve)(point) ? point.start : point;
|
|
8
|
+
if (index === 0) {
|
|
9
|
+
ctx.moveTo(start.x, start.y);
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
ctx.lineTo(start.x, start.y);
|
|
13
|
+
}
|
|
14
|
+
if ((0, bezier_curve_1.isBezierCurve)(point)) {
|
|
15
|
+
ctx.bezierCurveTo(point.startControl.x, point.startControl.y, point.endControl.x, point.endControl.y, point.end.x, point.end.y);
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
exports.formatCanvasPath = formatCanvasPath;
|
|
20
|
+
const createCanvasPath = (ctx, paths) => {
|
|
21
|
+
ctx.beginPath();
|
|
22
|
+
(0, exports.formatCanvasPath)(ctx, paths);
|
|
23
|
+
ctx.closePath();
|
|
24
|
+
};
|
|
25
|
+
exports.createCanvasPath = createCanvasPath;
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CanvasRenderer = void 0;
|
|
4
|
+
const stacking_context_1 = require("../stacking-context");
|
|
5
|
+
const color_utilities_1 = require("../../css/types/color-utilities");
|
|
6
|
+
const path_1 = require("../path");
|
|
7
|
+
const bound_curves_1 = require("../bound-curves");
|
|
8
|
+
const background_1 = require("../background");
|
|
9
|
+
const box_sizing_1 = require("../box-sizing");
|
|
10
|
+
const text_renderer_1 = require("./text-renderer");
|
|
11
|
+
const background_renderer_1 = require("./background-renderer");
|
|
12
|
+
const border_renderer_1 = require("./border-renderer");
|
|
13
|
+
const border_image_renderer_1 = require("./border-image-renderer");
|
|
14
|
+
const effects_renderer_1 = require("./effects-renderer");
|
|
15
|
+
const canvas_path_1 = require("./canvas-path");
|
|
16
|
+
const object_fit_1 = require("../object-fit");
|
|
17
|
+
const content_renderer_1 = require("./content-renderer");
|
|
18
|
+
const constants_1 = require("../../core/constants");
|
|
19
|
+
class CanvasRenderer {
|
|
20
|
+
constructor(context, options) {
|
|
21
|
+
this.context = context;
|
|
22
|
+
this.options = options;
|
|
23
|
+
this.canvas = options.canvas ? options.canvas : document.createElement('canvas');
|
|
24
|
+
const ctx = this.canvas.getContext('2d');
|
|
25
|
+
if (!ctx) {
|
|
26
|
+
throw new Error('Failed to get 2D rendering context from canvas');
|
|
27
|
+
}
|
|
28
|
+
this.ctx = ctx;
|
|
29
|
+
if (!options.canvas) {
|
|
30
|
+
this.canvas.width = Math.floor(options.width * options.scale);
|
|
31
|
+
this.canvas.height = Math.floor(options.height * options.scale);
|
|
32
|
+
this.canvas.style.width = `${options.width}px`;
|
|
33
|
+
this.canvas.style.height = `${options.height}px`;
|
|
34
|
+
}
|
|
35
|
+
this.ctx.scale(this.options.scale, this.options.scale);
|
|
36
|
+
this.ctx.translate(-options.x, -options.y);
|
|
37
|
+
this.ctx.textBaseline = 'bottom';
|
|
38
|
+
// Set image smoothing options
|
|
39
|
+
if (options.imageSmoothing !== undefined) {
|
|
40
|
+
this.ctx.imageSmoothingEnabled = options.imageSmoothing;
|
|
41
|
+
}
|
|
42
|
+
if (options.imageSmoothingQuality) {
|
|
43
|
+
this.ctx.imageSmoothingQuality = options.imageSmoothingQuality;
|
|
44
|
+
}
|
|
45
|
+
// Initialize specialized renderers
|
|
46
|
+
this.backgroundRenderer = new background_renderer_1.BackgroundRenderer({
|
|
47
|
+
ctx: this.ctx,
|
|
48
|
+
context: this.context,
|
|
49
|
+
canvas: this.canvas,
|
|
50
|
+
options: {
|
|
51
|
+
width: options.width,
|
|
52
|
+
height: options.height,
|
|
53
|
+
scale: options.scale
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
this.borderRenderer = new border_renderer_1.BorderRenderer({ ctx: this.ctx }, {
|
|
57
|
+
path: (paths) => this.path(paths),
|
|
58
|
+
formatPath: (paths) => this.formatPath(paths)
|
|
59
|
+
});
|
|
60
|
+
this.borderImageRenderer = new border_image_renderer_1.BorderImageRenderer(this.ctx);
|
|
61
|
+
this.effectsRenderer = new effects_renderer_1.EffectsRenderer({ ctx: this.ctx }, { path: (paths) => this.path(paths) });
|
|
62
|
+
this.textRenderer = new text_renderer_1.TextRenderer({
|
|
63
|
+
ctx: this.ctx,
|
|
64
|
+
options: { scale: options.scale }
|
|
65
|
+
});
|
|
66
|
+
this.context.logger.debug(`Canvas renderer initialized (${options.width}x${options.height}) with scale ${options.scale}`);
|
|
67
|
+
}
|
|
68
|
+
async renderStack(stack) {
|
|
69
|
+
const styles = stack.element.container.styles;
|
|
70
|
+
if (styles.isVisible()) {
|
|
71
|
+
await this.renderStackContent(stack);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async renderNode(paint) {
|
|
75
|
+
if (paint.container.debugRender) {
|
|
76
|
+
debugger;
|
|
77
|
+
}
|
|
78
|
+
if (paint.container.styles.isVisible()) {
|
|
79
|
+
await this.renderNodeBackgroundAndBorders(paint);
|
|
80
|
+
await this.renderNodeContent(paint);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Helper method to render text with paint order support
|
|
85
|
+
* Reduces code duplication in line-clamp and normal rendering
|
|
86
|
+
*/
|
|
87
|
+
// Helper method to truncate text and add ellipsis if needed
|
|
88
|
+
renderReplacedElement(container, curves, image) {
|
|
89
|
+
const intrinsicWidth = image.naturalWidth || container.intrinsicWidth;
|
|
90
|
+
const intrinsicHeight = image.naturalHeight || container.intrinsicHeight;
|
|
91
|
+
if (image && intrinsicWidth > 0 && intrinsicHeight > 0) {
|
|
92
|
+
const box = (0, box_sizing_1.contentBox)(container);
|
|
93
|
+
const path = (0, bound_curves_1.calculatePaddingBoxPath)(curves);
|
|
94
|
+
this.path(path);
|
|
95
|
+
this.ctx.save();
|
|
96
|
+
this.ctx.clip();
|
|
97
|
+
const { sx, sy, sw, sh, dx, dy, dw, dh } = (0, object_fit_1.calculateObjectFitRendering)(intrinsicWidth, intrinsicHeight, box, container.styles.objectFit, container.styles.objectPosition);
|
|
98
|
+
this.ctx.drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh);
|
|
99
|
+
this.ctx.restore();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
async renderNodeContent(paint) {
|
|
103
|
+
this.effectsRenderer.applyEffects(paint.getEffects(4 /* EffectTarget.CONTENT */));
|
|
104
|
+
const container = paint.container;
|
|
105
|
+
const curves = paint.curves;
|
|
106
|
+
const styles = container.styles;
|
|
107
|
+
// Use content box for text overflow calculation (excludes padding and border)
|
|
108
|
+
const textBounds = (0, box_sizing_1.contentBox)(container);
|
|
109
|
+
for (const child of container.textNodes) {
|
|
110
|
+
await this.textRenderer.renderTextNode(child, styles, textBounds);
|
|
111
|
+
}
|
|
112
|
+
await (0, content_renderer_1.renderReplacedElements)(this.ctx, this.context, {
|
|
113
|
+
scale: this.options.scale,
|
|
114
|
+
backgroundColor: this.options.backgroundColor,
|
|
115
|
+
x: this.options.x,
|
|
116
|
+
y: this.options.y,
|
|
117
|
+
width: this.options.width,
|
|
118
|
+
height: this.options.height
|
|
119
|
+
}, (ctx, opts) => new CanvasRenderer(ctx, opts), container, curves, styles, (c, cv, img) => this.renderReplacedElement(c, cv, img));
|
|
120
|
+
(0, content_renderer_1.renderFormElements)(this.ctx, this.textRenderer, this.path.bind(this), container, styles);
|
|
121
|
+
await (0, content_renderer_1.renderListMarker)(this.ctx, this.context, this.textRenderer, paint, container, styles);
|
|
122
|
+
}
|
|
123
|
+
async renderStackContent(stack) {
|
|
124
|
+
if (stack.element.container.debugRender) {
|
|
125
|
+
debugger;
|
|
126
|
+
}
|
|
127
|
+
const signal = this.options.signal;
|
|
128
|
+
// https://www.w3.org/TR/css-position-3/#painting-order
|
|
129
|
+
// 1. the background and borders of the element forming the stacking context.
|
|
130
|
+
await this.renderNodeBackgroundAndBorders(stack.element);
|
|
131
|
+
// 2. the child stacking contexts with negative stack levels (most negative first).
|
|
132
|
+
for (const child of stack.negativeZIndex) {
|
|
133
|
+
if (signal?.aborted)
|
|
134
|
+
throw new DOMException('The operation was aborted.', 'AbortError');
|
|
135
|
+
await this.renderStack(child);
|
|
136
|
+
}
|
|
137
|
+
// 3. For all its in-flow, non-positioned, block-level descendants in tree order:
|
|
138
|
+
if (signal?.aborted)
|
|
139
|
+
throw new DOMException('The operation was aborted.', 'AbortError');
|
|
140
|
+
await this.renderNodeContent(stack.element);
|
|
141
|
+
for (const child of stack.nonInlineLevel) {
|
|
142
|
+
await this.renderNode(child);
|
|
143
|
+
}
|
|
144
|
+
// 4. All non-positioned floating descendants, in tree order. For each one of these,
|
|
145
|
+
// treat the element as if it created a new stacking context, but any positioned descendants and descendants
|
|
146
|
+
// which actually create a new stacking context should be considered part of the parent stacking context,
|
|
147
|
+
// not this new one.
|
|
148
|
+
for (const child of stack.nonPositionedFloats) {
|
|
149
|
+
if (signal?.aborted)
|
|
150
|
+
throw new DOMException('The operation was aborted.', 'AbortError');
|
|
151
|
+
await this.renderStack(child);
|
|
152
|
+
}
|
|
153
|
+
// 5. the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
|
|
154
|
+
for (const child of stack.nonPositionedInlineLevel) {
|
|
155
|
+
if (signal?.aborted)
|
|
156
|
+
throw new DOMException('The operation was aborted.', 'AbortError');
|
|
157
|
+
await this.renderStack(child);
|
|
158
|
+
}
|
|
159
|
+
for (const child of stack.inlineLevel) {
|
|
160
|
+
await this.renderNode(child);
|
|
161
|
+
}
|
|
162
|
+
// 6. All positioned, opacity or transform descendants, in tree order that fall into the following categories:
|
|
163
|
+
// All positioned descendants with 'z-index: auto' or 'z-index: 0', in tree order.
|
|
164
|
+
// For those with 'z-index: auto', treat the element as if it created a new stacking context,
|
|
165
|
+
// but any positioned descendants and descendants which actually create a new stacking context should be
|
|
166
|
+
// considered part of the parent stacking context, not this new one. For those with 'z-index: 0',
|
|
167
|
+
// treat the stacking context generated atomically.
|
|
168
|
+
//
|
|
169
|
+
// All opacity descendants with opacity less than 1
|
|
170
|
+
//
|
|
171
|
+
// All transform descendants with transform other than none
|
|
172
|
+
for (const child of stack.zeroOrAutoZIndexOrTransformedOrOpacity) {
|
|
173
|
+
if (signal?.aborted)
|
|
174
|
+
throw new DOMException('The operation was aborted.', 'AbortError');
|
|
175
|
+
await this.renderStack(child);
|
|
176
|
+
}
|
|
177
|
+
// 7. Stacking contexts formed by positioned descendants with z-indices greater than or equal to 1 in z-index
|
|
178
|
+
// order (smallest first) then tree order.
|
|
179
|
+
for (const child of stack.positiveZIndex) {
|
|
180
|
+
if (signal?.aborted)
|
|
181
|
+
throw new DOMException('The operation was aborted.', 'AbortError');
|
|
182
|
+
await this.renderStack(child);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
mask(paths) {
|
|
186
|
+
this.ctx.beginPath();
|
|
187
|
+
this.ctx.moveTo(0, 0);
|
|
188
|
+
// Use logical dimensions (options.width/height) instead of canvas pixel dimensions
|
|
189
|
+
// because context has already been scaled by this.options.scale
|
|
190
|
+
// Fix for Issue #126: Using canvas pixel dimensions causes broken output
|
|
191
|
+
this.ctx.lineTo(this.options.width, 0);
|
|
192
|
+
this.ctx.lineTo(this.options.width, this.options.height);
|
|
193
|
+
this.ctx.lineTo(0, this.options.height);
|
|
194
|
+
this.ctx.lineTo(0, 0);
|
|
195
|
+
this.formatPath(paths.slice(0).reverse());
|
|
196
|
+
this.ctx.closePath();
|
|
197
|
+
}
|
|
198
|
+
path(paths) {
|
|
199
|
+
(0, canvas_path_1.createCanvasPath)(this.ctx, paths);
|
|
200
|
+
}
|
|
201
|
+
formatPath(paths) {
|
|
202
|
+
(0, canvas_path_1.formatCanvasPath)(this.ctx, paths);
|
|
203
|
+
}
|
|
204
|
+
async renderNodeBackgroundAndBorders(paint) {
|
|
205
|
+
this.effectsRenderer.applyEffects(paint.getEffects(2 /* EffectTarget.BACKGROUND_BORDERS */));
|
|
206
|
+
const styles = paint.container.styles;
|
|
207
|
+
const hasBackground = !(0, color_utilities_1.isTransparent)(styles.backgroundColor) || styles.backgroundImage.length;
|
|
208
|
+
const borders = [
|
|
209
|
+
{ style: styles.borderTopStyle, color: styles.borderTopColor, width: styles.borderTopWidth },
|
|
210
|
+
{ style: styles.borderRightStyle, color: styles.borderRightColor, width: styles.borderRightWidth },
|
|
211
|
+
{ style: styles.borderBottomStyle, color: styles.borderBottomColor, width: styles.borderBottomWidth },
|
|
212
|
+
{ style: styles.borderLeftStyle, color: styles.borderLeftColor, width: styles.borderLeftWidth }
|
|
213
|
+
];
|
|
214
|
+
const backgroundPaintingArea = calculateBackgroundCurvedPaintingArea((0, background_1.getBackgroundValueForIndex)(styles.backgroundClip, 0), paint.curves);
|
|
215
|
+
if (hasBackground || styles.boxShadow.length) {
|
|
216
|
+
this.ctx.save();
|
|
217
|
+
this.path(backgroundPaintingArea);
|
|
218
|
+
this.ctx.clip();
|
|
219
|
+
if (!(0, color_utilities_1.isTransparent)(styles.backgroundColor)) {
|
|
220
|
+
this.ctx.fillStyle = (0, color_utilities_1.asString)(styles.backgroundColor);
|
|
221
|
+
this.ctx.fill();
|
|
222
|
+
}
|
|
223
|
+
await this.backgroundRenderer.renderBackgroundImage(paint.container);
|
|
224
|
+
this.ctx.restore();
|
|
225
|
+
styles.boxShadow
|
|
226
|
+
.slice(0)
|
|
227
|
+
.reverse()
|
|
228
|
+
.forEach((shadow) => {
|
|
229
|
+
this.ctx.save();
|
|
230
|
+
const borderBoxArea = (0, bound_curves_1.calculateBorderBoxPath)(paint.curves);
|
|
231
|
+
const maskOffset = shadow.inset ? 0 : constants_1.SHADOW_MASK_OFFSET;
|
|
232
|
+
const shadowPaintingArea = (0, path_1.transformPath)(borderBoxArea, -maskOffset + (shadow.inset ? 1 : -1) * shadow.spread.number, (shadow.inset ? 1 : -1) * shadow.spread.number, shadow.spread.number * (shadow.inset ? -2 : 2), shadow.spread.number * (shadow.inset ? -2 : 2));
|
|
233
|
+
if (shadow.inset) {
|
|
234
|
+
this.path(borderBoxArea);
|
|
235
|
+
this.ctx.clip();
|
|
236
|
+
this.mask(shadowPaintingArea);
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
this.mask(borderBoxArea);
|
|
240
|
+
this.ctx.clip();
|
|
241
|
+
this.path(shadowPaintingArea);
|
|
242
|
+
}
|
|
243
|
+
this.ctx.shadowOffsetX = shadow.offsetX.number + maskOffset;
|
|
244
|
+
this.ctx.shadowOffsetY = shadow.offsetY.number;
|
|
245
|
+
this.ctx.shadowColor = (0, color_utilities_1.asString)(shadow.color);
|
|
246
|
+
this.ctx.shadowBlur = shadow.blur.number;
|
|
247
|
+
this.ctx.fillStyle = shadow.inset ? (0, color_utilities_1.asString)(shadow.color) : 'rgba(0,0,0,1)';
|
|
248
|
+
this.ctx.fill();
|
|
249
|
+
this.ctx.restore();
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
// Render border-image if present (replaces traditional borders per CSS spec)
|
|
253
|
+
if (styles.borderImageSource) {
|
|
254
|
+
const source = styles.borderImageSource;
|
|
255
|
+
if (source.type === 0 /* CSSImageType.URL */) {
|
|
256
|
+
const url = source.url;
|
|
257
|
+
try {
|
|
258
|
+
const image = await this.context.cache.match(url);
|
|
259
|
+
if (image) {
|
|
260
|
+
const bounds = paint.container.bounds;
|
|
261
|
+
this.borderImageRenderer.renderBorderImage(bounds, image, styles.borderImageSlice, styles.borderImageRepeat, Math.max(0, styles.borderTopWidth), Math.max(0, styles.borderRightWidth), Math.max(0, styles.borderBottomWidth), Math.max(0, styles.borderLeftWidth));
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
catch (e) {
|
|
265
|
+
this.context.logger.error(`Error loading border-image ${url}`);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
// When border-image is present, skip regular border rendering
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
let side = 0;
|
|
272
|
+
for (const border of borders) {
|
|
273
|
+
if (border.style !== 0 /* BORDER_STYLE.NONE */ && !(0, color_utilities_1.isTransparent)(border.color) && border.width > 0) {
|
|
274
|
+
if (border.style === 2 /* BORDER_STYLE.DASHED */) {
|
|
275
|
+
await this.borderRenderer.renderDashedDottedBorder(border.color, border.width, side, paint.curves, 2 /* BORDER_STYLE.DASHED */);
|
|
276
|
+
}
|
|
277
|
+
else if (border.style === 3 /* BORDER_STYLE.DOTTED */) {
|
|
278
|
+
await this.borderRenderer.renderDashedDottedBorder(border.color, border.width, side, paint.curves, 3 /* BORDER_STYLE.DOTTED */);
|
|
279
|
+
}
|
|
280
|
+
else if (border.style === 4 /* BORDER_STYLE.DOUBLE */) {
|
|
281
|
+
await this.borderRenderer.renderDoubleBorder(border.color, border.width, side, paint.curves);
|
|
282
|
+
}
|
|
283
|
+
else {
|
|
284
|
+
await this.borderRenderer.renderSolidBorder(border.color, side, paint.curves);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
side++;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
async render(element) {
|
|
291
|
+
if (this.options.backgroundColor) {
|
|
292
|
+
this.ctx.fillStyle = (0, color_utilities_1.asString)(this.options.backgroundColor);
|
|
293
|
+
this.ctx.fillRect(this.options.x, this.options.y, this.options.width, this.options.height);
|
|
294
|
+
}
|
|
295
|
+
const stack = (0, stacking_context_1.parseStackingContexts)(element);
|
|
296
|
+
await this.renderStack(stack);
|
|
297
|
+
this.effectsRenderer.applyEffects([]);
|
|
298
|
+
return this.canvas;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
exports.CanvasRenderer = CanvasRenderer;
|
|
302
|
+
const calculateBackgroundCurvedPaintingArea = (clip, curves) => {
|
|
303
|
+
switch (clip) {
|
|
304
|
+
case 0 /* BACKGROUND_CLIP.BORDER_BOX */:
|
|
305
|
+
return (0, bound_curves_1.calculateBorderBoxPath)(curves);
|
|
306
|
+
case 2 /* BACKGROUND_CLIP.CONTENT_BOX */:
|
|
307
|
+
return (0, bound_curves_1.calculateContentBoxPath)(curves);
|
|
308
|
+
case 1 /* BACKGROUND_CLIP.PADDING_BOX */:
|
|
309
|
+
default:
|
|
310
|
+
return (0, bound_curves_1.calculatePaddingBoxPath)(curves);
|
|
311
|
+
}
|
|
312
|
+
};
|