3
3
use crate :: adjust:: Adjust ;
4
4
use crate :: cubic_spline:: CubicSplines ;
5
5
use core:: fmt:: Debug ;
6
+ use glam:: { Vec3 , Vec4 } ;
6
7
#[ cfg( feature = "std" ) ]
7
8
use graphene_core:: gradient:: GradientStops ;
8
9
#[ cfg( feature = "std" ) ]
@@ -753,7 +754,8 @@ fn channel_mixer<T: Adjust<Color>>(
753
754
image
754
755
}
755
756
756
- #[ derive( Debug , Clone , Copy , Default , PartialEq , Eq , Hash , node_macro:: ChoiceType ) ]
757
+ #[ repr( u32 ) ]
758
+ #[ derive( Debug , Clone , Copy , Default , PartialEq , Eq , Hash , node_macro:: ChoiceType , BufferStruct , FromPrimitive , IntoPrimitive ) ]
757
759
#[ cfg_attr( feature = "std" , derive( dyn_any:: DynAny , specta:: Type , serde:: Serialize , serde:: Deserialize ) ) ]
758
760
#[ widget( Radio ) ]
759
761
pub enum RelativeAbsolute {
@@ -762,8 +764,8 @@ pub enum RelativeAbsolute {
762
764
Absolute ,
763
765
}
764
766
765
- #[ repr( C ) ]
766
- #[ derive( Debug , Clone , Copy , Default , PartialEq , Eq , Hash , node_macro:: ChoiceType ) ]
767
+ #[ repr( u32 ) ]
768
+ #[ derive( Debug , Clone , Copy , Default , PartialEq , Eq , Hash , node_macro:: ChoiceType , BufferStruct , FromPrimitive , IntoPrimitive ) ]
767
769
#[ cfg_attr( feature = "std" , derive( dyn_any:: DynAny , specta:: Type , serde:: Serialize , serde:: Deserialize ) ) ]
768
770
pub enum SelectiveColorChoice {
769
771
#[ default]
@@ -786,7 +788,7 @@ pub enum SelectiveColorChoice {
786
788
//
787
789
// Algorithm based on:
788
790
// https://blog.pkh.me/p/22-understanding-selective-coloring-in-adobe-photoshop.html
789
- #[ node_macro:: node( category( "Raster: Adjustment" ) , properties( "selective_color_properties" ) , cfg ( feature = "std" ) ) ]
791
+ #[ node_macro:: node( category( "Raster: Adjustment" ) , properties( "selective_color_properties" ) , shader_node ( PerPixelAdjust ) ) ]
790
792
fn selective_color < T : Adjust < Color > > (
791
793
_: impl Ctx ,
792
794
#[ implementations(
@@ -880,7 +882,7 @@ fn selective_color<T: Adjust<Color>>(
880
882
RelativeAbsolute :: Absolute => ( -1. , -1. , -1. ) ,
881
883
} ;
882
884
883
- let ( sum_r , sum_g , sum_b ) = [
885
+ let array = [
884
886
( SelectiveColorChoice :: Reds , ( r_c, r_m, r_y, r_k) ) ,
885
887
( SelectiveColorChoice :: Yellows , ( y_c, y_m, y_y, y_k) ) ,
886
888
( SelectiveColorChoice :: Greens , ( g_c, g_m, g_y, g_k) ) ,
@@ -890,14 +892,16 @@ fn selective_color<T: Adjust<Color>>(
890
892
( SelectiveColorChoice :: Whites , ( w_c, w_m, w_y, w_k) ) ,
891
893
( SelectiveColorChoice :: Neutrals , ( n_c, n_m, n_y, n_k) ) ,
892
894
( SelectiveColorChoice :: Blacks , ( k_c, k_m, k_y, k_k) ) ,
893
- ]
894
- . into_iter ( )
895
- . fold ( ( 0. , 0. , 0. ) , |acc, ( color_parameter_group, ( c, m, y, k) ) | {
895
+ ] ;
896
+ let mut sum = Vec3 :: ZERO ;
897
+ for i in 0 ..array. len ( ) {
898
+ let ( color_parameter_group, ( c, m, y, k) ) = array[ i] ;
899
+
896
900
// Skip this color parameter group...
897
901
// ...if it's unchanged from the default of zero offset on all CMYK parameters, or...
898
902
// ...if this pixel's color isn't in the range affected by this color parameter group
899
903
if ( c < f32:: EPSILON && m < f32:: EPSILON && y < f32:: EPSILON && k < f32:: EPSILON ) || ( !pixel_color_range ( color_parameter_group) ) {
900
- return acc ;
904
+ continue ;
901
905
}
902
906
903
907
let ( c, m, y, k) = ( c / 100. , m / 100. , y / 100. , k / 100. ) ;
@@ -910,14 +914,15 @@ fn selective_color<T: Adjust<Color>>(
910
914
SelectiveColorChoice :: Blacks => 1. - max ( r, g, b) * 2. ,
911
915
} ;
912
916
913
- let offset_r = ( ( c + k * ( c + 1. ) ) * slope_r) . clamp ( -r, -r + 1. ) * color_parameter_group_scale_factor;
914
- let offset_g = ( ( m + k * ( m + 1. ) ) * slope_g) . clamp ( -g, -g + 1. ) * color_parameter_group_scale_factor;
915
- let offset_b = ( ( y + k * ( y + 1. ) ) * slope_b) . clamp ( -b, -b + 1. ) * color_parameter_group_scale_factor;
917
+ let offset_r = f32 :: clamp ( ( c + k * ( c + 1. ) ) * slope_r, -r, -r + 1. ) * color_parameter_group_scale_factor;
918
+ let offset_g = f32 :: clamp ( ( m + k * ( m + 1. ) ) * slope_g, -g, -g + 1. ) * color_parameter_group_scale_factor;
919
+ let offset_b = f32 :: clamp ( ( y + k * ( y + 1. ) ) * slope_b, -b, -b + 1. ) * color_parameter_group_scale_factor;
916
920
917
- ( acc . 0 + offset_r, acc . 1 + offset_g, acc . 2 + offset_b)
918
- } ) ;
921
+ sum += Vec3 :: new ( offset_r, offset_g, offset_b) ;
922
+ }
919
923
920
- let color = Color :: from_rgbaf32_unchecked ( ( r + sum_r) . clamp ( 0. , 1. ) , ( g + sum_g) . clamp ( 0. , 1. ) , ( b + sum_b) . clamp ( 0. , 1. ) , a) ;
924
+ let rgb = Vec3 :: new ( r, g, b) ;
925
+ let color = Color :: from_vec4 ( Vec4 :: from ( ( ( sum + rgb) . clamp ( Vec3 :: ZERO , Vec3 :: ONE ) , a) ) ) ;
921
926
922
927
color. to_linear_srgb ( )
923
928
} ) ;
0 commit comments