@gjsify/canvas2d-core 0.4.0 → 0.4.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.
- package/package.json +50 -46
- package/src/cairo-types.ts +0 -44
- package/src/cairo-utils.ts +0 -254
- package/src/canvas-clearing.spec.ts +0 -126
- package/src/canvas-color.spec.ts +0 -113
- package/src/canvas-composite.spec.ts +0 -114
- package/src/canvas-drawimage.spec.ts +0 -334
- package/src/canvas-gradient.ts +0 -36
- package/src/canvas-imagedata.spec.ts +0 -150
- package/src/canvas-path.ts +0 -131
- package/src/canvas-pattern.ts +0 -84
- package/src/canvas-rendering-context-2d.ts +0 -1208
- package/src/canvas-state.spec.ts +0 -245
- package/src/canvas-state.ts +0 -77
- package/src/canvas-text.spec.ts +0 -241
- package/src/canvas-transform.spec.ts +0 -211
- package/src/color.ts +0 -177
- package/src/dom-types.ts +0 -96
- package/src/image-data.ts +0 -34
- package/src/index.ts +0 -14
- package/src/test.browser.mts +0 -614
- package/src/test.mts +0 -22
- package/tmp/.tsbuildinfo +0 -1
- package/tsconfig.json +0 -47
package/src/canvas-path.ts
DELETED
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
// Path2D implementation for Canvas 2D context
|
|
2
|
-
// Reference: https://developer.mozilla.org/en-US/docs/Web/API/Path2D
|
|
3
|
-
// Records path operations and replays them on a Cairo context.
|
|
4
|
-
|
|
5
|
-
import { quadraticToCubic, cairoRoundRect } from './cairo-utils.js';
|
|
6
|
-
|
|
7
|
-
/** A recorded path operation. */
|
|
8
|
-
type PathOp =
|
|
9
|
-
| { type: 'moveTo'; x: number; y: number }
|
|
10
|
-
| { type: 'lineTo'; x: number; y: number }
|
|
11
|
-
| { type: 'closePath' }
|
|
12
|
-
| { type: 'bezierCurveTo'; cp1x: number; cp1y: number; cp2x: number; cp2y: number; x: number; y: number }
|
|
13
|
-
| { type: 'quadraticCurveTo'; cpx: number; cpy: number; x: number; y: number }
|
|
14
|
-
| { type: 'arc'; x: number; y: number; radius: number; startAngle: number; endAngle: number; ccw: boolean }
|
|
15
|
-
| { type: 'ellipse'; x: number; y: number; rx: number; ry: number; rotation: number; startAngle: number; endAngle: number; ccw: boolean }
|
|
16
|
-
| { type: 'rect'; x: number; y: number; w: number; h: number }
|
|
17
|
-
| { type: 'roundRect'; x: number; y: number; w: number; h: number; radii: number | number[] };
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Path2D records path operations for later replay on a CanvasRenderingContext2D.
|
|
21
|
-
*/
|
|
22
|
-
export class Path2D {
|
|
23
|
-
/** @internal Recorded operations */
|
|
24
|
-
_ops: PathOp[] = [];
|
|
25
|
-
|
|
26
|
-
constructor(pathOrSvg?: Path2D | string) {
|
|
27
|
-
if (pathOrSvg instanceof Path2D) {
|
|
28
|
-
this._ops = [...pathOrSvg._ops];
|
|
29
|
-
}
|
|
30
|
-
// SVG path string parsing is not implemented (complex, rarely needed)
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
addPath(path: Path2D): void {
|
|
34
|
-
this._ops.push(...path._ops);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
moveTo(x: number, y: number): void {
|
|
38
|
-
this._ops.push({ type: 'moveTo', x, y });
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
lineTo(x: number, y: number): void {
|
|
42
|
-
this._ops.push({ type: 'lineTo', x, y });
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
closePath(): void {
|
|
46
|
-
this._ops.push({ type: 'closePath' });
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): void {
|
|
50
|
-
this._ops.push({ type: 'bezierCurveTo', cp1x, cp1y, cp2x, cp2y, x, y });
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void {
|
|
54
|
-
this._ops.push({ type: 'quadraticCurveTo', cpx, cpy, x, y });
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise = false): void {
|
|
58
|
-
this._ops.push({ type: 'arc', x, y, radius, startAngle, endAngle, ccw: counterclockwise });
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
ellipse(x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, counterclockwise = false): void {
|
|
62
|
-
if (radiusX < 0 || radiusY < 0) throw new RangeError('The radii provided are negative');
|
|
63
|
-
this._ops.push({ type: 'ellipse', x, y, rx: radiusX, ry: radiusY, rotation, startAngle, endAngle, ccw: counterclockwise });
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
rect(x: number, y: number, w: number, h: number): void {
|
|
67
|
-
this._ops.push({ type: 'rect', x, y, w, h });
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
roundRect(x: number, y: number, w: number, h: number, radii: number | number[] = 0): void {
|
|
71
|
-
this._ops.push({ type: 'roundRect', x, y, w, h, radii });
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* @internal Replay all recorded path operations onto a Cairo context.
|
|
76
|
-
*/
|
|
77
|
-
_replayOnCairo(ctx: import('cairo').default.Context): void {
|
|
78
|
-
let lastX = 0, lastY = 0;
|
|
79
|
-
|
|
80
|
-
for (const op of this._ops) {
|
|
81
|
-
switch (op.type) {
|
|
82
|
-
case 'moveTo':
|
|
83
|
-
ctx.moveTo(op.x, op.y);
|
|
84
|
-
lastX = op.x; lastY = op.y;
|
|
85
|
-
break;
|
|
86
|
-
case 'lineTo':
|
|
87
|
-
ctx.lineTo(op.x, op.y);
|
|
88
|
-
lastX = op.x; lastY = op.y;
|
|
89
|
-
break;
|
|
90
|
-
case 'closePath':
|
|
91
|
-
ctx.closePath();
|
|
92
|
-
break;
|
|
93
|
-
case 'bezierCurveTo':
|
|
94
|
-
ctx.curveTo(op.cp1x, op.cp1y, op.cp2x, op.cp2y, op.x, op.y);
|
|
95
|
-
lastX = op.x; lastY = op.y;
|
|
96
|
-
break;
|
|
97
|
-
case 'quadraticCurveTo': {
|
|
98
|
-
const { cp1x, cp1y, cp2x, cp2y } = quadraticToCubic(lastX, lastY, op.cpx, op.cpy, op.x, op.y);
|
|
99
|
-
ctx.curveTo(cp1x, cp1y, cp2x, cp2y, op.x, op.y);
|
|
100
|
-
lastX = op.x; lastY = op.y;
|
|
101
|
-
break;
|
|
102
|
-
}
|
|
103
|
-
case 'arc':
|
|
104
|
-
if (op.ccw) {
|
|
105
|
-
ctx.arcNegative(op.x, op.y, op.radius, op.startAngle, op.endAngle);
|
|
106
|
-
} else {
|
|
107
|
-
ctx.arc(op.x, op.y, op.radius, op.startAngle, op.endAngle);
|
|
108
|
-
}
|
|
109
|
-
break;
|
|
110
|
-
case 'ellipse':
|
|
111
|
-
ctx.save();
|
|
112
|
-
ctx.translate(op.x, op.y);
|
|
113
|
-
ctx.rotate(op.rotation);
|
|
114
|
-
ctx.scale(op.rx, op.ry);
|
|
115
|
-
if (op.ccw) {
|
|
116
|
-
ctx.arcNegative(0, 0, 1, op.startAngle, op.endAngle);
|
|
117
|
-
} else {
|
|
118
|
-
ctx.arc(0, 0, 1, op.startAngle, op.endAngle);
|
|
119
|
-
}
|
|
120
|
-
ctx.restore();
|
|
121
|
-
break;
|
|
122
|
-
case 'rect':
|
|
123
|
-
ctx.rectangle(op.x, op.y, op.w, op.h);
|
|
124
|
-
break;
|
|
125
|
-
case 'roundRect':
|
|
126
|
-
cairoRoundRect(ctx, op.x, op.y, op.w, op.h, op.radii);
|
|
127
|
-
break;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
package/src/canvas-pattern.ts
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
// CanvasPattern implementation backed by Cairo SurfacePattern
|
|
2
|
-
// Reference: https://developer.mozilla.org/en-US/docs/Web/API/CanvasPattern
|
|
3
|
-
|
|
4
|
-
import Cairo from 'cairo';
|
|
5
|
-
import Gdk from 'gi://Gdk?version=4.0';
|
|
6
|
-
|
|
7
|
-
import { asCairoPattern, type CairoPattern } from './cairo-types.js';
|
|
8
|
-
import { isPixbufImageSource, isCanvasImageSource } from './dom-types.js';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* CanvasPattern wrapping a Cairo SurfacePattern.
|
|
12
|
-
*/
|
|
13
|
-
export class CanvasPattern {
|
|
14
|
-
private _pattern: CairoPattern;
|
|
15
|
-
|
|
16
|
-
private constructor(surface: Cairo.ImageSurface, repetition: string | null) {
|
|
17
|
-
const raw = new Cairo.SurfacePattern(surface);
|
|
18
|
-
// setExtend is missing from the GIR types; asCairoPattern narrows.
|
|
19
|
-
const pat = asCairoPattern(raw);
|
|
20
|
-
if (!pat) {
|
|
21
|
-
throw new TypeError(
|
|
22
|
-
'CanvasPattern: cairo SurfacePattern is missing setExtend at runtime — incompatible Cairo binding',
|
|
23
|
-
);
|
|
24
|
-
}
|
|
25
|
-
this._pattern = pat;
|
|
26
|
-
|
|
27
|
-
// Set extend mode based on repetition
|
|
28
|
-
switch (repetition) {
|
|
29
|
-
case 'repeat':
|
|
30
|
-
case '':
|
|
31
|
-
case null:
|
|
32
|
-
pat.setExtend(Cairo.Extend.REPEAT);
|
|
33
|
-
break;
|
|
34
|
-
case 'repeat-x':
|
|
35
|
-
case 'repeat-y':
|
|
36
|
-
// Cairo doesn't have separate x/y repeat — use REPEAT as approximation
|
|
37
|
-
pat.setExtend(Cairo.Extend.REPEAT);
|
|
38
|
-
break;
|
|
39
|
-
case 'no-repeat':
|
|
40
|
-
pat.setExtend(Cairo.Extend.NONE);
|
|
41
|
-
break;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/** Create a CanvasPattern from a supported image source. Returns null if unsupported. */
|
|
46
|
-
static create(image: unknown, repetition: string | null): CanvasPattern | null {
|
|
47
|
-
// HTMLImageElement (GdkPixbuf-backed)
|
|
48
|
-
if (isPixbufImageSource(image)) {
|
|
49
|
-
const pixbuf = image._pixbuf;
|
|
50
|
-
// Create a Cairo surface from the pixbuf
|
|
51
|
-
const w = pixbuf.get_width();
|
|
52
|
-
const h = pixbuf.get_height();
|
|
53
|
-
const surface = new Cairo.ImageSurface(Cairo.Format.ARGB32, w, h);
|
|
54
|
-
const ctx = new Cairo.Context(surface);
|
|
55
|
-
Gdk.cairo_set_source_pixbuf(ctx, pixbuf, 0, 0);
|
|
56
|
-
ctx.paint();
|
|
57
|
-
ctx.$dispose();
|
|
58
|
-
return new CanvasPattern(surface, repetition);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// HTMLCanvasElement with a 2D context
|
|
62
|
-
if (isCanvasImageSource(image)) {
|
|
63
|
-
const ctx2d = image.getContext('2d');
|
|
64
|
-
if (ctx2d && typeof ctx2d._getSurface === 'function') {
|
|
65
|
-
const sourceSurface = ctx2d._getSurface();
|
|
66
|
-
const w = sourceSurface.getWidth();
|
|
67
|
-
const h = sourceSurface.getHeight();
|
|
68
|
-
const surface = new Cairo.ImageSurface(Cairo.Format.ARGB32, w, h);
|
|
69
|
-
const ctx = new Cairo.Context(surface);
|
|
70
|
-
ctx.setSourceSurface(sourceSurface, 0, 0);
|
|
71
|
-
ctx.paint();
|
|
72
|
-
ctx.$dispose();
|
|
73
|
-
return new CanvasPattern(surface, repetition);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return null;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/** @internal Get the underlying Cairo pattern for rendering. */
|
|
81
|
-
_getCairoPattern(): Cairo.SurfacePattern {
|
|
82
|
-
return this._pattern as unknown as Cairo.SurfacePattern;
|
|
83
|
-
}
|
|
84
|
-
}
|