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   1087868 use attributes;
  21         21530  
  21         103  
4 21     21   945 use strict;
  21         31  
  21         376  
5 21     21   10214 use utf8;
  21         174  
  21         91  
6 21     21   526 use warnings;
  21         26  
  21         530  
7              
8 21     21   77 use Carp;
  21         26  
  21         974  
9 21     21   84 use Exporter;
  21         26  
  21         585  
10 21     21   9867 use Params::Validate qw(:all);
  21         152523  
  21         3550  
11 21     21   8679 use POSIX ();
  21         97874  
  21         608  
12              
13 21     21   105 use Scalar::Util qw(dualvar);
  21         23  
  21         881  
14 21     21   189 use List::Util qw(min max reduce sum);
  21         21  
  21         1578  
15              
16 21     21   8849 use Graphics::ColorNames qw( hex2tuple tuple2hex );
  21         82923  
  21         1039  
17 21     21   8022 use Graphics::ColorNames::HTML qw();
  21         11508  
  21         22092  
18              
19             our $VERSION = "1.074";
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   255 sub __put_tuple { map { my $a = int($_); length($a) % 3 ? $a : dualvar($a, "0$a") } @_ };
  831         588  
  831         3085  
42 290     290   610 sub __put_hex { dualvar((reduce { ($a << 8) | ($b & 0xFF) } @_), tuple2hex(@_)) };
  145     145   893  
43 106 100   106   237 sub __put_html { my $col = lc(tuple2hex(@_)); $__HTMLColors{$col} || '#'.$col; };
  106         1375  
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 5178 my $pkg = shift; validate(@_, \%new_param);
  219         2031  
83 219         612 my $self = {@_}; bless($self, $pkg);
  219         299  
