@vvfx/svg2ir 0.0.1-beta.0 → 0.0.1-beta.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/README.md +86 -48
  2. package/dist/{svg2ge-adapter → adapter/svg2ge}/assemble.d.ts +2 -2
  3. package/dist/adapter/svg2ge/convert.d.ts +7 -0
  4. package/dist/{svg2ge-adapter → adapter/svg2ge}/normalize-shape-animation.d.ts +1 -1
  5. package/dist/{svg2ge-adapter → adapter/svg2ge}/post-process/apply-shape-geometry-animation.d.ts +1 -1
  6. package/dist/{svg2ge-adapter → adapter/svg2ge}/post-process/apply-shape-paint-animation.d.ts +1 -1
  7. package/dist/{svg2ge-adapter → adapter/svg2ge}/post-process/rewrite-text-components.d.ts +1 -1
  8. package/dist/{svg2ge-adapter → adapter/svg2ge}/pre-process.d.ts +1 -1
  9. package/dist/{svg2ge-adapter → adapter/svg2ge}/types.d.ts +2 -2
  10. package/dist/adapter/svg2layers/assemble.d.ts +23 -0
  11. package/dist/adapter/svg2layers/baking/build-baked-layers.d.ts +13 -0
  12. package/dist/adapter/svg2layers/baking/normalize-layer-blending.d.ts +10 -0
  13. package/dist/adapter/svg2layers/baking/plan-graphic-baking.d.ts +18 -0
  14. package/dist/adapter/svg2layers/baking/resolve-baking-warnings.d.ts +4 -0
  15. package/dist/adapter/svg2layers/convert.d.ts +4 -0
  16. package/dist/{svg2layers-adapter → adapter/svg2layers}/converter/diagnostics/collect-warnings.d.ts +1 -1
  17. package/dist/adapter/svg2layers/converter/image/inspect-mask.d.ts +3 -0
  18. package/dist/{svg2layers-adapter → adapter/svg2layers}/converter/layers/build-layers.d.ts +1 -1
  19. package/dist/{svg2layers-adapter → adapter/svg2layers}/converter/layers/conversion-session.d.ts +2 -2
  20. package/dist/{svg2layers-adapter → adapter/svg2layers}/converter/text/parse-text-runs.d.ts +1 -1
  21. package/dist/{svg2layers-adapter → adapter/svg2layers}/converter/text/text-layout.d.ts +2 -2
  22. package/dist/{svg2layers-adapter → adapter/svg2layers}/matrix.d.ts +1 -1
  23. package/dist/adapter/svg2layers/strip-layer-animation.d.ts +5 -0
  24. package/dist/{svg2layers-adapter → adapter/svg2layers}/types.d.ts +8 -1
  25. package/dist/common/types.d.ts +7 -3
  26. package/dist/index.d.ts +6 -6
  27. package/dist/index.js +1324 -103
  28. package/dist/index.js.map +1 -1
  29. package/dist/index.mjs +1323 -103
  30. package/dist/index.mjs.map +1 -1
  31. package/dist/node.js +1326 -105
  32. package/dist/node.js.map +1 -1
  33. package/dist/node.mjs +1325 -105
  34. package/dist/node.mjs.map +1 -1
  35. package/dist/parse-svg/build-element-tree-path.d.ts +2 -0
  36. package/dist/svg-rasterizer/prepare-snapshot.d.ts +9 -0
  37. package/dist/svg-rasterizer/rasterize-svg.d.ts +11 -0
  38. package/dist/svg2ir/assemble.d.ts +3 -1
  39. package/dist/svg2ir/convert.d.ts +5 -2
  40. package/dist/svg2ir/converter/layers/conversion-session.d.ts +2 -0
  41. package/dist/svg2ir/converter/text/font-metrics.d.ts +2 -0
  42. package/package.json +5 -5
  43. package/dist/convert.d.ts +0 -19
  44. package/dist/svg2ge-adapter/convert.d.ts +0 -5
  45. package/dist/svg2layers-adapter/assemble.d.ts +0 -8
  46. package/dist/svg2layers-adapter/convert.d.ts +0 -4
  47. /package/dist/{svg2ge-adapter → adapter/svg2ge}/converter/animation.d.ts +0 -0
  48. /package/dist/{svg2ge-adapter → adapter/svg2ge}/converter/data-path.d.ts +0 -0
  49. /package/dist/{svg2ge-adapter → adapter/svg2ge}/post-process/apply-fonts.d.ts +0 -0
  50. /package/dist/{svg2ge-adapter → adapter/svg2ge}/post-process/paint-animation-sampling.d.ts +0 -0
  51. /package/dist/{svg2ge-adapter → adapter/svg2ge}/post-process/restore-gradient-uv.d.ts +0 -0
  52. /package/dist/{svg2layers-adapter → adapter/svg2layers}/converter/image/convert-image-layer.d.ts +0 -0
  53. /package/dist/{svg2layers-adapter → adapter/svg2layers}/converter/layers/registry.d.ts +0 -0
  54. /package/dist/{svg2layers-adapter → adapter/svg2layers}/converter/layers/resolve-visual-state.d.ts +0 -0
  55. /package/dist/{svg2layers-adapter → adapter/svg2layers}/converter/text/convert-text-layer.d.ts +0 -0
  56. /package/dist/{svg2layers-adapter → adapter/svg2layers}/converter/transform/build-transform.d.ts +0 -0
  57. /package/dist/{svg2layers-adapter → adapter/svg2layers}/post-process/inline-image-resources.d.ts +0 -0
