@effindomv2/fui-rs 0.1.16 → 0.1.17
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/Cargo.toml +1 -1
- package/package.json +3 -2
- package/scripts/build.sh +6 -1
- package/src/bitmap.rs +39 -3
- package/src/drawing.rs +47 -1
- package/src/node/core.rs +5 -0
- package/src/node/text_node.rs +4 -0
- package/src/text.rs +41 -4
- package/src/typography.rs +9 -1
package/Cargo.toml
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effindomv2/fui-rs",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.17",
|
|
4
4
|
"private": false,
|
|
5
5
|
"license": "AGPL-3.0-only OR LicenseRef-EffinDom-Commercial",
|
|
6
6
|
"description": "EffinDom v2 Rust frontend framework SDK and host generators",
|
|
@@ -27,9 +27,10 @@
|
|
|
27
27
|
"generate:host-events:workbench": "mkdir -p build && esbuild scripts/generate-host-events.ts --bundle --format=esm --platform=node --target=node20 --packages=external --outfile=build/generate-host-events.mjs && node build/generate-host-events.mjs demo/src/host-events.ts demoHostEvents crates/demo-workbench/src/generated/host_events.rs",
|
|
28
28
|
"generate:host-events:stage4": "mkdir -p build && esbuild scripts/generate-host-events.ts --bundle --format=esm --platform=node --target=node20 --packages=external --outfile=build/generate-host-events.mjs && node build/generate-host-events.mjs demo/src/host-events.ts demoHostEvents crates/demo-stage4/src/generated/host_events.rs",
|
|
29
29
|
"generate:host-events:stage5": "mkdir -p build && esbuild scripts/generate-host-events.ts --bundle --format=esm --platform=node --target=node20 --packages=external --outfile=build/generate-host-events.mjs && node build/generate-host-events.mjs demo/src/host-events.ts demoHostEvents crates/demo-stage5/src/generated/host_events.rs",
|
|
30
|
+
"generate:host-events:immediate-drawing": "mkdir -p build && esbuild scripts/generate-host-events.ts --bundle --format=esm --platform=node --target=node20 --packages=external --outfile=build/generate-host-events.mjs && node build/generate-host-events.mjs demo/src/host-events.ts demoHostEvents crates/demo-immediate-drawing/src/generated/host_events.rs",
|
|
30
31
|
"generate:worker-host-services": "mkdir -p build && esbuild scripts/generate-host-services.ts --bundle --format=esm --platform=node --target=node20 --packages=external --outfile=build/generate-host-services.mjs && node build/generate-host-services.mjs demo/src/worker-host-services.ts demoWorkerHostServices crates/demo-shared/src/generated/worker_host_services.rs fui::host_services fui_host_service",
|
|
31
32
|
"generate:framework-host-services": "mkdir -p build && esbuild scripts/generate-host-services.ts --bundle --format=esm --platform=node --target=node20 --packages=external --outfile=build/generate-host-services.mjs && node build/generate-host-services.mjs scripts/framework-host-services.ts frameworkHostServices src/generated/framework_host_services.rs crate::host_services fui_host",
|
|
32
|
-
"generate:host": "npm run generate:host-services && npm run generate:host-events:home && npm run generate:host-events:workbench && npm run generate:host-events:stage4 && npm run generate:host-events:stage5 && npm run generate:worker-host-services && npm run generate:framework-host-services",
|
|
33
|
+
"generate:host": "npm run generate:host-services && npm run generate:host-events:home && npm run generate:host-events:workbench && npm run generate:host-events:stage4 && npm run generate:host-events:stage5 && npm run generate:host-events:immediate-drawing && npm run generate:worker-host-services && npm run generate:framework-host-services",
|
|
33
34
|
"guard:runtime-dependency": "bash scripts/check-runtime-dependency.sh",
|
|
34
35
|
"lint": "cd ../.. && npm run lint:v2",
|
|
35
36
|
"build": "npm run guard:runtime-dependency && npm run check:abi && bash scripts/build.sh",
|
package/scripts/build.sh
CHANGED
|
@@ -15,7 +15,7 @@ HOST_EVENT_GENERATOR_BUILD="${PACKAGE_DIR}/build/generate-host-events.mjs"
|
|
|
15
15
|
WORKER_BOOTSTRAP_BUILD="${PACKAGE_DIR}/build/worker-bootstrap.js"
|
|
16
16
|
WORKER_BOOTSTRAP_MAP_BUILD="${PACKAGE_DIR}/build/worker-bootstrap.js.map"
|
|
17
17
|
|
|
18
|
-
mkdir -p "${PACKAGE_DIR}/build" "${OUT_DIR}" "${DEMO_OUT_DIR}" "${DEMO_OUT_DIR}/workbench" "${DEMO_OUT_DIR}/stage4" "${DEMO_OUT_DIR}/stage5"
|
|
18
|
+
mkdir -p "${PACKAGE_DIR}/build" "${OUT_DIR}" "${DEMO_OUT_DIR}" "${DEMO_OUT_DIR}/workbench" "${DEMO_OUT_DIR}/stage4" "${DEMO_OUT_DIR}/stage5" "${DEMO_OUT_DIR}/immediate-drawing"
|
|
19
19
|
|
|
20
20
|
cd "${PACKAGE_DIR}"
|
|
21
21
|
if ! command -v cargo >/dev/null 2>&1 && [ -f "${HOME}/.cargo/env" ]; then
|
|
@@ -127,6 +127,7 @@ generate_host_events "demo/src/host-events.ts" "demoHostEvents" "crates/demo-hom
|
|
|
127
127
|
generate_host_events "demo/src/host-events.ts" "demoHostEvents" "crates/demo-workbench/src/generated/host_events.rs"
|
|
128
128
|
generate_host_events "demo/src/host-events.ts" "demoHostEvents" "crates/demo-stage4/src/generated/host_events.rs"
|
|
129
129
|
generate_host_events "demo/src/host-events.ts" "demoHostEvents" "crates/demo-stage5/src/generated/host_events.rs"
|
|
130
|
+
generate_host_events "demo/src/host-events.ts" "demoHostEvents" "crates/demo-immediate-drawing/src/generated/host_events.rs"
|
|
130
131
|
generate_host_services "demo/src/worker-host-services.ts" "demoWorkerHostServices" "crates/demo-shared/src/generated/worker_host_services.rs" "fui::host_services" "fui_host_service"
|
|
131
132
|
generate_host_services "demo/src/worker-host-services.ts" "demoWorkerHostServices" "crates/demo-worker/src/generated/worker_host_services.rs" "" "fui_host_service"
|
|
132
133
|
generate_host_services "scripts/framework-host-services.ts" "frameworkHostServices" "src/generated/framework_host_services.rs" "crate::host_services" "fui_host"
|
|
@@ -147,10 +148,12 @@ build_demo_route "fui-rs-demo-home" "fui_rs_demo_home" "${DEMO_OUT_DIR}/home.was
|
|
|
147
148
|
build_demo_route "fui-rs-demo-workbench" "fui_rs_demo_workbench" "${DEMO_OUT_DIR}/workbench.wasm"
|
|
148
149
|
build_demo_route "fui-rs-demo-stage4" "fui_rs_demo_stage4" "${DEMO_OUT_DIR}/stage4.wasm"
|
|
149
150
|
build_demo_route "fui-rs-demo-stage5" "fui_rs_demo_stage5" "${DEMO_OUT_DIR}/stage5.wasm"
|
|
151
|
+
build_demo_route "fui-rs-demo-immediate-drawing" "fui_rs_demo_immediate_drawing" "${DEMO_OUT_DIR}/immediate-drawing.wasm"
|
|
150
152
|
build_demo_route "fui-rs-demo-worker" "fui_rs_demo_worker" "${DEMO_OUT_DIR}/workers.wasm"
|
|
151
153
|
cp "${DEMO_OUT_DIR}/workers.wasm" "${DEMO_OUT_DIR}/workbench/workers.wasm"
|
|
152
154
|
cp "${DEMO_OUT_DIR}/workers.wasm" "${DEMO_OUT_DIR}/stage4/workers.wasm"
|
|
153
155
|
cp "${DEMO_OUT_DIR}/workers.wasm" "${DEMO_OUT_DIR}/stage5/workers.wasm"
|
|
156
|
+
cp "${DEMO_OUT_DIR}/workers.wasm" "${DEMO_OUT_DIR}/immediate-drawing/workers.wasm"
|
|
154
157
|
|
|
155
158
|
npx esbuild "${PACKAGE_DIR}/demo/harness.ts" \
|
|
156
159
|
--bundle \
|
|
@@ -187,6 +190,7 @@ cp "${PACKAGE_DIR}/demo/index.html" "${DEMO_OUT_DIR}/index.html"
|
|
|
187
190
|
cp "${PACKAGE_DIR}/demo/route-shell.html" "${DEMO_OUT_DIR}/workbench/index.html"
|
|
188
191
|
cp "${PACKAGE_DIR}/demo/route-shell.html" "${DEMO_OUT_DIR}/stage4/index.html"
|
|
189
192
|
cp "${PACKAGE_DIR}/demo/route-shell.html" "${DEMO_OUT_DIR}/stage5/index.html"
|
|
193
|
+
cp "${PACKAGE_DIR}/demo/route-shell.html" "${DEMO_OUT_DIR}/immediate-drawing/index.html"
|
|
190
194
|
cp "${PACKAGE_DIR}/demo/routes.json" "${DEMO_OUT_DIR}/routes.json"
|
|
191
195
|
rm -f "${DEMO_OUT_DIR}/worker-manifest.json"
|
|
192
196
|
if [ -f "${SHARED_DEMO_TEXTURE}" ]; then
|
|
@@ -195,6 +199,7 @@ if [ -f "${SHARED_DEMO_TEXTURE}" ]; then
|
|
|
195
199
|
cp "${SHARED_DEMO_TEXTURE}" "${DEMO_OUT_DIR}/workbench/demo-texture.png"
|
|
196
200
|
cp "${SHARED_DEMO_TEXTURE}" "${DEMO_OUT_DIR}/stage4/demo-texture.png"
|
|
197
201
|
cp "${SHARED_DEMO_TEXTURE}" "${DEMO_OUT_DIR}/stage5/demo-texture.png"
|
|
202
|
+
cp "${SHARED_DEMO_TEXTURE}" "${DEMO_OUT_DIR}/immediate-drawing/demo-texture.png"
|
|
198
203
|
fi
|
|
199
204
|
RUNTIME_SET_HASH="$(node -e 'const fs=require("fs"); const value=JSON.parse(fs.readFileSync(process.argv[1], "utf8")).runtime_set_hash; if (typeof value !== "string" || value.length === 0) process.exit(1); process.stdout.write(value);' "${RUNTIME_DIST_DIR}/effindom.v2.manifest.json")"
|
|
200
205
|
cat > "${OUT_DIR}/effindom-runtime-config.js" << RUNTIMECFG
|
package/src/bitmap.rs
CHANGED
|
@@ -5,6 +5,7 @@ use crate::frame_scheduler::on_loaded;
|
|
|
5
5
|
use crate::logger::error;
|
|
6
6
|
use crate::node::Node;
|
|
7
7
|
use crate::text::TextLayout;
|
|
8
|
+
use crate::typography::FontFace;
|
|
8
9
|
use std::cell::RefCell;
|
|
9
10
|
use std::rc::Rc;
|
|
10
11
|
|
|
@@ -136,6 +137,7 @@ impl Bitmap {
|
|
|
136
137
|
}
|
|
137
138
|
|
|
138
139
|
pub fn prepare_text<T: Node>(node: &T) {
|
|
140
|
+
node.build();
|
|
139
141
|
crate::bindings::ui::prepare_node(node.handle().raw());
|
|
140
142
|
}
|
|
141
143
|
|
|
@@ -145,9 +147,17 @@ impl Bitmap {
|
|
|
145
147
|
callback: impl FnOnce(BitmapTextReadyEventArgs) + 'static,
|
|
146
148
|
) -> &Self {
|
|
147
149
|
let node = node.clone();
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
150
|
+
let required_font_ids = node.required_font_ids_for_preparation();
|
|
151
|
+
let callback = Rc::new(RefCell::new(Some(callback)));
|
|
152
|
+
FontFace::when_fonts_loaded(&required_font_ids, move |_| {
|
|
153
|
+
let node = node.clone();
|
|
154
|
+
let callback = callback.clone();
|
|
155
|
+
on_loaded(move |_| {
|
|
156
|
+
Self::prepare_text(&node);
|
|
157
|
+
if let Some(callback) = callback.borrow_mut().take() {
|
|
158
|
+
callback(BitmapTextReadyEventArgs::EMPTY);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
151
161
|
});
|
|
152
162
|
self
|
|
153
163
|
}
|
|
@@ -255,6 +265,10 @@ mod tests {
|
|
|
255
265
|
use super::Bitmap;
|
|
256
266
|
use crate::drawing::Paint;
|
|
257
267
|
use crate::ffi::{self, Call};
|
|
268
|
+
use crate::frame_scheduler;
|
|
269
|
+
use crate::node::{Node, TextNode};
|
|
270
|
+
use std::cell::Cell;
|
|
271
|
+
use std::rc::Rc;
|
|
258
272
|
|
|
259
273
|
#[test]
|
|
260
274
|
fn bitmap_canvas_commit_flushes_offscreen_and_marks_asset_ready() {
|
|
@@ -314,4 +328,26 @@ mod tests {
|
|
|
314
328
|
}
|
|
315
329
|
)));
|
|
316
330
|
}
|
|
331
|
+
|
|
332
|
+
#[test]
|
|
333
|
+
fn bitmap_text_ready_builds_detached_text_before_preparing_it() {
|
|
334
|
+
ffi::test::reset();
|
|
335
|
+
frame_scheduler::reset_commit_state();
|
|
336
|
+
let bitmap = Bitmap::new(64, 32);
|
|
337
|
+
let text = TextNode::new("Detached bitmap text");
|
|
338
|
+
let fired = Rc::new(Cell::new(false));
|
|
339
|
+
bitmap.on_text_ready(&text, {
|
|
340
|
+
let fired = fired.clone();
|
|
341
|
+
move |_| fired.set(true)
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
frame_scheduler::fire_loaded_callbacks();
|
|
345
|
+
|
|
346
|
+
assert!(fired.get());
|
|
347
|
+
assert!(text.has_built_handle());
|
|
348
|
+
let calls = ffi::test::take_calls();
|
|
349
|
+
assert!(calls
|
|
350
|
+
.iter()
|
|
351
|
+
.any(|call| matches!(call, Call::PrepareNode { .. })));
|
|
352
|
+
}
|
|
317
353
|
}
|
package/src/drawing.rs
CHANGED
|
@@ -2,7 +2,7 @@ use crate::ffi;
|
|
|
2
2
|
use crate::image_sampling::ImageSampling;
|
|
3
3
|
use crate::logger::error;
|
|
4
4
|
use crate::node::Node;
|
|
5
|
-
use crate::text::TextLayout;
|
|
5
|
+
use crate::text::{DynamicTextLayout, TextLayout};
|
|
6
6
|
use std::cell::RefCell;
|
|
7
7
|
use std::rc::Rc;
|
|
8
8
|
|
|
@@ -317,6 +317,18 @@ impl DrawContext {
|
|
|
317
317
|
self.draw_text_node(&node, x, y);
|
|
318
318
|
}
|
|
319
319
|
|
|
320
|
+
pub fn draw_dynamic_text_layout(&self, layout: &DynamicTextLayout, x: f32, y: f32) {
|
|
321
|
+
if !layout.is_ready() {
|
|
322
|
+
error(
|
|
323
|
+
"DynamicTextLayout",
|
|
324
|
+
"DrawContext.draw_dynamic_text_layout() called before the DynamicTextLayout was ready; register on_ready and draw after the callback.",
|
|
325
|
+
);
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
let node = layout.draw_node();
|
|
329
|
+
self.draw_text_node(&node, x, y);
|
|
330
|
+
}
|
|
331
|
+
|
|
320
332
|
pub fn draw_image(&self, texture_id: u32, x: f32, y: f32, w: f32, h: f32) {
|
|
321
333
|
self.draw_image_sampling(texture_id, x, y, w, h, ImageSampling::linear());
|
|
322
334
|
}
|
|
@@ -355,8 +367,13 @@ impl DrawContext {
|
|
|
355
367
|
#[cfg(test)]
|
|
356
368
|
mod tests {
|
|
357
369
|
use super::{DrawContext, Paint, Path};
|
|
370
|
+
use crate::assets;
|
|
358
371
|
use crate::ffi::{self, Call};
|
|
372
|
+
use crate::frame_scheduler;
|
|
359
373
|
use crate::image_sampling::ImageSampling;
|
|
374
|
+
use crate::text::DynamicTextLayout;
|
|
375
|
+
use crate::typography::FontStack;
|
|
376
|
+
use crate::Unit;
|
|
360
377
|
|
|
361
378
|
#[test]
|
|
362
379
|
fn path_and_draw_context_emit_batched_host_calls() {
|
|
@@ -386,4 +403,33 @@ mod tests {
|
|
|
386
403
|
Call::CanvasDrawBatch { canvas_ptr: 77, words } if !words.is_empty()
|
|
387
404
|
)));
|
|
388
405
|
}
|
|
406
|
+
|
|
407
|
+
#[test]
|
|
408
|
+
fn draw_dynamic_text_layout_emits_text_command_without_exposing_draw_node() {
|
|
409
|
+
ffi::test::reset();
|
|
410
|
+
frame_scheduler::reset_commit_state();
|
|
411
|
+
assets::test_reset();
|
|
412
|
+
|
|
413
|
+
let layout = DynamicTextLayout::fixed_charset("0123456789");
|
|
414
|
+
layout
|
|
415
|
+
.font_stack(FontStack::from_id(1), 14.0)
|
|
416
|
+
.width(72.0, Unit::Pixel)
|
|
417
|
+
.height(20.0, Unit::Pixel)
|
|
418
|
+
.set_text("42");
|
|
419
|
+
layout.on_ready(|_| {});
|
|
420
|
+
frame_scheduler::fire_loaded_callbacks();
|
|
421
|
+
assert!(layout.is_ready());
|
|
422
|
+
ffi::test::take_calls();
|
|
423
|
+
|
|
424
|
+
let ctx = DrawContext::new(88);
|
|
425
|
+
ctx.draw_dynamic_text_layout(&layout, 5.0, 7.0);
|
|
426
|
+
ctx.flush();
|
|
427
|
+
|
|
428
|
+
let calls = ffi::test::take_calls();
|
|
429
|
+
assert!(calls.iter().any(|call| matches!(
|
|
430
|
+
call,
|
|
431
|
+
Call::CanvasDrawBatch { canvas_ptr: 88, words }
|
|
432
|
+
if words.first() == Some(&super::OP_DRAW_TEXT_NODE)
|
|
433
|
+
)));
|
|
434
|
+
}
|
|
389
435
|
}
|
package/src/node/core.rs
CHANGED
|
@@ -1577,6 +1577,11 @@ pub trait Node: Clone {
|
|
|
1577
1577
|
#[doc(hidden)]
|
|
1578
1578
|
fn build_self(&self);
|
|
1579
1579
|
|
|
1580
|
+
#[doc(hidden)]
|
|
1581
|
+
fn required_font_ids_for_preparation(&self) -> Vec<u32> {
|
|
1582
|
+
Vec::new()
|
|
1583
|
+
}
|
|
1584
|
+
|
|
1580
1585
|
fn node_id(&self, node_id: impl Into<String>) -> &Self
|
|
1581
1586
|
where
|
|
1582
1587
|
Self: Sized,
|
package/src/node/text_node.rs
CHANGED
package/src/text.rs
CHANGED
|
@@ -255,6 +255,10 @@ impl Node for RichText {
|
|
|
255
255
|
fn build_self(&self) {
|
|
256
256
|
self.node.build_self();
|
|
257
257
|
}
|
|
258
|
+
|
|
259
|
+
fn required_font_ids_for_preparation(&self) -> Vec<u32> {
|
|
260
|
+
self.node.required_font_ids()
|
|
261
|
+
}
|
|
258
262
|
}
|
|
259
263
|
|
|
260
264
|
fn compile_rich_text_state(state: &RichTextState) -> CompiledRichText {
|
|
@@ -781,6 +785,8 @@ impl DynamicTextLayout {
|
|
|
781
785
|
layout.set_text(value);
|
|
782
786
|
if was_ready {
|
|
783
787
|
layout.prepare_or_wait();
|
|
788
|
+
} else {
|
|
789
|
+
layout.schedule_ready();
|
|
784
790
|
}
|
|
785
791
|
true
|
|
786
792
|
}
|
|
@@ -853,12 +859,15 @@ impl DynamicTextLayout {
|
|
|
853
859
|
value.chars().all(|ch| charset.contains(ch))
|
|
854
860
|
}
|
|
855
861
|
|
|
856
|
-
fn include_in_charset(state: &mut DynamicTextLayoutState, value: &str) {
|
|
862
|
+
fn include_in_charset(state: &mut DynamicTextLayoutState, value: &str) -> bool {
|
|
863
|
+
let mut changed = false;
|
|
857
864
|
for ch in value.chars() {
|
|
858
865
|
if !state.charset.contains(ch) {
|
|
859
866
|
state.charset.push(ch);
|
|
867
|
+
changed = true;
|
|
860
868
|
}
|
|
861
869
|
}
|
|
870
|
+
changed
|
|
862
871
|
}
|
|
863
872
|
|
|
864
873
|
fn refresh_numeric_text(&self) {
|
|
@@ -880,12 +889,14 @@ impl DynamicTextLayout {
|
|
|
880
889
|
let mut state = self.inner.borrow_mut();
|
|
881
890
|
let prefix = state.numeric_prefix.clone();
|
|
882
891
|
let suffix = state.numeric_suffix.clone();
|
|
883
|
-
Self::include_in_charset(&mut state, &prefix)
|
|
884
|
-
|
|
892
|
+
let charset_changed = Self::include_in_charset(&mut state, &prefix)
|
|
893
|
+
| Self::include_in_charset(&mut state, &suffix);
|
|
885
894
|
let charset = state.charset.clone();
|
|
886
895
|
let layout = state.layout.clone();
|
|
887
896
|
drop(state);
|
|
888
|
-
|
|
897
|
+
if charset_changed {
|
|
898
|
+
layout.set_dynamic_charset_internal(charset);
|
|
899
|
+
}
|
|
889
900
|
format!("{prefix}{}{suffix}", self.format_numeric_value(value))
|
|
890
901
|
}
|
|
891
902
|
|
|
@@ -1077,4 +1088,30 @@ mod tests {
|
|
|
1077
1088
|
.iter()
|
|
1078
1089
|
.any(|call| matches!(call, Call::SetDynamicTextCharset { charset, .. } if charset == "0123456789")));
|
|
1079
1090
|
}
|
|
1091
|
+
|
|
1092
|
+
#[test]
|
|
1093
|
+
fn numeric_dynamic_text_layout_stays_ready_across_value_updates() {
|
|
1094
|
+
ffi::test::reset();
|
|
1095
|
+
frame_scheduler::reset_commit_state();
|
|
1096
|
+
assets::test_reset();
|
|
1097
|
+
|
|
1098
|
+
let layout = DynamicTextLayout::numeric();
|
|
1099
|
+
layout
|
|
1100
|
+
.precision(0)
|
|
1101
|
+
.font_stack(crate::typography::FontStack::from_id(1), 16.0)
|
|
1102
|
+
.width(120.0, Unit::Pixel)
|
|
1103
|
+
.height(24.0, Unit::Pixel)
|
|
1104
|
+
.on_ready(|_| {});
|
|
1105
|
+
frame_scheduler::fire_loaded_callbacks();
|
|
1106
|
+
assert!(layout.is_ready());
|
|
1107
|
+
ffi::test::take_calls();
|
|
1108
|
+
|
|
1109
|
+
assert!(layout.set_value(42.0));
|
|
1110
|
+
assert!(layout.is_ready());
|
|
1111
|
+
assert_eq!(layout.current_text(), "42");
|
|
1112
|
+
let calls = ffi::test::take_calls();
|
|
1113
|
+
assert!(calls
|
|
1114
|
+
.iter()
|
|
1115
|
+
.any(|call| matches!(call, Call::PrepareNode { .. })));
|
|
1116
|
+
}
|
|
1080
1117
|
}
|
package/src/typography.rs
CHANGED
|
@@ -158,7 +158,7 @@ impl FontFace {
|
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
pub(crate) fn is_font_loaded(font_id: u32) -> bool {
|
|
161
|
-
font_id == 0 || assets::is_font_loaded(font_id)
|
|
161
|
+
font_id == 0 || (1..=6).contains(&font_id) || assets::is_font_loaded(font_id)
|
|
162
162
|
}
|
|
163
163
|
|
|
164
164
|
pub fn on_loaded(&self, callback: impl Fn(FontFaceLoadedEventArgs) + 'static) -> Self {
|
|
@@ -502,6 +502,14 @@ mod tests {
|
|
|
502
502
|
assert_eq!(fired.get(), 1);
|
|
503
503
|
}
|
|
504
504
|
|
|
505
|
+
#[test]
|
|
506
|
+
fn built_in_font_faces_are_preloaded_like_fui_as() {
|
|
507
|
+
assets::test_reset();
|
|
508
|
+
for font_id in 1..=6 {
|
|
509
|
+
assert!(FontFace::new(font_id).is_loaded());
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
|
|
505
513
|
#[test]
|
|
506
514
|
fn font_stack_reports_required_font_ids() {
|
|
507
515
|
let stack = FontStack::from_id(1)
|