summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuilhem Moulin <guilhem.moulin@chalmers.se>2010-09-24 00:18:05 +0200
committerGuilhem Moulin <guilhem.moulin@chalmers.se>2010-09-24 00:18:05 +0200
commit6a2940bcf58d32c6d634e57ca67cb29f79e4b8b0 (patch)
tree50835d7cb9627c71e09d55bbd955bff86ccd0b8d
parentb10d827ab1433f9a990b4354d5a9f0f1c1463447 (diff)
Still cleaning
-rwxr-xr-xpscrop.pl163
1 files 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 (<FINGS>) {
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 = <FINPS2PS>) {
+while (defined ($l = <FINPS2PS>) && $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 = <FINPS2PS>) {
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 (<FINPS2PS>) {
print FOUT $_ or die "Can't print: $!";
@@ -158,9 +151,14 @@ while (<FINPS2PS>) {
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);
}
-
-