use crate::draw::primitive::path;
use crate::draw::primitive::Primitive;
use crate::draw::properties::spatial::{self, dimension, orientation, position};
use crate::draw::properties::{SetDimensions, SetOrientation, SetPosition};
use crate::draw::{self, Drawing};
use crate::geom;
use crate::glam::Vec2;
use crate::wgpu;
#[derive(Clone, Debug)]
pub struct Texture {
texture_view: wgpu::TextureView,
spatial: spatial::Properties,
area: geom::Rect,
}
pub type DrawingTexture<'a> = Drawing<'a, Texture>;
impl Texture {
pub(crate) fn new(view: &dyn wgpu::ToTextureView) -> Self {
let texture_view = view.to_texture_view();
let [w, h] = texture_view.size();
let w = w as f32;
let h = h as f32;
let spatial = spatial::Properties::default().w_h(w, h);
let x = geom::Range {
start: 0.0,
end: 1.0,
};
let y = geom::Range {
start: 0.0,
end: 1.0,
};
let area = geom::Rect { x, y };
Self {
texture_view,
spatial,
area,
}
}
}
impl Texture {
pub fn area(mut self, rect: geom::Rect) -> Self {
self.area = rect;
self
}
}
impl<'a> DrawingTexture<'a> {
pub fn area(self, rect: geom::Rect) -> Self {
self.map_ty(|ty| ty.area(rect))
}
}
impl draw::renderer::RenderPrimitive for Texture {
fn render_primitive(
self,
mut ctxt: draw::renderer::RenderContext,
mesh: &mut draw::Mesh,
) -> draw::renderer::PrimitiveRender {
let Texture {
texture_view,
spatial,
area,
} = self;
let spatial::Properties {
dimensions,
position,
orientation,
} = spatial;
let (maybe_x, maybe_y, maybe_z) = (dimensions.x, dimensions.y, dimensions.z);
assert!(
maybe_z.is_none(),
"z dimension support for rect is unimplemented"
);
let w = maybe_x.unwrap_or(100.0);
let h = maybe_y.unwrap_or(100.0);
let rect = geom::Rect::from_w_h(w, h);
let global_transform = *ctxt.transform;
let local_transform = position.transform() * orientation.transform();
let transform = global_transform * local_transform;
let points_textured = rect
.corners()
.vertices()
.map(Vec2::from)
.zip(area.invert_y().corners().vertices().map(Vec2::from));
path::render_path_points_textured(
points_textured,
true,
transform,
path::Options::Fill(Default::default()),
&mut ctxt.fill_tessellator,
&mut ctxt.stroke_tessellator,
mesh,
);
draw::renderer::PrimitiveRender::texture(texture_view)
}
}
impl SetOrientation for Texture {
fn properties(&mut self) -> &mut orientation::Properties {
SetOrientation::properties(&mut self.spatial)
}
}
impl SetPosition for Texture {
fn properties(&mut self) -> &mut position::Properties {
SetPosition::properties(&mut self.spatial)
}
}
impl SetDimensions for Texture {
fn properties(&mut self) -> &mut dimension::Properties {
SetDimensions::properties(&mut self.spatial)
}
}
impl From<Texture> for Primitive {
fn from(prim: Texture) -> Self {
Primitive::Texture(prim)
}
}
impl Into<Option<Texture>> for Primitive {
fn into(self) -> Option<Texture> {
match self {
Primitive::Texture(prim) => Some(prim),
_ => None,
}
}
}