package/README.md CHANGED
@@ -7,21 +7,13 @@ Convert SVG into source-neutral Animation IR, with optional SVG-to-GE and SVG-to
7
7
 
8
8
  ## Contents
9
9
 
10
- - [@vvfx/svg2ir](#vvfxsvg2ir)
11
- - [Contents](#contents)
12
- - [Install](#install)
13
- - [Usage](#usage)
14
- - [SVG to IR](#svg-to-ir)
15
- - [Preserve SVG-specific data](#preserve-svg-specific-data)
16
- - [SVG to GE](#svg-to-ge)
17
- - [SVG to static layers](#svg-to-static-layers)
18
- - [API](#api)
19
- - [Package API](#package-api)
20
- - [Output](#output)
21
- - [Support](#support)
22
- - [Limitations](#limitations)
23
- - [Contributing](#contributing)
24
- - [License](#license)
10
+ - [Install](#install)
11
+ - [Usage](#usage)
12
+ - [API](#api)
13
+ - [Output](#output)
14
+ - [Input capabilities](#input-capabilities)
15
+ - [Limitations](#limitations)
16
+ - [License](#license)
25
17
 
26
18
  ## Install
27
19
 
@@ -29,7 +21,7 @@ Convert SVG into source-neutral Animation IR, with optional SVG-to-GE and SVG-to
29
21
  pnpm add @vvfx/svg2ir @vvfx/ge-ir
30
22
  ```
31
23
 
32
- Node.js 22 or later and pnpm 10 or later are required. Browser and Node callers use the same root import; the Node
24
+ Node.js 24 or later and pnpm 10 or later are required. Browser and Node callers use the same root import; the Node
33
25
  conditional entry automatically supplies the `svgdom` parsing base.
34
26
 
35
27
  ## Usage
@@ -66,42 +58,63 @@ import { convertSVGToGE, splitSVG } from '@vvfx/svg2ir';
66
58
 
67
59
  const split = splitSVG(svgSource);
68
60
  const { data, warnings } = convertSVGToGE(
69
- svgSource,
61
+ split,
70
62
  { fonts: [{ fontFamily: 'Custom Sans', fontURL: 'https://example.com/fonts/custom-sans.woff2' }] },
71
- split.preservedData,
72
63
  );
73
64
  ```
74
65
 
75
66
  `convertSVGToGE` uses `@vvfx/ge-ir` to build the base scene. Passing the sidecar enables SVG-specific rich-text,
76
- paint-animation, and gradient-UV post-processing. Font definitions are supplied independently through `fonts`.
67
+ paint-animation, and gradient-UV post-processing. Passing the `SVGConversionContext` returned by `splitSVG` reuses its
68
+ parsed IR and preserved data without parsing the SVG again. Passing an SVG string keeps source-specific post-processing
69
+ disabled unless `preservedData` is supplied separately. Pass parse options such as `frameRate`, `durationSeconds`, and
70
+ `measureText` to `splitSVG`; options passed to `convertSVGToGE` apply to GE output and diagnostics. Font definitions are
71
+ supplied independently through `fonts`.
77
72
 
78
73
  ### SVG to static layers
79
74
 
80
75
  ```ts
81
- import { convertSVG } from '@vvfx/svg2ir';
76
+ import { convertSVGToLayers } from '@vvfx/svg2ir';
82
77
 
83
78
  const svgSource = '<svg width="400" height="300"><text x="20" y="40" font-size="24">Hello</text></svg>';
84
- const { size: canvasSize, data: layers, warnings } = await convertSVG(svgSource, { outputFormat: 'layers' });
79
+ const { size: canvasSize, data: layers, warnings } = await convertSVGToLayers(svgSource);
85
80
  const json = JSON.stringify(layers);
86
81
 
87
82
  console.info(canvasSize, json, warnings);
88
83
  ```
89
84
 
90
- With `outputFormat: 'layers'`, `convertSVG` converts Animation IR and SVG preserved text data directly into
85
+ `convertSVGToLayers` converts Animation IR and SVG preserved text data directly into
91
86
  static layers and asynchronously returns `{ size, data, warnings }`.
92
87
  `data` is a flat array of image and text layers; `size` is the separate canvas width and height in pixels.
93
88
  SVG images become image layers, and native text becomes editable text layers. Text inside images is not recognized.
94
89
 
90
+ Self-contained static graphics are baked into transparent PNG layers, preserving fills, gradients,
91
+ patterns, strokes, markers, transforms, filters, clipping, masks, and opacity. Ordinary graphics stay separate;
92
+ group-wide effects may merge child graphics into one PNG. Native text and images are never baked.
93
+ Consumers must create layers in array order to retain SVG painter order.
94
+
95
+ Non-normal blend modes (such as multiply, screen, and overlay) are downgraded to normal alpha compositing.
96
+ Baking and downgrades produce warnings; successful baking remains advisory in strict mode.
97
+ Baking requires browser SVG, Canvas, and DOM support; Node converts native layers and warns for unbaked graphics.
98
+ Mixed native effect groups, dependencies containing text/images, external paint resources, animations, scripts,
99
+ and `foreignObject` are not baked.
100
+
95
101
  Layer format:
96
102
 
97
103
  - Common fields: `id` is generated automatically; `bbox` uses canvas-pixel coordinates
98
- `[left, top, right, bottom]`. Geometry is rounded to two decimal places.
104
+ `[left, top, right, bottom]`.
99
105
  - Image layers: `type: 'image'`, `role: 'content'`, and a Base64 data URL in `url`.
100
106
  `size` holds display dimensions before rotation; `rotation` holds XYZ Euler angles in degrees (positive Z is
101
107
  clockwise). `width` and `height` are the bbox dimensions.
108
+ Native image geometry is rounded to two decimal places. Baked geometry follows raster resolution;
109
+ transforms are included in the pixels, with `rotation: [0, 0, 0]`.
102
110
  - Text layers: `type: 'text'`, `state: 'active'`, full text in `content`, and `fragments` containing text runs,
103
111
  fonts, sizes, colors, and spacing. Fragment `bbox` and `polygon` are relative to the text layer's top-left corner;
104
112
  polygon contains the layout corners. Rotation uses degrees and colors use `#RRGGBB`.
113
+ `font_family` contains the family name without enclosing CSS quotes.
114
+ Preserve `font_size` and `letter_spacing` on import.
115
+ Text positions, font sizes, spacing, and rotation retain precision.
116
+ Frame widths use per-code-point measurements at the transformed font size, with spacing only between characters.
117
+ No width padding is added; consumers should preserve this precision when saving and restoring text.
105
118
  Native text requires no image erasure, so `erase_operations` is empty.
106
119
 
107
120
  External images are fetched and inlined; browser fetch requires CORS. Supply `loadImage` for local files or
@@ -113,17 +126,20 @@ authenticated resources and `resourceBaseUrl` for relative image references. Fai
113
126
 
114
127
  - `convertSVGToIR(source, options?)` returns `{ ir, warnings }`.
115
128
  - `splitSVG(source, options?)` returns `{ ir, warnings, preservedData }`.
116
- - `convertSVGToGE(source, options?, preservedData?)` returns `{ data, warnings }`.
117
- - `convertSVG(source, options?, preservedData?)` returns `{ data, warnings }` synchronously for GE, or
118
- `Promise<SVGToLayersResult>` for layers.
129
+ - `convertSVGToGE(sourceOrContext, options?, preservedData?)` returns `{ data, warnings }`.
130
+ - `convertSVGToLayers(source, options?, preservedData?)` returns `Promise<SVGToLayersResult>`.
131
+ - `inferNumericWeightFromFamily(fontFamily)` infers a numeric font weight, or returns `null`.
119
132
 
120
133
  Important options include `frameRate` (default `30`), `durationSeconds` (default `5` for static SVG),
121
134
  `backgroundColor`, `resourceBaseUrl`, `imageNaturalSizes`, `measureText`, `strict`, `onWarning`, and the GE-only
122
135
  `fonts` list. `resourceBaseUrl` must be absolute when used to resolve relative image references.
123
- `convertSVG` also accepts `outputFormat` (`'ge'` by default or `'layers'`) and a layers-only `loadImage` callback:
136
+ `convertSVGToLayers` accepts a `loadImage` callback:
124
137
  `(url) => Promise<{ data: Uint8Array; mimeType: string }>`; `data` contains the original image bytes.
125
138
 
126
- All public types, including `SVGPreservedData`, `ConvertOptions`, `SVGToGEOptions`, `SVGToLayersOptions`, `SVGStaticLayer`,
139
+ The layers-only `rasterScale` option controls PNG resolution without changing display size; it defaults to `2`
140
+ and must be finite and positive. The working raster is limited to 16 megapixels.
141
+
142
+ All public types, including `SVGConversionContext`, `SVGPreservedData`, `ConvertOptions`, `SVGToGEOptions`, `SVGToLayersOptions`, `SVGStaticLayer`,
127
143
  `SVG2IRWarning`, and result types, are exported from `@vvfx/svg2ir`.
128
144
 
129
145
  ## Output
@@ -135,20 +151,48 @@ convertSVGToIR(source, options?);
135
151
  splitSVG(source, options?);
136
152
  // { ir: IRScene; warnings: SVG2IRWarning[]; preservedData: SVGPreservedData }
137
153
 
138
- convertSVGToGE(source, options?, preservedData?);
154
+ convertSVGToGE(sourceOrContext, options?, preservedData?);
139
155
  // { data: JSONScene; warnings: SVG2IRWarning[] }
140
156
 
141
- await convertSVG(source, { outputFormat: 'layers' });
157
+ await convertSVGToLayers(source, options?, preservedData?);
142
158
  // { size: [number, number]; data: SVGStaticLayer[]; warnings: SVG2IRWarning[] }
143
159
  ```
144
160
 
145
- ## Support
146
-
147
- The converter supports basic shapes (`rect`, `circle`, `ellipse`, `path`, `polygon`, `polyline`, and `line`), images
148
- with natural sizes and `preserveAspectRatio`, text and tspan styles, text paths, gradients, element masks and clip
149
- paths, transforms, opacity, `use`/`symbol`, and portions of SMIL animation. Supported paint types include solid,
150
- linear, radial, angular, and image paints where the target scene can represent them. Group masks and element clip
151
- paths are supported; group-level `clip-path` is currently a limitation.
161
+ ## Input capabilities
162
+
163
+ Supported refers to the listed subset; partial means some attributes are approximated or omitted. Output format
164
+ matters: static layers support a smaller subset than IR and GE.
165
+
166
+ ### IR and GE
167
+
168
+ | Capability | Status | Behavior |
169
+ | --- | --- | --- |
170
+ | SVG string and shapes | Supported | `rect`, `circle`, `ellipse`, `path`, `polygon`, `polyline`, and `line`. |
171
+ | Groups and references | Supported | Hierarchy, transforms, opacity, and expanded `use` / `symbol` instances. |
172
+ | Images | Partial | URL assets and aspect ratio; supply natural sizes to avoid fitted-geometry fallback. |
173
+ | Text | Partial | Text/tspan, text paths, multiline and vertical text; GE rich text needs the sidecar. |
174
+ | Paints | Partial | Solid and supported gradients; gradient text is flattened, some gradient attributes lost. |
175
+ | Masks and clip paths | Partial | Element clip paths and element/group masks; unit and region limits below. |
176
+ | Group `clip-path` | Unsupported | Omitted with `svg2ir_group_clip_path_dropped`. |
177
+ | SMIL | Partial | Transform, motion, opacity, visibility, selected geometry and paint; GE paint uses sidecar. |
178
+ | Filters / patterns / markers | Unsupported | Effects omitted with warnings; supported content remains. |
179
+ | Skew and text decoration | Unsupported | Dropped with warnings; text stroke is also omitted. |
180
+ | Other elements | Unsupported | Unmapped content such as `foreignObject` is omitted with warnings. |
181
+
182
+ ### Static layers
183
+
184
+ | Capability | Status | Behavior |
185
+ | --- | --- | --- |
186
+ | Images and native text | Supported | Flat image/text layers; text inside images is not recognized. |
187
+ | Image resources | Supported | Fetches and inlines bytes; use `loadImage` for local or authenticated resources. |
188
+ | Text layout and styles | Partial | Metrics may be estimated; bold/italic are downgraded; vertical text is split. |
189
+ | Shapes and animation | Unsupported | Skipped with warnings; layers export does not rasterize vector shapes. |
190
+ | Masks and visual transforms | Partial | Basic rotation/scale; unsupported opacity, crop, skew, etc. skip layers. |
191
+
192
+ Read `warnings` and optionally `onWarning`. Examples include `svg2ir_filter_dropped`,
193
+ `svg2ir_text_gradient_fill_flattened`, and `svg2ge_layers_unsupported_feature`.
194
+ `strict: true` rejects reported unsupported features and style downgrades; estimated layer text bounds still warn.
195
+ Invalid SVG and failed layer image loads throw errors. An empty warning list is not a complete rendering-fidelity check.
152
196
 
153
197
  ## Limitations
154
198
 
@@ -160,20 +204,14 @@ paths are supported; group-level `clip-path` is currently a limitation.
160
204
  - IR and GE conversion do not download external resources. Callers own URL resolution, font loading, and runtime
161
205
  resource access. Layers export reads and inlines image resources as described above.
162
206
 
163
- Static layers export supports images and text only. Unsupported animated channels, shapes, solid backgrounds,
164
- image skew/reflection/cropping, masks, blending, opacity, nonuniform text scaling, and text paths are skipped with warnings.
207
+ Static layers export supports images and text only. SMIL animation elements are removed with a warning; unsupported animated channels, unbaked shapes, solid backgrounds,
208
+ image skew/reflection/cropping, masks, opacity, nonuniform text scaling, and text paths are skipped with warnings.
165
209
  Bold and italic styles are downgraded with warnings; vertical text is split into character layers with horizontal fragments.
166
- Supply `measureText` for font metrics; incomplete metrics produce estimated bounds and warnings.
210
+ Load the fonts used by `measureText` before conversion; the callback is synchronous and does not load fonts.
211
+ Incomplete metrics produce estimated bounds and warnings.
167
212
  `strict: true` turns unsupported content and style downgrades into errors; estimated bounds still produce warnings.
168
213
 
169
- ## Contributing
170
-
171
- From the monorepo root:
172
-
173
- ```bash
174
- pnpm --filter @vvfx/svg2ir test
175
- pnpm --filter @vvfx/svg2ir build
176
- ```
214
+ Images are retained when a straight rectangular mask covers the full image without inversion or subtraction.
177
215
 
178
216
  ## License
179
217
 
@@ -1,5 +1,5 @@
1
- import { type ConvertResult } from '../common/types';
2
- import type { SVGPreservedData } from '../svg-preserved-data';
1
+ import { type ConvertResult } from '../../common/types';
2
+ import type { SVGPreservedData } from '../../svg-preserved-data';
3
3
  import type { SVGToGEOptions, SVGToGEResult } from './types';
4
4
  /** 从已解析的 IR 和 SVG 保留数据生成 GE 场景。 */
5
5
  export declare function assembleSVGGE(parsed: ConvertResult, options?: SVGToGEOptions, preservedData?: SVGPreservedData): SVGToGEResult;
@@ -0,0 +1,7 @@
1
+ import type { SVGSource } from '../../common/types';
2
+ import type { SVGConversionContext } from '../../svg2ir/convert';
3
+ import type { SVGPreservedData } from '../../svg-preserved-data';
4
+ import type { SVGToGEOptions, SVGToGEResult } from './types';
5
+ /** SVG→GE 显式入口。传入 preservedData 时应用 SVG 专属后处理。 */
6
+ export declare function convertSVGToGE(source: SVGSource, options?: SVGToGEOptions, preservedData?: SVGPreservedData): SVGToGEResult;
7
+ export declare function convertSVGToGE(context: SVGConversionContext, options?: SVGToGEOptions, preservedData?: SVGPreservedData): SVGToGEResult;
@@ -1,2 +1,2 @@
1
- import type { SVGPreservedShapeAnimation } from '../svg-preserved-data';
1
+ import type { SVGPreservedShapeAnimation } from '../../svg-preserved-data';
2
2
  export declare function normalizeShapeAnimationForGE(animation: SVGPreservedShapeAnimation): SVGPreservedShapeAnimation | undefined;
@@ -1,4 +1,4 @@
1
1
  import type { IRScene } from '@vvfx/animation-ir';
2
2
  import { type JSONScene } from '@galacean/effects-specification';
3
- import type { SVGPreservedShapeAnimation } from '../../svg-preserved-data';
3
+ import type { SVGPreservedShapeAnimation } from '../../../svg-preserved-data';
4
4
  export declare function applyShapeGeometryAnimations(scene: JSONScene, ir: IRScene, animationsByLayerId: ReadonlyMap<string, SVGPreservedShapeAnimation> | undefined): void;
@@ -1,4 +1,4 @@
1
1
  import type { IRScene } from '@vvfx/animation-ir';
2
2
  import { type JSONScene } from '@galacean/effects-specification';
3
- import type { SVGPreservedPaintAnimation } from '../../svg-preserved-data';
3
+ import type { SVGPreservedPaintAnimation } from '../../../svg-preserved-data';
4
4
  export declare function applyShapePaintAnimation(scene: JSONScene, ir: IRScene, paintAnimationByLayerIndex: ReadonlyMap<string, readonly SVGPreservedPaintAnimation[]>): void;
@@ -3,7 +3,7 @@
3
3
  * 文本尺寸字段和 textPath 标记保留在 Effects 场景中。
4
4
  */
5
5
  import { type JSONScene } from '@galacean/effects-specification';
6
- import type { SVGPreservedTextData } from '../../svg-preserved-data';
6
+ import type { SVGPreservedTextData } from '../../../svg-preserved-data';
7
7
  interface RewriteTextComponentsToRichTextInput {
8
8
  textDataByLayerId: ReadonlyMap<string, SVGPreservedTextData>;
9
9
  itemLayerIds: Readonly<Record<string, string>>;
@@ -1,5 +1,5 @@
1
1
  import type { IRScene } from '@vvfx/animation-ir';
2
- import type { SVGPreservedPaintAnimation, SVGPreservedShapeAnimation } from '../svg-preserved-data';
2
+ import type { SVGPreservedPaintAnimation, SVGPreservedShapeAnimation } from '../../svg-preserved-data';
3
3
  export declare function applyShapeAnimationBasePaths(ir: IRScene, animationsByLayerId: ReadonlyMap<string, SVGPreservedShapeAnimation> | undefined): void;
4
4
  /** convertIRToGE 用 IR 副本展开 hold 过渡点,result.ir 仍保留解析原始关键帧。 */
5
5
  export declare function expandIRHoldTransitions(ir: IRScene): IRScene;
@@ -1,6 +1,6 @@
1
1
  import type { JSONScene } from '@galacean/effects-specification';
2
- import type { ConvertOptions, SVG2IRWarning } from '../common/types';
3
- import type { SVGFontDefinition } from '../svg-preserved-data';
2
+ import type { ConvertOptions, SVG2IRWarning } from '../../common/types';
3
+ import type { SVGFontDefinition } from '../../svg-preserved-data';
4
4
  export interface SVGToGEOptions extends ConvertOptions {
5
5
  fonts?: readonly SVGFontDefinition[];
6
6
  }
@@ -0,0 +1,23 @@
1
+ import type { IRScene } from '@vvfx/animation-ir';
2
+ import { type ConvertOptions, type SVG2IRWarning } from '../../common/types';
3
+ import type { SVGPreservedData } from '../../svg-preserved-data';
4
+ import type { SVGConversionContext } from '../../svg2ir/convert';
5
+ import type { BakedLayersResult } from './baking/build-baked-layers';
6
+ import type { SVGStaticLayer, SVGToLayersResult } from './types';
7
+ export declare function assembleSVGStaticLayers(scene: IRScene, options: ConvertOptions, warnings: SVG2IRWarning[], preservedData?: SVGPreservedData, sourceIds?: Map<SVGStaticLayer, string>): {
8
+ size: [number, number];
9
+ data: SVGStaticLayer[];
10
+ };
11
+ export interface SVGStaticLayerConversionContext extends SVGConversionContext {
12
+ source: string;
13
+ layerSources: ReadonlyMap<string, string>;
14
+ warningSources: ReadonlyMap<SVG2IRWarning, string>;
15
+ }
16
+ interface SVGLayerAssemblyInput {
17
+ context: SVGStaticLayerConversionContext;
18
+ options: ConvertOptions;
19
+ baking: BakedLayersResult;
20
+ }
21
+ /** Replace baked sources, combine native and raster layers in painter order, then report final diagnostics. */
22
+ export declare function assembleSVGLayers(input: SVGLayerAssemblyInput): SVGToLayersResult;
23
+ export {};
@@ -0,0 +1,13 @@
1
+ import { type ConvertOptions, type SVG2IRWarning } from '../../../common/types';
2
+ import type { SVGImageLayer } from '../types';
3
+ export interface BakedLayersResult {
4
+ layers: Array<{
5
+ path: string;
6
+ layer: SVGImageLayer;
7
+ }>;
8
+ warnings: SVG2IRWarning[];
9
+ replacesSource: (path: string | undefined) => boolean;
10
+ resolvesWarning: (warning: SVG2IRWarning, path: string | undefined) => boolean;
11
+ }
12
+ /** Rasterize graphics and track the source layers and warnings they replace. */
13
+ export declare function buildBakedLayers(source: string, size: [number, number], options: ConvertOptions, rasterScale: number): Promise<BakedLayersResult>;
@@ -0,0 +1,10 @@
1
+ interface BlendDowngrade {
2
+ mode: string;
3
+ selector: string;
4
+ }
5
+ /** Replace non-normal mix-blend-mode declarations with normal and report each downgrade. */
6
+ export declare function normalizeLayerBlending(source: string): {
7
+ source: string;
8
+ downgrades: BlendDowngrade[];
9
+ };
10
+ export {};
@@ -0,0 +1,18 @@
1
+ import type { SVGSnapshotContext } from '../../../svg-rasterizer/prepare-snapshot';
2
+ interface GraphicBakeScope {
3
+ path: string;
4
+ selector: string;
5
+ isGroup: boolean;
6
+ }
7
+ interface GraphicBakingPlan {
8
+ scopes: GraphicBakeScope[];
9
+ warnings: Array<{
10
+ message: string;
11
+ selector: string;
12
+ }>;
13
+ }
14
+ /** Select graphic-only subtrees; keep native text and images as separate layers. */
15
+ export declare function planGraphicBaking(source: string): GraphicBakingPlan;
16
+ /** Reject text/image dependencies and effects that cannot be rendered independently. */
17
+ export declare function validateGraphicSnapshot(context: SVGSnapshotContext): void;
18
+ export {};
@@ -0,0 +1,4 @@
1
+ /** Mask and clipPath definitions do not produce visible layers. */
2
+ export declare function collectNonRenderingDeclarationPaths(source: string): Set<string>;
3
+ /** A stylesheet diagnostic is resolved only when every element it can affect was baked. */
4
+ export declare function collectBakedStylesheetPaths(source: string, isBaked: (path: string) => boolean): Set<string>;
@@ -0,0 +1,4 @@
1
+ import { type SVGSource } from '../../common/types';
2
+ import type { SVGPreservedData } from '../../svg-preserved-data';
3
+ import type { SVGToLayersOptions, SVGToLayersResult } from './types';
4
+ export declare function convertSVGToLayers(source: SVGSource, options?: SVGToLayersOptions, preservedData?: SVGPreservedData): Promise<SVGToLayersResult>;
@@ -1,5 +1,5 @@
1
1
  import type { IRLayer } from '@vvfx/animation-ir';
2
- import { type ConvertOptions, type SVG2IRWarning, type SVG2IRWarningCode } from '../../../common/types';
2
+ import { type ConvertOptions, type SVG2IRWarning, type SVG2IRWarningCode } from '../../../../common/types';
3
3
  export declare class LayerConversionError extends Error {
4
4
  readonly code: SVG2IRWarningCode;
5
5
  constructor(code: SVG2IRWarningCode, message: string);
@@ -0,0 +1,3 @@
1
+ import type { IRLocalBounds, IRMask } from '@vvfx/animation-ir';
2
+ /** 完全覆盖图片的直边矩形 mask 不改变可见内容。 */
3
+ export declare function maskCoversImage(mask: IRMask, bounds: IRLocalBounds): boolean;
@@ -1,3 +1,3 @@
1
1
  import type { SVGStaticLayer } from '../../types';
2
2
  import type { LayerConversionSession } from './conversion-session';
3
- export declare function buildIRStaticLayers(session: LayerConversionSession): SVGStaticLayer[];
3
+ export declare function buildIRStaticLayers(session: LayerConversionSession, sourceIds?: Map<SVGStaticLayer, string>): SVGStaticLayer[];
@@ -1,6 +1,6 @@
1
1
  import type { IRAsset, IRComposition, IRLayer, IRScene } from '@vvfx/animation-ir';
2
- import type { ConvertOptions, SVG2IRWarning } from '../../../common/types';
3
- import type { SVGPreservedData } from '../../../svg-preserved-data';
2
+ import type { ConvertOptions, SVG2IRWarning } from '../../../../common/types';
3
+ import type { SVGPreservedData } from '../../../../svg-preserved-data';
4
4
  import { type StaticLayerState } from '../transform/build-transform';
5
5
  export interface LayerConversionSession {
6
6
  readonly composition: IRComposition;
@@ -1,5 +1,5 @@
1
1
  import type { IRFontAsset, IRTextLayer } from '@vvfx/animation-ir';
2
- import type { SVGPreservedTextData } from '../../../svg-preserved-data';
2
+ import type { SVGPreservedTextData } from '../../../../svg-preserved-data';
3
3
  export interface TextRun {
4
4
  text: string;
5
5
  fontSize: number;
@@ -1,9 +1,9 @@
1
1
  import type { IRTextContent } from '@vvfx/animation-ir';
2
- import { type ConvertOptions, type SVG2IRWarning } from '../../../common/types';
2
+ import { type ConvertOptions, type SVG2IRWarning } from '../../../../common/types';
3
3
  import type { SVGLayerBBox } from '../../types';
4
4
  import type { TextRun } from './parse-text-runs';
5
5
  export interface PositionedTextRun {
6
6
  run: TextRun;
7
7
  box: SVGLayerBBox;
8
8
  }
9
- export declare function buildTextRunLayout(runs: TextRun[], family: string, spacing: number, content: IRTextContent, size: [number, number], conversionOptions: ConvertOptions, warnings: SVG2IRWarning[], id: string, segmented?: boolean): PositionedTextRun[];
9
+ export declare function buildTextRunLayout(runs: TextRun[], family: string, spacing: number, content: IRTextContent, size: [number, number], conversionOptions: ConvertOptions, warnings: SVG2IRWarning[], id: string, segmented?: boolean, renderScale?: readonly [number, number]): PositionedTextRun[];
@@ -12,5 +12,5 @@ export declare const IDENTITY_MATRIX: LayerMatrix;
12
12
  export declare function multiplyMatrices(parent: LayerMatrix, local: LayerMatrix): LayerMatrix;
13
13
  export declare function transformPoint(matrix: LayerMatrix, x: number, y: number): LayerPoint;
14
14
  export declare function transformBoxCorners(matrix: LayerMatrix, box: SVGLayerBBox): LayerPoint[];
15
- export declare function mapPointsToBBox(points: readonly LayerPoint[]): SVGLayerBBox;
15
+ export declare function mapPointsToBBox(points: readonly LayerPoint[], roundCoordinates?: boolean): SVGLayerBBox;
16
16
  export declare function roundPixel(value: number): number;
@@ -0,0 +1,5 @@
1
+ /** Static layers cannot sample animation; drop SMIL nodes so elements keep their authored state. */
2
+ export declare function stripLayerAnimation(source: string): {
3
+ source: string;
4
+ removed: number;
5
+ };
@@ -1,4 +1,4 @@
1
- import type { SVG2IRWarning } from '../common/types';
1
+ import type { ConvertOptions, SVG2IRWarning } from '../../common/types';
2
2
  /** 图片读取结果;data 为原始文件字节,不是 Base64 字符串。 */
3
3
  export interface SVGImageResource {
4
4
  data: Uint8Array;
@@ -6,6 +6,12 @@ export interface SVGImageResource {
6
6
  }
7
7
  /** 读取外链、本地文件或需要鉴权的图片资源。 */
8
8
  export type SVGImageResourceLoader = (url: string) => Promise<SVGImageResource>;
9
+ export interface SVGToLayersOptions extends ConvertOptions {
10
+ /** 外链图片读取回调,默认使用 fetch。 */
11
+ loadImage?: SVGImageResourceLoader;
12
+ /** 烘焙分辨率倍数,默认 2,不改变显示尺寸。 */
13
+ rasterScale?: number;
14
+ }
9
15
  /** 像素边界:[左、上、右、下]。 */
10
16
  export type SVGLayerBBox = [number, number, number, number];
11
17
  export interface SVGImageLayer {
@@ -30,6 +36,7 @@ export interface SVGTextFragment {
30
36
  bbox: SVGLayerBBox;
31
37
  /** 相对文字层的布局四边形,依次为变换前的左上、右上、右下、左下角;不是字形轮廓。 */
32
38
  polygon: Array<[number, number]> | null;
39
+ /** 字体名,不含 CSS 外层引号。 */
33
40
  font_family: string;
34
41
  font_size: number;
35
42
  color: string;
@@ -13,7 +13,7 @@ export interface ConvertOptions {
13
13
  strict?: boolean;
14
14
  /** warning 回调:每条 warning 会先进入 ConvertResult.warnings,再通知调用方。 */
15
15
  onWarning?: (warning: SVG2IRWarning) => void;
16
- /** 可选的文本测量回调,用于改进 SVG 文本几何的 IR bounds。 */
16
+ /** 同步文本测量回调,用于计算文字边界;调用转换前需加载测量使用的字体。 */
17
17
  measureText?: (fontDesc: string, text: string) => {
18
18
  width: number;
19
19
  fontBoundingBoxAscent?: number;
@@ -39,15 +39,19 @@ export interface ConvertResult {
39
39
  /** 转换过程丢弃/降级的特性列表。 */
40
40
  warnings: SVG2IRWarning[];
41
41
  }
42
- /** 转换过程中产生的 warning(可丢降级特性,非致命)。 */
42
+ /** 转换过程中产生的烘焙、降级或内容损失诊断。 */
43
43
  export interface SVG2IRWarning {
44
44
  code: SVG2IRWarningCode;
45
45
  message: string;
46
46
  /** 触发元素在 SVG 里的定位提示(id/tag/索引等)。 */
47
47
  elementSelector?: string;
48
48
  }
49
- /** SVG 转换诊断码。不支持的特性按降级和 warning 处理。 */
49
+ /** SVG 转换诊断码;用于报告烘焙、降级和不支持的特性。 */
50
50
  export declare const SVG2IR_WARNING_CODES: {
51
+ /** 图形或图形组已栅格化,矢量编辑能力变化通过 warning 报告。 */
52
+ readonly LAYERS_GRAPHIC_BAKED: "svg2ge_layers_graphic_baked";
53
+ readonly LAYERS_BLEND_MODE_DOWNGRADED: "svg2ge_layers_blend_mode_downgraded";
54
+ readonly LAYERS_ANIMATION_STRIPPED: "svg2ge_layers_animation_stripped";
51
55
  readonly LAYERS_UNSUPPORTED_TYPE: "svg2ge_layers_unsupported_type";
52
56
  readonly LAYERS_UNSUPPORTED_FEATURE: "svg2ge_layers_unsupported_feature";
53
57
  readonly LAYERS_INVALID_DATA: "svg2ge_layers_invalid_data";
package/dist/index.d.ts CHANGED
@@ -4,11 +4,11 @@
4
4
  * 根入口提供 SVG→IR、SVG 保留数据拆分及 GE/静态分层输出。
5
5
  */
6
6
  export { convertSVGToIR, splitSVG } from './svg2ir/convert';
7
- export { convertSVG } from './convert';
8
- export { convertSVGToGE } from './svg2ge-adapter/convert';
7
+ export { convertSVGToLayers } from './adapter/svg2layers/convert';
8
+ export { convertSVGToGE } from './adapter/svg2ge/convert';
9
9
  export type { ConvertOptions, ConvertResult, SVG2IRWarning, SVG2IRWarningCode, SVGSource, } from './common/types';
10
- export type { SplitSVGOptions, SplitSVGResult } from './svg2ir/convert';
11
- export type { SVGToGEOptions, SVGToGEResult } from './svg2ge-adapter/types';
12
- export type { SVGConversionOptions, SVGToLayersOptions } from './convert';
10
+ export type { SplitSVGOptions, SplitSVGResult, SVGConversionContext } from './svg2ir/convert';
11
+ export type { SVGToGEOptions, SVGToGEResult } from './adapter/svg2ge/types';
13
12
  export type { SVGPreservedData, SVGFontDefinition, SVGPreservedPaintAnimation, SVGPreservedShapeAnimation, SVGPreservedTextData, SVGPreservedTextSpan, } from './svg-preserved-data';
14
- export type { SVGStaticLayer, SVGImageLayer, SVGTextLayer, SVGTextFragment, SVGLayerBBox, SVGToLayersResult, SVGLayerEraseOperation, SVGImageResource, SVGImageResourceLoader, } from './svg2layers-adapter/types';
13
+ export type { SVGStaticLayer, SVGImageLayer, SVGTextLayer, SVGTextFragment, SVGLayerBBox, SVGToLayersOptions, SVGToLayersResult, SVGLayerEraseOperation, SVGImageResource, SVGImageResourceLoader, } from './adapter/svg2layers/types';
14
+ export { inferNumericWeightFromFamily } from './svg2ir/converter/text/font-metrics';