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");