diff --git a/Cargo.lock b/Cargo.lock index 003050dd..5206e7c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -880,7 +880,7 @@ dependencies = [ [[package]] name = "bevy" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "bevy_internal", ] @@ -888,7 +888,7 @@ dependencies = [ [[package]] name = "bevy_a11y" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "accesskit", "bevy_app", @@ -899,7 +899,7 @@ dependencies = [ [[package]] name = "bevy_animation" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "bevy_app", "bevy_asset", @@ -928,7 +928,7 @@ dependencies = [ [[package]] name = "bevy_app" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "bevy_derive", "bevy_ecs", @@ -945,7 +945,7 @@ dependencies = [ [[package]] name = "bevy_asset" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "async-broadcast", "async-fs", @@ -977,7 +977,7 @@ dependencies = [ [[package]] name = "bevy_asset_macros" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "bevy_macro_utils 0.14.1", "proc-macro2", @@ -1010,7 +1010,7 @@ dependencies = [ [[package]] name = "bevy_audio" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "bevy_app", "bevy_asset", @@ -1028,7 +1028,7 @@ dependencies = [ [[package]] name = "bevy_color" version = "0.14.2" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "bevy_math", "bevy_reflect", @@ -1065,7 +1065,7 @@ dependencies = [ [[package]] name = "bevy_core" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "bevy_app", "bevy_ecs", @@ -1078,7 +1078,7 @@ dependencies = [ [[package]] name = "bevy_core_pipeline" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "bevy_app", "bevy_asset", @@ -1102,7 +1102,7 @@ dependencies = [ [[package]] name = "bevy_derive" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "bevy_macro_utils 0.14.1", "quote", @@ -1112,7 +1112,7 @@ dependencies = [ [[package]] name = "bevy_diagnostic" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "bevy_app", "bevy_core", @@ -1138,7 +1138,7 @@ dependencies = [ [[package]] name = "bevy_ecs" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "arrayvec", "bevy_ecs_macros", @@ -1158,7 +1158,7 @@ dependencies = [ [[package]] name = "bevy_ecs_macros" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "bevy_macro_utils 0.14.1", "proc-macro2", @@ -1203,7 +1203,7 @@ dependencies = [ [[package]] name = "bevy_encase_derive" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "bevy_macro_utils 0.14.1", "encase_derive_impl", @@ -1212,7 +1212,7 @@ dependencies = [ [[package]] name = "bevy_gilrs" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "bevy_app", "bevy_ecs", @@ -1226,7 +1226,7 @@ dependencies = [ [[package]] name = "bevy_gizmos" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "bevy_app", "bevy_asset", @@ -1248,7 +1248,7 @@ dependencies = [ [[package]] name = "bevy_gizmos_macros" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "bevy_macro_utils 0.14.1", "proc-macro2", @@ -1259,7 +1259,7 @@ dependencies = [ [[package]] name = "bevy_gltf" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "base64 0.22.1", "bevy_animation", @@ -1289,7 +1289,7 @@ dependencies = [ [[package]] name = "bevy_hierarchy" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "bevy_app", "bevy_core", @@ -1302,7 +1302,7 @@ dependencies = [ [[package]] name = "bevy_input" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "bevy_app", "bevy_ecs", @@ -1316,7 +1316,7 @@ dependencies = [ [[package]] name = "bevy_internal" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "bevy_a11y", "bevy_animation", @@ -1369,7 +1369,7 @@ dependencies = [ [[package]] name = "bevy_log" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "android_log-sys", "bevy_app", @@ -1385,7 +1385,7 @@ dependencies = [ [[package]] name = "bevy_macro_utils" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "proc-macro2", "quote", @@ -1408,7 +1408,7 @@ dependencies = [ [[package]] name = "bevy_math" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "bevy_reflect", "glam 0.27.0", @@ -1421,7 +1421,7 @@ dependencies = [ [[package]] name = "bevy_mikktspace" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "glam 0.27.0", ] @@ -1429,7 +1429,7 @@ dependencies = [ [[package]] name = "bevy_pbr" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "bevy_app", "bevy_asset", @@ -1455,12 +1455,12 @@ dependencies = [ [[package]] name = "bevy_ptr" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" [[package]] name = "bevy_reflect" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "bevy_ptr", "bevy_reflect_derive", @@ -1479,7 +1479,7 @@ dependencies = [ [[package]] name = "bevy_reflect_derive" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "bevy_macro_utils 0.14.1", "proc-macro2", @@ -1491,7 +1491,7 @@ dependencies = [ [[package]] name = "bevy_render" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "async-channel 2.3.1", "bevy_app", @@ -1539,7 +1539,7 @@ dependencies = [ [[package]] name = "bevy_render_macros" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "bevy_macro_utils 0.14.1", "proc-macro2", @@ -1550,7 +1550,7 @@ dependencies = [ [[package]] name = "bevy_scene" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "bevy_app", "bevy_asset", @@ -1579,7 +1579,7 @@ dependencies = [ [[package]] name = "bevy_sprite" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "bevy_app", "bevy_asset", @@ -1604,7 +1604,7 @@ dependencies = [ [[package]] name = "bevy_state" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "bevy_app", "bevy_ecs", @@ -1617,7 +1617,7 @@ dependencies = [ [[package]] name = "bevy_state_macros" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "bevy_macro_utils 0.14.1", "proc-macro2", @@ -1628,7 +1628,7 @@ dependencies = [ [[package]] name = "bevy_tasks" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "async-channel 2.3.1", "async-executor", @@ -1640,7 +1640,7 @@ dependencies = [ [[package]] name = "bevy_text" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "bevy_app", "bevy_asset", @@ -1664,7 +1664,7 @@ dependencies = [ [[package]] name = "bevy_time" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "bevy_app", "bevy_ecs", @@ -1677,7 +1677,7 @@ dependencies = [ [[package]] name = "bevy_transform" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "bevy_app", "bevy_ecs", @@ -1690,7 +1690,7 @@ dependencies = [ [[package]] name = "bevy_ui" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "bevy_a11y", "bevy_app", @@ -1719,7 +1719,7 @@ dependencies = [ [[package]] name = "bevy_utils" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "ahash", "bevy_utils_proc_macros", @@ -1733,7 +1733,7 @@ dependencies = [ [[package]] name = "bevy_utils_proc_macros" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "proc-macro2", "quote", @@ -1743,7 +1743,7 @@ dependencies = [ [[package]] name = "bevy_window" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "bevy_a11y", "bevy_app", @@ -1758,7 +1758,7 @@ dependencies = [ [[package]] name = "bevy_winit" version = "0.14.1" -source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#985cbb2a9a7e4106584fcb57e67908d210936340" +source = "git+https://github.com/robtfm/bevy?branch=release-0.14-dcl-cosmic-noimage#5cd52a4e31c9561926b98bb404db3e81db6bccc2" dependencies = [ "accesskit_winit", "approx", diff --git a/crates/scene_runner/src/update_world/scene_ui/ui_text.rs b/crates/scene_runner/src/update_world/scene_ui/ui_text.rs index 1cf1805b..db2041f8 100644 --- a/crates/scene_runner/src/update_world/scene_ui/ui_text.rs +++ b/crates/scene_runner/src/update_world/scene_ui/ui_text.rs @@ -106,7 +106,7 @@ pub fn set_ui_text( continue; }; - let text = make_text_section( + let (text, extras) = make_text_section( ui_text.text.as_str(), ui_text.font_size, ui_text @@ -207,11 +207,15 @@ pub fn set_ui_text( ..Default::default() }) .try_with_children(|c| { - c.spawn(TextBundle { + let mut cmds = c.spawn(TextBundle { text, z_index: ZIndex::Local(1), ..Default::default() }); + + if let Some(extras) = extras { + cmds.insert(extras); + } }); }); }); diff --git a/crates/scene_runner/src/update_world/text_shape.rs b/crates/scene_runner/src/update_world/text_shape.rs index ec6243ff..f4704f2a 100644 --- a/crates/scene_runner/src/update_world/text_shape.rs +++ b/crates/scene_runner/src/update_world/text_shape.rs @@ -90,8 +90,9 @@ bevy: not implemented use bevy::{ core::FrameCount, prelude::*, - text::{BreakLineOn, CosmicBuffer}, - utils::hashbrown::HashMap, + text::{BreakLineOn, CosmicBuffer, TextLayoutInfo}, + ui::{update::update_clipping_system, widget::text_system}, + utils::{hashbrown::HashMap, HashSet}, }; use common::{ sets::{SceneLoopSets, SceneSets}, @@ -125,6 +126,13 @@ impl Plugin for TextShapePlugin { Update, add_cosmic_buffers.after(SceneSets::RestrictedActions), ); + app.add_systems( + PostUpdate, + apply_text_extras + .after(text_system) + .after(TransformSystem::TransformPropagate) + .before(update_clipping_system), + ); } } @@ -262,7 +270,7 @@ fn update_text_shapes( }; // create ui layout - let text = make_text_section( + let (text, extras) = make_text_section( text_shape.0.text.as_str(), font_size, text_shape @@ -308,7 +316,7 @@ fn update_text_shapes( ..Default::default() }) .with_children(|c| { - c.spawn(TextBundle { + let mut cmds = c.spawn(TextBundle { text, style: Style { align_self: match halign { @@ -321,6 +329,9 @@ fn update_text_shapes( }, ..Default::default() }); + if let Some(extras) = extras { + cmds.insert(extras); + } }); if halign != JustifyText::Right { @@ -363,6 +374,229 @@ fn update_text_shapes( } } +#[derive(Component)] +pub struct TextExtraMarker; + +#[inline] +fn round_ties_up(value: f32) -> f32 { + if value.fract() != -0.5 { + value.round() + } else { + value.ceil() + } +} + +#[inline] +fn round_layout_coords(value: Vec2) -> Vec2 { + Vec2 { + x: round_ties_up(value.x), + y: round_ties_up(value.y), + } +} +fn apply_text_extras( + mut commands: Commands, + q: Query< + ( + &Text, + &TextExtras, + &CosmicBuffer, + &Parent, + &GlobalTransform, + &Node, + Option<&TargetCamera>, + Option<&Children>, + ), + Or<(Changed, Changed, Changed)>, + >, + existing: Query<(), With>, + mut removed: RemovedComponents, + children: Query<&Children>, +) { + for removed in removed.read() { + if let Ok(children) = children.get(removed) { + for child in children { + if existing.get(*child).is_ok() { + commands.entity(*child).despawn_recursive(); + } + } + } + } + + let find_bounds = |buffer: &CosmicBuffer, text: &Text, section: usize| -> Vec { + let mut segments = Vec::default(); + let preceding_text = text.sections[..section] + .iter() + .map(|s| s.value.clone()) + .collect::>() + .join(""); + let start_line = preceding_text.chars().filter(|c| *c == '\n').count(); + let start_line_index = preceding_text + .char_indices() + .rfind(|(_, c)| *c == '\n') + .map(|(ix, _)| ix) + .unwrap_or(0); + let start_section_index = preceding_text + .char_indices() + .last() + .map(|(ix, _)| ix) + .unwrap_or(0) + - start_line_index; + + let end_line = start_line + + text.sections[section] + .value + .chars() + .filter(|c| *c == '\n') + .count(); + let end_line_index = text.sections[section] + .value + .char_indices() + .last() + .map(|(ix, _)| ix) + .unwrap_or(0); + let end_section_index = text.sections[section] + .value + .char_indices() + .rfind(|(_, c)| *c == '\n') + .map(|(ix, _)| end_line_index - ix) + .unwrap_or(start_section_index + end_line_index + 1); + + let mut segment_y = f32::NEG_INFINITY; + let runs = buffer + .layout_runs() + .skip_while(|run| run.line_i < start_line) + .take_while(|run| run.line_i <= end_line); + + for run in runs { + let glyphs = run + .glyphs + .iter() + .skip_while(|g| run.line_i == start_line && g.start < start_section_index) + .take_while(|g| run.line_i < end_line || g.end <= end_section_index); + + for glyph in glyphs { + debug!("g: {},{}", glyph.x, glyph.y); + if run.line_top + glyph.y != segment_y { + segments.push(Vec4::new( + glyph.x, + run.line_top + glyph.y, + glyph.w, + run.line_height, + )); + segment_y = run.line_top + glyph.y; + } else { + let segment = segments.last_mut().unwrap(); + segment.z = glyph.x + glyph.w - segment.x; + } + } + } + + segments + }; + + for (text, extras, buffer, parent, gt, node, maybe_camera, maybe_children) in q.iter() { + for &child in maybe_children.map(|c| c.iter()).unwrap_or_default() { + if existing.get(child).is_ok() { + commands.entity(child).despawn_recursive(); + } + } + let mut ents = Vec::default(); + + let mut make_mark = |bound: Vec4, color: Color, top: f32, height: f32| -> Entity { + // because we make marks based on calculated text positions, we have to run after the ui layout functions + // but that means our marks won't be positioned until next frame. if text is deleted/replaced every frame + // then it never shows. + // so we do the layouting ourselves, copying bevy's `update_uinode_geometry_recursive`, and set the visibility explicitly. + // we have to also add the equivalent style settings, or it will be overwritten next frame. + let mut view_visibility = ViewVisibility::default(); + view_visibility.set(); + let height = (bound.w * height).max(1.0); + let size = Vec2::new(bound.z, height); + let parent_tl = gt.translation().truncate() - node.calculated_size * 0.5; + let my_tl = parent_tl + Vec2::new(bound.x, bound.y + bound.w * top); + let my_translation = round_layout_coords(my_tl + size * 0.5); + let mut cmds = commands.spawn(( + NodeBundle { + style: Style { + position_type: PositionType::Absolute, + left: Val::Px(bound.x), + top: Val::Px(bound.y + bound.w * top), + width: Val::Px(bound.z), + height: Val::Px(height), + ..Default::default() + }, + background_color: color.into(), + z_index: ZIndex::Local(1), + view_visibility, + node: Node { + stack_index: node.stack_index + 1000, + calculated_size: round_layout_coords(size), + outline_width: 0.0, + outline_offset: 0.0, + unrounded_size: size, + }, + global_transform: GlobalTransform::from_translation(my_translation.extend(0.0)), + ..Default::default() + }, + TextExtraMarker, + )); + + if let Some(target_camera) = maybe_camera { + cmds.insert(target_camera.clone()); + } + + cmds.id() + }; + + for strike in extras.strike.iter() { + let bounds = find_bounds(buffer, text, *strike); + for bound in bounds { + ents.push(make_mark( + bound, + text.sections[*strike].style.color, + 0.6, + 0.1, + )); + } + } + + for under in extras.underline.iter() { + let bounds = find_bounds(buffer, text, *under); + for bound in bounds { + ents.push(make_mark( + bound, + text.sections[*under].style.color, + 0.95, + 0.1, + )); + } + } + + for (mark_section, mark_color) in extras.mark.iter() { + let bounds = find_bounds(buffer, text, *mark_section); + for bound in bounds { + ents.push(make_mark(bound, *mark_color, 0.0, 1.0)); + } + } + + commands + .entity(parent.get()) + .try_push_children(ents.as_slice()); + } +} + +#[derive(Component, Default)] +pub struct TextExtras { + strike: HashSet, + underline: HashSet, + mark: HashMap, +} + +impl TextExtras { + pub fn is_empty(&self) -> bool { + self.strike.is_empty() && self.underline.is_empty() && self.mark.is_empty() + } +} pub fn make_text_section( text: &str, font_size: f32, @@ -370,8 +604,9 @@ pub fn make_text_section( font: dcl_component::proto_components::sdk::components::common::Font, justify: JustifyText, wrapping: bool, -) -> Text { +) -> (Text, Option) { let text = text.replace("\\n", "\n"); + let mut extras = TextExtras::default(); let font_name = match font { dcl_component::proto_components::sdk::components::common::Font::FSansSerif => { @@ -386,6 +621,9 @@ pub fn make_text_section( // split by s and s let mut b_count = 0usize; let mut i_count = 0usize; + let mut u_count = 0usize; + let mut s_count = 0usize; + let mut marks = Vec::::default(); let mut section_start = 0usize; let mut sections = Vec::default(); @@ -403,8 +641,27 @@ pub fn make_text_section( match tag.as_str() { "b" => b_count += 1, "i" => i_count += 1, + "s" => s_count += 1, + "u" => u_count += 1, "/b" => b_count = b_count.saturating_sub(1), "/i" => i_count = i_count.saturating_sub(1), + "/s" => s_count = s_count.saturating_sub(1), + "/u" => u_count = u_count.saturating_sub(1), + i if i.get(0..4) == Some("mark") => { + marks.push( + i.get(5..) + .and_then(|color| Srgba::hex(color).map(Color::from).ok()) + .unwrap_or_else(|| { + warn!("unrecognised mark color `{i}`"); + let mut mark_color = color; + mark_color.set_alpha(color.alpha() * 0.5); + mark_color + }), + ); + } + "/mark" => { + marks.pop(); + } _ => warn!("unrecognised text tag `{tag}`"), } section_start = section_start + close + 1; @@ -417,6 +674,15 @@ pub fn make_text_section( (_, 0) => WeightName::Bold, (_, _) => WeightName::BoldItalic, }; + if s_count > 0 { + extras.strike.insert(sections.len()); + } + if u_count > 0 { + extras.underline.insert(sections.len()); + } + if let Some(mark) = marks.last().as_ref() { + extras.mark.insert(sections.len(), **mark); + } let section_end = text[section_start..] .char_indices() @@ -448,15 +714,18 @@ pub fn make_text_section( section_start = section_end; } - Text { - sections, - linebreak_behavior: if wrapping { - BreakLineOn::WordBoundary - } else { - BreakLineOn::NoWrap + ( + Text { + sections, + linebreak_behavior: if wrapping { + BreakLineOn::WordBoundary + } else { + BreakLineOn::NoWrap + }, + justify, }, - justify, - } + (!extras.is_empty()).then_some(extras), + ) } // workaround for using bevy cosmic buffer patch without lib support