File Coverage

lib/Graphics/Toolkit/Color/Space/Basis.pm
Criterion Covered Total %
statement 102 102 100.0
branch 60 66 90.9
condition 33 41 80.4
subroutine 28 28 100.0
pod 0 25 0.0
total 223 262 85.1


line stmt bran cond sub pod time code
1              
2             # count and names of color space axis (short and long), space name = usr | prefix + axis initials
3              
4             package Graphics::Toolkit::Color::Space::Basis;
5 48     48   510965 use v5.12;
  48         167  
6 48     48   289 use warnings;
  48         125  
  48         2706  
7 48     48   22474 use Graphics::Toolkit::Color::Space::Util qw/is_nr/;
  48         151  
  48         89958  
8              
9             sub new {
10 469     469 0 16475 my ($pkg, $axis_long_names, $axis_short_names, $space_name, $alias_name) = @_;
11 469 100       1861 return 'first argument (axis names) has to be an ARRAY reference' unless ref $axis_long_names eq 'ARRAY';
12 466 100 66     1373 return 'amount of short axis names have to match the count of long axis names'
      100        
13             if defined $axis_short_names and (ref $axis_short_names ne 'ARRAY' or @$axis_long_names != @$axis_short_names);
14              
15 465         1165 my @axis_long_name = map {lc} @$axis_long_names;
  1422         3710  
16 465 100       1293 my @axis_short_name = map { color_key_shortcut($_) } (defined $axis_short_names) ? @$axis_short_names : @axis_long_name;
  1422         2418  
17 465 50       1187 return 'need some axis names to create a color space' unless @axis_long_name > 0;
18 465 50       1183 return 'need same amount of axis short names and long names' unless @axis_long_name == @axis_short_name;
19              
20 465         1238 my @iterator = 0 .. $#axis_long_name;
21 465         965 my %long_name_order = map { $axis_long_name[$_] => $_ } @iterator;
  1422         3999  
22 465         1117 my %short_name_order = map { $axis_short_name[$_] => $_ } @iterator;
  1422         3172  
23 465         1667 my $axis_initials = uc join( '', @axis_short_name );
24 465   66     1757 $space_name //= $axis_initials;
25 465   100     1431 $alias_name //= '';
26              
27 465         1151 bless { space_name => $space_name, alias_name => $alias_name,
28             normal_name => normalize_name('',$space_name), normal_alias => normalize_name('',$alias_name) ,
29             axis_long_name => \@axis_long_name, axis_short_name => \@axis_short_name,
30             long_name_order => \%long_name_order, short_name_order => \%short_name_order,
31             axis_iterator => \@iterator }
32             }
33 1422 50   1422 0 6076 sub color_key_shortcut { lc substr($_[0], 0, 1) if defined $_[0] }
34              
35             #### getter ############################################################
36             sub space_name { # -- ?alias ?given --> ~
37 4782     4782 0 10956 my ($self, $alias, $given) = @_;
38 4782 100 66     11190 if (defined $alias and $alias ){
39 467 100 66     2065 return (defined $given and $given) ? $self->{'alias_name'} : $self->{'normal_alias'};
40             } else {
41 4315 100 66     18394 return (defined $given and $given) ? $self->{'space_name'} : $self->{'normal_name'};
42             }
43             }
44 288     288 0 412 sub long_axis_names { @{$_[0]{'axis_long_name'}} } # axis full names
  288         1249  
45 9     9 0 19 sub short_axis_names { @{$_[0]{'axis_short_name'}} } # axis short names
  9         67  
46 7986     7986 0 9508 sub axis_iterator { @{$_[0]{'axis_iterator'}} } # counting all axis 0 .. -1
  7986         18383  
47 13703     13703 0 19417 sub axis_count { int @{$_[0]{'axis_iterator'}} } # amount of axis
  13703         46552  
