App-Music-ChordPro

 view release on metacpan or  search on metacpan

lib/ChordPro/lib/SVGPDF.pm  view on Meta::CPAN


    # Get llx lly urx ury bounding box rectangle.
    @bb = $self->vb2bb(@vb);
    $self->_dbg( "vb $vbox => bb %.2f %.2f %.2f %.2f", @bb );
    warn( sprintf("vb $vbox => bb %.2f %.2f %.2f %.2f\n", @bb ))
      if $verbose && !$debug;
    $xo->bbox(@bb);

    if ( my $c = $style->{"background-color"} ) {
	if ( $c ne "none" ) {
	    $xo->fill_color($c);
	    $xo->rectangle(@bb);
	    $xo->fill;
	}
    }

    # Set up result forms.
    $xoforms->[-1] =
      { xo      => $xo,
	# Design (desired) width and height.
	vwidth  => $vwidth  || $vb[2],
	vheight => $vheight || $vb[3],
	# viewBox (SVG coordinates)
	vbox    => [ @vb ],
	width   => $vb[2],
	height  => $vb[3],
	# See e.g. https://oreillymedia.github.io/Using_SVG/extras/ch05-percentages.html
	diag    => sqrt( $vb[2]**2 + $vb[3]**2 ) / sqrt(2),
	# bbox (PDF coordinates)
	bbox    => [ @bb ],
      };
    # Not sure if this is ever needed.
    $xoforms->[-1]->{valign} = $valign if $valign;

#    use DDumper; DDumper( { %{$xoforms->[-1]}, xo => 'XO' } );
    # <svg> coordinates are topleft down, so translate.
    $self->_dbg( "matrix( 1 0 0 -1 0 0)" );
    $xo->matrix( 1, 0, 0, -1, 0, 0 );

    if ( $debug ) {		# show bb
	$xo->save;
	$self->_dbg( "vb rect( %.2f %.2f %.2f %.2f)",
		        $vb[0], $vb[1], $vb[2]+$vb[0], $vb[1]+$vb[3]);
	$xo->rectangle( $vb[0], $vb[1], $vb[2]+$vb[0], $vb[1]+$vb[3]);
	$xo->fill_color("#ffffc0");
	$xo->fill;
	$xo->move(  $vb[0], 0 );
	$xo->hline( $vb[0]+$vb[2]);
	$xo->move( 0, $vb[1] );
	$xo->vline( $vb[1]+$vb[3] );
	$xo->line_width(0.5);
	$xo->stroke_color( "red" );
	$xo->stroke;
	$xo->restore;
    }
    $self->draw_grid( $xo, \@vb ) if $grid;


    # Establish currentColor.
    for ( $css->find("fill") ) {
	next if $_ eq 'none' or $_ eq 'transparent';
	$self->_dbg( "xo fill_color ",
		     $_ eq 'currentColor' ? 'black' : $_,
		     " (initial)");
	$xo->fill_color( $_ eq 'currentColor' ? 'black' : $_ );
    }
    for ( $css->find("stroke") ) {
	next if $_ eq 'none' or $_ eq 'transparent';
	$self->_dbg( "xo stroke_color ",
		     $_ eq 'currentColor' ? 'black' : $_,
		     " (initial)");
	$xo->stroke_color( $_ eq 'currentColor' ? 'black' : $_ );
    }
    $svg->traverse;

    $svg->css_pop;

    $self->_dbg( "==== end ", $e->{name}, " ====" );
}

sub min( $a, $b ) { $a < $b ? $a : $b }
sub max( $a, $b ) { $a > $b ? $a : $b }

method combine_svg( $forms, %opts ) {
    my $type = $opts{type} // "stacked";
    return $forms if $type eq "none";

    my ( $xmin, $ymin, $xmax, $ymax );
    my $y = 0;
    my $x = 0;
    my $sep = $opts{sep} || 0;
    my $nx;

    if ( $type eq "bbox" ) {
	warn("Combining ", scalar(@$forms), " XObjects\n")
	  if $verbose;
	...;
	$nx->bbox( $xmin, $ymax, $xmax, 0 );
    }
    else {
	my $i = 0;
	for my $xo ( @$forms ) {
	    $xo = $xo->{xo};
	    my @bb = $xo->bbox;
	    my $w = abs( $bb[2] - $bb[0] );
	    my $h = abs( $bb[3] - $bb[1] );

	    $nx //= $pdf->xo_form;
	    my @xy = ( $x - min($bb[0],$bb[2]), $y - max($bb[1],$bb[3]) );
	    warn(sprintf("Stack obj %2d: %.2f %.2f %.2f %.2f \@ %.2f %.2f\n",
			 ++$i, @bb, @xy ) ) if $verbose;
	    $nx->object( $xo, @xy );
	    $y -= $h;

	    if ( defined $xmax ) {
		$xmax = $w if $w > $xmax;
	    }
	    else {
		$xmax = $w;
		$xmin = 0;
	    }
	    $ymax = $y;
	    $y -= $sep;
	}
	warn("Stacked ", scalar(@$forms), " XObjects => bb",
	     ( map { sprintf(" %.2f", $_ ) } $xmin, $ymax, $xmax, 0 ),
	     "\n")
	  if $verbose;



( run in 2.328 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )