summaryrefslogtreecommitdiffstats
path: root/tiny_skia/src
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón <hector@hecrj.dev>2024-02-02 14:54:56 +0100
committerLibravatar GitHub <noreply@github.com>2024-02-02 14:54:56 +0100
commitaea172543cb49f1f1e3625f60b49336f59e26c00 (patch)
treee99e7a55873678ac37fd695a0f46c1350b30dd2f /tiny_skia/src
parent759f0e922598504705b543185bc7140a652b726a (diff)
parentb3adf3184594c9bf60e0548a0362d30c512f3966 (diff)
downloadiced-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.rs99
-rw-r--r--tiny_skia/src/geometry.rs6
-rw-r--r--tiny_skia/src/text.rs23
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(),