File Coverage

lib/Graphics/Toolkit/Color/Space/Basis.pm
Criterion Covered Total %
statement 102 104 98.0
branch 64 72 88.8
condition 22 26 84.6
subroutine 28 28 100.0
pod 0 25 0.0
total 216 255 84.7


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 36     36   445466 use v5.12;
  36         130  
6 36     36   246 use warnings;
  36         80  
  36         2360  
7 36     36   6718 use Graphics::Toolkit::Color::Space::Util qw/is_nr/;
  36         77  
  36         78182  
8              
9             sub new {
10 289     289 0 9476 my ($pkg, $axis_long_names, $axis_short_names, $space_name, $alias_name) = @_;
11 289 100       1169 return 'first argument (axis names) has to be an ARRAY reference' unless ref $axis_long_names eq 'ARRAY';
12 286 100 66     1002 return 'amount of shortcut names have to match that of full names'
      100        
13             if defined $axis_short_names and (ref $axis_short_names ne 'ARRAY' or @$axis_long_names != @$axis_short_names);
14              
15 285         771 my @axis_long_name = map {lc} @$axis_long_names;
  882         2463  
16 285 100       941 my @axis_short_name = map { color_key_shortcut($_) } (defined $axis_short_names) ? @$axis_short_names : @axis_long_name;
  882         1655  
17 285 50       733 return 'need some axis names to create a color space' unless @axis_long_name > 0;
18 285 50       693 return 'need same amount of axis short names and long names' unless @axis_long_name == @axis_short_name;
19              
20 285         741 my @iterator = 0 .. $#axis_long_name;
21 285         581 my %long_name_order = map { $axis_long_name[$_] => $_ } @iterator;
  882         2658  
22 285         4788 my %short_name_order = map { $axis_short_name[$_] => $_ } @iterator;
  882         2026  
23 285         1180 my $axis_initials = uc join( '', @axis_short_name );
24 285   66     1294 $space_name //= $axis_initials;
25 285   100     1058 $alias_name //= '';
26              
27 285         3036 bless { space_name => uc $space_name, alias_name => uc $alias_name,
28             axis_long_name => \@axis_long_name, axis_short_name => \@axis_short_name,
29             long_name_order => \%long_name_order, short_name_order => \%short_name_order,
30             axis_iterator => \@iterator }
31             }
32 882 50   882 0 3959 sub color_key_shortcut { lc substr($_[0], 0, 1) if defined $_[0] }
33              
34             #### getter ############################################################
35 5576     5576 0 20020 sub space_name { $_[0]{'space_name'} } # color space name
36 2091     2091 0 5522 sub alias_name { $_[0]{'alias_name'} } # alternative space name
37              
38 189     189 0 242 sub long_axis_names { @{$_[0]{'axis_long_name'}} } # axis full names
  189         740  
39 9     9 0 11 sub short_axis_names { @{$_[0]{'axis_short_name'}} } # axis short names
  9         62  
40 7532     7532 0 10164 sub axis_iterator { @{$_[0]{'axis_iterator'}} } # counting all axis 0 .. -1
  7532         18945  
41 13035     13035 0 22438 sub axis_count { int @{$_[0]{'axis_iterator'}} } # amount of axis
  13035         49735  
