@live-codes/ocaml 0.0.0-stage → 0.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.
Files changed (130) hide show
  1. package/LICENSE +220 -0
  2. package/README.md +165 -2
  3. package/THIRD-PARTY-NOTICES.md +52 -0
  4. package/assets/compiler/compile_stdout.browser.js +27856 -0
  5. package/assets/compiler/jsoo.js +12631 -0
  6. package/assets/compiler/package.json +3 -0
  7. package/assets/compiler/runtime/bigarray.js +1072 -0
  8. package/assets/compiler/runtime/bigstring.js +137 -0
  9. package/assets/compiler/runtime/domain.js +393 -0
  10. package/assets/compiler/runtime/dynlink.js +91 -0
  11. package/assets/compiler/runtime/float32.js +486 -0
  12. package/assets/compiler/runtime/fs.js +416 -0
  13. package/assets/compiler/runtime/fs_fake.js +600 -0
  14. package/assets/compiler/runtime/fs_node.js +609 -0
  15. package/assets/compiler/runtime/fs_quickjs.js +532 -0
  16. package/assets/compiler/runtime/gc.js +201 -0
  17. package/assets/compiler/runtime/graphics.js +1053 -0
  18. package/assets/compiler/runtime/ieee_754.js +621 -0
  19. package/assets/compiler/runtime/int64.js +516 -0
  20. package/assets/compiler/runtime/io.js +739 -0
  21. package/assets/compiler/runtime/jslib.js +553 -0
  22. package/assets/compiler/runtime/jslib_js_of_ocaml.js +81 -0
  23. package/assets/compiler/runtime/lexing.js +240 -0
  24. package/assets/compiler/runtime/manifest.txt +31 -0
  25. package/assets/compiler/runtime/marshal.js +863 -0
  26. package/assets/compiler/runtime/md5.js +236 -0
  27. package/assets/compiler/runtime/mlBytes.js +1007 -0
  28. package/assets/compiler/runtime/nat.js +469 -0
  29. package/assets/compiler/runtime/parsing.js +317 -0
  30. package/assets/compiler/runtime/prng.js +84 -0
  31. package/assets/compiler/runtime/promise.js +45 -0
  32. package/assets/compiler/runtime/runtime.js +16688 -0
  33. package/assets/compiler/runtime/runtime_events.js +90 -0
  34. package/assets/compiler/runtime/stdlib.js +363 -0
  35. package/assets/compiler/runtime/sync.js +35 -0
  36. package/assets/compiler/runtime/toplevel.js +150 -0
  37. package/assets/compiler/runtime/unix.js +914 -0
  38. package/assets/compiler/runtime/weak.js +247 -0
  39. package/assets/compiler/stdlib.js +254 -0
  40. package/assets/compiler/worker.js +46 -0
  41. package/assets/interpreter/libs/greet.cma +0 -0
  42. package/assets/interpreter/libs/greet.cmi +0 -0
  43. package/assets/interpreter/libs/manifest.txt +1 -0
  44. package/assets/interpreter/package.json +3 -0
  45. package/assets/interpreter/stdlib/camlinternalFormat.cmi +0 -0
  46. package/assets/interpreter/stdlib/camlinternalFormatBasics.cmi +0 -0
  47. package/assets/interpreter/stdlib/camlinternalLazy.cmi +0 -0
  48. package/assets/interpreter/stdlib/camlinternalMod.cmi +0 -0
  49. package/assets/interpreter/stdlib/camlinternalOO.cmi +0 -0
  50. package/assets/interpreter/stdlib/std_exit.cmi +0 -0
  51. package/assets/interpreter/stdlib/stdlib.cmi +0 -0
  52. package/assets/interpreter/stdlib/stdlib__Arg.cmi +0 -0
  53. package/assets/interpreter/stdlib/stdlib__Array.cmi +0 -0
  54. package/assets/interpreter/stdlib/stdlib__ArrayLabels.cmi +0 -0
  55. package/assets/interpreter/stdlib/stdlib__Atomic.cmi +0 -0
  56. package/assets/interpreter/stdlib/stdlib__Bigarray.cmi +0 -0
  57. package/assets/interpreter/stdlib/stdlib__Bool.cmi +0 -0
  58. package/assets/interpreter/stdlib/stdlib__Buffer.cmi +0 -0
  59. package/assets/interpreter/stdlib/stdlib__Bytes.cmi +0 -0
  60. package/assets/interpreter/stdlib/stdlib__BytesLabels.cmi +0 -0
  61. package/assets/interpreter/stdlib/stdlib__Callback.cmi +0 -0
  62. package/assets/interpreter/stdlib/stdlib__Char.cmi +0 -0
  63. package/assets/interpreter/stdlib/stdlib__Complex.cmi +0 -0
  64. package/assets/interpreter/stdlib/stdlib__Condition.cmi +0 -0
  65. package/assets/interpreter/stdlib/stdlib__Digest.cmi +0 -0
  66. package/assets/interpreter/stdlib/stdlib__Domain.cmi +0 -0
  67. package/assets/interpreter/stdlib/stdlib__Dynarray.cmi +0 -0
  68. package/assets/interpreter/stdlib/stdlib__Effect.cmi +0 -0
  69. package/assets/interpreter/stdlib/stdlib__Either.cmi +0 -0
  70. package/assets/interpreter/stdlib/stdlib__Ephemeron.cmi +0 -0
  71. package/assets/interpreter/stdlib/stdlib__Filename.cmi +0 -0
  72. package/assets/interpreter/stdlib/stdlib__Float.cmi +0 -0
  73. package/assets/interpreter/stdlib/stdlib__Format.cmi +0 -0
  74. package/assets/interpreter/stdlib/stdlib__Fun.cmi +0 -0
  75. package/assets/interpreter/stdlib/stdlib__Gc.cmi +0 -0
  76. package/assets/interpreter/stdlib/stdlib__Hashtbl.cmi +0 -0
  77. package/assets/interpreter/stdlib/stdlib__Iarray.cmi +0 -0
  78. package/assets/interpreter/stdlib/stdlib__In_channel.cmi +0 -0
  79. package/assets/interpreter/stdlib/stdlib__Int.cmi +0 -0
  80. package/assets/interpreter/stdlib/stdlib__Int32.cmi +0 -0
  81. package/assets/interpreter/stdlib/stdlib__Int64.cmi +0 -0
  82. package/assets/interpreter/stdlib/stdlib__Lazy.cmi +0 -0
  83. package/assets/interpreter/stdlib/stdlib__Lexing.cmi +0 -0
  84. package/assets/interpreter/stdlib/stdlib__List.cmi +0 -0
  85. package/assets/interpreter/stdlib/stdlib__ListLabels.cmi +0 -0
  86. package/assets/interpreter/stdlib/stdlib__Map.cmi +0 -0
  87. package/assets/interpreter/stdlib/stdlib__Marshal.cmi +0 -0
  88. package/assets/interpreter/stdlib/stdlib__MoreLabels.cmi +0 -0
  89. package/assets/interpreter/stdlib/stdlib__Mutex.cmi +0 -0
  90. package/assets/interpreter/stdlib/stdlib__Nativeint.cmi +0 -0
  91. package/assets/interpreter/stdlib/stdlib__Obj.cmi +0 -0
  92. package/assets/interpreter/stdlib/stdlib__Oo.cmi +0 -0
  93. package/assets/interpreter/stdlib/stdlib__Option.cmi +0 -0
  94. package/assets/interpreter/stdlib/stdlib__Out_channel.cmi +0 -0
  95. package/assets/interpreter/stdlib/stdlib__Pair.cmi +0 -0
  96. package/assets/interpreter/stdlib/stdlib__Parsing.cmi +0 -0
  97. package/assets/interpreter/stdlib/stdlib__Pqueue.cmi +0 -0
  98. package/assets/interpreter/stdlib/stdlib__Printexc.cmi +0 -0
  99. package/assets/interpreter/stdlib/stdlib__Printf.cmi +0 -0
  100. package/assets/interpreter/stdlib/stdlib__Queue.cmi +0 -0
  101. package/assets/interpreter/stdlib/stdlib__Random.cmi +0 -0
  102. package/assets/interpreter/stdlib/stdlib__Repr.cmi +0 -0
  103. package/assets/interpreter/stdlib/stdlib__Result.cmi +0 -0
  104. package/assets/interpreter/stdlib/stdlib__Scanf.cmi +0 -0
  105. package/assets/interpreter/stdlib/stdlib__Semaphore.cmi +0 -0
  106. package/assets/interpreter/stdlib/stdlib__Seq.cmi +0 -0
  107. package/assets/interpreter/stdlib/stdlib__Set.cmi +0 -0
  108. package/assets/interpreter/stdlib/stdlib__Stack.cmi +0 -0
  109. package/assets/interpreter/stdlib/stdlib__StdLabels.cmi +0 -0
  110. package/assets/interpreter/stdlib/stdlib__String.cmi +0 -0
  111. package/assets/interpreter/stdlib/stdlib__StringLabels.cmi +0 -0
  112. package/assets/interpreter/stdlib/stdlib__Sys.cmi +0 -0
  113. package/assets/interpreter/stdlib/stdlib__Type.cmi +0 -0
  114. package/assets/interpreter/stdlib/stdlib__Uchar.cmi +0 -0
  115. package/assets/interpreter/stdlib/stdlib__Unit.cmi +0 -0
  116. package/assets/interpreter/stdlib/stdlib__Weak.cmi +0 -0
  117. package/assets/interpreter/stdlib/topdirs.cmi +0 -0
  118. package/assets/interpreter/stdlib/units.txt +75 -0
  119. package/assets/interpreter/stdlib/unix.cmi +0 -0
  120. package/assets/interpreter/stdlib/unixLabels.cmi +0 -0
  121. package/assets/interpreter/worker-entry.js +39 -0
  122. package/assets/interpreter/worker.js +42356 -0
  123. package/bin/copy-assets.mjs +75 -0
  124. package/package.json +41 -4
  125. package/src/compiler/compile.js +170 -0
  126. package/src/compiler/index.js +46 -0
  127. package/src/compiler/worker.js +46 -0
  128. package/src/index.js +12 -0
  129. package/src/interpreter/api.js +182 -0
  130. package/src/interpreter/index.js +5 -0
