From b10d827ab1433f9a990b4354d5a9f0f1c1463447 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Thu, 23 Sep 2010 20:08:24 +0200 Subject: Cleanin the code --- pscrop.pl | 134 +++++++++++++++++++++++++++++--------------------------------- 1 file changed, 63 insertions(+), 71 deletions(-) diff --git a/pscrop.pl b/pscrop.pl index 796bdbb..9bb0728 100755 --- a/pscrop.pl +++ b/pscrop.pl @@ -42,35 +42,40 @@ use IPC::Open3; use warnings; use strict; +# TODO: units +# TODO: "-m h1cm:v3cm": horizontal, vertical my $margin = '1'; -my $papersize = 'a4'; +my $papersize = 'a4'; -our ($opt_d, $opt_r); our $opt_m = 1; # in centimeters our ($opt_w, $opt_h) = (21.0, 29.7); # in centimeters, A4 -our ($opt_l, $opt_s) = (2, 1); # Default: 2 pages per page - -our $opt_D = 'L'; # 'L' or 'R'. How to rotate, if required. my $units_per_cm = 72 * .3937; # 1 centimeters = .393700787 inches, 1 inch = 72 PostScript units5 +# TODO: not always STDIN +open *FIN, "<&STDIN"; + +#TODO: not always stdout +open FOUT, ">&STDOUT"; + + + +# # Calculate the maximal bounding box # -my $pid; -my ($x1, $y1, $x2, $y2) = (2**16, 2**16, -2**16, -2**16); -my $cmdline = "gs -sDEVICE=bbox -dBATCH -dNOPAUSE - 2>&1"; +my $pid; -open *KIDIN, "<&STDIN"; +# need to duplicate STDIN, since it will be closed in the parent process +open *KIDFIN, "<&FIN"; -#open *FIN, '-|', 'gs', '-sDEVICE=bbox', '-dBATCH', '-dNOPAUSE', '-' -#open *FIN, '-|', 'gs -sDEVICE=bbox -dBATCH -dNOPAUSE - 2>&1' -open3 "<&KIDIN", ">&FIN", *FIN, +$pid = open3 "<&KIDFIN", ">&FINGS", *FINGS, 'gs', '-sDEVICE=bbox', '-dBATCH', '-dNOPAUSE', '-' - or die "Can't run: '$cmdline'"; + or die "Can't run: `gs -sDEVICE=bbox -dBATCH -dNOPAUSE -'"; my $n = 0; -while () { +my ($x1, $y1, $x2, $y2) = (1<<16, 1<<16, -(1<<16), -(1<<16)); +while () { if ($_ =~ m/^\%\%BoundingBox: (\d+) (\d+) (\d+) (\d+)/) { $x1 = $1 if $1 < $x1; $y1 = $2 if $2 < $y1; @@ -79,21 +84,26 @@ while () { print STDERR "[", ++$n, "] "; } } -close FIN; - +close FINGS; print STDERR "\n"; -seek STDIN, 0, 0; +# No zombie processes +waitpid $pid, 0; die "Error calculating bounding box" if (($x1 >= $x2) || ($y1 >= $y2)); #print "Bounding box: ($x1,$y1), ($x2,$y2)\n"; my @bbox = ($x1, $y1, $x2, $y2); + +# Let's go back to the beginning of the input +seek FIN, 0, 0; + + + # # Calculate pstops specification # -#my @views = &calculate_views_short_x_long($opt_s, $opt_l, $opt_r); -my @views = &calculate_views_short_x_long(1, 1, 3); +my @views = &calculate_views_short_x_long; my $spec = scalar(@views); for (my $i = 0; $i < scalar(@views); $i++) { @@ -103,52 +113,54 @@ for (my $i = 0; $i < scalar(@views); $i++) { my ($w, $h) = ($opt_w * $units_per_cm, $opt_h * $units_per_cm); $w = int($w + .5); $h = int($h + .5); -my $ps_size_spec = "\%\%BeginFeature: *PageSize ($w $h)\n<< /PageSize [$w $h] >> setpagedevice\n\%\%EndFeature\n"; +my $ps_size_spec = << "EOF"; +\%\%BeginFeature: *PageSize ($w $h) +<< /PageSize [$w $h] >> setpagedevice +\%\%EndFeature +EOF + -# -# Dry run? Only print the specification -# -#$cmdline = "pstops -w$w -h$h '$spec' $in_file"; -#if ($opt_d) { -# print "$cmdline $out_file\nAnd add after the first '\%\%EndComments':\n$ps_size_spec"; -# exit(0); -#} # # Run the program and filter the output # -my $PStoPSclip_hack = 1; -#$out_file = '-' unless $out_file; -#(open FOUT, ">$out_file") or die "Can't create '$out_file': $!\n"; -open2 *FIN, "<&STDIN", 'pstops', "-w$w", "-h$h", "$spec" - or die "Can't run '$cmdline': $!\n"; -#(open FIN, "$cmdline|") or die "Can't run '$cmdline': $!\n"; -while (my $l = ) { +open2 *FINPS2PS, "<&FIN", 'pstops', "-w$w", "-h$h", "$spec" + or die "Can't run `pstops -w$w -h$h $spec': $!\n"; + +my $l; +# Header and comments +while ($l = ) { # Optional, but nice: tune how "gv" will show the document next if $l =~ m/^\%\%DocumentMedia:/; + if ($l =~ m/^\%\%BoundingBox:/) { - (print "\%\%BoundingBox: 0 0 $w $h\n") or die "Can't print: $!"; - next; + print FOUT "\%\%BoundingBox: 0 0 $w $h\n" or die "Can't print: $!"; + next; } - (print $l) or die "Can't print: $!"; + print FOUT $l or die "Can't print: $!"; chomp $l; + # Important to print the document right if ('%%EndComments' eq $l) { - (print $ps_size_spec) or die "Can't print: $!"; - last; + print FOUT $ps_size_spec or die "Can't print: $!"; + last; } } -while (my $l = ) { - (print $l) or die "Can't print: $!"; - if ($PStoPSclip_hack && ($l =~ m/^userdict\/PStoPSclip{0 0 moveto$/)) { - $l = ; - $l =~ s/\./0./g; # Increase clipping box by 10 - (print $l) or die "Can't print: $!"; +# Body +while () { + print FOUT $_ or die "Can't print: $!"; + + # PStoPSclip hack: increase clipping box by 10 + if ($_ =~ m/^userdict\/PStoPSclip{0 0 moveto$/) { + $l = ; + $l =~ s/\./0./g; + print FOUT $l or die "Can't print: $!"; } } -#(close FIN) or die "Can't close '$cmdline': $!"; -#(close FOUT) or die "Can't close '$out_file': $!"; +close FIN; +close FOUT; + # ========================================================= @@ -166,18 +178,12 @@ sub calc_pstops_page { $box_from->[3] - $box_from->[1]); my ($width_to, $height_to) = ($box_to->[2] - $box_to->[0], $box_to->[3] - $box_to->[1]); - my $rotation = (($width_from > $height_from) xor ($width_to > $height_to)); # # Scale factor # my ($scale1, $scale2); - if ($rotation) { - ($scale1, $scale2) = ($height_to / $width_from, - $width_to / $height_from); - } else { ($scale1, $scale2) = ($width_to / $width_from, $height_to / $height_from); - } my $scale = ($scale1 > $scale2) ? $scale2 : $scale1; #print "scale 1,2,common: [$scale1] [$scale2] [$scale]\n"; # @@ -191,21 +197,11 @@ sub calc_pstops_page { # Fist, pstops scales, then rotates, then moves # ($cx, $cy) = ($cx * $scale, $cy * $scale); - if ($rotation) { - $rotation = $opt_D; - if ('L' eq $rotation) { - ($cx, $cy) = (-$cy, $cx); - } elsif ('R' eq $rotation) { - ($cx, $cy) = ($cy, -$cx); - } else { - die "Unknown rotation"; - } - } my ($movex, $movey) = ($cx_to - $cx, $cy_to - $cy); # # Generate the summary # - my $s = sprintf('%s@%.3f(%.1f,%.1f)', $rotation, $scale, $movex, $movey); + my $s = sprintf('@%.3f(%.1f,%.1f)', $scale, $movex, $movey); #print "pstops string: [$s]\n"; return $s; } @@ -232,17 +228,13 @@ sub calculate_coordinates { # (For A4, short == width, long == height) # sub calculate_views_short_x_long { - my ($n_short_edge, $n_long_edge, $long_reverse) = @_; my ($pu_width, $pu_height, $pu_margin) = ($opt_w * $units_per_cm, $opt_h * $units_per_cm, $opt_m * $units_per_cm); my @short_coordinates = - &calculate_coordinates($pu_width, $pu_margin, $n_short_edge); + &calculate_coordinates($pu_width, $pu_margin, 1); my @long_coordinates = - &calculate_coordinates($pu_height, $pu_margin, $n_long_edge); - if ($long_reverse) { - @long_coordinates = reverse @long_coordinates; - } + &calculate_coordinates($pu_height, $pu_margin, 1); my @views; foreach my $x_coords (@short_coordinates) { foreach my $y_coords (@long_coordinates) { -- cgit v1.2.3