File Coverage

lib/Graphics/Toolkit/Color/Values.pm
Criterion Covered Total %
statement 89 89 100.0
branch 30 38 78.9
condition 3 9 33.3
subroutine 15 15 100.0
pod 0 10 0.0
total 137 161 85.0


line stmt bran cond sub pod time code
1              
2             # read only store of a single color: name + values in default and original space
3              
4             package Graphics::Toolkit::Color::Values;
5 9     9   700597 use v5.12;
  9         36  
6 9     9   52 use warnings;
  9         16  
  9         600  
7 9     9   4828 use Graphics::Toolkit::Color::Name;
  9         49  
  9         894  
8 9     9   104 use Graphics::Toolkit::Color::Space::Hub;
  9         21  
  9         14557  
9              
10             my $RGB = Graphics::Toolkit::Color::Space::Hub::default_space();
11              
12             #### constructor #######################################################
13             sub new_from_any_input { # values => %space_name => tuple , ~origin_space, ~color_name
14 136     136 0 589065 my ($pkg, $color_def) = @_;
15 136 50       412 return "Can not create color value object without color definition!" unless defined $color_def;
16 136 100       426 if (not ref $color_def) { # try to resolve color name
17 65         246 my $rgb = Graphics::Toolkit::Color::Name::get_values( $color_def );
18 65 100       195 if (ref $rgb){
19 39         153 $rgb = $RGB->clamp( $RGB->normalize( $rgb ), 'normal' );
20 39         483 return bless { name => $color_def, rgb => $rgb, source_values => '', source_space_name => ''};
21             }
22             }
23 97         414 my ($values, $space_name) = Graphics::Toolkit::Color::Space::Hub::deformat( $color_def );
24 97 100       613 return "could not recognize color value format or color name: $color_def" unless ref $values;
25 54         231 new_from_tuple( '', $values, $space_name);
26             }
27             sub new_from_tuple { #
28 477     477 0 252994 my ($pkg, $values, $space_name, $range_def) = @_;
29 477         1274 my $color_space = Graphics::Toolkit::Color::Space::Hub::try_get_space( $space_name );
30 477 50       1085 return $color_space unless ref $color_space;
31 477 100       1523 return "Need ARRAY of ".$color_space->axis_count." ".$color_space->name." values as first argument!"
32             unless $color_space->is_value_tuple( $values );
33 476         1370 $values = $color_space->clamp( $values, $range_def);
34 476         1595 $values = $color_space->normalize( $values, $range_def );
35 476         1523 $values = $color_space->clamp( $values, 'normal');
36 476         1293 _new_from_normal_tuple($values, $color_space);
37             }
38             sub _new_from_normal_tuple { #
39 476     476   961 my ($values, $color_space) = @_;
40 476         849 my $source_values = '';
41 476         990 my $source_space_name = '';
42 476 100       1589 if ($color_space->name ne $RGB->name){
43 123         318 $source_values = $values;
44 123         321 $source_space_name = $color_space->name;
45 123         316 $values = Graphics::Toolkit::Color::Space::Hub::deconvert( $color_space->name, $values, 'normal' );
46             }
47 476         1568 $values = $RGB->clamp( $values, 'normal' );
48 476         1671 my $name = Graphics::Toolkit::Color::Name::from_values( $RGB->round( $RGB->denormalize( $values ) ) );
49 476         6301 bless { rgb => $values, source_values => $source_values, source_space_name => $source_space_name, name => $name };
50             }
51              
52             #### getter ############################################################
53             sub normalized { # normalized (0..1) value tuple in any color space
54 375     375 0 6403 my ($self, $space_name) = @_;
55             Graphics::Toolkit::Color::Space::Hub::convert(
56 375         1654 $self->{'rgb'}, $space_name, 'normal', $self->{'source_space_name'}, $self->{'source_values'},
57             );
58             }
59             sub shaped { # in any color space, range and precision
60 329     329 0 72762 my ($self, $space_name, $range_def, $precision_def) = @_;
61 329         946 my $color_space = Graphics::Toolkit::Color::Space::Hub::try_get_space( $space_name );
62 329 50       798 return $color_space unless ref $color_space;
63 329         828 my $values = $self->normalized( $color_space->name );
64 329 50       919 return $values if not ref $values;
65 329         1004 $values = $color_space->denormalize( $values, $range_def );
66 329         1201 $values = $color_space->clamp( $values, $range_def );
67 329         1172 $values = $color_space->round( $values, $precision_def );
68 329         1324 return $values;
69             }
70             sub formatted { # in shape values in any format # _ -- ~space, @~|~format, @~|~range, @~|~suffix
71 78     78 0 36056 my ($self, $space_name, $format_name, $suffix_def, $range_def, $precision_def) = @_;
72 78         261 my $color_space = Graphics::Toolkit::Color::Space::Hub::try_get_space( $space_name );
73 78 50       199 return $color_space unless ref $color_space;
74 78         292 my $values = $self->shaped( $color_space->name, $range_def, $precision_def );
75 78 50       288 return $values unless ref $values;
76 78         375 return $color_space->format( $values, $format_name, $suffix_def );
77             }
78 67     67 0 53436 sub name { $_[0]->{'name'} }
79              
80             #### single color calculator ###########################################
81             sub set { # .values, %newval -- ~space_name --> _
82 13     13 0 4529 my ($self, $partial_hash, $preselected_space_name) = @_;
83 13         46 my ($new_values, $space_name) = Graphics::Toolkit::Color::Space::Hub::deformat_partial_hash(
84             $partial_hash, $preselected_space_name );
85 13 100       36 unless (ref $new_values){
86 4         19 my $help_start = 'axis names: '.join(', ', keys %$partial_hash).' do not correlate to ';
87 4 100       32 return (defined $preselected_space_name) ? $help_start.'the selected color space: '.$preselected_space_name.'!'
88             : 'any supported color space!';
89             }
90 9         35 my $values = $self->shaped( $space_name );
91 9         29 my $color_space = Graphics::Toolkit::Color::Space::Hub::get_space( $space_name );
92 9         32 for my $pos ($color_space->basis->axis_iterator) {
93 27 100       75 $values->[$pos] = $new_values->[$pos] if defined $new_values->[$pos];
94             }
95 9         26 $self->new_from_tuple( $values, $color_space->name );
96             }
97              
98             sub add { # .values, %newval -- ~space_name --> _
99 13     13 0 8543 my ($self, $partial_hash, $preselected_space_name) = @_;
100 13         45 my ($new_values, $space_name) = Graphics::Toolkit::Color::Space::Hub::deformat_partial_hash(
101             $partial_hash, $preselected_space_name );
102 13 100       42 unless (ref $new_values){
103 5         25 my $help_start = 'axis names: '.join(', ', keys %$partial_hash).' do not correlate to ';
104 5 100       38 return (defined $preselected_space_name) ? $help_start.'the selected color space: '.$preselected_space_name.'!'
105             : 'any supported color space!';
106             }
107 8         32 my $values = $self->shaped( $space_name );
108 8         27 my $color_space = Graphics::Toolkit::Color::Space::Hub::get_space( $space_name );
109 8         28 for my $pos ($color_space->basis->axis_iterator) {
110 24 100       65 $values->[$pos] += $new_values->[$pos] if defined $new_values->[$pos];
111             }
112 8         24 $self->new_from_tuple( $values, $color_space->name );
113             }
114              
115             sub mix { # @%(+percent, _color) -- ~space_name --> _
116 75     75 0 4424 my ($self, $recipe, $color_space ) = @_;
117 75 50       254 return if ref $recipe ne 'ARRAY';
118 75         282 my $result_values = [(0) x $color_space->axis_count];
119 75         203 for my $ingredient (@$recipe){
120             return if ref $ingredient ne 'HASH' or not exists $ingredient->{'percent'}
121 153 50 33     1343 or not exists $ingredient->{'color'} or ref $ingredient->{'color'} ne __PACKAGE__;
      33        
      33        
122 153         572 my $values = $ingredient->{'color'}->shaped( $color_space->name );
123 153         1430 $result_values->[$_] += $values->[$_] * $ingredient->{'percent'} / 100 for 0 .. $#$values;
124             }
125 75         289 $self->new_from_tuple( $result_values, $color_space->name );
126             }
127              
128             sub invert {
129 18     18 0 3007 my ($self, $color_space ) = @_;
130 18         71 my $values = $self->normalized( $color_space->name );
131 18         54 $self->new_from_tuple( [ map {1 - $_} @$values ], $color_space->name, 'normal' );
  54         163  
132             }
133              
134             1;