48              
49             #### predicates ########################################################
50             sub is_name { # --> ? # is this a valid name of this space
51 2224     2224 0 3328 my ($self, $name) = @_;
52 2224 100       5377 return 0 unless defined $name;
53 1232         2213 $name = $self->normalize_name( $name );
54 1232 100       3337 return 1 if $name eq $self->{'normal_name'};
55 1096 100 100     3151 return 1 if $self->{'alias_name'} and $name eq $self->{'normal_alias'};
56 1064         2686 return 0;
57             }
58             sub normalize_name {
59 8306     8306 0 14262 my ($self, $name) = @_;
60 8306 50       14143 return $name unless defined $name;
61 8306         12454 $name = uc $name;
62 8306         14740 $name =~ tr/_ .-//d; # '-' has to be last
63 8306         27994 return $name;
64             }
65              
66 1403 100 66 1403 0 7877 sub is_long_axis_name { (defined $_[1] and exists $_[0]->{'long_name_order'}{ lc $_[1] }) ? 1 : 0 } # ~long_name --> ?
67 1000 100 66 1000 0 6468 sub is_short_axis_name { (defined $_[1] and exists $_[0]->{'short_name_order'}{ lc $_[1] }) ? 1 : 0 } # ~short_name --> ?
68 1395 100   1395 0 2625 sub is_axis_name { $_[0]->is_long_axis_name($_[1]) or $_[0]->is_short_axis_name($_[1]) } # ~name --> ?
69              
70 976 50   976 0 3591 sub pos_from_long_axis_name { defined $_[1] ? $_[0]->{'long_name_order'}{ lc $_[1] } : undef } # ~long_name --> +pos
71 498 50   498 0 1790 sub pos_from_short_axis_name { defined $_[1] ? $_[0]->{'short_name_order'}{ lc $_[1] } : undef } # ~short_name --> +pos
72 366   100 366 0 725 sub pos_from_axis_name { pos_from_long_axis_name(@_) // pos_from_short_axis_name(@_) }
73              
74             sub is_hash { # with all axis names as keys
75 2028     2028 0 2741 my ($self, $value_hash) = @_;
76 2028 100       3205 $self->is_partial_hash( $value_hash ) and (keys %$value_hash == $self->axis_count);
77             }
78             sub is_partial_hash { # with some axis names as keys
79 2445     2445 0 3220 my ($self, $value_hash) = @_;
80 2445 100       7375 return 0 unless ref $value_hash eq 'HASH';
81 955         1200 my $key_count = keys %$value_hash;
82 955         1024 my @axis_visited;
83 955 100 100     2107 return 0 unless $key_count and $key_count <= $self->axis_count;
84 766         1466 for my $axis_name (keys %$value_hash) {
85 1160 100 66     1904 return 0 unless $self->is_axis_name( $axis_name ) and defined $value_hash->{$axis_name};
86 601         1092 my $axis_pos = $self->pos_from_long_axis_name( $axis_name );
87 601 100       1302 $axis_pos = $self->pos_from_short_axis_name( $axis_name ) unless defined $axis_pos;
88 601         965 $axis_visited[ $axis_pos ]++;
89 601 100       1388 return 0 if $axis_visited[ $axis_pos ] > 1;
90             }
91 198         770 return 1;
92             }
93 6097 100 100 6097 0 15013 sub is_value_tuple { (ref $_[1] eq 'ARRAY' and @{$_[1]} == $_[0]->axis_count) ? 1 : 0 }
94             sub is_number_tuple {
95 1245     1245 0 1957 my ($self, $tuple) = @_;
96 1245 100       2243 return 0 unless $self->is_value_tuple( $tuple );
97 1237 100       2170 map { return 0 unless is_nr( $tuple->[$_] ) } $self->axis_iterator;
  3725         6970  
98 1233         3447 return 1;
99             }
100              
101             #### converter #########################################################
102             sub short_axis_name_from_long {
103 4     4 0 13 my ($self, $name) = @_;
104 4 100       15 return unless $self->is_long_axis_name( $name );
105 3         11 ($self->short_axis_names)[ $self->pos_from_long_axis_name( $name ) ];
106             }
107             sub long_axis_name_from_short {
108 4     4 0 13 my ($self, $name) = @_;
109 4 100       14 return unless $self->is_short_axis_name( $name );
110 3         43 ($self->long_axis_names)[ $self->pos_from_short_axis_name( $name ) ];
111             }
112              
113             sub long_name_hash_from_tuple {
114 13     13 0 40 my ($self, $tuple) = @_;
115 13 100       54 return unless $self->is_value_tuple( $tuple );
116 11         48 return { map { $self->{'axis_long_name'}[$_] => $tuple->[$_]} $self->axis_iterator };
  49         222  
117             }
118             sub short_name_hash_from_tuple {
119 10     10 0 33 my ($self, $tuple) = @_;
120 10 100       31 return unless $self->is_value_tuple( $tuple );
121 8         31 return { map {$self->{'axis_short_name'}[$_] => $tuple->[$_]} $self->axis_iterator };
  25         123  
122             }
123              
124             sub tuple_from_hash {
125 38     38 0 6656 my ($self, $value_hash) = @_;
126 38 100       75 return unless $self->is_hash( $value_hash );
127 37         76 my $values = [ (0) x $self->axis_count ];
128 37         76 for my $key (keys %$value_hash) {
129 116         199 $values->[ $self->pos_from_axis_name( $key ) ] = $value_hash->{ $key };
130             }
131 37         121 return $values;
132             }
133             sub tuple_from_partial_hash {
134 322     322 0 20817 my ($self, $value_hash) = @_;
135 322 100       467 return unless $self->is_partial_hash( $value_hash );
136 29         48 my $values = [];
137 29         55 for my $key (keys %$value_hash) {
138 46         89 $values->[ $self->pos_from_axis_name( $key ) ] = $value_hash->{ $key };
139             }
140 29         79 return $values;
141             }
142              
143             1;