File Coverage

lib/Graphics/Toolkit/Color/Name/Scheme.pm
Criterion Covered Total %
statement 78 78 100.0
branch 29 34 85.2
condition 15 24 62.5
subroutine 13 13 100.0
pod 0 8 0.0
total 135 157 85.9


line stmt bran cond sub pod time code
1              
2             # name space for color names, translate values > names & back, find closest name
3              
4             package Graphics::Toolkit::Color::Name::Scheme;
5 12     12   184704 use v5.12;
  12         41  
6 12     12   45 use warnings;
  12         14  
  12         518  
7 12     12   4814 use Graphics::Toolkit::Color::Space::Hub;
  12         29  
  12         556  
8 12     12   72 use Graphics::Toolkit::Color::Space::Util qw/round_int uniq/;
  12         19  
  12         10401  
9              
10             my $RGB = Graphics::Toolkit::Color::Space::Hub::default_space_name();
11              
12             #### constructor #######################################################
13             sub new {
14 13     13 0 3955 my $pkg = shift;
15 13         75 bless { shaped => {name => [], values => {}}, normal => {} }
16             }
17             sub add_color {
18 7881     7881 0 11226 my ($self, $name, $values) = @_;
19 7881 50 33     22289 return 0 if not defined $name or ref $values ne 'ARRAY' or @$values != 3 or $self->is_name_taken($name);
      33        
      33        
20 7881         7585 $name = _clean_name( $name );
21 7881         10778 $self->{'shaped'}{'values'}{$name} = $values;
22             $self->{'shaped'}{'name'}[$values->[0]][$values->[1]][$values->[2]] =
23             (exists $self->{'shaped'}{'name'}[$values->[0]][$values->[1]][$values->[2]])
24 7881 100       33569 ? [ @{$self->{'shaped'}{'name'}[$values->[0]][$values->[1]][$values->[2]]}, $name ]
  628         1495  
25             : [$name];
26 7881         11410 1;
27             }
28              
29             #### exact getter ######################################################
30 2     2 0 561 sub all_names { keys %{$_[0]->{'shaped'}{'values'}} }
  2         192  
31             sub is_name_taken {
32 7893     7893 0 10298 my ($self, $name) = @_;
33 7893 100       8382 (exists $self->{'shaped'}{'values'}{_clean_name($name)}) ? 1 : 0;
34             }
35             sub values_from_name {
36 98     98 0 4544 my ($self, $name) = @_;
37 98 50       165 return unless defined $name;
38 98         188 $name = _clean_name($name);
39 98 100       442 return $self->{'shaped'}{'values'}{$name} if exists $self->{'shaped'}{'values'}{$name};
40             }
41             sub names_from_values {
42 586     586 0 5262 my ($self, $values) = @_;
43             return '' unless ref $values eq 'ARRAY' and @$values == 3
44             and exists ($self->{'shaped'}{'name'}[$values->[0]])
45             and exists ($self->{'shaped'}{'name'}[$values->[0]][$values->[1]])
46 586 100 66     4151 and exists ($self->{'shaped'}{'name'}[$values->[0]][$values->[1]][$values->[2]]);
      100        
      100        
      100        
47 181         482 return $self->{'shaped'}{'name'}[$values->[0]][$values->[1]][$values->[2]];
48             }
49              
50             #### nearness methods ##################################################
51             sub closest_names_from_values {
52 12     12 0 7173 my ($self, $values) = @_;
53 12 50 33     49 return '' unless ref $values eq 'ARRAY' and @$values == 3;
54 12         20 my $names = names_from_values( $values );
55 12 50       23 return ($names, 0) if ref $names;
56 12         14 my @names;
57 12         14 my $sqr_min = 1 + 255**3;
58 12         21 my $all_values = $self->{'shaped'}{'values'};
59 12         428 for my $index_name (keys %$all_values){
60 3593         3150 my $index_values = $all_values->{ $index_name };
61 3593         3610 my $temp_sqr_sum = ($index_values->[0] - $values->[0]) ** 2;
62 3593 100       3852 next if $temp_sqr_sum > $sqr_min;
63 601         553 $temp_sqr_sum += ($index_values->[1] - $values->[1]) ** 2;
64 601 100       692 next if $temp_sqr_sum > $sqr_min;
65 79         94 $temp_sqr_sum += ($index_values->[2] - $values->[2]) ** 2;
66 79 100       110 next if $temp_sqr_sum > $sqr_min;
67 46 100       76 @names = ($sqr_min == $temp_sqr_sum) ? (@names, $index_name) : $index_name;
68 46         48 $sqr_min = $temp_sqr_sum;
69             }
70 12 100       161 return '' unless @names;
71             # keep names in insert possible
72 11         21 @names = map { @{$self->names_from_values( $self->values_from_name($_))} } @names;
  16         16  
  16         31  
73 11         32 @names = uniq( @names );
74 11         33 return (\@names, sqrt($sqr_min));
75             }
76              
77             sub names_in_range {
78 3     3 0 6 my ($self, $values, $range) = @_;
79 3         4 my @names;
80 3         9 my $sqr_max = $range ** 2;
81 3         7 my $all_values = $self->{'shaped'}{'values'};
82 3         207 for my $index_name (keys %$all_values){
83 1433         1274 my $index_values = $all_values->{ $index_name };
84 1433         1442 my $temp_sqr_sum = ($index_values->[0] - $values->[0]) ** 2;
85 1433 100       1530 next if $temp_sqr_sum > $sqr_max;
86 153         138 $temp_sqr_sum += ($index_values->[1] - $values->[1]) ** 2;
87 153 100       193 next if $temp_sqr_sum > $sqr_max;
88 28         28 $temp_sqr_sum += ($index_values->[2] - $values->[2]) ** 2;
89 28 100       31 next if $temp_sqr_sum > $sqr_max;
90 5         20 push @names, [$index_name, $temp_sqr_sum];
91             }
92 3 50       48 return '' unless @names;
93 3         11 @names = map { $_->[0] } sort { $a->[1] <=> $b->[1] } @names;
  5         31  
  3         7  
94             # keep names in insert possible
95 3         7 @names = map { @{$self->names_from_values( $self->values_from_name($_))} } @names;
  5         6  
  5         10  
96 3         11 return [ uniq( @names ) ];
97             }
98              
99             #### util ##############################################################
100             sub _clean_name {
101 15872     15872   13666 my $name = shift;
102 15872         14789 $name =~ tr/_ '.\/-//d;
103 15872         25620 lc $name;
104             }
105              
106             1;