diff options
author | 2024-02-02 14:54:56 +0100 | |
---|---|---|
committer | 2024-02-02 14:54:56 +0100 | |
commit | aea172543cb49f1f1e3625f60b49336f59e26c00 (patch) | |
tree | e99e7a55873678ac37fd695a0f46c1350b30dd2f /tiny_skia/src | |
parent | 759f0e922598504705b543185bc7140a652b726a (diff) | |
parent | b3adf3184594c9bf60e0548a0362d30c512f3966 (diff) | |
download | iced-aea172543cb49f1f1e3625f60b49336f59e26c00.tar.gz iced-aea172543cb49f1f1e3625f60b49336f59e26c00.tar.bz2 iced-aea172543cb49f1f1e3625f60b49336f59e26c00.zip |
Merge pull request #2120 from iced-rs/transform-primitive
`Transform` primitive
Diffstat (limited to 'tiny_skia/src')
-rw-r--r-- | tiny_skia/src/backend.rs | 99 | ||||
-rw-r--r-- | tiny_skia/src/geometry.rs | 6 | ||||
-rw-r--r-- | tiny_skia/src/text.rs | 23 |
3 files changed, 75 insertions, 53 deletions
diff --git a/tiny_skia/src/backend.rs b/tiny_skia/src/backend.rs index 468bcb7e..44f5c151 100644 --- a/tiny_skia/src/backend.rs +++ b/tiny_skia/src/backend.rs @@ -1,6 +1,8 @@ use tiny_skia::Size; -use crate::core::{Background, Color, Gradient, Rectangle, Vector}; +use crate::core::{ + Background, Color, Gradient, Rectangle, Transformation, Vector, +}; use crate::graphics::backend; use crate::graphics::text; use crate::graphics::Viewport; @@ -106,7 +108,7 @@ impl Backend { clip_mask, region, scale_factor, - Vector::ZERO, + Transformation::IDENTITY, ); } @@ -146,7 +148,7 @@ impl Backend { clip_mask: &mut tiny_skia::Mask, clip_bounds: Rectangle, scale_factor: f32, - translation: Vector, + transformation: Transformation, ) { match primitive { Primitive::Quad { @@ -164,7 +166,7 @@ impl Backend { "Quad with non-normal height!" ); - let physical_bounds = (*bounds + translation) * scale_factor; + let physical_bounds = (*bounds * transformation) * scale_factor; if !clip_bounds.intersects(&physical_bounds) { return; @@ -173,11 +175,8 @@ impl Backend { let clip_mask = (!physical_bounds.is_within(&clip_bounds)) .then_some(clip_mask as &_); - let transform = tiny_skia::Transform::from_translate( - translation.x, - translation.y, - ) - .post_scale(scale_factor, scale_factor); + let transform = into_transform(transformation) + .post_scale(scale_factor, scale_factor); // Make sure the border radius is not larger than the bounds let border_width = border @@ -199,7 +198,7 @@ impl Backend { y: bounds.y + shadow.offset.y - shadow.blur_radius, width: bounds.width + shadow.blur_radius * 2.0, height: bounds.height + shadow.blur_radius * 2.0, - } + translation) + } * transformation) * scale_factor; let radii = fill_border_radius @@ -451,7 +450,7 @@ impl Backend { clip_bounds: text_clip_bounds, } => { let physical_bounds = - (*text_clip_bounds + translation) * scale_factor; + *text_clip_bounds * transformation * scale_factor; if !clip_bounds.intersects(&physical_bounds) { return; @@ -462,11 +461,12 @@ impl Backend { self.text_pipeline.draw_paragraph( paragraph, - *position + translation, + *position, *color, scale_factor, pixels, clip_mask, + transformation, ); } Primitive::Editor { @@ -476,7 +476,7 @@ impl Backend { clip_bounds: text_clip_bounds, } => { let physical_bounds = - (*text_clip_bounds + translation) * scale_factor; + (*text_clip_bounds * transformation) * scale_factor; if !clip_bounds.intersects(&physical_bounds) { return; @@ -487,11 +487,12 @@ impl Backend { self.text_pipeline.draw_editor( editor, - *position + translation, + *position, *color, scale_factor, pixels, clip_mask, + transformation, ); } Primitive::Text { @@ -507,7 +508,7 @@ impl Backend { clip_bounds: text_clip_bounds, } => { let physical_bounds = - (*text_clip_bounds + translation) * scale_factor; + *text_clip_bounds * transformation * scale_factor; if !clip_bounds.intersects(&physical_bounds) { return; @@ -518,7 +519,7 @@ impl Backend { self.text_pipeline.draw_cached( content, - *bounds + translation, + *bounds, *color, *size, *line_height, @@ -529,6 +530,7 @@ impl Backend { scale_factor, pixels, clip_mask, + transformation, ); } Primitive::RawText(text::Raw { @@ -542,7 +544,7 @@ impl Backend { }; let physical_bounds = - (*text_clip_bounds + translation) * scale_factor; + *text_clip_bounds * transformation * scale_factor; if !clip_bounds.intersects(&physical_bounds) { return; @@ -553,11 +555,12 @@ impl Backend { self.text_pipeline.draw_raw( &buffer, - *position + translation, + *position, *color, scale_factor, pixels, clip_mask, + transformation, ); } #[cfg(feature = "image")] @@ -566,7 +569,7 @@ impl Backend { filter_method, bounds, } => { - let physical_bounds = (*bounds + translation) * scale_factor; + let physical_bounds = (*bounds * transformation) * scale_factor; if !clip_bounds.intersects(&physical_bounds) { return; @@ -575,11 +578,8 @@ impl Backend { let clip_mask = (!physical_bounds.is_within(&clip_bounds)) .then_some(clip_mask as &_); - let transform = tiny_skia::Transform::from_translate( - translation.x, - translation.y, - ) - .post_scale(scale_factor, scale_factor); + let transform = into_transform(transformation) + .post_scale(scale_factor, scale_factor); self.raster_pipeline.draw( handle, @@ -602,7 +602,7 @@ impl Backend { bounds, color, } => { - let physical_bounds = (*bounds + translation) * scale_factor; + let physical_bounds = (*bounds * transformation) * scale_factor; if !clip_bounds.intersects(&physical_bounds) { return; @@ -614,7 +614,7 @@ impl Backend { self.vector_pipeline.draw( handle, *color, - (*bounds + translation) * scale_factor, + (*bounds * transformation) * scale_factor, pixels, clip_mask, ); @@ -637,7 +637,7 @@ impl Backend { y: bounds.y(), width: bounds.width(), height: bounds.height(), - } + translation) + } * transformation) * scale_factor; if !clip_bounds.intersects(&physical_bounds) { @@ -651,11 +651,8 @@ impl Backend { path, paint, *rule, - tiny_skia::Transform::from_translate( - translation.x, - translation.y, - ) - .post_scale(scale_factor, scale_factor), + into_transform(transformation) + .post_scale(scale_factor, scale_factor), clip_mask, ); } @@ -671,7 +668,7 @@ impl Backend { y: bounds.y(), width: bounds.width(), height: bounds.height(), - } + translation) + } * transformation) * scale_factor; if !clip_bounds.intersects(&physical_bounds) { @@ -685,11 +682,8 @@ impl Backend { path, paint, stroke, - tiny_skia::Transform::from_translate( - translation.x, - translation.y, - ) - .post_scale(scale_factor, scale_factor), + into_transform(transformation) + .post_scale(scale_factor, scale_factor), clip_mask, ); } @@ -701,12 +695,12 @@ impl Backend { clip_mask, clip_bounds, scale_factor, - translation, + transformation, ); } } - Primitive::Translate { - translation: offset, + Primitive::Transform { + transformation: new_transformation, content, } => { self.draw_primitive( @@ -715,11 +709,11 @@ impl Backend { clip_mask, clip_bounds, scale_factor, - translation + *offset, + transformation * *new_transformation, ); } Primitive::Clip { bounds, content } => { - let bounds = (*bounds + translation) * scale_factor; + let bounds = (*bounds * transformation) * scale_factor; if bounds == clip_bounds { self.draw_primitive( @@ -728,7 +722,7 @@ impl Backend { clip_mask, bounds, scale_factor, - translation, + transformation, ); } else if let Some(bounds) = clip_bounds.intersection(&bounds) { if bounds.x + bounds.width <= 0.0 @@ -749,7 +743,7 @@ impl Backend { clip_mask, bounds, scale_factor, - translation, + transformation, ); adjust_clip_mask(clip_mask, clip_bounds); @@ -762,7 +756,7 @@ impl Backend { clip_mask, clip_bounds, scale_factor, - translation, + transformation, ); } } @@ -780,6 +774,19 @@ fn into_color(color: Color) -> tiny_skia::Color { .expect("Convert color from iced to tiny_skia") } +fn into_transform(transformation: Transformation) -> tiny_skia::Transform { + let translation = transformation.translation(); + + tiny_skia::Transform { + sx: transformation.scale_factor(), + kx: 0.0, + ky: 0.0, + sy: transformation.scale_factor(), + tx: translation.x, + ty: translation.y, + } +} + fn rounded_rectangle( bounds: Rectangle, border_radius: [f32; 4], diff --git a/tiny_skia/src/geometry.rs b/tiny_skia/src/geometry.rs index 74a08d38..f7518731 100644 --- a/tiny_skia/src/geometry.rs +++ b/tiny_skia/src/geometry.rs @@ -1,5 +1,5 @@ use crate::core::text::LineHeight; -use crate::core::{Pixels, Point, Rectangle, Size, Vector}; +use crate::core::{Pixels, Point, Rectangle, Size, Transformation, Vector}; use crate::graphics::geometry::fill::{self, Fill}; use crate::graphics::geometry::stroke::{self, Stroke}; use crate::graphics::geometry::{Path, Style, Text}; @@ -181,8 +181,8 @@ impl Frame { } pub fn clip(&mut self, frame: Self, at: Point) { - self.primitives.push(Primitive::Translate { - translation: Vector::new(at.x, at.y), + self.primitives.push(Primitive::Transform { + transformation: Transformation::translate(at.x, at.y), content: Box::new(frame.into_primitive()), }); } diff --git a/tiny_skia/src/text.rs b/tiny_skia/src/text.rs index 9413e311..c16037cf 100644 --- a/tiny_skia/src/text.rs +++ b/tiny_skia/src/text.rs @@ -1,6 +1,8 @@ use crate::core::alignment; use crate::core::text::{LineHeight, Shaping}; -use crate::core::{Color, Font, Pixels, Point, Rectangle, Size}; +use crate::core::{ + Color, Font, Pixels, Point, Rectangle, Size, Transformation, +}; use crate::graphics::text::cache::{self, Cache}; use crate::graphics::text::editor; use crate::graphics::text::font_system; @@ -42,6 +44,7 @@ impl Pipeline { scale_factor: f32, pixels: &mut tiny_skia::PixmapMut<'_>, clip_mask: Option<&tiny_skia::Mask>, + transformation: Transformation, ) { use crate::core::text::Paragraph as _; @@ -62,6 +65,7 @@ impl Pipeline { scale_factor, pixels, clip_mask, + transformation, ); } @@ -73,6 +77,7 @@ impl Pipeline { scale_factor: f32, pixels: &mut tiny_skia::PixmapMut<'_>, clip_mask: Option<&tiny_skia::Mask>, + transformation: Transformation, ) { use crate::core::text::Editor as _; @@ -93,6 +98,7 @@ impl Pipeline { scale_factor, pixels, clip_mask, + transformation, ); } @@ -110,6 +116,7 @@ impl Pipeline { scale_factor: f32, pixels: &mut tiny_skia::PixmapMut<'_>, clip_mask: Option<&tiny_skia::Mask>, + transformation: Transformation, ) { let line_height = f32::from(line_height.to_absolute(size)); @@ -145,6 +152,7 @@ impl Pipeline { scale_factor, pixels, clip_mask, + transformation, ); } @@ -156,6 +164,7 @@ impl Pipeline { scale_factor: f32, pixels: &mut tiny_skia::PixmapMut<'_>, clip_mask: Option<&tiny_skia::Mask>, + transformation: Transformation, ) { let mut font_system = font_system().write().expect("Write font system"); @@ -172,6 +181,7 @@ impl Pipeline { scale_factor, pixels, clip_mask, + transformation, ); } @@ -192,8 +202,9 @@ fn draw( scale_factor: f32, pixels: &mut tiny_skia::PixmapMut<'_>, clip_mask: Option<&tiny_skia::Mask>, + transformation: Transformation, ) { - let bounds = bounds * scale_factor; + let bounds = bounds * transformation * scale_factor; let x = match horizontal_alignment { alignment::Horizontal::Left => bounds.x, @@ -211,7 +222,8 @@ fn draw( for run in buffer.layout_runs() { for glyph in run.glyphs { - let physical_glyph = glyph.physical((x, y), scale_factor); + let physical_glyph = glyph + .physical((x, y), scale_factor * transformation.scale_factor()); if let Some((buffer, placement)) = glyph_cache.allocate( physical_glyph.cache_key, @@ -229,7 +241,10 @@ fn draw( pixels.draw_pixmap( physical_glyph.x + placement.left, physical_glyph.y - placement.top - + (run.line_y * scale_factor).round() as i32, + + (run.line_y + * scale_factor + * transformation.scale_factor()) + .round() as i32, pixmap, &tiny_skia::PixmapPaint::default(), tiny_skia::Transform::identity(), |