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   292141 use v5.12;
  10         51  
6 10     10   74 use warnings;
  10         16  
  10         593  
7 10     10   5195 use Graphics::Toolkit::Color::Name::Scheme;
  10         35  
  10         460  
8 10     10   64 use Graphics::Toolkit::Color::Space::Util qw/uniq round_decimals/;
  10         21  
  10         12955  
9              
10             #### public API ########################################################
11             sub all {
12 1     1 1 3 my (@scheme_names) = @_;
13 1 50       4 push @scheme_names, 'default' unless @scheme_names;
14 1         2 my @names = ();
15 1         1 for my $scheme_name (@scheme_names) {
16 1         3 my $scheme = try_get_scheme( $scheme_name );
17 1 50       3 next unless ref $scheme;
18 1         3 push @names, $scheme->all_names;
19             }
20 1         16 return uniq( @names );
21             }
22              
23             sub get_values {
24 68     68 1 1257 my ($color_name, $scheme_name) = @_;
25 68 100       234 ($scheme_name, $color_name) = split(':', $color_name, 2) if index($color_name, ':') > -1;
26 68         210 my $scheme = try_get_scheme( $scheme_name );
27 68 100       201 return $scheme unless ref $scheme;
28 66         282 return $scheme->values_from_name( $color_name );
29             }
30              
31             sub from_values {
32 502     502 1 11678 my ($values, $scheme_name, $all_names, $full_name, $distance) = @_;
33 502         1026 my @return_names = ();
34 502 100       1947 my @scheme_names = (ref $scheme_name eq 'ARRAY') ? (@$scheme_name)
    100          
35             : (defined $scheme_name) ? $scheme_name : 'DEFAULT';
36 502         1171 for my $scheme_name (@scheme_names) {
37 506         1400 my $scheme = try_get_scheme( $scheme_name );
38 506 50       1314 next unless ref $scheme;
39 506 100       2102 my $names = $distance ? $scheme->names_in_range( $values, $distance )
40             : $scheme->names_from_values( $values );
41 506 100       1588 next unless ref $names;
42 141 100 100     476 $names = [ map { uc($scheme_name).':'.$_} @$names] if $full_name and uc($scheme_name) ne 'DEFAULT';
  1         7  
43 141         520 push @return_names, @$names;
44             }
45 502 100       1427 push @return_names, '' unless @return_names;
46 502         1428 @return_names = uniq( @return_names );
47 502 100 100     2606 return (defined $all_names and $all_names) ? @return_names : $return_names[0];
48             }
49              
50             sub closest_from_values {
51 17     17 1 9055 my ($values, $scheme_name, $all_names, $full_name) = @_;
52             # exact search first
53 17         44 my @return_names = from_values( $values, $scheme_name, $all_names, $full_name );
54 17 100 100     125 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       33 my @scheme_names = (ref $scheme_name eq 'ARRAY') ? (@$scheme_name)
    100          
58             : (defined $scheme_name) ? $scheme_name : 'DEFAULT';
59 5         9 @return_names = ();
60 5         8 my $distance = 'Inf';
61 5         9 for my $scheme_name (@scheme_names) {
62 7         13 my $scheme = try_get_scheme( $scheme_name );
63 7 50       13 next unless ref $scheme;
64 7         22 my ($names, $d) = $scheme->closest_names_from_values( $values );
65 7         18 $d = round_decimals($d, 5);
66 7 50       35 next unless ref $names;
67 7 50       20 next unless $d <= $distance;
68 7         9 $distance = $d;
69 7 50 33     20 $names = [ map { uc($scheme_name).':'.$_} @$names] if $full_name and uc($scheme_name) ne 'DEFAULT';
  0         0  
70 7 50       28 @return_names = ($distance == $d) ? (@return_names, @$names) : (@$names);
71             }
72 5         12 @return_names = uniq( @return_names );
73 5 100 100     21 my $name = (defined $all_names and $all_names) ? \@return_names : $return_names[0];
74 5         21 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 587   100 587 0 2680 my $scheme_name = shift // 'DEFAULT';
87 587         1299 $scheme_name = uc $scheme_name;
88 587 100       1925 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         8 my $module = $module_base.'::'.$scheme_name;
93 2     2   398 eval "use $module";
  0         0  
  0         0  
  3         286  
94 3 50       30 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 584         1558 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__