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