remove inner enum from raster types (#2929)
This commit is contained in:
parent
a52ee70e4c
commit
4d5a1a6ff1
|
|
@ -212,41 +212,6 @@ impl BoundingBox for GraphicGroupTable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de> serde::Deserialize<'de> for Raster<CPU> {
|
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
||||||
where
|
|
||||||
D: serde::Deserializer<'de>,
|
|
||||||
{
|
|
||||||
Ok(Raster::new_cpu(Image::deserialize(deserializer)?))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl serde::Serialize for Raster<CPU> {
|
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
||||||
where
|
|
||||||
S: serde::Serializer,
|
|
||||||
{
|
|
||||||
self.data().serialize(serializer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'de> serde::Deserialize<'de> for Raster<GPU> {
|
|
||||||
fn deserialize<D>(_deserializer: D) -> Result<Self, D::Error>
|
|
||||||
where
|
|
||||||
D: serde::Deserializer<'de>,
|
|
||||||
{
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl serde::Serialize for Raster<GPU> {
|
|
||||||
fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error>
|
|
||||||
where
|
|
||||||
S: serde::Serializer,
|
|
||||||
{
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Some [`ArtboardData`] with some optional clipping bounds that can be exported.
|
/// Some [`ArtboardData`] with some optional clipping bounds that can be exported.
|
||||||
#[derive(Clone, Debug, Hash, PartialEq, DynAny, serde::Serialize, serde::Deserialize)]
|
#[derive(Clone, Debug, Hash, PartialEq, DynAny, serde::Serialize, serde::Deserialize)]
|
||||||
pub struct Artboard {
|
pub struct Artboard {
|
||||||
|
|
|
||||||
|
|
@ -6,136 +6,202 @@ use crate::raster::Image;
|
||||||
use core::ops::Deref;
|
use core::ops::Deref;
|
||||||
use dyn_any::DynAny;
|
use dyn_any::DynAny;
|
||||||
use glam::{DAffine2, DVec2};
|
use glam::{DAffine2, DVec2};
|
||||||
#[cfg(feature = "wgpu")]
|
use std::fmt::Debug;
|
||||||
use std::sync::Arc;
|
use std::ops::DerefMut;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Hash, PartialEq, Eq, Copy)]
|
mod __private {
|
||||||
pub struct CPU;
|
pub trait Sealed {}
|
||||||
#[derive(Clone, Debug, Hash, PartialEq, Eq, Copy)]
|
}
|
||||||
pub struct GPU;
|
|
||||||
|
|
||||||
trait Storage: 'static {}
|
pub trait Storage: __private::Sealed + Clone + Debug + 'static {
|
||||||
impl Storage for CPU {}
|
fn is_empty(&self) -> bool;
|
||||||
impl Storage for GPU {}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Hash, PartialEq)]
|
#[derive(Clone, Debug, PartialEq, Hash, Default)]
|
||||||
#[allow(private_bounds)]
|
pub struct Raster<T>
|
||||||
pub struct Raster<T: Storage> {
|
where
|
||||||
data: RasterStorage,
|
Raster<T>: Storage,
|
||||||
|
{
|
||||||
storage: T,
|
storage: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<T: Storage> dyn_any::StaticType for Raster<T> {
|
unsafe impl<T> dyn_any::StaticType for Raster<T>
|
||||||
|
where
|
||||||
|
Raster<T>: Storage,
|
||||||
|
{
|
||||||
type Static = Raster<T>;
|
type Static = Raster<T>;
|
||||||
}
|
}
|
||||||
#[derive(Clone, Debug, Hash, PartialEq, DynAny)]
|
|
||||||
pub enum RasterStorage {
|
impl<T> Raster<T>
|
||||||
Cpu(Image<Color>),
|
where
|
||||||
#[cfg(feature = "wgpu")]
|
Raster<T>: Storage,
|
||||||
Gpu(Arc<wgpu::Texture>),
|
{
|
||||||
#[cfg(not(feature = "wgpu"))]
|
pub fn new(t: T) -> Self {
|
||||||
Gpu(()),
|
Self { storage: t }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RasterStorage {}
|
impl<T> Deref for Raster<T>
|
||||||
impl Raster<CPU> {
|
where
|
||||||
pub fn new_cpu(image: Image<Color>) -> Self {
|
Raster<T>: Storage,
|
||||||
Self {
|
{
|
||||||
data: RasterStorage::Cpu(image),
|
type Target = T;
|
||||||
storage: CPU,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn data(&self) -> &Image<Color> {
|
|
||||||
let RasterStorage::Cpu(cpu) = &self.data else { unreachable!() };
|
|
||||||
cpu
|
|
||||||
}
|
|
||||||
pub fn data_mut(&mut self) -> &mut Image<Color> {
|
|
||||||
let RasterStorage::Cpu(cpu) = &mut self.data else { unreachable!() };
|
|
||||||
cpu
|
|
||||||
}
|
|
||||||
pub fn into_data(self) -> Image<Color> {
|
|
||||||
let RasterStorage::Cpu(cpu) = self.data else { unreachable!() };
|
|
||||||
cpu
|
|
||||||
}
|
|
||||||
pub fn is_empty(&self) -> bool {
|
|
||||||
let data = self.data();
|
|
||||||
data.height == 0 || data.width == 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl Default for Raster<CPU> {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
data: RasterStorage::Cpu(Image::default()),
|
|
||||||
storage: CPU,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl Deref for Raster<CPU> {
|
|
||||||
type Target = Image<Color>;
|
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
self.data()
|
&self.storage
|
||||||
}
|
|
||||||
}
|
|
||||||
#[cfg(feature = "wgpu")]
|
|
||||||
impl Raster<GPU> {
|
|
||||||
pub fn new_gpu(image: Arc<wgpu::Texture>) -> Self {
|
|
||||||
Self {
|
|
||||||
data: RasterStorage::Gpu(image),
|
|
||||||
storage: GPU,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn data(&self) -> &wgpu::Texture {
|
|
||||||
let RasterStorage::Gpu(gpu) = &self.data else { unreachable!() };
|
|
||||||
gpu
|
|
||||||
}
|
|
||||||
pub fn data_mut(&mut self) -> &mut Arc<wgpu::Texture> {
|
|
||||||
let RasterStorage::Gpu(gpu) = &mut self.data else { unreachable!() };
|
|
||||||
gpu
|
|
||||||
}
|
|
||||||
pub fn data_owned(&self) -> Arc<wgpu::Texture> {
|
|
||||||
let RasterStorage::Gpu(gpu) = &self.data else { unreachable!() };
|
|
||||||
gpu.clone()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Raster<GPU> {
|
impl<T> DerefMut for Raster<T>
|
||||||
#[cfg(feature = "wgpu")]
|
where
|
||||||
pub fn is_empty(&self) -> bool {
|
Raster<T>: Storage,
|
||||||
let data = self.data();
|
{
|
||||||
data.width() == 0 || data.height() == 0
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
}
|
&mut self.storage
|
||||||
#[cfg(not(feature = "wgpu"))]
|
|
||||||
pub fn is_empty(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "wgpu")]
|
|
||||||
impl Deref for Raster<GPU> {
|
|
||||||
type Target = wgpu::Texture;
|
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
self.data()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type RasterDataTable<Storage> = Instances<Raster<Storage>>;
|
pub type RasterDataTable<Storage> = Instances<Raster<Storage>>;
|
||||||
|
|
||||||
// TODO: Make this not dupliated
|
pub use cpu::CPU;
|
||||||
impl BoundingBox for RasterDataTable<CPU> {
|
|
||||||
fn bounding_box(&self, transform: DAffine2, _include_stroke: bool) -> Option<[DVec2; 2]> {
|
mod cpu {
|
||||||
self.instance_ref_iter()
|
use super::*;
|
||||||
.filter(|instance| !instance.instance.is_empty()) // Eliminate empty images
|
use crate::raster_types::__private::Sealed;
|
||||||
.flat_map(|instance| {
|
|
||||||
let transform = transform * *instance.transform;
|
#[derive(Clone, Debug, Default, PartialEq, Hash, DynAny)]
|
||||||
(transform.matrix2.determinant() != 0.).then(|| (transform * Quad::from_box([DVec2::ZERO, DVec2::ONE])).bounding_box())
|
pub struct CPU(Image<Color>);
|
||||||
})
|
|
||||||
.reduce(Quad::combine_bounds)
|
impl Sealed for Raster<CPU> {}
|
||||||
|
|
||||||
|
impl Storage for Raster<CPU> {
|
||||||
|
fn is_empty(&self) -> bool {
|
||||||
|
self.0.height == 0 || self.0.width == 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Raster<CPU> {
|
||||||
|
pub fn new_cpu(image: Image<Color>) -> Self {
|
||||||
|
Self::new(CPU(image))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn data(&self) -> &Image<Color> {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn data_mut(&mut self) -> &mut Image<Color> {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_data(self) -> Image<Color> {
|
||||||
|
self.storage.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for CPU {
|
||||||
|
type Target = Image<Color>;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DerefMut for CPU {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
&mut self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> serde::Deserialize<'de> for Raster<CPU> {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: serde::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
Ok(Raster::new_cpu(Image::deserialize(deserializer)?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl serde::Serialize for Raster<CPU> {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: serde::Serializer,
|
||||||
|
{
|
||||||
|
self.0.serialize(serializer)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BoundingBox for RasterDataTable<GPU> {
|
pub use gpu::GPU;
|
||||||
|
|
||||||
|
#[cfg(feature = "wgpu")]
|
||||||
|
mod gpu {
|
||||||
|
use super::*;
|
||||||
|
use crate::raster_types::__private::Sealed;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Hash)]
|
||||||
|
pub struct GPU {
|
||||||
|
texture: wgpu::Texture,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Sealed for Raster<GPU> {}
|
||||||
|
|
||||||
|
impl Storage for Raster<GPU> {
|
||||||
|
fn is_empty(&self) -> bool {
|
||||||
|
self.texture.width() == 0 || self.texture.height() == 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Raster<GPU> {
|
||||||
|
pub fn new_gpu(texture: wgpu::Texture) -> Self {
|
||||||
|
Self::new(GPU { texture })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn data(&self) -> &wgpu::Texture {
|
||||||
|
&self.texture
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "wgpu"))]
|
||||||
|
mod gpu {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct GPU;
|
||||||
|
|
||||||
|
impl Storage for Raster<GPU> {
|
||||||
|
fn is_empty(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod gpu_common {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
impl<'de> serde::Deserialize<'de> for Raster<GPU> {
|
||||||
|
fn deserialize<D>(_deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: serde::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl serde::Serialize for Raster<GPU> {
|
||||||
|
fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: serde::Serializer,
|
||||||
|
{
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> BoundingBox for RasterDataTable<T>
|
||||||
|
where
|
||||||
|
Raster<T>: Storage,
|
||||||
|
{
|
||||||
fn bounding_box(&self, transform: DAffine2, _include_stroke: bool) -> Option<[DVec2; 2]> {
|
fn bounding_box(&self, transform: DAffine2, _include_stroke: bool) -> Option<[DVec2; 2]> {
|
||||||
self.instance_ref_iter()
|
self.instance_ref_iter()
|
||||||
.filter(|instance| !instance.instance.is_empty()) // Eliminate empty images
|
.filter(|instance| !instance.instance.is_empty()) // Eliminate empty images
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue