@gjsify/canvas2d-core 0.1.3

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.
@@ -0,0 +1,39 @@
1
+ import { BLACK } from "./color.js";
2
+ function createDefaultState() {
3
+ return {
4
+ fillStyle: "#000000",
5
+ fillColor: { ...BLACK },
6
+ strokeStyle: "#000000",
7
+ strokeColor: { ...BLACK },
8
+ lineWidth: 1,
9
+ lineCap: "butt",
10
+ lineJoin: "miter",
11
+ miterLimit: 10,
12
+ lineDash: [],
13
+ lineDashOffset: 0,
14
+ globalAlpha: 1,
15
+ globalCompositeOperation: "source-over",
16
+ shadowColor: "rgba(0, 0, 0, 0)",
17
+ shadowBlur: 0,
18
+ shadowOffsetX: 0,
19
+ shadowOffsetY: 0,
20
+ font: "10px sans-serif",
21
+ textAlign: "start",
22
+ textBaseline: "alphabetic",
23
+ direction: "ltr",
24
+ imageSmoothingEnabled: true,
25
+ imageSmoothingQuality: "low"
26
+ };
27
+ }
28
+ function cloneState(state) {
29
+ return {
30
+ ...state,
31
+ fillColor: { ...state.fillColor },
32
+ strokeColor: { ...state.strokeColor },
33
+ lineDash: [...state.lineDash]
34
+ };
35
+ }
36
+ export {
37
+ cloneState,
38
+ createDefaultState
39
+ };
@@ -0,0 +1,209 @@
1
+ const NAMED_COLORS = {
2
+ aliceblue: "#f0f8ff",
3
+ antiquewhite: "#faebd7",
4
+ aqua: "#00ffff",
5
+ aquamarine: "#7fffd4",
6
+ azure: "#f0ffff",
7
+ beige: "#f5f5dc",
8
+ bisque: "#ffe4c4",
9
+ black: "#000000",
10
+ blanchedalmond: "#ffebcd",
11
+ blue: "#0000ff",
12
+ blueviolet: "#8a2be2",
13
+ brown: "#a52a2a",
14
+ burlywood: "#deb887",
15
+ cadetblue: "#5f9ea0",
16
+ chartreuse: "#7fff00",
17
+ chocolate: "#d2691e",
18
+ coral: "#ff7f50",
19
+ cornflowerblue: "#6495ed",
20
+ cornsilk: "#fff8dc",
21
+ crimson: "#dc143c",
22
+ cyan: "#00ffff",
23
+ darkblue: "#00008b",
24
+ darkcyan: "#008b8b",
25
+ darkgoldenrod: "#b8860b",
26
+ darkgray: "#a9a9a9",
27
+ darkgreen: "#006400",
28
+ darkgrey: "#a9a9a9",
29
+ darkkhaki: "#bdb76b",
30
+ darkmagenta: "#8b008b",
31
+ darkolivegreen: "#556b2f",
32
+ darkorange: "#ff8c00",
33
+ darkorchid: "#9932cc",
34
+ darkred: "#8b0000",
35
+ darksalmon: "#e9967a",
36
+ darkseagreen: "#8fbc8f",
37
+ darkslateblue: "#483d8b",
38
+ darkslategray: "#2f4f4f",
39
+ darkslategrey: "#2f4f4f",
40
+ darkturquoise: "#00ced1",
41
+ darkviolet: "#9400d3",
42
+ deeppink: "#ff1493",
43
+ deepskyblue: "#00bfff",
44
+ dimgray: "#696969",
45
+ dimgrey: "#696969",
46
+ dodgerblue: "#1e90ff",
47
+ firebrick: "#b22222",
48
+ floralwhite: "#fffaf0",
49
+ forestgreen: "#228b22",
50
+ fuchsia: "#ff00ff",
51
+ gainsboro: "#dcdcdc",
52
+ ghostwhite: "#f8f8ff",
53
+ gold: "#ffd700",
54
+ goldenrod: "#daa520",
55
+ gray: "#808080",
56
+ green: "#008000",
57
+ greenyellow: "#adff2f",
58
+ grey: "#808080",
59
+ honeydew: "#f0fff0",
60
+ hotpink: "#ff69b4",
61
+ indianred: "#cd5c5c",
62
+ indigo: "#4b0082",
63
+ ivory: "#fffff0",
64
+ khaki: "#f0e68c",
65
+ lavender: "#e6e6fa",
66
+ lavenderblush: "#fff0f5",
67
+ lawngreen: "#7cfc00",
68
+ lemonchiffon: "#fffacd",
69
+ lightblue: "#add8e6",
70
+ lightcoral: "#f08080",
71
+ lightcyan: "#e0ffff",
72
+ lightgoldenrodyellow: "#fafad2",
73
+ lightgray: "#d3d3d3",
74
+ lightgreen: "#90ee90",
75
+ lightgrey: "#d3d3d3",
76
+ lightpink: "#ffb6c1",
77
+ lightsalmon: "#ffa07a",
78
+ lightseagreen: "#20b2aa",
79
+ lightskyblue: "#87cefa",
80
+ lightslategray: "#778899",
81
+ lightslategrey: "#778899",
82
+ lightsteelblue: "#b0c4de",
83
+ lightyellow: "#ffffe0",
84
+ lime: "#00ff00",
85
+ limegreen: "#32cd32",
86
+ linen: "#faf0e6",
87
+ magenta: "#ff00ff",
88
+ maroon: "#800000",
89
+ mediumaquamarine: "#66cdaa",
90
+ mediumblue: "#0000cd",
91
+ mediumorchid: "#ba55d3",
92
+ mediumpurple: "#9370db",
93
+ mediumseagreen: "#3cb371",
94
+ mediumslateblue: "#7b68ee",
95
+ mediumspringgreen: "#00fa9a",
96
+ mediumturquoise: "#48d1cc",
97
+ mediumvioletred: "#c71585",
98
+ midnightblue: "#191970",
99
+ mintcream: "#f5fffa",
100
+ mistyrose: "#ffe4e1",
101
+ moccasin: "#ffe4b5",
102
+ navajowhite: "#ffdead",
103
+ navy: "#000080",
104
+ oldlace: "#fdf5e6",
105
+ olive: "#808000",
106
+ olivedrab: "#6b8e23",
107
+ orange: "#ffa500",
108
+ orangered: "#ff4500",
109
+ orchid: "#da70d6",
110
+ palegoldenrod: "#eee8aa",
111
+ palegreen: "#98fb98",
112
+ paleturquoise: "#afeeee",
113
+ palevioletred: "#db7093",
114
+ papayawhip: "#ffefd5",
115
+ peachpuff: "#ffdab9",
116
+ peru: "#cd853f",
117
+ pink: "#ffc0cb",
118
+ plum: "#dda0dd",
119
+ powderblue: "#b0e0e6",
120
+ purple: "#800080",
121
+ rebeccapurple: "#663399",
122
+ red: "#ff0000",
123
+ rosybrown: "#bc8f8f",
124
+ royalblue: "#4169e1",
125
+ saddlebrown: "#8b4513",
126
+ salmon: "#fa8072",
127
+ sandybrown: "#f4a460",
128
+ seagreen: "#2e8b57",
129
+ seashell: "#fff5ee",
130
+ sienna: "#a0522d",
131
+ silver: "#c0c0c0",
132
+ skyblue: "#87ceeb",
133
+ slateblue: "#6a5acd",
134
+ slategray: "#708090",
135
+ slategrey: "#708090",
136
+ snow: "#fffafa",
137
+ springgreen: "#00ff7f",
138
+ steelblue: "#4682b4",
139
+ tan: "#d2b48c",
140
+ teal: "#008080",
141
+ thistle: "#d8bfd8",
142
+ tomato: "#ff6347",
143
+ turquoise: "#40e0d0",
144
+ violet: "#ee82ee",
145
+ wheat: "#f5deb3",
146
+ white: "#ffffff",
147
+ whitesmoke: "#f5f5f5",
148
+ yellow: "#ffff00",
149
+ yellowgreen: "#9acd32",
150
+ transparent: "#00000000"
151
+ };
152
+ function parseColor(color) {
153
+ if (!color || typeof color !== "string") return null;
154
+ const trimmed = color.trim().toLowerCase();
155
+ const named = NAMED_COLORS[trimmed];
156
+ if (named) return parseHex(named);
157
+ if (trimmed.startsWith("#")) return parseHex(trimmed);
158
+ const rgbMatch = trimmed.match(
159
+ /^rgba?\(\s*(\d+(?:\.\d+)?%?)\s*[,\s]\s*(\d+(?:\.\d+)?%?)\s*[,\s]\s*(\d+(?:\.\d+)?%?)\s*(?:[,/]\s*(\d+(?:\.\d+)?%?))?\s*\)$/
160
+ );
161
+ if (rgbMatch) {
162
+ return {
163
+ r: parseComponent(rgbMatch[1], 255) / 255,
164
+ g: parseComponent(rgbMatch[2], 255) / 255,
165
+ b: parseComponent(rgbMatch[3], 255) / 255,
166
+ a: rgbMatch[4] !== void 0 ? parseComponent(rgbMatch[4], 1) : 1
167
+ };
168
+ }
169
+ return null;
170
+ }
171
+ function parseHex(hex) {
172
+ const h = hex.slice(1);
173
+ let r, g, b, a = 1;
174
+ if (h.length === 3) {
175
+ r = parseInt(h[0] + h[0], 16) / 255;
176
+ g = parseInt(h[1] + h[1], 16) / 255;
177
+ b = parseInt(h[2] + h[2], 16) / 255;
178
+ } else if (h.length === 4) {
179
+ r = parseInt(h[0] + h[0], 16) / 255;
180
+ g = parseInt(h[1] + h[1], 16) / 255;
181
+ b = parseInt(h[2] + h[2], 16) / 255;
182
+ a = parseInt(h[3] + h[3], 16) / 255;
183
+ } else if (h.length === 6) {
184
+ r = parseInt(h.slice(0, 2), 16) / 255;
185
+ g = parseInt(h.slice(2, 4), 16) / 255;
186
+ b = parseInt(h.slice(4, 6), 16) / 255;
187
+ } else if (h.length === 8) {
188
+ r = parseInt(h.slice(0, 2), 16) / 255;
189
+ g = parseInt(h.slice(2, 4), 16) / 255;
190
+ b = parseInt(h.slice(4, 6), 16) / 255;
191
+ a = parseInt(h.slice(6, 8), 16) / 255;
192
+ } else {
193
+ return null;
194
+ }
195
+ return { r, g, b, a };
196
+ }
197
+ function parseComponent(value, max) {
198
+ if (value.endsWith("%")) {
199
+ return parseFloat(value) / 100 * max;
200
+ }
201
+ return parseFloat(value);
202
+ }
203
+ const BLACK = { r: 0, g: 0, b: 0, a: 1 };
204
+ const TRANSPARENT = { r: 0, g: 0, b: 0, a: 0 };
205
+ export {
206
+ BLACK,
207
+ TRANSPARENT,
208
+ parseColor
209
+ };
@@ -0,0 +1,22 @@
1
+ class OurImageData {
2
+ constructor(swOrData, sh, maybeHeight) {
3
+ this.colorSpace = "srgb";
4
+ if (typeof swOrData === "number") {
5
+ this.width = swOrData;
6
+ this.height = sh;
7
+ this.data = new Uint8ClampedArray(this.width * this.height * 4);
8
+ } else {
9
+ this.data = swOrData;
10
+ this.width = sh;
11
+ this.height = maybeHeight ?? this.data.length / (4 * this.width);
12
+ if (this.data.length !== this.width * this.height * 4) {
13
+ throw new RangeError(
14
+ `Source data length ${this.data.length} is not a multiple of (4 * width=${this.width})`
15
+ );
16
+ }
17
+ }
18
+ }
19
+ }
20
+ export {
21
+ OurImageData
22
+ };
@@ -0,0 +1,14 @@
1
+ import { CanvasRenderingContext2D } from "./canvas-rendering-context-2d.js";
2
+ import { CanvasGradient } from "./canvas-gradient.js";
3
+ import { CanvasPattern } from "./canvas-pattern.js";
4
+ import { Path2D } from "./canvas-path.js";
5
+ import { OurImageData } from "./image-data.js";
6
+ import { parseColor } from "./color.js";
7
+ export {
8
+ CanvasGradient,
9
+ CanvasPattern,
10
+ CanvasRenderingContext2D,
11
+ OurImageData as ImageData,
12
+ Path2D,
13
+ parseColor
14
+ };
@@ -0,0 +1,54 @@
1
+ import type Cairo from 'cairo';
2
+ /**
3
+ * Convert quadratic Bezier control point to cubic Bezier control points.
4
+ * Canvas 2D has quadraticCurveTo but Cairo only has cubic curveTo.
5
+ *
6
+ * Given current point (cx, cy), quadratic control point (cpx, cpy), and end (x, y):
7
+ * cp1 = current + 2/3 * (cp - current)
8
+ * cp2 = end + 2/3 * (cp - end)
9
+ */
10
+ export declare function quadraticToCubic(cx: number, cy: number, cpx: number, cpy: number, x: number, y: number): {
11
+ cp1x: number;
12
+ cp1y: number;
13
+ cp2x: number;
14
+ cp2y: number;
15
+ };
16
+ /**
17
+ * Compute arcTo parameters.
18
+ * Canvas arcTo(x1,y1,x2,y2,radius) draws a line from current point to the tangent point,
19
+ * then an arc of the given radius tangent to both lines (current→p1 and p1→p2).
20
+ *
21
+ * Returns the two tangent points and arc center, or null if degenerate (collinear points).
22
+ */
23
+ export declare function computeArcTo(x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, radius: number): {
24
+ tx0: number;
25
+ ty0: number;
26
+ tx1: number;
27
+ ty1: number;
28
+ cx: number;
29
+ cy: number;
30
+ startAngle: number;
31
+ endAngle: number;
32
+ counterclockwise: boolean;
33
+ } | null;
34
+ /**
35
+ * Apply an arcTo operation to a Cairo context.
36
+ */
37
+ export declare function cairoArcTo(ctx: Cairo.Context, x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, radius: number): void;
38
+ /**
39
+ * Draw an ellipse on a Cairo context.
40
+ * Canvas ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, counterclockwise)
41
+ * is implemented via save/translate/rotate/scale/arc/restore.
42
+ */
43
+ export declare function cairoEllipse(ctx: Cairo.Context, x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, counterclockwise: boolean): void;
44
+ /**
45
+ * Draw a rounded rectangle path on a Cairo context.
46
+ * Implements the Canvas roundRect(x, y, w, h, radii) method.
47
+ */
48
+ export declare function cairoRoundRect(ctx: Cairo.Context, x: number, y: number, w: number, h: number, radii: number | number[]): void;
49
+ /** Map Canvas globalCompositeOperation to Cairo.Operator values */
50
+ export declare const COMPOSITE_OP_MAP: Record<string, number>;
51
+ /** Map Canvas lineCap to Cairo.LineCap values */
52
+ export declare const LINE_CAP_MAP: Record<string, number>;
53
+ /** Map Canvas lineJoin to Cairo.LineJoin values */
54
+ export declare const LINE_JOIN_MAP: Record<string, number>;
@@ -0,0 +1,11 @@
1
+ import Cairo from 'cairo';
2
+ /**
3
+ * CanvasGradient wrapping a Cairo LinearGradient or RadialGradient.
4
+ */
5
+ export declare class CanvasGradient {
6
+ private _pattern;
7
+ constructor(type: 'linear' | 'radial', x0: number, y0: number, x1: number, y1: number, r0?: number, r1?: number);
8
+ addColorStop(offset: number, color: string): void;
9
+ /** @internal Get the underlying Cairo pattern for rendering. */
10
+ _getCairoPattern(): Cairo.LinearGradient | Cairo.RadialGradient;
11
+ }
@@ -0,0 +1,80 @@
1
+ /** A recorded path operation. */
2
+ type PathOp = {
3
+ type: 'moveTo';
4
+ x: number;
5
+ y: number;
6
+ } | {
7
+ type: 'lineTo';
8
+ x: number;
9
+ y: number;
10
+ } | {
11
+ type: 'closePath';
12
+ } | {
13
+ type: 'bezierCurveTo';
14
+ cp1x: number;
15
+ cp1y: number;
16
+ cp2x: number;
17
+ cp2y: number;
18
+ x: number;
19
+ y: number;
20
+ } | {
21
+ type: 'quadraticCurveTo';
22
+ cpx: number;
23
+ cpy: number;
24
+ x: number;
25
+ y: number;
26
+ } | {
27
+ type: 'arc';
28
+ x: number;
29
+ y: number;
30
+ radius: number;
31
+ startAngle: number;
32
+ endAngle: number;
33
+ ccw: boolean;
34
+ } | {
35
+ type: 'ellipse';
36
+ x: number;
37
+ y: number;
38
+ rx: number;
39
+ ry: number;
40
+ rotation: number;
41
+ startAngle: number;
42
+ endAngle: number;
43
+ ccw: boolean;
44
+ } | {
45
+ type: 'rect';
46
+ x: number;
47
+ y: number;
48
+ w: number;
49
+ h: number;
50
+ } | {
51
+ type: 'roundRect';
52
+ x: number;
53
+ y: number;
54
+ w: number;
55
+ h: number;
56
+ radii: number | number[];
57
+ };
58
+ /**
59
+ * Path2D records path operations for later replay on a CanvasRenderingContext2D.
60
+ */
61
+ export declare class Path2D {
62
+ /** @internal Recorded operations */
63
+ _ops: PathOp[];
64
+ constructor(pathOrSvg?: Path2D | string);
65
+ addPath(path: Path2D): void;
66
+ moveTo(x: number, y: number): void;
67
+ lineTo(x: number, y: number): void;
68
+ closePath(): void;
69
+ bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): void;
70
+ quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void;
71
+ arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise?: boolean): void;
72
+ ellipse(x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, counterclockwise?: boolean): void;
73
+ rect(x: number, y: number, w: number, h: number): void;
74
+ roundRect(x: number, y: number, w: number, h: number, radii?: number | number[]): void;
75
+ /**
76
+ * @internal Replay all recorded path operations onto a Cairo context.
77
+ */
78
+ _replayOnCairo(ctx: import('cairo').default.Context): void;
79
+ }
80
+ export {};
@@ -0,0 +1,12 @@
1
+ import Cairo from 'cairo';
2
+ /**
3
+ * CanvasPattern wrapping a Cairo SurfacePattern.
4
+ */
5
+ export declare class CanvasPattern {
6
+ private _pattern;
7
+ private constructor();
8
+ /** Create a CanvasPattern from a supported image source. Returns null if unsupported. */
9
+ static create(image: any, repetition: string | null): CanvasPattern | null;
10
+ /** @internal Get the underlying Cairo pattern for rendering. */
11
+ _getCairoPattern(): Cairo.SurfacePattern;
12
+ }
@@ -0,0 +1,164 @@
1
+ import Cairo from 'cairo';
2
+ import { Path2D } from './canvas-path.js';
3
+ /**
4
+ * CanvasRenderingContext2D backed by Cairo.ImageSurface.
5
+ * Implements the Canvas 2D API for GJS.
6
+ */
7
+ export declare class CanvasRenderingContext2D {
8
+ readonly canvas: any;
9
+ private _surface;
10
+ private _ctx;
11
+ private _state;
12
+ private _stateStack;
13
+ private _surfaceWidth;
14
+ private _surfaceHeight;
15
+ constructor(canvas: any, _options?: any);
16
+ /** Ensure the surface matches the current canvas dimensions. Recreate if resized. */
17
+ private _ensureSurface;
18
+ /** Reset drawing state to defaults (called when canvas dimensions are explicitly reset). */
19
+ _resetState(): void;
20
+ /** Apply the current fill style (color, gradient, or pattern) to the Cairo context. */
21
+ private _applyFillStyle;
22
+ /** Apply the current stroke style to the Cairo context. */
23
+ private _applyStrokeStyle;
24
+ /** Apply line properties to the Cairo context. */
25
+ private _applyLineStyle;
26
+ /** Apply compositing operator. */
27
+ private _applyCompositing;
28
+ /** Get the Cairo ImageSurface (used by other contexts like drawImage). */
29
+ _getSurface(): Cairo.ImageSurface;
30
+ /** Check if shadow rendering is needed. */
31
+ private _hasShadow;
32
+ /**
33
+ * Render a shadow for the current path by painting to a temp surface,
34
+ * applying a simple box blur approximation, and compositing back.
35
+ * This is called before the actual fill/stroke when shadows are active.
36
+ */
37
+ private _renderShadow;
38
+ save(): void;
39
+ restore(): void;
40
+ translate(x: number, y: number): void;
41
+ rotate(angle: number): void;
42
+ scale(x: number, y: number): void;
43
+ /**
44
+ * Multiply the current transformation matrix by the given values.
45
+ * Matrix: [a c e]
46
+ * [b d f]
47
+ * [0 0 1]
48
+ */
49
+ transform(a: number, b: number, c: number, d: number, e: number, f: number): void;
50
+ /**
51
+ * Reset the transform to identity, then apply the given matrix.
52
+ */
53
+ setTransform(matrix?: DOMMatrix2DInit): void;
54
+ setTransform(a: number, b: number, c: number, d: number, e: number, f: number): void;
55
+ /**
56
+ * Return the current transformation matrix as a DOMMatrix-like object.
57
+ */
58
+ getTransform(): DOMMatrix;
59
+ resetTransform(): void;
60
+ get fillStyle(): string | CanvasGradient | CanvasPattern;
61
+ set fillStyle(value: string | CanvasGradient | CanvasPattern);
62
+ get strokeStyle(): string | CanvasGradient | CanvasPattern;
63
+ set strokeStyle(value: string | CanvasGradient | CanvasPattern);
64
+ get lineWidth(): number;
65
+ set lineWidth(value: number);
66
+ get lineCap(): CanvasLineCap;
67
+ set lineCap(value: CanvasLineCap);
68
+ get lineJoin(): CanvasLineJoin;
69
+ set lineJoin(value: CanvasLineJoin);
70
+ get miterLimit(): number;
71
+ set miterLimit(value: number);
72
+ get globalAlpha(): number;
73
+ set globalAlpha(value: number);
74
+ get globalCompositeOperation(): GlobalCompositeOperation;
75
+ set globalCompositeOperation(value: GlobalCompositeOperation);
76
+ get imageSmoothingEnabled(): boolean;
77
+ set imageSmoothingEnabled(value: boolean);
78
+ get imageSmoothingQuality(): ImageSmoothingQuality;
79
+ set imageSmoothingQuality(value: ImageSmoothingQuality);
80
+ setLineDash(segments: number[]): void;
81
+ getLineDash(): number[];
82
+ get lineDashOffset(): number;
83
+ set lineDashOffset(value: number);
84
+ get shadowColor(): string;
85
+ set shadowColor(value: string);
86
+ get shadowBlur(): number;
87
+ set shadowBlur(value: number);
88
+ get shadowOffsetX(): number;
89
+ set shadowOffsetX(value: number);
90
+ get shadowOffsetY(): number;
91
+ set shadowOffsetY(value: number);
92
+ get font(): string;
93
+ set font(value: string);
94
+ get textAlign(): CanvasTextAlign;
95
+ set textAlign(value: CanvasTextAlign);
96
+ get textBaseline(): CanvasTextBaseline;
97
+ set textBaseline(value: CanvasTextBaseline);
98
+ get direction(): CanvasDirection;
99
+ set direction(value: CanvasDirection);
100
+ beginPath(): void;
101
+ moveTo(x: number, y: number): void;
102
+ lineTo(x: number, y: number): void;
103
+ closePath(): void;
104
+ bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): void;
105
+ quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void;
106
+ arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise?: boolean): void;
107
+ arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void;
108
+ ellipse(x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, counterclockwise?: boolean): void;
109
+ rect(x: number, y: number, w: number, h: number): void;
110
+ roundRect(x: number, y: number, w: number, h: number, radii?: number | number[]): void;
111
+ fill(fillRule?: CanvasFillRule): void;
112
+ fill(path: Path2D, fillRule?: CanvasFillRule): void;
113
+ stroke(): void;
114
+ stroke(path: Path2D): void;
115
+ fillRect(x: number, y: number, w: number, h: number): void;
116
+ strokeRect(x: number, y: number, w: number, h: number): void;
117
+ clearRect(x: number, y: number, w: number, h: number): void;
118
+ clip(fillRule?: CanvasFillRule): void;
119
+ clip(path: Path2D, fillRule?: CanvasFillRule): void;
120
+ isPointInPath(x: number, y: number, fillRule?: CanvasFillRule): boolean;
121
+ isPointInPath(path: Path2D, x: number, y: number, fillRule?: CanvasFillRule): boolean;
122
+ isPointInStroke(x: number, y: number): boolean;
123
+ isPointInStroke(path: Path2D, x: number, y: number): boolean;
124
+ createLinearGradient(x0: number, y0: number, x1: number, y1: number): CanvasGradient;
125
+ createRadialGradient(x0: number, y0: number, r0: number, x1: number, y1: number, r1: number): CanvasGradient;
126
+ createPattern(image: any, repetition: string | null): CanvasPattern | null;
127
+ createImageData(sw: number, sh: number): ImageData;
128
+ createImageData(imagedata: ImageData): ImageData;
129
+ getImageData(sx: number, sy: number, sw: number, sh: number): ImageData;
130
+ putImageData(imageData: ImageData, dx: number, dy: number, dirtyX?: number, dirtyY?: number, dirtyWidth?: number, dirtyHeight?: number): void;
131
+ drawImage(image: any, dx: number, dy: number): void;
132
+ drawImage(image: any, dx: number, dy: number, dw: number, dh: number): void;
133
+ drawImage(image: any, sx: number, sy: number, sw: number, sh: number, dx: number, dy: number, dw: number, dh: number): void;
134
+ private _getDrawImageSource;
135
+ /** Create a PangoCairo layout configured with current font/text settings. */
136
+ private _createTextLayout;
137
+ /** Parse a CSS font string (e.g. "bold 16px Arial") into a Pango.FontDescription. */
138
+ private _parseFontToDescription;
139
+ /**
140
+ * Compute the x-offset for text alignment relative to the given x coordinate.
141
+ */
142
+ private _getTextAlignOffset;
143
+ /**
144
+ * Compute the y-offset for text baseline positioning.
145
+ *
146
+ * PangoCairo.show_layout() places the layout TOP-LEFT at the current Cairo point
147
+ * (not the baseline). Within the layout, the first line's baseline is at
148
+ * approximately `ascent` pixels below the layout top.
149
+ *
150
+ * For CSS textBaseline semantics, we shift the current point UP (negative offset)
151
+ * so the layout top lands at the right position relative to the user's y coordinate.
152
+ */
153
+ private _getTextBaselineOffset;
154
+ fillText(text: string, x: number, y: number, _maxWidth?: number): void;
155
+ strokeText(text: string, x: number, y: number, _maxWidth?: number): void;
156
+ measureText(text: string): TextMetrics;
157
+ /**
158
+ * Write the canvas surface to a PNG file and return as data URL.
159
+ * Used by HTMLCanvasElement.toDataURL() when a '2d' context is active.
160
+ */
161
+ _toDataURL(type?: string, _quality?: number): string;
162
+ /** Release native Cairo resources. Call when the canvas is discarded. */
163
+ _dispose(): void;
164
+ }
@@ -0,0 +1,27 @@
1
+ import type { RGBA } from './color.js';
2
+ export interface CanvasState {
3
+ fillStyle: string | CanvasGradient | CanvasPattern;
4
+ fillColor: RGBA;
5
+ strokeStyle: string | CanvasGradient | CanvasPattern;
6
+ strokeColor: RGBA;
7
+ lineWidth: number;
8
+ lineCap: CanvasLineCap;
9
+ lineJoin: CanvasLineJoin;
10
+ miterLimit: number;
11
+ lineDash: number[];
12
+ lineDashOffset: number;
13
+ globalAlpha: number;
14
+ globalCompositeOperation: GlobalCompositeOperation;
15
+ shadowColor: string;
16
+ shadowBlur: number;
17
+ shadowOffsetX: number;
18
+ shadowOffsetY: number;
19
+ font: string;
20
+ textAlign: CanvasTextAlign;
21
+ textBaseline: CanvasTextBaseline;
22
+ direction: CanvasDirection;
23
+ imageSmoothingEnabled: boolean;
24
+ imageSmoothingQuality: ImageSmoothingQuality;
25
+ }
26
+ export declare function createDefaultState(): CanvasState;
27
+ export declare function cloneState(state: CanvasState): CanvasState;
@@ -0,0 +1,15 @@
1
+ export interface RGBA {
2
+ r: number;
3
+ g: number;
4
+ b: number;
5
+ a: number;
6
+ }
7
+ /**
8
+ * Parse a CSS color string into RGBA components (0-1 range).
9
+ * Supports: #rgb, #rrggbb, #rgba, #rrggbbaa, rgb(), rgba(), named colors, 'transparent'.
10
+ */
11
+ export declare function parseColor(color: string): RGBA | null;
12
+ /** Default color: opaque black */
13
+ export declare const BLACK: RGBA;
14
+ /** Transparent black */
15
+ export declare const TRANSPARENT: RGBA;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * ImageData represents the pixel data of a canvas area.
3
+ * Each pixel is 4 bytes: R, G, B, A (0-255 each).
4
+ */
5
+ export declare class OurImageData {
6
+ readonly data: Uint8ClampedArray;
7
+ readonly width: number;
8
+ readonly height: number;
9
+ readonly colorSpace: PredefinedColorSpace;
10
+ constructor(sw: number, sh: number);
11
+ constructor(data: Uint8ClampedArray, sw: number, sh?: number);
12
+ }
@@ -0,0 +1,6 @@
1
+ export { CanvasRenderingContext2D } from './canvas-rendering-context-2d.js';
2
+ export { CanvasGradient } from './canvas-gradient.js';
3
+ export { CanvasPattern } from './canvas-pattern.js';
4
+ export { Path2D } from './canvas-path.js';
5
+ export { OurImageData as ImageData } from './image-data.js';
6
+ export { parseColor } from './color.js';