File Coverage

blib/lib/Convert/Color/CMYK.pm
Criterion Covered Total %
statement 56 58 96.5
branch 10 14 71.4
condition n/a
subroutine 17 17 100.0
pod 7 12 58.3
total 90 101 89.1


line stmt bran cond sub pod time code
1             # You may distribute under the terms of either the GNU General Public License
2             # or the Artistic License (the same terms as Perl itself)
3             #
4             # (C) Paul Evans, 2009-2022 -- leonerd@leonerd.org.uk
5              
6             package Convert::Color::CMYK 0.14;
7              
8 12     12   135339 use v5.14;
  12         97  
9 12     12   66 use warnings;
  12         33  
  12         407  
10 12     12   63 use base qw( Convert::Color );
  12         24  
  12         2166  
11              
12             __PACKAGE__->register_color_space( 'cmyk' );
13              
14 12     12   92 use List::Util qw( min );
  12         24  
  12         1194  
15              
16 12     12   89 use Carp;
  12         34  
  12         9289  
17              
18             =head1 NAME
19              
20             C - a color value represented as cyan/magenta/yellow/key
21              
22             =head1 SYNOPSIS
23              
24             Directly:
25              
26             use Convert::Color::CMYK;
27              
28             my $red = Convert::Color::CMYK->new( 0, 1, 1, 0 );
29              
30             # Can also parse strings
31             my $pink = Convert::Color::CMYK->new( '0,0.3,0.3,0' );
32              
33             Via L:
34              
35             use Convert::Color;
36              
37             my $cyan = Convert::Color->new( 'cmyk:1,0,0,0' );
38              
39             =head1 DESCRIPTION
40              
41             Objects in this class represent a color in CMYK space, as a set of four
42             floating-point values in the range 0 to 1.
43              
44             =cut
45              
46             =head1 CONSTRUCTOR
47              
48             =cut
49              
50             =head2 new
51              
52             $color = Convert::Color::CMYK->new( $cyan, $magenta, $yellow, $key )
53              
54             Returns a new object to represent the set of values given. These values should
55             be floating-point numbers between 0 and 1. Values outside of this range will
56             be clamped.
57              
58             $color = Convert::Color::CMYK->new( $string )
59              
60             Parses C<$string> for values, and construct a new object similar to the above
61             three-argument form. The string should be in the form
62              
63             cyan,magenta,yellow,key
64              
65             containing the three floating-point values in decimal notation.
66              
67             =cut
68              
69             sub new
70             {
71 18     18 1 199 my $class = shift;
72              
73 18         37 my ( $c, $m, $y, $k );
74              
75 18 100       60 if( @_ == 1 ) {
    50          
76 3         10 local $_ = $_[0];
77 3 50       23 if( m/^(\d+(?:\.\d+)?),(\d+(?:\.\d+)?),(\d+(?:\.\d+)?),(\d+(?:\.\d+)?)$/ ) {
78 3         18 ( $c, $m, $y, $k ) = ( $1, $2, $3, $4 );
79             }
80             else {
81 0         0 croak "Unrecognised CMYK string spec '$_'";
82             }
83             }
84             elsif( @_ == 4 ) {
85 15         33 ( $c, $m, $y, $k ) = @_;
86             }
87             else {
88 0         0 croak "usage: Convert::Color::CMYK->new( SPEC ) or ->new( C, M, Y, K )";
89             }
90              
91             # Clamp
92 18         42 for ( $c, $m, $y, $k ) {
93 72 50       138 $_ = 0 if $_ < 0;
94 72 50       139 $_ = 1 if $_ > 1;
95             }
96              
97 18         83 return bless [ $c, $m, $y, $k ], $class;
98             }
99              
100             =head1 METHODS
101              
102             =cut
103              
104             =head2 cyan
105              
106             $c = $color->cyan
107              
108             =head2 magenta
109              
110             $m = $color->magenta
111              
112             =head2 yellow
113              
114             $y = $color->yellow
115              
116             =head2 key
117              
118             $k = $color->key
119              
120             Accessors for the four components of the color.
121              
122             =cut
123              
124             # Simple accessors
125 18     18 1 459 sub cyan { shift->[0] }
126 18     18 1 85 sub magenta { shift->[1] }
127 18     18 1 77 sub yellow { shift->[2] }
128 25     25 1 88 sub key { shift->[3] }
129              
130             =head2 black
131              
132             $k = $color->black
133              
134             An alias to C
135              
136             =cut
137              
138             *black = \&key; # alias
139              
140             =head2 cmyk
141              
142             ( $cyan, $magenta, $yellow, $key ) = $color->cmyk
143              
144             Returns the individual cyan, magenta, yellow and key components of the color
145             value.
146              
147             =cut
148              
149             sub cmyk
150             {
151 5     5 1 13 my $self = shift;
152 5         31 return @$self;
153             }
154              
155             # Conversions
156              
157             sub cmy
158             {
159 7     7 0 13 my $self = shift;
160              
161 7 100       14 if( $self->key == 1 ) {
162             # Pure black
163 2         8 return ( 1, 1, 1 );
164             }
165              
166 5         10 my $k = $self->key;
167 5         10 my $w = 1 - $k;
168              
169 5         11 return ( ($self->cyan * $w) + $k, ($self->magenta * $w) + $k, ($self->yellow * $w) + $k );
170             }
171              
172             sub rgb
173             {
174 5     5 1 8 my $self = shift;
175 5         10 my ( $c, $m, $y ) = $self->cmy;
176 5         19 return ( 1 - $c, 1 - $m, 1 - $y );
177             }
178              
179             sub new_cmy
180             {
181 7     7 0 13 my $class = shift;
182 7         14 my ( $c, $m, $y ) = @_;
183              
184 7         24 my $k = min( $c, $m, $y );
185              
186 7 100       20 if( $k == 1 ) {
187             # Pure black
188 2         10 return $class->new( 0, 0, 0, 1 );
189             }
190             else {
191             # Rescale other components around key
192 5         9 my $w = 1 - $k; # whiteness
193 5         22 return $class->new( ($c - $k) / $w, ($m - $k) / $w, ($y - $k) / $w, $k );
194             }
195             }
196              
197             sub new_rgb
198             {
199 5     5 0 11 my $class = shift;
200 5         9 my ( $r, $g, $b ) = @_;
201              
202 5         17 return $class->new_cmy( 1-$r, 1-$g, 1-$b );
203             }
204              
205             sub convert_to_cmy
206             {
207 2     2 0 3 my $self = shift;
208 2         11 require Convert::Color::CMY;
209 2         5 return Convert::Color::CMY->new( $self->cmy );
210             }
211              
212             sub new_from_cmy
213             {
214 2     2 0 5 my $class = shift;
215 2         4 my ( $cmy ) = @_;
216 2         6 return $class->new_cmy( $cmy->cyan, $cmy->magenta, $cmy->yellow );
217             }
218              
219             =head1 SEE ALSO
220              
221             =over 4
222              
223             =item *
224              
225             L - color space conversions
226              
227             =item *
228              
229             L - a color value represented as cyan/magenta/yellow
230              
231             =back
232              
233             =head1 AUTHOR
234              
235             Paul Evans
236              
237             =cut
238              
239             0x55AA;