diff options
author | 2020-03-10 06:12:06 +0100 | |
---|---|---|
committer | 2020-03-10 06:12:06 +0100 | |
commit | e4fbca59b4b9478c9c5fa5eec9ebe31dc93412ad (patch) | |
tree | 237d2e5dd29c2d0f05f2b68f829425bb480b8ce7 /wgpu/src/widget | |
parent | 6151c528241d0a6ece88e6e664df1b50f8174ecb (diff) | |
parent | 5a91b52ef4066701d82a897b44a3f90412f210d2 (diff) | |
download | iced-e4fbca59b4b9478c9c5fa5eec9ebe31dc93412ad.tar.gz iced-e4fbca59b4b9478c9c5fa5eec9ebe31dc93412ad.tar.bz2 iced-e4fbca59b4b9478c9c5fa5eec9ebe31dc93412ad.zip |
Merge branch 'master' into feature/panes-widget
Diffstat (limited to 'wgpu/src/widget')
-rw-r--r-- | wgpu/src/widget/canvas.rs | 6 | ||||
-rw-r--r-- | wgpu/src/widget/canvas/frame.rs | 71 | ||||
-rw-r--r-- | wgpu/src/widget/canvas/layer.rs | 14 | ||||
-rw-r--r-- | wgpu/src/widget/canvas/layer/cache.rs | 20 | ||||
-rw-r--r-- | wgpu/src/widget/canvas/text.rs | 34 |
5 files changed, 117 insertions, 28 deletions
diff --git a/wgpu/src/widget/canvas.rs b/wgpu/src/widget/canvas.rs index 38c1ce62..3a9605c9 100644 --- a/wgpu/src/widget/canvas.rs +++ b/wgpu/src/widget/canvas.rs @@ -20,6 +20,7 @@ mod drawable; mod fill; mod frame; mod stroke; +mod text; pub use drawable::Drawable; pub use fill::Fill; @@ -27,6 +28,7 @@ pub use frame::Frame; pub use layer::Layer; pub use path::Path; pub use stroke::{LineCap, LineJoin, Stroke}; +pub use text::Text; /// A widget capable of drawing 2D graphics. /// @@ -121,9 +123,9 @@ impl<'a, Message> Widget<Message, Renderer> for Canvas<'a> { primitives: self .layers .iter() - .map(|layer| Primitive::Mesh2D { + .map(|layer| Primitive::Cached { origin, - buffers: layer.draw(size), + cache: layer.draw(size), }) .collect(), }, diff --git a/wgpu/src/widget/canvas/frame.rs b/wgpu/src/widget/canvas/frame.rs index fa6d8c0a..7d7ce06a 100644 --- a/wgpu/src/widget/canvas/frame.rs +++ b/wgpu/src/widget/canvas/frame.rs @@ -1,8 +1,8 @@ -use iced_native::{Point, Size, Vector}; +use iced_native::{Point, Rectangle, Size, Vector}; use crate::{ - canvas::{Fill, Path, Stroke}, - triangle, + canvas::{Fill, Path, Stroke, Text}, + triangle, Primitive, }; /// The frame of a [`Canvas`]. @@ -13,6 +13,7 @@ pub struct Frame { width: f32, height: f32, buffers: lyon::tessellation::VertexBuffers<triangle::Vertex2D, u32>, + primitives: Vec<Primitive>, transforms: Transforms, } @@ -40,6 +41,7 @@ impl Frame { width, height, buffers: lyon::tessellation::VertexBuffers::new(), + primitives: Vec::new(), transforms: Transforms { previous: Vec::new(), current: Transform { @@ -154,6 +156,52 @@ impl Frame { let _ = result.expect("Stroke path"); } + /// Draws the characters of the given [`Text`] on the [`Frame`], filling + /// them with the given color. + /// + /// __Warning:__ Text currently does not work well with rotations and scale + /// transforms! The position will be correctly transformed, but the + /// resulting glyphs will not be rotated or scaled properly. + /// + /// Additionally, all text will be rendered on top of all the layers of + /// a [`Canvas`]. Therefore, it is currently only meant to be used for + /// overlays, which is the most common use case. + /// + /// Support for vectorial text is planned, and should address all these + /// limitations. + /// + /// [`Text`]: struct.Text.html + /// [`Frame`]: struct.Frame.html + pub fn fill_text(&mut self, text: Text) { + use std::f32; + + let position = if self.transforms.current.is_identity { + text.position + } else { + let transformed = self.transforms.current.raw.transform_point( + lyon::math::Point::new(text.position.x, text.position.y), + ); + + Point::new(transformed.x, transformed.y) + }; + + // TODO: Use vectorial text instead of primitive + self.primitives.push(Primitive::Text { + content: text.content, + bounds: Rectangle { + x: position.x, + y: position.y, + width: f32::INFINITY, + height: f32::INFINITY, + }, + color: text.color, + size: text.size, + font: text.font, + horizontal_alignment: text.horizontal_alignment, + vertical_alignment: text.vertical_alignment, + }); + } + /// Stores the current transform of the [`Frame`] and executes the given /// drawing operations, restoring the transform afterwards. /// @@ -209,13 +257,20 @@ impl Frame { self.transforms.current.is_identity = false; } - /// Produces the geometry that has been drawn on the [`Frame`]. + /// Produces the primitive representing everything drawn on the [`Frame`]. /// /// [`Frame`]: struct.Frame.html - pub fn into_mesh(self) -> triangle::Mesh2D { - triangle::Mesh2D { - vertices: self.buffers.vertices, - indices: self.buffers.indices, + pub fn into_primitive(mut self) -> Primitive { + self.primitives.push(Primitive::Mesh2D { + origin: Point::ORIGIN, + buffers: triangle::Mesh2D { + vertices: self.buffers.vertices, + indices: self.buffers.indices, + }, + }); + + Primitive::Group { + primitives: self.primitives, } } } diff --git a/wgpu/src/widget/canvas/layer.rs b/wgpu/src/widget/canvas/layer.rs index 82d647bb..a46b7fb1 100644 --- a/wgpu/src/widget/canvas/layer.rs +++ b/wgpu/src/widget/canvas/layer.rs @@ -3,23 +3,23 @@ mod cache; pub use cache::Cache; -use crate::triangle; - +use crate::Primitive; use iced_native::Size; + use std::sync::Arc; /// A layer that can be presented at a [`Canvas`]. /// /// [`Canvas`]: ../struct.Canvas.html pub trait Layer: std::fmt::Debug { - /// Draws the [`Layer`] in the given bounds and produces [`Mesh2D`] as a - /// result. + /// Draws the [`Layer`] in the given bounds and produces a [`Primitive`] as + /// a result. /// - /// The [`Layer`] may choose to store the produced [`Mesh2D`] locally and + /// The [`Layer`] may choose to store the produced [`Primitive`] locally and /// only recompute it when the bounds change, its contents change, or is /// otherwise explicitly cleared by other means. /// /// [`Layer`]: trait.Layer.html - /// [`Mesh2D`]: ../../../triangle/struct.Mesh2D.html - fn draw(&self, bounds: Size) -> Arc<triangle::Mesh2D>; + /// [`Primitive`]: ../../../enum.Primitive.html + fn draw(&self, bounds: Size) -> Arc<Primitive>; } diff --git a/wgpu/src/widget/canvas/layer/cache.rs b/wgpu/src/widget/canvas/layer/cache.rs index 8f265142..be08d48d 100644 --- a/wgpu/src/widget/canvas/layer/cache.rs +++ b/wgpu/src/widget/canvas/layer/cache.rs @@ -1,12 +1,10 @@ use crate::{ canvas::{Drawable, Frame, Layer}, - triangle, + Primitive, }; use iced_native::Size; -use std::cell::RefCell; -use std::marker::PhantomData; -use std::sync::Arc; +use std::{cell::RefCell, marker::PhantomData, sync::Arc}; /// A simple cache that stores generated geometry to avoid recomputation. /// @@ -24,8 +22,8 @@ pub struct Cache<T: Drawable> { enum State { Empty, Filled { - mesh: Arc<triangle::Mesh2D>, bounds: Size, + primitive: Arc<Primitive>, }, } @@ -74,28 +72,28 @@ impl<'a, T> Layer for Bind<'a, T> where T: Drawable + std::fmt::Debug, { - fn draw(&self, current_bounds: Size) -> Arc<triangle::Mesh2D> { + fn draw(&self, current_bounds: Size) -> Arc<Primitive> { use std::ops::Deref; - if let State::Filled { mesh, bounds } = + if let State::Filled { bounds, primitive } = self.cache.state.borrow().deref() { if *bounds == current_bounds { - return mesh.clone(); + return primitive.clone(); } } let mut frame = Frame::new(current_bounds.width, current_bounds.height); self.input.draw(&mut frame); - let mesh = Arc::new(frame.into_mesh()); + let primitive = Arc::new(frame.into_primitive()); *self.cache.state.borrow_mut() = State::Filled { - mesh: mesh.clone(), bounds: current_bounds, + primitive: primitive.clone(), }; - mesh + primitive } } diff --git a/wgpu/src/widget/canvas/text.rs b/wgpu/src/widget/canvas/text.rs new file mode 100644 index 00000000..d1cf1a0f --- /dev/null +++ b/wgpu/src/widget/canvas/text.rs @@ -0,0 +1,34 @@ +use iced_native::{Color, Font, HorizontalAlignment, Point, VerticalAlignment}; + +/// A bunch of text that can be drawn to a canvas +#[derive(Debug, Clone)] +pub struct Text { + /// The contents of the text + pub content: String, + /// The position where to begin drawing the text (top-left corner coordinates) + pub position: Point, + /// The color of the text + pub color: Color, + /// The size of the text + pub size: f32, + /// The font of the text + pub font: Font, + /// The horizontal alignment of the text + pub horizontal_alignment: HorizontalAlignment, + /// The vertical alignment of the text + pub vertical_alignment: VerticalAlignment, +} + +impl Default for Text { + fn default() -> Text { + Text { + content: String::new(), + position: Point::ORIGIN, + color: Color::BLACK, + size: 16.0, + font: Font::Default, + horizontal_alignment: HorizontalAlignment::Left, + vertical_alignment: VerticalAlignment::Top, + } + } +} |