84              
85 219 50       1450 unless(UNIVERSAL::isa($self->{'ColorScheme'}, 'Graphics::ColorNames')) {
86 219         191 my %ColorNames;
87 219 100       318 if(defined $self->{'ColorScheme'}) {
88 7 50 33     74 if(!ref $self->{'ColorScheme'} && $self->{'ColorScheme'} =~ m/^([[:alnum:]_]+)$/) {
89 7         23 my $module = 'Graphics::ColorNames::'.$1;
90 7 50   7   378 eval "use $module;"; croak $! if $@;
  7         32  
  7         2090  
  7         4252  
  7         112  
91 7         25 my $names = UNIVERSAL::can($module, 'NamesRgbTable');
92 7 50       15 croak "$module is not compatible with Graphics::ColorNames" if !$names;
93 7         18 $self->{'ColorScheme'} = &$names();
94             }
95              
96 7         630 tie %ColorNames, 'Graphics::ColorNames', $self->{'ColorScheme'};
97             } else {
98 212         723 tie %ColorNames, 'Graphics::ColorNames';
99             }
100 219         75422 $self->{'ColorScheme'} = \%ColorNames;
101             }
102              
103 219   100     864 $self->set_output_format($self->{'OutputFormat'} || 'tuple');
104 219         282 return $self;
105             }
106              
107             my $__default_object = undef;
108             sub __get_default {
109 36 100   36   71 $__default_object = __PACKAGE__->new('OutputFormat' => '__MODEvar') unless $__default_object;
110 36         61 return $__default_object;
111             }
112              
113             my $__raw_object = undef;
114             sub __get_raw {
115 189 100   189   410 $__raw_object = __PACKAGE__->new('OutputFormat' => 'tuple') unless $__raw_object;
116 189         425 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   89 my $pkg = shift;
130 15 100 66     81 if(!@_ || !exists $import_param_names{$_[0]}) {
131 4         8 local $Exporter::ExportLevel; $Exporter::ExportLevel++;
  4         5  
132 4         7908 return Exporter::import($pkg, @_);
133             }
134 11 50       43 return __import(scalar caller(0),@_) ? 1 : 0;
135             }
136              
137             sub __import {
138 200     200   179 my $pkg = shift;
139 200         3550 validate(@_, \%import_param);
140 200         832 my %param = @_;
141            
142 200 100       397 my $std_prefix = (exists $param{'Prefix'}) ? $param{'Prefix'} : 'color';
143 200         325 delete $param{'Prefix'};
144              
145 200 100       384 my $prefix = (exists $param{'__Prefix'}) ? $param{'__Prefix'} : $std_prefix ? $std_prefix.'_' : '';
    50          
146 200         143 delete $param{'__Prefix'};
147 200 100       253 my $suffix = (exists $param{'__Suffix'}) ? $param{'__Suffix'} : '';
148 200         163 delete $param{'__Suffix'};
149              
150 200         358 my $obj = new(__PACKAGE__, %param);
151              
152             {
153 21     21   109 no strict 'refs';
  21         26  
  21         37529  
  200         192  
154             {
155 200         150 $prefix = $pkg.'::'.$prefix;
  200         271  
156 200         259 foreach my $sub (@__subs) {
157 3000         2915 my $name = $prefix.$sub.$suffix;
158 3000     244   12503 *$name = sub { $obj->$sub(@_); };
  244         68946  
159             };
160             };
161            
162 200 100       347 if($std_prefix) {
163 116         149 my $name = $pkg.'::'.$std_prefix.$suffix;
164 116     13   534 *$name = sub { $obj->get(@_); };
  13         3366  
165             }
166             }
167 200         12441 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   732 return map { (!defined($_) || $_ < 0) ? 0 : (($_ > 255) ? 255 : int($_+.5)) } @_;
  2400 50       9340  
178             }
179              
180             sub __is_col_val {
181 195 50   195   285 return undef unless defined $_[0];
182 195 50       342 return undef if $_[0] eq '';
183 195         732 my ($n,$u) = POSIX::strtod($_[0]);
184 195 50       304 return undef if $u != 0;
185 195   33     998 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   735 my ($self,$p,$q) = @_;
197              
198 698 50 66     1544 if ((ref $$p[0]) eq 'ARRAY' && $#{$$p[0]} == 0 ) {
  272         1008  
199 0         0 $$p[0] = $$p[0]->[0];
200             }
201            
202 698 100 66     8622 if ((ref $$p[0]) eq 'ARRAY' && $#{$$p[0]} == 2 ) {
  272 50 33     586  
    50 33        
    100 100        
    100 66        
      66        
      33        
203 272         192 return __normtuple_in(@{shift @$p});
  272         378  
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         305 return (splice @$p, 0, 3);
218             }
219             elsif( $$p[0] =~ m/^#?(([0-9A-F][0-9A-F][0-9A-F])+)$/i ) {
220 58         92 shift @$p;
221 58         151 my $hh = $1; my $hl = (length $hh)/3;
  58         114  
222 58         178 return map { hex($_) * 255.0 / hex('F' x $hl) }
  174         543  
223             (substr($hh,0,$hl), substr($hh,$hl,$hl), substr($hh,2*$hl));
224             }
225             else {
226 303         1603 my $col = $self->{'ColorScheme'}->{$$p[0]};
227 303 50       5050 if(defined $col) {
228 303         305 shift @$p;
229 303         592 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   126 my $new_fmt = shift;
239              
240 126 100       283 if(exists $__formats_require{$new_fmt}) {
241 21     21   3396 eval "use $__formats_require{$new_fmt}()";
  0     21   0  
  0         0  
  21         3282  
  0         0  
  0         0  
  42         2395  
242 42 50       5698 croak $@ if $@;
243             }
244 84         181 return 1;
245             }
246              
247             sub set_output_format {
248 219     219 1 4495 validate_pos(@_, { isa => __PACKAGE__ }, { type => SCALAR, regexp => qr($__formats_re) });
249 219         668 my $self = shift;
250 219         226 my $new_fmt = shift;
251              
252 219         228 my $old = $self->{'OutputFormat'};
253 219         223 $self->{'OutputFormat'} = $new_fmt;
254              
255             $self->{'__put'} = $self->{'OutputFormat'} eq '__MODEvar'
256 114   50 114   325 ? sub{ return $__formats{$MODE || 'tuple'}->(@_); }
257 219 100       832 : $__formats{$self->{'OutputFormat'}};
258            
259 219         249 return $old;
260             }
261              
262             sub __put {
263 528     528   640 my $self = shift;
264 528         773 return $self->{'__put'}->(__normtuple_in(@_));
265             }
266              
267             sub __get_self {
268 572 100   572   1623 if(UNIVERSAL::isa($_[0]->[0], __PACKAGE__)) {
269 536         435 return shift @{$_[0]};
  536         933  
270             } else {
271 36         63 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 4452 my $self = __get_self(\@_);
483 40         110 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 1148 my $self = __get_self(\@_);
494 22         91 return $self->__put(map { 255 - $_ } $self->__get(\@_));
  66         235  
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 35 my $self = __get_self(\@_);
506 15         35 my @rgb = $self->__get(\@_);
507              
508 15         52 my $min = min @rgb;
509 15         20 my $max = max @rgb;
510              
511             return $self->__put(
512 15         15 map { $max - $_ + $min } @rgb
  45         67  
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 3132 my $self = __get_self(\@_);
528 110         212 my @c = $self->__get(\@_);
529 110         592 my $g = $c[0]*.3 + $c[1]*.59 + $c[2]*.11;
530 110         202 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 61 my $self = __get_self(\@_);
549 26         45 my @rgb = $self->__get(\@_);
550 26   50     98 my $steps = shift || 6;
551 26         23 $steps--;
552              
553             return $self->__put(
554 26         26 map { int(int( $_ * $steps / 255 + 0.5) * 255 / $steps + 0.5) } @rgb
  78         153  
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   325 my @a = splice @_, 0, 3;
570 221         185 return sum map { POSIX::pow($_ - shift @a, 2) } @_;
  663         9163  
571             }
572              
573             sub safe {
574 13     13 1 30 my $self = __get_self(\@_);
575 13         25 my @rgb = $self->__get(\@_);
576              
577 13         51 my @new_rgb = __get_raw->round(@rgb);
578 13         46 my $new_d2 = __dist2(@rgb, @new_rgb);
579              
580 13         90 foreach my $h (keys %__HTMLColors) {
581 208         268 my @h_rgb = hex2tuple($h);
582 208         864 my $h_d2 = __dist2(@rgb, @h_rgb);
583              
584 208 100       972 if($h_d2 <= $new_d2) {
585 8         16 @new_rgb = @h_rgb;
586 8         8 $new_d2 = $h_d2;
587             }
588             }
589 13         31 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 5498 my $self = __get_self(\@_);
603 126         249 my @c1 = ($self->__get(\@_,1));
604 126         369 my @c2 = ($self->__get(\@_));
605 126 50       260 my $alpha = shift(@_); $alpha = 0.5 unless defined $alpha;
  126         230  
606              
607 126         506 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 1067 my $self = __get_self(\@_);
625 22         83 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 1010 my $self = __get_self(\@_);
640 22         55 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 1064 my $self = __get_self(\@_);
659 88         160 my @rgb = $self->__get(\@_);
660 88   50     471 my $cut = (shift || .5) * 255;
661 88 100       105 return $self->__put(map { $_ >= $cut ? 0 : 255 } @rgb);
  264         501  
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 993 my $self = __get_self(\@_);
677 44         99 my @rgb = $self->__get(\@_);
678 44         207 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 1409 my $self = __get_self(\@_);
701 22         80 my @c1 = $self->__get(\@_);
702 22         232 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 1029 my $self = __get_self(\@_);
717 22         70 my @c = $self->__get(\@_);
718 22         201 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__