diff --git a/docs/astro/src/content/docs/reference/elements/path.mdx b/docs/astro/src/content/docs/reference/elements/path.mdx index 69509ba8792..2a238ab4454 100644 --- a/docs/astro/src/content/docs/reference/elements/path.mdx +++ b/docs/astro/src/content/docs/reference/elements/path.mdx @@ -76,6 +76,12 @@ These four properties allow defining the position and size of the viewport of th If the `viewbox-width` or `viewbox-height` is less or equal than zero, the viewbox properties are ignored and instead the bounding rectangle of all path elements is used to define the view port. +### fit-style + + +This property defines how elements in a path's view box are transformed to fit into the Path's +width and height. If no view box is defined, the implicit bounding rectangle becomes the view box. + ### clip By default, when a path has a view box defined and the elements render diff --git a/internal/common/enums.rs b/internal/common/enums.rs index c624b9e1a48..ae2f2a97472 100644 --- a/internal/common/enums.rs +++ b/internal/common/enums.rs @@ -353,6 +353,25 @@ macro_rules! for_each_enums { EndClosed, } + /// This enum defines how elements in a path's view box are transformed to fit into the Path's + /// width and height. If no view box is defined, the + /// implicit bounding rectangle becomes the view box. + #[non_exhaustive] + enum PathFitStyle { + /// Scale elements to fit into the Path element's + /// dimensions while preserving the aspect ratio, + /// avoiding overflow. + Min, + /// Scale elements to fit into the Path element's + /// dimensions while preserving the aspect ratio. + /// If the aspect ratio of the view box differs from + /// the aspect ratio of the Path, then the elements will overflow. + Max, + /// Scale elements horizontall and vertically to + /// fit exactly the Path's dimenions. + Stretch, + } + /// This enum represents the different values for the `accessible-role` property, used to describe the /// role of an element in the context of assistive technology such as screen readers. #[non_exhaustive] diff --git a/internal/compiler/builtins.slint b/internal/compiler/builtins.slint index b416cc5ad5a..09fbfa4af88 100644 --- a/internal/compiler/builtins.slint +++ b/internal/compiler/builtins.slint @@ -466,6 +466,7 @@ export component Path { in property viewbox-y; in property viewbox-width; in property viewbox-height; + in property fit-style; in property clip; in property anti-alias: true; diff --git a/internal/core/graphics/path.rs b/internal/core/graphics/path.rs index e06afae4c91..3f4380ce637 100644 --- a/internal/core/graphics/path.rs +++ b/internal/core/graphics/path.rs @@ -6,7 +6,7 @@ This module contains path related types and functions for the run-time library. */ use crate::debug_log; -use crate::items::PathEvent; +use crate::items::{PathEvent, PathFitStyle}; #[cfg(feature = "rtti")] use crate::rtti::*; use auto_enums::auto_enum; @@ -248,14 +248,24 @@ impl PathDataIterator { /// Applies a transformation on the elements this iterator provides that tries to fit everything /// into the specified width/height, respecting the provided viewbox. If no viewbox is specified, /// the bounding rectangle of the path is used. - pub fn fit(&mut self, width: f32, height: f32, viewbox: Option) { + pub fn fit( + &mut self, + width: f32, + height: f32, + viewbox: Option, + style: PathFitStyle, + ) { if width > 0. || height > 0. { let viewbox = viewbox.unwrap_or_else(|| lyon_algorithms::aabb::bounding_box(self.iter())); self.transform = lyon_algorithms::fit::fit_box( &viewbox, &lyon_path::math::Box2D::from_size(lyon_path::math::Size::new(width, height)), - lyon_algorithms::fit::FitStyle::Min, + match style { + PathFitStyle::Min => lyon_algorithms::fit::FitStyle::Min, + PathFitStyle::Max => lyon_algorithms::fit::FitStyle::Max, + PathFitStyle::Stretch => lyon_algorithms::fit::FitStyle::Stretch, + }, ); } } diff --git a/internal/core/items/path.rs b/internal/core/items/path.rs index 380d3eddc86..10524a12f2b 100644 --- a/internal/core/items/path.rs +++ b/internal/core/items/path.rs @@ -16,6 +16,7 @@ use crate::input::{ }; use crate::item_rendering::CachedRenderingData; +use crate::items::PathFitStyle; use crate::layout::{LayoutInfo, Orientation}; use crate::lengths::{ LogicalBorderRadius, LogicalLength, LogicalRect, LogicalSize, LogicalVector, RectLengths, @@ -45,6 +46,7 @@ pub struct Path { pub viewbox_y: Property, pub viewbox_width: Property, pub viewbox_height: Property, + pub fit_style: Property, pub clip: Property, pub anti_alias: Property, pub cached_rendering_data: CachedRenderingData, @@ -163,7 +165,12 @@ impl Path { None }; - elements_iter.fit(bounds_width.get() as _, bounds_height.get() as _, maybe_viewbox); + elements_iter.fit( + bounds_width.get() as _, + bounds_height.get() as _, + maybe_viewbox, + self.fit_style(), + ); (offset, elements_iter).into() } }