Readjusted namespaces, removed Geometry example as it's no longer relevant.

This commit is contained in:
shan 2022-10-05 10:49:58 -07:00
parent 6e7b3ced0b
commit 30432cbade
27 changed files with 394 additions and 625 deletions

View file

@ -1,4 +1,6 @@
//! For creating a Gradient.
mod linear;
use iced_native::Color;
pub use crate::gradient::linear::Linear;
use crate::Point;
@ -28,76 +30,3 @@ impl Gradient {
}
}
/// Linear gradient builder & definition.
pub mod linear {
use crate::gradient::{ColorStop, Gradient};
use crate::{Color, Point};
/// A linear gradient that can be used in the style of [`super::Fill`] or [`super::Stroke`].
#[derive(Debug, Clone, PartialEq)]
pub struct Linear {
/// The point where the linear gradient begins.
pub start: Point,
/// The point where the linear gradient ends.
pub end: Point,
/// [`ColorStop`]s along the linear gradient path.
pub color_stops: Vec<ColorStop>,
}
/// A [`Linear`] builder.
#[derive(Debug)]
pub struct Builder {
start: Point,
end: Point,
stops: Vec<(f32, Color)>,
valid: bool,
}
impl Builder {
/// Creates a new [`Builder`].
pub fn new(start: Point, end: Point) -> Self {
Self {
start,
end,
stops: vec![],
valid: true,
}
}
/// Adds a new stop, defined by an offset and a color, to the gradient.
///
/// `offset` must be between `0.0` and `1.0`.
pub fn add_stop(mut self, offset: f32, color: Color) -> Self {
if !(0.0..=1.0).contains(&offset) {
self.valid = false;
}
self.stops.push((offset, color));
self
}
/// Builds the linear [`Gradient`] of this [`Builder`].
///
/// Returns `None` if no stops were added to the builder or
/// if stops not between 0.0 and 1.0 were added.
pub fn build(self) -> Option<Gradient> {
if self.stops.is_empty() || !self.valid {
return None;
}
let mut stops: Vec<ColorStop> = self.stops.clone().into_iter().map(|f| ColorStop {
offset: f.0,
color: f.1
}).collect();
stops.sort_by(|a, b| a.offset.partial_cmp(&b.offset).unwrap());
Some(Gradient::Linear(Linear {
start: self.start,
end: self.end,
color_stops: stops
}))
}
}
}

View file

@ -0,0 +1,71 @@
//! Linear gradient builder & definition.
use crate::gradient::{ColorStop, Gradient};
use crate::{Color, Point};
/// A linear gradient that can be used in the style of [`super::Fill`] or [`super::Stroke`].
#[derive(Debug, Clone, PartialEq)]
pub struct Linear {
/// The point where the linear gradient begins.
pub start: Point,
/// The point where the linear gradient ends.
pub end: Point,
/// [`ColorStop`]s along the linear gradient path.
pub color_stops: Vec<ColorStop>,
}
/// A [`Linear`] builder.
#[derive(Debug)]
pub struct Builder {
start: Point,
end: Point,
stops: Vec<(f32, Color)>,
valid: bool,
}
impl Builder {
/// Creates a new [`Builder`].
pub fn new(start: Point, end: Point) -> Self {
Self {
start,
end,
stops: vec![],
valid: true,
}
}
/// Adds a new stop, defined by an offset and a color, to the gradient.
///
/// `offset` must be between `0.0` and `1.0`.
pub fn add_stop(mut self, offset: f32, color: Color) -> Self {
if !(0.0..=1.0).contains(&offset) {
self.valid = false;
}
self.stops.push((offset, color));
self
}
/// Builds the linear [`Gradient`] of this [`Builder`].
///
/// Returns `None` if no stops were added to the builder or
/// if stops not between 0.0 and 1.0 were added.
pub fn build(self) -> Option<Gradient> {
if self.stops.is_empty() || !self.valid {
return None;
}
let mut stops: Vec<ColorStop> = self.stops.clone().into_iter().map(|f| ColorStop {
offset: f.0,
color: f.1
}).collect();
stops.sort_by(|a, b| a.offset.partial_cmp(&b.offset).unwrap());
Some(Gradient::Linear(Linear {
start: self.start,
end: self.end,
color_stops: stops
}))
}
}

View file

