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 0 7 0.0
total 137 177 77.4


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 12     12   188009 use v5.12;
  11         25  
6 11     12   42 use warnings;
  12         188  
  11         421  
7 11     12   4201 use Graphics::Toolkit::Color::Name::Scheme;
  12         142  
  11         424  
8 11     12   57 use Graphics::Toolkit::Color::Space::Util qw/uniq round_decimals/;
  12         130  
  11         10941  
9              
10             #### public API ########################################################
11             sub all {
12 1     1 0 3 my (@scheme_names) = @_;
13 1 50       6 push @scheme_names, 'default' unless @scheme_names;
14 1         3 my @names = ();
15 1         3 for my $scheme_name (@scheme_names) {
16 1         4 my $scheme = try_get_scheme( $scheme_name );
17 1 50       4 next unless ref $scheme;
18 1         6 push @names, $scheme->all_names;
19             }
20 1         63 return uniq( @names );
21             }
22              
23             sub get_values {
24 77     77 0 2548 my ($color_name, $scheme_name) = @_;
25 77 100       187 ($scheme_name, $color_name) = split(':', $color_name, 2) if index($color_name, ':') > -1;
26 77         713 my $scheme = try_get_scheme( $scheme_name );
27 77 100       146 return $scheme unless ref $scheme;
28 72         189 return $scheme->values_from_name( $color_name );
29             }
30              
31             sub from_values {
32 547     547 0 18267 my ($values, $scheme_name, $all_names, $full_name, $distance) = @_;
33 547         669 my @return_names = ();
34 547 100       1289 my @scheme_names = (ref $scheme_name eq 'ARRAY') ? (@$scheme_name)
    100          
35             : (defined $scheme_name) ? $scheme_name : 'DEFAULT';
36 547         747 for my $scheme_name (@scheme_names) {
37 551         871 my $scheme = try_get_scheme( $scheme_name );
38 551 50       784 next unless ref $scheme;
39 551 100       1345 my $names = $distance ? $scheme->names_in_range( $values, $distance )
40             : $scheme->names_from_values( $values );
41 551 100       1047 next unless ref $names;
42 160 100 100     278 $names = [ map { uc($scheme_name).':'.$_} @$names] if $full_name and uc($scheme_name) ne 'DEFAULT';
  1         5  
43 160         331 push @return_names, @$names;
44             }
45 547 100       894 push @return_names, '' unless @return_names;
46 547         875 @return_names = uniq( @return_names );
47 547 100 100     1655 return (defined $all_names and $all_names) ? @return_names : $return_names[0];
48             }
49              
50             sub closest_from_values {
51 17     17 0 16105 my ($values, $scheme_name, $all_names, $full_name) = @_;
52             # exact search first
53 17         45 my @return_names = from_values( $values, $scheme_name, $all_names, $full_name );
54 17 100 100     91 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       25 my @scheme_names = (ref $scheme_name eq 'ARRAY') ? (@$scheme_name)
    100          
58             : (defined $scheme_name) ? $scheme_name : 'DEFAULT';
59 5         14 @return_names = ();
60 5         10 my $distance = 'Inf';
61 5         673 for my $scheme_name (@scheme_names) {
62 7         19 my $scheme = try_get_scheme( $scheme_name );
63 7 50       20 next unless ref $scheme;
64 7         28 my ($names, $d) = $scheme->closest_names_from_values( $values );
65 7         24 $d = round_decimals($d, 5);
66 7 50       63 next unless ref $names;
67 7 50       28 next unless $d <= $distance;
68 7         12 $distance = $d;
69 7 50 33     22 $names = [ map { uc($scheme_name).':'.$_} @$names] if $full_name and uc($scheme_name) ne 'DEFAULT';
  0         0  
70 7 50       39 @return_names = ($distance == $d) ? (@return_names, @$names) : (@$names);
71             }
72 5         15 @return_names = uniq( @return_names );
73 5 100 100     28 my $name = (defined $all_names and $all_names) ? \@return_names : $return_names[0];
74 5         28 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 641   100 641 0 2558 my $scheme_name = shift // 'DEFAULT';
87 641         1006 $scheme_name = uc $scheme_name;
88 641 100       1248 unless (exists $color_scheme{ $scheme_name }){
89 6         14 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 6         14 my $module = $module_base.'::'.$scheme_name;
93 6     2   541 eval "use $module";
  2         499  
  0            
  0            
94 6 50       48 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 635         874 return $color_scheme{ $scheme_name };
102             }
103             sub add_scheme {
104 1     1 0 4 my ($scheme, $scheme_name) = @_;
105             return if ref $scheme ne 'Graphics::Toolkit::Color::Name::Scheme'
106 1 50 33     15 or not defined $scheme_name or exists $color_scheme{ $scheme_name };
      33        
107 1         7 $color_scheme{ uc $scheme_name } = $scheme;
108             }
109             my $rgb_max = 256;
110             sub from_hex_to_rgb_tuple {
111 0     0 0 0 my $hex = shift;
112 0         0 my $rg = int $hex / $rgb_max;
113 0         0 return [ int $rg / $rgb_max, $rg % $rgb_max, $hex % $rgb_max];
114             }
115              
116              
117             1;