File Coverage

lib/ChordPro/lib/SVGPDF/Text.pm
Criterion Covered Total %
statement 11 120 9.1
branch 0 64 0.0
condition 0 39 0.0
subroutine 4 5 80.0
pod 0 1 0.0
total 15 229 6.5


line stmt bran cond sub pod time code
1             #! perl
2              
3 10     10   144 use v5.26;
  10         46  
4 10     10   66 use Object::Pad;
  10         24  
  10         77  
5 10     10   1496 use utf8;
  10         27  
  10         101  
6 10     10   345 use Carp;
  10         25  
  10         2591  
7              
8             class SVGPDF::Text :isa(SVGPDF::Element);
9              
10 0     0 0   method process () {
  0            
  0            
11 0           my $atts = $self->atts;
12 0           my $xo = $self->xo;
13 0 0         return if $atts->{omit}; # for testing/debugging.
14              
15 0           my ( $x, $y, $dx, $dy, $tf ) =
16             $self->get_params( $atts, qw( x:s y:s dx:U dy:U transform:s ) );
17 0           my $style = $self->style;
18 0           $_ = 0+$self->u($_) for $style->{'font-size'};
19 0           my $text = "";
20              
21 0           my $color = $style->{fill};
22 0 0 0       $color = $style->{color} if $color && $color eq "currentColor";
23 0   0       my $anchor = $style->{'text-anchor'} || "left";
24 0           $self->set_graphics;
25              
26             $self->_dbg( $self->name, " ",
27             defined($atts->{x}) ? ( " x=$x" ) : (),
28             defined($atts->{y}) ? ( " y=$y" ) : (),
29             defined($atts->{dx}) ? ( " dx=$dx" ) : (),
30             defined($atts->{dy}) ? ( " dy=$dy" ) : (),
31             defined($style->{"text-anchor"})
32             ? ( " anchor=\"$anchor\"" ) : (),
33 0 0         defined($style->{"transform"}) #???
    0          
    0          
    0          
    0          
    0          
34             ? ( " transform=\"$tf\"" ) : (),
35             );
36              
37             # We assume that if there is an x/y list, there is one single text
38             # argument.
39              
40 0           my @c = $self->get_children;
41              
42 0 0         if ( $x =~ /,/ ) {
43 0 0 0       if ( @c > 1 || ref($c[0]) ne "SVGPDF::TextElement" ) {
44 0           die("text: Cannot combine coordinate list with multiple elements\n");
45             }
46 0           $x = [ $self->getargs($x) ];
47 0           $y = [ $self->getargs($y) ];
48 0           $text = [ split( //, $c[0]->content ) ];
49 0 0 0       die( "\"", $self->get_cdata, "\" ", 0+@$x, " ", 0+@$y, " ", 0+@$text )
50             unless @$x == @$y && @$y == @$text;
51             }
52             else {
53 0   0       $x = [ $self->u($x||0) ];
54 0   0       $y = [ $self->u($y||0) ];
55             }
56              
57 0           $self->_dbg( "+ xo save" );
58 0           $xo->save;
59 0           my $ix = $x->[0];
60 0           my $iy = $y->[0];
61 0           my ( $ex, $ey );
62              
63 0           my $scalex = 1;
64 0           my $scaley = 1;
65 0 0         if ( $tf ) {
66 0 0         ( $dx, $dy ) = $self->getargs($1)
67             if $tf =~ /translate\((.*?)\)/;
68 0 0         ( $scalex, $scaley ) = $self->getargs($1)
69             if $tf =~ /scale\((.*?)\)/;
70 0   0       $scaley ||= $scalex;
71 0           $self->_dbg("TF: $dx, $dy, $scalex, $scaley")
72             }
73             # NOTE: rotate applies to the individual characters, not the text
74             # as a whole.
75              
76 0 0         if ( @$x > 1 ) {
77 0           for ( @$x ) {
78 0 0         if ( $tf ) {
79 0           $self->_dbg( "X %.2f = %.2f + %.2f",
80             $dx + $_, $dx, $_ );
81 0           $self->_dbg( "Y %.2f = - %.2f - %.2f",
82             $dy + $y->[0], $dy, $y->[0] );
83             }
84 0           my $x = $dx + $_;
85 0           my $y = $dy + shift(@$y);
86 0 0 0       $self->_dbg( "txt* translate( %.2f, %.2f )%s %x",
87             $x, $y,
88             ( $scalex != 1 || $scaley != -1 )
89             ? sprintf(" scale( %.1f, %.1f )", $scalex, -$scaley ) : "",
90             ord($text->[0]));
91             # $xo-> translate( $x, $y );
92 0           $xo->save;
93 0 0 0       $xo->transform( translate => [ $x, $y ],
94             ($scalex != 1 || $scaley != -1 )
95             ? ( scale => [ $scalex, -$scaley ] ) : (),
96             );
97 0           my %o = ();
98 0 0         $o{align} = $anchor eq "end"
    0          
99             ? "right"
100             : $anchor eq "middle" ? "center" : "left";
101 0           $xo->textstart;
102 0           $self->set_font( $xo, $style );
103 0           $xo->text( shift(@$text), %o );
104 0           $xo->textend;
105 0           $xo->restore;
106             }
107             }
108             else {
109 0           $_ = $x->[0];
110 0 0         if ( $tf ) {
111 0           $self->_dbg( "X %.2f = %.2f + %.2f",
112             $dx + $_, $dx, $_ );
113 0           $self->_dbg( "Y %.2f = - %.2f - %.2f",
114             - $dy - $y->[0], $dy, $y->[0] );
115             }
116 0           my $x = $dx + $_;
117 0           my $y = $dy + shift(@$y);
118 0 0 0       $self->_dbg( "txt translate( %.2f, %.2f )%s",
119             $x, $y,
120             ($scalex != 1 || $scaley != -1 )
121             ? sprintf(" scale( %.2f %.2f )", $scalex, -$scaley ) : "" );
122 0           my %o = ();
123 0 0         $o{align} = $anchor eq "end"
    0          
124             ? "right"
125             : $anchor eq "middle" ? "center" : "left";
126 0           my $tc = $self->root->tc;
127 0           my $fc = $self->root->fc;
128 0           for my $c ( @c ) {
129 0 0         if ( ref($c) eq 'SVGPDF::TextElement' ) {
    0          
130 0           $self->_dbg( "+ xo save" );
131 0           $xo->save;
132 0 0 0       $xo->transform( translate => [ $x, $y ],
133             ($scalex != 1 || $scaley != -1 )
134             ? ( scale => [ $scalex, -$scaley ] ) : ()
135             );
136 0           $scalex = $scaley = 1; # no more scaling.
137              
138 0           $xo->textstart;
139 0 0         if ( $tc ) {
140 0           $x += $tc->( $self, xo => $xo, pdf => $self->root->pdf,
141             style => $style, text => $c->content, %o );
142             }
143             else {
144 0           $self->set_font( $xo, $style );
145 0           $x += $xo->text( $c->content, %o );
146             }
147 0           $xo->textend;
148 0 0         if ( $style->{'outline-style'} ) {
149             # BEEP BEEP TRICKERY.
150 0           my $fn = $xo->{" font"};
151 0           my $sz = $xo->{" fontsize"};
152 0   0       $xo->line_width( $self->u($style->{'outline-width'} || 1 ));
153 0   0       $xo->stroke_color( $style->{'outline-color'} || 'black' );
154 0   0       my $d = $self->u($style->{'outline-offset'}) || 1;
155 0           $xo->rectangle( -$d,
156             -$d+$sz*$fn->descender/1000,
157             $x-$ix+2*$d,
158             2*$d+$sz*$fn->ascender/1000 );
159 0           $xo->stroke;
160             }
161 0           $self->_dbg( "- xo restore" );
162 0           $xo->restore;
163 0           $ex = $x; $ey = $y;
  0            
164             }
165             elsif ( ref($c) eq 'SVGPDF::Tspan' ) {
166 0           $self->_dbg( "+ xo save" );
167 0           $xo->save;
168 0 0         if ( defined($c->atts->{x}) ) {
169 0           $x = 0;
170             }
171 0 0         if ( defined($c->atts->{'y'}) ) {
172 0           $y = 0;
173             }
174 0 0 0       $xo->transform( translate => [ $x, $y ],
175             ( $scalex != 1 || $scaley != -1 )
176             ? ( scale => [ $scalex, -$scaley ] ) : (),
177             );
178 0           $scalex = $scaley = 1; # no more scaling.
179 0           my ( $x0, $y0 ) = $c->process();
180 0           $x += $x0; $y += $y0;
  0            
181 0           $self->_dbg("tspan moved to $x, $y");
182 0           $self->_dbg( "- xo restore" );
183 0           $xo->restore;
184 0           $ex = $x; $ey = $y;
  0            
185             }
186             else {
187 0           $self->nfi( $c->name . " in text" );
188             }
189             }
190             }
191              
192 0           $self->_dbg( "- xo restore" );
193 0           $xo->restore;
194 0           $self->css_pop;
195             }
196              
197             1;