deno.land / x / skia_canvas@0.5.8 / src / svgcanvas.ts

نووسراو ببینە
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import { CanvasRenderingContext2D } from "./context2d.ts";import ffi, { cstr, getBuffer } from "./ffi.ts";
const { sk_svg_destroy, sk_svg_get_buffer, sk_svg_new, sk_svg_get_context, sk_svg_write_file, sk_data_free, sk_svg_delete_canvas,} = ffi;
const SVG_FINALIZER = new FinalizationRegistry((ptr: Deno.PointerValue) => { sk_svg_destroy(ptr);});
const SK_DATA_FINALIZER = new FinalizationRegistry( (ptr: Deno.PointerValue) => { sk_data_free(ptr); },);
const OUT_SIZE = new Uint32Array(1);const OUT_SIZE_PTR = new Uint8Array(OUT_SIZE.buffer);const OUT_DATA = new BigUint64Array(1);const OUT_DATA_PTR = new Uint8Array(OUT_DATA.buffer);
export class SvgRenderingContext2D extends CanvasRenderingContext2D { // @ts-expect-error typescript warning declare readonly canvas: SvgCanvas;
constructor(canvas: SvgCanvas, ptr: Deno.PointerValue) { // deno-lint-ignore no-explicit-any super(canvas as any, ptr); }}
export interface SvgCanvasOptions { convertTextsToPaths?: boolean; noPrettyXml?: boolean; relativePathEncoding?: boolean;}
const _ptr = Symbol("[[ptr]]");
/** * A canvas that can be used to render SVG. * * Make sure to call `complete()` when you are done drawing. * Only call `save()` or `encode()` after calling `complete()`, once. */export class SvgCanvas { [_ptr]: Deno.PointerValue;
constructor( public readonly width: number, public readonly height: number, options: SvgCanvasOptions = {}, ) { this[_ptr] = sk_svg_new( width, height, 0 | (options.convertTextsToPaths ? 1 : 0) | (options.noPrettyXml ? 2 : 0) | (options.relativePathEncoding ? 4 : 0), ); if (this[_ptr] === null) { throw new Error("Failed to create SVG Canvas"); } SVG_FINALIZER.register(this, this[_ptr]); }
/** Obtain 2D context for drawing on SVG */ getContext(): SvgRenderingContext2D { const ptr = sk_svg_get_context(this[_ptr]); if (ptr === null) { throw new Error("Failed to get SVG context"); } return new SvgRenderingContext2D(this, ptr); }
/** Save SVG on file system */ save(path: string) { if (!sk_svg_write_file(this[_ptr], cstr(path))) { throw new Error("Failed to save SVG"); } }
/** Encode and return buffer containing SVG data */ encode(): Uint8Array { const skdata = sk_svg_get_buffer(this[_ptr], OUT_DATA_PTR, OUT_SIZE_PTR); if (!skdata) { throw new Error("Failed to encode SVG"); } const size = OUT_SIZE[0]; const ptr = OUT_DATA[0]; const buffer = new Uint8Array( getBuffer(Deno.UnsafePointer.create(ptr), 0, size), ); SK_DATA_FINALIZER.register(buffer, skdata); return buffer; }
/** Convert to SVG string */ toString(): string { const skdata = sk_svg_get_buffer(this[_ptr], OUT_DATA_PTR, OUT_SIZE_PTR); if (!skdata) { throw new Error("Failed to encode SVG"); } const size = OUT_SIZE[0]; const ptr = OUT_DATA[0]; const buffer = new Uint8Array( getBuffer(Deno.UnsafePointer.create(ptr), 0, size), ); const text = new TextDecoder().decode(buffer); sk_data_free(skdata); Object.defineProperty(text, Symbol.for("Jupyter.display"), { value: function (this: string) { return { "image/svg+xml": this, }; }, }); return text; }
/** * In order to complete the SVG, you must call this method. * Call it only once before saving or encoding. */ complete() { sk_svg_delete_canvas(this[_ptr]); }}
skia_canvas

Version Info

Tagged at
8 months ago