| #!/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. Similarly 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.3", |
| "-I".File::Spec->curdir(), |
| "-P-", "-dNOPAUSE", "-dBATCH", "-sDEVICE${o}pdfwrite", |
| "-sstdout${o}%stderr", "-sOutputFile${o}${out}", |
| "-dOptimize${o}true", |
| "-dEmbedAllFonts${o}true", "-dSubsetFonts${o}true", |
| "-dMaxSubsetPct${o}100", |
| $fpopt, |
| "-dCompressPages${o}" . ($compress ? 'true' : 'false'), |
| "-dUseFlateCompression${o}true", |
| "-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; |