postscript

postscript line width doubler

Wed, 2009-08-26 21:04

I maintain the text that is used for the Math 120 (Precalculus) course at the University of Washington. (You can check it out here). The book has many figures (1500?), which all exist as postscript files in the text's archive. Now, over the last number of years, I've been trying to improve the book, and this has included improving the figures. Many figures were made with line widths that are too tiny, and sometimes don't print well. One way to fix this is to open the figures xfig file, edit the line widths there, and export to postscript again. I wanted a quicker way, and had previously found a script on line which doubled the line widths in a postscript file. But, yesterday I couldn't find it, so I wrote one myself.

The thing is, these postscript files are generated by xfig, so they have what I think is a peculiarity. Near the head of the file, in all the postscript files I've looked at in the archive, is this line:

/slw {setlinewidth} bind def

This "aliases" slw to stand for setlinewidth. Then, throughout the file are lines like

7.500 slw

consisting of nothing but a number (the line width) and slw. This makes things easy to manipulate.

So, I wrote this little perl script. It halves the difference between the current
line width and twice the new minimum width.

For instance, if $minWidth is set to 15, then line weights of 5 get increased to 17.5, line weights of 10 get increased to 20, line weights of 15 get increased to 22.5, 20 to 25, etc. Only weights below twice the $minWdith (in this case 30) get increased.

This works well, I think.


#!/bin/perl

$minWidth = 15; # all widths will be at least this much after processing

while(<>) { # read the file one line at a time
$line=$_; # call the line $line
if ($line =~ /[+-]?(\d+\.\d+|\d+\.|\.\d+)\s+slw/ ) { # if the line contains a number followed
# by whitespace and the string "slw", do this
$num=$1; # set $num to be the number bit
if ($num<2*$minWidth) { # if $num is small enough to need to be increased
print 0.5*$num+$minWidth," slw \n"; # increase the line width
}
else {
print $line; # otherwise no change
}
}
else {
print $line; # otherwise no change
}

}

To use this code, put it in a file called, say, lineWidths.pl. Then execute a command like

perl lineWidths.pl < original.ps > new.ps

and new.ps will be just like original.ps except the small line widths will now be somewhat thicker.

Something similar should work for most any postscript file, but this aliasing business makes me wonder how simple a completely general-purpose script would be to create.