From 3e6ec2d8328c1f8e39b31d96d02a5126f32bd6f5 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Sun, 15 May 2011 20:27:08 +0200 Subject: error handling / factorized the code --- pdftool.pl | 608 ++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 324 insertions(+), 284 deletions(-) diff --git a/pdftool.pl b/pdftool.pl index 01b45a8..49c6e5a 100755 --- a/pdftool.pl +++ b/pdftool.pl @@ -15,6 +15,7 @@ use Pod::Usage; use IPC::Open2; use IPC::Open3; use POSIX qw(floor); +use Error qw(:try); use strict; @@ -289,6 +290,7 @@ map {&topoints ($_)} ( \$outwidth, \$outheight, die "Margins are too big" if $outwidth <= $margin*2 or $outheight <= $margin*2; + # # Check options # @@ -299,6 +301,7 @@ die "Bad nup: `$nup'" if defined $nup && not ($nup =~ /^\d+$/ && $nup > 0); + # # Open input and output files # @@ -329,9 +332,9 @@ if (defined $outfile && $outfile ne "-") { # Detect filetype # # To avoid to seek into FIN, it gonna be copied from WRITE to READ in -# background, once the filetype has been read +# the background, once the filetype has been read -# TODO: read specification to detect filetype properly +# TODO: read specifications, to properly detect the filetype my $filetype; pipe *READ, *WRITE or die "Can't pipe: $!"; while (not (defined $filetype) && defined (my $l = )) { @@ -371,305 +374,313 @@ my @auxfiles; # Pids, to waid for my @pids; +# Return value +my $return = 0; + +try { + &pdftops(); + + &psselect() if defined $select; + + my @bbox = &psbbox(); + + &psbook() if defined $book; + + my ($landscape,$rotate) = &psnup (@bbox); + + &pstopdf ($landscape,$rotate); +} +catch Error with { -# -# Conversion from PDF to PS, if necessary -# -my @cmd; -if ($filetype eq "PDF") { - unless (defined $infile && $inseek) { - # Need to copy the whole input to an auxiliary file, since - # conversion from PDF to PS requires random access to the data + # Print the error message + print LOG shift; - $infile = "$tmpdir/pdftool-stdin-$$" . lc ".$filetype"; + # Kill all the running childrens + kill 15, map {$$_[0]} @pids; - open FINAUX, '>', "$infile" - or die "Can't write into `$infile': $!"; - push @auxfiles, "$infile"; + $return = 1; +} + +finally { + + # Avoid zombies + map { my ($pid, @cmd) = @$_; + my ($r,$v) = (waitpid ($pid, 0), $?); + warn "Can't run `" . &printcmd (@cmd) . "'" + if ($r != -1 and $v >> 8); + } @pids; + + # Close opened file handles + map { close $_ or die "Can't close: $!" } + ( *READ, *FIN, *FOUT ); + + # Delete auxiliary files + unlink @auxfiles; + + exit $return; +}; + +# Useless, but Perl doesn't see that this filehandle is used more than +# one time (and even automatically closed by `open3') +close GSIN; - # cat > $infile - while () { - print FINAUX or die "Can't print: $!"; - } - close FINAUX; - } - my ($first, $last); - # pdftops doesn't provide any way to have page numbers relative to - # the end of the document, hence there is no detection of the - # smallest interval if $select contains `_' - if (defined $select && not $select =~ /_/) { - # Convert to PS only the pages we are interested in - ($first, $last) = (1<<16,-(1<<16)); - for (split /,/, $select) { - $_ =~ /^(\d*)(-?)(\d*)$/; - my ($rmin,$sep,$rmax) = ($1,$2,$3); - undef $first if $sep && not $rmin; - undef $last if $sep && not $rmax; - if ($rmin) { - $first = $rmin if defined $first && $rmin < $first; - $last = $rmin if defined $last && $rmin > $last; - } - if ($rmax) { - $first = $rmax if defined $first && $rmax < $first; - $last = $rmax if defined $last && $rmax > $last; - } - } - # Calculate the new page range - my @newselect; - for (split /,/, $select) { - $_ =~ /^(\d*)(-?)(\d*)$/; - my ($rmin,$sep,$rmax) = ($1,$2,$3); - if (defined $first) { - $rmin -= $first-1 if $rmin; - $rmax -= $first-1 if $rmax; +# ========================================================= + + + +# +# Conversion from PDF to PS, if necessary +# Reads from FIN, writes to IN +# +sub pdftops { + + if ($filetype eq "PDF") { + unless (defined $infile && $inseek) { + # Need to copy the whole input to an auxiliary file, since + # conversion from PDF to PS requires random access to the data + + $infile = "$tmpdir/pdftool-stdin-$$." . lc $filetype; + + open FINAUX, '>', $infile + or die "Can't write into `$infile': $!"; + push @auxfiles, $infile; + + # cat > $infile + while () { + print FINAUX or die "Can't print: $!"; } - push @newselect, "$rmin$sep$rmax"; + close FINAUX; } + + my ($first, $last); + # pdftops doesn't provide any way to have page numbers relative to + # the end of the document, hence there is no detection of the + # smallest interval if $select contains `_' + if (defined $select && not $select =~ /_/) { + # Convert to PS only the pages we are interested in + ($first, $last) = (1<<16,-(1<<16)); + for (split /,/, $select) { + $_ =~ /^(\d*)(-?)(\d*)$/; + my ($rmin,$sep,$rmax) = ($1,$2,$3); + undef $first if $sep && not $rmin; + undef $last if $sep && not $rmax; + if ($rmin) { + $first = $rmin if defined $first && $rmin < $first; + $last = $rmin if defined $last && $rmin > $last; + } + if ($rmax) { + $first = $rmax if defined $first && $rmax < $first; + $last = $rmax if defined $last && $rmax > $last; + } + } + + # Calculate the new page range + my @newselect; + for (split /,/, $select) { + $_ =~ /^(\d*)(-?)(\d*)$/; + my ($rmin,$sep,$rmax) = ($1,$2,$3); + if (defined $first) { + $rmin -= $first-1 if $rmin; + $rmax -= $first-1 if $rmax; + } + push @newselect, "$rmin$sep$rmax"; + } + + $select = join ',', @newselect; + } + + # Convert to PS + my @cmd = ('pdftops', '-origpagesizes', "$infile", '-'); + push @cmd, '-f', $first if defined $first; + push @cmd, '-l', $last if defined $last; + push @cmd, '-q' if defined $quiet; + my $pid = open *PSIN, "-|", @cmd + or die "Can't run `" . &printcmd (@cmd) . "'"; + push @pids, [$pid, @cmd]; - $select = join ',', @newselect; + } else { + open *PSIN, "<&FIN" or die "Can't dup: $!"; } - - # Convert to PS - @cmd = ('pdftops', '-origpagesizes', "$infile", '-'); - push @cmd, '-f', $first if defined $first; - push @cmd, '-l', $last if defined $last; - push @cmd, '-q' if defined $quiet; - my $pid = open *PSIN, "-|", @cmd - or die "Can't run `" . &printcmd (@cmd) . "'"; - push @pids, [$pid, @cmd]; -} else { - open *PSIN, "<&FIN" or die "Can't dup: $!"; + open *IN, "<&PSIN" or die "Can't dup: $!"; } -open *IN, "<&PSIN" or die "Can't dup: $!"; # -# Select, if necessary +# Select some pages in the document +# Reads/writes from/to IN # -if (defined $select) { - @cmd = ('psselect', $select); +sub psselect { + my @cmd = ('psselect', '-p', $select); push @cmd, '-q' if defined $quiet; + my $pid = open3 "<&IN", *OUT, ">&LOG", @cmd; push @pids, [$pid, @cmd]; + open *IN, "<&OUT" or die "Can't dup: $!"; } # -# Bounding box +# Detect / calculate the bounding box +# Reads/writes from/to IN # -my @bbox; -if (defined $crop) { - # Calculate the maximal bounding box - - unless (seek IN, 0, 1) { - # The input is not seekable: have to create a seekable auxiliary file - - my $auxfile = "$tmpdir/pdftool-stdin-$$.ps"; +sub psbbox { + my @bbox; - open AUXFD, '>', "$auxfile" - or die "Can't write into `$auxfile': $!"; - push @auxfiles, $auxfile; - - # cat > $auxfile - while () { - print AUXFD or die "Can't print: $!"; + if (defined $crop) { + # Calculate the maximal bounding box + + unless (seek IN, 0, 1) { + # The input is not seekable: have to create a seekable auxiliary + # file + + my $auxfile = "$tmpdir/pdftool-stdin-$$.ps"; + + open AUXFD, '>', "$auxfile" + or die "Can't write into `$auxfile': $!"; + push @auxfiles, $auxfile; + + # cat > $auxfile + while () { + print AUXFD or die "Can't print: $!"; + } + close AUXFD or die "Can't close: $!"; + close IN or die "Can't close: $!"; + + open IN, '<', "$auxfile" or die "Can't read `$auxfile': $!"; } - close AUXFD or die "Can't close: $!"; - close IN or die "Can't close: $!"; - - open IN, '<', "$auxfile" or die "Can't read `$auxfile': $!"; - } - - # Need to duplicate IN, since it will be closed in the parent process - open *GSIN, '<&IN'; - - @cmd = ('gs', '-sDEVICE=bbox', '-dBATCH', '-dNOPAUSE', '-'); - my $pid = open3 "<&GSIN", ">&GSOUT", *GSOUT, @cmd; - - my ($p,$c) = (0,0); # Page & character counter - my ($x0, $y0, $x1, $y1) = (1<<16, 1<<16, -(1<<16), -(1<<16)); - while () { - if ($_ =~ m/^\%\%BoundingBox: (\d+) (\d+) (\d+) (\d+)/) { - $x0 = $1 if $1 < $x0; - $y0 = $2 if $2 < $y0; - $x1 = $3 if $3 > $x1; - $y1 = $4 if $4 > $y1; - unless (defined $quiet) { - my $s = "[" . ++$p . "] "; - $c += length $s; - if ($c >= 80) { - print LOG "\n" or die "Can't close: $!"; - $c = length $s; + + # Need to duplicate IN, since it will be closed in the parent process + open *GSIN, '<&IN'; + + my @cmd = ('gs', '-sDEVICE=bbox', '-dBATCH', '-dNOPAUSE', '-'); + my $pid = open3 "<&GSIN", ">&GSOUT", *GSOUT, @cmd; + + my ($p,$c) = (0,0); # Page & character counter + my ($x0, $y0, $x1, $y1) = (1<<16, 1<<16, -(1<<16), -(1<<16)); + while () { + if ($_ =~ m/^\%\%BoundingBox: (\d+) (\d+) (\d+) (\d+)/) { + $x0 = $1 if $1 < $x0; + $y0 = $2 if $2 < $y0; + $x1 = $3 if $3 > $x1; + $y1 = $4 if $4 > $y1; + unless (defined $quiet) { + my $s = "[" . ++$p . "] "; + $c += length $s; + if ($c >= 80) { + print LOG "\n" or die "Can't close: $!"; + $c = length $s; + } + print LOG $s or die "Can't close: $!"; } - print LOG $s or die "Can't close: $!"; } } - } - close GSOUT or die "Can't close: $!";; - print LOG "\n" or die "Can't close: $!" unless defined $quiet; - - # No zombie processes - waitpid $pid, 0; - die "Can't run `" . &printcmd (@cmd) . "'" if $? >> 8; - - die "Error when calculating bounding box" if ($x0 >= $x1 || $y0 >= $y1); - @bbox = ($x0, $y0, $x1, $y1); - - # Let's go back to the beginning of the input - seek IN, 0, 0 or die "$!"; - -} elsif (defined $inwidth and defined $inheight) { - @bbox = (0, 0, $inwidth, $inheight); -} else { - # Guess page size from the input file - - # To avoid to seek into IN, it gonna be copied from WRITE to READ - # in background, once the Bounding Box has been read - pipe *READ, *WRITE or die "Can't pipe: $!"; + close GSOUT or die "Can't close: $!"; + print LOG "\n" or die "Can't close: $!" unless defined $quiet; + + # No zombie processes + waitpid $pid, 0; + die "Can't run `" . &printcmd (@cmd) . "'" if $? >> 8; + + die "Error while calculating bounding box" + if ($x0 >= $x1 || $y0 >= $y1); + @bbox = ($x0, $y0, $x1, $y1); + + # Let's go back to the beginning of the input + seek IN, 0, 0 or die "$!"; + + } elsif (defined $inwidth and defined $inheight) { + @bbox = (0, 0, $inwidth, $inheight); - while (not (@bbox) && defined (my $l = )) { - print WRITE $l or die "Can't close: $!"; - @bbox = ($1, $2, $3, $4) - if ($l =~ m/^\%\%BoundingBox: (\d+) (\d+) (\d+) (\d+)/); - } - - die "Cannot guess input page size!" unless @bbox; - - unless (my $pid = fork) { - # Child: cat IN > WRITE in background - die "Can't fork: $!" unless defined $pid; - close READ or die "Can't close: $!";; - - while () { - print WRITE or die "Can't close: $!"; + } else { + # Guess page size from the input file + + # To avoid to seek into IN, it gonna be copied from WRITE to READ + # in background, once the Bounding Box has been read + pipe *READ, *WRITE or die "Can't pipe: $!"; + + while (not (@bbox) && defined (my $l = )) { + print WRITE $l or die "Can't close: $!"; + @bbox = ($1, $2, $3, $4) + if ($l =~ m/^\%\%BoundingBox: (\d+) (\d+) (\d+) (\d+)/); + } + + die "Cannot guess input page size!" unless @bbox; + + unless (my $pid = fork) { + # Child: cat IN > WRITE in background + die "Can't fork: $!" unless defined $pid; + close READ or die "Can't close: $!";; + + while () { + print WRITE or die "Can't close: $!"; + } + exit; } - exit; + # Parent + + close WRITE or die "Can't close: $!"; + close IN or die "Can't close: $!"; + + open *IN, "<&READ" or die "Can't dup: $!"; } - # Parent - - close WRITE or die "Can't close: $!"; - close IN or die "Can't close: $!"; - - open *IN, "<&READ" or die "Can't dup: $!"; + return @bbox; } # # PSBook +# Reads/writes from/to IN # -if (defined $book) { - @cmd = ('psbook'); +sub psbook { + my @cmd = ('psbook'); push @cmd, '-q' if defined $quiet; my $pid = open3 "<&IN", *OUT, ">&LOG", @cmd; - open *IN, "<&OUT" or die "Can't dup: $!"; push @pids, [$pid, @cmd]; -} - - -# -# PSNup (inlined here, to keep track of the possible rotation) -# -my $landscape; -if ((($bbox[2]-$bbox[0] > $bbox[3]-$bbox[1]) - and not ($outwidth-2*$margin > $outheight-2*$margin)) - or - (defined $screen - and not ($bbox[2]-$bbox[0] > $bbox[3]-$bbox[1]) - and ($outwidth-2*$margin > $outheight-2*$margin))) { - ($outheight, $outwidth) = ($outwidth, $outheight); - $landscape = 1; -} - -my ($horiz, $vert, $rotate, $scale, $hshift, $vshift) - = &calc_layout ($nup, $border, \@bbox, - $outwidth-2*$margin, $outheight-2*$margin); - -my ($ospecs,$especs) = &calc_specs ($horiz, $vert, $rotate, $scale, - [$outwidth-2*$margin, $outheight-2*$margin, - $hshift, $vshift]); -my $land = ($outwidth > $outheight); -$land = not $land if ($rotate%2); - -my $pagespecs; -if (defined $screen || not $land) { - $pagespecs = "$nup:" . join ('+', @$ospecs); -} else { - $pagespecs = 2*$nup . ':' . join ('+', @$ospecs) . ',' . join ('+', @$especs); + open *IN, "<&OUT" or die "Can't dup: $!"; } -@cmd = ('pstops', '-w', $bbox[2], '-h', $bbox[3], $pagespecs); -push @cmd, '-q' if defined $quiet; -my $pid = open3 "<&IN", *OUT, ">&LOG", @cmd; -open *IN, "<&OUT" or die "Can't dup: $!"; -push @pids, [$pid, @cmd]; # -# Final file: Convert back to PDF +# PSNup (inlined here, to keep track of the possible rotation) +# Reads/writes from/to IN # -my $pagedevice; -if (defined $screen || $land || $landscape) { - $rotate = ($rotate+1)%4 if not (defined $screen) and $land; - $pagedevice = "/Orientation $rotate /PageSize [$outwidth $outheight]"; -} else { - $pagedevice = "/PageSize [$outwidth $outheight]"; -} - -@cmd = ('gs', "-sDEVICE=pdfwrite", "-sOutputFile=%stdout%", "-dBATCH", - "-dNOPAUSE", "-dAutoRotatePages=/None", - "-c", "<< $pagedevice >> setpagedevice", - "-f", "-"); -$pid = open3 "<&IN", ">&FOUT", ">&LOG", @cmd; -push @pids, [$pid, @cmd]; - - - -# Avoid zombies -map { my ($pid, @cmd) = @$_; -# print STDERR "PID: ", $pid, " Cmd: `", &printcmd (@cmd), "'"; - my ($r,$v) = (waitpid ($pid, 0), $?); - warn "Can't run `" . &printcmd (@cmd) . "'" if ($r != -1 and $v >> 8); - } @pids; - - -map { close $_ or die "Can't close: $!" } - ( *READ, *FIN, *FOUT ); - - -# Delete auxiliary files -unlink @auxfiles; - - - -# Useless, but Perl doesn't see that this filehandle is used more than -# one time (and even automatically closed by `open3') -exit; -close GSIN; +sub psnup { + my @bbox = @_; + my ($landscape, $rotate); + if ((($bbox[2]-$bbox[0] > $bbox[3]-$bbox[1]) + and not ($outwidth-2*$margin > $outheight-2*$margin)) + or + (defined $screen + and not ($bbox[2]-$bbox[0] > $bbox[3]-$bbox[1]) + and ($outwidth-2*$margin > $outheight-2*$margin))) { + ($outheight, $outwidth) = ($outwidth, $outheight); + $landscape = 1; + } -# ========================================================= + + # + # Finding the best layout is an optimisation problem. We try all of + # the combinations of width*height in both normal and rotated form, + # and minimise the wasted space. + # -# -# Finding the best layout is an optimisation problem. We try all of the -# combinations of width*height in both normal and rotated form, and -# minimise the wasted space. -# -sub calc_layout { - my ($nup, $border, $bbox, $outwidth, $outheight) = @_; + my ($ow,$oh) = ($outwidth-2*$margin, $outheight-2*$margin); - my ($inwidth, $inheight) = ($bbox[2]-$bbox[0], $bbox[3]-$bbox[1]); - my ($horiz, $vert, $rotate, $scale, $hshift, $vshift); + my ($iw, $ih) = ($bbox[2]-$bbox[0], $bbox[3]-$bbox[1]); + my ($horiz, $vert, $scale, $hshift, $vshift); my $tolerance = 100000; # layout tolerance my $best = $tolerance; @@ -677,31 +688,31 @@ sub calc_layout { for (my $hor = 1; $hor; $hor = &nextdiv($hor, $nup)) { my $ver = $nup / $hor; # try normal orientation first - my $scl = &min ($outheight/($inheight*$ver), $outwidth/($inwidth*$hor)); + my $scl = &min ($oh/($ih*$ver), $ow/($iw*$hor)); - my $optim = ($outwidth-$scl*$inwidth*$hor)*($outwidth-$scl*$inwidth*$hor) - + ($outheight-$scl*$inheight*$ver)*($outheight-$scl*$inheight*$ver); + my $optim = ($ow-$scl*$iw*$hor) * ($ow-$scl*$iw*$hor) + + ($oh-$scl*$ih*$ver) * ($oh-$scl*$ih*$ver); if ($optim < $best) { $best = $optim; # recalculate scale to allow for internal borders - $scale = &min (($outheight-2*$border*$ver)/($inheight*$ver), - ($outwidth-2*$border*$hor)/($inwidth*$hor)); - $hshift = ($outwidth/$hor - ($bbox[2]+$bbox[0])*$scale)/2; - $vshift = ($outheight/$ver - ($bbox[3]+$bbox[1])*$scale)/2; + $scale = &min (($oh-2*$border*$ver)/($ih*$ver), + ($ow-2*$border*$hor)/($iw*$hor)); + $hshift = ($ow/$hor - ($bbox[2]+$bbox[0])*$scale)/2; + $vshift = ($oh/$ver - ($bbox[3]+$bbox[1])*$scale)/2; ($horiz, $vert) = ($hor, $ver); $rotate = 0; } # try rotated orientation - $scl = &min ($outheight/($inwidth*$hor), $outwidth/($inheight*$ver)); - $optim = ($outheight-$scl*$inwidth*$hor)*($outheight-$scl*$inwidth*$hor) - + ($outwidth-$scl*$inheight*$ver)*($outwidth-$scl*$inheight*$ver); + $scl = &min ($oh/($iw*$hor), $ow/($ih*$ver)); + $optim = ($oh-$scl*$iw*$hor) * ($oh-$scl*$iw*$hor) + + ($ow-$scl*$ih*$ver) * ($ow-$scl*$ih*$ver); if ($optim < $best) { $best = $optim; # recalculate scale to allow for internal borders - $scale = &min (($outheight-2*$border*$hor)/($inwidth*$hor), - ($outwidth-2*$border*$ver)/($inheight*$ver)); - $hshift = ($outwidth/$ver - ($bbox[3]+$bbox[1])*$scale)/2; - $vshift = ($outheight/$hor - ($bbox[2]+$bbox[0])*$scale)/2; + $scale = &min (($oh-2*$border*$hor)/($iw*$hor), + ($ow-2*$border*$ver)/($ih*$ver)); + $hshift = ($ow/$ver - ($bbox[3]+$bbox[1])*$scale)/2; + $vshift = ($oh/$hor - ($bbox[2]+$bbox[0])*$scale)/2; ($horiz, $vert) = ($ver, $hor); $rotate = 3; } @@ -710,20 +721,11 @@ sub calc_layout { # fail if nothing better than worst tolerance was found die "Can't find acceptable layout for $nup-up" if $best == $tolerance; - return ($horiz, $vert, $rotate, $scale, $hshift, $vshift); -} - - - -# -# Construct pstops specification list -# -sub calc_specs { - my ($horiz, $vert, $rotate, $scale, $bbox) = @_; - my ($outwidth, $outheight, $hshift, $vshift) = @$bbox; + # + # Construct pstops specification list + # my $n = $horiz * $vert; - my (@ospecs, @especs); # specs for odd and even pages for (my $pageno = 0; $pageno < $n; $pageno++) { @@ -743,7 +745,7 @@ sub calc_specs { $up = $pageno % $vert; } ($orot,$erot) = ('L','R'); - $xoff = ($across+1)*$outwidth/$horiz - $hshift; + $xoff = ($across+1)*$ow/$horiz - $hshift; } else { if (defined $column) { # column=1; leftright=1; topbottom=1; @@ -754,19 +756,66 @@ sub calc_specs { $across = $pageno % $horiz; $up = $vert-1 - floor($pageno / $horiz); } - $xoff = $across*$outwidth/$horiz + $hshift; + $xoff = $across*$ow/$horiz + $hshift; } - $yoff = $up*$outheight/$vert + $vshift; + $yoff = $up*$oh/$vert + $vshift; push @ospecs, sprintf ("%d%s@%.3f(%.3f,%.3f)", $pageno, $orot, $scale, $xoff+$margin, $yoff+$margin); push @especs, sprintf ("%d%s@%.3f(%.3f,%.3f)", $n + $pageno, $erot, $scale, - $outwidth-$xoff+$margin, - $outheight-$yoff+$margin); + $ow-$xoff+$margin, $oh-$yoff+$margin); } - return (\@ospecs,\@especs); + + ($ow,$oh) = ($oh,$ow) if $rotate%2; + + my $pagespecs; + if (defined $screen || $ow < $oh) { + $pagespecs = $nup . ':' . join ('+', @ospecs); + } else { + $pagespecs = 2*$nup . ':' . join ('+', @ospecs) + . ',' . join ('+', @especs); + } + + my @cmd = ('pstops', '-w', $bbox[2], '-h', $bbox[3], $pagespecs); + push @cmd, '-q' if defined $quiet; + + my $pid = open3 "<&IN", *OUT, ">&LOG", @cmd; + push @pids, [$pid, @cmd]; + + open *IN, "<&OUT" or die "Can't dup: $!"; + + return ($landscape,$rotate); +} + + + +# +# Final file: Convert back to PDF +# Reads from IN, writes to FOUT +# +sub pstopdf { + my ($landscape,$rotate) = @_; + + my ($ow,$oh) = ($outwidth,$outheight); + ($ow,$oh) = ($oh,$ow) if $rotate%2; + + my $pagedevice; + if (defined $screen || $oh < $oh || $landscape) { + $rotate = ($rotate+1)%4 if not (defined $screen) and $oh < $ow; + $pagedevice = "/Orientation $rotate /PageSize [$outwidth $outheight]"; + } else { + $pagedevice = "/PageSize [$outwidth $outheight]"; + } + + my @cmd = ('gs', "-sDEVICE=pdfwrite", "-sOutputFile=%stdout%", "-dBATCH", + "-dNOPAUSE", "-dAutoRotatePages=/None", + "-c", "<< $pagedevice >> setpagedevice", + "-f", "-"); + + my $pid = open3 "<&IN", ">&FOUT", ">&LOG", @cmd; + push @pids, [$pid, @cmd]; } @@ -835,7 +884,7 @@ sub papersize { } elsif ($p eq "quarto") { ($$w,$$h) = (610, 780); # 8.5in * 10.83in } elsif ($p eq "10x14") { - ($$w,$$h) = ("10in", "14in"); + ($$w,$$h) = ("10in", "14in"); } else { die "Unknown paper size: `$p'"; } @@ -859,8 +908,6 @@ sub printcmd { join ' ', @cmd; } - - sub nextdiv { my ($n, $m) = @_; while (++$n <= $m) { @@ -869,15 +916,8 @@ sub nextdiv { return 0; } - sub min { my ($n, $m) = @_; return $n if $n < $m; return $m; } - - -sub round { - return floor ($_[0] + .5); -} - -- cgit v1.2.3