xbintsc 0.5.38 → 0.5.41
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/src/cli/help.d.ts +1 -1
- package/dist/src/codegen/generator/module.js +23 -7
- package/dist/src/codegen/generator/module.js.map +1 -1
- package/dist/src/driver/version.d.ts +1 -1
- package/dist/src/driver/version.js +1 -1
- package/dist/src/extensions/gui/html.js +9 -2
- package/dist/src/extensions/gui/html.js.map +1 -1
- package/dist/tests/codegen/closures.test.js +7 -0
- package/dist/tests/codegen/closures.test.js.map +1 -1
- package/dist/tests/e2e/compile-objects-classes.test.js +31 -0
- package/dist/tests/e2e/compile-objects-classes.test.js.map +1 -1
- package/dist/tests/e2e/gui-canvas-state.test.d.ts +9 -0
- package/dist/tests/e2e/gui-canvas-state.test.js +297 -0
- package/dist/tests/e2e/gui-canvas-state.test.js.map +1 -0
- package/dist/tests/e2e/gui-draw-perf.test.d.ts +22 -0
- package/dist/tests/e2e/gui-draw-perf.test.js +405 -0
- package/dist/tests/e2e/gui-draw-perf.test.js.map +1 -0
- package/dist/tests/e2e/gui-perf.test.d.ts +23 -0
- package/dist/tests/e2e/gui-perf.test.js +283 -0
- package/dist/tests/e2e/gui-perf.test.js.map +1 -0
- package/dist/tests/e2e/gui-script-import-order.test.js +9 -1
- package/dist/tests/e2e/gui-script-import-order.test.js.map +1 -1
- package/dist/tests/e2e/gui-webgl.test.js +4 -4
- package/dist/tests/e2e/gui-webgl.test.js.map +1 -1
- package/dist/tests/e2e/gui-webgl2-shadow-sampler.test.d.ts +8 -0
- package/dist/tests/e2e/gui-webgl2-shadow-sampler.test.js +336 -0
- package/dist/tests/e2e/gui-webgl2-shadow-sampler.test.js.map +1 -0
- package/dist/tests/extensions/gui.test.js +23 -0
- package/dist/tests/extensions/gui.test.js.map +1 -1
- package/doc/gui/api.md +28 -2
- package/doc/gui/canvas.md +110 -27
- package/doc/gui/known-issues.md +32 -10
- package/doc/gui/rendering.md +77 -0
- package/doc/gui/runtime.md +18 -3
- package/doc/gui/webgl.md +38 -19
- package/doc/gui.md +33 -1
- package/doc/zh-CN/gui/api.md +25 -2
- package/doc/zh-CN/gui/canvas.md +95 -26
- package/doc/zh-CN/gui/known-issues.md +21 -4
- package/doc/zh-CN/gui/rendering.md +59 -0
- package/doc/zh-CN/gui/runtime.md +13 -3
- package/doc/zh-CN/gui/webgl.md +27 -5
- package/doc/zh-CN/gui.md +25 -2
- package/package.json +7 -7
- package/runtime/ext_gui/browser.cpp +3 -1
- package/runtime/ext_gui/canvas.cpp +135 -89
- package/runtime/ext_gui/canvas.h +116 -0
- package/runtime/ext_gui/canvas_clip.cpp +143 -0
- package/runtime/ext_gui/canvas_composite.cpp +241 -0
- package/runtime/ext_gui/canvas_coverage.cpp +241 -0
- package/runtime/ext_gui/canvas_gradient.cpp +41 -4
- package/runtime/ext_gui/canvas_image_data.cpp +4 -0
- package/runtime/ext_gui/canvas_internal.h +34 -9
- package/runtime/ext_gui/canvas_raster.cpp +207 -178
- package/runtime/ext_gui/canvas_shadow.cpp +161 -0
- package/runtime/ext_gui/canvas_stroke.cpp +37 -9
- package/runtime/ext_gui/canvas_style.cpp +59 -0
- package/runtime/ext_gui/canvas_text.cpp +140 -0
- package/runtime/ext_gui/css.h +7 -0
- package/runtime/ext_gui/css_sheet.cpp +22 -0
- package/runtime/ext_gui/document.cpp +25 -1
- package/runtime/ext_gui/document.h +8 -0
- package/runtime/ext_gui/dom_api_canvas.cpp +16 -1
- package/runtime/ext_gui/dom_api_canvas_image.cpp +9 -0
- package/runtime/ext_gui/dom_api_canvas_state.cpp +217 -0
- package/runtime/ext_gui/dom_api_internal.h +36 -37
- package/runtime/ext_gui/dom_api_offscreen.cpp +213 -0
- package/runtime/ext_gui/dom_api_proto.cpp +18 -0
- package/runtime/ext_gui/dom_api_webgl.cpp +19 -9
- package/runtime/ext_gui/dom_api_webgl_internal.h +58 -0
- package/runtime/ext_gui/dom_api_webgl_source.cpp +18 -0
- package/runtime/ext_gui/gradient_values.cpp +12 -1
- package/runtime/ext_gui/gui.cpp +5 -0
- package/runtime/ext_gui/gui_canvas.cpp +4 -0
- package/runtime/ext_gui/gui_engine.h +30 -0
- package/runtime/ext_gui/gui_events.cpp +182 -58
- package/runtime/ext_gui/gui_media.cpp +3 -0
- package/runtime/ext_gui/image.cpp +69 -0
- package/runtime/ext_gui/image_bitmap_browser.cpp +11 -0
- package/runtime/ext_gui/layout.cpp +4 -0
- package/runtime/ext_gui/paint.cpp +19 -0
- package/runtime/ext_gui/paint_background.cpp +18 -1
- package/runtime/ext_gui/perf.cpp +171 -0
- package/runtime/ext_gui/perf.h +127 -0
- package/runtime/ext_gui/renderer.cpp +109 -41
- package/runtime/ext_gui/renderer.h +33 -9
- package/runtime/ext_gui/renderer_image.cpp +135 -65
- package/runtime/ext_gui/renderer_internal.h +15 -3
- package/runtime/ext_gui/renderer_text.cpp +24 -12
- package/runtime/ext_gui/style.cpp +101 -30
- package/runtime/ext_gui/style.h +6 -3
- package/runtime/ext_gui/style_print.cpp +7 -1
- package/runtime/ext_gui/text.cpp +23 -4
- package/runtime/ext_gui/text.h +29 -0
- package/runtime/ext_gui/text_cache.cpp +118 -0
- package/runtime/ext_gui/text_glyph_cache.cpp +100 -0
- package/runtime/ext_gui/webgl.h +48 -146
- package/runtime/ext_gui/webgl_blit.cpp +12 -1
- package/runtime/ext_gui/webgl_blit_depth.cpp +270 -0
- package/runtime/ext_gui/webgl_buffer.cpp +59 -1
- package/runtime/ext_gui/webgl_buffer_objects.cpp +106 -9
- package/runtime/ext_gui/webgl_clear.cpp +3 -0
- package/runtime/ext_gui/webgl_context.cpp +29 -3
- package/runtime/ext_gui/webgl_draw.cpp +75 -270
- package/runtime/ext_gui/webgl_draw_buffers.cpp +1 -0
- package/runtime/ext_gui/webgl_draw_setup.cpp +321 -0
- package/runtime/ext_gui/webgl_draw_state.h +130 -0
- package/runtime/ext_gui/webgl_glsl_scan.cpp +3 -8
- package/runtime/ext_gui/webgl_objects.h +148 -0
- package/runtime/ext_gui/webgl_pipeline.cpp +8 -8
- package/runtime/ext_gui/webgl_program_internal.h +35 -0
- package/runtime/ext_gui/webgl_shader.cpp +22 -30
- package/runtime/ext_gui/webgl_webgl2.cpp +36 -0
- package/runtime/ext_gui/window.cpp +56 -1
- package/src/codegen/generator/module.ts +22 -7
- package/src/driver/version.ts +1 -1
- package/src/extensions/gui/html.ts +9 -2
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* xbintsc GUI engine — the Canvas2D state additions.
|
|
3
|
+
*
|
|
4
|
+
* `globalCompositeOperation`, the four shadow properties, the image-smoothing
|
|
5
|
+
* flags, and the path/clip hit-testing entry points. They live apart from the
|
|
6
|
+
* original style bindings so both translation units stay small.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
#include "dom_api_internal.h"
|
|
10
|
+
|
|
11
|
+
#include <string>
|
|
12
|
+
#include <vector>
|
|
13
|
+
|
|
14
|
+
#include "canvas.h"
|
|
15
|
+
|
|
16
|
+
#define METHOD(name) xt_value name(xt_value self, xt_value env, int32_t argc, xt_value *argv)
|
|
17
|
+
|
|
18
|
+
namespace domapi {
|
|
19
|
+
|
|
20
|
+
namespace {
|
|
21
|
+
|
|
22
|
+
/** Parse a trailing fill-rule argument (`"evenodd"`/`"nonzero"`). */
|
|
23
|
+
bool fill_rule_arg(xt_value value, bool *even_odd) {
|
|
24
|
+
if (!XT_IS_STRING(value)) return false;
|
|
25
|
+
const std::string rule = to_string_value(value);
|
|
26
|
+
if (rule == "evenodd") {
|
|
27
|
+
*even_odd = true;
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
if (rule == "nonzero") {
|
|
31
|
+
*even_odd = false;
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
} // namespace
|
|
38
|
+
|
|
39
|
+
METHOD(canvas_global_composite_get) {
|
|
40
|
+
(void)env;
|
|
41
|
+
(void)argc;
|
|
42
|
+
(void)argv;
|
|
43
|
+
xtgui::Canvas2D *canvas = canvas_from_context(self);
|
|
44
|
+
return xt_string_from_cstr(canvas != nullptr ? canvas->global_composite_operation().c_str()
|
|
45
|
+
: "source-over");
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
METHOD(canvas_global_composite_set) {
|
|
49
|
+
(void)env;
|
|
50
|
+
xtgui::Canvas2D *canvas = canvas_from_context(self);
|
|
51
|
+
if (canvas != nullptr) canvas->set_global_composite_operation(canvas_string_arg(argc, argv, 0));
|
|
52
|
+
return XT_UNDEFINED;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
METHOD(canvas_shadow_color_get) {
|
|
56
|
+
(void)env;
|
|
57
|
+
(void)argc;
|
|
58
|
+
(void)argv;
|
|
59
|
+
xtgui::Canvas2D *canvas = canvas_from_context(self);
|
|
60
|
+
return xt_string_from_cstr(canvas != nullptr ? canvas->shadow_color().c_str()
|
|
61
|
+
: "rgba(0, 0, 0, 0)");
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
METHOD(canvas_shadow_color_set) {
|
|
65
|
+
(void)env;
|
|
66
|
+
xtgui::Canvas2D *canvas = canvas_from_context(self);
|
|
67
|
+
if (canvas != nullptr) canvas->set_shadow_color(canvas_string_arg(argc, argv, 0));
|
|
68
|
+
return XT_UNDEFINED;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
METHOD(canvas_shadow_blur_get) {
|
|
72
|
+
(void)env;
|
|
73
|
+
(void)argc;
|
|
74
|
+
(void)argv;
|
|
75
|
+
xtgui::Canvas2D *canvas = canvas_from_context(self);
|
|
76
|
+
return xt_number(canvas != nullptr ? canvas->shadow_blur() : 0.0);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
METHOD(canvas_shadow_blur_set) {
|
|
80
|
+
(void)env;
|
|
81
|
+
xtgui::Canvas2D *canvas = canvas_from_context(self);
|
|
82
|
+
if (canvas != nullptr) canvas->set_shadow_blur((float)canvas_number_arg(argc, argv, 0, 0.0));
|
|
83
|
+
return XT_UNDEFINED;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
METHOD(canvas_shadow_offset_x_get) {
|
|
87
|
+
(void)env;
|
|
88
|
+
(void)argc;
|
|
89
|
+
(void)argv;
|
|
90
|
+
xtgui::Canvas2D *canvas = canvas_from_context(self);
|
|
91
|
+
return xt_number(canvas != nullptr ? canvas->shadow_offset_x() : 0.0);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
METHOD(canvas_shadow_offset_x_set) {
|
|
95
|
+
(void)env;
|
|
96
|
+
xtgui::Canvas2D *canvas = canvas_from_context(self);
|
|
97
|
+
if (canvas != nullptr) canvas->set_shadow_offset_x((float)canvas_number_arg(argc, argv, 0, 0.0));
|
|
98
|
+
return XT_UNDEFINED;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
METHOD(canvas_shadow_offset_y_get) {
|
|
102
|
+
(void)env;
|
|
103
|
+
(void)argc;
|
|
104
|
+
(void)argv;
|
|
105
|
+
xtgui::Canvas2D *canvas = canvas_from_context(self);
|
|
106
|
+
return xt_number(canvas != nullptr ? canvas->shadow_offset_y() : 0.0);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
METHOD(canvas_shadow_offset_y_set) {
|
|
110
|
+
(void)env;
|
|
111
|
+
xtgui::Canvas2D *canvas = canvas_from_context(self);
|
|
112
|
+
if (canvas != nullptr) canvas->set_shadow_offset_y((float)canvas_number_arg(argc, argv, 0, 0.0));
|
|
113
|
+
return XT_UNDEFINED;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
METHOD(canvas_image_smoothing_enabled_get) {
|
|
117
|
+
(void)env;
|
|
118
|
+
(void)argc;
|
|
119
|
+
(void)argv;
|
|
120
|
+
xtgui::Canvas2D *canvas = canvas_from_context(self);
|
|
121
|
+
return xt_bool(canvas == nullptr || canvas->image_smoothing_enabled());
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
METHOD(canvas_image_smoothing_enabled_set) {
|
|
125
|
+
(void)env;
|
|
126
|
+
xtgui::Canvas2D *canvas = canvas_from_context(self);
|
|
127
|
+
if (canvas != nullptr) {
|
|
128
|
+
canvas->set_image_smoothing_enabled(value_truthy(xt_arg(argc, argv, 0)));
|
|
129
|
+
}
|
|
130
|
+
return XT_UNDEFINED;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
METHOD(canvas_image_smoothing_quality_get) {
|
|
134
|
+
(void)env;
|
|
135
|
+
(void)argc;
|
|
136
|
+
(void)argv;
|
|
137
|
+
xtgui::Canvas2D *canvas = canvas_from_context(self);
|
|
138
|
+
return xt_string_from_cstr(canvas != nullptr ? canvas->image_smoothing_quality().c_str()
|
|
139
|
+
: "low");
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
METHOD(canvas_image_smoothing_quality_set) {
|
|
143
|
+
(void)env;
|
|
144
|
+
xtgui::Canvas2D *canvas = canvas_from_context(self);
|
|
145
|
+
if (canvas != nullptr) canvas->set_image_smoothing_quality(canvas_string_arg(argc, argv, 0));
|
|
146
|
+
return XT_UNDEFINED;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
METHOD(canvas_clip) {
|
|
150
|
+
(void)env;
|
|
151
|
+
xtgui::Canvas2D *canvas = canvas_from_context(self);
|
|
152
|
+
if (canvas == nullptr) return XT_UNDEFINED;
|
|
153
|
+
bool even_odd = false;
|
|
154
|
+
bool has_path = false;
|
|
155
|
+
std::vector<xtgui::CanvasSubpath> path;
|
|
156
|
+
for (int32_t i = 0; i < argc; i++) {
|
|
157
|
+
xt_value value = xt_arg(argc, argv, i);
|
|
158
|
+
bool rule = false;
|
|
159
|
+
if (fill_rule_arg(value, &rule)) {
|
|
160
|
+
even_odd = rule;
|
|
161
|
+
} else if (path2d_is(value)) {
|
|
162
|
+
path = path2d_subpaths(value);
|
|
163
|
+
has_path = true;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (has_path) {
|
|
167
|
+
canvas->clip_paths(path, even_odd);
|
|
168
|
+
} else {
|
|
169
|
+
canvas->clip(even_odd);
|
|
170
|
+
}
|
|
171
|
+
return XT_UNDEFINED;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
METHOD(canvas_is_point_in_path) {
|
|
175
|
+
(void)env;
|
|
176
|
+
xtgui::Canvas2D *canvas = canvas_from_context(self);
|
|
177
|
+
if (canvas == nullptr || argc == 0) return XT_FALSE;
|
|
178
|
+
int32_t index = 0;
|
|
179
|
+
std::vector<xtgui::CanvasSubpath> path;
|
|
180
|
+
bool has_path = false;
|
|
181
|
+
if (path2d_is(xt_arg(argc, argv, 0))) {
|
|
182
|
+
path = path2d_subpaths(xt_arg(argc, argv, 0));
|
|
183
|
+
has_path = true;
|
|
184
|
+
index = 1;
|
|
185
|
+
}
|
|
186
|
+
const float x = (float)canvas_number_arg(argc, argv, index, 0.0);
|
|
187
|
+
const float y = (float)canvas_number_arg(argc, argv, index + 1, 0.0);
|
|
188
|
+
bool even_odd = false;
|
|
189
|
+
for (int32_t i = index + 2; i < argc; i++) fill_rule_arg(xt_arg(argc, argv, i), &even_odd);
|
|
190
|
+
const bool inside =
|
|
191
|
+
has_path ? canvas->is_point_in_paths(path, x, y, even_odd)
|
|
192
|
+
: canvas->is_point_in_path(x, y, even_odd);
|
|
193
|
+
return xt_bool(inside);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
METHOD(canvas_is_point_in_stroke) {
|
|
197
|
+
(void)env;
|
|
198
|
+
xtgui::Canvas2D *canvas = canvas_from_context(self);
|
|
199
|
+
if (canvas == nullptr || argc == 0) return XT_FALSE;
|
|
200
|
+
int32_t index = 0;
|
|
201
|
+
std::vector<xtgui::CanvasSubpath> path;
|
|
202
|
+
bool has_path = false;
|
|
203
|
+
if (path2d_is(xt_arg(argc, argv, 0))) {
|
|
204
|
+
path = path2d_subpaths(xt_arg(argc, argv, 0));
|
|
205
|
+
has_path = true;
|
|
206
|
+
index = 1;
|
|
207
|
+
}
|
|
208
|
+
const float x = (float)canvas_number_arg(argc, argv, index, 0.0);
|
|
209
|
+
const float y = (float)canvas_number_arg(argc, argv, index + 1, 0.0);
|
|
210
|
+
const bool inside =
|
|
211
|
+
has_path ? canvas->is_point_in_stroke_paths(path, x, y) : canvas->is_point_in_stroke(x, y);
|
|
212
|
+
return xt_bool(inside);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
} // namespace domapi
|
|
216
|
+
|
|
217
|
+
#undef METHOD
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
#include <vector>
|
|
18
18
|
|
|
19
19
|
#include "gui_engine.h"
|
|
20
|
+
#include "dom_api_webgl_internal.h"
|
|
20
21
|
|
|
21
22
|
namespace domapi {
|
|
22
23
|
|
|
@@ -52,6 +53,23 @@ xt_value class_list_proto();
|
|
|
52
53
|
xt_value style_proto();
|
|
53
54
|
xt_value computed_style_proto();
|
|
54
55
|
xt_value canvas_proto();
|
|
56
|
+
/** The `getContextAttributes()` object for a freshly created 2D context. */
|
|
57
|
+
xt_value canvas_context_attributes(xt_value requested, bool alpha);
|
|
58
|
+
/** `OffscreenCanvas.prototype`. */
|
|
59
|
+
xt_value offscreen_canvas_proto();
|
|
60
|
+
/** `new OffscreenCanvas(width, height)`. */
|
|
61
|
+
xt_value offscreen_canvas_create(int32_t argc, xt_value *argv);
|
|
62
|
+
/** `canvas.transferControlToOffscreen()`. */
|
|
63
|
+
xt_value canvas_transfer_control_to_offscreen(xt_value self, xt_value env, int32_t argc,
|
|
64
|
+
xt_value *argv);
|
|
65
|
+
xt_value offscreen_get_context(xt_value self, xt_value env, int32_t argc, xt_value *argv);
|
|
66
|
+
xt_value offscreen_width_get(xt_value self, xt_value env, int32_t argc, xt_value *argv);
|
|
67
|
+
xt_value offscreen_width_set(xt_value self, xt_value env, int32_t argc, xt_value *argv);
|
|
68
|
+
xt_value offscreen_height_get(xt_value self, xt_value env, int32_t argc, xt_value *argv);
|
|
69
|
+
xt_value offscreen_height_set(xt_value self, xt_value env, int32_t argc, xt_value *argv);
|
|
70
|
+
xt_value offscreen_transfer_to_image_bitmap(xt_value self, xt_value env, int32_t argc,
|
|
71
|
+
xt_value *argv);
|
|
72
|
+
xt_value offscreen_convert_to_blob(xt_value self, xt_value env, int32_t argc, xt_value *argv);
|
|
55
73
|
xt_value canvas_gradient_proto();
|
|
56
74
|
xt_value webgl_proto();
|
|
57
75
|
xt_value webgl2_proto();
|
|
@@ -91,43 +109,7 @@ xt_value canvas_gradient_handle(xt_value context, const xtgui::Canvas2D *canvas,
|
|
|
91
109
|
uint64_t canvas_gradient_id(xt_value handle, const xtgui::Canvas2D *canvas);
|
|
92
110
|
|
|
93
111
|
/* -- WebGL helpers shared by `dom_api_webgl*.cpp` ------------------------- */
|
|
94
|
-
|
|
95
|
-
/** The engine WebGL context behind a context handle, or null. */
|
|
96
|
-
xtgui::WebGLContext *webgl_from_context(xt_value self);
|
|
97
|
-
/** Like `webgl_from_context`, but null while the context is lost: every GL
|
|
98
|
-
* entry point except `getError`/`isContextLost` is a no-op in that state. */
|
|
99
|
-
xtgui::WebGLContext *webgl_live_context(xt_value self);
|
|
100
|
-
/** The numeric context id stored on a context handle (0 when absent). */
|
|
101
|
-
uint64_t webgl_context_id(xt_value self);
|
|
102
|
-
/** Create the JavaScript handle for a canvas's WebGL context. */
|
|
103
|
-
xt_value webgl_context_handle(xt_value element, xtgui::WebGLContext *context);
|
|
104
|
-
/** The id stored on an object handle under `key`, or 0. */
|
|
105
|
-
uint32_t webgl_object_id(xt_value handle, const char *key);
|
|
106
|
-
/** Build an object handle (`{__xt_gl_context, __xt_gl_<key>}`). */
|
|
107
|
-
xt_value webgl_make_object(xt_value context, const char *key, uint32_t id,
|
|
108
|
-
const std::string &kind);
|
|
109
|
-
double webgl_number(int32_t argc, xt_value *argv, int32_t index, double fallback);
|
|
110
|
-
int webgl_int(int32_t argc, xt_value *argv, int32_t index, int fallback);
|
|
111
|
-
std::string webgl_string(int32_t argc, xt_value *argv, int32_t index);
|
|
112
|
-
/** Read an array/typed array of numbers. */
|
|
113
|
-
std::vector<double> webgl_numbers(xt_value value);
|
|
114
|
-
/** Read the raw bytes of a typed array / ArrayBuffer (or a byte array). */
|
|
115
|
-
std::vector<uint8_t> webgl_bytes(xt_value value);
|
|
116
|
-
/** Store `count` bytes into a typed array / array handle. */
|
|
117
|
-
void webgl_write_bytes(xt_value target, const uint8_t *bytes, size_t count);
|
|
118
|
-
/** Convert a source pixel array (RGBA/RGB/LUMINANCE/…) to RGBA8. */
|
|
119
|
-
void webgl_convert_pixels(const uint8_t *source, int count, int format, bool premultiply,
|
|
120
|
-
std::vector<uint8_t> *out);
|
|
121
|
-
/** Decode a `texImage2D` source (`<img>`, `<canvas>`, `<video>`, `ImageData`,
|
|
122
|
-
* `ImageBitmap`) into top-down RGBA8. */
|
|
123
|
-
bool webgl_read_source(xt_value source, int *width, int *height,
|
|
124
|
-
std::vector<uint8_t> *rgba, bool premultiply);
|
|
125
|
-
/** Read the `UNPACK_FLIP_Y_WEBGL` / `UNPACK_PREMULTIPLY_ALPHA_WEBGL` flags set
|
|
126
|
-
* through `pixelStorei`. */
|
|
127
|
-
void webgl_unpack_flags(xt_value context, bool *flip_y, bool *premultiply);
|
|
128
|
-
/** Extension object for a compressed-texture family (null when unsupported,
|
|
129
|
-
* undefined when the name is not one of those extensions). */
|
|
130
|
-
xt_value webgl_compressed_extension(const std::string &name, xtgui::WebGLContext *context);
|
|
112
|
+
/* Declared in `dom_api_webgl_internal.h`, included above. */
|
|
131
113
|
|
|
132
114
|
/** How a pending handle names the node it will bind to. */
|
|
133
115
|
enum PendingKind { pending_by_id = 1, pending_by_selector = 2 };
|
|
@@ -285,6 +267,23 @@ METHOD(canvas_line_width_get);
|
|
|
285
267
|
METHOD(canvas_line_width_set);
|
|
286
268
|
METHOD(canvas_global_alpha_get);
|
|
287
269
|
METHOD(canvas_global_alpha_set);
|
|
270
|
+
METHOD(canvas_global_composite_get);
|
|
271
|
+
METHOD(canvas_global_composite_set);
|
|
272
|
+
METHOD(canvas_shadow_color_get);
|
|
273
|
+
METHOD(canvas_shadow_color_set);
|
|
274
|
+
METHOD(canvas_shadow_blur_get);
|
|
275
|
+
METHOD(canvas_shadow_blur_set);
|
|
276
|
+
METHOD(canvas_shadow_offset_x_get);
|
|
277
|
+
METHOD(canvas_shadow_offset_x_set);
|
|
278
|
+
METHOD(canvas_shadow_offset_y_get);
|
|
279
|
+
METHOD(canvas_shadow_offset_y_set);
|
|
280
|
+
METHOD(canvas_image_smoothing_enabled_get);
|
|
281
|
+
METHOD(canvas_image_smoothing_enabled_set);
|
|
282
|
+
METHOD(canvas_image_smoothing_quality_get);
|
|
283
|
+
METHOD(canvas_image_smoothing_quality_set);
|
|
284
|
+
METHOD(canvas_clip);
|
|
285
|
+
METHOD(canvas_is_point_in_path);
|
|
286
|
+
METHOD(canvas_is_point_in_stroke);
|
|
288
287
|
METHOD(canvas_font_get);
|
|
289
288
|
METHOD(canvas_font_set);
|
|
290
289
|
METHOD(canvas_text_align_get);
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* xbintsc GUI engine — `OffscreenCanvas`.
|
|
3
|
+
*
|
|
4
|
+
* An offscreen canvas is a `Canvas2D` bitmap with no DOM element behind it. It
|
|
5
|
+
* is created either by `new OffscreenCanvas(w, h)` or by transferring a live
|
|
6
|
+
* `<canvas>` element (`transferControlToOffscreen`), in which case the element
|
|
7
|
+
* keeps its bitmap and only the context ownership moves.
|
|
8
|
+
*
|
|
9
|
+
* Ownership stays with the window (`offscreen_canvases`), like every other
|
|
10
|
+
* canvas; the process-wide id table makes the bitmap reachable from
|
|
11
|
+
* `drawImage`/`createPattern`/`texImage2D` without a DOM node.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
#include "dom_api_internal.h"
|
|
15
|
+
|
|
16
|
+
#include <string>
|
|
17
|
+
#include <vector>
|
|
18
|
+
|
|
19
|
+
#include "canvas.h"
|
|
20
|
+
#include "gui_engine.h"
|
|
21
|
+
#include "image_bitmap.h"
|
|
22
|
+
|
|
23
|
+
#define METHOD(name) xt_value name(xt_value self, xt_value env, int32_t argc, xt_value *argv)
|
|
24
|
+
|
|
25
|
+
namespace domapi {
|
|
26
|
+
|
|
27
|
+
namespace {
|
|
28
|
+
|
|
29
|
+
xtgui::Canvas2D *offscreen_canvas(xt_value self) {
|
|
30
|
+
xt_value id = xt_object_get_cstr(self, "__xt_gui_canvas");
|
|
31
|
+
if (!XT_IS_NUMBER(id)) return nullptr;
|
|
32
|
+
return xtgui::xt_canvas_by_id((uint64_t)xt_to_number(id));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
xt_value make_offscreen(xtgui::Canvas2D *canvas, xt_value window) {
|
|
36
|
+
xt_value handle = xt_object_new_with_proto(offscreen_canvas_proto());
|
|
37
|
+
xt_object_set(handle, xt_string_from_cstr("__xt_gui_canvas"), xt_number((double)canvas->id()));
|
|
38
|
+
xt_object_set(handle, xt_string_from_cstr("__xt_gui_window"), window);
|
|
39
|
+
xt_object_set(handle, xt_string_from_cstr("__xt_gui_offscreen"), XT_TRUE);
|
|
40
|
+
/* `ctx.canvas` of an offscreen context returns the offscreen object. */
|
|
41
|
+
xt_object_set(handle, xt_string_from_cstr("__xt_gui_node"), handle);
|
|
42
|
+
return handle;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
xt_value image_bitmap_handle(const xtgui::Image &image) {
|
|
46
|
+
const uint64_t id = xtgui::xt_image_bitmap_add(image);
|
|
47
|
+
xt_value name = xt_string_from_cstr("ImageBitmap");
|
|
48
|
+
xt_value constructor = xt_browser_type(1, &name);
|
|
49
|
+
xt_value prototype = xt_object_get_cstr(constructor, "prototype");
|
|
50
|
+
xt_value bitmap = XT_IS_OBJECT(prototype) ? xt_object_new_with_proto(prototype)
|
|
51
|
+
: xt_object_new();
|
|
52
|
+
xt_object_set(bitmap, xt_string_from_cstr("width"), xt_number(image.width));
|
|
53
|
+
xt_object_set(bitmap, xt_string_from_cstr("height"), xt_number(image.height));
|
|
54
|
+
xt_object_set(bitmap, xt_string_from_cstr("__xt_bitmap"), xt_number((double)id));
|
|
55
|
+
return bitmap;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
} // namespace
|
|
59
|
+
|
|
60
|
+
xt_value offscreen_canvas_proto() {
|
|
61
|
+
static xt_value proto = XT_UNDEFINED;
|
|
62
|
+
if (XT_IS_OBJECT(proto)) return proto;
|
|
63
|
+
proto = xt_object_new();
|
|
64
|
+
xt_gc_add_root(&proto);
|
|
65
|
+
struct Entry {
|
|
66
|
+
const char *name;
|
|
67
|
+
void *getter;
|
|
68
|
+
void *setter;
|
|
69
|
+
};
|
|
70
|
+
const Entry properties[] = {
|
|
71
|
+
{"width", (void *)offscreen_width_get, (void *)offscreen_width_set},
|
|
72
|
+
{"height", (void *)offscreen_height_get, (void *)offscreen_height_set},
|
|
73
|
+
};
|
|
74
|
+
for (const Entry &property : properties) {
|
|
75
|
+
xt_object_define_getter(proto, xt_string_from_cstr(property.name),
|
|
76
|
+
xt_closure_new(property.getter, 0, nullptr));
|
|
77
|
+
xt_object_define_setter(proto, xt_string_from_cstr(property.name),
|
|
78
|
+
xt_closure_new(property.setter, 0, nullptr));
|
|
79
|
+
}
|
|
80
|
+
struct Method {
|
|
81
|
+
const char *name;
|
|
82
|
+
void *fn;
|
|
83
|
+
};
|
|
84
|
+
const Method methods[] = {
|
|
85
|
+
{"getContext", (void *)offscreen_get_context},
|
|
86
|
+
{"transferToImageBitmap", (void *)offscreen_transfer_to_image_bitmap},
|
|
87
|
+
{"convertToBlob", (void *)offscreen_convert_to_blob},
|
|
88
|
+
};
|
|
89
|
+
for (const Method &method : methods) {
|
|
90
|
+
xt_object_set(proto, xt_string_from_cstr(method.name),
|
|
91
|
+
xt_closure_new(method.fn, 0, nullptr));
|
|
92
|
+
}
|
|
93
|
+
return proto;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
xt_value offscreen_canvas_create(int32_t argc, xt_value *argv) {
|
|
97
|
+
xt_value window = xt_gui_ensure_window();
|
|
98
|
+
XtGuiWindow *win = xt_gui_window_from_this(window);
|
|
99
|
+
if (win == nullptr) return XT_NULL;
|
|
100
|
+
int width = argc >= 1 ? (int)xt_to_number(xt_arg(argc, argv, 0)) : 300;
|
|
101
|
+
int height = argc >= 2 ? (int)xt_to_number(xt_arg(argc, argv, 1)) : 150;
|
|
102
|
+
if (width < 1) width = 1;
|
|
103
|
+
if (height < 1) height = 1;
|
|
104
|
+
auto canvas = std::make_unique<xtgui::Canvas2D>(width, height);
|
|
105
|
+
xtgui::Canvas2D *raw = canvas.get();
|
|
106
|
+
win->offscreen_canvases[raw->id()] = std::move(canvas);
|
|
107
|
+
return make_offscreen(raw, window);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
METHOD(offscreen_width_get) {
|
|
111
|
+
(void)env;
|
|
112
|
+
(void)argc;
|
|
113
|
+
(void)argv;
|
|
114
|
+
xtgui::Canvas2D *canvas = offscreen_canvas(self);
|
|
115
|
+
return xt_number(canvas != nullptr ? canvas->width() : 0);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
METHOD(offscreen_width_set) {
|
|
119
|
+
(void)env;
|
|
120
|
+
xtgui::Canvas2D *canvas = offscreen_canvas(self);
|
|
121
|
+
if (canvas != nullptr) canvas->resize((int)canvas_number_arg(argc, argv, 0, 0.0), canvas->height());
|
|
122
|
+
return XT_UNDEFINED;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
METHOD(offscreen_height_get) {
|
|
126
|
+
(void)env;
|
|
127
|
+
(void)argc;
|
|
128
|
+
(void)argv;
|
|
129
|
+
xtgui::Canvas2D *canvas = offscreen_canvas(self);
|
|
130
|
+
return xt_number(canvas != nullptr ? canvas->height() : 0);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
METHOD(offscreen_height_set) {
|
|
134
|
+
(void)env;
|
|
135
|
+
xtgui::Canvas2D *canvas = offscreen_canvas(self);
|
|
136
|
+
if (canvas != nullptr) canvas->resize(canvas->width(), (int)canvas_number_arg(argc, argv, 0, 0.0));
|
|
137
|
+
return XT_UNDEFINED;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
METHOD(offscreen_get_context) {
|
|
141
|
+
(void)env;
|
|
142
|
+
xtgui::Canvas2D *canvas = offscreen_canvas(self);
|
|
143
|
+
if (canvas == nullptr) return XT_NULL;
|
|
144
|
+
const std::string mode = canvas_string_arg(argc, argv, 0);
|
|
145
|
+
/* The GPU context needs a DOM node for its texture table; the 2D bitmap does
|
|
146
|
+
* not, so only "2d" resolves here. */
|
|
147
|
+
if (mode != "2d") return XT_NULL;
|
|
148
|
+
xt_value cached = xt_object_get_cstr(self, "__xt_gui_ctx");
|
|
149
|
+
if (XT_IS_OBJECT(cached)) return cached;
|
|
150
|
+
xt_value attributes = xt_arg(argc, argv, 1);
|
|
151
|
+
bool alpha = true;
|
|
152
|
+
if (XT_IS_OBJECT(attributes)) {
|
|
153
|
+
xt_value value = xt_object_get_cstr(attributes, "alpha");
|
|
154
|
+
if (XT_IS_BOOL(value)) alpha = value_truthy(value);
|
|
155
|
+
}
|
|
156
|
+
canvas->set_alpha(alpha);
|
|
157
|
+
xt_value context = xt_object_new_with_proto(canvas_proto());
|
|
158
|
+
xt_object_set(context, xt_string_from_cstr("__xt_gui_canvas"), xt_number((double)canvas->id()));
|
|
159
|
+
xt_object_set(context, xt_string_from_cstr("__xt_gui_node"), self);
|
|
160
|
+
xt_object_set(context, xt_string_from_cstr("__xt_gui_ctx_attributes"),
|
|
161
|
+
canvas_context_attributes(attributes, alpha));
|
|
162
|
+
xt_object_set(self, xt_string_from_cstr("__xt_gui_ctx"), context);
|
|
163
|
+
return context;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
METHOD(offscreen_transfer_to_image_bitmap) {
|
|
167
|
+
(void)env;
|
|
168
|
+
(void)argc;
|
|
169
|
+
(void)argv;
|
|
170
|
+
xtgui::Canvas2D *canvas = offscreen_canvas(self);
|
|
171
|
+
if (canvas == nullptr || canvas->image().width <= 0) return XT_NULL;
|
|
172
|
+
return image_bitmap_handle(canvas->image());
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
METHOD(offscreen_convert_to_blob) {
|
|
176
|
+
(void)env;
|
|
177
|
+
(void)argc;
|
|
178
|
+
(void)argv;
|
|
179
|
+
xtgui::Canvas2D *canvas = offscreen_canvas(self);
|
|
180
|
+
if (canvas == nullptr) return xt_promise_reject(xt_string_from_cstr("InvalidStateError"));
|
|
181
|
+
std::vector<unsigned char> png;
|
|
182
|
+
if (!canvas->encode_png(&png)) return xt_promise_reject(xt_string_from_cstr("InvalidStateError"));
|
|
183
|
+
xt_value data = xt_array_new(0, nullptr);
|
|
184
|
+
for (unsigned char byte : png) xt_array_push(data, xt_number((double)byte));
|
|
185
|
+
xt_value blob = xt_object_new();
|
|
186
|
+
xt_object_set(blob, xt_string_from_cstr("type"), xt_string_from_cstr("image/png"));
|
|
187
|
+
xt_object_set(blob, xt_string_from_cstr("size"), xt_number((double)png.size()));
|
|
188
|
+
xt_object_set(blob, xt_string_from_cstr("__xt_gui_blob_data"), data);
|
|
189
|
+
return xt_promise_resolve(blob);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
METHOD(canvas_transfer_control_to_offscreen) {
|
|
193
|
+
(void)env;
|
|
194
|
+
(void)argc;
|
|
195
|
+
(void)argv;
|
|
196
|
+
xt_value existing = xt_object_get_cstr(self, "__xt_gui_offscreen");
|
|
197
|
+
if (XT_IS_OBJECT(existing)) return existing;
|
|
198
|
+
XtGuiWindow *win = nullptr;
|
|
199
|
+
xtgui::Node *node = resolve_node(self, &win);
|
|
200
|
+
if (win == nullptr || node == nullptr || !node->isElement() || !node->isTag("canvas")) {
|
|
201
|
+
return XT_NULL;
|
|
202
|
+
}
|
|
203
|
+
if (xt_gui_webgl_find(win, node) != nullptr) return XT_NULL;
|
|
204
|
+
xtgui::Canvas2D *canvas = xt_gui_canvas_get(win, node);
|
|
205
|
+
if (canvas == nullptr) return XT_NULL;
|
|
206
|
+
xt_value handle = make_offscreen(canvas, win->object);
|
|
207
|
+
xt_object_set(self, xt_string_from_cstr("__xt_gui_offscreen"), handle);
|
|
208
|
+
return handle;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
} // namespace domapi
|
|
212
|
+
|
|
213
|
+
#undef METHOD
|
|
@@ -111,6 +111,7 @@ xt_value node_proto() {
|
|
|
111
111
|
define_method(proto, "pause", (void *)node_pause);
|
|
112
112
|
define_method(proto, "load", (void *)node_load);
|
|
113
113
|
define_method(proto, "getContext", (void *)node_get_context);
|
|
114
|
+
define_method(proto, "transferControlToOffscreen", (void *)canvas_transfer_control_to_offscreen);
|
|
114
115
|
/* `toDataURL`/`toBlob` belong to the canvas *element*, as in the DOM. */
|
|
115
116
|
define_method(proto, "toDataURL", (void *)canvas_to_data_url);
|
|
116
117
|
define_method(proto, "toBlob", (void *)canvas_to_blob);
|
|
@@ -210,6 +211,20 @@ xt_value canvas_proto() {
|
|
|
210
211
|
define_setter(proto, "lineWidth", (void *)canvas_line_width_set);
|
|
211
212
|
define_getter(proto, "globalAlpha", (void *)canvas_global_alpha_get);
|
|
212
213
|
define_setter(proto, "globalAlpha", (void *)canvas_global_alpha_set);
|
|
214
|
+
define_getter(proto, "globalCompositeOperation", (void *)canvas_global_composite_get);
|
|
215
|
+
define_setter(proto, "globalCompositeOperation", (void *)canvas_global_composite_set);
|
|
216
|
+
define_getter(proto, "shadowColor", (void *)canvas_shadow_color_get);
|
|
217
|
+
define_setter(proto, "shadowColor", (void *)canvas_shadow_color_set);
|
|
218
|
+
define_getter(proto, "shadowBlur", (void *)canvas_shadow_blur_get);
|
|
219
|
+
define_setter(proto, "shadowBlur", (void *)canvas_shadow_blur_set);
|
|
220
|
+
define_getter(proto, "shadowOffsetX", (void *)canvas_shadow_offset_x_get);
|
|
221
|
+
define_setter(proto, "shadowOffsetX", (void *)canvas_shadow_offset_x_set);
|
|
222
|
+
define_getter(proto, "shadowOffsetY", (void *)canvas_shadow_offset_y_get);
|
|
223
|
+
define_setter(proto, "shadowOffsetY", (void *)canvas_shadow_offset_y_set);
|
|
224
|
+
define_getter(proto, "imageSmoothingEnabled", (void *)canvas_image_smoothing_enabled_get);
|
|
225
|
+
define_setter(proto, "imageSmoothingEnabled", (void *)canvas_image_smoothing_enabled_set);
|
|
226
|
+
define_getter(proto, "imageSmoothingQuality", (void *)canvas_image_smoothing_quality_get);
|
|
227
|
+
define_setter(proto, "imageSmoothingQuality", (void *)canvas_image_smoothing_quality_set);
|
|
213
228
|
define_getter(proto, "font", (void *)canvas_font_get);
|
|
214
229
|
define_setter(proto, "font", (void *)canvas_font_set);
|
|
215
230
|
define_getter(proto, "textAlign", (void *)canvas_text_align_get);
|
|
@@ -245,6 +260,9 @@ xt_value canvas_proto() {
|
|
|
245
260
|
define_method(proto, "bezierCurveTo", (void *)canvas_bezier_curve_to);
|
|
246
261
|
define_method(proto, "fill", (void *)canvas_fill);
|
|
247
262
|
define_method(proto, "stroke", (void *)canvas_stroke);
|
|
263
|
+
define_method(proto, "clip", (void *)canvas_clip);
|
|
264
|
+
define_method(proto, "isPointInPath", (void *)canvas_is_point_in_path);
|
|
265
|
+
define_method(proto, "isPointInStroke", (void *)canvas_is_point_in_stroke);
|
|
248
266
|
define_method(proto, "clearRect", (void *)canvas_clear_rect);
|
|
249
267
|
define_method(proto, "fillRect", (void *)canvas_fill_rect);
|
|
250
268
|
define_method(proto, "strokeRect", (void *)canvas_stroke_rect);
|
|
@@ -331,15 +331,17 @@ std::vector<uint8_t> webgl_bytes(xt_value value) {
|
|
|
331
331
|
const double length = xt_to_number(xt_get(value, xt_string_from_cstr("byteLength")));
|
|
332
332
|
if (!(length > 0.0) || !xt_is_array_buffer(buffer)) return out;
|
|
333
333
|
out.resize((size_t)length);
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
334
|
+
/* The runtime stores an ArrayBuffer as one byte value per array slot, so
|
|
335
|
+
* this is still an element loop — but one call into the runtime instead of
|
|
336
|
+
* one extern call per byte, which is what a multi-megabyte vertex buffer or
|
|
337
|
+
* `texImage2D` pays for. */
|
|
338
|
+
out.resize(xt_array_buffer_copy_bytes_out(buffer, offset, out.data(), (uint32_t)length));
|
|
337
339
|
return out;
|
|
338
340
|
}
|
|
339
341
|
if (xt_is_array_buffer(value)) {
|
|
340
342
|
const uint32_t length = xt_array_buffer_byte_length(value);
|
|
341
343
|
out.resize(length);
|
|
342
|
-
|
|
344
|
+
out.resize(xt_array_buffer_copy_bytes_out(value, 0, out.data(), length));
|
|
343
345
|
return out;
|
|
344
346
|
}
|
|
345
347
|
const std::vector<double> numbers = webgl_numbers(value);
|
|
@@ -356,13 +358,21 @@ std::vector<uint8_t> webgl_bytes(xt_value value) {
|
|
|
356
358
|
void webgl_write_bytes(xt_value target, const uint8_t *bytes, size_t count) {
|
|
357
359
|
if (!XT_IS_OBJECT(target) || bytes == nullptr) return;
|
|
358
360
|
const int kind = xt_typed_array_kind_of(target);
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
361
|
+
if (kind >= 0) {
|
|
362
|
+
xt_value buffer = xt_typed_array_buffer_of(target);
|
|
363
|
+
const uint32_t offset = xt_typed_array_byte_offset_of(target);
|
|
364
|
+
if (xt_is_array_buffer(buffer)) {
|
|
365
|
+
xt_array_buffer_copy_bytes_in(buffer, offset, bytes, (uint32_t)count);
|
|
366
|
+
return;
|
|
364
367
|
}
|
|
365
368
|
}
|
|
369
|
+
if (xt_is_array_buffer(target)) {
|
|
370
|
+
xt_array_buffer_copy_bytes_in(target, 0, bytes, (uint32_t)count);
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
for (size_t i = 0; i < count; i++) {
|
|
374
|
+
xt_set(target, xt_number((double)i), xt_number((double)bytes[i]));
|
|
375
|
+
}
|
|
366
376
|
}
|
|
367
377
|
|
|
368
378
|
/* -- context handle members ---------------------------------------------- */
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* xbintsc GUI engine — helpers shared by the WebGL DOM bindings.
|
|
3
|
+
*
|
|
4
|
+
* Split out of `dom_api_internal.h` to keep that header under the repository's
|
|
5
|
+
* file-length budget; `dom_api_internal.h` includes this file, so every WebGL
|
|
6
|
+
* binding sees the same declarations.
|
|
7
|
+
*/
|
|
8
|
+
#ifndef XT_GUI_DOM_API_WEBGL_INTERNAL_H
|
|
9
|
+
#define XT_GUI_DOM_API_WEBGL_INTERNAL_H
|
|
10
|
+
|
|
11
|
+
#include <cstdint>
|
|
12
|
+
#include <string>
|
|
13
|
+
#include <vector>
|
|
14
|
+
|
|
15
|
+
#include "gui_engine.h"
|
|
16
|
+
|
|
17
|
+
namespace domapi {
|
|
18
|
+
|
|
19
|
+
/** The engine WebGL context behind a context handle, or null. */
|
|
20
|
+
xtgui::WebGLContext *webgl_from_context(xt_value self);
|
|
21
|
+
/** Like `webgl_from_context`, but null while the context is lost: every GL
|
|
22
|
+
* entry point except `getError`/`isContextLost` is a no-op in that state. */
|
|
23
|
+
xtgui::WebGLContext *webgl_live_context(xt_value self);
|
|
24
|
+
/** The numeric context id stored on a context handle (0 when absent). */
|
|
25
|
+
uint64_t webgl_context_id(xt_value self);
|
|
26
|
+
/** Create the JavaScript handle for a canvas's WebGL context. */
|
|
27
|
+
xt_value webgl_context_handle(xt_value element, xtgui::WebGLContext *context);
|
|
28
|
+
/** The id stored on an object handle under `key`, or 0. */
|
|
29
|
+
uint32_t webgl_object_id(xt_value handle, const char *key);
|
|
30
|
+
/** Build an object handle (`{__xt_gl_context, __xt_gl_<key>}`). */
|
|
31
|
+
xt_value webgl_make_object(xt_value context, const char *key, uint32_t id,
|
|
32
|
+
const std::string &kind);
|
|
33
|
+
double webgl_number(int32_t argc, xt_value *argv, int32_t index, double fallback);
|
|
34
|
+
int webgl_int(int32_t argc, xt_value *argv, int32_t index, int fallback);
|
|
35
|
+
std::string webgl_string(int32_t argc, xt_value *argv, int32_t index);
|
|
36
|
+
/** Read an array/typed array of numbers. */
|
|
37
|
+
std::vector<double> webgl_numbers(xt_value value);
|
|
38
|
+
/** Read the raw bytes of a typed array / ArrayBuffer (or a byte array). */
|
|
39
|
+
std::vector<uint8_t> webgl_bytes(xt_value value);
|
|
40
|
+
/** Store `count` bytes into a typed array / array handle. */
|
|
41
|
+
void webgl_write_bytes(xt_value target, const uint8_t *bytes, size_t count);
|
|
42
|
+
/** Convert a source pixel array (RGBA/RGB/LUMINANCE/…) to RGBA8. */
|
|
43
|
+
void webgl_convert_pixels(const uint8_t *source, int count, int format, bool premultiply,
|
|
44
|
+
std::vector<uint8_t> *out);
|
|
45
|
+
/** Decode a `texImage2D` source (`<img>`, `<canvas>`, `<video>`, `ImageData`,
|
|
46
|
+
* `ImageBitmap`) into top-down RGBA8. */
|
|
47
|
+
bool webgl_read_source(xt_value source, int *width, int *height,
|
|
48
|
+
std::vector<uint8_t> *rgba, bool premultiply);
|
|
49
|
+
/** Read the `UNPACK_FLIP_Y_WEBGL` / `UNPACK_PREMULTIPLY_ALPHA_WEBGL` flags set
|
|
50
|
+
* through `pixelStorei`. */
|
|
51
|
+
void webgl_unpack_flags(xt_value context, bool *flip_y, bool *premultiply);
|
|
52
|
+
/** Extension object for a compressed-texture family (null when unsupported,
|
|
53
|
+
* undefined when the name is not one of those extensions). */
|
|
54
|
+
xt_value webgl_compressed_extension(const std::string &name, xtgui::WebGLContext *context);
|
|
55
|
+
|
|
56
|
+
} // namespace domapi
|
|
57
|
+
|
|
58
|
+
#endif /* XT_GUI_DOM_API_WEBGL_INTERNAL_H */
|