File Coverage

blib/lib/Tree/Cladogram/Imager.pm
Criterion Covered Total %
statement 15 72 20.8
branch 0 10 0.0
condition 0 7 0.0
subroutine 5 16 31.2
pod 0 8 0.0
total 20 113 17.7


line stmt bran cond sub pod time code
1             package Tree::Cladogram::Imager;
2              
3 1     1   741389 use parent 'Tree::Cladogram';
  1         2  
  1         7  
4              
5 1     1   81 use Imager;
  1         1  
  1         9  
6 1     1   634 use Imager::Fill;
  1         962  
  1         24  
7              
8 1     1   6 use Moo;
  1         1  
  1         5  
9              
10 1     1   232 use Types::Standard qw/Any Int Str/;
  1         2  
  1         9  
11              
12             has leaf_font =>
13             (
14             default => sub{return ''},
15             is => 'rw',
16             isa => Any,
17             required => 0,
18             );
19              
20             has title_font => # Internal.
21             (
22             default => sub{return ''},
23             is => 'rw',
24             isa => Any,
25             required => 0,
26             );
27              
28             our $VERSION = '1.02';
29              
30             # ------------------------------------------------
31              
32             sub BUILD
33             {
34 0     0 0   my($self) = @_;
35              
36 0   0       $self -> leaf_font
37             (
38             Imager::Font -> new
39             (
40             color => Imager::Color -> new($self -> leaf_font_color),
41             file => $self -> leaf_font_file,
42             size => $self -> leaf_font_size,
43             utf8 => 1
44             ) || die "Error. Can't define leaf font: " . Imager -> errstr
45             );
46 0   0       $self -> title_font
47             (
48             Imager::Font -> new
49             (
50             color => Imager::Color -> new($self -> title_font_color),
51             file => $self -> title_font_file,
52             size => $self -> title_font_size,
53             utf8 => 1
54             ) || die "Error. Can't define title font: " . Imager -> errstr
55             );
56              
57             } # End of BUILD.
58              
59             # ------------------------------------------------
60              
61             sub _calculate_leaf_name_bounds
62             {
63 0     0     my($self) = @_;
64 0           my($leaf_font_size) = $self -> leaf_font_size;
65 0           my($x_step) = $self -> x_step;
66              
67 0           my($attributes);
68             my(@bounds);
69              
70             $self -> root -> walk_down
71             ({
72             callback =>
73             sub
74             {
75 0     0     my($node) = @_;
76 0           $attributes = $node -> attributes;
77             @bounds = $self -> leaf_font -> align
78             (
79             halign => 'left',
80             image => undef,
81             string => $node -> name,
82             valign => 'baseline',
83             x => $$attributes{x} + $x_step + 4,
84 0           y => $$attributes{y} + int($leaf_font_size / 2),
85             );
86 0           $$attributes{bounds} = [@bounds];
87              
88 0           $node -> attributes($attributes);
89              
90 0           return 1; # Keep walking.
91             },
92 0           _depth => 0,
93             });
94              
95             } # End of _calculate_leaf_name_bounds.
96              
97             # ------------------------------------------------
98              
99             sub _calculate_title_metrics
100             {
101 0     0     my($self, $image, $maximum_x, $maximum_y) = @_;
102 0           my(@metrics) = $self -> title_font -> align
103             (
104             halign => 'left',
105             image => undef,
106             string => $self -> title,
107             valign => 'baseline',
108             x => 0,
109             y => 0,
110             );
111              
112 0           $self -> title_width($metrics[2] + 1);
113              
114             } # End of _calculate_title_metrics.
115              
116             # ------------------------------------------------
117              
118             sub create_image
119             {
120 0     0 0   my($self, $maximum_x, $maximum_y) = @_;
121 0           my($image) = Imager -> new(xsize => $maximum_x, ysize => $maximum_y);
122 0           my($frame_color) = Imager::Color -> new($self -> frame_color);
123 0           my($white) = Imager::Color -> new(255, 255, 255);
124              
125 0           $image -> box(color => $white, filled => 1);
126 0 0         $self -> _calculate_title_metrics($image, $maximum_x, $maximum_y) if (length($self -> title) );
127 0 0         $image -> box(color => $frame_color) if ($self -> draw_frame);
128              
129 0           return $image;
130              
131             } # End of create_image.
132              
133             # ------------------------------------------------
134              
135             sub draw_horizontal_branch
136             {
137 0     0 0   my($self, $image, $middle_attributes, $daughter_attributes, $final_offset) = @_;
138 0           my($branch_color) = $self -> branch_color;
139 0           my($branch_width) = $self -> branch_width - 1;
140 0           my($x_step) = $self -> x_step;
141              
142             $image -> box
143             (
144             box =>
145             [
146             $$middle_attributes{x},
147             $$daughter_attributes{y},
148             $$daughter_attributes{x} + $x_step + $final_offset,
149 0           $$daughter_attributes{y} + $branch_width,
150             ],
151             color => $branch_color,
152             filled => 1,
153             );
154              
155             } # End of draw_horizontal_branch.
156              
157             # ------------------------------------------------
158              
159             sub draw_leaf_name
160             {
161 0     0 0   my($self, $image, $name, $daughter_attributes, $final_offset) = @_;
162              
163 0 0 0       if ( (length($name) > 0) && ($name !~ /^\d+$/) )
164             {
165 0           my($bounds) = $$daughter_attributes{bounds};
166 0           $$bounds[0] += $final_offset;
167 0           $$bounds[2] += $final_offset;
168              
169 0           $image -> string
170             (
171             align => 0,
172             font => $self -> leaf_font,
173             string => $name,
174             x => $$bounds[0],
175             y => $$bounds[1],
176             );
177              
178 0 0         if ($self -> debug)
179             {
180 0           my($fuchsia) = Imager::Color -> new(0xff, 0, 0xff);
181              
182 0           $image -> box
183             (
184             box => $bounds,
185             color => $fuchsia,
186             filled => 0,
187             );
188             }
189             }
190              
191             } # End of draw_leaf_name.
192              
193             # ------------------------------------------------
194              
195             sub draw_root_branch
196             {
197 0     0 0   my($self, $image) = @_;
198 0           my($branch_color) = $self -> branch_color;
199 0           my($branch_width) = $self -> branch_width - 1;
200 0           my($attributes) = $self -> root -> attributes;
201 0           my(@daughters) = $self -> root -> daughters;
202 0           my($daughter_attributes) = $daughters[0] -> attributes;
203              
204             $image -> box
205             (
206             box =>
207             [
208             $$daughter_attributes{x},
209             $$daughter_attributes{y},
210             $self -> left_margin,
211 0           $$attributes{y} + $branch_width,
212             ],
213             color => $branch_color,
214             filled => 1,
215             );
216              
217             } # End of draw_root_branch.
218              
219             # ------------------------------------------------
220              
221             sub draw_title
222             {
223 0     0 0   my($self, $image, $maximum_x, $maximum_y) = @_;
224 0           my($title) = $self -> title;
225              
226 0 0         if (length($title) > 0)
227             {
228 0           $image -> string
229             (
230             align => 0,
231             font => $self -> title_font,
232             string => $title,
233             x => int( ($maximum_x - $self -> title_width) / 2),
234             y => $maximum_y - $self -> top_margin,
235             );
236             }
237              
238             } # End of draw_title.
239              
240             # ------------------------------------------------
241              
242             sub draw_vertical_branch
243             {
244 0     0 0   my($self, $image, $middle_attributes, $daughter_attributes) = @_;
245 0           my($branch_color) = $self -> branch_color;
246 0           my($branch_width) = $self -> branch_width - 1;
247              
248             $image -> box
249             (
250             box =>
251             [
252             $$middle_attributes{x},
253             $$middle_attributes{y},
254             $$middle_attributes{x} + $branch_width,
255             $$daughter_attributes{y},
256 0           ],
257             color => $branch_color,
258             filled => 1,
259             );
260              
261             } # End of draw_vertical_branch.
262              
263             # ------------------------------------------------
264              
265             sub write
266             {
267 0     0 0   my($self, $image, $file_name) = @_;
268              
269 0           $image -> write(file => $file_name);
270 0           $self -> log('Wrote ' . $file_name);
271              
272             } # End of write.
273              
274             # ------------------------------------------------
275              
276             1;
277              
278             =pod
279              
280             =head1 NAME
281              
282             C - Render a cladogram using Imager or Image::Magick
283              
284             =head1 Synopsis
285              
286             See L.
287              
288             =head1 Description
289              
290             See L.
291              
292             =head1 Distributions
293              
294             See L.
295              
296             =head1 Constructor and Initialization
297              
298             See L.
299              
300             =head1 Methods
301              
302             See L.
303              
304             =head1 FAQ
305              
306             See L.
307              
308             =head1 See Also
309              
310             See L.
311              
312             =head1 Machine-Readable Change Log
313              
314             The file Changes was converted into Changelog.ini by L.
315              
316             =head1 Version Numbers
317              
318             Version numbers < 1.00 represent development versions. From 1.00 up, they are production versions.
319              
320             =head1 Repository
321              
322             L
323              
324             =head1 Support
325              
326             Email the author, or log a bug on RT:
327              
328             L.
329              
330             =head1 Author
331              
332             L was written by Ron Savage Iron@savage.net.auE> in 2015.
333              
334             My homepage: L
335              
336             =head1 Copyright
337              
338             Australian copyright (c) 2015, Ron Savage.
339              
340             All Programs of mine are 'OSI Certified Open Source Software';
341             you can redistribute them and/or modify them under the terms of
342             The Artistic License 2.0, a copy of which is available at:
343             http://opensource.org/licenses/alphabetical.
344              
345             =cut