File Coverage

blib/lib/Image/Base/Imlib2.pm
Criterion Covered Total %
statement 8 10 80.0
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 12 14 85.7


line stmt bran cond sub pod time code
1             # Copyright 2011 Kevin Ryde
2              
3             # This file is part of Image-Base-Imlib2.
4             #
5             # Image-Base-Imlib2 is free software; you can redistribute it and/or modify
6             # it under the terms of the GNU General Public License as published by the
7             # Free Software Foundation; either version 3, or (at your option) any later
8             # version.
9             #
10             # Image-Base-Imlib2 is distributed in the hope that it will be useful, but
11             # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12             # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13             # for more details.
14             #
15             # You should have received a copy of the GNU General Public License along
16             # with Image-Base-Imlib2. If not, see .
17              
18              
19             package Image::Base::Imlib2;
20 2     2   6781 BEGIN { require 5 }
21 2     2   9 use strict;
  2         4  
  2         66  
22 2     2   13 use Carp;
  2         4  
  2         156  
23 2     2   3029 use Image::Imlib2 ();
  0            
  0            
24              
25             use vars '$VERSION', '@ISA';
26             $VERSION = 1;
27              
28             use Image::Base;
29             @ISA = ('Image::Base');
30              
31             # uncomment this to run the ### lines
32             #use Devel::Comments '###';
33              
34              
35             sub new {
36             my ($class, %params) = @_;
37             ### Image-Base-Imlib2 new(): %params
38              
39             # $obj->new(...) means make a copy, with some extra settings
40             if (ref $class) {
41             my $self = $class;
42             $class = ref $class;
43             if (! defined $params{'-imlib'}) {
44             $params{'-imlib'} = $self->get('-imlib')->clone;
45             }
46             # inherit everything else
47             %params = (%$self, %params);
48             ### copy params: \%params
49             }
50              
51             if (! defined $params{'-imlib'}) {
52             my $width = delete $params{'-width'};
53             my $height = delete $params{'-height'};
54              
55             # same 256 default as Image::Imlib2->new() itself
56             if (! defined $width) { $width = 256; }
57             if (! defined $height) { $height = 256; }
58              
59             $params{'-imlib'} = Image::Imlib2->new ($width, $height);
60             }
61             my $self = bless {}, $class;
62             $self->set (%params);
63              
64             if (defined $params{'-file'}) {
65             $self->load;
66             }
67              
68             ### new made: $self
69             return $self;
70             }
71              
72              
73             my %attr_to_get_method = (-width => 'width',
74             -height => 'height',
75             -file_format => sub {
76             croak "Cannot get -file_format (write-only)";
77             },
78             );
79             sub _get {
80             my ($self, $key) = @_;
81             ### Image-Base-Imlib2 _get(): $key
82              
83             my $method;
84             if ($method = $attr_to_get_method{$key}) {
85             ### $method
86             ### is: $self->{'-imlib'}->$method
87             return $self->{'-imlib'}->$method();
88             }
89             return $self->SUPER::_get ($key);
90             }
91              
92             my %attr_to_method = (-quality_percent => 'set_quality',
93             -file_format => sub {
94             my ($imlib, $format) = @_;
95             # Imlib2 expects lower case "png" etc, allow upper
96             # "PNG" for -file_format too.
97             if ($format) {
98             $format = lc($format);
99             }
100             $imlib->image_set_format ($format);
101             },
102             );
103             sub set {
104             my ($self, %param) = @_;
105             ### Image-Base-Imlib2 set(): \%param
106              
107             {
108             my $key;
109             foreach $key ('-width','-height') {
110             if (exists $param{$key}) {
111             croak "Attribute $key is read-only";
112             }
113             }
114             }
115              
116             # apply this first
117             my $imlib;
118             if ($imlib = delete $param{'-imlib'}) {
119             $self->{'-imlib'} = $imlib;
120             } else {
121             $imlib = $self->{'-imlib'};
122             }
123              
124             {
125             my $key;
126             foreach $key (keys %param) {
127             my $method;
128             if ($method = $attr_to_method{$key}) {
129             $imlib->$method($param{$key});
130             }
131             }
132             }
133              
134             %$self = (%$self, %param);
135             }
136              
137             sub load {
138             my ($self, $filename) = @_;
139             ### Image-Base-Imlib2 load(): @_
140             if (@_ == 1) {
141             $filename = $self->get('-file');
142             } else {
143             $self->set('-file', $filename);
144             }
145             $self->{'-imlib'} = Image::Imlib2->load ($filename);
146              
147             ### imlib: $self->{'-imlib'}
148             ### size: $self->{'-imlib'}->width.'x'.$self->{'-imlib'}->height
149             }
150              
151             sub save {
152             my ($self, $filename) = @_;
153             ### Image-Base-Imlib2 save(): @_
154             if (@_ == 2) {
155             $self->set('-file', $filename);
156             } else {
157             $filename = $self->get('-file');
158             }
159             ### $filename
160              
161             $self->{'-imlib'}->save ($filename);
162             }
163              
164             sub _set_colour {
165             my ($self, $colour) = @_;
166             my $imlib = $self->{'-imlib'};
167              
168             if ($colour eq 'None') {
169             $imlib->set_color (0,0,0,0);
170              
171             } elsif ($colour =~ /^#(([0-9A-F]{3}){1,4})$/i) {
172             my $len = length($1)/3; # of each group, so 1,2,3 or 4
173             $imlib->set_color
174             ((map {hex(substr($_ x 2, 0, 2))} # first 2 chars of replicated
175             substr ($colour, 1, $len), # full groups
176             substr ($colour, 1+$len, $len),
177             substr ($colour, -$len)),
178             255); # alpha
179             } else {
180             croak "Unrecognised colour: $colour";
181             }
182             return $imlib;
183             }
184              
185              
186             sub xy {
187             my ($self, $x, $y, $colour) = @_;
188             ### Image-Base-Imlib2 xy: $x,$y,$colour
189             my $imlib = $self->{'-imlib'};
190             if (@_ == 4) {
191             _set_colour($self,$colour)->draw_point ($x, $y);
192              
193             } else {
194             my ($r,$g,$b,$a) = $imlib->query_pixel ($x, $y);
195             ### rgba: "$r,$g,$b,$a"
196             if ($a == 0) {
197             return 'None';
198             }
199             return sprintf ('#%02X%02X%02X', $r, $g, $b);
200             }
201             }
202             sub line {
203             my ($self, $x1, $y1, $x2, $y2, $colour) = @_;
204             ### Image-Base-Imlib2 line: @_
205             _set_colour($self,$colour)->draw_line ($x1,$y1, $x2,$y2);
206             }
207             sub rectangle {
208             my ($self, $x1, $y1, $x2, $y2, $colour, $fill) = @_;
209             ### Image-Base-Imlib2 rectangle: @_
210              
211             my $method = ($fill ? 'fill_rectangle' : 'draw_rectangle');
212             _set_colour($self,$colour)->$method ($x1,$y1,
213             $x2-$x1+1,
214             $y2-$y1+1);
215             }
216              
217             sub diamond {
218             my ($self, $x1, $y1, $x2, $y2, $colour, $fill) = @_;
219             ### Image-Base-Imlib2 diamond() ...
220              
221             my $imlib = _set_colour($self,$colour);
222              
223             # 0 1 2 3 4
224             # x1=0, x2=4 -> xh=2
225             #
226             # 0 1 2 3 4 5
227             # x1=0, x2=5 -> xh=2
228             #
229             my $xh = ($x2 - $x1);
230             my $yh = ($y2 - $y1);
231              
232             # Imlib2 1.4.4 does something fishy in draw_polygon() for a 1-high shape,
233             # ie. y1==y2, ending up not drawing the right half of the shape.
234             $fill ||= ($yh == 0);
235              
236             my $xeven = ($xh & 1);
237             my $yeven = ($yh & 1);
238             $xh = int($xh / 2);
239             $yh = int($yh / 2);
240             ### $xh
241             ### $yh
242             ### top lo: $x1+$xh
243             ### top hi: $x2-$xh
244              
245             my $poly = Image::Imlib2::Polygon->new;
246              
247             # top centre
248             $poly->add_point ($x1+$xh,$y1);
249              
250             # left
251             $poly->add_point ($x1,$y1+$yh);
252             if ($yeven) { $poly->add_point ($x1,$y2-$yh); }
253              
254             # bottom
255             $poly->add_point ($x1+$xh,$y2);
256             if ($xeven) { $poly->add_point ($x2-$xh,$y2); }
257              
258             # right
259             if ($yeven) { $poly->add_point ($x2,$y2-$yh); }
260             $poly->add_point ($x2,$y1+$yh);
261              
262             # top again
263             if ($xeven) { $poly->add_point ($x2-$xh,$y1); }
264              
265             if ($fill) {
266             $poly->fill;
267             } else {
268             $imlib->draw_polygon ($poly, 1);
269             }
270             }
271              
272             # sub ellipse {
273             # my ($self, $x1, $y1, $x2, $y2, $colour, $fill) = @_;
274             # ### Image-Base-Imlib2 ellipse: "$x1, $y1, $x2, $y2, $colour"
275             #
276             # my $a = $x2 - $x1;
277             # my $b = $y2 - $y1;
278             # ### diameters ...
279             # ### $a
280             # ### $b
281             #
282             # shift->SUPER::ellipse(@_);
283             #
284             # # if (($a & 1) || ($b & 1)) {
285             # #
286             # # } else {
287             # # $a = $a/2;
288             # # $b = $b/2;
289             # # ### centre: $x1+$a, $y1+$b
290             # # ### $a
291             # # ### $b
292             # # my $method = ($fill ? 'fill_ellipse' : 'draw_ellipse');
293             # # _set_colour($self,$colour)->$method ($x1 + $a,
294             # # $y1 + $b,
295             # # $a, $b);
296             # # }
297             # }
298              
299             # sub add_colours {
300             # my $self = shift;
301             # ### add_colours: @_
302             # $self->{'-imlib'}->addcolors (colors => \@_);
303             # }
304              
305              
306             1;
307             __END__