summaryrefslogtreecommitdiffstats
path: root/wgpu/src/geometry.rs
diff options
context:
space:
mode:
Diffstat (limited to 'wgpu/src/geometry.rs')
-rw-r--r--wgpu/src/geometry.rs91
1 files changed, 86 insertions, 5 deletions
diff --git a/wgpu/src/geometry.rs b/wgpu/src/geometry.rs
index f6213e1d..cb629b3e 100644
--- a/wgpu/src/geometry.rs
+++ b/wgpu/src/geometry.rs
@@ -1,7 +1,9 @@
//! Build and draw geometry.
+use crate::core::image;
+use crate::core::svg;
use crate::core::text::LineHeight;
use crate::core::{
- Pixels, Point, Radians, Rectangle, Size, Transformation, Vector,
+ Color, Pixels, Point, Radians, Rectangle, Size, Transformation, Vector,
};
use crate::graphics::cache::{self, Cached};
use crate::graphics::color;
@@ -11,7 +13,7 @@ use crate::graphics::geometry::{
};
use crate::graphics::gradient::{self, Gradient};
use crate::graphics::mesh::{self, Mesh};
-use crate::graphics::{self, Text};
+use crate::graphics::{self, Image, Text};
use crate::text;
use crate::triangle;
@@ -19,16 +21,22 @@ use lyon::geom::euclid;
use lyon::tessellation;
use std::borrow::Cow;
+use std::sync::Arc;
#[derive(Debug)]
pub enum Geometry {
- Live { meshes: Vec<Mesh>, text: Vec<Text> },
+ Live {
+ meshes: Vec<Mesh>,
+ images: Vec<Image>,
+ text: Vec<Text>,
+ },
Cached(Cache),
}
#[derive(Debug, Clone)]
pub struct Cache {
pub meshes: Option<triangle::Cache>,
+ pub images: Option<Arc<[Image]>>,
pub text: Option<text::Cache>,
}
@@ -45,7 +53,17 @@ impl Cached for Geometry {
previous: Option<Self::Cache>,
) -> Self::Cache {
match self {
- Self::Live { meshes, text } => {
+ Self::Live {
+ meshes,
+ images,
+ text,
+ } => {
+ let images = if images.is_empty() {
+ None
+ } else {
+ Some(Arc::from(images))
+ };
+
if let Some(mut previous) = previous {
if let Some(cache) = &mut previous.meshes {
cache.update(meshes);
@@ -59,10 +77,13 @@ impl Cached for Geometry {
previous.text = text::Cache::new(group, text);
}
+ previous.images = images;
+
previous
} else {
Cache {
meshes: triangle::Cache::new(meshes),
+ images,
text: text::Cache::new(group, text),
}
}
@@ -78,6 +99,7 @@ pub struct Frame {
clip_bounds: Rectangle,
buffers: BufferStack,
meshes: Vec<Mesh>,
+ images: Vec<Image>,
text: Vec<Text>,
transforms: Transforms,
fill_tessellator: tessellation::FillTessellator,
@@ -96,6 +118,7 @@ impl Frame {
clip_bounds: bounds,
buffers: BufferStack::new(),
meshes: Vec::new(),
+ images: Vec::new(),
text: Vec::new(),
transforms: Transforms {
previous: Vec::new(),
@@ -335,10 +358,11 @@ impl geometry::frame::Backend for Frame {
Frame::with_clip(clip_bounds)
}
- fn paste(&mut self, frame: Frame, _at: Point) {
+ fn paste(&mut self, frame: Frame) {
self.meshes
.extend(frame.buffers.into_meshes(frame.clip_bounds));
+ self.images.extend(frame.images);
self.text.extend(frame.text);
}
@@ -348,9 +372,51 @@ impl geometry::frame::Backend for Frame {
Geometry::Live {
meshes: self.meshes,
+ images: self.images,
text: self.text,
}
}
+
+ fn draw_image(
+ &mut self,
+ handle: &image::Handle,
+ bounds: Rectangle,
+ filter_method: image::FilterMethod,
+ rotation: Radians,
+ opacity: f32,
+ ) {
+ let (bounds, external_rotation) =
+ self.transforms.current.transform_rectangle(bounds);
+
+ self.images.push(Image::Raster {
+ handle: handle.clone(),
+ filter_method,
+ bounds,
+ rotation: rotation + external_rotation,
+ opacity,
+ snap: false,
+ });
+ }
+
+ fn draw_svg(
+ &mut self,
+ handle: &svg::Handle,
+ bounds: Rectangle,
+ color: Option<Color>,
+ rotation: Radians,
+ opacity: f32,
+ ) {
+ let (bounds, external_rotation) =
+ self.transforms.current.transform_rectangle(bounds);
+
+ self.images.push(Image::Vector {
+ handle: handle.clone(),
+ color,
+ bounds,
+ rotation: rotation + external_rotation,
+ opacity,
+ });
+ }
}
enum Buffer {
@@ -518,6 +584,21 @@ impl Transform {
gradient
}
+
+ fn transform_rectangle(
+ &self,
+ rectangle: Rectangle,
+ ) -> (Rectangle, Radians) {
+ let top_left = self.transform_point(rectangle.position());
+ let top_right = self.transform_point(
+ rectangle.position() + Vector::new(rectangle.width, 0.0),
+ );
+ let bottom_left = self.transform_point(
+ rectangle.position() + Vector::new(0.0, rectangle.height),
+ );
+
+ Rectangle::with_vertices(top_left, top_right, bottom_left)
+ }
}
struct GradientVertex2DBuilder {
gradient: gradient::Packed,