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