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