@ -1,13 +1,17 @@
//! Organize rendering primitives into a flattened list of layers.
pub mod mesh;
mod quad;
mod text;
mod image;
use crate::alignment;
use crate::triangle;
use crate::{
Background, Font, Point, Primitive, Rectangle, Size, Vector, Viewport,
};
use iced_native::image;
use iced_native::svg;
use crate::shader::Shader;
pub use crate::layer::image::Image;
pub use crate::layer::mesh::Mesh;
pub use crate::layer::quad::Quad;
pub use crate::layer::text::Text;
/// A group of primitives that should be clipped together.
#[derive(Debug)]
@ -163,7 +167,7 @@ impl<'a> Layer<'a> {
Primitive::Mesh2D {
buffers,
size,
shader,
style,
} => {
let layer = &mut layers[current_layer];
@ -179,7 +183,7 @@ impl<'a> Layer<'a> {
origin: Point::new(translation.x, translation.y),
buffers,
clip_bounds,
shader,
style,
}
);
}
@ -242,99 +246,6 @@ impl<'a> Layer<'a> {
}
}
/// A colored rectangle with a border.
///
/// This type can be directly uploaded to GPU memory.
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct Quad {
/// The position of the [`Quad`].
pub position: [f32; 2],
/// The size of the [`Quad`].
pub size: [f32; 2],
/// The color of the [`Quad`], in __linear RGB__.
pub color: [f32; 4],
/// The border color of the [`Quad`], in __linear RGB__.
pub border_color: [f32; 4],
/// The border radius of the [`Quad`].
pub border_radius: f32,
/// The border width of the [`Quad`].
pub border_width: f32,
}
/// A mesh of triangles.
#[derive(Debug, Clone, Copy)]
pub struct Mesh<'a> {
/// The origin of the vertices of the [`Mesh`].
pub origin: Point,
/// The vertex and index buffers of the [`Mesh`].
pub buffers: &'a triangle::Mesh2D,
/// The clipping bounds of the [`Mesh`].
pub clip_bounds: Rectangle<f32>,
/// The shader of the [`Mesh`].
pub shader: &'a Shader,
}
/// A paragraph of text.
#[derive(Debug, Clone, Copy)]
pub struct Text<'a> {
/// The content of the [`Text`].
pub content: &'a str,
/// The layout bounds of the [`Text`].
pub bounds: Rectangle,
/// The color of the [`Text`], in __linear RGB_.
pub color: [f32; 4],
/// 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: alignment::Horizontal,
/// The vertical alignment of the [`Text`].
pub vertical_alignment: alignment::Vertical,
}
/// A raster or vector image.
#[derive(Debug, Clone)]
pub enum Image {
/// A raster image.
Raster {
/// The handle of a raster image.
handle: image::Handle,
/// The bounds of the image.
bounds: Rectangle,
},
/// A vector image.
Vector {
/// The handle of a vector image.
handle: svg::Handle,
/// The bounds of the image.
bounds: Rectangle,
},
}
#[allow(unsafe_code)]
unsafe impl bytemuck::Zeroable for Quad {}
#[allow(unsafe_code)]
unsafe impl bytemuck::Pod for Quad {}
/// Returns the number of total vertices & total indices of all [`Mesh`]es.
pub fn attribute_count_of<'a>(meshes: &'a [Mesh<'a>]) -> (usize, usize) {
meshes

View file

@ -0,0 +1,23 @@
use iced_native::{image, svg};
use crate::Rectangle;
/// A raster or vector image.
#[derive(Debug, Clone)]
pub enum Image {
/// A raster image.
Raster {
/// The handle of a raster image.
handle: image::Handle,
/// The bounds of the image.
bounds: Rectangle,
},
/// A vector image.
Vector {
/// The handle of a vector image.
handle: svg::Handle,
/// The bounds of the image.
bounds: Rectangle,
},
}

View file

@ -0,0 +1,39 @@
//! A collection of triangle primitives.
use crate::{Color, Point, Rectangle, triangle};
use crate::gradient::Gradient;
/// A mesh of triangles.
#[derive(Debug, Clone, Copy)]
pub struct Mesh<'a> {
/// The origin of the vertices of the [`Mesh`].
pub origin: Point,
/// The vertex and index buffers of the [`Mesh`].
pub buffers: &'a triangle::Mesh2D,
/// The clipping bounds of the [`Mesh`].
pub clip_bounds: Rectangle<f32>,
/// The shader of the [`Mesh`].
pub style: &'a Style,
}
#[derive(Debug, Clone)]
/// Supported shaders for primitives.
pub enum Style {
/// Fill a primitive with a solid color.
Solid(Color),
/// Fill a primitive with an interpolated color.
Gradient(Gradient)
}
impl <'a> Into<Style> for Gradient {
fn into(self) -> Style {
match self {
Gradient::Linear(linear) => {
Style::Gradient(Gradient::Linear(linear))
}
}
}
}

