Add Image rotation support
Co-authored-by: DKolter <68352124+DKolter@users.noreply.github.com>
This commit is contained in:
parent
aae8e4f5cf
commit
09a6bcfffc
19 changed files with 374 additions and 84 deletions
|
|
@ -539,10 +539,10 @@ impl Engine {
|
|||
pub fn draw_image(
|
||||
&mut self,
|
||||
image: &Image,
|
||||
_transformation: Transformation,
|
||||
_pixels: &mut tiny_skia::PixmapMut<'_>,
|
||||
_clip_mask: &mut tiny_skia::Mask,
|
||||
_clip_bounds: Rectangle,
|
||||
transformation: Transformation,
|
||||
pixels: &mut tiny_skia::PixmapMut<'_>,
|
||||
clip_mask: &mut tiny_skia::Mask,
|
||||
clip_bounds: Rectangle,
|
||||
) {
|
||||
match image {
|
||||
#[cfg(feature = "image")]
|
||||
|
|
@ -550,22 +550,31 @@ impl Engine {
|
|||
handle,
|
||||
filter_method,
|
||||
bounds,
|
||||
rotation,
|
||||
scale,
|
||||
} => {
|
||||
let physical_bounds = *bounds * _transformation;
|
||||
let physical_bounds = *bounds * transformation;
|
||||
|
||||
if !_clip_bounds.intersects(&physical_bounds) {
|
||||
if !clip_bounds.intersects(&physical_bounds) {
|
||||
return;
|
||||
}
|
||||
|
||||
let clip_mask = (!physical_bounds.is_within(&_clip_bounds))
|
||||
.then_some(_clip_mask as &_);
|
||||
let clip_mask = (!physical_bounds.is_within(&clip_bounds))
|
||||
.then_some(clip_mask as &_);
|
||||
|
||||
let center = physical_bounds.center();
|
||||
let transform = into_transform(transformation)
|
||||
.post_rotate_at(rotation.to_degrees(), center.x, center.y)
|
||||
.post_translate(-center.x, -center.y)
|
||||
.post_scale(scale.width, scale.height)
|
||||
.post_translate(center.x, center.y);
|
||||
|
||||
self.raster_pipeline.draw(
|
||||
handle,
|
||||
*filter_method,
|
||||
*bounds,
|
||||
_pixels,
|
||||
into_transform(_transformation),
|
||||
pixels,
|
||||
transform,
|
||||
clip_mask,
|
||||
);
|
||||
}
|
||||
|
|
@ -574,21 +583,31 @@ impl Engine {
|
|||
handle,
|
||||
color,
|
||||
bounds,
|
||||
rotation,
|
||||
scale,
|
||||
} => {
|
||||
let physical_bounds = *bounds * _transformation;
|
||||
let physical_bounds = *bounds * transformation;
|
||||
|
||||
if !_clip_bounds.intersects(&physical_bounds) {
|
||||
if !clip_bounds.intersects(&physical_bounds) {
|
||||
return;
|
||||
}
|
||||
|
||||
let clip_mask = (!physical_bounds.is_within(&_clip_bounds))
|
||||
.then_some(_clip_mask as &_);
|
||||
let clip_mask = (!physical_bounds.is_within(&clip_bounds))
|
||||
.then_some(clip_mask as &_);
|
||||
|
||||
let center = physical_bounds.center();
|
||||
let transform = into_transform(transformation)
|
||||
.post_rotate_at(rotation.to_degrees(), center.x, center.y)
|
||||
.post_translate(-center.x, -center.y)
|
||||
.post_scale(scale.width, scale.height)
|
||||
.post_translate(center.x, center.y);
|
||||
|
||||
self.vector_pipeline.draw(
|
||||
handle,
|
||||
*color,
|
||||
physical_bounds,
|
||||
_pixels,
|
||||
pixels,
|
||||
transform,
|
||||
clip_mask,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use crate::core::image;
|
||||
use crate::core::renderer::Quad;
|
||||
use crate::core::svg;
|
||||
use crate::core::{Background, Color, Point, Rectangle, Transformation};
|
||||
use crate::core::{
|
||||
image, renderer::Quad, svg, Background, Color, Point, Rectangle, Size,
|
||||
Transformation,
|
||||
};
|
||||
use crate::graphics::damage;
|
||||
use crate::graphics::layer;
|
||||
use crate::graphics::text::{Editor, Paragraph, Text};
|
||||
|
|
@ -121,11 +121,15 @@ impl Layer {
|
|||
filter_method: image::FilterMethod,
|
||||
bounds: Rectangle,
|
||||
transformation: Transformation,
|
||||
rotation: f32,
|
||||
scale: Size,
|
||||
) {
|
||||
let image = Image::Raster {
|
||||
handle,
|
||||
filter_method,
|
||||
bounds: bounds * transformation,
|
||||
rotation,
|
||||
scale,
|
||||
};
|
||||
|
||||
self.images.push(image);
|
||||
|
|
@ -137,11 +141,15 @@ impl Layer {
|
|||
color: Option<Color>,
|
||||
bounds: Rectangle,
|
||||
transformation: Transformation,
|
||||
rotation: f32,
|
||||
scale: Size,
|
||||
) {
|
||||
let svg = Image::Vector {
|
||||
handle,
|
||||
color,
|
||||
bounds: bounds * transformation,
|
||||
rotation,
|
||||
scale,
|
||||
};
|
||||
|
||||
self.images.push(svg);
|
||||
|
|
@ -256,6 +264,22 @@ impl Layer {
|
|||
Image::eq,
|
||||
);
|
||||
|
||||
// let center = bounds.center();
|
||||
// let rotated_size = RotationLayout::Change
|
||||
// .apply_to_size(bounds.size(), *rotation);
|
||||
//
|
||||
// let scaled_size = Size::new(
|
||||
// rotated_size.width * scale.width,
|
||||
// rotated_size.height * scale.height,
|
||||
// );
|
||||
//
|
||||
// let top_left = Point::new(
|
||||
// center.x - scaled_size.width / 2.0,
|
||||
// center.y - scaled_size.height / 2.0,
|
||||
// );
|
||||
//
|
||||
// Rectangle::new(top_left, scaled_size).expand(1.0)
|
||||
|
||||
damage.extend(text);
|
||||
damage.extend(primitives);
|
||||
damage.extend(images);
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ pub use geometry::Geometry;
|
|||
|
||||
use crate::core::renderer;
|
||||
use crate::core::{
|
||||
Background, Color, Font, Pixels, Point, Rectangle, Transformation,
|
||||
Background, Color, Font, Pixels, Point, Rectangle, Size, Transformation,
|
||||
};
|
||||
use crate::engine::Engine;
|
||||
use crate::graphics::compositor;
|
||||
|
|
@ -377,9 +377,18 @@ impl core::image::Renderer for Renderer {
|
|||
handle: Self::Handle,
|
||||
filter_method: core::image::FilterMethod,
|
||||
bounds: Rectangle,
|
||||
rotation: f32,
|
||||
scale: Size,
|
||||
) {
|
||||
let (layer, transformation) = self.layers.current_mut();
|
||||
layer.draw_image(handle, filter_method, bounds, transformation);
|
||||
layer.draw_image(
|
||||
handle,
|
||||
filter_method,
|
||||
bounds,
|
||||
transformation,
|
||||
rotation,
|
||||
scale,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -397,9 +406,11 @@ impl core::svg::Renderer for Renderer {
|
|||
handle: core::svg::Handle,
|
||||
color: Option<Color>,
|
||||
bounds: Rectangle,
|
||||
rotation: f32,
|
||||
scale: Size,
|
||||
) {
|
||||
let (layer, transformation) = self.layers.current_mut();
|
||||
layer.draw_svg(handle, color, bounds, transformation);
|
||||
layer.draw_svg(handle, color, bounds, transformation, rotation, scale);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ use crate::graphics::text;
|
|||
|
||||
use resvg::usvg::{self, TreeTextToPath};
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use tiny_skia::Transform;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::collections::hash_map;
|
||||
|
|
@ -34,6 +35,7 @@ impl Pipeline {
|
|||
color: Option<Color>,
|
||||
bounds: Rectangle,
|
||||
pixels: &mut tiny_skia::PixmapMut<'_>,
|
||||
transform: Transform,
|
||||
clip_mask: Option<&tiny_skia::Mask>,
|
||||
) {
|
||||
if let Some(image) = self.cache.borrow_mut().draw(
|
||||
|
|
@ -46,7 +48,7 @@ impl Pipeline {
|
|||
bounds.y as i32,
|
||||
image,
|
||||
&tiny_skia::PixmapPaint::default(),
|
||||
tiny_skia::Transform::identity(),
|
||||
transform,
|
||||
clip_mask,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue