codeboard-studio 0.2.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.
Files changed (208) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE +23 -0
  3. package/README.md +54 -0
  4. package/dist/src/animation/camera-plane.d.ts +8 -0
  5. package/dist/src/animation/camera-plane.d.ts.map +1 -0
  6. package/dist/src/animation/camera-plane.js +16 -0
  7. package/dist/src/animation/camera-plane.js.map +1 -0
  8. package/dist/src/animation/drawing-neighbors.d.ts +4 -0
  9. package/dist/src/animation/drawing-neighbors.d.ts.map +1 -0
  10. package/dist/src/animation/drawing-neighbors.js +38 -0
  11. package/dist/src/animation/drawing-neighbors.js.map +1 -0
  12. package/dist/src/animation/evaluate.d.ts +17 -0
  13. package/dist/src/animation/evaluate.d.ts.map +1 -0
  14. package/dist/src/animation/evaluate.js +70 -0
  15. package/dist/src/animation/evaluate.js.map +1 -0
  16. package/dist/src/animation/frame.d.ts +8 -0
  17. package/dist/src/animation/frame.d.ts.map +1 -0
  18. package/dist/src/animation/frame.js +16 -0
  19. package/dist/src/animation/frame.js.map +1 -0
  20. package/dist/src/animation/ik.d.ts +26 -0
  21. package/dist/src/animation/ik.d.ts.map +1 -0
  22. package/dist/src/animation/ik.js +47 -0
  23. package/dist/src/animation/ik.js.map +1 -0
  24. package/dist/src/animation/retime.d.ts +4 -0
  25. package/dist/src/animation/retime.d.ts.map +1 -0
  26. package/dist/src/animation/retime.js +116 -0
  27. package/dist/src/animation/retime.js.map +1 -0
  28. package/dist/src/audio/wav.d.ts +11 -0
  29. package/dist/src/audio/wav.d.ts.map +1 -0
  30. package/dist/src/audio/wav.js +58 -0
  31. package/dist/src/audio/wav.js.map +1 -0
  32. package/dist/src/authoring-runner.d.ts +2 -0
  33. package/dist/src/authoring-runner.d.ts.map +1 -0
  34. package/dist/src/authoring-runner.js +24 -0
  35. package/dist/src/authoring-runner.js.map +1 -0
  36. package/dist/src/cli.d.ts +3 -0
  37. package/dist/src/cli.d.ts.map +1 -0
  38. package/dist/src/cli.js +127 -0
  39. package/dist/src/cli.js.map +1 -0
  40. package/dist/src/core/coordinates.d.ts +16 -0
  41. package/dist/src/core/coordinates.d.ts.map +1 -0
  42. package/dist/src/core/coordinates.js +48 -0
  43. package/dist/src/core/coordinates.js.map +1 -0
  44. package/dist/src/core/handles.d.ts +93 -0
  45. package/dist/src/core/handles.d.ts.map +1 -0
  46. package/dist/src/core/handles.js +190 -0
  47. package/dist/src/core/handles.js.map +1 -0
  48. package/dist/src/core/history.d.ts +14 -0
  49. package/dist/src/core/history.d.ts.map +1 -0
  50. package/dist/src/core/history.js +80 -0
  51. package/dist/src/core/history.js.map +1 -0
  52. package/dist/src/core/inspection.d.ts +51 -0
  53. package/dist/src/core/inspection.d.ts.map +1 -0
  54. package/dist/src/core/inspection.js +72 -0
  55. package/dist/src/core/inspection.js.map +1 -0
  56. package/dist/src/core/production.d.ts +208 -0
  57. package/dist/src/core/production.d.ts.map +1 -0
  58. package/dist/src/core/production.js +894 -0
  59. package/dist/src/core/production.js.map +1 -0
  60. package/dist/src/core/project.d.ts +146 -0
  61. package/dist/src/core/project.d.ts.map +1 -0
  62. package/dist/src/core/project.js +700 -0
  63. package/dist/src/core/project.js.map +1 -0
  64. package/dist/src/drawing/brush-authoring.d.ts +6 -0
  65. package/dist/src/drawing/brush-authoring.d.ts.map +1 -0
  66. package/dist/src/drawing/brush-authoring.js +12 -0
  67. package/dist/src/drawing/brush-authoring.js.map +1 -0
  68. package/dist/src/drawing/brushes.d.ts +157 -0
  69. package/dist/src/drawing/brushes.d.ts.map +1 -0
  70. package/dist/src/drawing/brushes.js +50 -0
  71. package/dist/src/drawing/brushes.js.map +1 -0
  72. package/dist/src/drawing/color.d.ts +5 -0
  73. package/dist/src/drawing/color.d.ts.map +1 -0
  74. package/dist/src/drawing/color.js +63 -0
  75. package/dist/src/drawing/color.js.map +1 -0
  76. package/dist/src/drawing/curves.d.ts +27 -0
  77. package/dist/src/drawing/curves.d.ts.map +1 -0
  78. package/dist/src/drawing/curves.js +170 -0
  79. package/dist/src/drawing/curves.js.map +1 -0
  80. package/dist/src/drawing/math.d.ts +10 -0
  81. package/dist/src/drawing/math.d.ts.map +1 -0
  82. package/dist/src/drawing/math.js +40 -0
  83. package/dist/src/drawing/math.js.map +1 -0
  84. package/dist/src/drawing/path-geometry.d.ts +18 -0
  85. package/dist/src/drawing/path-geometry.d.ts.map +1 -0
  86. package/dist/src/drawing/path-geometry.js +115 -0
  87. package/dist/src/drawing/path-geometry.js.map +1 -0
  88. package/dist/src/drawing/path-sampling.d.ts +10 -0
  89. package/dist/src/drawing/path-sampling.d.ts.map +1 -0
  90. package/dist/src/drawing/path-sampling.js +64 -0
  91. package/dist/src/drawing/path-sampling.js.map +1 -0
  92. package/dist/src/drawing/path.d.ts +4 -0
  93. package/dist/src/drawing/path.d.ts.map +1 -0
  94. package/dist/src/drawing/path.js +27 -0
  95. package/dist/src/drawing/path.js.map +1 -0
  96. package/dist/src/drawing/pen-input.d.ts +5 -0
  97. package/dist/src/drawing/pen-input.d.ts.map +1 -0
  98. package/dist/src/drawing/pen-input.js +30 -0
  99. package/dist/src/drawing/pen-input.js.map +1 -0
  100. package/dist/src/drawing/pixel-selection.d.ts +23 -0
  101. package/dist/src/drawing/pixel-selection.d.ts.map +1 -0
  102. package/dist/src/drawing/pixel-selection.js +142 -0
  103. package/dist/src/drawing/pixel-selection.js.map +1 -0
  104. package/dist/src/drawing/pixels.d.ts +22 -0
  105. package/dist/src/drawing/pixels.d.ts.map +1 -0
  106. package/dist/src/drawing/pixels.js +79 -0
  107. package/dist/src/drawing/pixels.js.map +1 -0
  108. package/dist/src/drawing/resource-binary.d.ts +23 -0
  109. package/dist/src/drawing/resource-binary.d.ts.map +1 -0
  110. package/dist/src/drawing/resource-binary.js +135 -0
  111. package/dist/src/drawing/resource-binary.js.map +1 -0
  112. package/dist/src/drawing/resources.d.ts +51 -0
  113. package/dist/src/drawing/resources.d.ts.map +1 -0
  114. package/dist/src/drawing/resources.js +239 -0
  115. package/dist/src/drawing/resources.js.map +1 -0
  116. package/dist/src/drawing/stroke-outline.d.ts +5 -0
  117. package/dist/src/drawing/stroke-outline.d.ts.map +1 -0
  118. package/dist/src/drawing/stroke-outline.js +53 -0
  119. package/dist/src/drawing/stroke-outline.js.map +1 -0
  120. package/dist/src/drawing/swatch.d.ts +6 -0
  121. package/dist/src/drawing/swatch.d.ts.map +1 -0
  122. package/dist/src/drawing/swatch.js +15 -0
  123. package/dist/src/drawing/swatch.js.map +1 -0
  124. package/dist/src/export/animatic-export.d.ts +11 -0
  125. package/dist/src/export/animatic-export.d.ts.map +1 -0
  126. package/dist/src/export/animatic-export.js +52 -0
  127. package/dist/src/export/animatic-export.js.map +1 -0
  128. package/dist/src/export/movie-export.d.ts +16 -0
  129. package/dist/src/export/movie-export.d.ts.map +1 -0
  130. package/dist/src/export/movie-export.js +108 -0
  131. package/dist/src/export/movie-export.js.map +1 -0
  132. package/dist/src/export/sheet-layout.d.ts +27 -0
  133. package/dist/src/export/sheet-layout.d.ts.map +1 -0
  134. package/dist/src/export/sheet-layout.js +72 -0
  135. package/dist/src/export/sheet-layout.js.map +1 -0
  136. package/dist/src/export/storyboard-export.d.ts +8 -0
  137. package/dist/src/export/storyboard-export.d.ts.map +1 -0
  138. package/dist/src/export/storyboard-export.js +76 -0
  139. package/dist/src/export/storyboard-export.js.map +1 -0
  140. package/dist/src/index.d.ts +36 -0
  141. package/dist/src/index.d.ts.map +1 -0
  142. package/dist/src/index.js +27 -0
  143. package/dist/src/index.js.map +1 -0
  144. package/dist/src/model/query.d.ts +6 -0
  145. package/dist/src/model/query.d.ts.map +1 -0
  146. package/dist/src/model/query.js +7 -0
  147. package/dist/src/model/query.js.map +1 -0
  148. package/dist/src/model/schema.d.ts +754 -0
  149. package/dist/src/model/schema.d.ts.map +1 -0
  150. package/dist/src/model/schema.js +205 -0
  151. package/dist/src/model/schema.js.map +1 -0
  152. package/dist/src/model/types.d.ts +537 -0
  153. package/dist/src/model/types.d.ts.map +1 -0
  154. package/dist/src/model/types.js +8 -0
  155. package/dist/src/model/types.js.map +1 -0
  156. package/dist/src/model/validate.d.ts +12 -0
  157. package/dist/src/model/validate.d.ts.map +1 -0
  158. package/dist/src/model/validate.js +183 -0
  159. package/dist/src/model/validate.js.map +1 -0
  160. package/dist/src/preview/server.d.ts +6 -0
  161. package/dist/src/preview/server.d.ts.map +1 -0
  162. package/dist/src/preview/server.js +71 -0
  163. package/dist/src/preview/server.js.map +1 -0
  164. package/dist/src/render/annotations.d.ts +4 -0
  165. package/dist/src/render/annotations.d.ts.map +1 -0
  166. package/dist/src/render/annotations.js +27 -0
  167. package/dist/src/render/annotations.js.map +1 -0
  168. package/dist/src/render/brush-engine.d.ts +14 -0
  169. package/dist/src/render/brush-engine.d.ts.map +1 -0
  170. package/dist/src/render/brush-engine.js +230 -0
  171. package/dist/src/render/brush-engine.js.map +1 -0
  172. package/dist/src/render/layer-compositor.d.ts +33 -0
  173. package/dist/src/render/layer-compositor.d.ts.map +1 -0
  174. package/dist/src/render/layer-compositor.js +296 -0
  175. package/dist/src/render/layer-compositor.js.map +1 -0
  176. package/dist/src/render/panel-renderer.d.ts +33 -0
  177. package/dist/src/render/panel-renderer.d.ts.map +1 -0
  178. package/dist/src/render/panel-renderer.js +118 -0
  179. package/dist/src/render/panel-renderer.js.map +1 -0
  180. package/dist/src/render/png.d.ts +4 -0
  181. package/dist/src/render/png.d.ts.map +1 -0
  182. package/dist/src/render/png.js +10 -0
  183. package/dist/src/render/png.js.map +1 -0
  184. package/dist/src/render/review.d.ts +42 -0
  185. package/dist/src/render/review.d.ts.map +1 -0
  186. package/dist/src/render/review.js +192 -0
  187. package/dist/src/render/review.js.map +1 -0
  188. package/dist/src/render/vector-renderer.d.ts +5 -0
  189. package/dist/src/render/vector-renderer.d.ts.map +1 -0
  190. package/dist/src/render/vector-renderer.js +98 -0
  191. package/dist/src/render/vector-renderer.js.map +1 -0
  192. package/dist/src/starter.d.ts +2 -0
  193. package/dist/src/starter.d.ts.map +1 -0
  194. package/dist/src/starter.js +23 -0
  195. package/dist/src/starter.js.map +1 -0
  196. package/dist/src/storage/codec.d.ts +20 -0
  197. package/dist/src/storage/codec.d.ts.map +1 -0
  198. package/dist/src/storage/codec.js +203 -0
  199. package/dist/src/storage/codec.js.map +1 -0
  200. package/dist/src/storage/store.d.ts +89 -0
  201. package/dist/src/storage/store.d.ts.map +1 -0
  202. package/dist/src/storage/store.js +392 -0
  203. package/dist/src/storage/store.js.map +1 -0
  204. package/dist/src/updates.d.ts +10 -0
  205. package/dist/src/updates.d.ts.map +1 -0
  206. package/dist/src/updates.js +134 -0
  207. package/dist/src/updates.js.map +1 -0
  208. package/package.json +84 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"curves.js","sourceRoot":"","sources":["../../../src/drawing/curves.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { AffineMatrix, Point, Transform, Pivot } from "../model/types.js";
2
+ /** Composition A × B applies B first, then A. */
3
+ export declare function multiplyMatrices(left: readonly number[], right: readonly number[]): AffineMatrix;
4
+ export declare function matrixFromTransform(value: Partial<Transform>, pivot?: Pivot): AffineMatrix;
5
+ export declare function invertMatrix(value: readonly number[]): AffineMatrix;
6
+ export declare function transformPoint(value: readonly number[], point: Pick<Point, "x" | "y">): {
7
+ x: number;
8
+ y: number;
9
+ };
10
+ //# sourceMappingURL=math.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"math.d.ts","sourceRoot":"","sources":["../../../src/drawing/math.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,YAAY,EAAC,KAAK,EAAC,SAAS,EAAC,KAAK,EAAC,MAAM,mBAAmB,CAAC;AAS1E,iDAAiD;AACjD,wBAAgB,gBAAgB,CAAC,IAAI,EAAC,SAAS,MAAM,EAAE,EAAC,KAAK,EAAC,SAAS,MAAM,EAAE,GAAE,YAAY,CAG5F;AACD,wBAAgB,mBAAmB,CAAC,KAAK,EAAC,OAAO,CAAC,SAAS,CAAC,EAAC,KAAK,GAAC,KAAe,GAAE,YAAY,CAK/F;AACD,wBAAgB,YAAY,CAAC,KAAK,EAAC,SAAS,MAAM,EAAE,GAAE,YAAY,CAOjE;AACD,wBAAgB,cAAc,CAAC,KAAK,EAAC,SAAS,MAAM,EAAE,EAAC,KAAK,EAAC,IAAI,CAAC,KAAK,EAAC,GAAG,GAAC,GAAG,CAAC,GAAE;IAAC,CAAC,EAAC,MAAM,CAAC;IAAA,CAAC,EAAC,MAAM,CAAA;CAAC,CAGpG"}
@@ -0,0 +1,40 @@
1
+ function finite(values) {
2
+ if (values.some(value => typeof value !== "number" || !Number.isFinite(value)))
3
+ throw new Error("Geometry values must be finite numbers");
4
+ }
5
+ function matrix(values) {
6
+ if (values.length !== 6)
7
+ throw new Error("An affine matrix requires six numbers");
8
+ finite(values);
9
+ return [...values];
10
+ }
11
+ /** Composition A × B applies B first, then A. */
12
+ export function multiplyMatrices(left, right) {
13
+ const [a, b, c, d, e, f] = matrix(left), [g, h, i, j, k, l] = matrix(right);
14
+ return matrix([a * g + c * h, b * g + d * h, a * i + c * j, b * i + d * j, a * k + c * l + e, b * k + d * l + f]);
15
+ }
16
+ export function matrixFromTransform(value, pivot = { x: 0, y: 0 }) {
17
+ const { x = 0, y = 0, rotation = 0, scaleX = 1, scaleY = 1 } = value;
18
+ finite([x, y, rotation, scaleX, scaleY]);
19
+ finite([pivot.x, pivot.y]);
20
+ const c = Math.cos(rotation), s = Math.sin(rotation), a = c * scaleX, b = s * scaleX, d = c * scaleY, h = -s * scaleY;
21
+ return matrix([a, b, h, d, x + (1 - a) * pivot.x - h * pivot.y, y - b * pivot.x + (1 - d) * pivot.y]);
22
+ }
23
+ export function invertMatrix(value) {
24
+ const [a, b, c, d, e, f] = matrix(value), scale = Math.max(Math.abs(a), Math.abs(b), Math.abs(c), Math.abs(d));
25
+ if (scale === 0)
26
+ throw new Error("Matrix is singular or too ill-conditioned to invert safely");
27
+ const aa = a / scale, bb = b / scale, cc = c / scale, dd = d / scale, det = aa * dd - bb * cc;
28
+ if (Math.abs(det) <= Number.EPSILON * 8)
29
+ throw new Error("Matrix is singular or too ill-conditioned to invert safely");
30
+ const ia = dd / det / scale, ib = -bb / det / scale, ic = -cc / det / scale, id = aa / det / scale;
31
+ return matrix([ia, ib, ic, id, -ia * e - ic * f, -ib * e - id * f]);
32
+ }
33
+ export function transformPoint(value, point) {
34
+ const [a, b, c, d, e, f] = matrix(value);
35
+ finite([point.x, point.y]);
36
+ const x = a * point.x + c * point.y + e, y = b * point.x + d * point.y + f;
37
+ finite([x, y]);
38
+ return { x, y };
39
+ }
40
+ //# sourceMappingURL=math.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"math.js","sourceRoot":"","sources":["../../../src/drawing/math.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { Path2D } from "skia-canvas";
2
+ import type { PathCommand } from "../model/types.js";
3
+ export type PathBooleanOperation = "union" | "intersect" | "difference" | "xor";
4
+ /** Insert a knot using de Casteljau subdivision; retain editable curve commands. */
5
+ export declare function splitPathSegment(commands: readonly PathCommand[], index: number, t?: number): PathCommand[];
6
+ /** Shared native conversion for rendering and explicit geometry operations. */
7
+ export declare function contourPath(commands: readonly PathCommand[], requireClosed?: boolean): Path2D;
8
+ export declare function combinePaths(a: readonly PathCommand[], b: readonly PathCommand[], operation: PathBooleanOperation): PathCommand[];
9
+ export declare function pathBounds(commands: readonly PathCommand[]): {
10
+ left: number;
11
+ top: number;
12
+ right: number;
13
+ bottom: number;
14
+ width: number;
15
+ height: number;
16
+ } | null;
17
+ export declare function pathContains(commands: readonly PathCommand[], x: number, y: number): boolean;
18
+ //# sourceMappingURL=path-geometry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-geometry.d.ts","sourceRoot":"","sources":["../../../src/drawing/path-geometry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AACnC,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,mBAAmB,CAAC;AAEnD,MAAM,MAAM,oBAAoB,GAAC,OAAO,GAAC,WAAW,GAAC,YAAY,GAAC,KAAK,CAAC;AAGxE,oFAAoF;AACpF,wBAAgB,gBAAgB,CAAC,QAAQ,EAAC,SAAS,WAAW,EAAE,EAAC,KAAK,EAAC,MAAM,EAAC,CAAC,SAAG,GAAE,WAAW,EAAE,CAuBhG;AAED,+EAA+E;AAC/E,wBAAgB,WAAW,CAAC,QAAQ,EAAC,SAAS,WAAW,EAAE,EAAC,aAAa,UAAM,GAAE,MAAM,CAmBtF;AAcD,wBAAgB,YAAY,CAAC,CAAC,EAAC,SAAS,WAAW,EAAE,EAAC,CAAC,EAAC,SAAS,WAAW,EAAE,EAAC,SAAS,EAAC,oBAAoB,GAAE,WAAW,EAAE,CAK3H;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAC,SAAS,WAAW,EAAE;;;;;;;SAIzD;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAC,SAAS,WAAW,EAAE,EAAC,CAAC,EAAC,MAAM,EAAC,CAAC,EAAC,MAAM,GAAE,OAAO,CAGtF"}
@@ -0,0 +1,115 @@
1
+ import { Path2D } from "skia-canvas";
2
+ const coordinates = { M: ["x", "y"], L: ["x", "y"], Q: ["x1", "y1", "x", "y"], C: ["x1", "y1", "x2", "y2", "x", "y"], Z: [] };
3
+ /** Insert a knot using de Casteljau subdivision; retain editable curve commands. */
4
+ export function splitPathSegment(commands, index, t = .5) {
5
+ if (!Number.isSafeInteger(index) || index < 0 || index >= commands.length)
6
+ throw new Error("Path segment index is out of range");
7
+ if (!Number.isFinite(t) || t <= 0 || t >= 1)
8
+ throw new Error("Path split parameter must be strictly between 0 and 1");
9
+ const segment = commands[index];
10
+ if (segment.op === 'M' || segment.op === 'Z')
11
+ throw new Error("Split an L, Q or C segment; M and Z are not supported");
12
+ contourPath(commands);
13
+ let current = { x: 0, y: 0 }, start = current;
14
+ for (const command of commands.slice(0, index)) {
15
+ if (command.op === 'Z')
16
+ current = start;
17
+ else {
18
+ current = { x: command.x, y: command.y };
19
+ if (command.op === 'M')
20
+ start = current;
21
+ }
22
+ }
23
+ const mix = (a, b) => ({ x: (1 - t) * a.x + t * b.x, y: (1 - t) * a.y + t * b.y });
24
+ const end = { x: segment.x, y: segment.y };
25
+ let halves;
26
+ if (segment.op === 'L')
27
+ halves = [{ op: 'L', ...mix(current, end) }, { op: 'L', ...end }];
28
+ else if (segment.op === 'Q') {
29
+ const control = { x: segment.x1, y: segment.y1 }, a = mix(current, control), b = mix(control, end), knot = mix(a, b);
30
+ halves = [{ op: 'Q', x1: a.x, y1: a.y, ...knot }, { op: 'Q', x1: b.x, y1: b.y, ...end }];
31
+ }
32
+ else if (segment.op === 'C') {
33
+ const a = mix(current, { x: segment.x1, y: segment.y1 }), b = mix({ x: segment.x1, y: segment.y1 }, { x: segment.x2, y: segment.y2 }), c = mix({ x: segment.x2, y: segment.y2 }, end);
34
+ const d = mix(a, b), e = mix(b, c), knot = mix(d, e);
35
+ halves = [{ op: 'C', x1: a.x, y1: a.y, x2: d.x, y2: d.y, ...knot }, { op: 'C', x1: e.x, y1: e.y, x2: c.x, y2: c.y, ...end }];
36
+ }
37
+ else
38
+ throw new Error("Unsupported path segment");
39
+ return [...commands.slice(0, index), ...halves, ...commands.slice(index + 1)].map(command => ({ ...command }));
40
+ }
41
+ /** Shared native conversion for rendering and explicit geometry operations. */
42
+ export function contourPath(commands, requireClosed = false) {
43
+ const path = new Path2D();
44
+ let opened = false, hasPoint = false;
45
+ for (const command of commands) {
46
+ const fields = coordinates[command.op];
47
+ if (!fields)
48
+ throw new Error(`Unsupported path command: ${command.op}`);
49
+ for (const key of fields) {
50
+ const value = command[key];
51
+ if (typeof value !== "number" || !Number.isFinite(value) || !Number.isFinite(Math.fround(value)))
52
+ throw new Error(`Path ${command.op}.${key} must be finite and within Skia's scalar range`);
53
+ }
54
+ if (command.op === "M") {
55
+ if (requireClosed && opened)
56
+ throw new Error("Boolean operations require explicitly closed contours");
57
+ path.moveTo(command.x, command.y);
58
+ opened = true;
59
+ hasPoint = true;
60
+ }
61
+ else {
62
+ if (!hasPoint || (requireClosed && !opened))
63
+ throw new Error("A contour must begin with M");
64
+ if (command.op === "L")
65
+ path.lineTo(command.x, command.y);
66
+ else if (command.op === "Q")
67
+ path.quadraticCurveTo(command.x1, command.y1, command.x, command.y);
68
+ else if (command.op === "C")
69
+ path.bezierCurveTo(command.x1, command.y1, command.x2, command.y2, command.x, command.y);
70
+ else {
71
+ path.closePath();
72
+ opened = false;
73
+ }
74
+ }
75
+ }
76
+ if (requireClosed && opened)
77
+ throw new Error("Boolean operations require explicitly closed contours");
78
+ return path;
79
+ }
80
+ function commandsOf(path) {
81
+ return path.edges.map(([verb, ...p]) => {
82
+ if (p.some(value => !Number.isFinite(value)))
83
+ throw new Error("Native geometry operation returned non-finite coordinates");
84
+ if (verb === "moveTo")
85
+ return { op: "M", x: p[0], y: p[1] };
86
+ if (verb === "lineTo")
87
+ return { op: "L", x: p[0], y: p[1] };
88
+ if (verb === "quadraticCurveTo")
89
+ return { op: "Q", x1: p[0], y1: p[1], x: p[2], y: p[3] };
90
+ if (verb === "bezierCurveTo")
91
+ return { op: "C", x1: p[0], y1: p[1], x2: p[2], y2: p[3], x: p[4], y: p[5] };
92
+ if (verb === "closePath")
93
+ return { op: "Z" };
94
+ throw new Error(`Native geometry produced unsupported ${verb}; no flattening was applied`);
95
+ });
96
+ }
97
+ export function combinePaths(a, b, operation) {
98
+ if (!["union", "intersect", "difference", "xor"].includes(operation))
99
+ throw new Error(`Unsupported path operation: ${operation}`);
100
+ const left = contourPath(a, true), right = contourPath(b, true);
101
+ // Native operation results can carry even-odd fill semantics, absent from command arrays.
102
+ return commandsOf(left[operation](right).unwind());
103
+ }
104
+ export function pathBounds(commands) {
105
+ if (!commands.length)
106
+ return null;
107
+ const { left, top, right, bottom, width, height } = contourPath(commands).bounds;
108
+ return { left, top, right, bottom, width, height };
109
+ }
110
+ export function pathContains(commands, x, y) {
111
+ if (!Number.isFinite(x) || !Number.isFinite(y) || !Number.isFinite(Math.fround(x)) || !Number.isFinite(Math.fround(y)))
112
+ throw new Error("Hit-test coordinates must be finite and within Skia's scalar range");
113
+ return contourPath(commands, true).contains(x, y);
114
+ }
115
+ //# sourceMappingURL=path-geometry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-geometry.js","sourceRoot":"","sources":["../../../src/drawing/path-geometry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { PathCommand, Point } from "../model/types.js";
2
+ export interface PathSamplingOptions {
3
+ /** Maximum intended spacing in local canvas units; native curve measurement is approximate. */
4
+ step?: number;
5
+ /** Reject before native sampling if the control-polygon estimate exceeds this allocation budget. */
6
+ maxSamples?: number;
7
+ }
8
+ /** Sample separate pen-down paths. The original editable contour commands remain untouched. */
9
+ export declare function samplePath(commands: readonly PathCommand[], options?: PathSamplingOptions): Point[][];
10
+ //# sourceMappingURL=path-sampling.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-sampling.d.ts","sourceRoot":"","sources":["../../../src/drawing/path-sampling.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,WAAW,EAAC,KAAK,EAAC,MAAM,mBAAmB,CAAC;AAGzD,MAAM,WAAW,mBAAmB;IAClC,+FAA+F;IAC/F,IAAI,CAAC,EAAC,MAAM,CAAC;IACb,oGAAoG;IACpG,UAAU,CAAC,EAAC,MAAM,CAAC;CACpB;AAED,+FAA+F;AAC/F,wBAAgB,UAAU,CAAC,QAAQ,EAAC,SAAS,WAAW,EAAE,EAAC,OAAO,GAAC,mBAAsB,GAAE,KAAK,EAAE,EAAE,CA4CnG"}
@@ -0,0 +1,64 @@
1
+ import { contourPath } from "./path-geometry.js";
2
+ /** Sample separate pen-down paths. The original editable contour commands remain untouched. */
3
+ export function samplePath(commands, options = {}) {
4
+ const step = options.step ?? 2, maxSamples = options.maxSamples ?? 1_000_000;
5
+ if (!Number.isFinite(step) || step <= 0)
6
+ throw new Error("Path sampling step must be positive and finite");
7
+ if (!Number.isSafeInteger(maxSamples) || maxSamples < 2)
8
+ throw new Error("Path sampling maxSamples must be a whole number of at least two");
9
+ contourPath(commands);
10
+ const contours = [];
11
+ let current = [], origin;
12
+ const finish = () => { if (current.length > 1)
13
+ contours.push(current); current = []; };
14
+ for (const command of commands) {
15
+ if (command.op === "M") {
16
+ finish();
17
+ origin = { x: command.x, y: command.y };
18
+ current = [command];
19
+ }
20
+ else if (command.op === "Z") {
21
+ // Native closed sampling offsets the first point. An explicit closing line preserves the seam.
22
+ if (current.length > 1) {
23
+ current.push({ op: "L", ...origin });
24
+ finish();
25
+ }
26
+ }
27
+ else {
28
+ if (!current.length)
29
+ current = [{ op: "M", ...origin }];
30
+ current.push(command);
31
+ }
32
+ }
33
+ finish();
34
+ let estimated = 0;
35
+ for (const contour of contours) {
36
+ const start = contour[0];
37
+ let x = start.x, y = start.y, length = 0;
38
+ const to = (xx, yy) => { length += Math.hypot(xx - x, yy - y); x = xx; y = yy; };
39
+ for (const command of contour.slice(1)) {
40
+ if (command.op === "Q" || command.op === "C")
41
+ to(command.x1, command.y1);
42
+ if (command.op === "C")
43
+ to(command.x2, command.y2);
44
+ if (command.op !== "Z")
45
+ to(command.x, command.y);
46
+ }
47
+ estimated += Math.ceil(length / step) + 2;
48
+ if (estimated > maxSamples)
49
+ throw new Error(`Path sampling estimate ${estimated} exceeds maxSamples ${maxSamples}; increase the explicit budget or step`);
50
+ }
51
+ const result = [];
52
+ for (const contour of contours) {
53
+ const sampled = contourPath(contour).points(step);
54
+ if (!sampled.length)
55
+ continue;
56
+ const first = contour[0], last = contour.at(-1);
57
+ const points = sampled.map(([x, y], index) => ({ x, y, time: index * 8 }));
58
+ Object.assign(points[0], { x: first.x, y: first.y });
59
+ Object.assign(points.at(-1), { x: last.x, y: last.y });
60
+ result.push(points);
61
+ }
62
+ return result;
63
+ }
64
+ //# sourceMappingURL=path-sampling.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-sampling.js","sourceRoot":"","sources":["../../../src/drawing/path-sampling.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,WAAW,EAAC,MAAM,oBAAoB,CAAC;AAS/C,+FAA+F;AAC/F,MAAM,UAAU,UAAU,CAAC,QAA+B,EAAC,UAA4B,EAAE;IACvF,MAAM,IAAI,GAAC,OAAO,CAAC,IAAI,IAAE,CAAC,EAAC,UAAU,GAAC,OAAO,CAAC,UAAU,IAAE,SAAS,CAAC;IACpE,IAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAE,IAAI,IAAE,CAAC;QAAC,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACrG,IAAG,CAAC,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,IAAE,UAAU,GAAC,CAAC;QAAC,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;IACtI,WAAW,CAAC,QAAQ,CAAC,CAAC;IACtB,MAAM,QAAQ,GAAiB,EAAE,CAAC;IAClC,IAAI,OAAO,GAAe,EAAE,EAAC,MAAoC,CAAC;IAClE,MAAM,MAAM,GAAC,GAAE,EAAE,GAAC,IAAG,OAAO,CAAC,MAAM,GAAC,CAAC;QAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAA,OAAO,GAAC,EAAE,CAAC,CAAA,CAAC,CAAC;IAC1E,KAAI,MAAM,OAAO,IAAI,QAAQ,EAAC,CAAC;QAC7B,IAAG,OAAO,CAAC,EAAE,KAAG,GAAG,EAAC,CAAC;YACnB,MAAM,EAAE,CAAC;YAAA,MAAM,GAAC,EAAC,CAAC,EAAC,OAAO,CAAC,CAAC,EAAC,CAAC,EAAC,OAAO,CAAC,CAAC,EAAC,CAAC;YAAA,OAAO,GAAC,CAAC,OAAO,CAAC,CAAC;QAC9D,CAAC;aAAK,IAAG,OAAO,CAAC,EAAE,KAAG,GAAG,EAAC,CAAC;YACzB,+FAA+F;YAC/F,IAAG,OAAO,CAAC,MAAM,GAAC,CAAC,EAAC,CAAC;gBAAA,OAAO,CAAC,IAAI,CAAC,EAAC,EAAE,EAAC,GAAG,EAAC,GAAG,MAAO,EAAC,CAAC,CAAC;gBAAA,MAAM,EAAE,CAAC;YAAA,CAAC;QACnE,CAAC;aAAI,CAAC;YACJ,IAAG,CAAC,OAAO,CAAC,MAAM;gBAAC,OAAO,GAAC,CAAC,EAAC,EAAE,EAAC,GAAG,EAAC,GAAG,MAAO,EAAC,CAAC,CAAC;YACjD,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IACD,MAAM,EAAE,CAAC;IACT,IAAI,SAAS,GAAC,CAAC,CAAC;IAChB,KAAI,MAAM,OAAO,IAAI,QAAQ,EAAC,CAAC;QAC7B,MAAM,KAAK,GAAC,OAAO,CAAC,CAAC,CAAyB,CAAC;QAC/C,IAAI,CAAC,GAAC,KAAK,CAAC,CAAC,EAAC,CAAC,GAAC,KAAK,CAAC,CAAC,EAAC,MAAM,GAAC,CAAC,CAAC;QACjC,MAAM,EAAE,GAAC,CAAC,EAAS,EAAC,EAAS,EAAC,EAAE,GAAC,MAAM,IAAE,IAAI,CAAC,KAAK,CAAC,EAAE,GAAC,CAAC,EAAC,EAAE,GAAC,CAAC,CAAC,CAAC,CAAA,CAAC,GAAC,EAAE,CAAC,CAAA,CAAC,GAAC,EAAE,CAAC,CAAA,CAAC,CAAC;QAC3E,KAAI,MAAM,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAC,CAAC;YACrC,IAAG,OAAO,CAAC,EAAE,KAAG,GAAG,IAAE,OAAO,CAAC,EAAE,KAAG,GAAG;gBAAC,EAAE,CAAC,OAAO,CAAC,EAAE,EAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAChE,IAAG,OAAO,CAAC,EAAE,KAAG,GAAG;gBAAC,EAAE,CAAC,OAAO,CAAC,EAAE,EAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAC9C,IAAG,OAAO,CAAC,EAAE,KAAG,GAAG;gBAAC,EAAE,CAAC,OAAO,CAAC,CAAC,EAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAC9C,CAAC;QACD,SAAS,IAAE,IAAI,CAAC,IAAI,CAAC,MAAM,GAAC,IAAI,CAAC,GAAC,CAAC,CAAC;QACpC,IAAG,SAAS,GAAC,UAAU;YAAC,MAAM,IAAI,KAAK,CAAC,0BAA0B,SAAS,uBAAuB,UAAU,wCAAwC,CAAC,CAAC;IACxJ,CAAC;IACD,MAAM,MAAM,GAAW,EAAE,CAAC;IAC1B,KAAI,MAAM,OAAO,IAAI,QAAQ,EAAC,CAAC;QAC7B,MAAM,OAAO,GAAC,WAAW,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAChD,IAAG,CAAC,OAAO,CAAC,MAAM;YAAC,SAAS;QAC5B,MAAM,KAAK,GAAC,OAAO,CAAC,CAAC,CAAyB,EAAC,IAAI,GAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAyB,CAAC;QAC3F,MAAM,MAAM,GAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,KAAK,EAAC,EAAE,CAAA,CAAC,EAAC,CAAC,EAAC,CAAC,EAAC,IAAI,EAAC,KAAK,GAAC,CAAC,EAAC,CAAC,CAAC,CAAC;QAC9D,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAE,EAAC,EAAC,CAAC,EAAC,KAAK,CAAC,CAAC,EAAC,CAAC,EAAC,KAAK,CAAC,CAAC,EAAC,CAAC,CAAC;QAChD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAE,EAAC,EAAC,CAAC,EAAC,IAAI,CAAC,CAAC,EAAC,CAAC,EAAC,IAAI,CAAC,CAAC,EAAC,CAAC,CAAC;QAClD,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACtB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { PathCommand } from "../model/types.js";
2
+ /** SVG's absolute M/L/C/Q/Z subset, retained as editable contour commands. */
3
+ export declare function pathCommands(source: string): PathCommand[];
4
+ //# sourceMappingURL=path.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../../src/drawing/path.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,8EAA8E;AAC9E,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,EAAE,CAgB1D"}
@@ -0,0 +1,27 @@
1
+ /** SVG's absolute M/L/C/Q/Z subset, retained as editable contour commands. */
2
+ export function pathCommands(source) {
3
+ const tokens = source.match(/[MLCQZmlcqz]|[-+]?(?:\d*\.\d+|\d+\.?\d*)(?:[eE][-+]?\d+)?/g) ?? [];
4
+ if (source.replace(/[MLCQZmlcqz]|[-+]?(?:\d*\.\d+|\d+\.?\d*)(?:[eE][-+]?\d+)?|[\s,]/g, ""))
5
+ throw new Error("Paths support absolute M L C Q Z commands only");
6
+ const commands = [];
7
+ let i = 0;
8
+ const n = () => { const value = Number(tokens[i++]); if (!Number.isFinite(value))
9
+ throw new Error("Missing finite path coordinate"); return value; };
10
+ while (i < tokens.length) {
11
+ const op = tokens[i++];
12
+ if (op === "M" || op === "L")
13
+ commands.push({ op, x: n(), y: n() });
14
+ else if (op === "Q")
15
+ commands.push({ op, x1: n(), y1: n(), x: n(), y: n() });
16
+ else if (op === "C")
17
+ commands.push({ op, x1: n(), y1: n(), x2: n(), y2: n(), x: n(), y: n() });
18
+ else if (op === "Z")
19
+ commands.push({ op });
20
+ else
21
+ throw new Error(`Unsupported path command ${op}; repeat absolute commands explicitly`);
22
+ }
23
+ if (commands[0]?.op !== "M")
24
+ throw new Error("A contour must begin with M");
25
+ return commands;
26
+ }
27
+ //# sourceMappingURL=path.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path.js","sourceRoot":"","sources":["../../../src/drawing/path.ts"],"names":[],"mappings":"AAEA,8EAA8E;AAC9E,MAAM,UAAU,YAAY,CAAC,MAAc;IACzC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,4DAA4D,CAAC,IAAI,EAAE,CAAC;IAChG,IAAI,MAAM,CAAC,OAAO,CAAC,kEAAkE,EAAE,EAAE,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IAC9J,MAAM,QAAQ,GAAkB,EAAE,CAAC;IACnC,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,MAAM,CAAC,GAAG,GAAG,EAAE,GAAG,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;IACrJ,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;QACzB,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC;QACvB,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,GAAG;YAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;aAC/D,IAAI,EAAE,KAAK,GAAG;YAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;aACxE,IAAI,EAAE,KAAK,GAAG;YAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;aAC1F,IAAI,EAAE,KAAK,GAAG;YAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;;YACtC,MAAM,IAAI,KAAK,CAAC,4BAA4B,EAAE,uCAAuC,CAAC,CAAC;IAC9F,CAAC;IACD,IAAI,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IAC5E,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { Point } from "../model/types.js";
2
+ export declare function interpolateRotation(a: number | undefined, b: number | undefined, t: number): number | undefined;
3
+ /** Supplied timestamps are anchors; omitted ones interpolate or continue at the default cadence. */
4
+ export declare function timedPoints(points: readonly Point[], defaultStep: number): Point[];
5
+ //# sourceMappingURL=pen-input.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pen-input.d.ts","sourceRoot":"","sources":["../../../src/drawing/pen-input.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,KAAK,EAAC,MAAM,mBAAmB,CAAC;AAE7C,wBAAgB,mBAAmB,CAAC,CAAC,EAAC,MAAM,GAAC,SAAS,EAAC,CAAC,EAAC,MAAM,GAAC,SAAS,EAAC,CAAC,EAAC,MAAM,GAAE,MAAM,GAAC,SAAS,CAKnG;AAED,oGAAoG;AACpG,wBAAgB,WAAW,CAAC,MAAM,EAAC,SAAS,KAAK,EAAE,EAAC,WAAW,EAAC,MAAM,GAAE,KAAK,EAAE,CAc9E"}
@@ -0,0 +1,30 @@
1
+ export function interpolateRotation(a, b, t) {
2
+ if (a === undefined)
3
+ return b;
4
+ if (b === undefined)
5
+ return a;
6
+ const delta = Math.atan2(Math.sin(b - a), Math.cos(b - a));
7
+ return a + delta * t;
8
+ }
9
+ /** Supplied timestamps are anchors; omitted ones interpolate or continue at the default cadence. */
10
+ export function timedPoints(points, defaultStep) {
11
+ const result = points.map(p => ({ ...p }));
12
+ if (!result.length)
13
+ return result;
14
+ result[0].time ??= 0;
15
+ let previous = 0;
16
+ for (let i = 0; i < result.length; i++) {
17
+ const time = result[i].time;
18
+ if (time === undefined)
19
+ continue;
20
+ if (!Number.isFinite(time) || time < 0 || time < result[previous].time)
21
+ throw new Error("Pen timestamps must be finite, nonnegative and nondecreasing milliseconds");
22
+ for (let j = previous + 1; j < i; j++)
23
+ result[j].time = result[previous].time + (time - result[previous].time) * (j - previous) / (i - previous);
24
+ previous = i;
25
+ }
26
+ for (let i = previous + 1; i < result.length; i++)
27
+ result[i].time = result[previous].time + (i - previous) * defaultStep;
28
+ return result;
29
+ }
30
+ //# sourceMappingURL=pen-input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pen-input.js","sourceRoot":"","sources":["../../../src/drawing/pen-input.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,mBAAmB,CAAC,CAAkB,EAAC,CAAkB,EAAC,CAAQ;IAChF,IAAG,CAAC,KAAG,SAAS;QAAC,OAAO,CAAC,CAAC;IAC1B,IAAG,CAAC,KAAG,SAAS;QAAC,OAAO,CAAC,CAAC;IAC1B,MAAM,KAAK,GAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAC,CAAC,CAAC,EAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,CAAC;IACpD,OAAO,CAAC,GAAC,KAAK,GAAC,CAAC,CAAC;AACnB,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,WAAW,CAAC,MAAuB,EAAC,WAAkB;IACpE,MAAM,MAAM,GAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA,EAAE,CAAA,CAAC,EAAC,GAAG,CAAC,EAAC,CAAC,CAAC,CAAC;IACrC,IAAG,CAAC,MAAM,CAAC,MAAM;QAAC,OAAO,MAAM,CAAC;IAChC,MAAM,CAAC,CAAC,CAAE,CAAC,IAAI,KAAG,CAAC,CAAC;IACpB,IAAI,QAAQ,GAAC,CAAC,CAAC;IACf,KAAI,IAAI,CAAC,GAAC,CAAC,EAAC,CAAC,GAAC,MAAM,CAAC,MAAM,EAAC,CAAC,EAAE,EAAC,CAAC;QAC/B,MAAM,IAAI,GAAC,MAAM,CAAC,CAAC,CAAE,CAAC,IAAI,CAAC;QAC3B,IAAG,IAAI,KAAG,SAAS;YAAC,SAAS;QAC7B,IAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAE,IAAI,GAAC,CAAC,IAAE,IAAI,GAAC,MAAM,CAAC,QAAQ,CAAE,CAAC,IAAK;YAAC,MAAM,IAAI,KAAK,CAAC,2EAA2E,CAAC,CAAC;QAC7J,KAAI,IAAI,CAAC,GAAC,QAAQ,GAAC,CAAC,EAAC,CAAC,GAAC,CAAC,EAAC,CAAC,EAAE;YAAC,MAAM,CAAC,CAAC,CAAE,CAAC,IAAI,GAAC,MAAM,CAAC,QAAQ,CAAE,CAAC,IAAK,GAAC,CAAC,IAAI,GAAC,MAAM,CAAC,QAAQ,CAAE,CAAC,IAAK,CAAC,GAAC,CAAC,CAAC,GAAC,QAAQ,CAAC,GAAC,CAAC,CAAC,GAAC,QAAQ,CAAC,CAAC;QAC9H,QAAQ,GAAC,CAAC,CAAC;IACb,CAAC;IACD,KAAI,IAAI,CAAC,GAAC,QAAQ,GAAC,CAAC,EAAC,CAAC,GAAC,MAAM,CAAC,MAAM,EAAC,CAAC,EAAE;QAAC,MAAM,CAAC,CAAC,CAAE,CAAC,IAAI,GAAC,MAAM,CAAC,QAAQ,CAAE,CAAC,IAAK,GAAC,CAAC,CAAC,GAAC,QAAQ,CAAC,GAAC,WAAW,CAAC;IAC1G,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,23 @@
1
+ import type { PixelBuffer, Point } from "../model/types.js";
2
+ export interface PixelSelection {
3
+ width: number;
4
+ height: number;
5
+ coverage: Uint8Array;
6
+ }
7
+ export type PixelColor = readonly [number, number, number, number];
8
+ export declare function polygonPixelSelection(width: number, height: number, points: Pick<Point, "x" | "y">[], fillRule?: "nonzero" | "evenodd"): PixelSelection;
9
+ /** Four-connected flood or all matching pixels, measured in premultiplied RGBA byte units. */
10
+ export declare function colorPixelSelection(image: PixelBuffer, x: number, y: number, options?: {
11
+ tolerance?: number;
12
+ contiguous?: boolean;
13
+ }): PixelSelection;
14
+ export declare function combinePixelSelections(a: PixelSelection, b: PixelSelection, operation: "union" | "intersect" | "subtract"): PixelSelection;
15
+ export declare function invertPixelSelection(selection: PixelSelection): PixelSelection;
16
+ /** Gaussian coverage feathering in source-pixel units; boundary samples repeat edge coverage. */
17
+ export declare function featherPixelSelection(selection: PixelSelection, sigma: number): Promise<PixelSelection>;
18
+ /** Apply coverage without flattening the source surface or its later paint strokes. */
19
+ export declare function fillPixels(image: PixelBuffer, color: PixelColor, options?: {
20
+ selection?: PixelSelection;
21
+ mode?: "source-over" | "copy" | "destination-out" | "source-atop";
22
+ }): void;
23
+ //# sourceMappingURL=pixel-selection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pixel-selection.d.ts","sourceRoot":"","sources":["../../../src/drawing/pixel-selection.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAG5D,MAAM,WAAW,cAAc;IAAG,KAAK,EAAC,MAAM,CAAC;IAAC,MAAM,EAAC,MAAM,CAAC;IAAC,QAAQ,EAAC,UAAU,CAAA;CAAE;AACpF,MAAM,MAAM,UAAU,GAAG,SAAS,CAAC,MAAM,EAAC,MAAM,EAAC,MAAM,EAAC,MAAM,CAAC,CAAC;AAQhE,wBAAgB,qBAAqB,CAAC,KAAK,EAAC,MAAM,EAAC,MAAM,EAAC,MAAM,EAAC,MAAM,EAAC,IAAI,CAAC,KAAK,EAAC,GAAG,GAAC,GAAG,CAAC,EAAE,EAAC,QAAQ,GAAC,SAAS,GAAC,SAAmB,GAAE,cAAc,CAWnJ;AAED,8FAA8F;AAC9F,wBAAgB,mBAAmB,CAAC,KAAK,EAAC,WAAW,EAAC,CAAC,EAAC,MAAM,EAAC,CAAC,EAAC,MAAM,EAAC,OAAO,GAAC;IAAC,SAAS,CAAC,EAAC,MAAM,CAAC;IAAA,UAAU,CAAC,EAAC,OAAO,CAAA;CAAI,GAAE,cAAc,CA2BzI;AAED,wBAAgB,sBAAsB,CAAC,CAAC,EAAC,cAAc,EAAC,CAAC,EAAC,cAAc,EAAC,SAAS,EAAC,OAAO,GAAC,WAAW,GAAC,UAAU,GAAE,cAAc,CAMhI;AAED,wBAAgB,oBAAoB,CAAC,SAAS,EAAC,cAAc,GAAE,cAAc,CAG5E;AAED,iGAAiG;AACjG,wBAAsB,qBAAqB,CAAC,SAAS,EAAC,cAAc,EAAC,KAAK,EAAC,MAAM,GAAE,OAAO,CAAC,cAAc,CAAC,CASzG;AAED,uFAAuF;AACvF,wBAAgB,UAAU,CAAC,KAAK,EAAC,WAAW,EAAC,KAAK,EAAC,UAAU,EAAC,OAAO,GAAC;IAAC,SAAS,CAAC,EAAC,cAAc,CAAC;IAAA,IAAI,CAAC,EAAC,aAAa,GAAC,MAAM,GAAC,iBAAiB,GAAC,aAAa,CAAA;CAAI,GAAE,IAAI,CAuBpK"}
@@ -0,0 +1,142 @@
1
+ import sharp from "sharp";
2
+ import { Canvas } from "skia-canvas";
3
+ import { validateDimensions, validatePixels } from "./pixels.js";
4
+ function validateSelection(selection, width = selection.width, height = selection.height) {
5
+ validateDimensions(selection.width, selection.height);
6
+ if (selection.width !== width || selection.height !== height || !(selection.coverage instanceof Uint8Array) || selection.coverage.length !== width * height)
7
+ throw new Error("Selection must contain one coverage byte per source pixel with matching dimensions");
8
+ }
9
+ export function polygonPixelSelection(width, height, points, fillRule = "nonzero") {
10
+ validateDimensions(width, height);
11
+ if (points.length < 3 || points.some(p => !Number.isFinite(p.x) || !Number.isFinite(p.y)))
12
+ throw new Error("A polygon selection requires at least three finite points");
13
+ if (fillRule !== "nonzero" && fillRule !== "evenodd")
14
+ throw new Error("Unknown selection fill rule");
15
+ const ctx = new Canvas(width, height).getContext("2d");
16
+ ctx.beginPath();
17
+ ctx.moveTo(points[0].x, points[0].y);
18
+ for (const point of points.slice(1))
19
+ ctx.lineTo(point.x, point.y);
20
+ ctx.closePath();
21
+ ctx.fillStyle = "#ffffff";
22
+ ctx.fill(fillRule);
23
+ const data = ctx.getImageData(0, 0, width, height).data, coverage = new Uint8Array(width * height);
24
+ for (let i = 0; i < coverage.length; i++)
25
+ coverage[i] = data[i * 4 + 3];
26
+ return { width, height, coverage };
27
+ }
28
+ /** Four-connected flood or all matching pixels, measured in premultiplied RGBA byte units. */
29
+ export function colorPixelSelection(image, x, y, options = {}) {
30
+ validatePixels(image);
31
+ if (!Number.isInteger(x) || !Number.isInteger(y) || x < 0 || y < 0 || x >= image.width || y >= image.height)
32
+ throw new Error("Selection seed must be inside the source surface");
33
+ const tolerance = options.tolerance ?? 0;
34
+ if (!Number.isFinite(tolerance) || tolerance < 0 || tolerance > 255)
35
+ throw new Error("Selection tolerance must be between 0 and 255");
36
+ const { width, height, pixels } = image, seed = y * width + x, coverage = new Uint8Array(width * height), offset = seed * 4, alpha = pixels[offset + 3];
37
+ const target = [pixels[offset] * alpha / 255, pixels[offset + 1] * alpha / 255, pixels[offset + 2] * alpha / 255, alpha];
38
+ const matches = (index) => {
39
+ const at = index * 4, a = pixels[at + 3];
40
+ if (Math.abs(a - target[3]) > tolerance)
41
+ return false;
42
+ for (let c = 0; c < 3; c++)
43
+ if (Math.abs(pixels[at + c] * a / 255 - target[c]) > tolerance)
44
+ return false;
45
+ return true;
46
+ };
47
+ if (options.contiguous === false) {
48
+ for (let i = 0; i < coverage.length; i++)
49
+ if (matches(i))
50
+ coverage[i] = 255;
51
+ }
52
+ else {
53
+ // Mark on insertion so each pixel can enter this bounded queue only once.
54
+ const queue = new Uint32Array(width * height);
55
+ let head = 0, tail = 1;
56
+ queue[0] = seed;
57
+ coverage[seed] = 255;
58
+ const add = (index) => { if (!coverage[index] && matches(index)) {
59
+ coverage[index] = 255;
60
+ queue[tail++] = index;
61
+ } };
62
+ while (head < tail) {
63
+ const index = queue[head++], column = index % width;
64
+ if (column > 0)
65
+ add(index - 1);
66
+ if (column + 1 < width)
67
+ add(index + 1);
68
+ if (index >= width)
69
+ add(index - width);
70
+ if (index + width < coverage.length)
71
+ add(index + width);
72
+ }
73
+ }
74
+ return { width, height, coverage };
75
+ }
76
+ export function combinePixelSelections(a, b, operation) {
77
+ validateSelection(a);
78
+ validateSelection(b, a.width, a.height);
79
+ if (!["union", "intersect", "subtract"].includes(operation))
80
+ throw new Error("Unknown selection combination");
81
+ const coverage = new Uint8Array(a.coverage.length);
82
+ for (let i = 0; i < coverage.length; i++)
83
+ coverage[i] = operation === "union" ? Math.max(a.coverage[i], b.coverage[i]) : operation === "intersect" ? Math.min(a.coverage[i], b.coverage[i]) : Math.max(0, a.coverage[i] - b.coverage[i]);
84
+ return { width: a.width, height: a.height, coverage };
85
+ }
86
+ export function invertPixelSelection(selection) {
87
+ validateSelection(selection);
88
+ return { ...selection, coverage: selection.coverage.map(value => 255 - value) };
89
+ }
90
+ /** Gaussian coverage feathering in source-pixel units; boundary samples repeat edge coverage. */
91
+ export async function featherPixelSelection(selection, sigma) {
92
+ validateSelection(selection);
93
+ if (!Number.isFinite(sigma) || (sigma !== 0 && (sigma < .3 || sigma > 1000)))
94
+ throw new Error("Selection feather sigma must be 0 or between 0.3 and 1000 source pixels");
95
+ const { width, height } = selection, coverage = selection.coverage.slice();
96
+ if (sigma === 0)
97
+ return { width, height, coverage };
98
+ const result = await sharp(coverage, { raw: { width, height, channels: 1 } })
99
+ .blur({ sigma, precision: "float", minAmplitude: .01 }).toColourspace("b-w").raw().toBuffer();
100
+ return { width, height, coverage: new Uint8Array(result) };
101
+ }
102
+ /** Apply coverage without flattening the source surface or its later paint strokes. */
103
+ export function fillPixels(image, color, options = {}) {
104
+ validatePixels(image);
105
+ const rgba = Array.from(color);
106
+ if (rgba.length !== 4 || rgba.some(c => !Number.isInteger(c) || c < 0 || c > 255))
107
+ throw new Error("Fill color must contain four RGBA8 channel values");
108
+ if (options.selection)
109
+ validateSelection(options.selection, image.width, image.height);
110
+ const mode = options.mode ?? "source-over";
111
+ if (!["source-over", "copy", "destination-out", "source-atop"].includes(mode))
112
+ throw new Error("Unsupported pixel fill mode");
113
+ const mask = options.selection?.coverage;
114
+ const selected = mask?.buffer === image.pixels.buffer ? mask.slice() : mask;
115
+ for (let i = 0; i < image.width * image.height; i++) {
116
+ const coverage = (selected?.[i] ?? 255) / 255;
117
+ if (!coverage)
118
+ continue;
119
+ const at = i * 4, da = image.pixels[at + 3] / 255, sa = rgba[3] / 255;
120
+ if (mode === "destination-out") {
121
+ image.pixels[at + 3] = Math.round(255 * da * (1 - sa * coverage));
122
+ continue;
123
+ }
124
+ if (mode === "source-atop") {
125
+ if (!da)
126
+ continue;
127
+ for (let c = 0; c < 3; c++)
128
+ image.pixels[at + c] = Math.round(rgba[c] * sa * coverage + image.pixels[at + c] * (1 - sa * coverage));
129
+ continue;
130
+ }
131
+ if (mode === "copy" && coverage === 1) {
132
+ image.pixels.set(rgba, at);
133
+ continue;
134
+ }
135
+ const source = sa * coverage, destination = da * (mode === "copy" ? 1 - coverage : 1 - source), alpha = source + destination;
136
+ if (alpha)
137
+ for (let c = 0; c < 3; c++)
138
+ image.pixels[at + c] = Math.round((rgba[c] * source + image.pixels[at + c] * destination) / alpha);
139
+ image.pixels[at + 3] = Math.round(alpha * 255);
140
+ }
141
+ }
142
+ //# sourceMappingURL=pixel-selection.js.map