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