File Coverage

lib/Graphics/Toolkit/Color/Space.pm
Criterion Covered Total %
statement 107 110 97.2
branch 38 56 67.8
condition 27 69 39.1
subroutine 44 47 93.6
pod 0 40 0.0
total 216 322 67.0


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 49     49   315951 use v5.12;
  49         137  
6 49     49   199 use warnings;
  49         76  
  49         2022  
7 49     49   20596 use Graphics::Toolkit::Color::Space::Basis; # 1 attr class
  49         142  
  49         1656  
8 49     49   22382 use Graphics::Toolkit::Color::Space::Shape; # 2 ..
  49         120  
  49         1774  
9 49     49   20961 use Graphics::Toolkit::Color::Space::Format; # 3 ..
  49         151  
  49         1705  
10 49     49   272 use Graphics::Toolkit::Color::Space::Util qw/:all/; # forward all its symbols
  49         70  
  49         7879  
11 49     49   263 use Exporter;
  49         69  
  49         69110  
12             our @ISA = qw(Exporter);
13             our @EXPORT_OK = qw/min max uniq round_int round_decimals mod_real spow mult_matrix_vector_3 is_nr/;
14             our %EXPORT_TAGS = (all => [@EXPORT_OK]);
15              
16             ########################################################################
17             sub new {
18 536     536 0 10559 my $pkg = shift;
19 536 50       1627 return if @_ % 2;
20 536         2175 my %args = @_;
21             my $basis = Graphics::Toolkit::Color::Space::Basis->new( $args{'axis'}, $args{'short'}, $args{'name'}, $args{'alias_name'},
22 536         4485 $args{'family'}, $args{'role'}, );
23 536 100       1530 return $basis unless ref $basis;
24 535         3443 my $shape = Graphics::Toolkit::Color::Space::Shape->new( $basis, $args{'type'}, $args{'range'}, $args{'precision'}, $args{'constraint'} );
25 535 50       1213 return $shape unless ref $shape;
26 535         3680 my $format = Graphics::Toolkit::Color::Space::Format->new( $basis, $args{'value_form'}, $args{'prefix'}, $args{'suffix'} );
27 535 50       1264 return $format unless ref $format;
28 535         1647 my $self = bless { basis => $basis, shape => $shape, format => $format, convert => {} };
29 535 100       1277 if (ref $args{'format'} eq 'HASH'){
30 16         24 for my $format_name (keys %{$args{'format'}}){
  16         44  
31 16         39 my $formatter = $args{'format'}{$format_name};
32 16 50 33     89 next unless ref $formatter eq 'ARRAY' and @$formatter > 0;
33 16 50 33     107 $format->add_formatter($format_name, $formatter->[0])
34             if exists $formatter->[0] and ref $formatter->[0] eq 'CODE';
35 16 50 33     81 $format->add_deformatter($format_name, $formatter->[1])
36             if exists $formatter->[1] and ref $formatter->[1] eq 'CODE';
37             }
38             }
39 535 100       1074 if (ref $args{'convert'} eq 'HASH'){
40 512         552 for my $converter_target_space_name (keys %{$args{'convert'}}){
  512         1444  
41 512         626 my $converter_data = $args{'convert'}{ $converter_target_space_name };
42 512 50 33     2991 next unless ref $converter_data eq 'ARRAY' and @$converter_data > 1
      33        
      33        
43             and ref $converter_data->[0] eq 'CODE' and ref $converter_data->[1] eq 'CODE';
44 512         1182 $self->add_converter( $converter_target_space_name, @$converter_data );
45             }
46             }
47 535 100       1084 if (ref $args{'values'} eq 'HASH') {
48 16         39 my $numifier = $args{'values'};
49             $format->set_value_numifier( $numifier->{'read'}, $numifier->{'write'} )
50 16 50 33     170 if ref $numifier->{'read'} eq 'CODE' and ref $numifier->{'write'} eq 'CODE';
51             }
52 535         7043 return $self;
53             }
54              
55             ########################################################################
56 28687     28687 0 45741 sub basis { $_[0]{'basis'} }
57 7819     7819 0 58444 sub name { shift->basis->space_name(@_) } # -- ?alias ?given --> ~
58 990     990 0 1146 sub family { shift->basis->family(@_) } # --> ~
59 529     529 0 739 sub is_name { shift->basis->is_name(@_) } # ~name --> ?
60 16211     16211 0 18852 sub normalize_name { shift->basis->normalize_name(@_) } # ~name --> ~
61 133     133 0 277 sub axis_count { shift->basis->axis_count } # --> +
62 235     235 0 610 sub is_axis_name { shift->basis->is_axis_name(@_) } # ~axis_name --> ?
63 28     28 0 65 sub is_axis_role { shift->basis->is_axis_role(@_) } # ~role_name --> ?
64 205     205 0 537 sub pos_from_axis_name { shift->basis->pos_from_axis_name(@_) }# ~axis_name --> +|
65 88     88 0 198 sub pos_from_axis_role { shift->basis->pos_from_axis_role(@_) }# ~axis_name --> +|
66 1071     1071 0 1438 sub is_value_tuple { shift->basis->is_value_tuple(@_) } # @+tuple --> ?
67 828     828 0 1168 sub is_number_tuple { shift->basis->is_number_tuple(@_) } # @+tuple --> ?
68 98     98 0 445 sub is_partial_hash { shift->basis->is_partial_hash(@_) } # %+partial_hash --> ?
69 379     379 0 398 sub tuple_from_partial_hash { shift->basis->tuple_from_partial_hash(@_) } # %+partial_hash --> @+tuple
70              
71             ########################################################################
72 4947     4947 0 11604 sub shape { $_[0]{'shape'} }
73 34     34 0 184 sub is_euclidean { shift->shape->is_euclidean() } # --> ?
74 33     33 0 122 sub is_cylindrical { shift->shape->is_cylindrical } # --> ?
75 0     0 0 0 sub is_equal { shift->shape->is_equal( @_ ) } # @+tuple_a, @+tuple_b -- @+precision --> ?
76 368     368 0 438 sub is_in_linear_bounds{ shift->shape->is_in_linear_bounds(@_)}#@+tuple -- @+range --> ?
77 0     0 0 0 sub is_in_bounds { shift->shape->is_in_bounds(@_)} # @+tuple -- @+range --> ?
78 1224     1224 0 7071 sub round { shift->shape->round( @_ ) } # @+tuple -- @+precision --> @+tuple
79 989     989 0 20536 sub clamp { shift->shape->clamp( @_ ) } # @+tuple -- @+range --> @+tuple
80 14     14 0 24 sub rotate { shift->shape->rotate( @_ ) } # @+tuple -- @+range --> @+tuple
81 365     365 0 1027 sub check_value_shape { shift->shape->check_value_shape( @_)}# @+tuple -- @+range, @+precision --> @+tuple|!~ # errmsg
82 719     719 0 6605 sub normalize { shift->shape->normalize(@_)} # @+tuple -- @+range --> @+tuple|!~
83 1021     1021 0 8400 sub denormalize { shift->shape->denormalize(@_)} # @+tuple -- @+range --> @+tuple|!~
84 29     29 0 4701 sub denormalize_delta { shift->shape->denormalize_delta(@_)} # @+tuple -- @+range --> @+tuple|!~
85 54     54 0 15090 sub delta { shift->shape->delta( @_ ) } # @+tuple_a, @+tuple_b --> @+tuple| # on normalized values
86 2     2 0 7 sub has_constraints { shift->shape->has_constraints(@_)} # --> ?
87 0     0 0 0 sub add_constraint { shift->shape->add_constraint(@_)} # ~name, ~error, &checker, &remedy --> %constraint
88              
89             ########################################################################
90 2470     2470 0 5031 sub form { $_[0]{'format'} }
91 135     135 0 14903 sub format { shift->form->format(@_) } # @+values, ~format_name -- @~suffix --> $*color
92 2330     2330 0 31180 sub deformat { shift->form->deformat(@_) } # $*color -- @~suffix --> @+values, ~format_name
93              
94             #### conversion ########################################################
95 855     855 0 1378 sub conversion_tree_parent { (keys %{ $_[0]{'convert'} })[0] }
  855         2416  
