File Coverage

blib/lib/SVGPDF/Svg.pm
Criterion Covered Total %
statement 71 98 72.4
branch 15 42 35.7
condition 9 28 32.1
subroutine 5 7 71.4
pod 0 3 0.0
total 100 178 56.1


line stmt bran cond sub pod time code
1             #! perl
2              
3 2     2   964 use v5.26;
  2         7  
4 2     2   10 use Object::Pad;
  2         3  
  2         13  
5 2     2   321 use utf8;
  2         3  
  2         12  
6 2     2   54 use Carp;
  2         3  
  2         460  
7              
8             class SVGPDF::Svg :isa(SVGPDF::Element);
9              
10 1     1 0 4 method process () {
  1         5  
  1         3  
11 1         8 my $atts = $self->atts;
12 1 50       5 return if $atts->{omit}; # for testing/debugging.
13              
14 1         41 my $xo = $self->xo;
15 1         6 my $xoforms = $self->root->xoforms;
16              
17 1         9 delete $atts->{$_} for qw( xmlns:xlink xmlns:svg xmlns version );
18 1         21 my ( $x, $y, $vwidth, $vheight, $vbox, $par, $tf ) =
19             $self->get_params( $atts, qw( x:U y:U width:s height:s viewBox preserveAspectRatio:s transform:s ) );
20 1 50       6 $self->nfi("nested svg transform") if $tf;
21 1 50       5 $self->nfi("preserveAspectRatio") if $par;
22 1         9 my $style = $self->style;
23              
24 1         3 my $parent;
25 1         3 for ( @{ $self->root->xoforms } ) {
  1         4  
26 1 50       8 next unless $_->{xo} eq $xo;
27 1         2 $parent = $_;
28 1         3 last;
29             }
30 1 50       5 croak("I feel like a motherless child") unless $parent;
31              
32 1         4 my $pwidth = $parent->{width};
33 1         3 my $pheight = $parent->{height};
34 1         4 for ( $vwidth ) {
35 1   33     7 $_ = $self->u( $_ || $pwidth, width => $pwidth );
36             }
37 1         5 for ( $vheight ) {
38 1   33     7 $_ = $self->u( $_ || $pheight, width => $pheight );
39             }
40              
41 1         25 $self->_dbg("pp w=$pwidth h=$pheight vw=$vwidth vh=$vheight");
42              
43 1         8 my @vb; # viewBox: llx lly width height
44             my @bb; # bbox: llx lly urx ury
45              
46 1         0 my $width; # width of the vbox
47 1         0 my $height; # height of the vbox
48 1 50       5 if ( $vbox ) {
49 1         11 @vb = $self->getargs($vbox);
50 1         6 $width = $self->u( $vb[2],
51             width => $pwidth );
52 1         4 $height = $self->u( $vb[3],
53             width => $height );
54             }
55             else {
56 0         0 $width = $vwidth;
57 0         0 $height = $vheight;
58 0         0 @vb = ( 0, 0, $width, $height );
59 0         0 $vbox = "@vb";
60             }
61              
62             # Get llx lly urx ury bounding box rectangle.
63 1         5 @bb = $self->root->vb2bb_noflip(@vb);
64 1         7 $self->_dbg( "vb $vbox => bb %.2f %.2f %.2f %.2f", @bb );
65 1 50 33     7 warn( sprintf("vb $vbox => bb %.2f %.2f %.2f %.2f\n", @bb ))
66             if $self->root->verbose && !$self->root->debug;
67              
68 1         7 my $new_xo = $self->root->pdf->xo_form;
69 1         634 $new_xo->bbox(@bb);
70              
71             # Set up result forms.
72 1   33     121 push( @$xoforms,
      33        
73             { xo => $new_xo,
74             # Design (desired) width and height.
75             vwidth => $vwidth || $vb[2],
76             vheight => $vheight || $vb[3],
77             # viewBox (SVG coordinates)
78             vbox => [ @vb ],
79             width => $vb[2],
80             height => $vb[3],
81             diag => sqrt( $vb[2]**2 + $vb[3]**2 ) / sqrt(2),
82             # bbox (PDF coordinates)
83             bbox => [ @bb ],
84             yflip => 0,
85             } );
86 1         8 $self->_dbg("XObject #", scalar(@$xoforms) );
87              
88 1         16 $self->traverse;
89              
90 1         9 my $scalex = 1;
91 1         3 my $scaley = 1;
92 1         4 my $dx = 0;
93 1         2 my $dy = 0;
94 1 50       5 if ( $vbox ) {
95 1         6 my @pbb = $xo->bbox; # parent
96 1 50       40 if ( $vwidth ) {
97 1         3 $scalex = $vwidth / $vb[2];
98             }
99 1 50       5 if ( $vheight ) {
100 1         3 $scaley = $vheight / $vb[3];
101             }
102             # warn("pbbx @pbb\n");
103             # warn("bbox @bb scale=$scalex/$scaley\n");
104 1 50       5 if ( $par =~ /none/i ) {
105 0         0 $par = "";
106             }
107             else {
108             # Uniform scale.
109             # $scalex = $scaley = min( $scalex, $scaley );
110             }
111 1 50 33     5 if ( $par =~ /xM(ax|id|in)/i && $scalex > $scaley ) {
112 0 0       0 if ( $1 eq "ax" ) {
    0          
113 0         0 $dx = max($pbb[0],$pbb[2]) - max($bb[0],$bb[2]);
114             }
115             elsif ( $1 eq "id" ) {
116 0         0 $dx = (($pbb[2]-$pbb[0])/2) - (($bb[2]-$bb[0])/2);
117             }
118             else {
119 0         0 $dx = min($pbb[0],$pbb[2]) - min($bb[0],$bb[2]);
120             }
121             }
122 1 50 33     5 if ( $par =~ /yM(in|id|ax)/i && $scaley > $scalex ) {
123 0 0       0 if ( $1 eq "ax" ) {
    0          
124 0         0 $dy = max($pbb[1],$pbb[3]) - max($bb[1],$bb[3]);
125             }
126             elsif ( $1 eq "id" ) {
127 0         0 $dy =
128             ((max($pbb[1],$pbb[3])-min($pbb[1],$pbb[3]))/2)
129             - ((max($bb[1],$bb[3])-min($bb[1],$bb[3]))/2)
130             }
131             else {
132 0         0 $dy = min($pbb[1],$pbb[3]) - min($bb[1],$bb[3]);
133             }
134             }
135 1 50       4 if ( $par ) {
136 0         0 $scalex = $scaley = min( $scalex, $scaley );
137 0         0 $dx *= $scalex;
138 0         0 $dy *= $scaley;
139 0         0 warn("disp dx=$dx, dy=$dy\n");
140             }
141             }
142 1   50     30 $self->_dbg( "xo object( %.2f%+.2f %.2f%+.2f %.3f %.3f ) %s",
143             $x, $dx, $y, $dy, $scalex, $scaley, $par//"" );
144 1 50 0     9 warn(sprintf("xo object( %.2f%+.2f %.2f%+.2f %.3f %.3f ) %s\n",
      33        
145             $x, $dx, $y, $dy, $scalex, $scaley, $par//"" ))
146             if $self->root->verbose && !$self->root->debug;
147 1         22 $xo->object( $new_xo, $x+$dx, $y+$dy, $scalex, $scaley );
148              
149 1         443 pop( @$xoforms );
150              
151 1         14 $self->css_pop;
152              
153             }
154              
155 0 0   0 0   sub min ( $x, $y ) { $x < $y ? $x : $y }
  0            
  0            
  0            
  0            
156 0 0   0 0   sub max ( $x, $y ) { $x > $y ? $x : $y }
  0            
  0            
  0            
  0            
157              
158             1;