/usr/local/CPAN/PostScript-EPSF/PostScript/EPSF.pm
package PostScript::EPSF;
use strict;
use vars qw($VERSION @EXPORT @EXPORT_OK);
$VERSION = "0.01";
require Exporter;
*import = \*Exporter::import;
@EXPORT=qw(include_epsf);
@EXPORT_OK=qw(epsf_prolog);
sub epsf_prolog
{
use vars qw($EPSF_PROLOG_DONE);
print <<"EOT" unless $EPSF_PROLOG_DONE++;
/BeginEPSF {
/b4_Inc_state save def
/dict_count countdictstack def
/op_count count 1 sub def
userdict begin
/showpage {} def
0 setgray 0 setlinecap 1 setlinewidth 0 setlinejoin
10 setmiterlimit [] 0 setdash newpath
/languagelevel where
{
1 ne {
false setstrokeadjust
false setoverprint
} if
} if
} bind def
/EndEPSF {
count op_count sub {pop} repeat
countdictstack dict_count sub {end} repeat
b4_Inc_state restore
} bind def
EOT
}
sub include_epsf
{
my %para;
while (my($k,$v) = splice(@_, 0, 2)) {
$k =~ s/^-//;
$para{$k} = $v;
}
#use Data::Dumper; print STDERR Dumper(\%para);
my $file = delete $para{"file"} ||
die "Mandatory -file argument is missing";
local(*EPS);
open(EPS, $file) || die "Can't open $file: $!";
my($llx, $lly, $urx, $ury);
my @eps;
while (<EPS>) {
if (/^%%BoundingBox:\s*(.*)/) {
($llx, $lly, $urx, $ury) = split(' ', $1);
} elsif (/^\s*%/ || /^\s*$/) {
# always skip other comments and empty lines
} else {
push(@eps, $_);
}
}
close(EPS);
die "Missing Bounding box in $file" unless defined $ury;
my $xscale = delete $para{"xscale"};
my $yscale = delete $para{"yscale"};
# Calculate width/height of included file
my $w = $urx - $llx;
my $h = $ury - $lly;
if (my $width = delete $para{"width"}) {
$xscale = $width / $w;
}
if (my $height = delete $para{"height"}) {
$yscale = $height / $h;
}
if (my $scale = delete $para{"scale"}) {
for ($xscale, $yscale) {
$_ = $scale unless $_;
}
}
$xscale = $yscale if $yscale && !$xscale;
$yscale = $xscale if $xscale && !$yscale;
if ($xscale) {
$w = $w * $xscale;
$h = $h * $yscale;
}
if (my $pos = delete $para{"pos"}) {
$pos =~ s/^\s*//;
@para{"x", "y"} = split(/\s*[,\s]\s*/, $pos);
}
my $x = delete $para{"x"} || 0;
my $y = delete $para{"y"} || 0;
my $anchor = delete $para{"anchor"} || "c";
if ($anchor =~ /w/) {
# no need to adjust $x
} elsif ($anchor =~ /e/) {
$x -= $w;
} else {
$x -= $w/2;
}
if ($anchor =~ /s/) {
# no need to adjust $y
} elsif ($anchor =~ /n/) {
$y -= $h;
} else {
$y -= $h/2;
}
my $rotate = delete $para{"rotate"};
my $clip = delete $para{"clip"};
my $background = delete $para{"background"};
my $boarder = delete $para{"boarder"} || 0;
if ($^W && %para) {
for (sort keys %para) {
warn "Unrecognized parameter: -$_ => $para{$_}\n";
}
}
epsf_prolog();
print "\nBeginEPSF\n";
if ($rotate || $xscale || $clip || $background) {
print "$x $y translate\n";
print "$rotate rotate\n" if $rotate;
if ($clip || $background) {
my $llx = 0;
my $lly = 0;
my $urx = $w;
my $ury = $h;
if ($boarder) {
$llx -= $boarder;
$lly -= $boarder;
$urx += $boarder;
$ury += $boarder;
}
print "$llx $lly moveto $urx $lly lineto\n";
print "$urx $ury lineto $llx $ury lineto closepath\n";
print "clip\n" if $clip;
if ($background) {
print "gsave ", color_to_ps($background), " fill grestore\n";
}
print "newpath\n";
}
print "$xscale $yscale scale\n" if $xscale;
print 0-$llx, " ", 0-$lly, " translate\n";
} else {
print $x-$llx, " ", $y-$lly, " translate\n";
}
print "%%BeginDocument: $file\n";
print @eps;
print "%%EndDocument: $file\n";
print "EndEPSF\n\n";
}
BEGIN
{
use vars qw(%color_names);
%color_names = (
black => 0,
white => 1,
red => "#f00",
green => "#0f0",
blue => "#00f",
yellow => "#ff0",
magenta => "#f0f",
cyan => "#0ff",
);
}
# should probably go into it's own module
sub color_to_ps
{
my $color = lc(shift || "");
$color =~ s/^\s+//;
$color =~ s/\s+$//;
$color = $color_names{$color} || $color;
if ($color =~ /^\d+(?:\.\d+)?$/) {
$color = 1 if $color > 1;
return sprintf "%.3f setgray", $color;
}
if ($color =~ /^\#([0-9a-f]+)$/ && (length($1) % 3) == 0) {
my $len = int(length($1) / 3);
my $fff = 2 ** ($len*4) - 1;
$color = $1;
my @rgb;
while (length $color) {
push(@rgb, hex(substr($color, 0, $len)) / $fff);
substr($color, 0, $len) = '';
}
return join(" ", map {sprintf "%.3f", $_} @rgb), " setrgbcolor";
}
return; # did not understand
}
1;