96 2586 100 66 2586 0 6525 sub can_convert { (defined $_[1] and exists $_[0]{'convert'}{ $_[0]->normalize_name($_[1]) }) ? 1 : 0 }
97             sub add_converter {
98 514     514 0 917 my ($self, $space_name, $to_code, $from_code, $normal) = @_;
99 514 50 33     2506 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        
100 514 50       857 return 0 if $self->can_convert( $space_name );
101 514 50 66     1015 return 0 if defined $normal and ref $normal ne 'HASH';
102 514 100       1329 $normal = { from => 1, to => 1, } unless ref $normal; # flags: default is full normalisation
103 514 50 33     2068 $normal->{'from'} = {} if not exists $normal->{'from'} or (exists $normal->{'from'} and not $normal->{'from'});
      33        
104 514 100       1417 $normal->{'from'} = {in => 1, out => 1} if not ref $normal->{'from'};
105 514 50       893 $normal->{'from'}{'in'} = 0 unless exists $normal->{'from'}{'in'};
106 514 100       808 $normal->{'from'}{'out'} = 0 unless exists $normal->{'from'}{'out'};
107 514 50 33     1727 $normal->{'to'} = {} if not exists $normal->{'to'} or (exists $normal->{'to'} and not $normal->{'to'});
      33        
108 514 100       1262 $normal->{'to'} = {in => 1, out => 1} if not ref $normal->{'to'};
109 514 100       760 $normal->{'to'}{'in'} = 0 unless exists $normal->{'to'}{'in'};
110 514 50       807 $normal->{'to'}{'out'} = 0 unless exists $normal->{'to'}{'out'};
111 514         1617 $self->{'convert'}{ $self->normalize_name( $space_name ) } = { from => $from_code, to => $to_code, normal => $normal };
112             }
113              
114             sub convert_to { # convert value tuple from this space into another
115 517     517 0 13020 my ($self, $space_name, $tuple) = @_;
116 517         821 $space_name = $self->normalize_name( $space_name );
117 517 50 33     865 return unless $self->is_value_tuple( $tuple ) and defined $space_name and $self->can_convert( $space_name );
      33        
118 517         1500 return $self->{'convert'}{ $space_name }{'to'}->( $tuple );
119             }
120             sub convert_from { # convert value tuple from another space into this
121 620     620 0 21753 my ($self, $space_name, $tuple) = @_;
122 620         937 $space_name = $self->normalize_name( $space_name );
123 620 50 33     2271 return unless ref $tuple eq 'ARRAY' and defined $space_name and $self->can_convert( $space_name );
      33        
124 620         1678 return $self->{'convert'}{ $space_name }{'from'}->( $tuple );
125             }
126             sub converter_normal_states {
127 848     848 0 1163 my ($self, $direction, $space_name) = @_;
128 848         1041 $space_name = $self->normalize_name( $space_name );
129 848 50 33     1307 return unless $self->can_convert( $space_name )
      66        
      66        
130             and defined $direction and ($direction eq 'from' or $direction eq 'to');
131 848         906 return @{$self->{'convert'}{ $space_name }{'normal'}{$direction}}{'in', 'out'};
  848         2315  
132             }
133              
134             1;