File Coverage

blib/lib/Color/Calc.pm
Criterion Covered Total %
statement 204 223 91.4
branch 53 70 75.7
condition 23 43 53.4
subroutine 49 53 92.4
pod 15 15 100.0
total 344 404 85.1


line stmt bran cond sub pod time code
1             package Color::Calc;
2              
3 21     21   763538 use attributes;
  21         36523  
  21         130  
4 21     21   1178 use strict;
  21         48  
  21         654  
5 21     21   28773 use utf8;
  21         207  
  21         162  
6 21     21   1269 use warnings;
  21         39  
  21         679  
7              
8 21     21   219 use Carp;
  21         315  
  21         1567  
9 21     21   107 use Exporter;
  21         37  
  21         751  
10 21     21   20565 use Params::Validate qw(:all);
  21         305362  
  21         6833  
11 21     21   22946 use POSIX;
  21         592204  
  21         198  
12              
13 21     21   77732 use Scalar::Util qw(dualvar);
  21         46  
  21         1367  
14 21     21   394 use List::Util qw(min max reduce sum);
  21         38  
  21         3731  
15              
16 21     21   23175 use Graphics::ColorNames qw( hex2tuple tuple2hex );
  21         169774  
  21         1783  
17 21     21   21755 use Graphics::ColorNames::HTML qw();
  21         24484  
  21         49844  
18              
19             our $VERSION = "1.073";
20             $VERSION = eval $VERSION;
21              
22             our $MODE = ();
23              
24             my %__HTMLColors = ();
25             our @__subs = qw(
26             blend blend_bw
27             bw
28             contrast contrast_bw
29             dark
30             get
31             gray
32             grey
33             invert
34             light
35             mix
36             opposite
37             round
38             safe
39             );
40              
41 277 100   277   423 sub __put_tuple { map { my $a = int($_); length($a) % 3 ? $a : dualvar($a, "0$a") } @_ };
  831         972  
  831         4645  
42 290     290   767 sub __put_hex { dualvar((reduce { ($a << 8) | ($b & 0xFF) } @_), tuple2hex(@_)) };
  145     145   2833  
43 106 100   106   309 sub __put_html { my $col = lc(tuple2hex(@_)); $__HTMLColors{$col} || '#'.$col; };
  106         1562  
44 0     0   0 sub __put_object{ return Graphics::ColorObject->new_RGB255( \@_, '', '' ); };
45 0     0   0 sub __put_obj { return Color::Object->newRGB(map { 255*$_; } @_); };
  0         0  
