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 )