App-Music-ChordPro
view release on metacpan or search on metacpan
lib/ChordPro/Output/PDF/Song.pm view on Meta::CPAN
"\n") if $config->{debug}->{spacing};
$x += $ps->{_indent};
$y -= $spreadimage if defined($spreadimage) && !ref($spreadimage);
# Prevent spread space on other pages (issue #640).
undef $spreadimage if $col == $ps->{columns}-1;
};
my $vsp_ignorefirst;
my $startpage = $opts->{page_num};
# These are 1 smaller since they'll be incremented first.
my $page_num = $startpage - 1; # page number
my $page_idx = $opts->{page_idx}-1; # page # in PDF
# Physical newpage handler.
my $newpage = sub {
$page_idx++;
$page_num++;
$s->{meta}->{page} =
[ $s->{page} = $opts->{roman}
? roman($page_num) : $page_num ];
# Add page to the PDF.
$pr->newpage( $opts->{prepend} ? $page_idx : () );
warn("page: $page_idx(",$s->{page},") added\n")
if $config->{debug}->{pages} & 0x01;
# Put titles and footer.
# If even/odd pages, leftpage signals whether the
# header/footer parts must be swapped.
my $rightpage = 1;
if ( $pagectrl->{dual_pages} ) {
$rightpage = is_odd($page_num);
}
# margin* are offsets from the edges of the paper.
# _*margin are offsets taking even/odd pages into account.
# _margin* are physical coordinates, taking ...
if ( $rightpage ) {
$ps->{_leftmargin} = $ps->{marginleft};
$ps->{_marginleft} = $ps->{marginleft};
$ps->{_rightmargin} = $ps->{marginright};
$ps->{_marginright} = $ps->{papersize}->[0] - $ps->{marginright};
}
else {
$ps->{_leftmargin} = $ps->{marginright};
$ps->{_marginleft} = $ps->{marginright};
$ps->{_rightmargin} = $ps->{marginleft};
$ps->{_marginright} = $ps->{papersize}->[0] - $ps->{marginleft};
}
$ps->{_marginbottom} = $ps->{marginbottom};
$ps->{_margintop} = $ps->{papersize}->[1] - $ps->{margintop};
$ps->{_bottommargin} = $ps->{marginbottom};
# Physical coordinates; will be adjusted to columns if needed.
$ps->{__leftmargin} = $ps->{_marginleft};
$ps->{__rightmargin} = $ps->{_marginright};
$ps->{__topmargin} = $ps->{_margintop};
$ps->{__bottommargin} = $ps->{_marginbottom};
# Determine page class and background.
my $class = 2; # default
my $bgpdf = $ps->{formats}->{default}->{background};
if ( $page_num == 1 ) {
$class = 0; # very first page
$bgpdf = $ps->{formats}->{first}->{background}
|| $ps->{formats}->{title}->{background}
|| $bgpdf;
}
elsif ( $page_num == $startpage ) {
$class = 1; # first of a song
$bgpdf = $ps->{formats}->{title}->{background}
|| $bgpdf;
}
if ( $bgpdf ) {
my ( $fn, $pg ) = ( $bgpdf, 1 );
if ( $bgpdf =~ /^(.+):(\d+)$/ ) {
( $bgpdf, $pg ) = ( $1, $2 );
}
$fn = CP->findres($bgpdf);
if ( $fn && fs_test( rs => $fn ) ) {
$pg++ if $pagectrl->{dual_pages} && !$rightpage;
$pr->importpage( $fn, $pg );
}
else {
warn( "PDF: Missing or empty background document: ",
$bgpdf, "\n" );
}
}
$x = $ps->{__leftmargin};
$y = $ps->{_margintop};
$y += $ps->{headspace} if $ps->{'head-first-only'} && $class == 2;
$x += $ps->{_indent};
$ps->{_top} = $y;
$col = 0;
$vsp_ignorefirst = 1;
$col_adjust->();
# Render the 'allpages' images.
for ( @allpages ) {
my %imageinfo = %$_;
my $img = delete $imageinfo{img};
my $x = delete $imageinfo{x};
my $y = delete $imageinfo{y};
$pr->add_object( $img, $x, $y, %imageinfo );
}
};
my $checkspace = sub {
# Verify that the amount of space if still available.
# If not, perform a column break or page break.
# Use negative argument to force a break.
# Returns true if there was space.
my $vsp = $_[0];
return 1 if $vsp >= 0 && $y - $vsp >= $ps->{_bottommargin};
if ( ++$col >= $ps->{columns}) {
$newpage->();
$vsp_ignorefirst = 0;
}
$col_adjust->();
return;
};
my $chorddiagrams = sub {
my ( $chords, $show, $ldisp ) = @_;
return if $lyrics_only || !$dctl->{show};
my @chords;
$chords = $s->{chords}->{chords}
if !defined($chords) && $s->{chords};
$show //= $dctl->{show};
if ( $chords ) {
for ( @$chords ) {
if ( my $i = $s->{chordsinfo}->{$_} ) {
push( @chords, $i ) if $i->has_diagram;
}
else {
warn("PDF: Missing chord info for \"$_\"\n");
}
}
}
return unless @chords;
lib/ChordPro/Output/PDF/Song.pm view on Meta::CPAN
$ftext = $fonts->{tab};
}
# Get vertical space the songline will occupy.
my $vsp = songline_vsp( $elt, $ps );
if ( $elt->{type} eq "songline" && !$elt->{indent} ) {
my $e = wrap( $pr, $elt, $x );
if ( @$e > 1 ) {
$checkspace->($vsp * scalar( @$e ));
$elt = shift( @$e );
unshift( @elts, @$e );
}
}
# Add prespace if fit. Otherwise newpage.
$checkspace->($vsp);
$pr->show_vpos( $y, 0 ) if $config->{debug}->{spacing};
my $indent = 0;
# Handle decorations.
if ( $elt->{context} eq "chorus" ) {
my $style = $ps->{chorus};
$indent = $style->{indent};
if ( $style->{bar}->{offset} && $style->{bar}->{width} ) {
my $cx = $ps->{__leftmargin} + $ps->{_indent}
- $style->{bar}->{offset}
+ $indent;
$pr->vline( $cx, $y, $vsp,
$style->{bar}->{width},
$style->{bar}->{color} );
}
$curctx = "chorus";
$i_tag = "" unless $config->{settings}->{choruslabels};
}
# Substitute metadata in comments.
if ( $elt->{type} =~ /^comment/ && !$elt->{indent} ) {
$elt = { %$elt };
# Flatten chords/phrases.
if ( $elt->{chords} ) {
$elt->{text} = "";
for ( 0..$#{ $elt->{chords} } ) {
$elt->{text} .= $elt->{chords}->[$_] . $elt->{phrases}->[$_];
}
}
$elt->{text} = fmt_subst( $s, $elt->{text} );
}
# Comment decorations.
$pr->setfont( $ftext );
=begin xxx
my $text = $elt->{text};
my $w = $pr->strwidth( $text );
# Draw background.
my $bgcol = $ftext->{background};
if ( $elt->{type} eq "comment" ) {
# Default to grey.
$bgcol ||= "#E5E5E5";
# Since we default to grey, we need a way to cancel it.
undef $bgcol if $bgcol eq "none";
}
if ( $bgcol ) {
$pr->rectxy( $x + $indent - 2, $y + 2,
$x + $indent + $w + 2, $y - $vsp, 3, $bgcol );
}
# Draw box.
my $x0 = $x;
if ( $elt->{type} eq "comment_box" ) {
$x0 += 0.25; # add some offset for the box
$pr->rectxy( $x0 + $indent, $y + 1,
$x0 + $indent + $w + 1, $y - $vsp + 1,
0.5, undef,
$ftext->{color} || $ps->{theme}->{foreground} );
}
=cut
my $r = songline( $elt, $x, $y, $ps, song => $s, indent => $indent );
$y -= $vsp;
$pr->show_vpos( $y, 1 ) if $config->{debug}->{spacing};
unshift( @elts, $r ) if $r;
next;
}
if ( $elt->{type} eq "chorus" ) {
warn("NYI: type => chorus\n");
my $cy = $y + vsp($ps,-2); # ####TODO????
foreach my $e ( @{$elt->{body}} ) {
if ( $e->{type} eq "songline" ) {
$y = songline( $e, $x, $y, $ps );
next;
}
elsif ( $e->{type} eq "empty" ) {
warn("***SHOULD NOT HAPPEN2***");
$y -= vsp($ps);
next;
}
}
my $style = $ps->{chorus};
my $cx = $ps->{__leftmargin} - $style->{bar}->{offset};
$pr->vline( $cx, $cy, vsp($ps), 1, $style->{bar}->{color} );
$y -= vsp($ps,4); # chordii
next;
}
if ( $elt->{type} eq "verse" ) {
warn("NYI: type => verse\n");
foreach my $e ( @{$elt->{body}} ) {
if ( $e->{type} eq "songline" ) {
my $h = songline_vsp( $e, $ps );
$checkspace->($h);
songline( $e, $x, $y, $ps );
( run in 0.751 second using v1.01-cache-2.11-cpan-f56aa216473 )