kei-lisp-plugin-graphics 1.0.0

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/dist/index.cjs ADDED
@@ -0,0 +1,1088 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let kei_lisp = require("kei-lisp");
3
+ //#region src/GraphicsPlugin/index.ts
4
+ /**
5
+ * @class
6
+ * @classdesc Canvas2D drawing plugin for the kei-lisp interpreter. Implements
7
+ * the `KeiLispPlugin` contract (`name` / `has` / `apply`) and
8
+ * exposes 43 `g…` Lisp functions that proxy to a 2D rendering
9
+ * context.
10
+ * @author Keisuke Ikeda
11
+ * @this {GraphicsPlugin}
12
+ */
13
+ var GraphicsPlugin = class GraphicsPlugin extends Object {
14
+ /**
15
+ * Dispatch map from a Lisp function name (InterpretedSymbol) to the name of
16
+ * the GraphicsPlugin method that implements it.
17
+ */
18
+ static buildInFunctions = GraphicsPlugin.setup();
19
+ /**
20
+ * Plugin identifier, used for diagnostics.
21
+ */
22
+ name = "graphics";
23
+ canvas;
24
+ ctx;
25
+ isOpen;
26
+ /**
27
+ * Constructor.
28
+ * @constructor
29
+ * @param canvas - the canvas to draw to
30
+ */
31
+ constructor(canvas) {
32
+ super();
33
+ this.canvas = canvas;
34
+ this.ctx = canvas.getContext("2d");
35
+ this.isOpen = false;
36
+ }
37
+ /**
38
+ * Returns true if this plugin handles the given symbol.
39
+ * @param aSymbol - the call symbol
40
+ * @return true if `apply` should be called
41
+ */
42
+ has(aSymbol) {
43
+ return GraphicsPlugin.buildInFunctions.has(aSymbol);
44
+ }
45
+ /**
46
+ * Dispatches the given symbol to the matching `g…` method.
47
+ * @param aSymbol - the call symbol
48
+ * @param args - the evaluated argument list
49
+ * @param _ctx - the interpreter context (unused by this plugin)
50
+ * @return the method's result, or `Cons.nil` if dispatch fails
51
+ */
52
+ apply(aSymbol, args, _ctx) {
53
+ return this.selectProcedure(aSymbol, args);
54
+ }
55
+ /**
56
+ * Resolves the procedure name and invokes the matching method.
57
+ * @param procedure - the Lisp symbol
58
+ * @param args - the evaluated argument list
59
+ * @return the method's result, or `Cons.nil` if not registered
60
+ */
61
+ selectProcedure(procedure, args) {
62
+ if (GraphicsPlugin.buildInFunctions.has(procedure)) return this.buildInFunction(procedure, args);
63
+ this._print(`I could find no procedure description for ${String(procedure)}`);
64
+ return kei_lisp.Cons.nil;
65
+ }
66
+ /**
67
+ * Looks up and invokes the JS method that implements the given Lisp symbol.
68
+ * Throws `TypeError` when the dispatch table points to a method that does
69
+ * not exist on the instance — this matches the legacy behavior, where the
70
+ * Ramda `R.invoker(1, methodName)(args, this)` call would surface the same
71
+ * error by attempting to call `undefined`.
72
+ * @param procedure - the Lisp symbol
73
+ * @param args - the evaluated argument list
74
+ * @return the method's result
75
+ */
76
+ buildInFunction(procedure, args) {
77
+ const methodName = GraphicsPlugin.buildInFunctions.get(procedure);
78
+ const method = this[methodName];
79
+ if (typeof method !== "function") throw new TypeError(`${this.constructor.name} does not have a method named "${methodName}"`);
80
+ return method.call(this, args);
81
+ }
82
+ /**
83
+ * Checks whether the canvas exposes a usable 2D context, and narrows
84
+ * `this.ctx` to non-null for the caller when it returns true.
85
+ * @return type predicate — true when ctx is non-null
86
+ */
87
+ checkSupport() {
88
+ if (this.ctx === null) {
89
+ this._print("Unable to initialize canvas. The browser or machine may not support it.");
90
+ return false;
91
+ }
92
+ return true;
93
+ }
94
+ /**
95
+ * Writes a diagnostic line directly to `process.stderr`, matching the
96
+ * convention used by kei-lisp itself (`Applier.format` writes to
97
+ * `process.stdout`). In a Node runtime this hits the real stderr; in a
98
+ * browser kei-lisp host (e.g. kei-lisp-web) the host typically swaps
99
+ * `process.stderr.write` for a sink that routes to the REPL output panel,
100
+ * so the same call reaches the user via the host's normal output channel.
101
+ * @param line - the line to write
102
+ */
103
+ _print(line) {
104
+ process.stderr.write(line + "\n");
105
+ }
106
+ gAlpha(args) {
107
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
108
+ if (this.isOpen) try {
109
+ if (args.length() === 1 && kei_lisp.Cons.isNumber(args.car)) {
110
+ const aNumber = args.car <= 0 ? 0 : args.car >= 1 ? 1 : args.car;
111
+ this.ctx.globalAlpha = aNumber;
112
+ this.ctx.save();
113
+ return kei_lisp.InterpretedSymbol.of("t");
114
+ }
115
+ this._print("Can not set alpha.");
116
+ return kei_lisp.Cons.nil;
117
+ } catch {
118
+ this._print("Can not set alpha.");
119
+ return kei_lisp.Cons.nil;
120
+ }
121
+ this._print("The canvas is closed and cannot be executed.");
122
+ return kei_lisp.Cons.nil;
123
+ }
124
+ gArc(args) {
125
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
126
+ if (this.isOpen) try {
127
+ if (args.length() === 6) {
128
+ const a0 = args.car;
129
+ const cdr1 = args.cdr;
130
+ const a1 = cdr1.car;
131
+ const cdr2 = cdr1.cdr;
132
+ const a2 = cdr2.car;
133
+ const cdr3 = cdr2.cdr;
134
+ const a3 = cdr3.car;
135
+ const cdr4 = cdr3.cdr;
136
+ const a4 = cdr4.car;
137
+ const a5 = cdr4.cdr.car;
138
+ if (kei_lisp.Cons.isNumber(a0) && kei_lisp.Cons.isNumber(a1) && kei_lisp.Cons.isNumber(a2) && kei_lisp.Cons.isNumber(a3) && kei_lisp.Cons.isNumber(a4) && kei_lisp.Cons.isNumber(a5)) {
139
+ const aFlag = a5 >= 0;
140
+ this.ctx.arc(a0, a1, a2, Math.PI / 180 * a3, Math.PI / 180 * a4, aFlag);
141
+ this.ctx.save();
142
+ return kei_lisp.InterpretedSymbol.of("t");
143
+ }
144
+ }
145
+ this._print("Can not draw arc.");
146
+ return kei_lisp.Cons.nil;
147
+ } catch {
148
+ this._print("Can not draw arc.");
149
+ return kei_lisp.Cons.nil;
150
+ }
151
+ this._print("The canvas is closed and cannot be executed.");
152
+ return kei_lisp.Cons.nil;
153
+ }
154
+ gArcTo(args) {
155
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
156
+ if (this.isOpen) try {
157
+ if (args.length() === 5) {
158
+ const a0 = args.car;
159
+ const cdr1 = args.cdr;
160
+ const a1 = cdr1.car;
161
+ const cdr2 = cdr1.cdr;
162
+ const a2 = cdr2.car;
163
+ const cdr3 = cdr2.cdr;
164
+ const a3 = cdr3.car;
165
+ const a4 = cdr3.cdr.car;
166
+ if (kei_lisp.Cons.isNumber(a0) && kei_lisp.Cons.isNumber(a1) && kei_lisp.Cons.isNumber(a2) && kei_lisp.Cons.isNumber(a3) && kei_lisp.Cons.isNumber(a4)) {
167
+ this.ctx.arcTo(a0, a1, a2, a3, a4);
168
+ this.ctx.save();
169
+ return kei_lisp.InterpretedSymbol.of("t");
170
+ }
171
+ }
172
+ this._print("Can not draw arc to.");
173
+ return kei_lisp.Cons.nil;
174
+ } catch {
175
+ this._print("Can not draw arc to.");
176
+ return kei_lisp.Cons.nil;
177
+ }
178
+ this._print("The canvas is closed and cannot be executed.");
179
+ return kei_lisp.Cons.nil;
180
+ }
181
+ gBezCurveTo(args) {
182
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
183
+ if (this.isOpen) try {
184
+ if (args.length() === 6) {
185
+ const a0 = args.car;
186
+ const cdr1 = args.cdr;
187
+ const a1 = cdr1.car;
188
+ const cdr2 = cdr1.cdr;
189
+ const a2 = cdr2.car;
190
+ const cdr3 = cdr2.cdr;
191
+ const a3 = cdr3.car;
192
+ const cdr4 = cdr3.cdr;
193
+ const a4 = cdr4.car;
194
+ const a5 = cdr4.cdr.car;
195
+ if (kei_lisp.Cons.isNumber(a0) && kei_lisp.Cons.isNumber(a1) && kei_lisp.Cons.isNumber(a2) && kei_lisp.Cons.isNumber(a3) && kei_lisp.Cons.isNumber(a4) && kei_lisp.Cons.isNumber(a5)) {
196
+ this.ctx.bezierCurveTo(a0, a1, a2, a3, a4, a5);
197
+ this.ctx.save();
198
+ return kei_lisp.InterpretedSymbol.of("t");
199
+ }
200
+ }
201
+ this._print("Can not draw bezier curve.");
202
+ return kei_lisp.Cons.nil;
203
+ } catch {
204
+ this._print("Can not draw bezier curve.");
205
+ return kei_lisp.Cons.nil;
206
+ }
207
+ this._print("The canvas is closed and cannot be executed.");
208
+ return kei_lisp.Cons.nil;
209
+ }
210
+ gClear() {
211
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
212
+ if (this.isOpen) try {
213
+ this.ctx.fillStyle = "#ffffff";
214
+ this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
215
+ this.ctx.fillStyle = "#000000";
216
+ this.ctx.save();
217
+ return kei_lisp.InterpretedSymbol.of("t");
218
+ } catch {
219
+ this._print("Can not clear.");
220
+ return kei_lisp.Cons.nil;
221
+ }
222
+ this._print("The canvas is closed and cannot be executed.");
223
+ return kei_lisp.Cons.nil;
224
+ }
225
+ gClose() {
226
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
227
+ if (this.isOpen) try {
228
+ this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
229
+ this.isOpen = false;
230
+ return kei_lisp.InterpretedSymbol.of("t");
231
+ } catch {
232
+ this._print("Can not close.");
233
+ return kei_lisp.Cons.nil;
234
+ }
235
+ this._print("The canvas has already been closed.");
236
+ return kei_lisp.Cons.nil;
237
+ }
238
+ gColor(args) {
239
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
240
+ if (this.isOpen) try {
241
+ if (args.length() >= 1) {
242
+ const aColor = this.selectColor(args);
243
+ this.ctx.fillStyle = aColor;
244
+ this.ctx.strokeStyle = aColor;
245
+ this.ctx.save();
246
+ return kei_lisp.InterpretedSymbol.of("t");
247
+ }
248
+ this._print("Can not set color.");
249
+ return kei_lisp.Cons.nil;
250
+ } catch {
251
+ this._print("Can not set color.");
252
+ return kei_lisp.Cons.nil;
253
+ }
254
+ this._print("The canvas is closed and cannot be executed.");
255
+ return kei_lisp.Cons.nil;
256
+ }
257
+ gFill() {
258
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
259
+ if (this.isOpen) try {
260
+ this.ctx.fill();
261
+ this.ctx.save();
262
+ return kei_lisp.InterpretedSymbol.of("t");
263
+ } catch {
264
+ this._print("Can not fill.");
265
+ return kei_lisp.Cons.nil;
266
+ }
267
+ this._print("The canvas is closed and cannot be executed.");
268
+ return kei_lisp.Cons.nil;
269
+ }
270
+ gFillColor(args) {
271
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
272
+ if (this.isOpen) try {
273
+ if (args.length() >= 1) {
274
+ const aColor = this.selectColor(args);
275
+ this.ctx.fillStyle = aColor;
276
+ this.ctx.save();
277
+ return kei_lisp.InterpretedSymbol.of("t");
278
+ }
279
+ this._print("Can not set fill color.");
280
+ return kei_lisp.Cons.nil;
281
+ } catch {
282
+ this._print("Can not set fill color.");
283
+ return kei_lisp.Cons.nil;
284
+ }
285
+ this._print("The canvas is closed and cannot be executed.");
286
+ return kei_lisp.Cons.nil;
287
+ }
288
+ gFillRect(args) {
289
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
290
+ if (this.isOpen) try {
291
+ if (args.length() === 4) {
292
+ const a0 = args.car;
293
+ const cdr1 = args.cdr;
294
+ const a1 = cdr1.car;
295
+ const cdr2 = cdr1.cdr;
296
+ const a2 = cdr2.car;
297
+ const a3 = cdr2.cdr.car;
298
+ if (kei_lisp.Cons.isNumber(a0) && kei_lisp.Cons.isNumber(a1) && kei_lisp.Cons.isNumber(a2) && kei_lisp.Cons.isNumber(a3)) {
299
+ this.ctx.fillRect(a0, a1, a2, a3);
300
+ this.ctx.save();
301
+ return kei_lisp.InterpretedSymbol.of("t");
302
+ }
303
+ }
304
+ this._print("Can not draw fill rectangle.");
305
+ return kei_lisp.Cons.nil;
306
+ } catch {
307
+ this._print("Can not draw fill rectangle.");
308
+ return kei_lisp.Cons.nil;
309
+ }
310
+ this._print("The canvas is closed and cannot be executed.");
311
+ return kei_lisp.Cons.nil;
312
+ }
313
+ gFillText(args) {
314
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
315
+ if (this.isOpen) try {
316
+ if (args.length() === 3) {
317
+ const a0 = args.car;
318
+ const cdr1 = args.cdr;
319
+ const a1 = cdr1.car;
320
+ const a2 = cdr1.cdr.car;
321
+ if (kei_lisp.Cons.isString(a0) && kei_lisp.Cons.isNumber(a1) && kei_lisp.Cons.isNumber(a2)) {
322
+ this.ctx.fillText(a0, a1, a2);
323
+ this.ctx.save();
324
+ return kei_lisp.InterpretedSymbol.of("t");
325
+ }
326
+ }
327
+ this._print("Can not draw fill text.");
328
+ return kei_lisp.Cons.nil;
329
+ } catch {
330
+ this._print("Can not draw fill text.");
331
+ return kei_lisp.Cons.nil;
332
+ }
333
+ this._print("The canvas is closed and cannot be executed.");
334
+ return kei_lisp.Cons.nil;
335
+ }
336
+ gFillTri(args) {
337
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
338
+ if (this.isOpen) try {
339
+ if (args.length() === 6) {
340
+ const a0 = args.car;
341
+ const cdr1 = args.cdr;
342
+ const a1 = cdr1.car;
343
+ const cdr2 = cdr1.cdr;
344
+ const a2 = cdr2.car;
345
+ const cdr3 = cdr2.cdr;
346
+ const a3 = cdr3.car;
347
+ const cdr4 = cdr3.cdr;
348
+ const a4 = cdr4.car;
349
+ const a5 = cdr4.cdr.car;
350
+ if (kei_lisp.Cons.isNumber(a0) && kei_lisp.Cons.isNumber(a1) && kei_lisp.Cons.isNumber(a2) && kei_lisp.Cons.isNumber(a3) && kei_lisp.Cons.isNumber(a4) && kei_lisp.Cons.isNumber(a5)) {
351
+ this.ctx.beginPath();
352
+ this.ctx.moveTo(a0, a1);
353
+ this.ctx.lineTo(a2, a3);
354
+ this.ctx.lineTo(a4, a5);
355
+ this.ctx.fill();
356
+ this.ctx.save();
357
+ return kei_lisp.InterpretedSymbol.of("t");
358
+ }
359
+ }
360
+ this._print("Can not draw fill triangle.");
361
+ return kei_lisp.Cons.nil;
362
+ } catch {
363
+ this._print("Can not draw fill triangle.");
364
+ return kei_lisp.Cons.nil;
365
+ }
366
+ this._print("The canvas is closed and cannot be executed.");
367
+ return kei_lisp.Cons.nil;
368
+ }
369
+ gFinishPath() {
370
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
371
+ if (this.isOpen) try {
372
+ this.ctx.closePath();
373
+ this.ctx.save();
374
+ return kei_lisp.InterpretedSymbol.of("t");
375
+ } catch {
376
+ this._print("Can not finish path.");
377
+ return kei_lisp.Cons.nil;
378
+ }
379
+ this._print("The canvas is closed and cannot be executed.");
380
+ return kei_lisp.Cons.nil;
381
+ }
382
+ gImage(args) {
383
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
384
+ if (this.isOpen) try {
385
+ const len = args.length();
386
+ if (len === 3) {
387
+ const a0 = args.car;
388
+ const cdr1 = args.cdr;
389
+ const a1 = cdr1.car;
390
+ const a2 = cdr1.cdr.car;
391
+ if (kei_lisp.Cons.isString(a0) && kei_lisp.Cons.isNumber(a1) && kei_lisp.Cons.isNumber(a2)) {
392
+ const ctx = this.ctx;
393
+ const anImage = new Image();
394
+ anImage.src = a0;
395
+ anImage.onload = () => {
396
+ ctx.drawImage(anImage, a1, a2);
397
+ };
398
+ ctx.save();
399
+ return kei_lisp.InterpretedSymbol.of("t");
400
+ }
401
+ } else if (len === 5) {
402
+ const a0 = args.car;
403
+ const cdr1 = args.cdr;
404
+ const a1 = cdr1.car;
405
+ const cdr2 = cdr1.cdr;
406
+ const a2 = cdr2.car;
407
+ const cdr3 = cdr2.cdr;
408
+ const a3 = cdr3.car;
409
+ const a4 = cdr3.cdr.car;
410
+ if (kei_lisp.Cons.isString(a0) && kei_lisp.Cons.isNumber(a1) && kei_lisp.Cons.isNumber(a2) && kei_lisp.Cons.isNumber(a3) && kei_lisp.Cons.isNumber(a4)) {
411
+ const ctx = this.ctx;
412
+ const anImage = new Image();
413
+ anImage.src = a0;
414
+ anImage.onload = () => {
415
+ ctx.drawImage(anImage, a1, a2, a3, a4);
416
+ };
417
+ ctx.save();
418
+ return kei_lisp.InterpretedSymbol.of("t");
419
+ }
420
+ }
421
+ this._print("Can not draw Image.");
422
+ return kei_lisp.Cons.nil;
423
+ } catch {
424
+ this._print("Can not draw Image.");
425
+ return kei_lisp.Cons.nil;
426
+ }
427
+ this._print("The canvas is closed and cannot be executed.");
428
+ return kei_lisp.Cons.nil;
429
+ }
430
+ gLineTo(args) {
431
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
432
+ if (this.isOpen) try {
433
+ if (args.length() === 2) {
434
+ const a0 = args.car;
435
+ const a1 = args.cdr.car;
436
+ if (kei_lisp.Cons.isNumber(a0) && kei_lisp.Cons.isNumber(a1)) {
437
+ this.ctx.lineTo(a0, a1);
438
+ this.ctx.save();
439
+ return kei_lisp.InterpretedSymbol.of("t");
440
+ }
441
+ }
442
+ this._print("Can not draw line to");
443
+ return kei_lisp.Cons.nil;
444
+ } catch {
445
+ this._print("Can not draw line to");
446
+ return kei_lisp.Cons.nil;
447
+ }
448
+ this._print("The canvas is closed and cannot be executed.");
449
+ return kei_lisp.Cons.nil;
450
+ }
451
+ gLineCap(args) {
452
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
453
+ if (this.isOpen) try {
454
+ if (args.length() === 1 && kei_lisp.Cons.isNumber(args.car)) {
455
+ const aString = args.car === 0 ? "butt" : args.car > 0 ? "round" : "square";
456
+ this.ctx.lineCap = aString;
457
+ this.ctx.save();
458
+ return kei_lisp.InterpretedSymbol.of("t");
459
+ }
460
+ this._print("Can not set line cap.");
461
+ return kei_lisp.Cons.nil;
462
+ } catch {
463
+ this._print("Can not set line cap.");
464
+ return kei_lisp.Cons.nil;
465
+ }
466
+ this._print("The canvas is closed and cannot be executed.");
467
+ return kei_lisp.Cons.nil;
468
+ }
469
+ gLineJoin(args) {
470
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
471
+ if (this.isOpen) try {
472
+ if (args.length() === 1 && kei_lisp.Cons.isNumber(args.car)) {
473
+ const aString = args.car === 0 ? "miter" : args.car > 0 ? "round" : "bevel";
474
+ this.ctx.lineJoin = aString;
475
+ this.ctx.save();
476
+ return kei_lisp.InterpretedSymbol.of("t");
477
+ }
478
+ this._print("Can not set line join.");
479
+ return kei_lisp.Cons.nil;
480
+ } catch {
481
+ this._print("Can not set line join.");
482
+ return kei_lisp.Cons.nil;
483
+ }
484
+ this._print("The canvas is closed and cannot be executed.");
485
+ return kei_lisp.Cons.nil;
486
+ }
487
+ gLineWidth(args) {
488
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
489
+ if (this.isOpen) try {
490
+ if (args.length() === 1 && kei_lisp.Cons.isNumber(args.car)) {
491
+ const aNumber = args.car <= 0 ? 1 : args.car;
492
+ this.ctx.lineWidth = aNumber;
493
+ this.ctx.save();
494
+ return kei_lisp.InterpretedSymbol.of("t");
495
+ }
496
+ this._print("Can not set line width.");
497
+ return kei_lisp.Cons.nil;
498
+ } catch {
499
+ this._print("Can not set line width.");
500
+ return kei_lisp.Cons.nil;
501
+ }
502
+ this._print("The canvas is closed and cannot be executed.");
503
+ return kei_lisp.Cons.nil;
504
+ }
505
+ gMoveTo(args) {
506
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
507
+ if (this.isOpen) try {
508
+ if (args.length() === 2) {
509
+ const a0 = args.car;
510
+ const a1 = args.cdr.car;
511
+ if (kei_lisp.Cons.isNumber(a0) && kei_lisp.Cons.isNumber(a1)) {
512
+ this.ctx.moveTo(a0, a1);
513
+ this.ctx.save();
514
+ return kei_lisp.InterpretedSymbol.of("t");
515
+ }
516
+ }
517
+ this._print("Can not move");
518
+ return kei_lisp.Cons.nil;
519
+ } catch {
520
+ this._print("Can not move");
521
+ return kei_lisp.Cons.nil;
522
+ }
523
+ this._print("The canvas is closed and cannot be executed.");
524
+ return kei_lisp.Cons.nil;
525
+ }
526
+ gOpen() {
527
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
528
+ if (!this.isOpen) try {
529
+ this.isOpen = true;
530
+ this.ctx.fillStyle = "#ffffff";
531
+ this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
532
+ this.ctx.fillStyle = "#000000";
533
+ this.ctx.save();
534
+ this._print("canvas size, width : 600 height : 300");
535
+ return kei_lisp.InterpretedSymbol.of("t");
536
+ } catch {
537
+ this._print("Can not open.");
538
+ return kei_lisp.Cons.nil;
539
+ }
540
+ this._print("The canvas has already been opened.");
541
+ return kei_lisp.Cons.nil;
542
+ }
543
+ gPattern(args) {
544
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
545
+ if (this.isOpen) try {
546
+ if (args.length() === 2) {
547
+ const a0 = args.car;
548
+ const a1 = args.cdr.car;
549
+ if (kei_lisp.Cons.isString(a0) && kei_lisp.Cons.isNumber(a1)) {
550
+ const aString = a1 === 0 ? "repeat" : a1 > 0 ? "repeat-x" : "repeat-y";
551
+ const ctx = this.ctx;
552
+ const anImage = new Image();
553
+ anImage.src = a0;
554
+ anImage.onload = () => {
555
+ ctx.fillStyle = ctx.createPattern(anImage, aString);
556
+ };
557
+ ctx.save();
558
+ return kei_lisp.InterpretedSymbol.of("t");
559
+ }
560
+ }
561
+ this._print("Can not set pattern.");
562
+ return kei_lisp.Cons.nil;
563
+ } catch {
564
+ this._print("Can not set pattern.");
565
+ return kei_lisp.Cons.nil;
566
+ }
567
+ this._print("The canvas is closed and cannot be executed.");
568
+ return kei_lisp.Cons.nil;
569
+ }
570
+ gQuadCurveTo(args) {
571
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
572
+ if (this.isOpen) try {
573
+ if (args.length() === 4) {
574
+ const a0 = args.car;
575
+ const cdr1 = args.cdr;
576
+ const a1 = cdr1.car;
577
+ const cdr2 = cdr1.cdr;
578
+ const a2 = cdr2.car;
579
+ const a3 = cdr2.cdr.car;
580
+ if (kei_lisp.Cons.isNumber(a0) && kei_lisp.Cons.isNumber(a1) && kei_lisp.Cons.isNumber(a2) && kei_lisp.Cons.isNumber(a3)) {
581
+ this.ctx.quadraticCurveTo(a0, a1, a2, a3);
582
+ this.ctx.save();
583
+ return kei_lisp.InterpretedSymbol.of("t");
584
+ }
585
+ }
586
+ this._print("Can not draw quadratic curve.");
587
+ return kei_lisp.Cons.nil;
588
+ } catch {
589
+ this._print("Can not draw quadratic curve.");
590
+ return kei_lisp.Cons.nil;
591
+ }
592
+ this._print("The canvas is closed and cannot be executed.");
593
+ return kei_lisp.Cons.nil;
594
+ }
595
+ gSaveJpeg() {
596
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
597
+ if (this.isOpen) try {
598
+ const anImage = new Image();
599
+ anImage.crossOrigin = "Anonymous";
600
+ anImage.src = this.canvas.toDataURL("image/jpeg");
601
+ const link = document.createElement("a");
602
+ link.href = anImage.src;
603
+ link.download = "canvas";
604
+ document.body.append(link);
605
+ link.click();
606
+ link.remove();
607
+ return kei_lisp.InterpretedSymbol.of("t");
608
+ } catch {
609
+ this._print("Can not save jpeg. If you are using an image in the canvas, you can't save jpeg.");
610
+ return kei_lisp.Cons.nil;
611
+ }
612
+ this._print("The canvas is closed and cannot be executed.");
613
+ return kei_lisp.Cons.nil;
614
+ }
615
+ gSavePng() {
616
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
617
+ if (this.isOpen) try {
618
+ const anImage = new Image();
619
+ anImage.crossOrigin = "Anonymous";
620
+ anImage.src = this.canvas.toDataURL("image/png");
621
+ const link = document.createElement("a");
622
+ link.href = anImage.src;
623
+ link.download = "canvas";
624
+ document.body.append(link);
625
+ link.click();
626
+ link.remove();
627
+ return kei_lisp.InterpretedSymbol.of("t");
628
+ } catch {
629
+ this._print("Can not save png. If you are using an image in the canvas, you can't save png.");
630
+ return kei_lisp.Cons.nil;
631
+ }
632
+ this._print("The canvas is closed and cannot be executed.");
633
+ return kei_lisp.Cons.nil;
634
+ }
635
+ gScale(args) {
636
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
637
+ if (this.isOpen) try {
638
+ if (args.length() === 2) {
639
+ const a0 = args.car;
640
+ const a1 = args.cdr.car;
641
+ if (kei_lisp.Cons.isNumber(a0) && kei_lisp.Cons.isNumber(a1)) {
642
+ this.ctx.scale(a0, a1);
643
+ this.ctx.save();
644
+ return kei_lisp.InterpretedSymbol.of("t");
645
+ }
646
+ }
647
+ this._print("Can not scale.");
648
+ return kei_lisp.Cons.nil;
649
+ } catch {
650
+ this._print("Can not scale.");
651
+ return kei_lisp.Cons.nil;
652
+ }
653
+ this._print("The canvas is closed and cannot be executed.");
654
+ return kei_lisp.Cons.nil;
655
+ }
656
+ gShadowBlur(args) {
657
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
658
+ if (this.isOpen) {
659
+ if (args.length() === 1 && kei_lisp.Cons.isNumber(args.car)) {
660
+ this.ctx.Blur = args.car;
661
+ this.ctx.save();
662
+ return kei_lisp.InterpretedSymbol.of("t");
663
+ }
664
+ this._print("Can not set shadow blur.");
665
+ return kei_lisp.Cons.nil;
666
+ }
667
+ this._print("The canvas is closed and cannot be executed.");
668
+ return kei_lisp.Cons.nil;
669
+ }
670
+ gShadowColor(args) {
671
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
672
+ if (this.isOpen) try {
673
+ if (args.length() === 1) {
674
+ const aColor = this.selectColor(args);
675
+ this.ctx.shadowColor = aColor;
676
+ this.ctx.save();
677
+ return kei_lisp.InterpretedSymbol.of("t");
678
+ }
679
+ this._print("Can not set shadow color.");
680
+ return kei_lisp.Cons.nil;
681
+ } catch {
682
+ this._print("Can not set shadow color.");
683
+ return kei_lisp.Cons.nil;
684
+ }
685
+ this._print("The canvas is closed and cannot be executed.");
686
+ return kei_lisp.Cons.nil;
687
+ }
688
+ gShadowOffsetX(args) {
689
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
690
+ if (this.isOpen) {
691
+ if (args.length() === 1 && kei_lisp.Cons.isNumber(args.car)) {
692
+ this.ctx.shadowOffsetX = args.car;
693
+ this.ctx.save();
694
+ return kei_lisp.InterpretedSymbol.of("t");
695
+ }
696
+ this._print("Can not set shadow offsetX.");
697
+ return kei_lisp.Cons.nil;
698
+ }
699
+ this._print("The canvas is closed and cannot be executed.");
700
+ return kei_lisp.Cons.nil;
701
+ }
702
+ gShadowOffsetY(args) {
703
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
704
+ if (this.isOpen) {
705
+ if (args.length() === 1 && kei_lisp.Cons.isNumber(args.car)) {
706
+ this.ctx.shadowOffsetY = args.car;
707
+ this.ctx.save();
708
+ return kei_lisp.InterpretedSymbol.of("t");
709
+ }
710
+ this._print("Can not set shadow offsetY.");
711
+ return kei_lisp.Cons.nil;
712
+ }
713
+ this._print("The canvas is closed and cannot be executed.");
714
+ return kei_lisp.Cons.nil;
715
+ }
716
+ gSleep(args) {
717
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
718
+ if (this.isOpen) {
719
+ const sleep = (ms) => {
720
+ const time = Date.now() + ms;
721
+ while (Date.now() < time);
722
+ };
723
+ if (args.length() === 1 && kei_lisp.Cons.isNumber(args.car)) {
724
+ sleep(args.car);
725
+ return kei_lisp.InterpretedSymbol.of("t");
726
+ }
727
+ this._print("Can not sleep");
728
+ return kei_lisp.Cons.nil;
729
+ }
730
+ this._print("The canvas is closed and cannot be executed.");
731
+ return kei_lisp.Cons.nil;
732
+ }
733
+ gStartPath() {
734
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
735
+ if (this.isOpen) try {
736
+ this.ctx.beginPath();
737
+ this.ctx.save();
738
+ return kei_lisp.InterpretedSymbol.of("t");
739
+ } catch {
740
+ this._print("Can not start path.");
741
+ return kei_lisp.Cons.nil;
742
+ }
743
+ this._print("The canvas is closed and cannot be executed.");
744
+ return kei_lisp.Cons.nil;
745
+ }
746
+ gStroke() {
747
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
748
+ if (this.isOpen) try {
749
+ this.ctx.stroke();
750
+ this.ctx.save();
751
+ return kei_lisp.InterpretedSymbol.of("t");
752
+ } catch {
753
+ this._print("Can not stroke.");
754
+ return kei_lisp.Cons.nil;
755
+ }
756
+ this._print("The canvas is closed and cannot be executed.");
757
+ return kei_lisp.Cons.nil;
758
+ }
759
+ gStrokeColor(args) {
760
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
761
+ if (this.isOpen) try {
762
+ if (args.length() >= 1) {
763
+ const aColor = this.selectColor(args);
764
+ this.ctx.strokeStyle = aColor;
765
+ this.ctx.save();
766
+ return kei_lisp.InterpretedSymbol.of("t");
767
+ }
768
+ this._print("Can not set stroke color");
769
+ return kei_lisp.Cons.nil;
770
+ } catch {
771
+ this._print("Can not set stroke color");
772
+ return kei_lisp.Cons.nil;
773
+ }
774
+ this._print("The canvas is closed and cannot be executed.");
775
+ return kei_lisp.Cons.nil;
776
+ }
777
+ gStrokeRect(args) {
778
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
779
+ if (this.isOpen) try {
780
+ if (args.length() === 4) {
781
+ const a0 = args.car;
782
+ const cdr1 = args.cdr;
783
+ const a1 = cdr1.car;
784
+ const cdr2 = cdr1.cdr;
785
+ const a2 = cdr2.car;
786
+ const a3 = cdr2.cdr.car;
787
+ if (kei_lisp.Cons.isNumber(a0) && kei_lisp.Cons.isNumber(a1) && kei_lisp.Cons.isNumber(a2) && kei_lisp.Cons.isNumber(a3)) {
788
+ this.ctx.strokeRect(a0, a1, a2, a3);
789
+ this.ctx.save();
790
+ return kei_lisp.InterpretedSymbol.of("t");
791
+ }
792
+ }
793
+ this._print("Can not draw stroke rectangle.");
794
+ return kei_lisp.Cons.nil;
795
+ } catch {
796
+ this._print("Can not draw stroke rectangle.");
797
+ return kei_lisp.Cons.nil;
798
+ }
799
+ this._print("The canvas is closed and cannot be executed.");
800
+ return kei_lisp.Cons.nil;
801
+ }
802
+ gStrokeText(args) {
803
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
804
+ if (this.isOpen) try {
805
+ if (args.length() === 3) {
806
+ const a0 = args.car;
807
+ const cdr1 = args.cdr;
808
+ const a1 = cdr1.car;
809
+ const a2 = cdr1.cdr.car;
810
+ if (kei_lisp.Cons.isString(a0) && kei_lisp.Cons.isNumber(a1) && kei_lisp.Cons.isNumber(a2)) {
811
+ this.ctx.strokeText(a0, a1, a2);
812
+ this.ctx.save();
813
+ return kei_lisp.InterpretedSymbol.of("t");
814
+ }
815
+ }
816
+ this._print("Can not draw fill text.");
817
+ return kei_lisp.Cons.nil;
818
+ } catch {
819
+ this._print("Can not draw fill text.");
820
+ return kei_lisp.Cons.nil;
821
+ }
822
+ this._print("The canvas is closed and cannot be executed.");
823
+ return kei_lisp.Cons.nil;
824
+ }
825
+ gStrokeTri(args) {
826
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
827
+ if (this.isOpen) try {
828
+ if (args.length() === 6) {
829
+ const a0 = args.car;
830
+ const cdr1 = args.cdr;
831
+ const a1 = cdr1.car;
832
+ const cdr2 = cdr1.cdr;
833
+ const a2 = cdr2.car;
834
+ const cdr3 = cdr2.cdr;
835
+ const a3 = cdr3.car;
836
+ const cdr4 = cdr3.cdr;
837
+ const a4 = cdr4.car;
838
+ const a5 = cdr4.cdr.car;
839
+ if (kei_lisp.Cons.isNumber(a0) && kei_lisp.Cons.isNumber(a1) && kei_lisp.Cons.isNumber(a2) && kei_lisp.Cons.isNumber(a3) && kei_lisp.Cons.isNumber(a4) && kei_lisp.Cons.isNumber(a5)) {
840
+ this.ctx.beginPath();
841
+ this.ctx.moveTo(a0, a1);
842
+ this.ctx.lineTo(a2, a3);
843
+ this.ctx.lineTo(a4, a5);
844
+ this.ctx.closePath();
845
+ this.ctx.stroke();
846
+ this.ctx.save();
847
+ return kei_lisp.InterpretedSymbol.of("t");
848
+ }
849
+ }
850
+ this._print("Can not draw stroke triangle.");
851
+ return kei_lisp.Cons.nil;
852
+ } catch {
853
+ this._print("Can not draw stroke triangle.");
854
+ return kei_lisp.Cons.nil;
855
+ }
856
+ this._print("The canvas is closed and cannot be executed.");
857
+ return kei_lisp.Cons.nil;
858
+ }
859
+ gTextAlign(args) {
860
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
861
+ if (this.isOpen) try {
862
+ if (args.length() === 1 && kei_lisp.Cons.isString(args.car)) {
863
+ this.ctx.textAlign = args.car;
864
+ this.ctx.save();
865
+ return kei_lisp.InterpretedSymbol.of("t");
866
+ }
867
+ this._print("Can not set text align.");
868
+ return kei_lisp.Cons.nil;
869
+ } catch {
870
+ this._print("Can not set text align.");
871
+ return kei_lisp.Cons.nil;
872
+ }
873
+ this._print("The canvas is closed and cannot be executed.");
874
+ return kei_lisp.Cons.nil;
875
+ }
876
+ gTextBaseline(args) {
877
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
878
+ if (this.isOpen) try {
879
+ if (args.length() === 1 && kei_lisp.Cons.isString(args.car)) {
880
+ this.ctx.textBaseline = args.car;
881
+ this.ctx.save();
882
+ return kei_lisp.InterpretedSymbol.of("t");
883
+ }
884
+ this._print("Can not set text baseline.");
885
+ return kei_lisp.Cons.nil;
886
+ } catch {
887
+ this._print("Can not set text baseline.");
888
+ return kei_lisp.Cons.nil;
889
+ }
890
+ this._print("The canvas is closed and cannot be executed.");
891
+ return kei_lisp.Cons.nil;
892
+ }
893
+ gTextDirection(args) {
894
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
895
+ if (this.isOpen) try {
896
+ if (args.length() === 1 && kei_lisp.Cons.isNumber(args.car)) {
897
+ const aString = args.car === 0 ? "inherit" : args.car > 0 ? "rtl" : "ltr";
898
+ this.ctx.direction = aString;
899
+ this.ctx.save();
900
+ return kei_lisp.InterpretedSymbol.of("t");
901
+ }
902
+ this._print("Can not set text direction.");
903
+ return kei_lisp.Cons.nil;
904
+ } catch {
905
+ this._print("Can not set text direction.");
906
+ return kei_lisp.Cons.nil;
907
+ }
908
+ this._print("The canvas is closed and cannot be executed.");
909
+ return kei_lisp.Cons.nil;
910
+ }
911
+ gTextFont(args) {
912
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
913
+ if (this.isOpen) try {
914
+ if (args.length() === 1 && kei_lisp.Cons.isString(args.car)) {
915
+ this.ctx.font = args.car;
916
+ this.ctx.save();
917
+ return kei_lisp.InterpretedSymbol.of("t");
918
+ }
919
+ this._print("Can not set text font.");
920
+ return kei_lisp.Cons.nil;
921
+ } catch {
922
+ this._print("Can not set text font.");
923
+ return kei_lisp.Cons.nil;
924
+ }
925
+ this._print("The canvas is closed and cannot be executed.");
926
+ return kei_lisp.Cons.nil;
927
+ }
928
+ gTranslate(args) {
929
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
930
+ if (this.isOpen) try {
931
+ if (args.length() === 2) {
932
+ const a0 = args.car;
933
+ const a1 = args.cdr.car;
934
+ if (kei_lisp.Cons.isNumber(a0) && kei_lisp.Cons.isNumber(a1)) {
935
+ this.ctx.translate(a0, a1);
936
+ this.ctx.save();
937
+ return kei_lisp.InterpretedSymbol.of("t");
938
+ }
939
+ }
940
+ this._print("Can not translate.");
941
+ return kei_lisp.Cons.nil;
942
+ } catch {
943
+ this._print("Can not translate.");
944
+ return kei_lisp.Cons.nil;
945
+ }
946
+ this._print("The canvas is closed and cannot be executed.");
947
+ return kei_lisp.Cons.nil;
948
+ }
949
+ gRect(args) {
950
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
951
+ if (this.isOpen) try {
952
+ if (args.length() === 4) {
953
+ const a0 = args.car;
954
+ const cdr1 = args.cdr;
955
+ const a1 = cdr1.car;
956
+ const cdr2 = cdr1.cdr;
957
+ const a2 = cdr2.car;
958
+ const a3 = cdr2.cdr.car;
959
+ if (kei_lisp.Cons.isNumber(a0) && kei_lisp.Cons.isNumber(a1) && kei_lisp.Cons.isNumber(a2) && kei_lisp.Cons.isNumber(a3)) {
960
+ this.ctx.rect(a0, a1, a2, a3);
961
+ this.ctx.save();
962
+ return kei_lisp.InterpretedSymbol.of("t");
963
+ }
964
+ }
965
+ this._print("Can not draw rectangle.");
966
+ return kei_lisp.Cons.nil;
967
+ } catch {
968
+ this._print("Can not draw rectangle.");
969
+ return kei_lisp.Cons.nil;
970
+ }
971
+ this._print("The canvas is closed and cannot be executed.");
972
+ return kei_lisp.Cons.nil;
973
+ }
974
+ gRotate(args) {
975
+ if (!this.checkSupport()) return kei_lisp.Cons.nil;
976
+ if (this.isOpen) try {
977
+ if (args.length() === 1 && kei_lisp.Cons.isNumber(args.car)) {
978
+ this.ctx.rotate(Math.PI / 180 * args.car);
979
+ this.ctx.save();
980
+ return kei_lisp.InterpretedSymbol.of("t");
981
+ }
982
+ this._print("Can not rotate.");
983
+ return kei_lisp.Cons.nil;
984
+ } catch {
985
+ this._print("Can not rotate.");
986
+ return kei_lisp.Cons.nil;
987
+ }
988
+ this._print("The canvas is closed and cannot be executed.");
989
+ return kei_lisp.Cons.nil;
990
+ }
991
+ /**
992
+ * Parses a color spec from the head of the argument Cons. Accepts
993
+ * (1 string), (3 numbers — rgb), or (4 numbers — rgba); falls back to
994
+ * `'black'` on anything else (legacy behavior).
995
+ * @param args - the argument Cons to parse
996
+ * @return CSS color string
997
+ */
998
+ selectColor(args) {
999
+ let aColor = "black";
1000
+ const len = args.length();
1001
+ const a0 = args.car;
1002
+ if (len === 1 && kei_lisp.Cons.isString(a0)) aColor = a0;
1003
+ else if (len === 3) {
1004
+ const cdr1 = args.cdr;
1005
+ const a1 = cdr1.car;
1006
+ const a2 = cdr1.cdr.car;
1007
+ if (kei_lisp.Cons.isNumber(a0) && kei_lisp.Cons.isNumber(a1) && kei_lisp.Cons.isNumber(a2)) aColor = `rgb(${a0}, ${a1}, ${a2})`;
1008
+ else this._print("Can not set color. set color \"black\".");
1009
+ } else if (len === 4) {
1010
+ const cdr1 = args.cdr;
1011
+ const a1 = cdr1.car;
1012
+ const cdr2 = cdr1.cdr;
1013
+ const a2 = cdr2.car;
1014
+ const a3 = cdr2.cdr.car;
1015
+ if (kei_lisp.Cons.isNumber(a0) && kei_lisp.Cons.isNumber(a1) && kei_lisp.Cons.isNumber(a2) && kei_lisp.Cons.isNumber(a3)) aColor = `rgba(${a0}, ${a1}, ${a2}, ${a3})`;
1016
+ else this._print("Can not set color. set color \"black\".");
1017
+ } else this._print("Can not set color. set color \"black\".");
1018
+ return aColor;
1019
+ }
1020
+ /**
1021
+ * Builds the dispatch table.
1022
+ * @return the dispatch table
1023
+ */
1024
+ static setup() {
1025
+ const aTable = /* @__PURE__ */ new Map();
1026
+ aTable.set(kei_lisp.InterpretedSymbol.of("galpha"), "gAlpha");
1027
+ aTable.set(kei_lisp.InterpretedSymbol.of("garc"), "gArc");
1028
+ aTable.set(kei_lisp.InterpretedSymbol.of("garc-to"), "gArcTo");
1029
+ aTable.set(kei_lisp.InterpretedSymbol.of("gbezcurve-to"), "gBezCurveTo");
1030
+ aTable.set(kei_lisp.InterpretedSymbol.of("gclear"), "gClear");
1031
+ aTable.set(kei_lisp.InterpretedSymbol.of("gclose"), "gClose");
1032
+ aTable.set(kei_lisp.InterpretedSymbol.of("gcolor"), "gColor");
1033
+ aTable.set(kei_lisp.InterpretedSymbol.of("gfill"), "gFill");
1034
+ aTable.set(kei_lisp.InterpretedSymbol.of("gfill-color"), "gFillColor");
1035
+ aTable.set(kei_lisp.InterpretedSymbol.of("gfill-rect"), "gFillRect");
1036
+ aTable.set(kei_lisp.InterpretedSymbol.of("gfill-text"), "gFillText");
1037
+ aTable.set(kei_lisp.InterpretedSymbol.of("gfill-tri"), "gFillTri");
1038
+ aTable.set(kei_lisp.InterpretedSymbol.of("gfinish-path"), "gFinishPath");
1039
+ aTable.set(kei_lisp.InterpretedSymbol.of("gimage"), "gImage");
1040
+ aTable.set(kei_lisp.InterpretedSymbol.of("gmove-to"), "gMoveTo");
1041
+ aTable.set(kei_lisp.InterpretedSymbol.of("gline-to"), "gLineTo");
1042
+ aTable.set(kei_lisp.InterpretedSymbol.of("gline-cap"), "gLineCap");
1043
+ aTable.set(kei_lisp.InterpretedSymbol.of("gline-join"), "gLineJoin");
1044
+ aTable.set(kei_lisp.InterpretedSymbol.of("gline-width"), "gLineWidth");
1045
+ aTable.set(kei_lisp.InterpretedSymbol.of("gopen"), "gOpen");
1046
+ aTable.set(kei_lisp.InterpretedSymbol.of("gpattern"), "gPattern");
1047
+ aTable.set(kei_lisp.InterpretedSymbol.of("gquadcurve-to"), "gQuadCurveTo");
1048
+ aTable.set(kei_lisp.InterpretedSymbol.of("gsave-jpeg"), "gSaveJpeg");
1049
+ aTable.set(kei_lisp.InterpretedSymbol.of("gsave-png"), "gSavePng");
1050
+ aTable.set(kei_lisp.InterpretedSymbol.of("gscale"), "gScale");
1051
+ aTable.set(kei_lisp.InterpretedSymbol.of("gshadow-blur"), "gShadowBlur");
1052
+ aTable.set(kei_lisp.InterpretedSymbol.of("gshadow-color"), "gShadowColor");
1053
+ aTable.set(kei_lisp.InterpretedSymbol.of("gshadow-offsetx"), "gShadowOffsetX");
1054
+ aTable.set(kei_lisp.InterpretedSymbol.of("gshadow-offsety"), "gShadowOffsetY");
1055
+ aTable.set(kei_lisp.InterpretedSymbol.of("gsleep"), "gSleep");
1056
+ aTable.set(kei_lisp.InterpretedSymbol.of("gstart-path"), "gStartPath");
1057
+ aTable.set(kei_lisp.InterpretedSymbol.of("gstroke"), "gStroke");
1058
+ aTable.set(kei_lisp.InterpretedSymbol.of("gstroke-color"), "gStrokeColor");
1059
+ aTable.set(kei_lisp.InterpretedSymbol.of("gstroke-rect"), "gStrokeRect");
1060
+ aTable.set(kei_lisp.InterpretedSymbol.of("gstroke-text"), "gStrokeText");
1061
+ aTable.set(kei_lisp.InterpretedSymbol.of("gstroke-tri"), "gStrokeTri");
1062
+ aTable.set(kei_lisp.InterpretedSymbol.of("gtext-align"), "gTextAlign");
1063
+ aTable.set(kei_lisp.InterpretedSymbol.of("gtext-dire"), "gTextDirection");
1064
+ aTable.set(kei_lisp.InterpretedSymbol.of("gtext-font"), "gTextFont");
1065
+ aTable.set(kei_lisp.InterpretedSymbol.of("gtext-line"), "gTextBaseline");
1066
+ aTable.set(kei_lisp.InterpretedSymbol.of("gtranslate"), "gTranslate");
1067
+ aTable.set(kei_lisp.InterpretedSymbol.of("grect"), "gRect");
1068
+ aTable.set(kei_lisp.InterpretedSymbol.of("grotate"), "gRotate");
1069
+ return aTable;
1070
+ }
1071
+ };
1072
+ //#endregion
1073
+ //#region src/index.ts
1074
+ /**
1075
+ * Creates a Canvas2D drawing plugin bound to the given canvas. Register it on
1076
+ * a `LispInterpreter` via `interpreter.use(plugin)` to make the `g…` drawing
1077
+ * primitives callable from Lisp source.
1078
+ * @param options - the canvas to draw to
1079
+ * @return a KeiLispPlugin that handles the `g…` symbols
1080
+ */
1081
+ function createGraphicsPlugin(options) {
1082
+ return new GraphicsPlugin(options.canvas);
1083
+ }
1084
+ //#endregion
1085
+ exports.GraphicsPlugin = GraphicsPlugin;
1086
+ exports.createGraphicsPlugin = createGraphicsPlugin;
1087
+
1088
+ //# sourceMappingURL=index.cjs.map