File Coverage

lib/SVG/Estimate/Path.pm
Criterion Covered Total %
statement 73 74 98.6
branch 29 34 85.2
condition 3 6 50.0
subroutine 13 13 100.0
pod 1 2 50.0
total 119 129 92.2


line stmt bran cond sub pod time code
1             package SVG::Estimate::Path;
2             $SVG::Estimate::Path::VERSION = '1.0114';
3 8     8   1568 use Moo;
  8         17  
  8         49  
4 8     8   6735 use Image::SVG::Path qw/extract_path_info/;
  8         146355  
  8         1262  
5 8     8   3954 use SVG::Estimate::Path::Moveto;
  8         23  
  8         275  
6 8     8   3015 use SVG::Estimate::Path::Lineto;
  8         21  
  8         300  
7 8     8   3080 use SVG::Estimate::Path::CubicBezier;
  8         22  
  8         265  
8 8     8   3520 use SVG::Estimate::Path::QuadraticBezier;
  8         23  
  8         256  
9 8     8   3339 use SVG::Estimate::Path::HorizontalLineto;
  8         22  
  8         304  
10 8     8   3329 use SVG::Estimate::Path::VerticalLineto;
  8         24  
  8         257  
11 8     8   3390 use SVG::Estimate::Path::Arc;
  8         22  
  8         317  
12 8     8   55 use Clone qw/clone/;
  8         16  
  8         374  
13 8     8   47 use Ouch;
  8         18  
  8         62  
14              
15             extends 'SVG::Estimate::Shape';
16              
17             =head1 NAME
18              
19             SVG::Estimate::Path - Handles estimating arbitrary vectors.
20              
21             =head1 VERSION
22              
23             version 1.0114
24              
25             =head1 SYNOPSIS
26              
27             my $path = SVG::Estimate::Path->new(
28             transformer => $transform,
29             start_point => [45,13],
30             d => 'M150 0 L75 200 L225 200 Z',
31             );
32              
33             my $length = $path->length;
34              
35             =head1 INHERITANCE
36              
37             This class extends L.
38              
39             =head1 METHODS
40              
41             =head2 new()
42              
43             Constructor.
44              
45             =over
46              
47             =item d
48              
49             An SVG path string as described L.
50              
51             =back
52              
53             =cut
54              
55             has d => ( is => 'ro', required => 1, );
56             has commands => ( is => 'ro', );
57             has internal_travel_length => ( is => 'ro', required => 1, );
58             has summarize => ( is => 'ro', default => sub { 0 }, );
59              
60             sub BUILDARGS {
61 56     56 0 12217 my ($class, @args) = @_;
62             ##Upgrade to hashref
63 56 50       278 my $args = @args % 2 ? $args[0] : { @args };
64              
65 56 100 66     451 if (! exists $args->{d} || $args->{d} =~ /^\s*$/) {
66 2         7 $args->{d} = "m 0 0";
67             }
68 56         318 my @path_info = extract_path_info($args->{d}, { absolute => 1, no_shortcuts=> 1, });
69 56         534251 my @commands = ();
70              
71 56         92 my $first_flag = 1;
72 56         68 my $first;
73 56         509 my $cursor = clone $args->{start_point};
74 56         150 $args->{length} = 0;
75 56         97 foreach my $subpath (@path_info) {
76 1080         3175 $subpath->{transformer} = $args->{transformer};
77             ##On the first command, set the start point to the moveto destination, otherwise the travel length gets counted twice.
78 1080         6540 $subpath->{start_point} = clone $cursor;
79             my $command = $subpath->{type} eq 'moveto' ? SVG::Estimate::Path::Moveto->new($subpath)
80             : $subpath->{type} eq 'line-to' ? SVG::Estimate::Path::Lineto->new($subpath)
81             : $subpath->{type} eq 'cubic-bezier' ? SVG::Estimate::Path::CubicBezier->new($subpath)
82             : $subpath->{type} eq 'quadratic-bezier' ? SVG::Estimate::Path::QuadraticBezier->new($subpath)
83             : $subpath->{type} eq 'horizontal-line-to' ? SVG::Estimate::Path::HorizontalLineto->new($subpath)
84             : $subpath->{type} eq 'vertical-line-to' ? SVG::Estimate::Path::VerticalLineto->new($subpath)
85             : $subpath->{type} eq 'arc' ? SVG::Estimate::Path::Arc->new($subpath)
86             : $subpath->{type} eq 'closepath' ? '' #Placeholder so we don't fall through
87 1080 50       22517 : ouch('unknown_path', "Unknown subpath type ".$subpath->{type}) ; ##Something bad happened
    100          
    100          
    100          
    50          
    100          
    100          
    100          
88 1080 100       6056 if ($subpath->{type} eq 'closepath') {
89 3         25 $subpath->{point} = clone $first->point;
90 3         61 $command = SVG::Estimate::Path::Lineto->new($subpath);
91             }
92 1080         10089 $cursor = clone $command->end_point;
93 1080 100       2588 if ($first_flag) {
94             ##Save the first point in order to handle a closepath, if it exists
95 56         71 $first_flag = 0;
96 56         82 $first = $command; ##According to SVG, this will be a Moveto.
97 56         144 $args->{min_x} = $command->min_x;
98 56         122 $args->{max_x} = $command->max_x;
99 56         115 $args->{min_y} = $command->min_y;
100 56         108 $args->{max_y} = $command->max_y;
101 56         102 $args->{draw_start} = $command->end_point;
102             }
103 1080         2411 $args->{shape_length} += $command->shape_length;
104 1080         2241 $args->{internal_travel_length} += $command->travel_length;
105 1080 100       2607 $args->{min_x} = $command->min_x if $command->min_x < $args->{min_x};
106 1080 100       2678 $args->{max_x} = $command->max_x if $command->max_x > $args->{max_x};
107 1080 100       2407 $args->{min_y} = $command->min_y if $command->min_y < $args->{min_y};
108 1080 100       2237 $args->{max_y} = $command->max_y if $command->max_y > $args->{max_y};
109 1080 0 33     1757 if (exists $args->{summarize} && $args->{summarize}) {
110 0         0 $command->summarize_myself;
111             }
112 1080         2450 push @commands, $command;
113             }
114 56         165 $args->{draw_end} = $cursor;
115              
116 56         118 $args->{commands} = \@commands;
117 56         4071 return $args;
118             }
119              
120             ##Return the internally calculated travel length, not the standard one use by SVG::Estimate::Shape
121             sub travel_length {
122 109     109 1 146 my $self = shift;
123 109         179 my $length = $self->internal_travel_length;
124 109         671 return $length;
125             }
126              
127             1;