pub mod color;
pub mod fill;
pub mod spatial;
pub mod stroke;
use self::spatial::dimension;
use crate::draw::{self, DrawingContext};
use crate::geom;
use crate::geom::graph::node;
use crate::math::BaseFloat;
use std::cell::RefCell;
use std::ops;
pub use self::color::SetColor;
pub use self::fill::SetFill;
pub use self::spatial::dimension::SetDimensions;
pub use self::spatial::orientation::SetOrientation;
pub use self::spatial::position::SetPosition;
pub use self::stroke::SetStroke;
pub type ColorScalar = crate::color::DefaultScalar;
pub type Srgba = color::DefaultSrgba;
pub type LinSrgba = color::DefaultLinSrgba;
pub type Drawn<S, V, I> = (spatial::Properties<S>, V, I);
#[derive(Debug)]
pub struct Draw<'a, S = geom::scalar::Default>
where
S: 'a + BaseFloat,
{
state: RefCell<&'a mut draw::State<S>>,
}
#[derive(Debug)]
pub struct VerticesFromRanges {
pub ranges: draw::IntermediaryVertexDataRanges,
pub fill_color: Option<draw::mesh::vertex::Color>,
}
#[derive(Debug)]
pub struct IndicesFromRange {
pub range: ops::Range<usize>,
pub min_index: usize,
}
#[derive(Debug)]
pub struct VerticesChain<A, B> {
pub a: A,
pub b: B,
}
#[derive(Debug)]
pub struct IndicesChain<A, B> {
pub a: A,
pub b: B,
}
impl<'a, S> Draw<'a, S>
where
S: BaseFloat,
{
pub fn new(state: &'a mut draw::State<S>) -> Self {
Draw {
state: RefCell::new(state),
}
}
pub fn untransformed_dimension_of<F>(&self, n: &node::Index, point_axis: &F) -> Option<S>
where
F: Fn(&draw::mesh::vertex::Point<S>) -> S,
{
self.state
.borrow_mut()
.untransformed_dimension_of(n, point_axis)
}
pub fn untransformed_x_dimension_of(&self, n: &node::Index) -> Option<S> {
self.state.borrow_mut().untransformed_x_dimension_of(n)
}
pub fn untransformed_y_dimension_of(&self, n: &node::Index) -> Option<S> {
self.state.borrow_mut().untransformed_y_dimension_of(n)
}
pub fn untransformed_z_dimension_of(&self, n: &node::Index) -> Option<S> {
self.state.borrow_mut().untransformed_z_dimension_of(n)
}
pub fn dimension_of<F>(&mut self, n: &node::Index, point_axis: &F) -> Option<S>
where
F: Fn(&draw::mesh::vertex::Point<S>) -> S,
{
self.state.borrow_mut().dimension_of(n, point_axis)
}
pub fn x_dimension_of(&self, n: &node::Index) -> Option<S> {
self.state.borrow_mut().x_dimension_of(n)
}
pub fn y_dimension_of(&self, n: &node::Index) -> Option<S> {
self.state.borrow_mut().y_dimension_of(n)
}
pub fn z_dimension_of(&self, n: &node::Index) -> Option<S> {
self.state.borrow_mut().z_dimension_of(n)
}
pub fn theme(&self) -> std::cell::Ref<draw::Theme> {
let state = self.state.borrow();
std::cell::Ref::map(state, |s| &s.theme)
}
pub fn drawing_context<F, T>(&mut self, f: F) -> T
where
F: FnOnce(DrawingContext<S>) -> T,
{
let state = self.state.borrow_mut();
let mut intermediary_state = state.intermediary_state.borrow_mut();
let super::IntermediaryState {
ref mut intermediary_mesh,
ref mut fill_tessellator,
ref mut path_event_buffer,
ref mut text_buffer,
ref mut glyph_cache,
} = *intermediary_state;
f(DrawingContext {
mesh: intermediary_mesh,
fill_tessellator: &mut fill_tessellator.0,
path_event_buffer: path_event_buffer,
text_buffer: text_buffer,
glyph_cache: glyph_cache,
})
}
}
impl VerticesFromRanges {
pub fn new(ranges: draw::IntermediaryVertexDataRanges, fill_color: Option<LinSrgba>) -> Self {
VerticesFromRanges { ranges, fill_color }
}
}
impl IndicesFromRange {
pub fn new(range: ops::Range<usize>, min_index: usize) -> Self {
IndicesFromRange { range, min_index }
}
}
pub trait Vertices<S>: Sized {
fn next(&mut self, data: &draw::IntermediaryMesh<S>) -> Option<draw::mesh::Vertex<S>>;
fn into_iter(self, data: &draw::IntermediaryMesh<S>) -> IterVertices<Self, S> {
IterVertices {
vertices: self,
data,
}
}
}
pub trait Indices: Sized {
fn next(&mut self, intermediary_indices: &[usize]) -> Option<usize>;
fn min_index(&self) -> usize {
0
}
fn into_iter(self, intermediary_indices: &[usize]) -> IterIndices<Self> {
IterIndices {
indices: self,
intermediary_indices,
}
}
}
pub trait IntoDrawn<S>
where
S: BaseFloat,
{
type Vertices: Vertices<S>;
type Indices: Indices;
fn into_drawn(self, _: Draw<S>) -> Drawn<S, Self::Vertices, Self::Indices>;
}
pub struct IterVertices<'a, V, S: 'a> {
vertices: V,
data: &'a draw::IntermediaryMesh<S>,
}
pub struct IterIndices<'a, I> {
indices: I,
intermediary_indices: &'a [usize],
}
impl<S> dimension::Properties<S>
where
S: BaseFloat,
{
pub fn to_scalars(&self, draw: &Draw<S>) -> (Option<S>, Option<S>, Option<S>) {
const EXPECT_DIMENSION: &'static str = "no raw dimension for node";
let x = self.x.as_ref().map(|x| {
x.to_scalar(|n| {
draw.untransformed_x_dimension_of(n)
.expect(EXPECT_DIMENSION)
})
});
let y = self.y.as_ref().map(|y| {
y.to_scalar(|n| {
draw.untransformed_y_dimension_of(n)
.expect(EXPECT_DIMENSION)
})
});
let z = self.z.as_ref().map(|z| {
z.to_scalar(|n| {
draw.untransformed_z_dimension_of(n)
.expect(EXPECT_DIMENSION)
})
});
(x, y, z)
}
}
impl<A, B> From<(A, B)> for VerticesChain<A, B> {
fn from((a, b): (A, B)) -> Self {
VerticesChain { a, b }
}
}
impl<A, B> From<(A, B)> for IndicesChain<A, B> {
fn from((a, b): (A, B)) -> Self {
IndicesChain { a, b }
}
}
impl<S, I> Vertices<S> for I
where
I: Iterator<Item = draw::mesh::Vertex<S>>,
{
fn next(&mut self, _data: &draw::IntermediaryMesh<S>) -> Option<draw::mesh::Vertex<S>> {
self.next()
}
}
impl<I> Indices for I
where
I: Iterator<Item = usize>,
{
fn next(&mut self, _intermediary_indices: &[usize]) -> Option<usize> {
self.next()
}
}
impl<'a, V, S> Iterator for IterVertices<'a, V, S>
where
V: Vertices<S>,
{
type Item = draw::mesh::Vertex<S>;
fn next(&mut self) -> Option<Self::Item> {
let IterVertices {
ref mut vertices,
data,
} = *self;
Vertices::next(vertices, data)
}
}
impl<'a, I> Iterator for IterIndices<'a, I>
where
I: Indices,
{
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
let IterIndices {
ref mut indices,
intermediary_indices,
} = *self;
Indices::next(indices, intermediary_indices)
}
}
impl<S> Vertices<S> for VerticesFromRanges
where
S: BaseFloat,
{
fn next(&mut self, mesh: &draw::IntermediaryMesh<S>) -> Option<draw::mesh::Vertex<S>> {
let VerticesFromRanges {
ref mut ranges,
fill_color,
} = *self;
let point = Iterator::next(&mut ranges.points);
let color = Iterator::next(&mut ranges.colors);
let tex_coords = Iterator::next(&mut ranges.tex_coords);
let point = match point {
None => return None,
Some(point_ix) => *mesh
.vertex_data
.points
.get(point_ix)
.expect("no point for point index in IntermediaryMesh"),
};
let color = color
.map(|color_ix| {
*mesh
.vertex_data
.colors
.get(color_ix)
.expect("no color for color index in IntermediaryMesh")
})
.or(fill_color)
.expect("no color for vertex");
let tex_coords = tex_coords
.map(|tex_coords_ix| {
*mesh
.vertex_data
.tex_coords
.get(tex_coords_ix)
.expect("no tex_coords for tex_coords index in IntermediaryMesh")
})
.unwrap_or_else(draw::mesh::vertex::default_tex_coords);
Some(draw::mesh::vertex::new(point, color, tex_coords))
}
}
impl Indices for IndicesFromRange {
fn next(&mut self, intermediary_indices: &[usize]) -> Option<usize> {
Iterator::next(&mut self.range).map(|ix| {
*intermediary_indices
.get(ix)
.expect("index into `intermediary_indices` is out of range")
})
}
fn min_index(&self) -> usize {
self.min_index
}
}
impl<S, A, B> Vertices<S> for VerticesChain<A, B>
where
A: Vertices<S>,
B: Vertices<S>,
{
fn next(&mut self, mesh: &draw::IntermediaryMesh<S>) -> Option<draw::mesh::Vertex<S>> {
self.a.next(mesh).or_else(|| self.b.next(mesh))
}
}
impl<A, B> Indices for IndicesChain<A, B>
where
A: Indices,
B: Indices,
{
fn next(&mut self, intermediary_indices: &[usize]) -> Option<usize> {
self.a
.next(intermediary_indices)
.or_else(|| self.b.next(intermediary_indices))
}
fn min_index(&self) -> usize {
std::cmp::min(self.a.min_index(), self.b.min_index())
}
}