21
21
22
22
#include " ../Color.h"
23
23
#include " ../MathUtil.h"
24
+ #include " ../Paths.h"
24
25
#include < math.h>
25
26
#include < string.h>
26
27
27
28
#include < iostream>
29
+ #include < vector>
28
30
using namespace std ;
29
31
30
32
#define GTK_COLOR_COMPONENT_GET_PRIVATE (obj ) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_COLOR_COMPONENT, GtkColorComponentPrivate))
@@ -60,9 +62,14 @@ typedef struct GtkColorComponentPrivate{
60
62
gint last_event_position;
61
63
bool changing_color;
62
64
65
+ bool out_of_gamut_mask;
66
+
63
67
ReferenceIlluminant lab_illuminant;
64
68
ReferenceObserver lab_observer;
65
69
70
+ cairo_surface_t *pattern_surface;
71
+ cairo_pattern_t *pattern;
72
+
66
73
const char *label[MaxNumberOfComponents][2 ];
67
74
gchar *text[MaxNumberOfComponents];
68
75
double range[MaxNumberOfComponents];
@@ -121,6 +128,11 @@ static void gtk_color_component_finalize(GObject *color_obj){
121
128
ns->text [i] = 0 ;
122
129
}
123
130
}
131
+ if (ns->pattern_surface )
132
+ cairo_surface_destroy (ns->pattern_surface );
133
+ if (ns->pattern )
134
+ cairo_pattern_destroy (ns->pattern );
135
+
124
136
gpointer parent_class = g_type_class_peek_parent (G_OBJECT_CLASS (GTK_COLOR_COMPONENT_GET_CLASS (color_obj)));
125
137
G_OBJECT_CLASS (parent_class)->finalize (color_obj);
126
138
}
@@ -130,11 +142,19 @@ GtkWidget *gtk_color_component_new (GtkColorComponentComp component){
130
142
GtkWidget* widget = (GtkWidget*)g_object_new (GTK_TYPE_COLOR_COMPONENT, NULL );
131
143
GtkColorComponentPrivate *ns = GTK_COLOR_COMPONENT_GET_PRIVATE (widget);
132
144
145
+ gchar* pattern_filename = build_filename (" gpick-gray-pattern.png" );
146
+ ns->pattern_surface = cairo_image_surface_create_from_png (pattern_filename);
147
+ g_free (pattern_filename);
148
+
149
+ ns->pattern = cairo_pattern_create_for_surface (ns->pattern_surface );
150
+ cairo_pattern_set_extend (ns->pattern , CAIRO_EXTEND_REPEAT);
151
+
133
152
ns->component = component;
134
153
ns->last_event_position = -1 ;
135
154
ns->changing_color = false ;
136
155
ns->lab_illuminant = REFERENCE_ILLUMINANT_D50;
137
156
ns->lab_observer = REFERENCE_OBSERVER_2;
157
+ ns->out_of_gamut_mask = false ;
138
158
139
159
for (int i = 0 ; i != sizeof (ns->text ) / sizeof (gchar*); i++){
140
160
ns->text [i] = 0 ;
@@ -323,6 +343,8 @@ static gboolean gtk_color_component_expose (GtkWidget *widget, GdkEventExpose *e
323
343
double int_part;
324
344
matrix3x3 adaptation_matrix;
325
345
346
+ vector<vector<bool > > out_of_gamut (MaxNumberOfComponents, vector<bool >(false , 1 ));
347
+
326
348
switch (ns->component ) {
327
349
case rgb:
328
350
steps = 1 ;
@@ -477,25 +499,22 @@ static gboolean gtk_color_component_expose (GtkWidget *widget, GdkEventExpose *e
477
499
478
500
color_get_chromatic_adaptation_matrix (color_get_reference (ns->lab_illuminant , ns->lab_observer ), color_get_reference (REFERENCE_ILLUMINANT_D65, REFERENCE_OBSERVER_2), &adaptation_matrix);
479
501
480
- for (i = 0 ; i < 3 ; ++i){
481
- color_copy (&ns->color , &c[i]);
482
- }
483
- for (i = 0 ; i <= steps; ++i){
484
- c[0 ].lab .L = (i / steps) * ns->range [0 ] + ns->offset [0 ];
485
- color_lab_to_rgb (&c[0 ], &rgb_points[0 * (int (steps) + 1 ) + i], color_get_reference (ns->lab_illuminant , ns->lab_observer ), color_get_inverted_sRGB_transformation_matrix (), &adaptation_matrix);
486
- color_rgb_normalize (&rgb_points[0 * (int (steps) + 1 ) + i]);
487
- }
502
+ for (j = 0 ; j < 3 ; ++j){
503
+ color_copy (&ns->color , &c[j]);
488
504
489
- for (i = 0 ; i <= steps; ++i){
490
- c[1 ].lab .a = (i / steps) * ns->range [1 ] + ns->offset [1 ];
491
- color_lab_to_rgb (&c[1 ], &rgb_points[1 * (int (steps) + 1 ) + i], color_get_reference (ns->lab_illuminant , ns->lab_observer ), color_get_inverted_sRGB_transformation_matrix (), &adaptation_matrix);
492
- color_rgb_normalize (&rgb_points[1 * (int (steps) + 1 ) + i]);
493
- }
494
- for (i = 0 ; i <= steps; ++i){
495
- c[2 ].lab .b = (i / steps) * ns->range [2 ] + ns->offset [2 ];
496
- color_lab_to_rgb (&c[2 ], &rgb_points[2 * (int (steps) + 1 ) + i], color_get_reference (ns->lab_illuminant , ns->lab_observer ), color_get_inverted_sRGB_transformation_matrix (), &adaptation_matrix);
497
- color_rgb_normalize (&rgb_points[2 * (int (steps) + 1 ) + i]);
505
+ out_of_gamut[j] = vector<bool >(steps + 1 , false );
506
+
507
+ for (i = 0 ; i <= steps; ++i){
508
+ c[j].ma [j] = (i / steps) * ns->range [j] + ns->offset [j];
509
+ color_lab_to_rgb (&c[j], &rgb_points[j * (int (steps) + 1 ) + i], color_get_reference (ns->lab_illuminant , ns->lab_observer ), color_get_inverted_sRGB_transformation_matrix (), &adaptation_matrix);
510
+
511
+ if (color_is_rgb_out_of_gamut (&rgb_points[j * (int (steps) + 1 ) + i])){
512
+ out_of_gamut[j][i] = true ;
513
+ }
514
+ color_rgb_normalize (&rgb_points[j * (int (steps) + 1 ) + i]);
515
+ }
498
516
}
517
+
499
518
for (i = 0 ; i < surface_width; ++i){
500
519
501
520
float position = modf (i * steps / surface_width, &int_part);
@@ -529,24 +548,19 @@ static gboolean gtk_color_component_expose (GtkWidget *widget, GdkEventExpose *e
529
548
530
549
color_get_chromatic_adaptation_matrix (color_get_reference (ns->lab_illuminant , ns->lab_observer ), color_get_reference (REFERENCE_ILLUMINANT_D65, REFERENCE_OBSERVER_2), &adaptation_matrix);
531
550
532
- for (i = 0 ; i < 3 ; ++i){
533
- color_copy (&ns->color , &c[i]);
534
- }
535
- for (i = 0 ; i <= steps; ++i){
536
- c[0 ].lch .L = (i / steps) * ns->range [0 ] + ns->offset [0 ];
537
- color_lch_to_rgb (&c[0 ], &rgb_points[0 * (int (steps) + 1 ) + i], color_get_reference (ns->lab_illuminant , ns->lab_observer ), color_get_inverted_sRGB_transformation_matrix (), &adaptation_matrix);
538
- color_rgb_normalize (&rgb_points[0 * (int (steps) + 1 ) + i]);
539
- }
551
+ for (j = 0 ; j < 3 ; ++j){
552
+ color_copy (&ns->color , &c[j]);
540
553
541
- for (i = 0 ; i <= steps; ++i){
542
- c[1 ].lch .C = (i / steps) * ns->range [1 ] + ns->offset [1 ];
543
- color_lch_to_rgb (&c[1 ], &rgb_points[1 * (int (steps) + 1 ) + i], color_get_reference (ns->lab_illuminant , ns->lab_observer ), color_get_inverted_sRGB_transformation_matrix (), &adaptation_matrix);
544
- color_rgb_normalize (&rgb_points[1 * (int (steps) + 1 ) + i]);
545
- }
546
- for (i = 0 ; i <= steps; ++i){
547
- c[2 ].lch .h = (i / steps) * ns->range [2 ] + ns->offset [2 ];
548
- color_lch_to_rgb (&c[2 ], &rgb_points[2 * (int (steps) + 1 ) + i], color_get_reference (ns->lab_illuminant , ns->lab_observer ), color_get_inverted_sRGB_transformation_matrix (), &adaptation_matrix);
549
- color_rgb_normalize (&rgb_points[2 * (int (steps) + 1 ) + i]);
554
+ out_of_gamut[j] = vector<bool >(steps + 1 , false );
555
+
556
+ for (i = 0 ; i <= steps; ++i){
557
+ c[j].ma [j] = (i / steps) * ns->range [j] + ns->offset [j];
558
+ color_lch_to_rgb (&c[j], &rgb_points[j * (int (steps) + 1 ) + i], color_get_reference (ns->lab_illuminant , ns->lab_observer ), color_get_inverted_sRGB_transformation_matrix (), &adaptation_matrix);
559
+ if (color_is_rgb_out_of_gamut (&rgb_points[j * (int (steps) + 1 ) + i])){
560
+ out_of_gamut[j][i] = true ;
561
+ }
562
+ color_rgb_normalize (&rgb_points[j * (int (steps) + 1 ) + i]);
563
+ }
550
564
}
551
565
for (i = 0 ; i < surface_width; ++i){
552
566
@@ -597,7 +611,38 @@ static gboolean gtk_color_component_expose (GtkWidget *widget, GdkEventExpose *e
597
611
598
612
cairo_restore (cr);
599
613
614
+
600
615
for (i = 0 ; i < ns->n_components ; ++i){
616
+ if (ns->out_of_gamut_mask ){
617
+ int first_out_of_gamut = 0 ;
618
+ bool out_of_gamut_found = false ;
619
+
620
+ cairo_matrix_t matrix;
621
+ cairo_matrix_init_translate (&matrix, -offset_x, i * 8 );
622
+ cairo_pattern_set_matrix (ns->pattern , &matrix);
623
+ cairo_set_source (cr, ns->pattern );
624
+
625
+ for (int j = 0 ; j < out_of_gamut[i].size (); j++){
626
+ if (out_of_gamut[i][j]){
627
+ if (!out_of_gamut_found){
628
+ out_of_gamut_found = true ;
629
+ first_out_of_gamut = j;
630
+ }
631
+ }else {
632
+ if (out_of_gamut_found){
633
+ cairo_rectangle (cr, offset_x + (first_out_of_gamut * 200.0 / out_of_gamut[i].size ()), 16 * i, (j - first_out_of_gamut) * 200.0 / out_of_gamut[i].size (), 15 );
634
+ cairo_fill (cr);
635
+ out_of_gamut_found = false ;
636
+ }
637
+ }
638
+ }
639
+
640
+ if (out_of_gamut_found){
641
+ cairo_rectangle (cr, offset_x + (first_out_of_gamut * 200.0 / out_of_gamut[i].size ()), 16 * i, (out_of_gamut[i].size () - first_out_of_gamut) * 200.0 / out_of_gamut[i].size (), 15 );
642
+ cairo_fill (cr);
643
+ }
644
+ }
645
+
601
646
cairo_move_to (cr, offset_x + 200 * pointer_pos[i], 16 * i + 9 );
602
647
cairo_line_to (cr, offset_x + 200 * pointer_pos[i] + 3 , 16 * i + 16 );
603
648
cairo_line_to (cr, offset_x + 200 * pointer_pos[i] - 3 , 16 * i + 16 );
@@ -656,8 +701,7 @@ static gboolean gtk_color_component_expose (GtkWidget *widget, GdkEventExpose *e
656
701
pango_font_description_free (font_description);
657
702
}
658
703
}
659
-
660
- cairo_destroy (cr);
704
+ cairo_destroy (cr);
661
705
662
706
return TRUE ;
663
707
}
@@ -811,3 +855,16 @@ void gtk_color_component_set_lab_observer(GtkColorComponent* color_component, Re
811
855
gtk_widget_queue_draw (GTK_WIDGET (color_component));
812
856
}
813
857
858
+ void gtk_color_component_set_out_of_gamut_mask (GtkColorComponent* color_component, bool mask_enabled)
859
+ {
860
+ GtkColorComponentPrivate *ns = GTK_COLOR_COMPONENT_GET_PRIVATE (color_component);
861
+ ns->out_of_gamut_mask = mask_enabled;
862
+ gtk_widget_queue_draw (GTK_WIDGET (color_component));
863
+ }
864
+
865
+ bool gtk_color_component_get_out_of_gamut_mask (GtkColorComponent* color_component)
866
+ {
867
+ GtkColorComponentPrivate *ns = GTK_COLOR_COMPONENT_GET_PRIVATE (color_component);
868
+ return ns->out_of_gamut_mask ;
869
+ }
870
+
0 commit comments