File Coverage

blib/lib/Image/Base/Tk/Photo.pm
Criterion Covered Total %
statement 15 109 13.7
branch 0 58 0.0
condition 0 15 0.0
subroutine 5 17 29.4
pod 7 10 70.0
total 27 209 12.9


line stmt bran cond sub pod time code
1             # Copyright 2010, 2011, 2012 Kevin Ryde
2              
3             # This file is part of Image-Base-Tk.
4             #
5             # Image-Base-Tk 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-Tk 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-Tk. If not, see .
17              
18              
19             # Tk::Photo
20             # Tk::Image
21             # Tk::options configure(), cget()
22             #
23             # Tk::PNG
24             # Tk::JPEG
25             # Tk::TIFF
26             # loaders
27              
28             package Image::Base::Tk::Photo;
29 1     1   533 use 5.004;
  1         2  
  1         32  
30 1     1   4 use strict;
  1         2  
  1         24  
31 1     1   5 use Carp;
  1         3  
  1         89  
32              
33 1     1   4 use vars '$VERSION', '@ISA';
  1         2  
  1         65  
34             $VERSION = 3;
35              
36 1     1   734 use Image::Base;
  1         1722  
  1         1021  
37             @ISA = ('Image::Base');
38              
39             # uncomment this to run the ### lines
40             #use Smart::Comments '###';
41              
42              
43             sub new {
44 0     0 1   my ($class, %params) = @_;
45             ### Image-Base-Tk new() ...
46              
47             # $obj->new(...) means make a copy, with some extra settings
48 0 0         if (ref $class) {
49 0           croak "Cannot clone Image::Base::Tk::Photo";
50              
51             # how to clone a Photo? how to get its originating widget to create new?
52             # my $self = $class;
53             # $class = ref $class;
54             # if (! defined $params{'-tkphoto'}) {
55             # my $tkphoto = $self->{'-tkphoto'};
56             # my $new_tkphoto = $tkphoto->Photo (map {$_=>$tkphoto->cget($_)}
57             # qw(-width -height -gamma -palette));
58             # $new_tkphoto->copy($tkphoto);
59             # $params{'-tkphoto'} = $new_tkphoto;
60             # }
61             # # inherit everything else
62             # %params = (%$self, %params);
63             # ### copy params: \%params
64             }
65              
66 0 0         if (! defined $params{'-tkphoto'}) {
67 0   0       my $for_widget = delete $params{'-for_widget'}
68             || croak 'Must have -for_widget to create new Tk::Photo';
69 0           $params{'-tkphoto'} = $for_widget->Photo (-width => $params{'-width'},
70             -height => $params{'-height'});
71             }
72 0           my $self = bless {}, $class;
73 0           $self->set (%params);
74              
75 0 0         if (exists $params{'-file'}) {
76 0           $self->load;
77             }
78              
79             ### new made: $self
80 0           return $self;
81             }
82              
83             my %attr_to_option = (-width => '-width',
84             -height => '-height');
85             sub _get {
86 0     0     my ($self, $key) = @_;
87             ### Image-Base-Tk-Photo _get(): $key
88 0 0         if (my $option = $attr_to_option{$key}) {
89             ### $option
90 0           return $self->{'-tkphoto'}->cget($option);
91             }
92 0           return $self->SUPER::_get ($key);
93             }
94              
95             sub set {
96 0     0 1   my ($self, %param) = @_;
97             ### Image-Base-Tk-Photo set(): \%param
98              
99             # apply this first
100 0 0         if (my $tkphoto = delete $param{'-tkphoto'}) {
101 0           $self->{'-tkphoto'} = $tkphoto;
102             }
103              
104             {
105 0           my @configure;
  0            
106 0           foreach my $key (keys %param) {
107 0 0         if (my $option = $attr_to_option{$key}) {
108 0           my $value = delete $param{$key};
109 0           push @configure, $option, $value;
110             }
111             }
112             ### @configure
113 0 0         if (@configure) {
114 0           $self->{'-tkphoto'}->configure (@configure);
115             }
116             }
117              
118 0           %$self = (%$self, %param);
119             }
120              
121             sub load {
122 0     0 1   my ($self, $filename) = @_;
123             ### Image-Base-Tk-Photo load()
124              
125 0 0         if (@_ == 1) {
126 0           $filename = $self->get('-file');
127             } else {
128 0           $self->set('-file', $filename);
129             }
130 0           my $tkphoto = $self->{'-tkphoto'};
131 0           $tkphoto->read ($filename);
132 0           $self->set (-file_format => $tkphoto->cget('-format'));
133             }
134              
135             # undocumented, untested ...
136             sub load_string {
137 0     0 0   my ($self, $str) = @_;
138             ### Image-Base-Tk-Photo load()
139 0           my $tkphoto = $self->{'-tkphoto'};
140 0           $tkphoto->configure (-data => $str);
141 0           $self->set (-file_format => $tkphoto->cget('-format'));
142             }
143              
144             my %format_to_module = (png => 'Tk::PNG',
145             jpeg => 'Tk::JPEG',
146             tiff => 'Tk::TIFF',
147             );
148             sub _format_use {
149 0     0     my ($format) = @_;
150 0 0         if (my $module = $format_to_module{lc($format)}) {
151 0 0         eval "require $module; 1" or die;
152             }
153 0           return $format;
154             }
155              
156             sub save {
157 0     0 1   my ($self, $filename) = @_;
158             ### Image-Base-Tk-Photo save()
159 0 0         if (@_ == 2) {
160 0           $self->set('-file', $filename);
161             } else {
162 0           $filename = $self->get('-file');
163             }
164 0           my $tkphoto = $self->{'-tkphoto'};
165             ### file: $filename
166              
167             # croaks if an error ...
168 0           $tkphoto->write ($filename,
169             -format => _format_use($self->get('-file_format')));
170             }
171              
172             # undocumented, untested ...
173             sub save_fh {
174 0     0 0   my ($self, $fh) = @_;
175 0           print $fh $self->save_string;
176             }
177              
178             # undocumented, untested ...
179             sub save_string {
180 0     0 0   my ($self, $fh) = @_;
181             # croaks if an error ...
182 0           return $self->{'-tkphoto'}->data
183             (-format => _format_use($self->get('-file_format')));
184             }
185              
186             #------------------------------------------------------------------------------
187             # drawing
188              
189             sub xy {
190 0     0 1   my ($self, $x, $y, $colour) = @_;
191             ### Image-Base-Tk-Photo xy() ...
192              
193             # "-to" doesn't allow negative coordinates
194 0 0 0       if ($x < 0 || $y < 0) {
195 0           return undef;
196             }
197              
198 0           my $tkphoto = $self->{'-tkphoto'};
199 0 0         if (@_ > 3) {
200 0 0         if (lc($colour) eq 'none') {
201 0           $tkphoto->transparencySet ($x, $y, 1);
202             } else {
203 0           $tkphoto->put ($colour, -to => $x,$y, $x+1,$y+1);
204             }
205             } else {
206             # get() and transparencyGet() don't allow x,y outside photo
207 0 0 0       if ($x >= $tkphoto->cget('-width')
208             || $y >= $tkphoto->cget('-height')) {
209 0           return undef;
210             }
211              
212 0 0         if ($tkphoto->transparencyGet ($x, $y)) {
213 0           return 'None';
214             } else {
215 0           return sprintf ('#%02X%02X%02X', $tkphoto->get ($x, $y)); # r,g,b
216             }
217             }
218             }
219              
220             sub rectangle {
221 0     0 1   my ($self, $x1, $y1, $x2, $y2, $colour, $fill) = @_;
222             ### Image-Base-Tk-Photo rectangle() ...
223              
224 0 0 0       if ($fill && lc($colour) ne 'none') {
225             ### filled rectangle with put() ...
226              
227 0 0 0       if ($x2 >= 0 && $y2 >= 0) {
228             # "-to" doesn't allow negative coordinates
229 0 0         if ($x1 < 0) { $x1 = 0; }
  0            
230 0 0         if ($y1 < 0) { $y1 = 0; }
  0            
231              
232             ### put: "$x1,$y1 ".($x2+1).",".($y2+1)
233 0           $self->{'-tkphoto'}->put ($colour, -to => $x1,$y1, $x2+1,$y2+1);
234             }
235              
236             } else {
237             ### unfilled or transparent rectangle with superclass lines ...
238 0           shift->SUPER::rectangle(@_);
239             }
240             }
241              
242             sub line {
243 0     0 1   my ($self, $x1, $y1, $x2, $y2, $colour) = @_;
244             ### Image-Base-Tk-Photo line(): "$x1,$y1, $x2,$y2"
245              
246 0 0         if (lc($colour) eq 'none') {
247             # any transparency by individual xy() pixels (with transparencySet())
248 0           shift->SUPER::line(@_);
249 0           return;
250             }
251              
252 0 0         if ($x1 == $x2) {
    0          
253             # vertical line by put() rectangle
254 0 0         if ($x1 < 0) {
255             ### vertical line all negative ...
256 0           return;
257             }
258 0 0         if ($y1 > $y2) { ($y1,$y2) = ($y2,$y1) }
  0            
259              
260             } elsif ($y1 == $y2) {
261             # horizontal line by put() rectangle
262 0 0         if ($y1 < 0) {
263             ### horizontal line all negative ...
264 0           return;
265             }
266 0 0         if ($x1 > $x2) { ($x1,$x2) = ($x2,$x1) }
  0            
267              
268             } else {
269             ### sloped line by individual xy() pixels ...
270 0           shift->SUPER::line(@_);
271 0           return;
272             }
273              
274             # "-to" doesn't allow negative coordinates
275 0 0         if ($x1 < 0) { $x1 = 0; }
  0            
276 0 0         if ($y1 < 0) { $y1 = 0; }
  0            
277              
278             ### put(): "$x1,$y1, ".($x2+1).",".($y2+1)
279 0           $self->{'-tkphoto'}->put ($colour, -to => $x1,$y1, $x2+1,$y2+1);
280             }
281              
282             1;
283             __END__