From fb2505bb1ca345340896b55cde0d0f3f7b930ace Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wies=C5=82aw=20=C5=A0olt=C3=A9s?= Date: Sat, 7 Nov 2026 19:58:24 +0100 Subject: [PATCH] FerroUI 4702de41a: the size work, Locale text cultures and url::Url keys The FerroUI submodule moves to the latest main, which carries the size work (theme trimming on by default, the trimmed type tables and registrations), with the workspace blocks written by sync-workspace.py and the lock file to match. Formatted text takes an icu Locale now (Locale::UNKNOWN for the invariant culture), the embedded font collection takes url::Url keys, and the XAML loader takes a UriRef. --- Cargo.lock | 21 +++++++- Cargo.toml | 52 ++++++++++++++++++- FerroUI | 2 +- crates/ferrodesign-app/Cargo.toml | 1 + crates/ferrodesign-app/src/canvas.rs | 6 +-- crates/ferrodesign-app/src/canvas/measure.rs | 2 +- crates/ferrodesign-app/src/canvas/resize.rs | 2 +- crates/ferrodesign-app/src/fonts.rs | 5 +- crates/ferrodesign-app/src/renderer.rs | 2 +- .../src/renderer/flatten_tests.rs | 5 +- .../src/renderer/typography.rs | 2 +- crates/ferrodesign-app/src/shell.rs | 4 +- 12 files changed, 86 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 380fe83..d7cbbf5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -646,6 +646,7 @@ dependencies = [ "ferroui-x11", "regex", "serde_json", + "url", "wasm-bindgen", "zip", ] @@ -686,6 +687,7 @@ dependencies = [ "ferroui-harfbuzz", "ferroui-opengl", "ferroui-vello", + "url", "wasm-bindgen", ] @@ -720,6 +722,7 @@ dependencies = [ "ferroui-remote-protocol", "ferroui-system", "rustc-hash 2.1.3", + "url", ] [[package]] @@ -730,6 +733,7 @@ dependencies = [ "ferroui-build", "ferroui-controls", "ferroui-markup-xaml", + "ferroui-system", "sysinfo", ] @@ -739,6 +743,7 @@ version = "0.5.0-preview.1" dependencies = [ "ferroui-base", "ferroui-controls", + "url", ] [[package]] @@ -748,7 +753,9 @@ dependencies = [ "bitflags", "ferroui-base", "ferroui-controls", + "ferroui-system", "futures-util", + "url", "uuid", "zbus", ] @@ -769,6 +776,7 @@ dependencies = [ "ferroui-base", "ferroui-controls", "ferroui-harfbuzz", + "ferroui-system", ] [[package]] @@ -786,6 +794,7 @@ dependencies = [ "ferroui-build-scan", "ferroui-controls", "ferroui-markup", + "url", ] [[package]] @@ -796,6 +805,8 @@ dependencies = [ "ferroui-build-scan", "ferroui-markup", "ferroui-markup-xaml", + "roxmltree 0.20.0", + "url", "xamlx", ] @@ -820,11 +831,11 @@ dependencies = [ "cc", "ferroui-base", "ferroui-controls", - "ferroui-dialogs", "ferroui-metal", "ferroui-microcom", "ferroui-opengl", "microcom-codegen", + "url", ] [[package]] @@ -842,6 +853,7 @@ dependencies = [ name = "ferroui-remote-protocol" version = "0.5.0-preview.1" dependencies = [ + "ferroui-system", "uuid", ] @@ -913,6 +925,7 @@ dependencies = [ "ferroui-opengl", "ferroui-vulkan", "microcom-codegen", + "url", "windows-sys", ] @@ -926,8 +939,10 @@ dependencies = [ "ferroui-dialogs", "ferroui-freedesktop", "ferroui-opengl", + "ferroui-system", "ferroui-vulkan", "libc", + "url", "x11-dl", ] @@ -3677,3 +3692,7 @@ dependencies = [ "syn 3.0.6", "winnow", ] + +[[patch.unused]] +name = "skia-bindings" +version = "0.153.3" diff --git a/Cargo.toml b/Cargo.toml index edab1af..78c6d81 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,33 @@ repository = "https://github.com/FerroUI/FerroDesign" [workspace.dependencies] # >>> FerroUI workspace dependencies (written by FerroUI/scripts/apps/sync-workspace.py from FerroUI/Cargo.toml; do not edit) +ferroui-media-camera-windows = { version = "=0.5.0-preview.1", path = "FerroUI/src/FerroUI.Media.Camera.Windows" } +ferroui-media-video-windows = { version = "=0.5.0-preview.1", path = "FerroUI/src/FerroUI.Media.Video.Windows" } +ferroui-media-windows = { version = "=0.5.0-preview.1", path = "FerroUI/src/FerroUI.Media.Windows" } +ferroui-media-camera-linux = { version = "=0.5.0-preview.1", path = "FerroUI/src/FerroUI.Media.Camera.Linux" } +ferroui-media-video-linux = { version = "=0.5.0-preview.1", path = "FerroUI/src/FerroUI.Media.Video.Linux" } +ferroui-media-linux = { version = "=0.5.0-preview.1", path = "FerroUI/src/FerroUI.Media.Linux" } +ferroui-media-video = { version = "=0.5.0-preview.1", path = "FerroUI/src/FerroUI.Media.Video" } +ferroui-media-camera = { version = "=0.5.0-preview.1", path = "FerroUI/src/FerroUI.Media.Camera" } +ferroui-media-video-controls = { version = "=0.5.0-preview.1", path = "FerroUI/src/FerroUI.Media.Video.Controls" } +ferroui-media-video-apple = { version = "=0.5.0-preview.1", path = "FerroUI/src/FerroUI.Media.Video.Apple" } +ferroui-media-camera-apple = { version = "=0.5.0-preview.1", path = "FerroUI/src/FerroUI.Media.Camera.Apple" } +ferroui-media-controls = { version = "=0.5.0-preview.1", path = "FerroUI/src/FerroUI.Media.Controls" } +ferroui-media-apple = { version = "=0.5.0-preview.1", path = "FerroUI/src/FerroUI.Media.Apple" } +ferroui-media-browser = { version = "=0.5.0-preview.1", path = "FerroUI/src/FerroUI.Media.Browser" } +ferroui-media-video-browser = { version = "=0.5.0-preview.1", path = "FerroUI/src/FerroUI.Media.Video.Browser" } +ferroui-media-camera-browser = { version = "=0.5.0-preview.1", path = "FerroUI/src/FerroUI.Media.Camera.Browser" } +ferroui-media = { version = "=0.5.0-preview.1", path = "FerroUI/src/FerroUI.Media" } +ferroui-media3d = { version = "=0.5.0-preview.1", path = "FerroUI/src/FerroUI.Media3D" } +ferroui-media-metal = { version = "=0.5.0-preview.1", path = "FerroUI/src/FerroUI.Media.Metal" } +ferroui-media-opengl = { version = "=0.5.0-preview.1", path = "FerroUI/src/FerroUI.Media.OpenGL" } +ferroui-media-android = { version = "=0.5.0-preview.1", path = "FerroUI/src/FerroUI.Media.Android" } +ferroui-media-video-android = { version = "=0.5.0-preview.1", path = "FerroUI/src/FerroUI.Media.Video.Android" } +ferroui-media-camera-android = { version = "=0.5.0-preview.1", path = "FerroUI/src/FerroUI.Media.Camera.Android" } +ferroui-media-camera-controls = { version = "=0.5.0-preview.1", path = "FerroUI/src/FerroUI.Media.Camera.Controls" } +ferroui-media-qr = { version = "=0.5.0-preview.1", path = "FerroUI/src/FerroUI.Media.Qr", default-features = false } +ferroui-media-qr-android = { version = "=0.5.0-preview.1", path = "FerroUI/src/FerroUI.Media.Qr.Android" } +ferroui-media-qr-apple = { version = "=0.5.0-preview.1", path = "FerroUI/src/FerroUI.Media.Qr.Apple" } # The Dock port (docs/porting/dock): its crates and the dependencies only it has. ferrodock-controls-recycling-model = { version = "=0.5.0-preview.1", path = "FerroUI/src/Dock/FerroDock.Controls.Recycling.Model" } ferrodock-controls-recycling-model-ferro = { version = "=0.5.0-preview.1", path = "FerroUI/src/Dock/FerroDock.Controls.Recycling.Model.Ferro" } @@ -193,7 +220,7 @@ wayland-protocols-misc = { version = "=0.3.12", features = ["client"] } jni-sys = { version = "=0.4.1" } paste = "1" cc = "1" -skia-safe = { version = "0.153" } +skia-safe = { version = "=0.153.3" } # The Vello render backend (docs/porting/vello-backend.md, section 2): exact versions, because the # renderers of the Vello project change their interfaces between minor releases. `vello_cpu` without # its default features: its thread pool is added by the backend on targets with threads (the @@ -230,6 +257,9 @@ gif = { version = "=0.14.2", default-features = false, features = ["std"] } vello_gpu = { version = "=0.3.0", default-features = false, features = ["std", "text"] } vello = { version = "=0.11.0", default-features = false, features = ["wgpu"] } wgpu = { version = "=30.0.1", default-features = false, features = ["std", "wgsl", "metal"] } +# The shader translator of `wgpu`, at its version: `ferroui-build` translates the WGSL of the runtime +# shader effects to GLSL ES 3.0 for WebGL2 at build time (its features `wgsl-in` and `glsl-out`). +naga = { version = "=30.0.1", default-features = false } # The version of the `wasm-bindgen` command-line tool on PATH has to be this exact version. wasm-bindgen = "=0.2.129" # The bindings of the WebGL2 renderer of `vello_gpu`, at the versions that belong to that release @@ -277,11 +307,27 @@ lto = false # then shows addresses (docs/binary-size.md, section 4.3). On Windows the executable never holds the # symbols (they are in the PDB beside it), so the setting changes nothing there. Build with the # release profile for a backtrace with names. +# +# Without unwinding (`panic = "abort"`, docs/binary-size.md, section 4.7, #567): a panic ends the +# process, after the panic hook has run. The unwind tables and the landing pads are left out: hello +# world's executable is 21 % smaller. No production path of the framework carries an expected +# error as a panic (docs/porting/panics-as-exceptions.md); what a catch of a panic still isolates +# is a bug, which then ends the process instead of being logged. The development tools that isolate +# the code of the application they inspect (the Designer, the previewer, hot reload, DevTools) are +# built with `dev`, `release` or `dist-unwind`. Cargo ignores the setting for tests, benches, build +# scripts and procedural macros, which always unwind. [profile.dist] inherits = "release" lto = "fat" codegen-units = 1 strip = "symbols" +panic = "abort" + +# The shipped build with unwinding: `dist` with `panic = "unwind"`, for an application that catches +# panics to carry on (a plug-in host, a tool that isolates the code it runs). +[profile.dist-unwind] +inherits = "dist" +panic = "unwind" # The WebAssembly module of the browser (scripts/build-browser.sh): optimised for size, because the # module is downloaded and compiled by every visitor (docs/porting/browser-platform.md, section 18). @@ -354,4 +400,8 @@ opt-level = 3 [profile.browser.package.read-fonts] opt-level = 3 + +[patch.crates-io] +# Pinned source hotfix for Graphite Metal's retained Objective-C objects. +skia-bindings = { path = "FerroUI/external/rust-skia-bindings" } # <<< FerroUI profiles diff --git a/FerroUI b/FerroUI index b753739..4702de4 160000 --- a/FerroUI +++ b/FerroUI @@ -1 +1 @@ -Subproject commit b753739811c34eba24c86ec383232053e914e42e +Subproject commit 4702de41a8b8d66e877788b33ca9af3b40e0a59a diff --git a/crates/ferrodesign-app/Cargo.toml b/crates/ferrodesign-app/Cargo.toml index 591acae..2f4f5f2 100644 --- a/crates/ferrodesign-app/Cargo.toml +++ b/crates/ferrodesign-app/Cargo.toml @@ -25,6 +25,7 @@ ferroui-markup-xaml = { path = "../../FerroUI/src/Markup/FerroUI.Markup.Xaml" } ferroui-themes-fluent = { path = "../../FerroUI/src/FerroUI.Themes.Fluent" } ferroui-fonts-inter = { path = "../../FerroUI/src/FerroUI.Fonts.Inter" } serde_json = "1" +url = { workspace = true } [target.'cfg(target_os = "emscripten")'.dependencies] ferroui-browser = { path = "../../FerroUI/src/Browser/FerroUI.Browser", default-features = false, features = ["vello"] } diff --git a/crates/ferrodesign-app/src/canvas.rs b/crates/ferrodesign-app/src/canvas.rs index 3f6731b..6ecc81f 100644 --- a/crates/ferrodesign-app/src/canvas.rs +++ b/crates/ferrodesign-app/src/canvas.rs @@ -40,7 +40,7 @@ use ferroui_base::media::{ }; use ferroui_base::platform::IGeometryContext; use ferroui_base::threading::{Dispatcher, DispatcherPriority}; -use ferroui_base::utilities::CultureInfo; +use ferroui_base::utilities::Locale; use ferroui_base::{ ferro_class, ferro_impl_classes, instantiate, FerroObjectImpl, Matrix, Point as UiPoint, Rect as UiRect, Ref, StyledElementImpl, VisualImpl, @@ -1862,7 +1862,7 @@ fn pen(color: u32, width: f64) -> Rc { fn label(ctx: &mut DrawingContext, text: &str, point: Point, size: f64, color: &str) { let text = FormattedText::new( text, - CultureInfo::invariant_culture(), + Locale::UNKNOWN, FlowDirection::LeftToRight, Typeface::from_name("fonts:Inter#Inter"), size, @@ -1876,7 +1876,7 @@ fn canvas_caption(ctx: &mut DrawingContext, name: &str, origin: Point, screen_wi let width = (screen_width - 4.0).min(400.0); if width < 20.0 || name.is_empty() { return; } let caption = FormattedText::new( - name, CultureInfo::invariant_culture(), FlowDirection::LeftToRight, + name, Locale::UNKNOWN, FlowDirection::LeftToRight, Typeface::from_name("fonts:Inter#Inter"), 11.0, Some(brush(color)), ); caption.set_max_text_width(width); diff --git a/crates/ferrodesign-app/src/canvas/measure.rs b/crates/ferrodesign-app/src/canvas/measure.rs index cef8416..f60e04c 100644 --- a/crates/ferrodesign-app/src/canvas/measure.rs +++ b/crates/ferrodesign-app/src/canvas/measure.rs @@ -172,7 +172,7 @@ impl DesignCanvas { distance, FormattedText::new( text, - CultureInfo::invariant_culture(), + Locale::UNKNOWN, FlowDirection::LeftToRight, Typeface::from_name("fonts:Inter#Inter"), 11.0, diff --git a/crates/ferrodesign-app/src/canvas/resize.rs b/crates/ferrodesign-app/src/canvas/resize.rs index f0eb1f4..40aeb18 100644 --- a/crates/ferrodesign-app/src/canvas/resize.rs +++ b/crates/ferrodesign-app/src/canvas/resize.rs @@ -329,7 +329,7 @@ impl DesignCanvas { }; let label = FormattedText::new( &text, - CultureInfo::invariant_culture(), + Locale::UNKNOWN, FlowDirection::LeftToRight, Typeface::from_name("fonts:Inter#Inter"), 11.0, diff --git a/crates/ferrodesign-app/src/fonts.rs b/crates/ferrodesign-app/src/fonts.rs index bcbd415..80dbff0 100644 --- a/crates/ferrodesign-app/src/fonts.rs +++ b/crates/ferrodesign-app/src/fonts.rs @@ -6,7 +6,6 @@ use ferroui_base::media::{ FontFallback, FontFamily, FontManager, FontManagerOptions, UnicodeRange, }; use ferroui_base::platform::{AssetLoader, register_assets}; -use ferroui_base::utilities::Uri; use std::{rc::Rc, sync::Once}; pub(crate) const HEBREW_FAMILY: &str = "fonts:FerroDesignFallback#Noto Sans Hebrew"; @@ -56,7 +55,7 @@ pub(crate) fn register_fallbacks(font_manager: &Rc) { // the font callback runs. Refresh its asset snapshot after registration. AssetLoader::invalidate_assembly_cache(crate::ASSEMBLY.name); font_manager.add_font_collection(Rc::new(EmbeddedFontCollection::new( - Uri::absolute("fonts:FerroDesignFallback").expect("a valid font collection key"), - Uri::absolute("ferres://FerroDesign/Fonts").expect("a valid embedded font source"), + url::Url::parse("fonts:FerroDesignFallback").expect("a valid font collection key"), + url::Url::parse("ferres://FerroDesign/Fonts").expect("a valid embedded font source"), ))); } diff --git a/crates/ferrodesign-app/src/renderer.rs b/crates/ferrodesign-app/src/renderer.rs index bb88510..c43eca5 100644 --- a/crates/ferrodesign-app/src/renderer.rs +++ b/crates/ferrodesign-app/src/renderer.rs @@ -60,7 +60,7 @@ use ferroui_base::media::{ TextDecorationCollection, TextDecorations, TextHintingMode, TextOptions, TextWrapping, TileMode, Typeface, }; use ferroui_base::platform::IGeometryContext; -use ferroui_base::utilities::{CultureInfo, ValueSpan}; +use ferroui_base::utilities::{Locale, ValueSpan}; use ferroui_base::{ Matrix, Point as UiPoint, Rect as UiRect, Ref, RelativePoint, RelativeUnit, RoundedRect, }; diff --git a/crates/ferrodesign-app/src/renderer/flatten_tests.rs b/crates/ferrodesign-app/src/renderer/flatten_tests.rs index 805c70f..eccd743 100644 --- a/crates/ferrodesign-app/src/renderer/flatten_tests.rs +++ b/crates/ferrodesign-app/src/renderer/flatten_tests.rs @@ -672,7 +672,6 @@ fn flatten_native_box_shadow_outward_spread_rounds_square_corners_and_rejects() #[test] fn flatten_native_mixed_colour_glyph_text_rejects_partial_geometry_atomically() { use ferroui_base::media::fonts::{EmbeddedFontCollection, IFontCollection}; - use ferroui_base::utilities::Uri; let scope = backend(); // Load a real colour font through the public font collection API; the // ordinary first glyph makes a silently partial outline look nonempty. @@ -681,8 +680,8 @@ fn flatten_native_mixed_colour_glyph_text_rejects_partial_geometry_atomically() .canonicalize() .unwrap(); let collection = Rc::new(EmbeddedFontCollection::new( - Uri::absolute("fonts:FlattenColour").unwrap(), - Uri::absolute(&format!("file://{}", font_file.display())).unwrap(), + url::Url::parse("fonts:FlattenColour").unwrap(), + url::Url::parse(&format!("file://{}", font_file.display())).unwrap(), )); assert_eq!(collection.count(), 1); let family = format!("fonts:FlattenColour#{}", collection.get(0).name()); diff --git a/crates/ferrodesign-app/src/renderer/typography.rs b/crates/ferrodesign-app/src/renderer/typography.rs index 83b7050..b86265a 100644 --- a/crates/ferrodesign-app/src/renderer/typography.rs +++ b/crates/ferrodesign-app/src/renderer/typography.rs @@ -78,7 +78,7 @@ pub(crate) fn range_styles(node: &Node, brush: Rc) -> Option Rc { let uri = - Uri::new("ferres://FerroDesign/ui/Editor.xaml", UriKind::Absolute).expect("editor URI"); + UriRef::parse("ferres://FerroDesign/ui/Editor.xaml").expect("editor URI"); let value = FerroXamlLoader::load(&uri, None).expect("compiled editor XAML"); let root = from_markup_value::>(&Some(value)) .expect("EditorRoot is a UserControl");