summaryrefslogtreecommitdiffstats
path: root/tiny_skia/src/geometry.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tiny_skia/src/geometry.rs')
-rw-r--r--tiny_skia/src/geometry.rs74
1 files changed, 71 insertions, 3 deletions
diff --git a/tiny_skia/src/geometry.rs b/tiny_skia/src/geometry.rs
index 02b6e1b9..0d5fff62 100644
--- a/tiny_skia/src/geometry.rs
+++ b/tiny_skia/src/geometry.rs
@@ -1,10 +1,10 @@
use crate::core::text::LineHeight;
-use crate::core::{Pixels, Point, Radians, Rectangle, Size, Vector};
+use crate::core::{self, Pixels, Point, Radians, Rectangle, Size, Svg, Vector};
use crate::graphics::cache::{self, Cached};
use crate::graphics::geometry::fill::{self, Fill};
use crate::graphics::geometry::stroke::{self, Stroke};
use crate::graphics::geometry::{self, Path, Style};
-use crate::graphics::{Gradient, Text};
+use crate::graphics::{self, Gradient, Image, Text};
use crate::Primitive;
use std::rc::Rc;
@@ -13,6 +13,7 @@ use std::rc::Rc;
pub enum Geometry {
Live {
text: Vec<Text>,
+ images: Vec<graphics::Image>,
primitives: Vec<Primitive>,
clip_bounds: Rectangle,
},
@@ -22,6 +23,7 @@ pub enum Geometry {
#[derive(Debug, Clone)]
pub struct Cache {
pub text: Rc<[Text]>,
+ pub images: Rc<[graphics::Image]>,
pub primitives: Rc<[Primitive]>,
pub clip_bounds: Rectangle,
}
@@ -37,10 +39,12 @@ impl Cached for Geometry {
match self {
Self::Live {
primitives,
+ images,
text,
clip_bounds,
} => Cache {
primitives: Rc::from(primitives),
+ images: Rc::from(images),
text: Rc::from(text),
clip_bounds,
},
@@ -55,6 +59,7 @@ pub struct Frame {
transform: tiny_skia::Transform,
stack: Vec<tiny_skia::Transform>,
primitives: Vec<Primitive>,
+ images: Vec<graphics::Image>,
text: Vec<Text>,
}
@@ -68,6 +73,7 @@ impl Frame {
clip_bounds,
stack: Vec::new(),
primitives: Vec::new(),
+ images: Vec::new(),
text: Vec::new(),
transform: tiny_skia::Transform::from_translate(
clip_bounds.x,
@@ -162,6 +168,15 @@ impl geometry::frame::Backend for Frame {
});
}
+ fn stroke_rectangle<'a>(
+ &mut self,
+ top_left: Point,
+ size: Size,
+ stroke: impl Into<Stroke<'a>>,
+ ) {
+ self.stroke(&Path::rectangle(top_left, size), stroke);
+ }
+
fn fill_text(&mut self, text: impl Into<geometry::Text>) {
let text = text.into();
@@ -238,7 +253,7 @@ impl geometry::frame::Backend for Frame {
Self::with_clip(clip_bounds)
}
- fn paste(&mut self, frame: Self, _at: Point) {
+ fn paste(&mut self, frame: Self) {
self.primitives.extend(frame.primitives);
self.text.extend(frame.text);
}
@@ -269,10 +284,63 @@ impl geometry::frame::Backend for Frame {
fn into_geometry(self) -> Geometry {
Geometry::Live {
primitives: self.primitives,
+ images: self.images,
text: self.text,
clip_bounds: self.clip_bounds,
}
}
+
+ fn draw_image(&mut self, bounds: Rectangle, image: impl Into<core::Image>) {
+ let mut image = image.into();
+
+ let (bounds, external_rotation) =
+ transform_rectangle(bounds, self.transform);
+
+ image.rotation += external_rotation;
+
+ self.images.push(graphics::Image::Raster(image, bounds));
+ }
+
+ fn draw_svg(&mut self, bounds: Rectangle, svg: impl Into<Svg>) {
+ let mut svg = svg.into();
+
+ let (bounds, external_rotation) =
+ transform_rectangle(bounds, self.transform);
+
+ svg.rotation += external_rotation;
+
+ self.images.push(Image::Vector(svg, bounds));
+ }
+}
+
+fn transform_rectangle(
+ rectangle: Rectangle,
+ transform: tiny_skia::Transform,
+) -> (Rectangle, Radians) {
+ let mut top_left = tiny_skia::Point {
+ x: rectangle.x,
+ y: rectangle.y,
+ };
+
+ let mut top_right = tiny_skia::Point {
+ x: rectangle.x + rectangle.width,
+ y: rectangle.y,
+ };
+
+ let mut bottom_left = tiny_skia::Point {
+ x: rectangle.x,
+ y: rectangle.y + rectangle.height,
+ };
+
+ transform.map_point(&mut top_left);
+ transform.map_point(&mut top_right);
+ transform.map_point(&mut bottom_left);
+
+ Rectangle::with_vertices(
+ Point::new(top_left.x, top_left.y),
+ Point::new(top_right.x, top_right.y),
+ Point::new(bottom_left.x, bottom_left.y),
+ )
}
fn convert_path(path: &Path) -> Option<tiny_skia::Path> {