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   610150 use v5.12;
  36         131  
6 36     36   263 use warnings;
  36         97  
  36         2360  
7 36     36   7421 use Graphics::Toolkit::Color::Space::Util qw/is_nr/;
  36         98  
  36         66203  
8              
9             sub new {
10 289     289 0 10467 my ($pkg, $axis_long_names, $axis_short_names, $space_name, $alias_name) = @_;
11 289 100       1157 return 'first argument (axis names) has to be an ARRAY reference' unless ref $axis_long_names eq 'ARRAY';
12 286 100 66     1038 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         746 my @axis_long_name = map {lc} @$axis_long_names;
  882         2556  
16 285 100       834 my @axis_short_name = map { color_key_shortcut($_) } (defined $axis_short_names) ? @$axis_short_names : @axis_long_name;
  882         1706  
17 285 50       793 return 'need some axis names to create a color space' unless @axis_long_name > 0;
18 285 50       737 return 'need same amount of axis short names and long names' unless @axis_long_name == @axis_short_name;
19              
20 285         856 my @iterator = 0 .. $#axis_long_name;
21 285         642 my %long_name_order = map { $axis_long_name[$_] => $_ } @iterator;
  882         2535  
22 285         647 my %short_name_order = map { $axis_short_name[$_] => $_ } @iterator;
  882         2101  
23 285         1115 my $axis_initials = uc join( '', @axis_short_name );
24 285   66     1202 $space_name //= $axis_initials;
25 285   100     977 $alias_name //= '';
26              
27 285         3073 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 3991 sub color_key_shortcut { lc substr($_[0], 0, 1) if defined $_[0] }
33              
34             #### getter ############################################################
35 5603     5603 0 20912 sub space_name { $_[0]{'space_name'} } # color space name
36 2091     2091 0 5911 sub alias_name { $_[0]{'alias_name'} } # alternative space name
37              
38 189     189 0 273 sub long_axis_names { @{$_[0]{'axis_long_name'}} } # axis full names
  189         901  
39 9     9 0 19 sub short_axis_names { @{$_[0]{'axis_short_name'}} } # axis short names
  9         80  
40 7603     7603 0 10748 sub axis_iterator { @{$_[0]{'axis_iterator'}} } # counting all axis 0 .. -1
  7603         21087  
41 13136     13136 0 22591 sub axis_count { int @{$_[0]{'axis_iterator'}} } # amount of axis
  13136         55431  
42              
43 604 50   604 0 1568 sub pos_from_long_axis_name { defined $_[1] ? $_[0]->{'long_name_order'}{ lc $_[1] } : undef } # ~long_name --> +pos
44 342 50   342 0 918 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 326 50   326 0 813 return 0 if not defined $_[1];
49 326 100       1170 return 1 if uc $_[1] eq $_[0]{'space_name'};
50 273 100 100     1151 return 1 if $_[0]{'alias_name'} and uc $_[1] eq $_[0]{'alias_name'};
51 257         907 return 0;
52             }
53 1254 100 66 1254 0 11321 sub is_long_axis_name { (defined $_[1] and exists $_[0]->{'long_name_order'}{ lc $_[1] }) ? 1 : 0 } # ~long_name --> ?
54 908 100 66 908 0 6420 sub is_short_axis_name { (defined $_[1] and exists $_[0]->{'short_name_order'}{ lc $_[1] }) ? 1 : 0 }# ~short_name --> ?
55 1082 100   1082 0 2123 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 2165     2165 0 3710 my ($self, $value_hash) = @_;
58 2165 100       4820 $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 2452     2452 0 4150 my ($self, $value_hash) = @_;
62 2452 100       10303 return 0 unless ref $value_hash eq 'HASH';
63 872         1480 my $key_count = keys %$value_hash;
64 872         1267 my @axis_visited;
65 872 100 100     2820 return 0 unless $key_count and $key_count <= $self->axis_count;
66 723         1867 for my $axis_name (keys %$value_hash) {
67 1074 100       2144 return 0 unless $self->is_axis_name( $axis_name );
68 510         1022 my $axis_pos = $self->pos_from_long_axis_name( $axis_name );
69 510 100       1176 $axis_pos = $self->pos_from_short_axis_name( $axis_name ) unless defined $axis_pos;
70 510         897 $axis_visited[ $axis_pos ]++;
71 510 100       1233 return 0 if $axis_visited[ $axis_pos ] > 1;
72             }
73 150         726 return 1;
74             }
75 4556 100 100 4556 0 13755 sub is_value_tuple { (ref $_[1] eq 'ARRAY' and @{$_[1]} == $_[0]->axis_count) ? 1 : 0 }
76             sub is_number_tuple {
77 359     359 0 644 my ($self, $tuple) = @_;
78 359 100       800 return 0 unless $self->is_value_tuple( $tuple );
79 354 100       753 map { return 0 unless is_nr( $tuple->[$_] ) } $self->axis_iterator;
  1067         2326  
80 350         1030 return 1;
81             }
82              
83             #### converter #########################################################
84             sub short_axis_name_from_long {
85 4     4 0 14 my ($self, $name) = @_;
86 4 100       14 return unless $self->is_long_axis_name( $name );
87 3         10 ($self->short_axis_names)[ $self->pos_from_long_axis_name( $name ) ];
88             }
89             sub long_axis_name_from_short {
90 4     4 0 14 my ($self, $name) = @_;
91 4 100       12 return unless $self->is_short_axis_name( $name );
92 3         9 ($self->long_axis_names)[ $self->pos_from_short_axis_name( $name ) ];
93             }
94              
95             sub long_name_hash_from_tuple {
96 13     13 0 40 my ($self, $values) = @_;
97 13 100       51 return unless $self->is_value_tuple( $values );
98 11         28 return { map { $self->{'axis_long_name'}[$_] => $values->[$_]} $self->axis_iterator };
  49         217  
99             }
100             sub short_name_hash_from_tuple {
101 10     10 0 30 my ($self, $values) = @_;
102 10 100       37 return unless $self->is_value_tuple( $values );
103 8         30 return { map {$self->{'axis_short_name'}[$_] => $values->[$_]} $self->axis_iterator };
  25         147  
104             }
105              
106             sub tuple_from_hash {
107 40     40 0 6822 my ($self, $value_hash) = @_;
108 40 100       101 return unless $self->is_hash( $value_hash );
109 39         121 my @values = (0) x $self->axis_count;
110 39         345 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       214  
112 63         193 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         194 return \@values;
116             }
117             sub tuple_from_partial_hash {
118 231     231 0 12300 my ($self, $value_hash) = @_;
119 231 100       435 return unless $self->is_partial_hash( $value_hash );
120 27         80 my $values = [];
121 27         66 for my $key (keys %$value_hash) {
122 42 100       90 if ( $self->is_long_axis_name( $key ) ) { $values->[$self->pos_from_long_axis_name($key) ] = $value_hash->{ $key } }
  26 50       67  
123 16         41 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         96 return $values;
127             }
128             sub select_tuple_value_from_axis_name {
129 31     31 0 1036 my ($self, $name, $values) = @_;
130 31         69 $name = lc $name;
131 31 100       86 return unless $self->is_value_tuple( $values );
132 29 100       149 return $values->[ $self->{'long_name_order'}{$name} ] if exists $self->{'long_name_order'}{$name};
133 15 100       86 return $values->[ $self->{'short_name_order'}{$name} ] if exists $self->{'short_name_order'}{$name};
134 2         11 undef;
135             }
136              
137             1;