App-Music-ChordPro
view release on metacpan or search on metacpan
lib/ChordPro/lib/SVGPDF.pm view on Meta::CPAN
$indent = $indent . " ";
warn( $indent, $1, "\n") if $1;
}
elsif ( $msg =~ /^\-\s*(.*)/ ) {
warn( $indent, $1, "\n") if $1;
confess("oeps") if length($indent) < 2;
$indent = substr( $indent, 2 );
}
elsif ( $msg =~ /^\^\s*(.*)/ ) {
$indent = "";
warn( $indent, $1, "\n") if $1;
}
else {
warn( $indent, $msg, "\n") if $msg;
}
}
method search ( $content ) {
# In general, we'll have an XHTML tree with one or more <sgv>
# elements.
for ( @$content ) {
next if $_->{type} eq 't';
my $name = $_->{name};
if ( $name eq "svg" ) {
$indent = "";
$self->handle_svg($_);
# Adds results to $self->{xoforms}.
}
else {
# Skip recursively.
$self->_dbg( "$name (ignored)" ) unless $name eq "<>"; # top
$self->search($_->{content});
}
}
}
method handle_svg ( $e ) {
$self->_dbg( "^ ==== start ", $e->{name}, " ====" );
my $xo;
if ( $prog ) {
$xo = SVGPDF::PAST->new( pdf => $pdf );
}
else {
$xo = $pdf->xo_form;
}
push( @$xoforms, { xo => $xo } );
$self->_dbg("XObject #", scalar(@$xoforms) );
my $svg = SVGPDF::Element->new
( name => $e->{name},
atts => { map { lc($_) => $e->{attrib}->{$_} } keys %{$e->{attrib}} },
content => $e->{content},
root => $self,
);
# If there are <style> elements, these must be processed first.
my $cdata = "";
for ( $svg->get_children ) {
next unless ref($_) eq "SVGPDF::Style";
# DDumper($_->get_children) unless scalar($_->get_children) == 1;
croak("ASSERT: 1 child") unless scalar($_->get_children) == 1;
for my $t ( $_->get_children ) {
croak("# ASSERT: non-text child in style")
unless ref($t) eq "SVGPDF::TextElement";
$cdata .= $t->content;
}
}
if ( $cdata =~ /\S/ ) {
$css->read_string($cdata);
}
my $atts = $svg->atts;
# The viewport, llx lly width height.
my $vbox = delete $atts->{viewbox};
# Width and height are the display size of the viewport.
# Resolve em, ex and percentages.
my $vwidth = delete $atts->{width} // 0;
my $vheight = delete $atts->{height} // 0;
for ( $vwidth ) {
$_ = $svg->u( $_, width => $pagesize->[0],
fontsize => $fontsize );
}
for ( $vheight ) {
$_ = $svg->u( $_, width => $pagesize->[1],
fontsize => $fontsize );
}
delete $atts->{$_} for qw( xmlns:xlink xmlns:svg xmlns version );
my $style = $svg->css_push($atts);
# If there is min-width the image must be scaled if the available
# width is smaller. If the width is larger we render to the
# available space.
my $minw = $style->{'min-width'} // 0;
$minw = $svg->u( $minw, width => $pagesize->[0],
fontsize => $fontsize ) if $minw;
# vertical-align is needed later when the XObject is placed.
my $valign = $style->{'vertical-align'} // 0;
$valign = $svg->u( $valign, fontsize => $fontsize ) if $valign;
my @vb; # viewBox: llx lly width height
my @bb; # bbox: llx lly urx ury
# We rely on the <svg> to supply the correct viewBox.
my $width; # width of the vbox
my $height; # height of the vbox
if ( $vbox ) {
@vb = $svg->getargs($vbox);
$width = $svg->u( $vb[2],
width => $pagesize->[0],
fontsize => $fontsize );
$height = $svg->u( $vb[3],
width => $pagesize->[1],
fontsize => $fontsize );
if ( $minw && $minw > $width ) {
$width = $minw;
$vb[2] = $minw / $vheight * $height;
$self->_dbg("minw: ", $style->{'min-width'}, " ",
"width -> $width, \$vb[2] -> $vb[2]\n");
}
if ( $valign ) {
# Verify valign against the vbox.
my $va = sprintf("%.2f", -$valign/$vheight);
my $vb = sprintf("%.2f", ($vb[3]+$vb[1])/$vb[3]);
warn("Vertical align = $va, but vbox says $vb\n")
unless $va eq $vb;
( run in 2.978 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )