File Coverage

lib/Graphics/Toolkit/Color/Space.pm
Criterion Covered Total %
statement 97 99 97.9
branch 33 56 58.9
condition 26 69 37.6
subroutine 38 40 95.0
pod 3 34 8.8
total 197 298 66.1


line stmt bran cond sub pod time code
1              
2             # common code of Graphics::Toolkit::Color::Space::Instance::* packages
3              
4             package Graphics::Toolkit::Color::Space;
5 33     33   792217 use v5.12;
  33         150  
6 33     33   225 use warnings;
  33         69  
  33         3113  
7             require Exporter;
8             our @ISA = qw(Exporter);
9 33     33   23034 use Graphics::Toolkit::Color::Space::Basis;
  33         92  
  33         1469  
10 33     33   20920 use Graphics::Toolkit::Color::Space::Shape;
  33         151  
  33         1740  
11 33     33   24189 use Graphics::Toolkit::Color::Space::Format;
  33         112  
  33         1774  
12 33     33   278 use Graphics::Toolkit::Color::Space::Util qw/:all/;
  33         56  
  33         71229  
13             our @EXPORT_OK = qw/round_int round_decimals mod_real min max uniq mult_matrix_vector_3 is_nr/;
14             our %EXPORT_TAGS = (all => [@EXPORT_OK]);
15              
16             ########################################################################
17             sub new {
18 278     278 1 23795 my $pkg = shift;
19 278 50       1166 return if @_ % 2;
20 278         1459 my %args = @_;
21 278         3105 my $basis = Graphics::Toolkit::Color::Space::Basis->new( $args{'axis'}, $args{'short'}, $args{'name'}, $args{'alias'});
22 278 100       1047 return $basis unless ref $basis;
23 277         2335 my $shape = Graphics::Toolkit::Color::Space::Shape->new( $basis, $args{'type'}, $args{'range'}, $args{'precision'} );
24 277 50       932 return $shape unless ref $shape;
25 277         2603 my $format = Graphics::Toolkit::Color::Space::Format->new( $basis, $args{'value_form'}, $args{'prefix'}, $args{'suffix'} );
26 277 50       1108 return $format unless ref $format;
27 277         1366 my $self = bless { basis => $basis, shape => $shape, format => $format, convert => {} };
28 277 100       890 if (ref $args{'format'} eq 'HASH'){
29 15         26 for my $format_name (keys %{$args{'format'}}){
  15         63  
30 30         62 my $formatter = $args{'format'}{$format_name};
31 30 50 33     181 next unless ref $formatter eq 'ARRAY' and @$formatter > 0;
32 30 50 33     280 $format->add_formatter($format_name, $formatter->[0])
33             if exists $formatter->[0] and ref $formatter->[0] eq 'CODE';
34 30 50 33     562 $format->add_deformatter($format_name, $formatter->[1])
35             if exists $formatter->[1] and ref $formatter->[1] eq 'CODE';
36             }
37             }
38 277 100       908 if (ref $args{'convert'} eq 'HASH'){
39 255         434 for my $converter_target (keys %{$args{'convert'}}){
  255         966  
40 255         483 my $converter = $args{'convert'}{ $converter_target };
41 255 50 33     2053 next unless ref $converter eq 'ARRAY' and @$converter > 1
      33        
      33        
42             and ref $converter->[0] eq 'CODE' and ref $converter->[1] eq 'CODE';
43 255         799 $self->add_converter( $converter_target, @$converter );
44             }
45             }
46 277 100       915 if (ref $args{'values'} eq 'HASH') {
47 15         35 my $numifier = $args{'values'};
48             $format->set_value_numifier( $numifier->{'read'}, $numifier->{'write'} )
49 15 50 33     208 if ref $numifier->{'read'} eq 'CODE' and ref $numifier->{'write'} eq 'CODE';
50             }
51              
52 277         5550 return $self;
53             }
54              
55             ########################################################################
56 6559     6559 0 16801 sub basis { $_[0]{'basis'} }
57 4122     4122 0 49939 sub name { shift->basis->space_name } # --> ~
58 767     767 0 1381 sub alias { shift->basis->alias_name } # --> ~
59 44     44 0 163 sub is_name { shift->basis->is_name(@_) } # ~name --> ?
60 108     108 0 327 sub axis_count { shift->basis->axis_count } # --> +
61 4     4 0 12 sub is_axis_name { shift->basis->is_axis_name(@_) } # ~axis_name --> ?
62 1196     1196 0 2637 sub is_value_tuple { shift->basis->is_value_tuple(@_) } # @+values --> ?
63 6     6 0 19 sub is_number_tuple { shift->basis->is_number_tuple(@_) } # @+values --> ?
64 47     47 0 183 sub is_partial_hash { shift->basis->is_partial_hash(@_) } # %+values --> ?
65 223     223 0 307 sub tuple_from_partial_hash { shift->basis->tuple_from_partial_hash(@_) } # %+values --> ?
66 21     21 0 49 sub select_tuple_value_from_name { shift->basis->select_tuple_value_from_axis_name(@_) } # ~axis_name. %+values --> +
67              
68             ########################################################################
69 4776     4776 0 16628 sub shape { $_[0]{'shape'} }
70 1     1 0 4 sub is_linear { shift->shape->is_linear() } # --> ?
71 339     339 0 640 sub is_in_linear_bounds{ shift->shape->is_in_linear_bounds(@_)}#@+values --> ?
72 0     0 0 0 sub is_equal { shift->shape->is_equal( @_ ) } # @+val_a, @+val_b -- @+precision --> ?
73 806     806 0 6566 sub round { shift->shape->round( @_ ) } # @+values -- @+precision --> @+rvals # result values
74 1939     1939 0 71062 sub clamp { shift->shape->clamp( @_ ) } # @+values -- @+range --> @+rvals # result values
75 212     212 0 624 sub check_value_shape { shift->shape->check_value_shape( @_)}# @+values -- @+range, @+precision --> @+values|!~ # errmsg
76 551     551 0 21493 sub normalize { shift->shape->normalize(@_)} # @+values -- @+range --> @+rvals|!~
77 846     846 0 23977 sub denormalize { shift->shape->denormalize(@_)} # @+values -- @+range --> @+rvals|!~
78 29     29 0 8076 sub denormalize_delta { shift->shape->denormalize_delta(@_)} # @+values -- @+range --> @+rvals|!~
79 35     35 0 23165 sub delta { shift->shape->delta( @_ ) } # @+val_a, @+val_b --> @+rvals| # on normalized values
80 0     0 1 0 sub add_constraint { shift->shape->add_constraint(@_)} # ~name, ~error, &checker, &remedy --> %constraint
81              
82             ########################################################################
83 2207     2207 0 6413 sub form { $_[0]{'format'} }
84 115     115 0 54732 sub format { shift->form->format(@_) } # @+values, ~format_name -- @~suffix --> $*color
85 2087     2087 0 85568 sub deformat { shift->form->deformat(@_) } # $*color -- @~suffix --> @+values, ~format_name
86              
87             #### conversion ########################################################
88 525     525 0 1373 sub converter_names { keys %{ $_[0]{'convert'} } }
  525         3319  
89             sub alias_converter_name {
90 84     84 0 199 my ($self, $space_name, $name_alias) = @_;
91 84         390 $self->{'convert'}{ uc $name_alias } = $self->{'convert'}{ uc $space_name };
92             }
93 967 100 66 967 0 8055 sub can_convert { (defined $_[1] and exists $_[0]{'convert'}{ uc $_[1] }) ? 1 : 0 }
94             sub add_converter {
95 257     257 1 665 my ($self, $space_name, $to_code, $from_code, $normal) = @_;
96 257 50 33     1979 return 0 if not defined $space_name or ref $space_name or ref $from_code ne 'CODE' or ref $to_code ne 'CODE';
      33        
      33        
97 257 50       690 return 0 if $self->can_convert( $space_name );
98 257 50 33     638 return 0 if defined $normal and ref $normal ne 'HASH';
99 257 50       978 $normal = { from => 1, to => 1, } unless ref $normal; # default is full normalisation
100 257 50 33     1516 $normal->{'from'} = {} if not exists $normal->{'from'} or (exists $normal->{'from'} and not $normal->{'from'});
      33        
101 257 50       993 $normal->{'from'} = {in => 1, out => 1} if not ref $normal->{'from'};
102 257 50       632 $normal->{'from'}{'in'} = 0 unless exists $normal->{'from'}{'in'};
103 257 50       609 $normal->{'from'}{'out'} = 0 unless exists $normal->{'from'}{'out'};
104 257 50 33     1377 $normal->{'to'} = {} if not exists $normal->{'to'} or (exists $normal->{'to'} and not $normal->{'to'});
      33        
105 257 50       968 $normal->{'to'} = {in => 1, out => 1} if not ref $normal->{'to'};
106 257 50       609 $normal->{'to'}{'in'} = 0 unless exists $normal->{'to'}{'in'};
107 257 50       1189 $normal->{'to'}{'out'} = 0 unless exists $normal->{'to'}{'out'};
108 257         1626 $self->{'convert'}{ uc $space_name } = { from => $from_code, to => $to_code, normal => $normal };
109             }
110              
111             sub convert_to { # convert value tuple from this space into another
112 212     212 0 62914 my ($self, $space_name, $values) = @_;
113 212 50 33     707 return unless $self->is_value_tuple( $values ) and defined $space_name and $self->can_convert( $space_name );
      33        
114 212         1103 return $self->{'convert'}{ uc $space_name }{'to'}->( $values );
115             }
116             sub convert_from { # convert value tuple from another space into this
117 196     196 0 77021 my ($self, $space_name, $values) = @_;
118 196 50 33     1487 return unless ref $values eq 'ARRAY' and defined $space_name and $self->can_convert( $space_name );
      33        
119 196         1035 return $self->{'convert'}{ uc $space_name }{'from'}->( $values );
120             }
121              
122             sub converter_normal_states {
123 269     269 0 682 my ($self, $direction, $space_name) = @_;
124 269 50 33     1903 return unless $self->can_convert( $space_name )
      66        
      66        
125             and defined $direction and ($direction eq 'from' or $direction eq 'to');
126 269         463 return @{$self->{'convert'}{ uc $space_name }{'normal'}{$direction}}{'in', 'out'};
  269         1298  
127             }
128              
129              
130             1;
131              
132             __END__