@@ -0,0 +1,1053 @@
1
+ // Js_of_ocaml runtime support
2
+ // http://www.ocsigen.org/js_of_ocaml/
3
+ // Copyright (C) 2014 Hugo Heuzard
4
+
5
+ // This program is free software; you can redistribute it and/or modify
6
+ // it under the terms of the GNU Lesser General Public License as published by
7
+ // the Free Software Foundation, with linking exception;
8
+ // either version 2.1 of the License, or (at your option) any later version.
9
+
10
+ // This program is distributed in the hope that it will be useful,
11
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ // GNU Lesser General Public License for more details.
14
+
15
+ // You should have received a copy of the GNU Lesser General Public License
16
+ // along with this program; if not, write to the Free Software
17
+ // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
+
19
+ //Provides: caml_gr_state
20
+ var caml_gr_state;
21
+
22
+ //Provides: caml_gr_state_get
23
+ //Requires: caml_gr_state
24
+ //Requires: caml_named_value, caml_string_of_jsbytes
25
+ //Requires: caml_maybe_attach_backtrace
26
+ function caml_gr_state_get() {
27
+ if (caml_gr_state) {
28
+ return caml_gr_state;
29
+ }
30
+ throw caml_maybe_attach_backtrace([
31
+ 0,
32
+ caml_named_value("Graphics.Graphic_failure"),
33
+ caml_string_of_jsbytes("Not initialized"),
34
+ ]);
35
+ }
36
+ //Provides: caml_gr_state_set
37
+ //Requires: caml_gr_state,caml_gr_state_init
38
+ function caml_gr_state_set(ctx) {
39
+ caml_gr_state = ctx;
40
+ caml_gr_state_init();
41
+ return 0;
42
+ }
43
+
44
+ //Provides: caml_gr_open_graph
45
+ //Requires: caml_gr_state_create
46
+ //Requires: caml_gr_state_set
47
+ //Requires: caml_failwith
48
+ //Requires: caml_jsstring_of_string
49
+ function caml_gr_open_graph(info) {
50
+ var info = caml_jsstring_of_string(info);
51
+ function get(name) {
52
+ var res = info.match("(^|,) *" + name + " *= *([a-zA-Z0-9_]+) *(,|$)");
53
+ if (res) return res[2];
54
+ }
55
+ var specs = [];
56
+ if (!(info === "")) specs.push(info);
57
+ var target = get("target");
58
+ if (!target) target = "";
59
+ var status = get("status");
60
+ if (!status) specs.push("status=1");
61
+
62
+ var w = get("width");
63
+ w = w ? Number.parseInt(w) : 200;
64
+ specs.push("width=" + w);
65
+
66
+ var h = get("height");
67
+ h = h ? Number.parseInt(h) : 200;
68
+ specs.push("height=" + h);
69
+
70
+ var win = globalThis.open("about:blank", target, specs.join(","));
71
+ if (!win) {
72
+ caml_failwith("Graphics.open_graph: cannot open the window");
73
+ }
74
+ var doc = win.document;
75
+ var canvas = doc.createElement("canvas");
76
+ canvas.width = w;
77
+ canvas.height = h;
78
+ var ctx = caml_gr_state_create(canvas, w, h);
79
+ ctx.set_title = function (title) {
80
+ doc.title = title;
81
+ };
82
+ caml_gr_state_set(ctx);
83
+ var body = doc.body;
84
+ body.style.margin = "0px";
85
+ body.appendChild(canvas);
86
+ return 0;
87
+ }
88
+
89
+ //Provides: caml_gr_state_init
90
+ //Requires: caml_gr_state
91
+ //Requires: caml_gr_set_color,caml_gr_moveto,caml_gr_resize_window
92
+ //Requires: caml_gr_set_line_width,caml_gr_set_text_size,caml_gr_set_font
93
+ //Requires: caml_gr_set_window_title
94
+ function caml_gr_state_init() {
95
+ caml_gr_moveto(caml_gr_state.x, caml_gr_state.y);
96
+ caml_gr_resize_window(caml_gr_state.width, caml_gr_state.height);
97
+ caml_gr_set_line_width(caml_gr_state.line_width);
98
+ caml_gr_set_text_size(caml_gr_state.text_size);
99
+ caml_gr_set_font(caml_gr_state.font);
100
+ caml_gr_set_color(caml_gr_state.color);
101
+ caml_gr_set_window_title(caml_gr_state.title);
102
+ //caml_gr_resize_window might reset some canvas' properties
103
+ caml_gr_state.context.textBaseline = "bottom";
104
+ }
105
+
106
+ //Provides: caml_gr_state_create
107
+ //Requires: caml_string_of_jsbytes
108
+ function caml_gr_state_create(canvas, w, h) {
109
+ var context = canvas.getContext("2d");
110
+ // the native X11 backend draws thick lines with round caps and joins
111
+ context.lineCap = "round";
112
+ context.lineJoin = "round";
113
+ return {
114
+ context: context,
115
+ canvas: canvas,
116
+ x: 0,
117
+ y: 0,
118
+ width: w,
119
+ height: h,
120
+ line_width: 1,
121
+ font: caml_string_of_jsbytes("fixed"),
122
+ text_size: 26,
123
+ color: 0x000000,
124
+ title: caml_string_of_jsbytes(""),
125
+ };
126
+ }
127
+
128
+ //Provides: caml_gr_doc_of_state
129
+ function caml_gr_doc_of_state(state) {
130
+ if (state.canvas.ownerDocument) return state.canvas.ownerDocument;
131
+ }
132
+
133
+ //Provides: caml_gr_close_graph
134
+ //Requires: caml_gr_state_get
135
+ function caml_gr_close_graph() {
136
+ var s = caml_gr_state_get();
137
+ s.canvas.width = 0;
138
+ s.canvas.height = 0;
139
+ return 0;
140
+ }
141
+
142
+ //Provides: caml_gr_set_window_title
143
+ //Requires: caml_gr_state_get
144
+ //Requires: caml_jsstring_of_string
145
+ function caml_gr_set_window_title(name) {
146
+ var s = caml_gr_state_get();
147
+ s.title = name;
148
+ var jsname = caml_jsstring_of_string(name);
149
+ if (s.set_title) s.set_title(jsname);
150
+ return 0;
151
+ }
152
+
153
+ //Provides: caml_gr_resize_window
154
+ //Requires: caml_gr_state_get
155
+ function caml_gr_resize_window(w, h) {
156
+ var s = caml_gr_state_get();
157
+ s.width = w;
158
+ s.height = h;
159
+ if (w !== s.canvas.width) s.canvas.width = w;
160
+ if (h !== s.canvas.height) s.canvas.height = h;
161
+ return 0;
162
+ }
163
+
164
+ //Provides: caml_gr_clear_graph
165
+ //Requires: caml_gr_state_get
166
+ function caml_gr_clear_graph() {
167
+ var s = caml_gr_state_get();
168
+ s.context.clearRect(0, 0, s.canvas.width, s.canvas.height);
169
+ return 0;
170
+ }
171
+
172
+ //Provides: caml_gr_size_x
173
+ //Requires: caml_gr_state_get
174
+ function caml_gr_size_x() {
175
+ var s = caml_gr_state_get();
176
+ return s.width;
177
+ }
178
+ //Provides: caml_gr_size_y
179
+ //Requires: caml_gr_state_get
180
+ function caml_gr_size_y() {
181
+ var s = caml_gr_state_get();
182
+ return s.height;
183
+ }
184
+
185
+ //Provides: caml_gr_set_color
186
+ //Requires: caml_gr_state_get
187
+ function caml_gr_set_color(color) {
188
+ var s = caml_gr_state_get();
189
+ function convert(number) {
190
+ var str = "" + number.toString(16);
191
+ while (str.length < 2) str = "0" + str;
192
+ return str;
193
+ }
194
+ var r = (color >> 16) & 0xff,
195
+ g = (color >> 8) & 0xff,
196
+ b = (color >> 0) & 0xff;
197
+ s.color = color;
198
+ var c_str = "#" + convert(r) + convert(g) + convert(b);
199
+ s.context.fillStyle = c_str;
200
+ s.context.strokeStyle = c_str;
201
+ return 0;
202
+ }
203
+ // Coordinate helpers. Graphics uses a bottom-left origin; the canvas uses a
204
+ // top-left origin, so the row of the bottom-left-origin coordinate y is
205
+ // height-1-y. Two conventions are used, shared by the JS and the wasm paths:
206
+ // - caml_gr_y: the pixel row itself. plot, point_color, fill_rect and
207
+ // fill_poly address whole pixels, so they use this.
208
+ // - caml_gr_xc / caml_gr_yc: the centre of the pixel (x+0.5, row+0.5).
209
+ // Strokes use it so a 1px line lands crisply on the pixel grid, and
210
+ // curved fills use it so a disc/ellipse is centred on the pixel rather
211
+ // than on the pixel corner (which would shift it half a pixel).
212
+
213
+ //Provides: caml_gr_y
214
+ function caml_gr_y(s, y) {
215
+ return s.height - 1 - y;
216
+ }
217
+
218
+ //Provides: caml_gr_xc
219
+ function caml_gr_xc(x) {
220
+ return x + 0.5;
221
+ }
222
+
223
+ //Provides: caml_gr_yc
224
+ //Requires: caml_gr_y
225
+ function caml_gr_yc(s, y) {
226
+ return caml_gr_y(s, y) + 0.5;
227
+ }
228
+
229
+ //Provides: caml_gr_plot
230
+ //Requires: caml_gr_state_get, caml_gr_y
231
+ function caml_gr_plot(x, y) {
232
+ var s = caml_gr_state_get();
233
+ var im = s.context.createImageData(1, 1);
234
+ var d = im.data;
235
+ var color = s.color;
236
+ d[0] = (color >> 16) & 0xff; //r
237
+ (d[1] =
238
+ (color >> 8) &
239
+ 0xff), //g
240
+ (d[2] = (color >> 0) & 0xff); //b
241
+ d[3] = 0xff; //a
242
+ s.x = x;
243
+ s.y = y;
244
+ s.context.putImageData(im, x, caml_gr_y(s, y));
245
+ return 0;
246
+ }
247
+
248
+ //Provides: caml_gr_point_color
249
+ //Requires: caml_gr_state_get, caml_gr_y
250
+ function caml_gr_point_color(x, y) {
251
+ var s = caml_gr_state_get();
252
+ var im = s.context.getImageData(x, caml_gr_y(s, y), 1, 1);
253
+ var d = im.data;
254
+ return (d[0] << 16) + (d[1] << 8) + d[2];
255
+ }
256
+ //Provides: caml_gr_moveto
257
+ //Requires: caml_gr_state_get
258
+ function caml_gr_moveto(x, y) {
259
+ var s = caml_gr_state_get();
260
+ s.x = x;
261
+ s.y = y;
262
+ return 0;
263
+ }
264
+
265
+ //Provides: caml_gr_current_x
266
+ //Requires: caml_gr_state_get
267
+ function caml_gr_current_x() {
268
+ var s = caml_gr_state_get();
269
+ return s.x;
270
+ }
271
+ //Provides: caml_gr_current_y
272
+ //Requires: caml_gr_state_get
273
+ function caml_gr_current_y() {
274
+ var s = caml_gr_state_get();
275
+ return s.y;
276
+ }
277
+ //Provides: caml_gr_lineto
278
+ //Requires: caml_gr_state_get, caml_gr_xc, caml_gr_yc
279
+ function caml_gr_lineto(x, y) {
280
+ var s = caml_gr_state_get();
281
+ s.context.beginPath();
282
+ s.context.moveTo(caml_gr_xc(s.x), caml_gr_yc(s, s.y));
283
+ s.context.lineTo(caml_gr_xc(x), caml_gr_yc(s, y));
284
+ s.context.stroke();
285
+ s.x = x;
286
+ s.y = y;
287
+ return 0;
288
+ }
289
+ //Provides: caml_gr_draw_rect
290
+ //Requires: caml_gr_state_get, caml_gr_xc, caml_gr_yc
291
+ function caml_gr_draw_rect(x, y, w, h) {
292
+ var s = caml_gr_state_get();
293
+ // explicit path rather than strokeRect: strokeRect renders its left edge
294
+ // half a pixel off from its right edge in some browsers
295
+ var x0 = caml_gr_xc(x);
296
+ var y0 = caml_gr_yc(s, y);
297
+ var x1 = caml_gr_xc(x + w);
298
+ var y1 = caml_gr_yc(s, y + h);
299
+ s.context.beginPath();
300
+ s.context.moveTo(x0, y0);
301
+ s.context.lineTo(x1, y0);
302
+ s.context.lineTo(x1, y1);
303
+ s.context.lineTo(x0, y1);
304
+ // close with an explicit lineTo, not closePath(): the closePath segment is
305
+ // anti-aliased half a pixel off, while an explicit edge stays crisp
306
+ s.context.lineTo(x0, y0);
307
+ s.context.stroke();
308
+ return 0;
309
+ }
310
+
311
+ //Provides: caml_gr_arc_aux
312
+ function caml_gr_arc_aux(ctx, cx, cy, ry, rx, a1, a2) {
313
+ while (a1 > a2) a2 += 360;
314
+ a1 /= 180;
315
+ a2 /= 180;
316
+ var rot = 0,
317
+ xPos,
318
+ yPos,
319
+ xPos_prev,
320
+ yPos_prev;
321
+ var space = 2;
322
+ var num = (((a2 - a1) * Math.PI * ((rx + ry) / 2)) / space) | 0;
323
+ var delta = ((a2 - a1) * Math.PI) / num;
324
+ // negate the angle: the canvas y axis is flipped, so the OCaml angle
325
+ // is the negative of the canvas angle
326
+ var i = -a1 * Math.PI;
327
+ for (var j = 0; j <= num; j++) {
328
+ xPos =
329
+ cx -
330
+ rx * Math.sin(i) * Math.sin(rot * Math.PI) +
331
+ ry * Math.cos(i) * Math.cos(rot * Math.PI);
332
+ xPos = xPos.toFixed(2);
333
+ yPos =
334
+ cy +
335
+ ry * Math.cos(i) * Math.sin(rot * Math.PI) +
336
+ rx * Math.sin(i) * Math.cos(rot * Math.PI);
337
+ yPos = yPos.toFixed(2);
338
+ if (j === 0) {
339
+ ctx.moveTo(xPos, yPos);
340
+ } else if (xPos_prev !== xPos || yPos_prev !== yPos) {
341
+ ctx.lineTo(xPos, yPos);
342
+ }
343
+ xPos_prev = xPos;
344
+ yPos_prev = yPos;
345
+ i -= delta; //ccw
346
+ }
347
+ return 0;
348
+ }
349
+
350
+ //Provides: caml_gr_draw_arc
351
+ //Requires: caml_gr_state_get, caml_gr_arc_aux, caml_gr_xc, caml_gr_yc
352
+ function caml_gr_draw_arc(x, y, rx, ry, a1, a2) {
353
+ var s = caml_gr_state_get();
354
+ s.context.beginPath();
355
+ caml_gr_arc_aux(s.context, caml_gr_xc(x), caml_gr_yc(s, y), rx, ry, a1, a2);
356
+ s.context.stroke();
357
+ return 0;
358
+ }
359
+
360
+ //Provides: caml_gr_set_line_width
361
+ //Requires: caml_gr_state_get
362
+ function caml_gr_set_line_width(w) {
363
+ var s = caml_gr_state_get();
364
+ s.line_width = w;
365
+ s.context.lineWidth = w;
366
+ // resizing the canvas resets these to their defaults; restore them
367
+ s.context.lineCap = "round";
368
+ s.context.lineJoin = "round";
369
+ return 0;
370
+ }
371
+
372
+ //Provides: caml_gr_fill_rect
373
+ //Requires: caml_gr_state_get, caml_gr_y
374
+ function caml_gr_fill_rect(x, y, w, h) {
375
+ var s = caml_gr_state_get();
376
+ // match the native X11 backend, which fills (w+1)x(h+1) pixels: the far
377
+ // edges (column x+w and row y+h) are included. The bottom-left pixel is
378
+ // (x, caml_gr_y(s, y)); fill up and to the right from there.
379
+ s.context.fillRect(x, caml_gr_y(s, y) - h, w + 1, h + 1);
380
+ return 0;
381
+ }
382
+ //Provides: caml_gr_fill_poly
383
+ //Requires: caml_gr_state_get, caml_gr_y
384
+ function caml_gr_fill_poly(ar) {
385
+ var s = caml_gr_state_get();
386
+ s.context.beginPath();
387
+ s.context.moveTo(ar[1][1], caml_gr_y(s, ar[1][2]));
388
+ for (var i = 2; i < ar.length; i++)
389
+ s.context.lineTo(ar[i][1], caml_gr_y(s, ar[i][2]));
390
+ s.context.lineTo(ar[1][1], caml_gr_y(s, ar[1][2]));
391
+ s.context.fill();
392
+ return 0;
393
+ }
394
+
395
+ //Provides: caml_gr_fill_arc
396
+ //Requires: caml_gr_state_get, caml_gr_arc_aux, caml_gr_xc, caml_gr_yc
397
+ function caml_gr_fill_arc(x, y, rx, ry, a1, a2) {
398
+ var s = caml_gr_state_get();
399
+ // centre the arc on the pixel (x, height-1-y), as native does, instead of
400
+ // on the pixel corner (which shifts a filled ellipse/disc half a pixel)
401
+ var cx = caml_gr_xc(x);
402
+ var cy = caml_gr_yc(s, y);
403
+ s.context.beginPath();
404
+ caml_gr_arc_aux(s.context, cx, cy, rx, ry, a1, a2);
405
+ // close through the centre so a partial arc fills a pie slice (like the
406
+ // native X11 backend), not the circular segment a bare fill() would give
407
+ s.context.lineTo(cx, cy);
408
+ s.context.fill();
409
+ return 0;
410
+ }
411
+
412
+ //Provides: caml_gr_draw_str
413
+ //Requires: caml_gr_state_get, caml_gr_y
414
+ function caml_gr_draw_str(str) {
415
+ var s = caml_gr_state_get();
416
+ var m = s.context.measureText(str);
417
+ var dx = m.width;
418
+ // the text baseline sits at the current point; it is placed one row below
419
+ // the pixel row (the continuous bottom-left-origin coordinate), which is
420
+ // caml_gr_y(s, s.y) + 1
421
+ s.context.fillText(str, s.x, caml_gr_y(s, s.y) + 1);
422
+ s.x += dx | 0;
423
+ return 0;
424
+ }
425
+
426
+ //Provides: caml_gr_draw_char
427
+ //Requires: caml_gr_draw_str
428
+ function caml_gr_draw_char(c) {
429
+ caml_gr_draw_str(String.fromCharCode(c));
430
+ return 0;
431
+ }
432
+
433
+ //Provides: caml_gr_draw_string
434
+ //Requires: caml_gr_draw_str
435
+ //Requires: caml_jsstring_of_string
436
+ function caml_gr_draw_string(str) {
437
+ caml_gr_draw_str(caml_jsstring_of_string(str));
438
+ return 0;
439
+ }
440
+
441
+ //Provides: caml_gr_set_font
442
+ //Requires: caml_gr_state_get
443
+ //Requires: caml_jsstring_of_string
444
+ function caml_gr_set_font(f) {
445
+ var s = caml_gr_state_get();
446
+ s.font = f;
447
+ s.context.font = s.text_size + "px " + caml_jsstring_of_string(s.font);
448
+ return 0;
449
+ }
450
+
451
+ //Provides: caml_gr_set_text_size
452
+ //Requires: caml_gr_state_get
453
+ //Requires: caml_jsstring_of_string
454
+ function caml_gr_set_text_size(size) {
455
+ var s = caml_gr_state_get();
456
+ s.text_size = size;
457
+ s.context.font = s.text_size + "px " + caml_jsstring_of_string(s.font);
458
+ return 0;
459
+ }
460
+
461
+ //Provides: caml_gr_text_size
462
+ //Requires: caml_gr_state_get
463
+ //Requires: caml_jsstring_of_string
464
+ function caml_gr_text_size(txt) {
465
+ var s = caml_gr_state_get();
466
+ var w = s.context.measureText(caml_jsstring_of_string(txt)).width;
467
+ return [0, w, s.text_size];
468
+ }
469
+
470
+ //Provides: caml_gr_make_image
471
+ //Requires: caml_gr_state_get
472
+ function caml_gr_make_image(arr) {
473
+ var s = caml_gr_state_get();
474
+ var h = arr.length - 1;
475
+ var w = arr[1].length - 1;
476
+ var im = s.context.createImageData(w, h);
477
+ for (var i = 0; i < h; i++) {
478
+ for (var j = 0; j < w; j++) {
479
+ var c = arr[i + 1][j + 1];
480
+ var o = i * (w * 4) + j * 4;
481
+ if (c === -1) {
482
+ im.data[o + 0] = 0;
483
+ im.data[o + 1] = 0;
484
+ im.data[o + 2] = 0;
485
+ im.data[o + 3] = 0;
486
+ } else {
487
+ im.data[o + 0] = (c >> 16) & 0xff;
488
+ im.data[o + 1] = (c >> 8) & 0xff;
489
+ im.data[o + 2] = (c >> 0) & 0xff;
490
+ im.data[o + 3] = 0xff;
491
+ }
492
+ }
493
+ }
494
+ return im;
495
+ }
496
+ //Provides: caml_gr_dump_image
497
+ //Requires: caml_gr_state_get
498
+ function caml_gr_dump_image(im) {
499
+ var data = [0];
500
+ for (var i = 0; i < im.height; i++) {
501
+ data[i + 1] = [0];
502
+ for (var j = 0; j < im.width; j++) {
503
+ var o = i * (im.width * 4) + j * 4,
504
+ r = im.data[o + 0],
505
+ g = im.data[o + 1],
506
+ b = im.data[o + 2];
507
+ data[i + 1][j + 1] = (r << 16) + (g << 8) + b;
508
+ }
509
+ }
510
+ return data;
511
+ }
512
+ //Provides: caml_gr_draw_image
513
+ //Requires: caml_gr_state_get, caml_gr_y
514
+ function caml_gr_draw_image(im, x, y) {
515
+ var s = caml_gr_state_get();
516
+ if (!im.image) {
517
+ var canvas = document.createElement("canvas");
518
+ canvas.width = s.width;
519
+ canvas.height = s.height;
520
+ canvas.getContext("2d").putImageData(im, 0, 0);
521
+ // a canvas is a valid drawImage source immediately, so draw it
522
+ // directly instead of round-tripping through an Image + data URL
523
+ // (which made the first draw asynchronous)
524
+ im.image = canvas;
525
+ }
526
+ // the image's bottom row is caml_gr_y(s, y); drawImage takes the top-left
527
+ s.context.drawImage(im.image, x, caml_gr_y(s, y) - im.height + 1);
528
+ return 0;
529
+ }
530
+ //Provides: caml_gr_create_image
531
+ //Requires: caml_gr_state_get
532
+ function caml_gr_create_image(x, y) {
533
+ var s = caml_gr_state_get();
534
+ return s.context.createImageData(x, y);
535
+ }
536
+ //Provides: caml_gr_blit_image
537
+ //Requires: caml_gr_state_get, caml_gr_y
538
+ function caml_gr_blit_image(im, x, y) {
539
+ var s = caml_gr_state_get();
540
+ // the image's bottom row is caml_gr_y(s, y); getImageData takes the top-left
541
+ var im2 = s.context.getImageData(
542
+ x,
543
+ caml_gr_y(s, y) - im.height + 1,
544
+ im.width,
545
+ im.height,
546
+ );
547
+ for (var i = 0; i < im2.data.length; i += 4) {
548
+ im.data[i] = im2.data[i];
549
+ im.data[i + 1] = im2.data[i + 1];
550
+ im.data[i + 2] = im2.data[i + 2];
551
+ im.data[i + 3] = im2.data[i + 3];
552
+ }
553
+ return 0;
554
+ }
555
+ //Provides: caml_gr_sigio_handler
556
+ function caml_gr_sigio_handler() {
557
+ return 0;
558
+ }
559
+ //Provides: caml_gr_sigio_signal
560
+ function caml_gr_sigio_signal() {
561
+ return 0;
562
+ }
563
+ //Provides: caml_gr_wait_event
564
+ //Requires: caml_failwith
565
+ function caml_gr_wait_event(_evl) {
566
+ caml_failwith("caml_gr_wait_event not Implemented: use Graphics_js instead");
567
+ }
568
+
569
+ //Provides: caml_gr_synchronize
570
+ //Requires: caml_failwith
571
+ function caml_gr_synchronize() {
572
+ caml_failwith("caml_gr_synchronize not Implemented");
573
+ }
574
+ //Provides: caml_gr_remember_mode
575
+ //Requires: caml_failwith
576
+ function caml_gr_remember_mode() {
577
+ caml_failwith("caml_gr_remember_mode not Implemented");
578
+ }
579
+ //Provides: caml_gr_display_mode
580
+ //Requires: caml_failwith
581
+ function caml_gr_display_mode() {
582
+ caml_failwith("caml_gr_display_mode not Implemented");
583
+ }
584
+
585
+ //Provides: caml_gr_window_id
586
+ //Requires: caml_failwith
587
+ function caml_gr_window_id(_a) {
588
+ caml_failwith("caml_gr_window_id not Implemented");
589
+ }
590
+
591
+ //Provides: caml_gr_open_subwindow
592
+ //Requires: caml_failwith
593
+ function caml_gr_open_subwindow(_a, _b, _c, _d) {
594
+ caml_failwith("caml_gr_open_subwindow not Implemented");
595
+ }
596
+
597
+ //Provides: caml_gr_close_subwindow
598
+ //Requires: caml_failwith
599
+ function caml_gr_close_subwindow(_a) {
600
+ caml_failwith("caml_gr_close_subwindow not Implemented");
601
+ }
602
+
603
+ // ---- Wasm helpers ----
604
+ // These functions take/return plain JS values (ints, JS strings, JS objects)
605
+ // and access caml_gr_state directly. State checking is done in WAT.
606
+
607
+ //Provides: gr_state_for_wasm
608
+ //Requires: caml_gr_state
609
+ //If: wasm
610
+ function gr_state_for_wasm() {
611
+ if (caml_gr_state) return caml_gr_state;
612
+ return null;
613
+ }
614
+
615
+ //Provides: gr_state_create_for_wasm
616
+ //If: wasm
617
+ function gr_state_create_for_wasm(canvas, w, h) {
618
+ var context = canvas.getContext("2d");
619
+ context.lineCap = "round";
620
+ context.lineJoin = "round";
621
+ return {
622
+ context: context,
623
+ canvas: canvas,
624
+ x: 0,
625
+ y: 0,
626
+ width: w,
627
+ height: h,
628
+ line_width: 1,
629
+ font: "fixed",
630
+ text_size: 26,
631
+ color: 0x000000,
632
+ title: "",
633
+ };
634
+ }
635
+
636
+ //Provides: gr_state_init_for_wasm
637
+ //Requires: caml_gr_state
638
+ //Requires: gr_set_color_for_wasm, gr_moveto_for_wasm, gr_resize_window_for_wasm
639
+ //Requires: gr_set_line_width_for_wasm, gr_set_text_size_for_wasm
640
+ //Requires: gr_set_font_for_wasm, gr_set_window_title_for_wasm
641
+ //If: wasm
642
+ function gr_state_init_for_wasm() {
643
+ var s = caml_gr_state;
644
+ gr_moveto_for_wasm(s.x, s.y);
645
+ gr_resize_window_for_wasm(s.width, s.height);
646
+ gr_set_line_width_for_wasm(s.line_width);
647
+ gr_set_text_size_for_wasm(s.text_size);
648
+ gr_set_font_for_wasm(s.font);
649
+ gr_set_color_for_wasm(s.color);
650
+ gr_set_window_title_for_wasm(s.title);
651
+ s.context.textBaseline = "bottom";
652
+ }
653
+
654
+ //Provides: gr_state_set_for_wasm
655
+ //Requires: caml_gr_state, gr_state_init_for_wasm
656
+ //If: wasm
657
+ function gr_state_set_for_wasm(ctx) {
658
+ caml_gr_state = ctx;
659
+ gr_state_init_for_wasm();
660
+ }
661
+
662
+ //Provides: gr_open_for_wasm
663
+ //Requires: gr_state_create_for_wasm, gr_state_set_for_wasm
664
+ //If: wasm
665
+ function gr_open_for_wasm(info) {
666
+ function get(name) {
667
+ var res = info.match("(^|,) *" + name + " *= *([a-zA-Z0-9_]+) *(,|$)");
668
+ if (res) return res[2];
669
+ }
670
+ var specs = [];
671
+ if (!(info === "")) specs.push(info);
672
+ var target = get("target");
673
+ if (!target) target = "";
674
+ var status = get("status");
675
+ if (!status) specs.push("status=1");
676
+ var w = get("width");
677
+ w = w ? Number.parseInt(w) : 200;
678
+ specs.push("width=" + w);
679
+ var h = get("height");
680
+ h = h ? Number.parseInt(h) : 200;
681
+ specs.push("height=" + h);
682
+ var win = globalThis.open("about:blank", target, specs.join(","));
683
+ if (!win) return -1;
684
+ var doc = win.document;
685
+ var canvas = doc.createElement("canvas");
686
+ canvas.width = w;
687
+ canvas.height = h;
688
+ var ctx = gr_state_create_for_wasm(canvas, w, h);
689
+ ctx.set_title = function (title) {
690
+ doc.title = title;
691
+ };
692
+ gr_state_set_for_wasm(ctx);
693
+ var body = doc.body;
694
+ body.style.margin = "0px";
695
+ body.appendChild(canvas);
696
+ return 0;
697
+ }
698
+
699
+ //Provides: gr_close_for_wasm
700
+ //Requires: caml_gr_state
701
+ //If: wasm
702
+ function gr_close_for_wasm() {
703
+ caml_gr_state.canvas.width = 0;
704
+ caml_gr_state.canvas.height = 0;
705
+ }
706
+
707
+ //Provides: gr_clear_for_wasm
708
+ //Requires: caml_gr_state
709
+ //If: wasm
710
+ function gr_clear_for_wasm() {
711
+ var s = caml_gr_state;
712
+ s.context.clearRect(0, 0, s.canvas.width, s.canvas.height);
713
+ }
714
+
715
+ //Provides: gr_size_x_for_wasm
716
+ //Requires: caml_gr_state
717
+ //If: wasm
718
+ function gr_size_x_for_wasm() {
719
+ return caml_gr_state.width;
720
+ }
721
+
722
+ //Provides: gr_size_y_for_wasm
723
+ //Requires: caml_gr_state
724
+ //If: wasm
725
+ function gr_size_y_for_wasm() {
726
+ return caml_gr_state.height;
727
+ }
728
+
729
+ //Provides: gr_current_x_for_wasm
730
+ //Requires: caml_gr_state
731
+ //If: wasm
732
+ function gr_current_x_for_wasm() {
733
+ return caml_gr_state.x;
734
+ }
735
+
736
+ //Provides: gr_current_y_for_wasm
737
+ //Requires: caml_gr_state
738
+ //If: wasm
739
+ function gr_current_y_for_wasm() {
740
+ return caml_gr_state.y;
741
+ }
742
+
743
+ //Provides: gr_moveto_for_wasm
744
+ //Requires: caml_gr_state
745
+ //If: wasm
746
+ function gr_moveto_for_wasm(x, y) {
747
+ caml_gr_state.x = x;
748
+ caml_gr_state.y = y;
749
+ }
750
+
751
+ //Provides: gr_set_color_for_wasm
752
+ //Requires: caml_gr_state
753
+ //If: wasm
754
+ function gr_set_color_for_wasm(color) {
755
+ var s = caml_gr_state;
756
+ function convert(number) {
757
+ var str = "" + number.toString(16);
758
+ while (str.length < 2) str = "0" + str;
759
+ return str;
760
+ }
761
+ var r = (color >> 16) & 0xff,
762
+ g = (color >> 8) & 0xff,
763
+ b = (color >> 0) & 0xff;
764
+ s.color = color;
765
+ var c_str = "#" + convert(r) + convert(g) + convert(b);
766
+ s.context.fillStyle = c_str;
767
+ s.context.strokeStyle = c_str;
768
+ }
769
+
770
+ //Provides: gr_plot_for_wasm
771
+ //Requires: caml_gr_state, caml_gr_y
772
+ //If: wasm
773
+ function gr_plot_for_wasm(x, y) {
774
+ var s = caml_gr_state;
775
+ var im = s.context.createImageData(1, 1);
776
+ var d = im.data;
777
+ var color = s.color;
778
+ d[0] = (color >> 16) & 0xff;
779
+ d[1] = (color >> 8) & 0xff;
780
+ d[2] = (color >> 0) & 0xff;
781
+ d[3] = 0xff;
782
+ s.x = x;
783
+ s.y = y;
784
+ s.context.putImageData(im, x, caml_gr_y(s, y));
785
+ }
786
+
787
+ //Provides: gr_point_color_for_wasm
788
+ //Requires: caml_gr_state, caml_gr_y
789
+ //If: wasm
790
+ function gr_point_color_for_wasm(x, y) {
791
+ var s = caml_gr_state;
792
+ var im = s.context.getImageData(x, caml_gr_y(s, y), 1, 1);
793
+ var d = im.data;
794
+ return (d[0] << 16) + (d[1] << 8) + d[2];
795
+ }
796
+
797
+ //Provides: gr_lineto_for_wasm
798
+ //Requires: caml_gr_state, caml_gr_xc, caml_gr_yc
799
+ //If: wasm
800
+ function gr_lineto_for_wasm(x, y) {
801
+ var s = caml_gr_state;
802
+ s.context.beginPath();
803
+ s.context.moveTo(caml_gr_xc(s.x), caml_gr_yc(s, s.y));
804
+ s.context.lineTo(caml_gr_xc(x), caml_gr_yc(s, y));
805
+ s.context.stroke();
806
+ s.x = x;
807
+ s.y = y;
808
+ }
809
+
810
+ //Provides: gr_draw_rect_for_wasm
811
+ //Requires: caml_gr_state, caml_gr_xc, caml_gr_yc
812
+ //If: wasm
813
+ function gr_draw_rect_for_wasm(x, y, w, h) {
814
+ var s = caml_gr_state;
815
+ // explicit path (see caml_gr_draw_rect): strokeRect can render its left
816
+ // edge half a pixel off from its right edge
817
+ var x0 = caml_gr_xc(x);
818
+ var y0 = caml_gr_yc(s, y);
819
+ var x1 = caml_gr_xc(x + w);
820
+ var y1 = caml_gr_yc(s, y + h);
821
+ s.context.beginPath();
822
+ s.context.moveTo(x0, y0);
823
+ s.context.lineTo(x1, y0);
824
+ s.context.lineTo(x1, y1);
825
+ s.context.lineTo(x0, y1);
826
+ s.context.lineTo(x0, y0);
827
+ s.context.stroke();
828
+ }
829
+
830
+ //Provides: gr_fill_rect_for_wasm
831
+ //Requires: caml_gr_state, caml_gr_y
832
+ //If: wasm
833
+ function gr_fill_rect_for_wasm(x, y, w, h) {
834
+ // match the native X11 backend: fill (w+1)x(h+1) pixels (see caml_gr_fill_rect)
835
+ var s = caml_gr_state;
836
+ s.context.fillRect(x, caml_gr_y(s, y) - h, w + 1, h + 1);
837
+ }
838
+
839
+ //Provides: gr_draw_arc_for_wasm
840
+ //Requires: caml_gr_state, caml_gr_arc_aux, caml_gr_xc, caml_gr_yc
841
+ //If: wasm
842
+ function gr_draw_arc_for_wasm(x, y, rx, ry, a1, a2) {
843
+ var s = caml_gr_state;
844
+ s.context.beginPath();
845
+ caml_gr_arc_aux(s.context, caml_gr_xc(x), caml_gr_yc(s, y), rx, ry, a1, a2);
846
+ s.context.stroke();
847
+ }
848
+
849
+ //Provides: gr_fill_arc_for_wasm
850
+ //Requires: caml_gr_state, caml_gr_arc_aux, caml_gr_xc, caml_gr_yc
851
+ //If: wasm
852
+ function gr_fill_arc_for_wasm(x, y, rx, ry, a1, a2) {
853
+ var s = caml_gr_state;
854
+ var cx = caml_gr_xc(x);
855
+ var cy = caml_gr_yc(s, y);
856
+ s.context.beginPath();
857
+ caml_gr_arc_aux(s.context, cx, cy, rx, ry, a1, a2);
858
+ // pie slice (close through the centre), matching native fill_arc
859
+ s.context.lineTo(cx, cy);
860
+ s.context.fill();
861
+ }
862
+
863
+ //Provides: gr_set_line_width_for_wasm
864
+ //Requires: caml_gr_state
865
+ //If: wasm
866
+ function gr_set_line_width_for_wasm(w) {
867
+ caml_gr_state.line_width = w;
868
+ caml_gr_state.context.lineWidth = w;
869
+ caml_gr_state.context.lineCap = "round";
870
+ caml_gr_state.context.lineJoin = "round";
871
+ }
872
+
873
+ //Provides: gr_resize_window_for_wasm
874
+ //Requires: caml_gr_state
875
+ //If: wasm
876
+ function gr_resize_window_for_wasm(w, h) {
877
+ var s = caml_gr_state;
878
+ s.width = w;
879
+ s.height = h;
880
+ if (w !== s.canvas.width) s.canvas.width = w;
881
+ if (h !== s.canvas.height) s.canvas.height = h;
882
+ }
883
+
884
+ //Provides: gr_draw_char_for_wasm
885
+ //Requires: gr_draw_str_for_wasm
886
+ //If: wasm
887
+ function gr_draw_char_for_wasm(c) {
888
+ gr_draw_str_for_wasm(String.fromCharCode(c));
889
+ }
890
+
891
+ //Provides: gr_draw_str_for_wasm
892
+ //Requires: caml_gr_state, caml_gr_y
893
+ //If: wasm
894
+ function gr_draw_str_for_wasm(str) {
895
+ var s = caml_gr_state;
896
+ var m = s.context.measureText(str);
897
+ var dx = m.width;
898
+ // text baseline = current point, one row below the pixel (see caml_gr_draw_str)
899
+ s.context.fillText(str, s.x, caml_gr_y(s, s.y) + 1);
900
+ s.x += dx | 0;
901
+ }
902
+
903
+ //Provides: gr_set_font_for_wasm
904
+ //Requires: caml_gr_state
905
+ //If: wasm
906
+ function gr_set_font_for_wasm(f) {
907
+ var s = caml_gr_state;
908
+ s.font = f;
909
+ s.context.font = s.text_size + "px " + f;
910
+ }
911
+
912
+ //Provides: gr_set_text_size_for_wasm
913
+ //Requires: caml_gr_state
914
+ //If: wasm
915
+ function gr_set_text_size_for_wasm(size) {
916
+ var s = caml_gr_state;
917
+ s.text_size = size;
918
+ s.context.font = s.text_size + "px " + s.font;
919
+ }
920
+
921
+ //Provides: gr_set_window_title_for_wasm
922
+ //Requires: caml_gr_state
923
+ //If: wasm
924
+ function gr_set_window_title_for_wasm(name) {
925
+ var s = caml_gr_state;
926
+ s.title = name;
927
+ if (s.set_title) s.set_title(name);
928
+ }
929
+
930
+ //Provides: gr_text_size_w_for_wasm
931
+ //Requires: caml_gr_state
932
+ //If: wasm
933
+ function gr_text_size_w_for_wasm(txt) {
934
+ return caml_gr_state.context.measureText(txt).width | 0;
935
+ }
936
+
937
+ //Provides: gr_text_size_h_for_wasm
938
+ //Requires: caml_gr_state
939
+ //If: wasm
940
+ function gr_text_size_h_for_wasm() {
941
+ return caml_gr_state.text_size;
942
+ }
943
+
944
+ //Provides: gr_fill_poly_for_wasm
945
+ //Requires: caml_gr_state, caml_gr_y
946
+ //If: wasm
947
+ function gr_fill_poly_for_wasm(ar, n) {
948
+ var s = caml_gr_state;
949
+ s.context.beginPath();
950
+ s.context.moveTo(ar[0], caml_gr_y(s, ar[1]));
951
+ for (var i = 1; i < n; i++)
952
+ s.context.lineTo(ar[i * 2], caml_gr_y(s, ar[i * 2 + 1]));
953
+ s.context.lineTo(ar[0], caml_gr_y(s, ar[1]));
954
+ s.context.fill();
955
+ }
956
+
957
+ //Provides: gr_create_image_for_wasm
958
+ //Requires: caml_gr_state
959
+ //If: wasm
960
+ function gr_create_image_for_wasm(x, y) {
961
+ return caml_gr_state.context.createImageData(x, y);
962
+ }
963
+
964
+ //Provides: gr_draw_image_for_wasm
965
+ //Requires: caml_gr_state, caml_gr_y
966
+ //If: wasm
967
+ function gr_draw_image_for_wasm(im, x, y) {
968
+ var s = caml_gr_state;
969
+ if (!im.image) {
970
+ var canvas = document.createElement("canvas");
971
+ canvas.width = s.width;
972
+ canvas.height = s.height;
973
+ canvas.getContext("2d").putImageData(im, 0, 0);
974
+ // a canvas is a valid drawImage source immediately, so draw it
975
+ // directly instead of round-tripping through an Image + data URL
976
+ // (which made the first draw asynchronous)
977
+ im.image = canvas;
978
+ }
979
+ // the image's bottom row is caml_gr_y(s, y); drawImage takes the top-left
980
+ s.context.drawImage(im.image, x, caml_gr_y(s, y) - im.height + 1);
981
+ }
982
+
983
+ //Provides: gr_blit_image_for_wasm
984
+ //Requires: caml_gr_state, caml_gr_y
985
+ //If: wasm
986
+ function gr_blit_image_for_wasm(im, x, y) {
987
+ var s = caml_gr_state;
988
+ // the image's bottom row is caml_gr_y(s, y); getImageData takes the top-left
989
+ var im2 = s.context.getImageData(
990
+ x,
991
+ caml_gr_y(s, y) - im.height + 1,
992
+ im.width,
993
+ im.height,
994
+ );
995
+ for (var i = 0; i < im2.data.length; i += 4) {
996
+ im.data[i] = im2.data[i];
997
+ im.data[i + 1] = im2.data[i + 1];
998
+ im.data[i + 2] = im2.data[i + 2];
999
+ im.data[i + 3] = im2.data[i + 3];
1000
+ }
1001
+ }
1002
+
1003
+ //Provides: gr_make_image_for_wasm
1004
+ //Requires: caml_gr_state
1005
+ //If: wasm
1006
+ function gr_make_image_for_wasm(pixels, w, h) {
1007
+ var s = caml_gr_state;
1008
+ var im = s.context.createImageData(w, h);
1009
+ for (var i = 0; i < h; i++) {
1010
+ for (var j = 0; j < w; j++) {
1011
+ var c = pixels[i * w + j];
1012
+ var o = i * (w * 4) + j * 4;
1013
+ if (c === -1) {
1014
+ im.data[o + 0] = 0;
1015
+ im.data[o + 1] = 0;
1016
+ im.data[o + 2] = 0;
1017
+ im.data[o + 3] = 0;
1018
+ } else {
1019
+ im.data[o + 0] = (c >> 16) & 0xff;
1020
+ im.data[o + 1] = (c >> 8) & 0xff;
1021
+ im.data[o + 2] = (c >> 0) & 0xff;
1022
+ im.data[o + 3] = 0xff;
1023
+ }
1024
+ }
1025
+ }
1026
+ return im;
1027
+ }
1028
+
1029
+ //Provides: gr_dump_image_width_for_wasm
1030
+ //If: wasm
1031
+ function gr_dump_image_width_for_wasm(im) {
1032
+ return im.width;
1033
+ }
1034
+
1035
+ //Provides: gr_dump_image_height_for_wasm
1036
+ //If: wasm
1037
+ function gr_dump_image_height_for_wasm(im) {
1038
+ return im.height;
1039
+ }
1040
+
1041
+ //Provides: gr_dump_image_pixel_for_wasm
1042
+ //If: wasm
1043
+ function gr_dump_image_pixel_for_wasm(im, i, j) {
1044
+ var o = i * (im.width * 4) + j * 4;
1045
+ return (im.data[o] << 16) + (im.data[o + 1] << 8) + im.data[o + 2];
1046
+ }
1047
+
1048
+ //Provides: gr_doc_of_state_for_wasm
1049
+ //If: wasm
1050
+ function gr_doc_of_state_for_wasm(state) {
1051
+ if (state.canvas.ownerDocument) return state.canvas.ownerDocument;
1052
+ return null;
1053
+ }