#!/usr/bin/perl -w
# By Kragen Sitaker, 2000.  In the public domain.
use strict;
print <<EOH;
%!
2 setlinewidth
/dotat {
	moveto 
	gsave 
		.001 0 rlineto 
		closepath stroke 
	grestore
	% The following lines will insert a smaller black dot at the center of every
	% dot, but due to the negative interactions between that dot and
	% halftoning on my printer (resulting in dots having more or less
	% random variations in darkness, depending on where this dot fell in
	% the halftoning pattern) I commented it out.  -- Kragen Sitaker
	% gsave
		% 0.1 setlinewidth 0 setgray
		% .001 0 rlineto closepath stroke
	% grestore
} bind def
1 setlinejoin
EOH

# Because I'm stupid and don't understand PostScript, I'll use physical
# coordinates in the Postscript and do all the math in Perl.
# 
# My coordinate system looks like this:
# 
#  (-1,1)  (0,2)   (1,2)
#
#      (0,1)   (1,1) 
#
#  (0,0)   (1,0)   (2,0)
#
# Ideally, (0,0), (0,1), and (1,0) are an equilateral triangle.

my $cos = cos (30 * 3.1415926/180);
my $sin = sin (30 * 3.1415926/180);
my $scale = 18;  # one fourth of an inch
my @origin = (20, 20);
sub phys {
	my ($x, $y) = @_;
	return (
		$origin[0] + $scale * $x + $scale * $sin * $y,
		$origin[1] + $scale * $cos * $y
	);
}

# allowable error is 1/1200 of an inch, or 0.06 points.
sub dotat {
	my ($x, $y) = @_;
	my ($physx, $physy) = phys $x, $y;
	printf "%.2f %.2f dotat\n", phys $x, $y;
}

sub setlinewidth { print "$_[0] setlinewidth\n"; }
sub setgray { print "$_[0] setgray\n"; }

# these physical numbers are taken from a Xerox Document Center printing
# on US Letter paper (8.5" by 11"); they ought to be reasonably close to
# valid for other people.
my $max_phys_x = 597.9;
my $max_x = ($max_phys_x - $origin[0])/$scale;  # valid for y=0
my $max_phys_y = 780.72;
my $max_y = ($max_phys_y - $origin[1])/($scale * $cos);

# evil: cut-and-pasted code.
setgray .85;
for my $y (0..int $max_y) {
	for my $x (int(-$y/2)..int($max_x)+int(-$y/2)) {
		dotat $x, $y;
	}
}

# now do darker dots every 3, then every 12
setlinewidth 2.2;
setgray .7;
for (my $y = 0; $y < $max_y; $y += 3) {
	for (my $x = 0; $x < $max_x; $x += 3) {
		dotat ($x - 3*int($y/2/3), $y);
	}
}

setlinewidth 3;
setgray .5;
for (my $y = 0; $y < $max_y; $y += 12) {
	for (my $x = 0; $x < $max_x; $x += 12) {
		dotat ($x - 12*int($y/2/12), $y);
	}
}

# sign it
print "gsave\n";
# add 1.5 to avoid that first dot
printf "%.2f %.2f translate\n", $origin[0], $origin[1] + 1.5;
# I was originally planning to use 24 vertical pixels per line, but
# that's too conspicuous on a 600dpi printer.  I calculated 24 vertical
# pixels per line for a 900dpi printer, which works out to 16 vertical
# pixels per line on a 600dpi printer --- not completely illegible.
# 12 points/line * X = 24 pixels/line
# 24 pixels/line * 1/900 inch/pixel = 24/900 inches/line
# 24/900 inches/line * 72 points/inch = 24 * 72 / 900 points/line
# that's what we want.  so X is 24*72/900*12, right?
# right, apparently.
print "/Times-Roman findfont 12 scalefont setfont\n";
printf "%f dup scale  0 setgray\n", 24*72/900/12;
my $x = 0;
for my $char (split //, 'hexpaper -- Kragen Sitaker') {
	printf "%d 0 moveto (%s) show\n", $x, $char;
	$x += 18 / (24*72/900/12);
}
print "grestore\n";

print "showpage\n";
