File Coverage

lib/Graphics/Toolkit/Color/Name.pm
Criterion Covered Total %
statement 69 80 86.2
branch 40 52 76.9
condition 17 26 65.3
subroutine 11 12 91.6
pod 4 7 57.1
total 141 177 79.6


line stmt bran cond sub pod time code
1              
2             # translate color names to values and vice versa
3              
4             package Graphics::Toolkit::Color::Name;
5 11     11   291754 use v5.12;
  10         48  
6 10     10   56 use warnings;
  10         19  
  10         561  
7 10     10   5786 use Graphics::Toolkit::Color::Name::Scheme;
  10         31  
  10         537  
8 10     10   74 use Graphics::Toolkit::Color::Space::Util qw/uniq round_decimals/;
  10         16  
  10         13775  
9              
10             #### public API ########################################################
11             sub all {
12 1     1 1 2 my (@scheme_names) = @_;
13 1 50       3 push @scheme_names, 'default' unless @scheme_names;
14 1         2 my @names = ();
15 1         2 for my $scheme_name (@scheme_names) {
16 1         2 my $scheme = try_get_scheme( $scheme_name );
17 1 50       4 next unless ref $scheme;
18 1         5 push @names, $scheme->all_names;
19             }
20 1         17 return uniq( @names );
21             }
22              
23             sub get_values {
24 70     70 1 1456 my ($color_name, $scheme_name) = @_;
25 70 100       233 ($scheme_name, $color_name) = split(':', $color_name, 2) if index($color_name, ':') > -1;
26 70         166 my $scheme = try_get_scheme( $scheme_name );
27 70 100       173 return $scheme unless ref $scheme;
28 68         229 return $scheme->values_from_name( $color_name );
29             }
30              
31             sub from_values {
32 501     501 1 14750 my ($values, $scheme_name, $all_names, $full_name, $distance) = @_;
33 501         940 my @return_names = ();
34 501 100       1659 my @scheme_names = (ref $scheme_name eq 'ARRAY') ? (@$scheme_name)
    100          
35             : (defined $scheme_name) ? $scheme_name : 'DEFAULT';
36 501         1006 for my $scheme_name (@scheme_names) {
37 505         1146 my $scheme = try_get_scheme( $scheme_name );
38 505 50       1206 next unless ref $scheme;
39 505 100       1835 my $names = $distance ? $scheme->names_in_range( $values, $distance )
40             : $scheme->names_from_values( $values );
41 505 100       1391 next unless ref $names;
42 144 100 100     386 $names = [ map { uc($scheme_name).':'.$_} @$names] if $full_name and uc($scheme_name) ne 'DEFAULT';
  1         4  
43 144         1015 push @return_names, @$names;
44             }
45 501 100       1151 push @return_names, '' unless @return_names;
46 501         2530 @return_names = uniq( @return_names );
47 501 100 100     2099 return (defined $all_names and $all_names) ? @return_names : $return_names[0];
48             }
49              
50             sub closest_from_values {
51 17     17 1 10163 my ($values, $scheme_name, $all_names, $full_name) = @_;
52             # exact search first
53 17         48 my @return_names = from_values( $values, $scheme_name, $all_names, $full_name );
54 17 100 100     142 return ((@return_names == 1) ? $return_names[0] : \@return_names, 0)
    100          
55             unless @return_names == 1 and $return_names[0] eq '';
56              
57 5 100       24 my @scheme_names = (ref $scheme_name eq 'ARRAY') ? (@$scheme_name)
    100          
58             : (defined $scheme_name) ? $scheme_name : 'DEFAULT';
59 5         11 @return_names = ();
60 5         11 my $distance = 'Inf';
61 5         9 for my $scheme_name (@scheme_names) {
62 7         12 my $scheme = try_get_scheme( $scheme_name );
63 7 50       15 next unless ref $scheme;
64 7         20 my ($names, $d) = $scheme->closest_names_from_values( $values );
65 7         19 $d = round_decimals($d, 5);
66 7 50       19 next unless ref $names;
67 7 50       22 next unless $d <= $distance;
68 7         35 $distance = $d;
69 7 50 33     30 $names = [ map { uc($scheme_name).':'.$_} @$names] if $full_name and uc($scheme_name) ne 'DEFAULT';
  0         0  
70 7 50       32 @return_names = ($distance == $d) ? (@return_names, @$names) : (@$names);
71             }
72 5         14 @return_names = uniq( @return_names );
73 5 100 100     23 my $name = (defined $all_names and $all_names) ? \@return_names : $return_names[0];
74 5         22 return ($name, $distance);
75             }
76              
77             #### color scheme API ##################################################
78             # load default scheme on RUNTIME
79             my %color_scheme = (DEFAULT => Graphics::Toolkit::Color::Name::Scheme->new());
80             my $default_names = require Graphics::Toolkit::Color::Name::Constant;
81             for my $color_block (@$default_names){
82             $color_scheme{'DEFAULT'}->add_color( $_, [ @{$color_block->{$_}}[0,1,2] ] ) for keys %$color_block;
83             }
84              
85             sub try_get_scheme { # auto loader
86 588   100 588 0 2614 my $scheme_name = shift // 'DEFAULT';
87 588         1097 $scheme_name = uc $scheme_name;
88 588 100       1641 unless (exists $color_scheme{ $scheme_name }){
89 3         7 my $module_base = 'Graphics::ColorNames';
90             # eval "use $module_base";
91             # return "$module_base is not installed, but it's needed to load external color schemes!" if $@;
92 3         9 my $module = $module_base.'::'.$scheme_name;
93 2     2   413 eval "use $module";
  0         0  
  0         0  
  3         294  
94 3 50       29 return "Perl module $module is not installed, but needed to load color scheme '$scheme_name'" if $@;
95 0         0 my $palette = eval $module.'::NamesRgbTable();';
96 0 0 0     0 return "Could not use Perl module $module , it seems to be damaged!" if $@ or ref $palette ne 'HASH';
97 0         0 my $scheme = Graphics::Toolkit::Color::Name::Scheme->new();
98 0         0 $scheme->add_color( $_, from_hex_to_rgb_tuple( $palette->{$_} ) ) for keys %$palette;
99 0         0 add_scheme( $scheme, $scheme_name );
100             }
101 585         1650 return $color_scheme{ $scheme_name };
102             }
103             sub add_scheme {
104 1     1 0 3 my ($scheme, $scheme_name) = @_;
105             return if ref $scheme ne 'Graphics::Toolkit::Color::Name::Scheme'
106 1 50 33     9 or not defined $scheme_name or exists $color_scheme{ $scheme_name };
      33        
107 1         5 $color_scheme{ uc $scheme_name } = $scheme;
108             }
109             my $rgb_max = 256;
110             sub from_hex_to_rgb_tuple {
111 0     0 0   my $hex = shift;
112 0           my $rg = int $hex / $rgb_max;
113 0           return [ int $rg / $rgb_max, $rg % $rgb_max, $hex % $rgb_max];
114             }
115              
116              
117             1;
118              
119             __END__