42              
43 600 50   600 0 1467 sub pos_from_long_axis_name { defined $_[1] ? $_[0]->{'long_name_order'}{ lc $_[1] } : undef } # ~long_name --> +pos
44 337 50   337 0 791 sub pos_from_short_axis_name { defined $_[1] ? $_[0]->{'short_name_order'}{ lc $_[1] } : undef } # ~short_name --> +pos
45              
46             #### predicates ########################################################
47             sub is_name {
48 324 50   324 0 2429 return 0 if not defined $_[1];
49 324 100       1102 return 1 if uc $_[1] eq $_[0]{'space_name'};
50 272 100 100     1128 return 1 if $_[0]{'alias_name'} and uc $_[1] eq $_[0]{'alias_name'};
51 256         838 return 0;
52             }
53 1250 100 66 1250 0 5991 sub is_long_axis_name { (defined $_[1] and exists $_[0]->{'long_name_order'}{ lc $_[1] }) ? 1 : 0 } # ~long_name --> ?
54 903 100 66 903 0 5819 sub is_short_axis_name { (defined $_[1] and exists $_[0]->{'short_name_order'}{ lc $_[1] }) ? 1 : 0 }# ~short_name --> ?
55 1078 100   1078 0 2066 sub is_axis_name { $_[0]->is_long_axis_name($_[1]) or $_[0]->is_short_axis_name($_[1]) } # ~name --> ?
56             sub is_hash { # with all axis names as keys
57 2141     2141 0 3403 my ($self, $value_hash) = @_;
58 2141 100       4133 $self->is_partial_hash( $value_hash ) and (keys %$value_hash == $self->axis_count);
59             }
60             sub is_partial_hash { # with some axis names as keys
61 2428     2428 0 3514 my ($self, $value_hash) = @_;
62 2428 100       8853 return 0 unless ref $value_hash eq 'HASH';
63 872         1480 my $key_count = keys %$value_hash;
64 872         1139 my @axis_visited;
65 872 100 100     2536 return 0 unless $key_count and $key_count <= $self->axis_count;
66 723         1648 for my $axis_name (keys %$value_hash) {
67 1070 100       1879 return 0 unless $self->is_axis_name( $axis_name );
68 506         942 my $axis_pos = $self->pos_from_long_axis_name( $axis_name );
69 506 100       1107 $axis_pos = $self->pos_from_short_axis_name( $axis_name ) unless defined $axis_pos;
70 506         783 $axis_visited[ $axis_pos ]++;
71 506 100       1125 return 0 if $axis_visited[ $axis_pos ] > 1;
72             }
73 150         605 return 1;
74             }
75 4534 100 100 4534 0 12050 sub is_value_tuple { (ref $_[1] eq 'ARRAY' and @{$_[1]} == $_[0]->axis_count) ? 1 : 0 }
76             sub is_number_tuple {
77 359     359 0 628 my ($self, $tuple) = @_;
78 359 100       1634 return 0 unless $self->is_value_tuple( $tuple );
79 354 100       687 map { return 0 unless is_nr( $tuple->[$_] ) } $self->axis_iterator;
  1067         3981  
80 350         923 return 1;
81             }
82              
83             #### converter #########################################################
84             sub short_axis_name_from_long {
85 4     4 0 7 my ($self, $name) = @_;
86 4 100       10 return unless $self->is_long_axis_name( $name );
87 3         7 ($self->short_axis_names)[ $self->pos_from_long_axis_name( $name ) ];
88             }
89             sub long_axis_name_from_short {
90 4     4 0 11 my ($self, $name) = @_;
91 4 100       8 return unless $self->is_short_axis_name( $name );
92 3         7 ($self->long_axis_names)[ $self->pos_from_short_axis_name( $name ) ];
93             }
94              
95             sub long_name_hash_from_tuple {
96 13     13 0 39 my ($self, $values) = @_;
97 13 100       44 return unless $self->is_value_tuple( $values );
98 11         30 return { map { $self->{'axis_long_name'}[$_] => $values->[$_]} $self->axis_iterator };
  49         213  
99             }
100             sub short_name_hash_from_tuple {
101 10     10 0 31 my ($self, $values) = @_;
102 10 100       33 return unless $self->is_value_tuple( $values );
103 8         55 return { map {$self->{'axis_short_name'}[$_] => $values->[$_]} $self->axis_iterator };
  25         131  
104             }
105              
106             sub tuple_from_hash {
107 40     40 0 9152 my ($self, $value_hash) = @_;
108 40 100       110 return unless $self->is_hash( $value_hash );
109 39         104 my @values = (0) x $self->axis_count;
110 39         92 for my $key (keys %$value_hash) {
111 122 100       239 if ($self->is_long_axis_name( $key )) { $values[ $self->pos_from_long_axis_name($key) ] = $value_hash->{ $key } }
  59 50       154  
112 63         163 elsif ($self->is_short_axis_name( $key )) { $values[ $self->pos_from_short_axis_name($key) ] = $value_hash->{ $key } }
113 0         0 else { return "value of $key is missing" }
114             }
115 39         172 return \@values;
116             }
117             sub tuple_from_partial_hash {
118 231     231 0 11303 my ($self, $value_hash) = @_;
119 231 100       328 return unless $self->is_partial_hash( $value_hash );
120 27         44 my $values = [];
121 27         53 for my $key (keys %$value_hash) {
122 42 100       71 if ( $self->is_long_axis_name( $key ) ) { $values->[$self->pos_from_long_axis_name($key) ] = $value_hash->{ $key } }
  26 50       58  
123 16         32 elsif ( $self->is_short_axis_name( $key )) { $values->[$self->pos_from_short_axis_name($key)] = $value_hash->{ $key } }
124 0         0 else { return "value of $key is missing" }
125             }
126 27         69 return $values;
127             }
128             sub select_tuple_value_from_axis_name {
129 31     31 0 1010 my ($self, $name, $values) = @_;
130 31         66 $name = lc $name;
131 31 100       79 return unless $self->is_value_tuple( $values );
132 29 100       142 return $values->[ $self->{'long_name_order'}{$name} ] if exists $self->{'long_name_order'}{$name};
133 15 100       93 return $values->[ $self->{'short_name_order'}{$name} ] if exists $self->{'short_name_order'}{$name};
134 2         12 undef;
135             }
136              
137             1;