nasm/doc/pspdf.pl
H. Peter Anvin 186f9a0514 doc: fix yet another set of Ghostscript font problems
Seems like Ghostscript has managed to break fontconfig support again,
at least in Fedora 30. Help Ghostscript along by giving it an explicit
font path.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
2019-06-06 20:51:10 -07:00

134 lines
3.5 KiB
Perl
Executable File

#!/usr/bin/perl
#
# Wrapper around a variety of programs that can do PS -> PDF conversion
#
use strict;
use File::Spec;
my $compress = 1;
my $win32_ok = eval {
require Win32::TieRegistry;
Win32::TieRegistry->import();
1;
};
while ($ARGV[0] =~ /^-(.*)$/) {
my $opt = $1;
shift @ARGV;
if ($opt eq '-nocompress') {
$compress = 0;
}
}
# Ghostscript executable name. "gs" on Unix-based systems.
my $gs = 'gs';
my ($in, $out, $fontpath) = @ARGV;
if (!defined($out)) {
die "Usage: $0 [-nocompress] infile outfile [fontpath]\n";
}
# If Win32, help GhostScript out with some defaults
sub win32_gs_help() {
return if (!$win32_ok);
use Sort::Versions;
use sort 'stable';
my $Reg = $::Registry->Open('', {Access => 'KEY_READ', Delimiter => '/'});
my $dir;
my @gs;
foreach my $k1 ('HKEY_CURRENT_USER/Software/',
'HKEY_LOCAL_MACHINE/SOFTWARE/') {
foreach my $k2 ('Artifex/', '') {
foreach my $k3 ('GPL Ghostscript/', 'AFPL Ghostscript/',
'Ghostscript/') {
my $r = $Reg->{$k1.$k2.$k3};
if (ref($r) eq 'Win32::TieRegistry') {
foreach my $k (keys(%$r)) {
my $rk = $r->{$k};
if (ref($rk) eq 'Win32::TieRegistry' &&
defined($rk->{'/GS_LIB'})) {
push @gs, $rk;
}
}
}
}
}
}
@gs = sort {
my($av) = $a->Path =~ m:^.*/([^/]+)/$:;
my($bv) = $b->Path =~ m:^.*/([^/]+)/$:;
versioncmp($av, $bv);
} @gs;
return unless (scalar(@gs));
$ENV{'PATH'} .= ';' . $gs[0]->{'/GS_LIB'};
$ENV{'GS_FONTPATH'} .= (defined($ENV{'GS_FONTPATH'}) ? ';' : '')
. $ENV{'windir'}.'\\fonts';
my $gsp = undef;
foreach my $p (split(/\;/, $gs[0]->{'/GS_LIB'})) {
foreach my $exe ('gswin64c.exe', 'gswin32c.exe', 'gs.exe') {
last if (defined($gsp));
my $e = File::Spec->catpath($p, $exe);
$gsp = $e if (-f $e && -x _);
}
}
$gs = $gsp if (defined($gsp));
}
# Remove output file
unlink($out);
# 1. Acrobat distiller
my $r = system('acrodist', '-n', '-q', '--nosecurity', '-o', $out, $in);
exit 0 if ( !$r && -f $out );
# 2. ps2pdf (from Ghostscript)
#
# GhostScript uses # rather than = to separate options and values on Windows,
# it seems. Similary it uses ; in path lists rather than :.
# Call gs directly rather than ps2pdf, because -dSAFER
# breaks font discovery on some systems, apparently.
win32_gs_help();
my $o = $win32_ok ? '#' : '=';
my $p = $win32_ok ? ';' : ':';
my $fpopt;
if (defined($fontpath)) {
my @fplist = ();
open(my $fp, '<', $fontpath) or die "$0: $fontpath: $!\n";
while (my $fpe = <$fp>) {
chomp $fpe;
push(@fplist, $fpe);
}
close($fp);
$fpopt = "-sFONTPATH${o}" . join($p, @fplist);
}
my $r = system($gs, "-dCompatibilityLevel${o}1.4", "-q",
"-P-", "-dNOPAUSE", "-dBATCH", "-sDEVICE${o}pdfwrite",
"-sstdout${o}%stderr", "-sOutputFile${o}${out}",
"-dOptimize${o}true", "-dEmbedAllFonts${o}true",
$fpopt,
"-dCompressPages${o}" . ($compress ? 'true' : 'false'),
"-dUseFlateCompression${o}true",
"-c", ".setpdfwrite", "-f", $in);
exit 0 if ( !$r && -f $out );
# 3. pstopdf (BSD/MacOS X utility)
my $r = system('pstopdf', $in, '-o', $out);
exit 0 if ( !$r && -f $out );
# Otherwise, fail
unlink($out);
exit 1;