From 6a2940bcf58d32c6d634e57ca67cb29f79e4b8b0 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Fri, 24 Sep 2010 00:18:05 +0200 Subject: Still cleaning --- pscrop.pl | 163 ++++++++++++++++++++++++-------------------------------------- 1 file changed, 63 insertions(+), 100 deletions(-) diff --git a/pscrop.pl b/pscrop.pl index 9bb0728..c5cea04 100755 --- a/pscrop.pl +++ b/pscrop.pl @@ -39,17 +39,17 @@ Version: 0.0.5, 23 October 2008 use Getopt::Long; use IPC::Open2; use IPC::Open3; +use POSIX qw(floor); use warnings; use strict; # TODO: units # TODO: "-m h1cm:v3cm": horizontal, vertical -my $margin = '1'; +my $opt_m = '1'; # in centimeters my $papersize = 'a4'; -our $opt_m = 1; # in centimeters -our ($opt_w, $opt_h) = (21.0, 29.7); # in centimeters, A4 +my ($opt_w, $opt_h) = (21.0, 29.7); # in centimeters, A4 my $units_per_cm = 72 * .3937; # 1 centimeters = .393700787 inches, 1 inch = 72 PostScript units5 @@ -74,13 +74,13 @@ $pid = open3 "<&KIDFIN", ">&FINGS", *FINGS, 'gs', '-sDEVICE=bbox', '-dBATCH', '-dNOPAUSE', '-' or die "Can't run: `gs -sDEVICE=bbox -dBATCH -dNOPAUSE -'"; my $n = 0; -my ($x1, $y1, $x2, $y2) = (1<<16, 1<<16, -(1<<16), -(1<<16)); +my ($x0, $y0, $x1, $y1) = (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; - $x2 = $3 if $3 > $x2; - $y2 = $4 if $4 > $y2; + $x0 = $1 if $1 < $x0; + $y0 = $2 if $2 < $y0; + $x1 = $3 if $3 > $x1; + $y1 = $4 if $4 > $y1; print STDERR "[", ++$n, "] "; } } @@ -90,34 +90,26 @@ print STDERR "\n"; # 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); +die "Error calculating bounding box" if ($x0 >= $x1 || $y0 >= $y1); +my @bbox = ($x0, $y0, $x1, $y1); # Let's go back to the beginning of the input -seek FIN, 0, 0; +seek FIN, 0, 0 or die "Can't seek!"; # # Calculate pstops specification # -my @views = &calculate_views_short_x_long; +# (rounded) width, height, and margin +my ($w, $h, $margin) = map { &round ($_ * $units_per_cm) } + ($opt_w, $opt_h, $opt_m); -my $spec = scalar(@views); -for (my $i = 0; $i < scalar(@views); $i++) { - my $s = &calc_pstops_page(\@bbox, $views[$i]); - $spec .= ($i ? '+' : ':') . $i. $s; -} -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 = << "EOF"; -\%\%BeginFeature: *PageSize ($w $h) -<< /PageSize [$w $h] >> setpagedevice -\%\%EndFeature -EOF +($x0,$x1) = &calculate_coordinates($w, $margin); +($y0,$y1) = &calculate_coordinates($h, $margin); + +my $spec = 0 . &calc_pstops_page(@bbox, $x0, $y0, $x1, $y1); @@ -125,12 +117,11 @@ EOF # Run the program and filter the output # -open2 *FINPS2PS, "<&FIN", 'pstops', "-w$w", "-h$h", "$spec" - or die "Can't run `pstops -w$w -h$h $spec': $!\n"; - +$pid = 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 = ) { +while (defined ($l = ) && $l ne "\%\%EndComments\n") { # Optional, but nice: tune how "gv" will show the document next if $l =~ m/^\%\%DocumentMedia:/; @@ -139,14 +130,16 @@ while ($l = ) { next; } print FOUT $l or die "Can't print: $!"; - chomp $l; - - # Important to print the document right - if ('%%EndComments' eq $l) { - print FOUT $ps_size_spec or die "Can't print: $!"; - last; - } } + +# Important to print the document right +print FOUT << "EOF"; +\%\%EndComments +\%\%BeginFeature: *PageSize ($w $h) +<< /PageSize [$w $h] >> setpagedevice +\%\%EndFeature +EOF + # Body while () { print FOUT $_ or die "Can't print: $!"; @@ -158,9 +151,14 @@ while () { print FOUT $l or die "Can't print: $!"; } } + close FIN; close FOUT; +# No zombie processes +waitpid $pid, 0; + + # ========================================================= @@ -168,42 +166,29 @@ close FOUT; # Calculate an item of the pstops specification # sub calc_pstops_page { - my ($box_from, $box_to) = @_; - #print 'bbox_from: ', join(' ', @$box_from), "\n"; - #print 'bbox_to: ', join(' ', @$box_to), "\n"; - # - # Check if rotation required - # - my ($width_from, $height_from) = ($box_from->[2] - $box_from->[0], - $box_from->[3] - $box_from->[1]); - my ($width_to, $height_to) = ($box_to->[2] - $box_to->[0], - $box_to->[3] - $box_to->[1]); - # - # Scale factor - # - my ($scale1, $scale2); - ($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"; - # + my ($fx0, $fy0, $fx1, $fy1, + $tx0, $ty0, $tx1, $ty1) = @_; + + # From and to width / height + my ($wf, $hf) = ($fx1 - $fx0, $fy1 - $fy0); + my ($wt, $ht) = ($tx1 - $tx0, $ty1 - $ty0); + + # Scale factor width / height + my ($sw, $sh) = ($wt / $wf, $ht / $hf); + + # We take the smallest scale + my $scale = ($sw > $sh) ? $sh : $sw; + # Calculate the centers of the boxes - # - my ($cx, $cy) = (.5 * ($box_from->[0] + $box_from->[2]), - .5 * ($box_from->[1] + $box_from->[3])); - my ($cx_to, $cy_to) = (.5 * ($box_to->[0] + $box_to->[2]), - .5 * ($box_to->[1] + $box_to->[3])); - # - # Fist, pstops scales, then rotates, then moves - # - ($cx, $cy) = ($cx * $scale, $cy * $scale); - my ($movex, $movey) = ($cx_to - $cx, $cy_to - $cy); - # + my ($cxf, $cyf) = ( .5 * ($fx0 + $fx1), .5 * ($fy0 + $fy1) ); + my ($cxt, $cyt) = ( .5 * ($tx0 + $tx1), .5 * ($ty0 + $ty1) ); + + # Fist, pstops scales, then moves + + my ($movex, $movey) = ($cxt - $cxf * $scale, $cyt - $cyf * $scale); + # Generate the summary - # - my $s = sprintf('@%.3f(%.1f,%.1f)', $scale, $movex, $movey); - #print "pstops string: [$s]\n"; - return $s; + return sprintf( '@%.3f(%.3f,%.3f)', $scale, $movex, $movey); } # ========================================================= @@ -214,37 +199,15 @@ sub calc_pstops_page { # elements: the begin and end coordinates # sub calculate_coordinates { - my ($length, $opt_m, $n) = @_; - my $skip = ($length - $opt_m) / $n; - my $width = $skip - $opt_m; - my @end_coords = map { int(.5 + $skip * $_) } (1..$n); - my @coords = map { my @a = (int(.5 + $_ - $width), $_); \@a } @end_coords; - #print "$n: "; map { print '[', $_->[0], ',', $_->[1], ']' } @coords; print "\n"; + my ($length, $margin) = @_; + my $skip = $length - $margin; + my $width = $skip - $margin; + my @coords = ( &round( &round($skip) - $width ), &round($skip) ); return @coords; } -# -# N_short_edge * N_long_edge views paer page -# (For A4, short == width, long == height) -# -sub calculate_views_short_x_long { - 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, 1); - my @long_coordinates = - &calculate_coordinates($pu_height, $pu_margin, 1); - my @views; - foreach my $x_coords (@short_coordinates) { - foreach my $y_coords (@long_coordinates) { - my @view = ($x_coords->[0], $y_coords->[0], - $x_coords->[1], $y_coords->[1]); - push @views, \@view; - } - } - return @views; +# Round a float number +sub round { + return floor ($_[0] + .5); } - - -- cgit v1.2.3