View file

@ -0,0 +1,30 @@
/// A colored rectangle with a border.
///
/// This type can be directly uploaded to GPU memory.
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct Quad {
/// The position of the [`Quad`].
pub position: [f32; 2],
/// The size of the [`Quad`].
pub size: [f32; 2],
/// The color of the [`Quad`], in __linear RGB__.
pub color: [f32; 4],
/// The border color of the [`Quad`], in __linear RGB__.
pub border_color: [f32; 4],
/// The border radius of the [`Quad`].
pub border_radius: f32,
/// The border width of the [`Quad`].
pub border_width: f32,
}
#[allow(unsafe_code)]
unsafe impl bytemuck::Zeroable for Quad {}
#[allow(unsafe_code)]
unsafe impl bytemuck::Pod for Quad {}

View file

@ -0,0 +1,26 @@
use crate::{alignment, Font, Rectangle};
/// A paragraph of text.
#[derive(Debug, Clone, Copy)]
pub struct Text<'a> {
/// The content of the [`Text`].
pub content: &'a str,
/// The layout bounds of the [`Text`].
pub bounds: Rectangle,
/// The color of the [`Text`], in __linear RGB_.
pub color: [f32; 4],
/// 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: alignment::Horizontal,
/// The vertical alignment of the [`Text`].
pub vertical_alignment: alignment::Vertical,
}

View file

@ -35,7 +35,6 @@ pub mod renderer;
pub mod triangle;
pub mod widget;
pub mod window;
pub mod shader;
pub mod gradient;
pub use antialiasing::Antialiasing;

View file

@ -2,10 +2,11 @@ use iced_native::image;
use iced_native::svg;
use iced_native::{Background, Color, Font, Rectangle, Size, Vector};
use crate::{alignment, shader};
use crate::{alignment, layer};
use crate::triangle;
use std::sync::Arc;
use layer::mesh;
/// A rendering primitive.
#[derive(Debug, Clone)]
@ -90,7 +91,7 @@ pub enum Primitive {
size: Size,
/// The shader of the mesh
shader: shader::Shader,
style: mesh::Style,
},
/// A cached primitive.
///

View file

@ -1,23 +0,0 @@
//! Supported shaders;
use crate::Color;
use crate::gradient::Gradient;
#[derive(Debug, Clone)]
/// Supported shaders for primitives.
pub enum Shader {
/// Fill a primitive with a solid color.
Solid(Color),
/// Fill a primitive with an interpolated color.
Gradient(Gradient)
}
impl <'a> Into<Shader> for Gradient {
fn into(self) -> Shader {
match self {
Gradient::Linear(linear) => {
Shader::Gradient(Gradient::Linear(linear))
}
}
}
}

View file

@ -9,17 +9,17 @@ pub mod path;
mod cache;
mod cursor;
mod fill;
mod frame;
mod geometry;
mod program;
mod stroke;
mod text;
pub mod fill;
pub mod stroke;
pub use cache::Cache;
pub use cursor::Cursor;
pub use event::Event;
pub use fill::{Fill, FillRule, Style};
pub use fill::{Fill, FillRule};
pub use frame::Frame;
pub use geometry::Geometry;
pub use path::Path;
@ -37,6 +37,8 @@ use iced_native::{
Clipboard, Element, Length, Point, Rectangle, Shell, Size, Vector, Widget,
};
pub use crate::gradient::Gradient;
use std::marker::PhantomData;
/// A widget capable of drawing 2D graphics.

View file

