@live-codes/ocaml 0.0.0-stage → 0.1.1
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/LICENSE +220 -0
- package/README.md +165 -2
- package/THIRD-PARTY-NOTICES.md +52 -0
- package/assets/compiler/compile_stdout.browser.js +27856 -0
- package/assets/compiler/jsoo.js +12631 -0
- package/assets/compiler/package.json +3 -0
- package/assets/compiler/runtime/bigarray.js +1072 -0
- package/assets/compiler/runtime/bigstring.js +137 -0
- package/assets/compiler/runtime/domain.js +393 -0
- package/assets/compiler/runtime/dynlink.js +91 -0
- package/assets/compiler/runtime/float32.js +486 -0
- package/assets/compiler/runtime/fs.js +416 -0
- package/assets/compiler/runtime/fs_fake.js +600 -0
- package/assets/compiler/runtime/fs_node.js +609 -0
- package/assets/compiler/runtime/fs_quickjs.js +532 -0
- package/assets/compiler/runtime/gc.js +201 -0
- package/assets/compiler/runtime/graphics.js +1053 -0
- package/assets/compiler/runtime/ieee_754.js +621 -0
- package/assets/compiler/runtime/int64.js +516 -0
- package/assets/compiler/runtime/io.js +739 -0
- package/assets/compiler/runtime/jslib.js +553 -0
- package/assets/compiler/runtime/jslib_js_of_ocaml.js +81 -0
- package/assets/compiler/runtime/lexing.js +240 -0
- package/assets/compiler/runtime/manifest.txt +31 -0
- package/assets/compiler/runtime/marshal.js +863 -0
- package/assets/compiler/runtime/md5.js +236 -0
- package/assets/compiler/runtime/mlBytes.js +1007 -0
- package/assets/compiler/runtime/nat.js +469 -0
- package/assets/compiler/runtime/parsing.js +317 -0
- package/assets/compiler/runtime/prng.js +84 -0
- package/assets/compiler/runtime/promise.js +45 -0
- package/assets/compiler/runtime/runtime.js +16688 -0
- package/assets/compiler/runtime/runtime_events.js +90 -0
- package/assets/compiler/runtime/stdlib.js +363 -0
- package/assets/compiler/runtime/sync.js +35 -0
- package/assets/compiler/runtime/toplevel.js +150 -0
- package/assets/compiler/runtime/unix.js +914 -0
- package/assets/compiler/runtime/weak.js +247 -0
- package/assets/compiler/stdlib.js +254 -0
- package/assets/compiler/worker.js +46 -0
- package/assets/interpreter/libs/greet.cma +0 -0
- package/assets/interpreter/libs/greet.cmi +0 -0
- package/assets/interpreter/libs/manifest.txt +1 -0
- package/assets/interpreter/package.json +3 -0
- package/assets/interpreter/stdlib/camlinternalFormat.cmi +0 -0
- package/assets/interpreter/stdlib/camlinternalFormatBasics.cmi +0 -0
- package/assets/interpreter/stdlib/camlinternalLazy.cmi +0 -0
- package/assets/interpreter/stdlib/camlinternalMod.cmi +0 -0
- package/assets/interpreter/stdlib/camlinternalOO.cmi +0 -0
- package/assets/interpreter/stdlib/std_exit.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Arg.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Array.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__ArrayLabels.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Atomic.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Bigarray.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Bool.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Buffer.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Bytes.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__BytesLabels.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Callback.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Char.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Complex.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Condition.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Digest.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Domain.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Dynarray.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Effect.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Either.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Ephemeron.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Filename.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Float.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Format.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Fun.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Gc.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Hashtbl.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Iarray.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__In_channel.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Int.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Int32.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Int64.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Lazy.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Lexing.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__List.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__ListLabels.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Map.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Marshal.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__MoreLabels.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Mutex.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Nativeint.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Obj.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Oo.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Option.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Out_channel.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Pair.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Parsing.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Pqueue.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Printexc.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Printf.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Queue.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Random.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Repr.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Result.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Scanf.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Semaphore.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Seq.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Set.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Stack.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__StdLabels.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__String.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__StringLabels.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Sys.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Type.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Uchar.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Unit.cmi +0 -0
- package/assets/interpreter/stdlib/stdlib__Weak.cmi +0 -0
- package/assets/interpreter/stdlib/topdirs.cmi +0 -0
- package/assets/interpreter/stdlib/units.txt +75 -0
- package/assets/interpreter/stdlib/unix.cmi +0 -0
- package/assets/interpreter/stdlib/unixLabels.cmi +0 -0
- package/assets/interpreter/worker-entry.js +39 -0
- package/assets/interpreter/worker.js +42356 -0
- package/bin/copy-assets.mjs +75 -0
- package/package.json +41 -4
- package/src/compiler/compile.js +195 -0
- package/src/compiler/index.js +46 -0
- package/src/compiler/worker.js +46 -0
- package/src/index.js +12 -0
- package/src/interpreter/api.js +182 -0
- 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
|
+
}
|