46              
47             my %__formats = (
48             map { m/^__put_(.*)/ ? ( $1 => $Color::Calc::{$_} ) : () }
49             keys %Color::Calc::
50             );
51              
52             # use Data::Dumper;
53             # print STDERR Dumper(\%__formats);
54              
55             my %__formats_require = (
56             'obj' => 'Color::Object',
57             'object' => 'Graphics::ColorObject',
58             );
59              
60             $__formats{'pdf'} = $__formats{'html'};
61              
62             my @__formats = keys %__formats;
63             my $__formats_re = join('|', @__formats,'__MODEvar');
64              
65             {
66             my $table = Graphics::ColorNames::HTML::NamesRgbTable();
67             %__HTMLColors = map
68             { ( sprintf('%06x', $$table{$_}) => $_ ) }
69             grep { $_ ne 'fuscia' }
70             keys %$table;
71             };
72              
73             our @EXPORT = ('color', map({"color_$_"} @__formats, map({my $s=$_; (map{$s.'_'.$_} @__formats)} @__subs), @__subs));
74             our @ISA = ('Exporter');
75              
76             my %new_param = (
77             'ColorScheme' => { type => SCALAR | HANDLE | HASHREF | ARRAYREF | CODEREF, optional => 1 },
78             'OutputFormat' => { type => SCALAR, untaint => 1, regexp => qr($__formats_re), optional => 1 },
79             );
80              
81             sub new {
82 219     219 1 5478 my $pkg = shift; validate(@_, \%new_param);
  219         3475  
83 219         994 my $self = {@_}; bless($self, $pkg);
  219         654  
84              
85 219 50       3910 unless(UNIVERSAL::isa($self->{'ColorScheme'}, 'Graphics::ColorNames')) {
86 219         285 my %ColorNames;
87 219 100       524 if(defined $self->{'ColorScheme'}) {
88 7 50 33     106 if(!ref $self->{'ColorScheme'} && $self->{'ColorScheme'} =~ m/^([[:alnum:]_]+)$/) {
89 7         35 my $module = 'Graphics::ColorNames::'.$1;
90 7 50   7   688 eval "use $module;"; croak $! if $@;
  7         53  
  7         5520  
  7         8135  
  7         165  
91 7         52 my $names = UNIVERSAL::can($module, 'NamesRgbTable');
92 7 50       28 croak "$module is not compatible with Graphics::ColorNames" if !$names;
93 7         26 $self->{'ColorScheme'} = &$names();
94             }
95              
96 7         1207 tie %ColorNames, 'Graphics::ColorNames', $self->{'ColorScheme'};
97             } else {
98 212         1169 tie %ColorNames, 'Graphics::ColorNames';
99             }
100 219         148040 $self->{'ColorScheme'} = \%ColorNames;
101             }
102              
103 219   100     1325 $self->set_output_format($self->{'OutputFormat'} || 'tuple');
104 219         559 return $self;
105             }
106              
107             my $__default_object = undef;
108             sub __get_default {
109 36 100   36   89 $__default_object = __PACKAGE__->new('OutputFormat' => '__MODEvar') unless $__default_object;
110 36         77 return $__default_object;
111             }
112              
113             my $__raw_object = undef;
114             sub __get_raw {
115 189 100   189   573 $__raw_object = __PACKAGE__->new('OutputFormat' => 'tuple') unless $__raw_object;
116 189         690 return $__raw_object;
117             }
118              
119             my %import_param = (
120             %new_param,
121             'Prefix' => { type => SCALAR, optional => 1, regexp => qr/^[[:alpha:]\d]\w*$/ },
122             '__Prefix' => { type => SCALAR, optional => 1, regexp => qr/^[[:alpha:]\d]\w*$/ },
123             '__Suffix' => { type => SCALAR, optional => 1, regexp => qr/^\w+$/ },
124             );
125              
126             my %import_param_names = map { ($_=>1) } keys %import_param;
127              
128             sub import {
129 15     15   142 my $pkg = shift;
130 15 100 66     131 if(!@_ || !exists $import_param_names{$_[0]}) {
131 4         10 local $Exporter::ExportLevel; $Exporter::ExportLevel++;
  4         8  
132 4         11487 return Exporter::import($pkg, @_);
133             }
134 11 50       51 return __import(scalar caller(0),@_) ? 1 : 0;
135             }
136              
137             sub __import {
138 200     200   301 my $pkg = shift;
139 200         5487 validate(@_, \%import_param);
140 200         1297 my %param = @_;
141            
142 200 100       568 my $std_prefix = (exists $param{'Prefix'}) ? $param{'Prefix'} : 'color';
143 200         382 delete $param{'Prefix'};
144              
145 200 100       617 my $prefix = (exists $param{'__Prefix'}) ? $param{'__Prefix'} : $std_prefix ? $std_prefix.'_' : '';
    50          
146 200         263 delete $param{'__Prefix'};
147 200 100       459 my $suffix = (exists $param{'__Suffix'}) ? $param{'__Suffix'} : '';
148 200         290 delete $param{'__Suffix'};
149              
150 200         739 my $obj = new(__PACKAGE__, %param);
151              
152             {
153 21     21   216 no strict 'refs';
  21         48  
  21         73422  
  200         286  
154             {
155 200         218 $prefix = $pkg.'::'.$prefix;
  200         407  
156 200         374 foreach my $sub (@__subs) {
157 3000         5689 my $name = $prefix.$sub.$suffix;
158 3000     244   21552 *$name = sub { $obj->$sub(@_); };
  244         67684  
159             };
160             };
161            
162 200 100       830 if($std_prefix) {
163 116         414 my $name = $pkg.'::'.$std_prefix.$suffix;
164 116     13   946 *$name = sub { $obj->get(@_); };
  13         6027  
165             }
166             }
167 200         24185 return 1;
168             }
169              
170             sub __dualvar_tuple {
171 0     0   0 my $str = shift;
172 0     0   0 my $num = reduce { ($a << 8) | ($b & 0xFF) } @_;
  0         0  
173 0         0 return dualvar $num, $str;
174             }
175              
176             sub __normtuple_in {
177 800 50 33 800   1236 return map { (!defined($_) || $_ < 0) ? 0 : (($_ > 255) ? 255 : int($_+.5)) } @_;
  2400 50       13299  
178             }
179              
180             sub __is_col_val {
181 195 50   195   451 return undef unless defined $_[0];
182 195 50       526 return undef if $_[0] eq '';
183 195         1138 my ($n,$u) = POSIX::strtod($_[0]);
184 195 50       413 return undef if $u != 0;
185 195   33     1372 return ($n <= 255) && ($n>= 0);
186             }
187              
188             # Note: Color::Object was supported in versions before 0.2. This
189             # is kept for compatibility, but no longer documented.
190             #
191             # Note: versions before 0.2 allowed calling some functions (those
192             # with one parameter) with a list instead of an arrayref. This is
193             # kept for compatibility, but no longer documented.
194              
195             sub __get {
196 698     698   1056 my ($self,$p,$q) = @_;
197              
198 698 50 66     2548 if ((ref $$p[0]) eq 'ARRAY' && $#{$$p[0]} == 0 ) {
  272         5912  
199 0         0 $$p[0] = $$p[0]->[0];
200             }
201            
202 698 100 66     13358 if ((ref $$p[0]) eq 'ARRAY' && $#{$$p[0]} == 2 ) {
  272 50 33     872  
    50 33        
    100 100        
    100 66        
      66        
      33        
203 272         303 return __normtuple_in(@{shift @$p});
  272         584  
204             }
205             elsif( my $f255 = UNIVERSAL::can($$p[0],'asRGB255')
206             || UNIVERSAL::can($$p[0],'as_RGB255') ) {
207 0         0 return ($f255->(shift(@{$p})));
  0         0  
208             }
209             elsif( my $f1 = UNIVERSAL::can($$p[0],'asRGB')
210             || UNIVERSAL::can($$p[0],'as_RGB') ) {
211 0         0 return (map { 255 * $_; } $f1->(shift(@{$p})));
  0         0  
  0         0  
212             }
213             elsif( $#$p >= (2 + ($q||0)) &&
214             __is_col_val($$p[0]) &&
215             __is_col_val($$p[1]) &&
216             __is_col_val($$p[2])) {
217 65         323 return (splice @$p, 0, 3);
218             }
219             elsif( $$p[0] =~ m/^#?(([0-9A-F][0-9A-F][0-9A-F])+)$/i ) {
220 58         121 shift @$p;
221 58         157 my $hh = $1; my $hl = (length $hh)/3;
  58         173  
222 58         232 return map { hex($_) * 255.0 / hex('F' x $hl) }
  174         614  
223             (substr($hh,0,$hl), substr($hh,$hl,$hl), substr($hh,2*$hl));
224             }
225             else {
226 303         2737 my $col = $self->{'ColorScheme'}->{$$p[0]};
227 303 50       7308 if(defined $col) {
228 303         414 shift @$p;
229 303         859 return hex2tuple($col);
230             } else {
231 0         0 carp("Invalid color name '$$p[0]'");
232 0         0 return undef;
233             }
234             }
235             }
236              
237             sub __require_format {
238 126     126   204 my $new_fmt = shift;
239              
240 126 100       445 if(exists $__formats_require{$new_fmt}) {
241 21     21   9863 eval "use $__formats_require{$new_fmt}()";
  0     21   0  
  0         0  
  21         8824  
  0         0  
  0         0  
  42         3685  
242 42 50       9206 croak $@ if $@;
243             }
244 84         782 return 1;
245             }
246              
247             sub set_output_format {
248 219     219 1 6709 validate_pos(@_, { isa => __PACKAGE__ }, { type => SCALAR, regexp => qr($__formats_re) });
249 219         1070 my $self = shift;
250 219         394 my $new_fmt = shift;
251              
252 219         388 my $old = $self->{'OutputFormat'};
253 219         343 $self->{'OutputFormat'} = $new_fmt;
254              
255             $self->{'__put'} = $self->{'OutputFormat'} eq '__MODEvar'
256 114   50 114   419 ? sub{ return $__formats{$MODE || 'tuple'}->(@_); }
257 219 100       1316 : $__formats{$self->{'OutputFormat'}};
258            
259 219         459 return $old;
260             }
261              
262             sub __put {
263 528     528   959 my $self = shift;
264 528         10200 return $self->{'__put'}->(__normtuple_in(@_));
265             }
266              
267             sub __get_self {
268 572 100   572   2400 if(UNIVERSAL::isa($_[0]->[0], __PACKAGE__)) {
269 536         591 return shift @{$_[0]};
  536         1237  
270             } else {
271 36         69 return __get_default;
272             }
273             }
274              
275             =head1 NAME
276              
277             Color::Calc - Simple calculations with RGB colors.
278              
279             =head1 SYNOPSIS
280              
281             use Color::Calc ();
282             my $background = 'green';
283             print 'background: ',Color::Calc::color_html($background),";\n";
284             print 'border-top: solid 1px ',Color::Calc::light_html($background),";\n";
285             print 'border-bottom: solid 1px ',Color::Calc::dark_html($background),";\n";
286             print 'color: ',Color::Calc::contrast_bw_html($background),";\n";
287              
288             =head1 DESCRIPTION
289              
290             The C module implements simple calculations with RGB colors. This
291             can be used to create a full color scheme from a few colors.
292              
293             =head2 USAGE
294              
295             =head3 Constructors
296              
297             =over
298              
299             =item Color::Calc->new( ... )
300              
301             This class method creates a new C object.
302              
303             use Color::Calc();
304             my $cc = new Color::Calc( 'ColorScheme' => 'X', OutputFormat => 'HTML' );
305             print $cc->invert( 'white' );
306              
307             It accepts the following parameters:
308              
309             =over
310              
311             =item ColorScheme
312              
313             One of the color schemes accepted by C,
314             which is used to interpret color names on input. Valid values
315             include C (color names used in X-Windows) and C (color
316             names defined in the HTML 4.0 specification). For a full list of
317             possible values, please refer to the documentation of of
318             C.
319              
320             Unlike C, barewords are I interpreted as a module
321             name under C. If you really want to use a filename like
322             "foo", you have to write it as "./foo".
323              
324             Default: C (Note: This is incompatible with HTML color names).
325              
326             =item OutputFormat
327              
328             One of the output formats defined by this module. Possible values are:
329              
330             =over
331              
332             =item tuple
333              
334             Returns a list of three values in the range 0..255. The first value is
335             guaranteed to have a C that is not a multiple of three.
336              
337             =item hex
338              
339             Returns a hexadecimal RGB value as a scalar that contains a string in the
340             format RRGGBB and a number representing the hexadecimal number 0xRRGGBB.
341              
342             =item html
343              
344             Returns a string compatible with W3C's HTML and CSS specifications,
345             i.e. I<#RRGGBB> or one of the sixteen HTML color names.
346              
347             =item obj
348            
349             (DEPRECATED) Returns a C reference. The module C
350             must be installed, of course.
351              
352             =item object
353              
354             Returns a C reference. The module
355             C must be installed, of course.
356              
357             =item pdf
358              
359             Returns a string compatible with C, i.e. I<#RRGGBB>.
360              
361             =item __MODEvar
362              
363             (DEPRECATED) Uses the value of C<$Color::Calc::MODE> to select one
364             of the above output formats. You should use C when setting
365             this variable:
366              
367             local $Color::Calc::MODE = 'html';
368              
369             =back
370              
371             Default: C<__MODEvar> (for compatibility)
372              
373             =back
374              
375             =item Color::Calc->import( ... )
376              
377             This method creates a new, hidden object and binds its methods to the namespace
378             of the calling module.
379              
380             This method is usually not called directly but from perl's C statement:
381              
382             use Color::Calc(
383             'ColorScheme' => 'X',
384             'OutputFormat' => 'HTML',
385             'Prefix' => 'cc' );
386             print cc_invert( 'white' ); # prints 'black'
387              
388             On import, you can specify the following parameters:
389              
390             =over
391              
392             =item ColorScheme
393              
394             See above.
395              
396             =item OutputFormat
397              
398             See above.
399              
400             =item Prefix
401              
402             Adds a prefix to the front of the method names. The calculation methods are
403             bound to the name I_I (the specified prefix, an
404             underscore, the calculation method's name). Further, I is made an alias
405             for IC<_get>.
406              
407             Default: C
408              
409             =back
410              
411             Please note that with perl's C and C statemehts, omitting the list
412             and specifying an empty list has different meanings:
413              
414             use Color::Calc; # import with default settings (see below)
415              
416             use Color::Calc(); # don't import anything
417              
418             =back
419              
420             =head3 Property "set"/"get" methods
421              
422             These methods are inaccessible without a object reference, i.e. when the
423             functions have been Ced.
424              
425             =over
426              
427             =item $cc->set_output_format( $format)
428              
429             Changes the output format for an existing C object.
430              
431             =back
432              
433             =head3 Calculation methods
434              
435             All calculation methods I accept the following formats for C<$color> or
436             C<$color1>/C<$color2>:
437              
438             =over
439              
440             =item *
441              
442             An arrayref pointing to an array with three elements in the range
443             C<0>..C<255> corresponding to the red, green, and blue component.
444              
445             =item *
446              
447             A list of three values in the range C<0>..C<255> corresponding to the red,
448             green, and blue component where the first value does not have 3 or a multiple
449             of 3 digits (e.g. C<('0128',128,128)>).
450              
451             =item *
452              
453             A string containing a hexadecimal RGB value like
454             C<#I>/C<#I>/C<#I>/..., or
455             C>/C>/C>/...
456              
457             =item *
458              
459             A color name accepted by C. The
460             interpretation is controlled by the C parameter.
461              
462             =item *
463              
464             A C reference.
465              
466             =back
467              
468             The calculation methods can be either accessed through a C object
469             reference (here: C<$cc>) or through the method names imported by C
470             (here using the prefix L).
471              
472             =over
473              
474             =item $cc->get($color) / color($color)
475              
476             Returns C<$color> as-is (but in the selected output format). This
477             function can be used for color format conversion/normalisation.
478              
479             =cut
480              
481             sub get {
482 40     40 1 4876 my $self = __get_self(\@_);
483 40         293 return $self->__put($self->__get(\@_));
484             }
485              
486             =item $cc->invert($color) / color_invert($color)
487              
488             Returns the inverse of C<$color>.
489              
490             =cut
491              
492             sub invert {
493 22     22 1 1149 my $self = __get_self(\@_);
494 22         140 return $self->__put(map { 255 - $_ } $self->__get(\@_));
  66         286  
495             }
496              
497             =item $cc->opposite($color) / color_opposite($color)
498              
499             Returns a color that is on the opposite side of the color wheel but roughly
500             keeps the saturation and lightness.
501              
502             =cut
503              
504             sub opposite {
505 15     15 1 28 my $self = __get_self(\@_);
506 15         37 my @rgb = $self->__get(\@_);
507              
508 15         77 my $min = min @rgb;
509 15         28 my $max = max @rgb;
510              
511 45         88 return $self->__put(
512 15         18 map { $max - $_ + $min } @rgb
513             );
514             }
515              
516             =item $cc->bw($color) / color_bw($color)
517              
518             =item $cc->grey($color) / color_grey($color)
519              
520             =item $cc->gray($color) / color_gray($color)
521              
522             Converts C<$color> to greyscale.
523              
524             =cut
525              
526             sub bw {
527 110     110 1 3471 my $self = __get_self(\@_);
528 110         300 my @c = $self->__get(\@_);
529 110         824 my $g = $c[0]*.3 + $c[1]*.59 + $c[2]*.11;
530 110         255 return $self->__put($g, $g, $g);
531             }
532              
533             *grey = \&bw;
534             *gray = \&bw;
535              
536             =item $cc->round($color, $value_count) / color_round($color, $value_count)
537              
538             Rounds each component to to the nearest number determined by dividing the range
539             0..255 into C<$value_count>+1 portions.
540              
541             The default for C<$value_count> is 6, yielding S<6^3 = 216> colors. Values
542             that are one higher than divisors of 255 yield the best results (e.g. 3+1, 5+1,
543             7+1, 9+1, 15+1, 17+1, ...).
544              
545             =cut
546              
547             sub round {
548 26     26 1 52 my $self = __get_self(\@_);
549 26         64 my @rgb = $self->__get(\@_);
550 26   50     155 my $steps = shift || 6;
551 26         27 $steps--;
552              
553 78         198 return $self->__put(
554 26         36 map { int(int( $_ * $steps / 255 + 0.5) * 255 / $steps + 0.5) } @rgb
555             );
556             }
557              
558             =item $cc->safe($color) / color_safe($color)
559              
560             Rounds each color component to a multiple of 0x33 (dec. 51) or to a named color
561             defined in the HTML 4.01 specification.
562              
563             Historically, these colors have been known as web-safe colors. They still
564             provide a convenient color palette.
565              
566             =cut
567              
568             sub __dist2 {
569 221     221   420 my @a = splice @_, 0, 3;
570 221         246 return sum map { POSIX::pow($_ - shift @a, 2) } @_;
  663         12762  
571             }
572              
573             sub safe {
574 13     13 1 33 my $self = __get_self(\@_);
575 13         32 my @rgb = $self->__get(\@_);
576              
577 13         68 my @new_rgb = __get_raw->round(@rgb);
578 13         29 my $new_d2 = __dist2(@rgb, @new_rgb);
579              
580 13         120 foreach my $h (keys %__HTMLColors) {
581 208         418 my @h_rgb = hex2tuple($h);
582 208         1200 my $h_d2 = __dist2(@rgb, @h_rgb);
583              
584 208 100       1362 if($h_d2 <= $new_d2) {
585 8         14 @new_rgb = @h_rgb;
586 8         14 $new_d2 = $h_d2;
587             }
588             }
589 13         41 return $self->__put(@new_rgb);
590             }
591              
592             =item $cc->mix($color1, $color2 [, $alpha]) / color_mix($color1, $color2 [, $alpha])
593              
594             Returns a color that is the mixture of C<$color1> and C<$color2>.
595              
596             The optional C<$alpha> parameter can be a value between 0.0 (use
597             C<$color1> only) and 1.0 (use C<$color2> only), the default is 0.5.
598              
599             =cut
600              
601             sub mix {
602 126     126 1 6808 my $self = __get_self(\@_);
603 126         376 my @c1 = ($self->__get(\@_,1));
604 126         596 my @c2 = ($self->__get(\@_));
605 126 50       393 my $alpha = shift(@_); $alpha = 0.5 unless defined $alpha;
  126         387  
606              
607 126         681 return $self->__put(
608             ($c1[0] + ($c2[0]-$c1[0])*$alpha),
609             ($c1[1] + ($c2[1]-$c1[1])*$alpha),
610             ($c1[2] + ($c2[2]-$c1[2])*$alpha) );
611             }
612              
613             =item $cc->light($color [, $alpha]) / color_light($color [, $alpha])
614              
615             Returns a lighter version of C<$color>, i.e. returns
616             C.
617              
618             The optional C<$alpha> parameter can be a value between 0.0 (use C<$color>
619             only) and 1.0 (use [255,255,255] only), the default is 0.5.
620              
621             =cut
622              
623             sub light {
624 22     22 1 1082 my $self = __get_self(\@_);
625 22         114 return $self->__put(__get_raw->mix([$self->__get(\@_)],[255,255,255],shift));
626             }
627              
628             =item $cc->dark($color [, $alpha]) / color_dark($color [, $alpha])
629              
630             Returns a darker version of C<$color>, i.e. returns
631             C.
632              
633             The optional C<$alpha> parameter can be a value between 0.0 (use
634             C<$color> only) and 1.0 (use [0,0,0] only), the default is 0.5.
635              
636             =cut
637              
638             sub dark {
639 22     22 1 1152 my $self = __get_self(\@_);
640 22         79 return $self->__put(__get_raw->mix([$self->__get(\@_)],[0,0,0],shift));
641             }
642              
643              
644             =item $cc->contrast($color [, $cut]) / color_contrast($color [, $cut])
645              
646             Returns a color that has the highest possible contrast to the input
647             color.
648              
649             This is done by setting the red, green, and blue values to 0 if
650             the corresponding value in the input is above C<($cut * 255)> and
651             to 255 otherwise.
652              
653             The default for C<$cut> is .5, representing a cutoff between 127 and 128.
654              
655             =cut
656              
657             sub contrast {
658 88     88 1 1208 my $self = __get_self(\@_);
659 88         255 my @rgb = $self->__get(\@_);
660 88   50     577 my $cut = (shift || .5) * 255;
661 88 100       153 return $self->__put(map { $_ >= $cut ? 0 : 255 } @rgb);
  264         765  
662             }
663              
664             =item $cc->contrast_bw($color [, $cut]) / color_contrast_bw($color [, $cut])
665              
666             Returns black or white, whichever has the higher contrast to C<$color>.
667              
668             This is done by returning black if the grey value of C<$color> is
669             above C<($cut * 255)> and white otherwise.
670              
671             The default for C<$cut> is .5, representing a cutoff between 127 and 128.
672              
673             =cut
674              
675             sub contrast_bw {
676 44     44 1 1178 my $self = __get_self(\@_);
677 44         155 my @rgb = $self->__get(\@_);
678 44         270 return $self->__put(__get_raw->contrast([__get_raw->bw(@rgb)], shift));
679             }
680              
681             =item $cc->blend($color [, $alpha]) / color_blend($color [, $alpha])
682              
683             Returns a color that blends into the background, i.e. it returns
684             C.
685              
686             The optional C<$alpha> parameter can be a value between 0.0 (use
687             C<$color> only) and 1.0 (use C only), the
688             default is 0.5.
689              
690             The idea is that C<$color> is the foreground color, so
691             C is similar to the background color. Mixing
692             them returns a color somewhere between them.
693              
694             You might want to use C instead
695             if you know the real background color.
696              
697             =cut
698              
699             sub blend {
700 22     22 1 1426 my $self = __get_self(\@_);
701 22         89 my @c1 = $self->__get(\@_);
702 22         58042 return $self->mix(\@c1,[__get_raw->contrast(\@c1)],shift);
703             }
704              
705             =item $cc->blend_bw($color [, $alpha]) / color_blend_bw($color [, $alpha])
706              
707             Returns a mix of C<$color> and black or white, whichever has the
708             higher contrast to C<$color>.
709              
710             The optional C<$alpha> parameter can be a value between 0.0 (use
711             C<$color> only) and 1.0 (use black/white only), the default is 0.5.
712              
713             =cut
714              
715             sub blend_bw {
716 22     22 1 1177 my $self = __get_self(\@_);
717 22         104 my @c = $self->__get(\@_);
718 22         264 return $self->mix(\@c,[__get_raw->contrast_bw(\@c)],shift);
719             }
720              
721             =back
722              
723             =head3 Functions
724              
725             The calculation methods are also available as functions. The output format is
726             selected through the function name.
727              
728             These functions are deprecated as they do not allow selecting the scheme of
729             recognized color names, which defaults to L (and is
730             incompatible with HTML's color names).
731              
732             By default, i.e. when no list is specified with C or C, all of
733             these functions are exported.
734              
735             =over
736              
737             =item color, color_mix, ...
738              
739             Use C<$Color::Calc::MODE> as the output format. This is the default.
740              
741             =item color_hex, color_mix_html, ...
742              
743             Use C as the output format.
744              
745             =item color_html, color_mix_html, ...
746              
747             Use C as the output format. Please note that the color names recognized
748             are still based on X's color names, which are incompatible with HTML. You can't
749             use the output of these functions as input for other color_*_html functions.
750              
751             See L for an alternative that does not suffer from this
752             problem.
753              
754             =item color_pdf, color_mix_pdf, ...
755              
756             Use C as the output format.
757              
758             =item color_object, color_mix_object, ...
759              
760             Use C as the output format.
761              
762             =back
763              
764             =cut
765              
766             foreach my $format (@__formats) {
767             next if !eval{__require_format($format)};
768             __import(__PACKAGE__, 'Prefix' => 'color', '__Suffix' => "_$format", 'OutputFormat' => $format);
769             __import(__PACKAGE__, 'Prefix' => '', '__Suffix' => "_$format", 'OutputFormat' => $format);
770             }
771              
772             __import(__PACKAGE__, 'Prefix' => 'color', 'OutputFormat' => '__MODEvar');
773              
774             =head1 SEE ALSO
775              
776             L (required); L (optional)
777              
778             =head1 AUTHOR
779              
780             Claus FErber
781              
782             =head1 LICENSE
783              
784             Copyright 2004-2010 Claus FErber. All rights reserved.
785              
786             This library is free software; you can redistribute it and/or modify it under
787             the same terms as Perl itself.
788              
789             =cut
790              
791             1;
792             __END__