@ -1,6 +1,8 @@
use iced_native::Color;
//! Fill [crate::widget::canvas::Geometry] with a certain style.
use crate::gradient::Gradient;
use crate::shader::Shader;
use crate::layer::mesh;
use iced_native::Color;
/// The style used to fill geometry.
#[derive(Debug, Clone)]
@ -21,7 +23,7 @@ pub struct Fill<'a> {
pub rule: FillRule,
}
impl <'a> Default for Fill<'a> {
impl<'a> Default for Fill<'a> {
fn default() -> Fill<'a> {
Fill {
style: Style::Solid(Color::BLACK),
@ -48,11 +50,11 @@ pub enum Style<'a> {
Gradient(&'a Gradient),
}
impl <'a> Into<Shader> for Style<'a> {
fn into(self) -> Shader {
impl<'a> Into<mesh::Style> for Style<'a> {
fn into(self) -> mesh::Style {
match self {
Style::Solid(color) => Shader::Solid(color),
Style::Gradient(gradient) => gradient.clone().into()
Style::Solid(color) => mesh::Style::Solid(color),
Style::Gradient(gradient) => gradient.clone().into(),
}
}
}

View file

@ -6,7 +6,7 @@ use crate::triangle;
use crate::widget::canvas::{path, Fill, Geometry, Path, Stroke, Text};
use crate::Primitive;
use crate::shader::Shader;
use crate::layer::mesh;
use crate::triangle::Vertex2D;
use lyon::tessellation;
use lyon::tessellation::geometry_builder::Positions;
@ -17,7 +17,10 @@ use lyon::tessellation::geometry_builder::Positions;
#[allow(missing_debug_implementations)]
pub struct Frame {
size: Size,
buffers: Vec<(tessellation::VertexBuffers<lyon::math::Point, u32>, Shader)>,
buffers: Vec<(
tessellation::VertexBuffers<lyon::math::Point, u32>,
mesh::Style,
)>,
primitives: Vec<Primitive>,
transforms: Transforms,
fill_tessellator: tessellation::FillTessellator,
@ -109,7 +112,8 @@ impl Frame {
&options,
&mut buffers,
)
}.expect("Tessellate path.");
}
.expect("Tessellate path.");
self.buffers.push((buf, style.into()))
}
@ -126,7 +130,8 @@ impl Frame {
let mut buf = tessellation::VertexBuffers::new();
let mut buffers = tessellation::BuffersBuilder::new(&mut buf, Positions);
let mut buffers =
tessellation::BuffersBuilder::new(&mut buf, Positions);
let top_left =
self.transforms.current.raw.transform_point(
@ -159,7 +164,8 @@ impl Frame {
let mut buf = tessellation::VertexBuffers::new();
let mut buffers = tessellation::BuffersBuilder::new(&mut buf, Positions);
let mut buffers =
tessellation::BuffersBuilder::new(&mut buf, Positions);
let mut options = tessellation::StrokeOptions::default();
options.line_width = stroke.width;
@ -187,7 +193,8 @@ impl Frame {
&options,
&mut buffers,
)
}.expect("Stroke path");
}
.expect("Stroke path");
self.buffers.push((buf, stroke.style.into()))
}
@ -331,7 +338,7 @@ impl Frame {
}
fn into_primitives(mut self) -> Vec<Primitive> {
for (buffer, shader) in self.buffers {
for (buffer, style) in self.buffers {
if !buffer.indices.is_empty() {
self.primitives.push(Primitive::Mesh2D {
buffers: triangle::Mesh2D {
@ -339,7 +346,7 @@ impl Frame {
indices: buffer.indices,
},
size: self.size,
shader,
style,
})
}
}
@ -350,5 +357,10 @@ impl Frame {
/// Converts from [`lyon::math::Point`] to [`Vertex2D`]. Used for generating primitives.
fn vertices_from(points: Vec<lyon::math::Point>) -> Vec<Vertex2D> {
points.iter().map(|p| Vertex2D { position: [p.x, p.y]}).collect()
}
points
.iter()
.map(|p| Vertex2D {
position: [p.x, p.y],
})
.collect()
}

View file

@ -1,6 +1,8 @@
//! Create lines from a [crate::widget::canvas::Path] and render with various attributes/styles.
use iced_native::Color;
use crate::gradient::Gradient;
use crate::shader::Shader;
use crate::layer::mesh;
/// The style of a stroke.
#[derive(Debug, Clone)]
@ -66,10 +68,10 @@ pub enum Style<'a> {
Gradient(&'a Gradient),
}
impl <'a> Into<Shader> for Style<'a> {
fn into(self) -> Shader {
impl <'a> Into<mesh::Style> for Style<'a> {
fn into(self) -> mesh::Style {
match self {
Style::Solid(color) => Shader::Solid(color),
Style::Solid(color) => mesh::Style::Solid(color),
Style::Gradient(gradient) => gradient.clone().into()
}
}