File Coverage

/root/.cpan/build/Imager-1.018-0/blib/lib/Imager/Fill.pm
Criterion Covered Total %
statement 70 86 81.4
branch 31 42 73.8
condition 25 34 73.5
subroutine 4 5 80.0
pod 3 3 100.0
total 133 170 78.2


line stmt bran cond sub pod time code
1             package Imager::Fill;
2 9     9   1209 use 5.006;
  9         36  
3 9     9   46 use strict;
  9         14  
  9         8618  
4              
5             our $VERSION = "1.013";
6              
7             # this needs to be kept in sync with the array of hatches in fills.c
8             my @hatch_types =
9             qw/check1x1 check2x2 check4x4 vline1 vline2 vline4
10             hline1 hline2 hline4 slash1 slosh1 slash2 slosh2
11             grid1 grid2 grid4 dots1 dots4 dots16 stipple weave cross1 cross2
12             vlozenge hlozenge scalesdown scalesup scalesleft scalesright stipple2
13             tile_L stipple3/;
14             my %hatch_types;
15             @hatch_types{@hatch_types} = 0..$#hatch_types;
16              
17             *_color = \&Imager::_color;
18              
19             sub new {
20 67     67 1 5435 my ($class, %hsh) = @_;
21              
22 67         162 my $self = bless { }, $class;
23 67         308 $hsh{combine} = Imager->_combine($hsh{combine}, 0);
24 67 100 33     349 if ($hsh{solid}) {
    100          
    100          
    100          
    50          
25 22         73 my $solid = _color($hsh{solid});
26 22 50       82 if (UNIVERSAL::isa($solid, 'Imager::Color')) {
    0          
27             $self->{fill} =
28 22         1137 Imager::i_new_fill_solid($solid, $hsh{combine});
29             }
30             elsif (UNIVERSAL::isa($solid, 'Imager::Color::Float')) {
31             $self->{fill} =
32 0         0 Imager::i_new_fill_solidf($solid, $hsh{combine});
33             }
34             else {
35 0         0 $Imager::ERRSTR = "solid isn't a color";
36 0         0 return undef;
37             }
38             }
39             elsif (defined $hsh{hatch}) {
40 22   100     101 $hsh{dx} ||= 0;
41 22   100     105 $hsh{dy} ||= 0;
42 22   66     98 $hsh{fg} ||= Imager::Color->new(0, 0, 0);
43 22 50       165 if (ref $hsh{hatch}) {
    50          
44 0         0 $hsh{cust_hatch} = pack("C8", @{$hsh{hatch}});
  0         0  
45 0         0 $hsh{hatch} = 0;
46             }
47             elsif ($hsh{hatch} =~ /\D/) {
48 22 100       76 unless (exists($hatch_types{$hsh{hatch}})) {
49 1         6 $Imager::ERRSTR = "Unknown hatch type $hsh{hatch}";
50 1         60 return undef;
51             }
52 21         48 $hsh{hatch} = $hatch_types{$hsh{hatch}};
53             }
54 21         63 my $fg = _color($hsh{fg});
55 21 50       87 if (UNIVERSAL::isa($fg, 'Imager::Color')) {
    0          
56 21   66     92 my $bg = _color($hsh{bg} || Imager::Color->new(255, 255, 255));
57             $self->{fill} =
58             Imager::i_new_fill_hatch($fg, $bg, $hsh{combine},
59             $hsh{hatch}, $hsh{cust_hatch},
60 21         1983 $hsh{dx}, $hsh{dy});
61             }
62             elsif (UNIVERSAL::isa($fg, 'Imager::Color::Float')) {
63 0   0     0 my $bg = _color($hsh{bg} || Imager::Color::Float->new(1, 1, 1));
64             $self->{fill} =
65             Imager::i_new_fill_hatchf($fg, $bg, $hsh{combine},
66             $hsh{hatch}, $hsh{cust_hatch},
67 0         0 $hsh{dx}, $hsh{dy});
68             }
69             else {
70 0         0 $Imager::ERRSTR = "fg isn't a color";
71 0         0 return undef;
72             }
73             }
74             elsif (defined $hsh{fountain}) {
75             # make sure we track the filter's defaults
76 7         16 my $fount = $Imager::filters{fountain};
77 7         12 my $def = $fount->{defaults};
78 7         12 my $names = $fount->{names};
79            
80 7         13 $hsh{ftype} = $hsh{fountain};
81             # process names of values
82 7         24 for my $name (keys %$names) {
83 28 100 100     78 if (defined $hsh{$name} && exists $names->{$name}{$hsh{$name}}) {
84 7         17 $hsh{$name} = $names->{$name}{$hsh{$name}};
85             }
86             }
87             # process defaults
88 7         57 %hsh = (%$def, %hsh);
89 7         12 my @parms = @{$fount->{callseq}};
  7         30  
90 7         12 shift @parms;
91 7         11 for my $name (@parms) {
92 70 50       104 unless (defined $hsh{$name}) {
93 0         0 $Imager::ERRSTR =
94             "required parameter '$name' not set for fountain fill";
95 0         0 return undef;
96             }
97             }
98              
99             # check that the segments supplied is an array ref
100 7 100 66     48 unless (ref $hsh{segments} && $hsh{segments} =~ /ARRAY/) {
101 1         3 $Imager::ERRSTR =
102             "segments must be an array reference or Imager::Fountain object";
103 1         5 return;
104             }
105              
106             # make sure the segments are specified with colors
107 6         11 my @segments;
108 6         6 for my $segment (@{$hsh{segments}}) {
  6         14  
109 6         12 my @new_segment = @$segment;
110              
111 6   100     25 $_ = _color($_) or return for @new_segment[3,4];
112 5         22 push @segments, \@new_segment;
113             }
114              
115             $self->{fill} =
116             Imager::i_new_fill_fount($hsh{xa}, $hsh{ya}, $hsh{xb}, $hsh{yb},
117             $hsh{ftype}, $hsh{repeat}, $hsh{combine}, $hsh{super_sample},
118 5         575 $hsh{ssample_param}, \@segments);
119             }
120             elsif (defined $hsh{image}) {
121 9   100     40 $hsh{xoff} ||= 0;
122 9   100     45 $hsh{yoff} ||= 0;
123             $self->{fill} =
124             Imager::i_new_fill_image($hsh{image}{IMG}, $hsh{matrix}, $hsh{xoff},
125 9         397 $hsh{yoff}, $hsh{combine});
126 9         45 $self->{DEPS} = [ $hsh{image}{IMG} ];
127             }
128             elsif (defined $hsh{type} && $hsh{type} eq "opacity") {
129 7         16 my $other_fill = delete $hsh{other};
130 7 100       14 unless (defined $other_fill) {
131 1         6 Imager->_set_error("'other' parameter required to create opacity fill");
132 1         6 return;
133             }
134 6 100 100     18 unless (ref $other_fill &&
135 5         42 eval { $other_fill->isa("Imager::Fill") }) {
136             # try to auto convert to a fill object
137 2 100 66     12 if (ref $other_fill && $other_fill =~ /HASH/) {
138 1 50       9 $other_fill = Imager::Fill->new(%$other_fill)
139             or return;
140             }
141             else {
142 1         2 undef $other_fill;
143             }
144 2 100       5 unless ($other_fill) {
145 1         4 Imager->_set_error("'other' parameter must be an Imager::Fill object to create an opacity fill");
146 1         4 return;
147             }
148             }
149              
150 5         10 my $raw_fill = $other_fill->{fill};
151 5         10 my $opacity = delete $hsh{opacity};
152 5 100       11 defined $opacity or $opacity = 0.5; # some sort of default
153             $self->{fill} =
154 5         191 Imager::i_new_fill_opacity($raw_fill, $opacity);
155 5         18 $self->{DEPS} = [ $other_fill ]; # keep reference to old fill and its deps
156             }
157             else {
158 0         0 $Imager::ERRSTR = "No fill type specified";
159 0         0 warn "No fill type!";
160 0         0 return undef;
161             }
162              
163 62         1227 $self;
164             }
165              
166             sub hatches {
167 0     0 1 0 return @hatch_types;
168             }
169              
170             sub combines {
171 1     1 1 13 return Imager->combines;
172             }
173              
174             1;
175              
176             =head1 NAME
177              
178             Imager::Fill - general fill types
179              
180             =head1 SYNOPSIS
181              
182             use Imager;
183             use Imager::Fill;
184              
185             my $fill1 = Imager::Fill->new(solid=>$color, combine=>$combine);
186             my $fill2 = Imager::Fill->new(hatch=>'vline2', fg=>$color1, bg=>$color2,
187             dx=>$dx, dy=>$dy);
188             my $fill3 = Imager::Fill->new(fountain=>$type, ...);
189             my $fill4 = Imager::Fill->new(image=>$img, ...);
190             my $fill5 = Imager::Fill->new(type => "opacity", other => $fill,
191             opacity => ...);
192              
193             =head1 DESCRIPTION
194              
195             Creates fill objects for use by most filled area drawing functions.
196              
197             All fills are created with the new method.
198              
199             =over
200              
201             =item new
202              
203             my $fill = Imager::Fill->new(...);
204              
205             The parameters depend on the type of fill being created. See below
206             for details.
207              
208             =back
209              
210             The currently available fills are:
211              
212             =over
213              
214             =item *
215              
216             solid
217              
218             =item *
219              
220             hatch
221              
222             =item *
223              
224             fountain (similar to gradients in paint software)
225              
226             =item *
227              
228             image - fill with an image, possibly transformed
229              
230             =item *
231              
232             opacity - a lower opacity version of some other fill
233              
234             =back
235              
236             =head1 Common options
237              
238             =over
239              
240             =item combine
241              
242             The way in which the fill data is combined with the underlying image.
243             See L.
244              
245             =back
246              
247             In general colors can be specified as L or
248             L objects. The fill object will typically store
249             both types and convert from one to the other. If a fill takes 2 color
250             objects they should have the same type.
251              
252             =head2 Solid fills
253              
254             my $fill = Imager::Fill->new(solid=>$color, combine =>$combine)
255              
256             Creates a solid fill, the only required parameter is C which
257             should be the color to fill with.
258              
259             A translucent red fill:
260              
261             my $red = Imager::Fill->new(solid => "FF000080", combine => "normal");
262              
263             =head2 Hatched fills
264              
265             my $fill = Imager::Fill->new(hatch=>$type, fg=>$fgcolor, bg=>$bgcolor,
266             dx=>$dx, $dy=>$dy);
267              
268             Creates a hatched fill. You can specify the following keywords:
269              
270             =over
271              
272             =item *
273              
274             C - The type of hatch to perform, this can either be the
275             numeric index of the hatch (not recommended), the symbolic name of the
276             hatch, or an array of 8 integers which specify the pattern of the
277             hatch.
278              
279             Hatches are represented as cells 8x8 arrays of bits, which limits their
280             complexity.
281              
282             Current hatch names are:
283              
284             =over
285              
286             =item *
287              
288             C, C, C - checkerboards at various sizes
289              
290             =item *
291              
292             C, C, C - 1, 2, or 4 vertical lines per cell
293              
294             =item *
295              
296             C, C, C - 1, 2, or 4 horizontal lines per cell
297              
298             =item *
299              
300             C, C - 1 or 2 / lines per cell.
301              
302             =item *
303              
304             C, C - 1 or 2 \ lines per cell
305              
306             =item *
307              
308             C, C, C - 1, 2, or 4 vertical and horizontal
309             lines per cell
310              
311             =item *
312              
313             C, C, C - 1, 4 or 16 dots per cell
314              
315             =item *
316              
317             C, C - see the samples
318              
319             =item *
320              
321             C - I hope this one is obvious.
322              
323             =item *
324              
325             C, C - 2 densities of crosshatch
326              
327             =item *
328              
329             C, C - something like lozenge tiles
330              
331             =item *
332              
333             C, C, C, C - Vaguely
334             like fish scales in each direction.
335              
336             =item *
337              
338             C - L-shaped tiles
339              
340             =back
341              
342             =item *
343              
344             C, C - The C color is rendered where bits are set in the
345             hatch, and the C where they are clear. If you use a transparent
346             C or C, and set combine, you can overlay the hatch onto an
347             existing image.
348              
349             C defaults to black, C to white.
350              
351             =item *
352              
353             C, C - An offset into the hatch cell. Both default to zero.
354              
355             =back
356              
357             A blue and white 4-pixel check pattern:
358              
359             my $fill = Imager::Fill->new(hatch => "check2x2", fg => "blue");
360              
361             You can call Imager::Fill->hatches for a list of hatch names.
362              
363             =head2 Fountain fills
364              
365             my $fill = Imager::Fill->new(fountain=>$ftype,
366             xa=>$xa, ya=>$ya, xb=>$xb, yb=>$yb,
367             segments=>$segments, repeat=>$repeat, combine=>$combine,
368             super_sample=>$super_sample, ssample_param=>$ssample_param);
369              
370             This fills the given region with a fountain fill. This is exactly the
371             same fill as the C filter, but is restricted to the shape
372             you are drawing, and the fountain parameter supplies the fill type,
373             and is required.
374              
375             A radial fill from white to transparent centered on (50, 50) with a 50
376             pixel radius:
377              
378             use Imager::Fountain;
379             my $segs = Imager::Fountain->simple(colors => [ "FFFFFF", "FFFFFF00" ],
380             positions => [ 0, 1 ]);
381             my $fill = Imager::Fill->new(fountain => "radial", segments => $segs,
382             xa => 50, ya => 50, xb => 0, yb => 50,
383             combine => "normal");
384              
385              
386             =head2 Image Fills
387              
388             my $fill = Imager::Fill->new(image=>$src, xoff=>$xoff, yoff=>$yoff,
389             matrix=>$matrix, combine => $combine);
390              
391             Fills the given image with a tiled version of the given image. The
392             first non-zero value of C or C will provide an offset
393             along the given axis between rows or columns of tiles respectively.
394              
395             The matrix parameter performs a co-ordinate transformation from the
396             co-ordinates in the target image to the fill image co-ordinates.
397             Linear interpolation is used to determine the fill pixel. You can use
398             the L class to create transformation matrices.
399              
400             The matrix parameter will significantly slow down the fill.
401              
402             # some image to act as a texture
403             my $txim = Imager->new(...);
404              
405             # simple tiling
406             my $fill = Imager::Fill->new(image => $txim);
407              
408             # tile with a vertical offset
409             my $fill = Imager::Fill->new(image => $txim, yoff => 10);
410              
411             # tile with a horizontal offset
412             my $fill = Imager::Fill->new(image => $txim, xoff => 10);
413              
414             # rotated
415             use Imager::Matrix2d;
416             my $fill = Imager::Fill->new(image => $txim,
417             matrix => Imager::Matrix2d->rotate(degrees => 20));
418              
419             =head2 Opacity modification fill
420              
421             my $fill = Imager::Fill->new(type => "opacity",
422             other => $fill, opacity => 0.25);
423              
424             This can be used to make a fill that is a more translucent or opaque
425             version of an existing fill. This is intended for use where you
426             receive a fill object as a parameter and need to change the opacity.
427              
428             Parameters:
429              
430             =over
431              
432             =item *
433              
434             type => "opacity" - Required
435              
436             =item *
437              
438             other - the fill to produce a modified version of. This must be an
439             Imager::Fill object. Required.
440              
441             =item *
442              
443             opacity - multiplier for the source fill opacity. Default: 0.5.
444              
445             =back
446              
447             The source fills combine mode is used.
448              
449             my $hatch = Imager::Fill->new(hatch => "check4x4", combine => "normal");
450             my $fill = Imager::Fill->new(type => "opacity", other => $hatch);
451              
452             =head1 OTHER METHODS
453              
454             =over
455              
456             =item Imager::Fill->hatches
457              
458             A list of all defined hatch names.
459              
460             =item Imager::Fill->combines
461              
462             A list of all combine types.
463              
464             =back
465              
466             =head1 FUTURE PLANS
467              
468             I'm planning on adding the following types of fills:
469              
470             =over
471              
472             =item *
473              
474             C - combines 2 other fills in a checkerboard
475              
476             =item *
477              
478             C - combines 2 other fills using the levels of an image
479              
480             =item *
481              
482             C - uses the transform2() register machine to create fills
483              
484             =back
485              
486             =head1 AUTHOR
487              
488             Tony Cook
489              
490             =head1 SEE ALSO
491              
492             Imager(3)
493              
494             =cut