Refactor vector data type from document-legacy into node graph (#1057)
Add vector data type
This commit is contained in:
parent
08b2782917
commit
4495488546
|
|
@ -1629,7 +1629,6 @@ dependencies = [
|
|||
"graphene-core",
|
||||
"log",
|
||||
"num-traits",
|
||||
"rand_chacha 0.3.1",
|
||||
"serde",
|
||||
"specta",
|
||||
]
|
||||
|
|
@ -1647,8 +1646,10 @@ dependencies = [
|
|||
"log",
|
||||
"node-macro",
|
||||
"once_cell",
|
||||
"rand_chacha 0.3.1",
|
||||
"serde",
|
||||
"specta",
|
||||
"spin 0.9.4",
|
||||
"spirv-std",
|
||||
]
|
||||
|
||||
|
|
@ -1738,12 +1739,10 @@ dependencies = [
|
|||
"kurbo",
|
||||
"log",
|
||||
"once_cell",
|
||||
"rand_chacha 0.3.1",
|
||||
"remain",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"specta",
|
||||
"spin 0.9.4",
|
||||
"test-case",
|
||||
"thiserror",
|
||||
]
|
||||
|
|
@ -2173,7 +2172,6 @@ dependencies = [
|
|||
"log",
|
||||
"num-traits",
|
||||
"once_cell",
|
||||
"rand_chacha 0.3.1",
|
||||
"serde",
|
||||
]
|
||||
|
||||
|
|
@ -5122,7 +5120,6 @@ dependencies = [
|
|||
"graphene-core",
|
||||
"log",
|
||||
"num-traits",
|
||||
"rand_chacha 0.3.1",
|
||||
"serde",
|
||||
"vulkano",
|
||||
]
|
||||
|
|
@ -5477,7 +5474,6 @@ dependencies = [
|
|||
"graphene-core",
|
||||
"log",
|
||||
"num-traits",
|
||||
"rand_chacha 0.3.1",
|
||||
"serde",
|
||||
"spirv",
|
||||
"wgpu",
|
||||
|
|
|
|||
|
|
@ -1,9 +1,3 @@
|
|||
use graphene_core::raster::color::Color;
|
||||
|
||||
// RENDERING
|
||||
pub const LAYER_OUTLINE_STROKE_COLOR: Color = Color::BLACK;
|
||||
pub const LAYER_OUTLINE_STROKE_WEIGHT: f64 = 1.;
|
||||
|
||||
// BOOLEAN OPERATIONS
|
||||
|
||||
// Bezier curve intersection algorithm
|
||||
|
|
|
|||
|
|
@ -25,6 +25,13 @@ pub mod layer_info;
|
|||
pub mod nodegraph_layer;
|
||||
/// Contains the [ShapeLayer](shape_layer::ShapeLayer) type, a generic SVG element defined using Bezier paths.
|
||||
pub mod shape_layer;
|
||||
pub mod style;
|
||||
/// Contains the [TextLayer](text_layer::TextLayer) type.
|
||||
pub mod text_layer;
|
||||
|
||||
mod render_data;
|
||||
pub use render_data::RenderData;
|
||||
|
||||
pub mod style {
|
||||
pub use super::RenderData;
|
||||
pub use graphene_core::vector::style::*;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
use super::style::ViewMode;
|
||||
use super::text_layer::FontCache;
|
||||
|
||||
use glam::DVec2;
|
||||
|
||||
/// Contains metadata for rendering the document as an svg
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct RenderData<'a> {
|
||||
pub font_cache: &'a FontCache,
|
||||
pub view_mode: ViewMode,
|
||||
pub culling_bounds: Option<[DVec2; 2]>,
|
||||
}
|
||||
|
||||
impl<'a> RenderData<'a> {
|
||||
pub fn new(font_cache: &'a FontCache, view_mode: ViewMode, culling_bounds: Option<[DVec2; 2]>) -> Self {
|
||||
Self {
|
||||
font_cache,
|
||||
view_mode,
|
||||
culling_bounds,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -23,8 +23,6 @@ serde_json = { version = "1.0" }
|
|||
graphite-proc-macros = { path = "../proc-macros" }
|
||||
bezier-rs = { path = "../libraries/bezier-rs" }
|
||||
glam = { version="0.22", features = ["serde"] }
|
||||
rand_chacha = "0.3.1"
|
||||
spin = "0.9.2"
|
||||
kurbo = { git = "https://github.com/linebender/kurbo.git", features = [
|
||||
"serde",
|
||||
] }
|
||||
|
|
|
|||
|
|
@ -1,15 +1,7 @@
|
|||
use crate::dispatcher::Dispatcher;
|
||||
use crate::messages::prelude::*;
|
||||
|
||||
use rand_chacha::rand_core::{RngCore, SeedableRng};
|
||||
use rand_chacha::ChaCha20Rng;
|
||||
use spin::Mutex;
|
||||
use std::cell::Cell;
|
||||
|
||||
static RNG: Mutex<Option<ChaCha20Rng>> = Mutex::new(None);
|
||||
thread_local! {
|
||||
pub static UUID_SEED: Cell<Option<u64>> = Cell::new(None);
|
||||
}
|
||||
pub use graphene_core::uuid::*;
|
||||
|
||||
// TODO: serialize with serde to save the current editor state
|
||||
pub struct Editor {
|
||||
|
|
@ -39,21 +31,6 @@ impl Default for Editor {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn set_uuid_seed(random_seed: u64) {
|
||||
UUID_SEED.with(|seed| seed.set(Some(random_seed)))
|
||||
}
|
||||
|
||||
pub fn generate_uuid() -> u64 {
|
||||
let mut lock = RNG.lock();
|
||||
if lock.is_none() {
|
||||
UUID_SEED.with(|seed| {
|
||||
let random_seed = seed.get().expect("Random seed not set before editor was initialized");
|
||||
*lock = Some(ChaCha20Rng::seed_from_u64(random_seed));
|
||||
})
|
||||
}
|
||||
lock.as_mut().map(ChaCha20Rng::next_u64).unwrap()
|
||||
}
|
||||
|
||||
pub fn release_series() -> String {
|
||||
format!("Release Series: {}", env!("GRAPHITE_RELEASE_SERIES"))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ kurbo = { git = "https://github.com/linebender/kurbo.git", features = [
|
|||
"serde",
|
||||
], optional = true }
|
||||
glam = { version = "^0.22", default-features = false, features = ["scalar-math", "libm"]}
|
||||
rand_chacha = "0.3.1"
|
||||
spin = "0.9.2"
|
||||
node-macro = {path = "../node-macro"}
|
||||
specta.workspace = true
|
||||
once_cell = { version = "1.17.0", default-features = false }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
use crate::raster::Color;
|
||||
|
||||
// RENDERING
|
||||
pub const LAYER_OUTLINE_STROKE_COLOR: Color = Color::BLACK;
|
||||
pub const LAYER_OUTLINE_STROKE_WEIGHT: f64 = 1.;
|
||||
|
|
@ -7,6 +7,7 @@ extern crate alloc;
|
|||
#[cfg(feature = "log")]
|
||||
extern crate log;
|
||||
|
||||
pub mod consts;
|
||||
pub mod generic;
|
||||
pub mod ops;
|
||||
pub mod structural;
|
||||
|
|
@ -22,6 +23,7 @@ pub mod raster;
|
|||
pub mod vector;
|
||||
|
||||
use core::any::TypeId;
|
||||
pub use raster::Color;
|
||||
|
||||
// pub trait Node: for<'n> NodeIO<'n> {
|
||||
pub trait Node<'i, Input: 'i>: 'i {
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ pub struct Color {
|
|||
alpha: f32,
|
||||
}
|
||||
|
||||
#[allow(clippy::derive_hash_xor_eq)]
|
||||
#[allow(clippy::derived_hash_with_manual_eq)]
|
||||
impl Hash for Color {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.red.to_bits().hash(state);
|
||||
|
|
|
|||
|
|
@ -40,3 +40,41 @@ mod u64_string {
|
|||
u64::from_str(&s).map_err(serde::de::Error::custom)
|
||||
}
|
||||
}
|
||||
|
||||
mod uuid_generation {
|
||||
use core::cell::Cell;
|
||||
use rand_chacha::rand_core::{RngCore, SeedableRng};
|
||||
use rand_chacha::ChaCha20Rng;
|
||||
use spin::Mutex;
|
||||
|
||||
static RNG: Mutex<Option<ChaCha20Rng>> = Mutex::new(None);
|
||||
thread_local! {
|
||||
pub static UUID_SEED: Cell<Option<u64>> = Cell::new(None);
|
||||
}
|
||||
|
||||
pub fn set_uuid_seed(random_seed: u64) {
|
||||
UUID_SEED.with(|seed| seed.set(Some(random_seed)))
|
||||
}
|
||||
|
||||
pub fn generate_uuid() -> u64 {
|
||||
let mut lock = RNG.lock();
|
||||
if lock.is_none() {
|
||||
UUID_SEED.with(|seed| {
|
||||
let random_seed = seed.get().unwrap_or(42);
|
||||
*lock = Some(ChaCha20Rng::seed_from_u64(random_seed));
|
||||
})
|
||||
}
|
||||
lock.as_mut().map(ChaCha20Rng::next_u64).expect("uuid mutex poisoned")
|
||||
}
|
||||
}
|
||||
|
||||
pub use uuid_generation::*;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
pub struct ManipulatorGroupId(u64);
|
||||
|
||||
impl bezier_rs::Identifier for ManipulatorGroupId {
|
||||
fn new() -> Self {
|
||||
Self(generate_uuid())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,16 @@
|
|||
pub mod consts;
|
||||
pub mod generator_nodes;
|
||||
pub mod id_vec;
|
||||
pub mod manipulator_group;
|
||||
pub mod manipulator_point;
|
||||
|
||||
pub mod style;
|
||||
pub use style::PathStyle;
|
||||
|
||||
pub mod subpath;
|
||||
pub use subpath::Subpath;
|
||||
|
||||
mod vector_data;
|
||||
pub use vector_data::VectorData;
|
||||
|
||||
mod id_vec;
|
||||
pub use id_vec::IdBackedVec;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
//! Contains stylistic options for SVG elements.
|
||||
|
||||
use super::text_layer::FontCache;
|
||||
use crate::consts::{LAYER_OUTLINE_STROKE_COLOR, LAYER_OUTLINE_STROKE_WEIGHT};
|
||||
|
||||
use graphene_core::raster::color::Color;
|
||||
use crate::Color;
|
||||
|
||||
use glam::{DAffine2, DVec2};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
|
@ -21,36 +19,6 @@ fn format_opacity(name: &str, opacity: f32) -> String {
|
|||
}
|
||||
}
|
||||
|
||||
/// Represents different ways of rendering an object
|
||||
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize, specta::Type)]
|
||||
pub enum ViewMode {
|
||||
/// Render with normal coloration at the current viewport resolution
|
||||
#[default]
|
||||
Normal,
|
||||
/// Render only the outlines of shapes at the current viewport resolution
|
||||
Outline,
|
||||
/// Render with normal coloration at the document resolution, showing the pixels when the current viewport resolution is higher
|
||||
Pixels,
|
||||
}
|
||||
|
||||
/// Contains metadata for rendering the document as an svg
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct RenderData<'a> {
|
||||
pub font_cache: &'a FontCache,
|
||||
pub view_mode: ViewMode,
|
||||
pub culling_bounds: Option<[DVec2; 2]>,
|
||||
}
|
||||
|
||||
impl<'a> RenderData<'a> {
|
||||
pub fn new(font_cache: &'a FontCache, view_mode: ViewMode, culling_bounds: Option<[DVec2; 2]>) -> Self {
|
||||
Self {
|
||||
font_cache,
|
||||
view_mode,
|
||||
culling_bounds,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, PartialEq, Eq, Clone, Copy, Debug, Hash, Serialize, Deserialize, specta::Type)]
|
||||
pub enum GradientType {
|
||||
#[default]
|
||||
|
|
@ -62,7 +30,7 @@ pub enum GradientType {
|
|||
///
|
||||
/// Contains the start and end points, along with the colors at varying points along the length.
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize, specta::Type)]
|
||||
#[derive(Debug, PartialEq, Default, Serialize, Deserialize, specta::Type)]
|
||||
pub struct Gradient {
|
||||
pub start: DVec2,
|
||||
pub end: DVec2,
|
||||
|
|
@ -71,7 +39,6 @@ pub struct Gradient {
|
|||
uuid: u64,
|
||||
pub gradient_type: GradientType,
|
||||
}
|
||||
|
||||
impl Gradient {
|
||||
/// Constructs a new gradient with the colors at 0 and 1 specified.
|
||||
pub fn new(start: DVec2, start_color: Color, end: DVec2, end_color: Color, transform: DAffine2, uuid: u64, gradient_type: GradientType) -> Self {
|
||||
|
|
@ -170,6 +137,21 @@ impl Gradient {
|
|||
}
|
||||
}
|
||||
|
||||
impl Clone for Gradient {
|
||||
/// Clones the gradient, with the cloned gradient having the new uuid.
|
||||
/// If multiple gradients have the same id then only one gradient will be shown in the final svg output.
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
start: self.start,
|
||||
end: self.end,
|
||||
transform: self.transform,
|
||||
positions: self.positions.clone(),
|
||||
uuid: crate::uuid::generate_uuid(),
|
||||
gradient_type: self.gradient_type,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes the fill of a layer.
|
||||
///
|
||||
/// Can be None, a solid [Color], a linear [Gradient], a radial [Gradient] or potentially some sort of image or pattern in the future
|
||||
|
|
@ -410,7 +392,7 @@ impl PathStyle {
|
|||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # use graphite_document_legacy::layers::style::{Fill, PathStyle};
|
||||
/// # use graphene_core::vector::style::{Fill, PathStyle};
|
||||
/// # use graphene_core::raster::color::Color;
|
||||
/// let fill = Fill::solid(Color::RED);
|
||||
/// let style = PathStyle::new(None, fill.clone());
|
||||
|
|
@ -425,7 +407,7 @@ impl PathStyle {
|
|||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # use graphite_document_legacy::layers::style::{Fill, Stroke, PathStyle};
|
||||
/// # use graphene_core::vector::style::{Fill, Stroke, PathStyle};
|
||||
/// # use graphene_core::raster::color::Color;
|
||||
/// let stroke = Stroke::new(Color::GREEN, 42.);
|
||||
/// let style = PathStyle::new(Some(stroke.clone()), Fill::None);
|
||||
|
|
@ -440,7 +422,7 @@ impl PathStyle {
|
|||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # use graphite_document_legacy::layers::style::{Fill, PathStyle};
|
||||
/// # use graphene_core::vector::style::{Fill, PathStyle};
|
||||
/// # use graphene_core::raster::color::Color;
|
||||
/// let mut style = PathStyle::default();
|
||||
///
|
||||
|
|
@ -459,7 +441,7 @@ impl PathStyle {
|
|||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # use graphite_document_legacy::layers::style::{Stroke, PathStyle};
|
||||
/// # use graphene_core::vector::style::{Stroke, PathStyle};
|
||||
/// # use graphene_core::raster::color::Color;
|
||||
/// let mut style = PathStyle::default();
|
||||
///
|
||||
|
|
@ -478,7 +460,7 @@ impl PathStyle {
|
|||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # use graphite_document_legacy::layers::style::{Fill, PathStyle};
|
||||
/// # use graphene_core::vector::style::{Fill, PathStyle};
|
||||
/// # use graphene_core::raster::color::Color;
|
||||
/// let mut style = PathStyle::new(None, Fill::Solid(Color::RED));
|
||||
///
|
||||
|
|
@ -496,7 +478,7 @@ impl PathStyle {
|
|||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # use graphite_document_legacy::layers::style::{Fill, Stroke, PathStyle};
|
||||
/// # use graphene_core::vector::style::{Fill, Stroke, PathStyle};
|
||||
/// # use graphene_core::raster::color::Color;
|
||||
/// let mut style = PathStyle::new(Some(Stroke::new(Color::GREEN, 42.)), Fill::None);
|
||||
///
|
||||
|
|
@ -524,3 +506,15 @@ impl PathStyle {
|
|||
format!("{}{}", fill_attribute, stroke_attribute)
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents different ways of rendering an object
|
||||
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize, specta::Type)]
|
||||
pub enum ViewMode {
|
||||
/// Render with normal coloration at the current viewport resolution
|
||||
#[default]
|
||||
Normal,
|
||||
/// Render only the outlines of shapes at the current viewport resolution
|
||||
Outline,
|
||||
/// Render with normal coloration at the document resolution, showing the pixels when the current viewport resolution is higher
|
||||
Pixels,
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
use glam::DAffine2;
|
||||
|
||||
use super::style::PathStyle;
|
||||
use crate::uuid::ManipulatorGroupId;
|
||||
|
||||
/// [VectorData] is passed between nodes.
|
||||
/// It contains a list of subpaths (that may be open or closed), a transform and some style information.
|
||||
pub struct VectorData {
|
||||
pub subpaths: Vec<bezier_rs::Subpath<ManipulatorGroupId>>,
|
||||
pub transform: DAffine2,
|
||||
pub style: PathStyle,
|
||||
}
|
||||
|
|
@ -16,7 +16,6 @@ graphene-core = { path = "../gcore", features = ["async", "std", "alloc"] }
|
|||
graph-craft = {path = "../graph-craft", features = ["serde"] }
|
||||
dyn-any = { path = "../../libraries/dyn-any", features = ["log-bad-types", "rc", "glam"] }
|
||||
num-traits = "0.2"
|
||||
rand_chacha = "0.3.1"
|
||||
log = "0.4"
|
||||
serde = { version = "1", features = ["derive", "rc"]}
|
||||
glam = { version = "0.22" }
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ graphene-core = { path = "../gcore", features = ["std"] }
|
|||
dyn-any = { path = "../../libraries/dyn-any", features = ["log-bad-types", "rc", "glam"] }
|
||||
num-traits = "0.2"
|
||||
dyn-clone = "1.0"
|
||||
rand_chacha = "0.3.1"
|
||||
log = "0.4"
|
||||
serde = { version = "1", features = ["derive", "rc"], optional = true }
|
||||
glam = { version = "0.22" }
|
||||
|
|
|
|||
|
|
@ -4,27 +4,14 @@ use graphene_core::{NodeIdentifier, Type};
|
|||
|
||||
use dyn_any::{DynAny, StaticType};
|
||||
use glam::IVec2;
|
||||
pub use graphene_core::uuid::generate_uuid;
|
||||
use graphene_core::TypeDescriptor;
|
||||
use rand_chacha::{
|
||||
rand_core::{RngCore, SeedableRng},
|
||||
ChaCha20Rng,
|
||||
};
|
||||
use std::borrow::Cow;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::sync::Mutex;
|
||||
|
||||
pub mod value;
|
||||
|
||||
pub type NodeId = u64;
|
||||
static RNG: Mutex<Option<ChaCha20Rng>> = Mutex::new(None);
|
||||
|
||||
pub fn generate_uuid() -> u64 {
|
||||
let mut lock = RNG.lock().expect("uuid mutex poisoned");
|
||||
if lock.is_none() {
|
||||
*lock = Some(ChaCha20Rng::seed_from_u64(0));
|
||||
}
|
||||
lock.as_mut().map(ChaCha20Rng::next_u64).unwrap()
|
||||
}
|
||||
|
||||
fn merge_ids(a: u64, b: u64) -> u64 {
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ dyn-any = { path = "../../libraries/dyn-any", features = ["log-bad-types", "glam
|
|||
num-traits = "0.2"
|
||||
borrow_stack = { path = "../borrow_stack" }
|
||||
dyn-clone = "1.0"
|
||||
rand_chacha = "0.3.1"
|
||||
log = "0.4"
|
||||
serde = { version = "1", features = ["derive"], optional = true }
|
||||
glam = { version = "0.22" }
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ graphene-core = { path = "../gcore", features = ["async", "std", "alloc", "gpu"]
|
|||
graph-craft = {path = "../graph-craft" }
|
||||
dyn-any = { path = "../../libraries/dyn-any", features = ["log-bad-types", "rc", "glam"] }
|
||||
num-traits = "0.2"
|
||||
rand_chacha = "0.3.1"
|
||||
log = "0.4"
|
||||
serde = { version = "1", features = ["derive", "rc"], optional = true }
|
||||
glam = { version = "0.22" }
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ graph-craft = {path = "../graph-craft" }
|
|||
dyn-any = { path = "../../libraries/dyn-any", features = ["log-bad-types", "rc", "glam"] }
|
||||
future-executor = { path = "../future-executor" }
|
||||
num-traits = "0.2"
|
||||
rand_chacha = "0.3.1"
|
||||
log = "0.4"
|
||||
serde = { version = "1", features = ["derive", "rc"], optional = true }
|
||||
glam = { version = "0.22" }
|
||||
|
|
|
|||
Loading…
Reference in New Issue