mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-08-03 21:08:18 +00:00
New nodes: Blend Colors, Percentage Value
This commit is contained in:
parent
c39032ab54
commit
d7546fb183
6 changed files with 175 additions and 9 deletions
|
@ -218,6 +218,14 @@ fn some<T>(input: T) -> Option<T> {
|
|||
Some(input)
|
||||
}
|
||||
|
||||
// Unwrap
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||
pub struct UnwrapNode;
|
||||
#[node_macro::node_fn(UnwrapNode)]
|
||||
fn some<T: Default>(input: Option<T>) -> T {
|
||||
input.unwrap_or_default()
|
||||
}
|
||||
|
||||
// Clone
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||
pub struct CloneNode<O>(PhantomData<O>);
|
||||
|
@ -337,14 +345,27 @@ impl<'i, N: for<'a> Node<'a, I> + Clone, I: 'i> Clone for TypeNode<N, I, <N as N
|
|||
}
|
||||
impl<'i, N: for<'a> Node<'a, I> + Copy, I: 'i> Copy for TypeNode<N, I, <N as Node<'i, I>>::Output> {}
|
||||
|
||||
// Map Option
|
||||
pub struct MapOptionNode<I, Mn> {
|
||||
node: Mn,
|
||||
_i: PhantomData<I>,
|
||||
}
|
||||
#[node_macro::node_fn(MapOptionNode<_I>)]
|
||||
fn map_option_node<_I, N>(input: Option<_I>, node: &'input N) -> Option<<N as Node<'input, _I>>::Output>
|
||||
where
|
||||
N: for<'a> Node<'a, _I>,
|
||||
{
|
||||
input.map(|x| node.eval(x))
|
||||
}
|
||||
|
||||
// Map Result
|
||||
pub struct MapResultNode<I, E, Mn> {
|
||||
node: Mn,
|
||||
_i: PhantomData<I>,
|
||||
_e: PhantomData<E>,
|
||||
}
|
||||
#[node_macro::node_fn(MapResultNode<_I, _E>)]
|
||||
fn flat_map<_I, _E, N>(input: Result<_I, _E>, node: &'input N) -> Result<<N as Node<'input, _I>>::Output, _E>
|
||||
#[node_macro::node_fn(MapResultNode<_I, _E>)]
|
||||
fn map_result_node<_I, _E, N>(input: Result<_I, _E>, node: &'input N) -> Result<<N as Node<'input, _I>>::Output, _E>
|
||||
where
|
||||
N: for<'a> Node<'a, _I>,
|
||||
{
|
||||
|
@ -359,7 +380,7 @@ pub struct FlatMapResultNode<I, O, E, Mn> {
|
|||
_e: PhantomData<E>,
|
||||
}
|
||||
#[node_macro::node_fn(FlatMapResultNode<_I, _O, _E>)]
|
||||
fn flat_map<_I, _O, _E, N>(input: Result<_I, _E>, node: &'input N) -> Result<_O, _E>
|
||||
fn flat_map_node<_I, _O, _E, N>(input: Result<_I, _E>, node: &'input N) -> Result<_O, _E>
|
||||
where
|
||||
N: for<'a> Node<'a, _I, Output = Result<_O, _E>>,
|
||||
{
|
||||
|
|
|
@ -11,6 +11,7 @@ use crate::GraphicGroup;
|
|||
|
||||
use dyn_any::{DynAny, StaticType};
|
||||
|
||||
use core::cmp::Ordering;
|
||||
use core::fmt::Debug;
|
||||
#[cfg(feature = "serde")]
|
||||
#[cfg(target_arch = "spirv")]
|
||||
|
@ -492,6 +493,37 @@ fn threshold_node(color: Color, min_luminance: f64, max_luminance: f64, luminanc
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct BlendColorsNode<Under, BlendMode, Opacity> {
|
||||
under: Under,
|
||||
blend_mode: BlendMode,
|
||||
opacity: Opacity,
|
||||
}
|
||||
|
||||
#[node_macro::node_fn(BlendColorsNode)]
|
||||
fn blend_node(over: Color, under: Color, blend_mode: BlendMode, opacity: f64) -> Color {
|
||||
blend_colors(over, under, blend_mode, opacity / 100.)
|
||||
}
|
||||
|
||||
#[node_macro::node_impl(BlendColorsNode)]
|
||||
fn blend_colors(over: GradientStops, under: GradientStops, blend_mode: BlendMode, opacity: f64) -> GradientStops {
|
||||
let mut combined_stops = over.0.iter().map(|(position, _)| position).chain(under.0.iter().map(|(position, _)| position)).collect::<Vec<_>>();
|
||||
combined_stops.dedup_by(|&mut a, &mut b| (a - b).abs() < 1e-6);
|
||||
combined_stops.sort_by(|a, b| a.partial_cmp(b).unwrap_or(Ordering::Equal));
|
||||
|
||||
let stops = combined_stops
|
||||
.into_iter()
|
||||
.map(|&position| {
|
||||
let over_color = over.evalute(position);
|
||||
let under_color = under.evalute(position);
|
||||
let color = blend_colors(over_color, under_color, blend_mode, opacity / 100.);
|
||||
(position, color)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
GradientStops(stops)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct BlendNode<BlendMode, Opacity> {
|
||||
blend_mode: BlendMode,
|
||||
|
@ -500,7 +532,7 @@ pub struct BlendNode<BlendMode, Opacity> {
|
|||
|
||||
#[node_macro::node_fn(BlendNode)]
|
||||
fn blend_node(input: (Color, Color), blend_mode: BlendMode, opacity: f64) -> Color {
|
||||
blend_colors(input.0, input.1, blend_mode, opacity as f32 / 100.)
|
||||
blend_colors(input.0, input.1, blend_mode, opacity / 100.)
|
||||
}
|
||||
|
||||
pub fn apply_blend_mode(foreground: Color, background: Color, blend_mode: BlendMode) -> Color {
|
||||
|
@ -543,7 +575,7 @@ pub fn apply_blend_mode(foreground: Color, background: Color, blend_mode: BlendM
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn blend_colors(foreground: Color, background: Color, blend_mode: BlendMode, opacity: f32) -> Color {
|
||||
pub fn blend_colors(foreground: Color, background: Color, blend_mode: BlendMode, opacity: f64) -> Color {
|
||||
let target_color = match blend_mode {
|
||||
// Other utility blend modes (hidden from the normal list) - do not have alpha blend
|
||||
BlendMode::Erase => return background.alpha_subtract(foreground),
|
||||
|
@ -552,7 +584,7 @@ pub fn blend_colors(foreground: Color, background: Color, blend_mode: BlendMode,
|
|||
blend_mode => apply_blend_mode(foreground, background, blend_mode),
|
||||
};
|
||||
|
||||
background.alpha_blend(target_color.to_associated_alpha(opacity))
|
||||
background.alpha_blend(target_color.to_associated_alpha(opacity as f32))
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue