diff --git a/Cargo.lock b/Cargo.lock index 773c72ca7..7732bc2b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1706,6 +1706,7 @@ dependencies = [ "bezier-rs", "glam", "graph-craft", + "graphene-core", "graphene-std", "image", "kurbo", diff --git a/document-legacy/Cargo.toml b/document-legacy/Cargo.toml index 65766fb22..8342c377d 100644 --- a/document-legacy/Cargo.toml +++ b/document-legacy/Cargo.toml @@ -13,6 +13,7 @@ license = "Apache-2.0" [dependencies] graph-craft = { path = "../node-graph/graph-craft", features = ["serde"] } graphene-std = { path = "../node-graph/gstd", features = ["serde"] } +graphene-core = { path = "../node-graph/gcore", features = ["serde"] } image = { version = "0.24", default-features = false } log = "0.4" diff --git a/document-legacy/src/color.rs b/document-legacy/src/color.rs deleted file mode 100644 index 75be8bf7a..000000000 --- a/document-legacy/src/color.rs +++ /dev/null @@ -1,221 +0,0 @@ -use serde::{Deserialize, Serialize}; - -/// Structure that represents a color. -/// Internally alpha is stored as `f32` that ranges from `0.0` (transparent) to `1.0` (opaque). -/// The other components (RGB) are stored as `f32` that range from `0.0` up to `f32::MAX`, -/// the values encode the brightness of each channel proportional to the light intensity in cd/m² (nits) in HDR, and `0.0` (black) to `1.0` (white) in SDR color. -#[repr(C)] -#[derive(Debug, Clone, Copy, PartialEq, Default, Serialize, Deserialize, specta::Type)] -pub struct Color { - red: f32, - green: f32, - blue: f32, - alpha: f32, -} - -impl Color { - pub const BLACK: Color = Color::from_uchecked(0., 0., 0.); - pub const WHITE: Color = Color::from_uchecked(1., 1., 1.); - pub const RED: Color = Color::from_uchecked(1., 0., 0.); - pub const GREEN: Color = Color::from_uchecked(0., 1., 0.); - pub const BLUE: Color = Color::from_uchecked(0., 0., 1.); - pub const TRANSPARENT: Color = Self { - red: 0., - green: 0., - blue: 0., - alpha: 0., - }; - - /// Returns `Some(Color)` if `red`, `green`, `blue` and `alpha` have a valid value. Negative numbers (including `-0.0`), NaN, and infinity are not valid values and return `None`. - /// Alpha values greater than `1.0` are not valid. - /// - /// # Examples - /// ``` - /// use graphite_document_legacy::color::Color; - /// let color = Color::from_rgbaf32(0.3, 0.14, 0.15, 0.92).unwrap(); - /// assert!(color.components() == (0.3, 0.14, 0.15, 0.92)); - /// - /// let color = Color::from_rgbaf32(1.0, 1.0, 1.0, f32::NAN); - /// assert!(color == None); - /// ``` - pub fn from_rgbaf32(red: f32, green: f32, blue: f32, alpha: f32) -> Option { - if alpha > 1. || [red, green, blue, alpha].iter().any(|c| c.is_sign_negative() || !c.is_finite()) { - return None; - } - Some(Color { red, green, blue, alpha }) - } - - /// Return an opaque `Color` from given `f32` RGB channels. - pub const fn from_uchecked(red: f32, green: f32, blue: f32) -> Color { - Color { red, green, blue, alpha: 1. } - } - - /// Return an opaque SDR `Color` given RGB channels from `0` to `255`. - /// - /// # Examples - /// ``` - /// use graphite_document_legacy::color::Color; - /// let color = Color::from_rgb8(0x72, 0x67, 0x62); - /// let color2 = Color::from_rgba8(0x72, 0x67, 0x62, 0xFF); - /// assert!(color == color2) - /// ``` - pub fn from_rgb8(red: u8, green: u8, blue: u8) -> Color { - Color::from_rgba8(red, green, blue, 255) - } - - /// Return an SDR `Color` given RGBA channels from `0` to `255`. - /// - /// # Examples - /// ``` - /// use graphite_document_legacy::color::Color; - /// let color = Color::from_rgba8(0x72, 0x67, 0x62, 0x61); - /// assert!("72676261" == color.rgba_hex()) - /// ``` - pub fn from_rgba8(red: u8, green: u8, blue: u8, alpha: u8) -> Color { - let map_range = |int_color| int_color as f32 / 255.0; - Color { - red: map_range(red), - green: map_range(green), - blue: map_range(blue), - alpha: map_range(alpha), - } - } - - /// Return the `red` component. - /// - /// # Examples - /// ``` - /// use graphite_document_legacy::color::Color; - /// let color = Color::from_rgbaf32(0.114, 0.103, 0.98, 0.97).unwrap(); - /// assert!(color.r() == 0.114); - /// ``` - pub fn r(&self) -> f32 { - self.red - } - - /// Return the `green` component. - /// - /// # Examples - /// ``` - /// use graphite_document_legacy::color::Color; - /// let color = Color::from_rgbaf32(0.114, 0.103, 0.98, 0.97).unwrap(); - /// assert!(color.g() == 0.103); - /// ``` - pub fn g(&self) -> f32 { - self.green - } - - /// Return the `blue` component. - /// - /// # Examples - /// ``` - /// use graphite_document_legacy::color::Color; - /// let color = Color::from_rgbaf32(0.114, 0.103, 0.98, 0.97).unwrap(); - /// assert!(color.b() == 0.98); - /// ``` - pub fn b(&self) -> f32 { - self.blue - } - - /// Return the `alpha` component without checking its expected `0.0` to `1.0` range. - /// - /// # Examples - /// ``` - /// use graphite_document_legacy::color::Color; - /// let color = Color::from_rgbaf32(0.114, 0.103, 0.98, 0.97).unwrap(); - /// assert!(color.a() == 0.97); - /// ``` - pub fn a(&self) -> f32 { - self.alpha - } - - /// Return the all components as a tuple, first component is red, followed by green, followed by blue, followed by alpha. - /// - /// # Examples - /// ``` - /// use graphite_document_legacy::color::Color; - /// let color = Color::from_rgbaf32(0.114, 0.103, 0.98, 0.97).unwrap(); - /// assert!(color.components() == (0.114, 0.103, 0.98, 0.97)); - /// ``` - pub fn components(&self) -> (f32, f32, f32, f32) { - (self.red, self.green, self.blue, self.alpha) - } - - /// Return an 8-character RGBA hex string (without a # prefix). - /// - /// # Examples - /// ``` - /// use graphite_document_legacy::color::Color; - /// let color = Color::from_rgba8(0x7C, 0x67, 0xFA, 0x61); - /// assert!("7C67FA61" == color.rgba_hex()) - /// ``` - pub fn rgba_hex(&self) -> String { - format!( - "{:02X?}{:02X?}{:02X?}{:02X?}", - (self.r() * 255.) as u8, - (self.g() * 255.) as u8, - (self.b() * 255.) as u8, - (self.a() * 255.) as u8, - ) - } - - /// Return a 6-character RGB hex string (without a # prefix). - /// ``` - /// use graphite_document_legacy::color::Color; - /// let color = Color::from_rgba8(0x7C, 0x67, 0xFA, 0x61); - /// assert!("7C67FA" == color.rgb_hex()) - /// ``` - pub fn rgb_hex(&self) -> String { - format!("{:02X?}{:02X?}{:02X?}", (self.r() * 255.) as u8, (self.g() * 255.) as u8, (self.b() * 255.) as u8,) - } - - /// Creates a color from a 8-character RGBA hex string (without a # prefix). - /// - /// # Examples - /// ``` - /// use graphite_document_legacy::color::Color; - /// let color = Color::from_rgba_str("7C67FA61").unwrap(); - /// assert!("7C67FA61" == color.rgba_hex()) - /// ``` - pub fn from_rgba_str(color_str: &str) -> Option { - if color_str.len() != 8 { - return None; - } - let r = u8::from_str_radix(&color_str[0..2], 16).ok()?; - let g = u8::from_str_radix(&color_str[2..4], 16).ok()?; - let b = u8::from_str_radix(&color_str[4..6], 16).ok()?; - let a = u8::from_str_radix(&color_str[6..8], 16).ok()?; - - Some(Color::from_rgba8(r, g, b, a)) - } - - /// Creates a color from a 6-character RGB hex string (without a # prefix). - /// ``` - /// use graphite_document_legacy::color::Color; - /// let color = Color::from_rgb_str("7C67FA").unwrap(); - /// assert!("7C67FA" == color.rgb_hex()) - /// ``` - pub fn from_rgb_str(color_str: &str) -> Option { - if color_str.len() != 6 { - return None; - } - let r = u8::from_str_radix(&color_str[0..2], 16).ok()?; - let g = u8::from_str_radix(&color_str[2..4], 16).ok()?; - let b = u8::from_str_radix(&color_str[4..6], 16).ok()?; - - Some(Color::from_rgb8(r, g, b)) - } - - /// Linearly interpolates between two colors based on t. - /// - /// T must be between 0 and 1. - pub fn lerp(self, other: Color, t: f32) -> Option { - assert!((0. ..=1.).contains(&t)); - Color::from_rgbaf32( - self.red + ((other.red - self.red) * t), - self.green + ((other.green - self.green) * t), - self.blue + ((other.blue - self.blue) * t), - self.alpha + ((other.alpha - self.alpha) * t), - ) - } -} diff --git a/document-legacy/src/consts.rs b/document-legacy/src/consts.rs index f3d0d66aa..1521cec34 100644 --- a/document-legacy/src/consts.rs +++ b/document-legacy/src/consts.rs @@ -1,4 +1,4 @@ -use crate::color::Color; +use graphene_core::raster::color::Color; // RENDERING pub const LAYER_OUTLINE_STROKE_COLOR: Color = Color::BLACK; diff --git a/document-legacy/src/layers/style/mod.rs b/document-legacy/src/layers/style/mod.rs index bf0884280..c86991dd2 100644 --- a/document-legacy/src/layers/style/mod.rs +++ b/document-legacy/src/layers/style/mod.rs @@ -1,9 +1,10 @@ //! Contains stylistic options for SVG elements. use super::text_layer::FontCache; -use crate::color::Color; use crate::consts::{LAYER_OUTLINE_STROKE_COLOR, LAYER_OUTLINE_STROKE_WEIGHT}; +use graphene_core::raster::color::Color; + use glam::{DAffine2, DVec2}; use serde::{Deserialize, Serialize}; use std::fmt::{self, Display, Write}; @@ -410,7 +411,7 @@ impl PathStyle { /// # Example /// ``` /// # use graphite_document_legacy::layers::style::{Fill, PathStyle}; - /// # use graphite_document_legacy::color::Color; + /// # use graphene_core::raster::color::Color; /// let fill = Fill::solid(Color::RED); /// let style = PathStyle::new(None, fill.clone()); /// @@ -425,7 +426,7 @@ impl PathStyle { /// # Example /// ``` /// # use graphite_document_legacy::layers::style::{Fill, Stroke, PathStyle}; - /// # use graphite_document_legacy::color::Color; + /// # use graphene_core::raster::color::Color; /// let stroke = Stroke::new(Color::GREEN, 42.); /// let style = PathStyle::new(Some(stroke.clone()), Fill::None); /// @@ -440,7 +441,7 @@ impl PathStyle { /// # Example /// ``` /// # use graphite_document_legacy::layers::style::{Fill, PathStyle}; - /// # use graphite_document_legacy::color::Color; + /// # use graphene_core::raster::color::Color; /// let mut style = PathStyle::default(); /// /// assert_eq!(*style.fill(), Fill::None); @@ -459,7 +460,7 @@ impl PathStyle { /// # Example /// ``` /// # use graphite_document_legacy::layers::style::{Stroke, PathStyle}; - /// # use graphite_document_legacy::color::Color; + /// # use graphene_core::raster::color::Color; /// let mut style = PathStyle::default(); /// /// assert_eq!(style.stroke(), None); @@ -478,7 +479,7 @@ impl PathStyle { /// # Example /// ``` /// # use graphite_document_legacy::layers::style::{Fill, PathStyle}; - /// # use graphite_document_legacy::color::Color; + /// # use graphene_core::raster::color::Color; /// let mut style = PathStyle::new(None, Fill::Solid(Color::RED)); /// /// assert!(style.fill().is_some()); @@ -496,7 +497,7 @@ impl PathStyle { /// # Example /// ``` /// # use graphite_document_legacy::layers::style::{Fill, Stroke, PathStyle}; - /// # use graphite_document_legacy::color::Color; + /// # use graphene_core::raster::color::Color; /// let mut style = PathStyle::new(Some(Stroke::new(Color::GREEN, 42.)), Fill::None); /// /// assert!(style.stroke().is_some()); diff --git a/document-legacy/src/lib.rs b/document-legacy/src/lib.rs index f7483baae..b0e232e24 100644 --- a/document-legacy/src/lib.rs +++ b/document-legacy/src/lib.rs @@ -3,8 +3,6 @@ extern crate log; pub mod boolean_ops; -/// Contains the [Color](color::Color) type. -pub mod color; /// Contains constant values used by this crate. pub mod consts; pub mod document; diff --git a/editor/src/consts.rs b/editor/src/consts.rs index 3a372c128..b8f3bb9f6 100644 --- a/editor/src/consts.rs +++ b/editor/src/consts.rs @@ -1,4 +1,4 @@ -use document_legacy::color::Color; +use graphene_core::raster::color::Color; // Viewport pub const VIEWPORT_ZOOM_WHEEL_RATE: f64 = (1. / 600.) * 3.; @@ -68,7 +68,7 @@ pub const ASYMPTOTIC_EFFECT: f64 = 0.5; pub const SCALE_EFFECT: f64 = 0.5; // Colors -pub const COLOR_ACCENT: Color = Color::from_uchecked(0x00 as f32 / 255., 0xA8 as f32 / 255., 0xFF as f32 / 255.); +pub const COLOR_ACCENT: Color = Color::from_rgbf32_unchecked(0x00 as f32 / 255., 0xA8 as f32 / 255., 0xFF as f32 / 255.); // Fonts pub const DEFAULT_FONT_FAMILY: &str = "Merriweather"; diff --git a/editor/src/dispatcher.rs b/editor/src/dispatcher.rs index 8823ca17c..da5ff9b75 100644 --- a/editor/src/dispatcher.rs +++ b/editor/src/dispatcher.rs @@ -255,9 +255,9 @@ mod test { use crate::messages::prelude::*; use crate::test_utils::EditorTestUtils; - use document_legacy::color::Color; use document_legacy::LayerId; use document_legacy::Operation; + use graphene_core::raster::color::Color; fn init_logger() { let _ = env_logger::builder().is_test(true).try_init(); diff --git a/editor/src/messages/frontend/frontend_message.rs b/editor/src/messages/frontend/frontend_message.rs index d85f40682..133815248 100644 --- a/editor/src/messages/frontend/frontend_message.rs +++ b/editor/src/messages/frontend/frontend_message.rs @@ -7,11 +7,11 @@ use crate::messages::portfolio::document::utility_types::layer_panel::{JsRawBuff use crate::messages::prelude::*; use crate::messages::tool::utility_types::HintData; -use document_legacy::color::Color; use document_legacy::layers::text_layer::Font; use document_legacy::LayerId; use graph_craft::document::NodeId; use graph_craft::imaginate_input::*; +use graphene_core::raster::color::Color; use serde::{Deserialize, Serialize}; diff --git a/editor/src/messages/layout/layout_message_handler.rs b/editor/src/messages/layout/layout_message_handler.rs index eb494aa84..8b74ad3e8 100644 --- a/editor/src/messages/layout/layout_message_handler.rs +++ b/editor/src/messages/layout/layout_message_handler.rs @@ -5,9 +5,9 @@ use crate::messages::layout::utility_types::layout_widget::{DiffUpdate, Widget}; use crate::messages::layout::utility_types::layout_widget::{Layout, WidgetLayout}; use crate::messages::prelude::*; -use document_legacy::color::Color; use document_legacy::layers::text_layer::Font; use document_legacy::LayerId; +use graphene_core::raster::color::Color; use serde_json::Value; use std::ops::Not; diff --git a/editor/src/messages/layout/utility_types/widgets/input_widgets.rs b/editor/src/messages/layout/utility_types/widgets/input_widgets.rs index 5d496f20f..493ef299c 100644 --- a/editor/src/messages/layout/utility_types/widgets/input_widgets.rs +++ b/editor/src/messages/layout/utility_types/widgets/input_widgets.rs @@ -1,9 +1,9 @@ use crate::messages::input_mapper::utility_types::misc::ActionKeys; use crate::messages::layout::utility_types::layout_widget::WidgetCallback; -use document_legacy::color::Color; use document_legacy::layers::layer_info::LayerDataTypeDiscriminant; use document_legacy::LayerId; +use graphene_core::raster::color::Color; use graphite_proc_macros::WidgetBuilder; use derivative::*; diff --git a/editor/src/messages/portfolio/document/artboard/artboard_message_handler.rs b/editor/src/messages/portfolio/document/artboard/artboard_message_handler.rs index d242cfd2e..47c35510c 100644 --- a/editor/src/messages/portfolio/document/artboard/artboard_message_handler.rs +++ b/editor/src/messages/portfolio/document/artboard/artboard_message_handler.rs @@ -2,12 +2,12 @@ use crate::application::generate_uuid; use crate::messages::portfolio::utility_types::PersistentData; use crate::messages::prelude::*; -use document_legacy::color::Color; use document_legacy::document::Document as DocumentLegacy; use document_legacy::layers::style::{self, Fill, RenderData, ViewMode}; use document_legacy::DocumentResponse; use document_legacy::LayerId; use document_legacy::Operation as DocumentOperation; +use graphene_core::raster::color::Color; use glam::DAffine2; use serde::{Deserialize, Serialize}; diff --git a/editor/src/messages/portfolio/document/document_message_handler.rs b/editor/src/messages/portfolio/document/document_message_handler.rs index fe600061e..65415fe86 100644 --- a/editor/src/messages/portfolio/document/document_message_handler.rs +++ b/editor/src/messages/portfolio/document/document_message_handler.rs @@ -23,7 +23,6 @@ use crate::messages::prelude::*; use crate::messages::tool::utility_types::ToolType; use document_legacy::boolean_ops::BooleanOperationError; -use document_legacy::color::Color; use document_legacy::document::Document as DocumentLegacy; use document_legacy::layers::blend_mode::BlendMode; use document_legacy::layers::folder_layer::FolderLayer; @@ -32,6 +31,7 @@ use document_legacy::layers::style::{Fill, RenderData, ViewMode}; use document_legacy::layers::text_layer::Font; use document_legacy::{DocumentError, DocumentResponse, LayerId, Operation as DocumentOperation}; use graph_craft::document::NodeId; +use graphene_core::raster::color::Color; use graphene_std::vector::subpath::Subpath; use glam::{DAffine2, DVec2}; diff --git a/editor/src/messages/portfolio/document/properties_panel/utility_functions.rs b/editor/src/messages/portfolio/document/properties_panel/utility_functions.rs index 764bd49e2..5d2ea0c09 100644 --- a/editor/src/messages/portfolio/document/properties_panel/utility_functions.rs +++ b/editor/src/messages/portfolio/document/properties_panel/utility_functions.rs @@ -9,11 +9,11 @@ use crate::messages::layout::utility_types::widgets::label_widgets::{IconLabel, use crate::messages::portfolio::utility_types::PersistentData; use crate::messages::prelude::*; -use document_legacy::color::Color; use document_legacy::document::Document; use document_legacy::layers::layer_info::{Layer, LayerDataType, LayerDataTypeDiscriminant}; use document_legacy::layers::style::{Fill, Gradient, GradientType, LineCap, LineJoin, RenderData, Stroke, ViewMode}; use document_legacy::layers::text_layer::TextLayer; +use graphene_core::raster::color::Color; use glam::{DAffine2, DVec2}; use std::f64::consts::PI; diff --git a/editor/src/messages/portfolio/document/utility_types/error.rs b/editor/src/messages/portfolio/document/utility_types/error.rs index 6ac1737e9..4238f8121 100644 --- a/editor/src/messages/portfolio/document/utility_types/error.rs +++ b/editor/src/messages/portfolio/document/utility_types/error.rs @@ -1,5 +1,5 @@ -use document_legacy::color::Color; use document_legacy::DocumentError; +use graphene_core::raster::color::Color; use thiserror::Error; diff --git a/editor/src/messages/portfolio/document/utility_types/misc.rs b/editor/src/messages/portfolio/document/utility_types/misc.rs index 17fd573ba..135495b6e 100644 --- a/editor/src/messages/portfolio/document/utility_types/misc.rs +++ b/editor/src/messages/portfolio/document/utility_types/misc.rs @@ -1,9 +1,9 @@ pub use super::layer_panel::{LayerMetadata, LayerPanelEntry}; use crate::messages::prelude::ArtboardMessageHandler; -use document_legacy::color::Color; use document_legacy::document::Document as DocumentLegacy; use document_legacy::LayerId; +use graphene_core::raster::color::Color; use serde::{Deserialize, Serialize}; use std::collections::HashMap; diff --git a/editor/src/messages/portfolio/portfolio_message_handler.rs b/editor/src/messages/portfolio/portfolio_message_handler.rs index 54ff9d97a..3ada78c16 100644 --- a/editor/src/messages/portfolio/portfolio_message_handler.rs +++ b/editor/src/messages/portfolio/portfolio_message_handler.rs @@ -838,7 +838,7 @@ impl PortfolioMessageHandler { let old_transforms = document.remove_document_transform(); let mask_is_some = mask_path.is_some(); let mask_image = mask_path.filter(|mask_layer_path| document.document_legacy.layer(mask_layer_path).is_ok()).map(|mask_layer_path| { - let render_mode = DocumentRenderMode::LayerCutout(&mask_layer_path, document_legacy::color::Color::WHITE); + let render_mode = DocumentRenderMode::LayerCutout(&mask_layer_path, graphene_core::raster::color::Color::WHITE); let svg = document.render_document(size, transform.inverse(), &self.persistent_data, render_mode); ImaginateMaskImage { svg, size } diff --git a/editor/src/messages/tool/common_functionality/overlay_renderer.rs b/editor/src/messages/tool/common_functionality/overlay_renderer.rs index 7f834d7c7..e057f0529 100644 --- a/editor/src/messages/tool/common_functionality/overlay_renderer.rs +++ b/editor/src/messages/tool/common_functionality/overlay_renderer.rs @@ -3,10 +3,10 @@ use crate::consts::VIEWPORT_GRID_ROUNDING_BIAS; use crate::consts::{COLOR_ACCENT, HIDE_HANDLE_DISTANCE, MANIPULATOR_GROUP_MARKER_SIZE, PATH_OUTLINE_WEIGHT}; use crate::messages::prelude::*; -use document_legacy::color::Color; use document_legacy::document::Document; use document_legacy::layers::style::{self, Fill, Stroke}; use document_legacy::{LayerId, Operation}; +use graphene_core::raster::color::Color; use graphene_std::vector::consts::ManipulatorType; use graphene_std::vector::manipulator_group::ManipulatorGroup; use graphene_std::vector::manipulator_point::ManipulatorPoint; diff --git a/editor/src/messages/tool/common_functionality/pivot.rs b/editor/src/messages/tool/common_functionality/pivot.rs index 34e12b737..7aed0c459 100644 --- a/editor/src/messages/tool/common_functionality/pivot.rs +++ b/editor/src/messages/tool/common_functionality/pivot.rs @@ -114,7 +114,7 @@ impl Pivot { transform: DAffine2::IDENTITY.to_cols_array(), style: style::PathStyle::new( Some(style::Stroke::new(COLOR_ACCENT, PIVOT_OUTER_OUTLINE_THICKNESS)), - style::Fill::Solid(document_legacy::color::Color::WHITE), + style::Fill::Solid(graphene_core::raster::color::Color::WHITE), ), insert_index: -1, } diff --git a/editor/src/messages/tool/common_functionality/transformation_cage.rs b/editor/src/messages/tool/common_functionality/transformation_cage.rs index 59b69eb1d..8cd61469a 100644 --- a/editor/src/messages/tool/common_functionality/transformation_cage.rs +++ b/editor/src/messages/tool/common_functionality/transformation_cage.rs @@ -4,10 +4,10 @@ use crate::messages::frontend::utility_types::MouseCursorIcon; use crate::messages::portfolio::document::utility_types::transformation::OriginalTransforms; use crate::messages::prelude::*; -use document_legacy::color::Color; use document_legacy::layers::style::{self, Fill, Stroke}; use document_legacy::LayerId; use document_legacy::Operation; +use graphene_core::raster::color::Color; use glam::{DAffine2, DVec2}; diff --git a/editor/src/messages/tool/tool_message.rs b/editor/src/messages/tool/tool_message.rs index ddfa87260..6a7687584 100644 --- a/editor/src/messages/tool/tool_message.rs +++ b/editor/src/messages/tool/tool_message.rs @@ -1,7 +1,7 @@ use super::utility_types::ToolType; use crate::messages::prelude::*; -use document_legacy::color::Color; +use graphene_core::raster::color::Color; use serde::{Deserialize, Serialize}; diff --git a/editor/src/messages/tool/tool_message_handler.rs b/editor/src/messages/tool/tool_message_handler.rs index 74c02c210..f3dbb0192 100644 --- a/editor/src/messages/tool/tool_message_handler.rs +++ b/editor/src/messages/tool/tool_message_handler.rs @@ -6,8 +6,8 @@ use crate::messages::portfolio::utility_types::PersistentData; use crate::messages::prelude::*; use crate::messages::tool::utility_types::ToolType; -use document_legacy::color::Color; use document_legacy::layers::style::RenderData; +use graphene_core::raster::color::Color; #[derive(Debug, Default)] pub struct ToolMessageHandler { diff --git a/editor/src/messages/tool/tool_messages/gradient_tool.rs b/editor/src/messages/tool/tool_messages/gradient_tool.rs index 08e44a23f..3022bbffc 100644 --- a/editor/src/messages/tool/tool_messages/gradient_tool.rs +++ b/editor/src/messages/tool/tool_messages/gradient_tool.rs @@ -9,12 +9,12 @@ use crate::messages::tool::common_functionality::snapping::SnapManager; use crate::messages::tool::utility_types::{EventToMessageMap, Fsm, ToolActionHandlerData, ToolMetadata, ToolTransition, ToolType}; use crate::messages::tool::utility_types::{HintData, HintGroup, HintInfo}; -use document_legacy::color::Color; use document_legacy::intersection::Quad; use document_legacy::layers::layer_info::Layer; use document_legacy::layers::style::{Fill, Gradient, GradientType, PathStyle, RenderData, Stroke}; use document_legacy::LayerId; use document_legacy::Operation; +use graphene_core::raster::color::Color; use glam::{DAffine2, DVec2}; use serde::{Deserialize, Serialize}; diff --git a/editor/src/messages/tool/utility_types.rs b/editor/src/messages/tool/utility_types.rs index cadd85ebc..c051b67ee 100644 --- a/editor/src/messages/tool/utility_types.rs +++ b/editor/src/messages/tool/utility_types.rs @@ -9,8 +9,8 @@ use crate::messages::layout::utility_types::widgets::input_widgets::SwatchPairIn use crate::messages::layout::utility_types::widgets::label_widgets::{Separator, SeparatorDirection, SeparatorType}; use crate::messages::prelude::*; -use document_legacy::color::Color; use document_legacy::layers::style::RenderData; +use graphene_core::raster::color::Color; use serde::{Deserialize, Serialize}; use std::fmt::{self, Debug}; diff --git a/editor/src/test_utils.rs b/editor/src/test_utils.rs index 2c8afcb02..8b6657e8a 100644 --- a/editor/src/test_utils.rs +++ b/editor/src/test_utils.rs @@ -6,7 +6,7 @@ use crate::messages::portfolio::utility_types::Platform; use crate::messages::prelude::*; use crate::messages::tool::utility_types::ToolType; -use document_legacy::color::Color; +use graphene_core::raster::color::Color; /// A set of utility functions to make the writing of editor test more declarative pub trait EditorTestUtils { diff --git a/frontend-svelte/wasm/src/editor_api.rs b/frontend-svelte/wasm/src/editor_api.rs index a50926bb7..7f5c97986 100644 --- a/frontend-svelte/wasm/src/editor_api.rs +++ b/frontend-svelte/wasm/src/editor_api.rs @@ -5,7 +5,6 @@ use crate::helpers::{translate_key, Error}; use crate::{EDITOR_HAS_CRASHED, EDITOR_INSTANCES, JS_EDITOR_HANDLES}; -use document_legacy::color::Color; use document_legacy::LayerId; use editor::application::generate_uuid; use editor::application::Editor; @@ -15,6 +14,7 @@ use editor::messages::input_mapper::utility_types::input_mouse::{EditorMouseStat use editor::messages::portfolio::utility_types::{ImaginateServerStatus, Platform}; use editor::messages::prelude::*; use graph_craft::document::NodeId; +use graphene_core::raster::color::Color; use serde::Serialize; use serde_wasm_bindgen::{self, from_value}; diff --git a/frontend/wasm/src/editor_api.rs b/frontend/wasm/src/editor_api.rs index a50926bb7..7f5c97986 100644 --- a/frontend/wasm/src/editor_api.rs +++ b/frontend/wasm/src/editor_api.rs @@ -5,7 +5,6 @@ use crate::helpers::{translate_key, Error}; use crate::{EDITOR_HAS_CRASHED, EDITOR_INSTANCES, JS_EDITOR_HANDLES}; -use document_legacy::color::Color; use document_legacy::LayerId; use editor::application::generate_uuid; use editor::application::Editor; @@ -15,6 +14,7 @@ use editor::messages::input_mapper::utility_types::input_mouse::{EditorMouseStat use editor::messages::portfolio::utility_types::{ImaginateServerStatus, Platform}; use editor::messages::prelude::*; use graph_craft::document::NodeId; +use graphene_core::raster::color::Color; use serde::Serialize; use serde_wasm_bindgen::{self, from_value}; diff --git a/node-graph/gcore/src/raster/color.rs b/node-graph/gcore/src/raster/color.rs index 32d1a9f53..09e555b15 100644 --- a/node-graph/gcore/src/raster/color.rs +++ b/node-graph/gcore/src/raster/color.rs @@ -44,6 +44,12 @@ impl Color { pub const RED: Color = Color::from_rgbf32_unchecked(1., 0., 0.); pub const GREEN: Color = Color::from_rgbf32_unchecked(0., 1., 0.); pub const BLUE: Color = Color::from_rgbf32_unchecked(0., 0., 1.); + pub const TRANSPARENT: Color = Self { + red: 0., + green: 0., + blue: 0., + alpha: 0., + }; /// Returns `Some(Color)` if `red`, `green`, `blue` and `alpha` have a valid value. Negative numbers (including `-0.0`), NaN, and infinity are not valid values and return `None`. /// Alpha values greater than `1.0` are not valid. @@ -67,13 +73,13 @@ impl Color { } /// Return an opaque `Color` from given `f32` RGB channels. - pub const fn from_rgbaf32_unchecked(red: f32, green: f32, blue: f32, alpha: f32) -> Color { - Color { red, green, blue, alpha } + pub const fn from_rgbf32_unchecked(red: f32, green: f32, blue: f32) -> Color { + Color { red, green, blue, alpha: 1. } } /// Return an opaque `Color` from given `f32` RGB channels. - pub const fn from_rgbf32_unchecked(red: f32, green: f32, blue: f32) -> Color { - Color { red, green, blue, alpha: 1. } + pub const fn from_rgbaf32_unchecked(red: f32, green: f32, blue: f32, alpha: f32) -> Color { + Color { red, green, blue, alpha } } /// Return an opaque SDR `Color` given RGB channels from `0` to `255`. @@ -202,6 +208,34 @@ impl Color { (self.red, self.green, self.blue, self.alpha) } + /// Return an 8-character RGBA hex string (without a # prefix). + /// + /// # Examples + /// ``` + /// use graphene_core::raster::color::Color; + /// let color = Color::from_rgba8(0x7C, 0x67, 0xFA, 0x61); + /// assert!("7C67FA61" == color.rgba_hex()) + /// ``` + pub fn rgba_hex(&self) -> String { + format!( + "{:02X?}{:02X?}{:02X?}{:02X?}", + (self.r() * 255.) as u8, + (self.g() * 255.) as u8, + (self.b() * 255.) as u8, + (self.a() * 255.) as u8, + ) + } + + /// Return a 6-character RGB hex string (without a # prefix). + /// ``` + /// use graphene_core::raster::color::Color; + /// let color = Color::from_rgba8(0x7C, 0x67, 0xFA, 0x61); + /// assert!("7C67FA" == color.rgb_hex()) + /// ``` + pub fn rgb_hex(&self) -> String { + format!("{:02X?}{:02X?}{:02X?}", (self.r() * 255.) as u8, (self.g() * 255.) as u8, (self.b() * 255.) as u8,) + } + /// Return the all components as a u8 slice, first component is red, followed by green, followed by blue, followed by alpha. /// /// # Examples @@ -287,6 +321,19 @@ impl Color { Some(Color::from_rgb8(r, g, b)) } + + /// Linearly interpolates between two colors based on t. + /// + /// T must be between 0 and 1. + pub fn lerp(self, other: Color, t: f32) -> Option { + assert!((0. ..=1.).contains(&t)); + Color::from_rgbaf32( + self.red + ((other.red - self.red) * t), + self.green + ((other.green - self.green) * t), + self.blue + ((other.blue - self.blue) * t), + self.alpha + ((other.alpha - self.alpha) * t), + ) + } } #[test]