summaryrefslogtreecommitdiff
path: root/Master/texmf-dist
diff options
context:
space:
mode:
authorNorbert Preining <preining@logic.at>2009-05-17 13:17:38 +0000
committerNorbert Preining <preining@logic.at>2009-05-17 13:17:38 +0000
commit0f56007420bc24eb70b86021113a1b683cafee0c (patch)
tree2f59f71d4711091d602586b90a19a068c6b0fd6c /Master/texmf-dist
parent67a008fbce1e7f8f0622bd463c67ccc62e35af56 (diff)
move pkfix from texmf to texmf-dist, and make it a package on its own
git-svn-id: svn://tug.org/texlive/trunk@13160 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist')
-rw-r--r--Master/texmf-dist/doc/pkfix/README260
-rwxr-xr-xMaster/texmf-dist/scripts/pkfix/pkfix.pl872
2 files changed, 1132 insertions, 0 deletions
diff --git a/Master/texmf-dist/doc/pkfix/README b/Master/texmf-dist/doc/pkfix/README
new file mode 100644
index 00000000000..d96c9d6dcc4
--- /dev/null
+++ b/Master/texmf-dist/doc/pkfix/README
@@ -0,0 +1,260 @@
+README for project pkfix 2009/03/18 v1.5
+
+TABLE OF CONTENTS
+=================
+A. Project pkfix
+B. Copyright, Disclaimer, License
+C. Files
+D. Requirements
+E. Installation
+F. User Interface
+G. Author
+H. Questions, Suggested Improvements
+I. Known Problems
+J. History
+
+A. PROJECT PKFIX
+================
+Often PostScript files with embedded pk fonts are available that
+were generated by dvips. If these files are converted to pdf,
+the quality is very poor because of the bitmapped fonts.
+But what can be done, if the sources dvi or tex are not available?
+ This project pkfix tries a solution by replacing the used
+pk fonts by the type 1 ones.
+ It scans the file for the pk fonts by searching the comments,
+introduced by not too old dvips versions. For each detected bitmap
+font pkfix generates a tex file that uses this font. Then it runs
+dvips with option setting for pdf and hopes, that the corresponding
+type 1 font is found and included in the temporary PostScript file.
+So this font will be extracted and replaces the bitmapped font of
+the original PostScript file.
+
+CAUTION: The state is experimental. Tests are only done with teTeX.
+
+NOTICE:
+ pkfix works only for PostScript files that are generated
+ by dvips 5.58 or newer. These versions records the used
+ font in a PostScript comment.
+ Scott Pakin wrote `pkfix-helper' that uses a heuristics
+ to guess the original fonts and writes a PostScript file
+ that is suitable for processing by pkfix. The Perl script
+ `pkfix-helper' is available at CTAN:support/pkfix-helper.
+
+B. COPYRIGHT, DISCLAIMER, LICENSE
+=================================
+Copyright (C) 2001, 2005, 2007, 2009 Heiko Oberdiek.
+
+This work may be distributed and/or modified under the
+conditions of the LaTeX Project Public License, either version 1.3
+of this license or (at your option) any later version.
+The latest version of this license is in
+ http://www.latex-project.org/lppl.txt
+and version 1.3 or later is part of all distributions of LaTeX
+ version 2003/12/01 or later.
+This work has the LPPL maintenance status "maintained".
+This Current Maintainer of this work is Heiko Oberdiek.
+
+C. FILES
+========
+The project `pkfix' consists of two files:
+pkfix(.pl): This perl script is the main program. The extension
+ `.pl' may be omitted.
+README: Documentation, the file you are reading.
+
+Following temporary files are produced if `pkfix' is invoked
+($$ means the job number):
+_pkfix_$$.tex, _pkfix_$$.log, _pkfix_$$.dvi, _pkfix_$$.ps
+eventually missfont.log
+
+D. REQUIREMENTS
+===============
+* Perl5 (version 5 of the perl interpreter).
+* TeX (plain format)
+* dvips (not too old, for example 5.86)
+* texps.pro (part of dvips)
+* fonts
+
+E. INSTALLATION
+===============
+1. TeX directory structure (TDS):
+ The file
+ `README' (documentation)
+ go to
+ texmf/doc/programs/pkfix/README
+ or
+ texmf/doc/pkfix/README
+
+2. Perl script `pkfix.pl':
+
+ Unix
+ * Your are allowed to rename `pkfix.pl' to `pkfix':
+ mv pkfix.pl pkfix
+ * Ensure that the execute permission is set:
+ chmod +x pkfix
+ * Move the file to a directory where the shell can find it
+ (environment variable PATH, e.g. /usr/local/bin/).
+
+ Dos/Windows/(OS2)
+ * Running the perl interpreter directly with the perl script:
+ perl pkfix.pl ...
+ * Methods for calling by typing the script name without extension
+ and perl interpreter:
+ a) If your perl distribution provides a pl2exe program,
+ use it to generate `pkfix.exe'.
+ Advantage: I/O redirection works.
+ b) A good method is a dos program of John Dallman:
+ #!perl.exe (versions below 4)
+ hbperl.exe (version 4)
+ http://www.perl.com/CPAN/authors/id/JDALLMAN/hbp_403.zip
+ Move pkfix.pl in a PERLLIB directory and copy the
+ exe program to `pkfix.exe'. Then the program looks
+ for the perl interpreter, the script and calls them.
+ Advantage: I/O redirection works.
+ c) Windows NT 4.0 users can use associated file types:
+ SET PATHEXT=.pl;%PATHEXT%
+ See perl win32 faq "How do I associate Perl scripts with perl?":
+ http://www.activestate.com/support/faqs/win32/perlwin32faq4.html
+ Disadvantage: I/O redirection does not work.
+ d) 4DOS: SET .PL=c:/bin/perl.exe
+ See perl win32 faq "How can I get Perl to run a Perl script at
+ the 4DOS command line by typing the name of the script without
+ the extension or "perl", just like a regular exe file?":
+ http://www.activestate.com/support/faqs/win32/perlwin32faq1.html
+ e) Convert the perl script to a batch file `pkfix.bat', if your
+ distribution provides `pl2bat.bat'.
+ Disadvantage: I/O redirection does not work.
+ Many of this methods are listed in the perl win32 faq
+ "What's the equivalent of the shebang ("#!") syntax for Win32?":
+ http://www.activestate.com/support/faqs/win32/perlwin32faq4.html
+
+F. USER INTERFACE
+=================
+The perl script `pkfix.pl' can be invoked in two ways:
+a) pkfix --help
+ prints a help screen with the options and some default values.
+b) pkfix [options] <input.ps> <output.ps>
+ <input.ps> is the original PostScript file with pk fonts,
+ <output.ps> will be the result.
+
+Options:
+--clean: Removing of the temporary files.
+--quiet Messages except warnings are suppressed.
+--verbose Informations about the actions are printed.
+--debug Additional messages for debugging purposes;
+ also option `--clean' is disabled.
+--options opt Here the options for the dvips run can be changed,
+ default is "-Ppdf -G0".
+The other options are experimental.
+
+Example:
+ pkfix --verbose test.ps out.ps
+
+If a file name is replaced by "-" then the standard input/output is
+used. In case of standard output, messages of pkfix are written to
+standard error output. Thus pkfix can be used in pipes, eg:
+ pkfix foo.ps - | ps2pdf - foo.pdf
+ cat foo.ps | pkfix --quiet - - | ps2pdf - - >foo.pdf
+
+Environment variable `PKFIX':
+Before scanning the command line for options the perl script
+`pkfix.pl' looks for the environment variable `PKFIX'.
+Example (bash syntax):
+ export PKFIX="--verbose"
+Example (DOS syntax):
+ SET PKFIX=--verbose
+
+G. AUTHOR
+=========
+Heiko Oberdiek
+Email: oberdiek@uni-freiburg.de
+
+Many thanks to
+* Berthold Crysmann (crysmann at dfki.de) and
+ Harald Harders (h.harders at tu-bs.de) for testing
+ and bug reports.
+* Melissa O'Neill for providing a patch to support dvips 5.399.
+* Scott Pakin who wrote pkfix-helper.
+
+H. QUESTIONS, SUGGESTED IMPROVEMENTS
+====================================
+If you have questions, problems with `pkfix', error reports,
+if you have improvements or want to have additional features,
+please send them to the author.
+
+The environment that I had used for developing and testing:
+* linux, suse 9.1
+* perl 5.8.1
+* tex 3.14159
+* dvips 5.94a
+* kpsewhich 3.5.2
+
+(Nowadays I have installed TeX Live, for instance).
+
+I. KNOWN PROBLEMS
+=================
+* I have only tested with a few test files on a linux machine
+ with teTeX.
+* PostScript files, generated with older dvips versions
+ (for example 5.58), do not contain the essential comments,
+ so pkfix does not detect pk fonts. See Scott Pakin's pkfix-helper
+ that addresses this problem.
+* The perl script pkfix uses dvips and analyses its output,
+ so the version should not be too old (5.86 recommanded).
+ Some older (not too old) versions do not know the option
+ "-G0". As workaround the options for dvips can currently
+ be overwritten by an option for pkfix "--options".
+ Example: --options="-Pcmz -Pamz".
+* The new embedded type 1 fonts are not added to the
+ DSC comment %%DocumentFonts'.
+* It is assumed that the conversion bitmap to type 1 font
+ does not result in type 1 fonts that are already present.
+ Then this font would be added twice with probably differnt
+ subsettings with the consequence of missing characters.
+
+J. HISTORY
+==========
+2001/04/12 v0.1:
+ * First try.
+2001/04/13 v0.2:
+ * TeX/dvips is called for each font for the case of errors.
+ * First release.
+2001/04/15 v0.3:
+ * Call of kpsewhich with option --progname.
+ * Extracting of texps.pro from temporary PostScript file,
+ if kpsewhich failed.
+ * Option -G0 for dvips run added.
+2001/04/16 v0.4:
+ * Support for merging PostScript fonts added.
+ * \special{!...}/@fedspecial detection added.
+ * Bug fix: I detection.
+2001/04/17 v0.5:
+ * Redirection of stderr (dvips run) if possible.
+2001/04/20 v0.6:
+ * Bug fix: dvips font names can contain numbers.
+2001/04/21 v0.7:
+ * Bug fix: long dvi file name in ps file.
+2001/04/23 v0.8:
+ * Bug fix: post string parsing.
+2001/04/26 v0.9:
+ * Check of version number of dvips in PostScript file.
+2001/06/30 v1.0:
+ * Problem with DOS line ending fixed.
+2005/01/28 v1.1:
+ * Bug fix: encoding files are now included.
+ * The intermediate DVI files are written directly.
+ * LPPL 1.3
+2005/01/29 v1.2:
+ * Merging is now based on type 1 names. This solves
+ the problem, if different bitmap fonts maps to the
+ same type 1 font, eg. (ecrm1000, larm1000) -> SFRM1000.
+ * Suppression of PK generation, if environment variable
+ MKTEXPK is supported.
+ * If output file is "-" (standard output) then messages of
+ pkfix are written to standard error output.
+2005/02/25 v1.3:
+ * Bug fix: Detection of "@fedspecial end" improved.
+ * Bug fix: Typo corrected (PRT -> $PRT).
+2007/11/07 v1.4:
+ * Deprecation warning of perl 5.8.8 fixed.
+2009/03/18 v1.5:
+ * Patch to support dvips 5.399 (submitted by Melissa O'Neill).
diff --git a/Master/texmf-dist/scripts/pkfix/pkfix.pl b/Master/texmf-dist/scripts/pkfix/pkfix.pl
new file mode 100755
index 00000000000..52e4d7698e8
--- /dev/null
+++ b/Master/texmf-dist/scripts/pkfix/pkfix.pl
@@ -0,0 +1,872 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' && eval 'exec perl -S $0 $argv:q'
+ if 0;
+use strict;
+$^W=1; # turn warning on
+#
+# pkfix.pl
+#
+# Copyright (C) 2001, 2005, 2007, 2009 Heiko Oberdiek.
+#
+# This work may be distributed and/or modified under the
+# conditions of the LaTeX Project Public License, either version 1.3
+# of this license or (at your option) any later version.
+# The latest version of this license is in
+# http://www.latex-project.org/lppl.txt
+# and version 1.3 or later is part of all distributions of LaTeX
+# version 2003/12/01 or later.
+# This work has the LPPL maintenance status "maintained".
+# This Current Maintainer of this work is Heiko Oberdiek.
+#
+# See file "README" for a list of files that belongs to this project.
+#
+# This file "pkfix.pl" may be renamed to "pkfix"
+# for installation purposes.
+#
+my $file = "pkfix.pl";
+my $program = uc($&) if $file =~ /^\w+/;
+my $project = lc($program);
+my $version = "1.5";
+my $date = "2009/03/18";
+my $author = "Heiko Oberdiek";
+my $copyright = "Copyright (c) 2001, 2005, 2007, 2009 by $author.";
+#
+# Reqirements: Perl5, dvips
+# History:
+# 2001/04/12 v0.1:
+# * First try.
+# 2001/04/13 v0.2:
+# * TeX/dvips is called for each font for the case of errors.
+# * First release.
+# 2001/04/15 v0.3:
+# * Call of kpsewhich with option --progname.
+# * Extracting of texps.pro from temporary PostScript file,
+# if kpsewhich failed.
+# * Option -G0 for dvips run added.
+# 2001/04/16 v0.4:
+# * Support for merging PostScript fonts added.
+# * \special{!...}/@fedspecial detection added.
+# * Bug fix: I detection.
+# 2001/04/17 v0.5:
+# * Redirection of stderr (dvips run) if possible.
+# 2001/04/20 v0.6:
+# * Bug fix: dvips font names can contain numbers.
+# 2001/04/21 v0.7:
+# * Bug fix: long dvi file name in ps file.
+# 2001/04/23 v0.8:
+# * Bug fix: post string parsing.
+# 2001/04/26 v0.9:
+# * Check of version number of dvips in PostScript file.
+# 2001/06/30 v1.0:
+# * Problem with DOS line endings fixed.
+# 2005/01/28 v1.1:
+# * Bug fix: encoding files are now included also.
+# * The intermediate DVI files are written directly.
+# * LPPL 1.3
+# 2005/01/29 v1.2:
+# * Merging is now based on type 1 names. This solves
+# the problem, if different bitmap fonts maps to the
+# same type 1 font, eg. (ecrm1000, larm1000) -> SFRM1000.
+# * Suppression of PK generation, if environment variable
+# MKTEXPK is supported.
+# * If output file is "-" (standard output) then messages of
+# pkfix are written to standard error output.
+# 2005/02/25 v1.3:
+# * Bug fix: Detection of "@fedspecial end" improved.
+# * Bug fix: Typo corrected (PRT -> $PRT).
+# 2007/11/07 v1.4:
+# * Deprecation warning of perl 5.8.8 fixed.
+# 2009/03/18 v1.5:
+# * Patch to support dvips 5.399 (submitted by Melissa O'Neill).
+#
+### program identification
+my $title = "$program $version, $date - $copyright\n";
+
+### error strings
+my $Error = "!!! Error:"; # error prefix
+my $Warning = "!!! Warning:"; # warning prefix
+
+### variables
+my $envvar = uc($project);
+my $infile = "";
+my $outfile = "";
+my $texpsfile = "texps.pro";
+my $prefix = "_${project}_$$";
+# my $prefix = "_${project}_";
+my $tempfile = "$prefix";
+my $texfile = "$tempfile.tex";
+my $dvifile = "$tempfile.dvi";
+my $logfile = "$tempfile.log";
+my $psfile = "$tempfile.ps";
+my $missfile = "missfont.log";
+my @cleanlist = ($dvifile, $psfile);
+push(@cleanlist, $missfile) unless -f $missfile;
+
+my $err_redirect = " 2>&1";
+$err_redirect = "" if $^O =~ /dos/i ||
+ $^O =~ /os2/i ||
+ $^O =~ /mswin32/i ||
+ $^O =~ /cygwin/i;
+
+my $x_resolution = 0;
+my $y_resolution = 0;
+my $blocks_found = 0;
+my $fonts_converted = 0;
+my $fonts_merged = 0;
+my $fonts_misses = 0;
+my $PRT = \*STDOUT;
+
+### option variables
+my @bool = ("false", "true");
+$::opt_tex = "tex";
+$::opt_dvips = "dvips";
+$::opt_kpsewhich = "kpsewhich --progname $project";
+$::opt_options = "-Ppdf -G0";
+$::opt_usetex = 0;
+$::opt_help = 0;
+$::opt_quiet = 0;
+$::opt_debug = 0;
+$::opt_verbose = 0;
+$::opt_clean = 1;
+
+my $usage = <<"END_OF_USAGE";
+${title}Syntax: \L$program\E [options] <inputfile.ps> <outputfile.ps>
+Function: This program tries to replace pk fonts in <inputfile.ps>
+ by the type 1 versions. The result is written in <outputfile.ps>.
+Options: (defaults:)
+ --help print usage
+ --(no)quiet suppress messages ($bool[$::opt_quiet])
+ --(no)verbose verbose printing ($bool[$::opt_verbose])
+ --(no)debug debug informations ($bool[$::opt_debug])
+ --(no)clean clear temp files ($bool[$::opt_clean])
+ --(no)usetex use TeX for generating the DVI file ($bool[$::opt_usetex])
+ --tex texcmd tex command name (plain format) ($::opt_tex)
+ --dvips dvipscmd dvips command name ($::opt_dvips)
+ --options opt dvips options ($::opt_options)
+END_OF_USAGE
+
+### environment variable PKFIX
+if ($ENV{$envvar}) {
+ unshift(@ARGV, split(/\s+/, $ENV{$envvar}));
+}
+
+### process options
+my @OrgArgv = @ARGV;
+use Getopt::Long;
+GetOptions(
+ "help!",
+ "quiet!",
+ "debug!",
+ "verbose!",
+ "clean!",
+ "usetex!",
+ "tex=s",
+ "dvips=s",
+ "options=s"
+) or die $usage;
+!$::opt_help or die $usage;
+@ARGV < 3 or die "$usage$Error Too many files!\n";
+@ARGV == 2 or die "$usage$Error Missing file names!\n";
+
+$::opt_quiet = 0 if $::opt_verbose;
+$::opt_clean = 0 if $::opt_debug;
+
+push(@cleanlist, $texfile, $logfile) if $::opt_usetex;
+
+### get file names
+$infile = $ARGV[0];
+$outfile = $ARGV[1];
+
+### suppress PK generation
+$ENV{'MKTEXPK'} = "0";
+
+$PRT = \*STDERR if $outfile eq "-";
+
+print $PRT $title unless $::opt_quiet;
+
+print $PRT "*** input file: `$infile'\n" if $::opt_verbose;
+print $PRT "*** output file: `$outfile'\n" if $::opt_verbose;
+
+if ($::opt_debug) {
+ print $PRT <<"END_DEB";
+*** OSNAME: $^O
+*** PERL_VERSION: $]
+*** ARGV: @OrgArgv
+END_DEB
+}
+
+### get texps.pro
+my $texps_data = 0;
+my $texps_string = get_texps_pro();
+
+### Encoding definitions
+my %encoding_files = ();
+my $encoding_string = "";
+
+### open input and output files
+open(IN, $infile) or die "$Error Cannot open `$infile'!\n";
+open(OUT, ">$outfile") or die "$Error Cannot write `$outfile'!\n";
+
+##################################
+# expected format:
+# ...
+# %%DVIPSParameters:... dpi=([\dx]+)...
+# ...
+# TeXDict begin \d+ \d+ \d+ \d+ \d+ \(\S+\)
+# @start ...
+# ...
+# %DVIPSBitmapFont: (\S+) (\S+) ([\d\.]+) (\d+)
+# /(\S+) ...
+# ...
+# %EndDVIPSBitmapFont
+# ...
+# ... end
+# %%EndProlog
+#
+# or if \special{!...} was used, the lines with TeXDict:
+# TeXdict begin @defspecial
+#
+# ...
+#
+# @fedspecial end TeXDict begin
+# \d+ \d+ \d+ \d+ \d+ \(\S+\) @start
+#
+# or
+# @fedspecial end
+# ...
+#
+# bitmap font:
+# start:
+# %%DVIPSBitmapFont: {dvips font} {font name} {at x pt} {chars}
+# /{dvips font} {chars} {max. char number + 1} df
+# character, variant a:
+# <{hex code}>{char number} D
+# character, variant b:\
+# [<{hex code}>{num1} {num2} {num3} {num4} {num5} {char number} D
+# end:
+# E
+# %%EndDVIPSBitmapFont
+#
+# type 1 font:
+# before TeXDict line:
+# %%BeginFont: CMR10
+# ...
+# %%EndFont
+# after @start:
+# /Fa ... /CMR10 rf
+#
+# Font names: /[F-Z][a-zA-Z0-9]
+#
+# Encoding files before texps.pro:
+# %%BeginProcSet: {file name}.enc 0 0
+# ...
+# %%EndProcSet
+#
+# Melissa O'Neill reported small variations for dvips 5.399:
+# TeXDict begin \d+ \d+ \d+
+# and
+# \d+ \d+ \d+ \(\d+\) @start
+#
+###################################
+
+my $x_comment_resolution = 0;
+my $y_comment_resolution = 0;
+my $start_string = "";
+my $post_string = "";
+my $dvips_resolution = "";
+my $texps_found = 0;
+my @font_list = ();
+my %font_txt = ();
+my %font_count = ();
+my %font_entry = ();
+
+sub init {
+ $x_comment_resolution = 0;
+ $y_comment_resolution = 0;
+ $x_resolution = 0;
+ $y_resolution = 0;
+ $start_string = "";
+ $texps_found = 0;
+ @font_list = ();
+ %font_txt = ();
+ %font_count = ();
+ %font_entry = ();
+}
+
+init();
+
+while (<IN>) {
+
+ if (/^%%Creator: (dvips\S*) (\S+)\s/) {
+ print $PRT "*** %%Creator: $1 $2\n" if $::opt_debug;
+ my $foundversion = $2;
+ if ($foundversion =~ /(\d+\.\d+)/) {
+ $foundversion = $1;
+ # 5.62 is ok, 5.58 does not produce font comments
+ if ($foundversion <= 5.58) {
+ print $PRT "$Warning dvips version $1 does not generate " .
+ "the required font comments!\n";
+ }
+ }
+ }
+
+ if (/^%%BeginProcSet:\s*(.+)\.enc/) {
+ $encoding_files{$1} = "";
+ }
+
+ if (/^%DVIPSParameters:.*dpi=([\dx]+)/) {
+ print OUT;
+ my $str = $1;
+ $x_comment_resolution = 0;
+ $y_comment_resolution = 0;
+ if ($str =~ /^(\d+)x(\d+)$/) {
+ $x_comment_resolution = $1;
+ $y_comment_resolution = $2;
+ }
+ if ($str =~ /^(\d+)$/) {
+ $x_comment_resolution = $1;
+ $y_comment_resolution = $1;
+ }
+ print $PRT "*** %DVIPSParameters: dpi=$str " .
+ "(x=$x_comment_resolution, y=$y_comment_resolution)\n"
+ if $::opt_debug;
+ $x_comment_resolution > 0 && $y_comment_resolution > 0 or
+ die "$Error Wrong resolution value " .
+ "($x_comment_resolution x $y_comment_resolution)!\n";
+ next;
+ }
+
+ if (/^%%BeginProcSet: texps.pro/) {
+ $texps_found = 1;
+ print $PRT "*** texps.pro found\n" if $::opt_debug;
+ }
+
+ if (/^TeXDict begin \@defspecial/) {
+ my $saved = $_;
+ print $PRT "*** \@defspecial found.\n" if $::opt_debug;
+ $start_string = $_;
+ while (<IN>) {
+ $start_string .= $_;
+ if (/^\@fedspecial end/) {
+ s/^\@fedspecial end\s*(\S)/$1/;
+ last;
+ }
+ }
+ }
+ elsif (/^TeXDict begin \d+ \d+ \d+ \d+ \d+/) {
+ print $PRT "*** TeXDict begin <5 nums> found.\n" if $::opt_debug;
+ $start_string = $_;
+ }
+ elsif (/^TeXDict begin \d+ \d+ \d+/) { # dvips 5.399
+ print $PRT "*** TeXDict begin <3 nums> found.\n" if $::opt_debug;
+ $start_string = $_;
+ }
+ if ($start_string ne "") {
+ # look for @start
+ unless (/\@start/) {
+ while (<IN>) {
+ $start_string .= $_;
+ last if /\@start/;
+ }
+ }
+
+ # divide post part
+ $start_string =~ /^([\s\S]*\@start)\s*([\s\S]*)$/ or
+ die "$Error Parse error (\@start)!\n";
+ $start_string = "$1\n";
+ $post_string = $2;
+ $post_string =~ s/\s*$//;
+ $post_string .= "\n" unless $post_string eq "";
+
+ $start_string =~
+ /\d+\s+\d+\s+\d+\s+(\d+)\s+(\d+)\s+\((.*)\)\s+\@start/ or
+ /\d+\s+(\d+)\s+(\d+)\s+\@start/ or # dvips 5.399
+ die "$Error Parse error (\@start parameters)!\n";
+
+ $blocks_found++;
+ print $PRT "*** dvi file: $3\n" if $::opt_debug and defined $3;
+
+ # get and check resolution values
+ $x_resolution = $1;
+ $y_resolution = $2;
+ print $PRT "*** resolution: $x_resolution x $y_resolution\n"
+ if $::opt_debug;
+ $x_comment_resolution > 0 or
+ die "$Error Missing comment `%DVIPSParameters'!\n";
+ $x_resolution == $x_comment_resolution &&
+ $y_resolution == $y_comment_resolution or
+ die "$Error Resolution values in comment and PostScript " .
+ "does not match!\n";
+ # setting dvips resolution option(s)
+ if ($x_resolution == $y_resolution) {
+ $dvips_resolution = "-D $x_resolution";
+ }
+ else {
+ $dvips_resolution = "-X $x_resolution -Y $y_resolution";
+ }
+
+ while (<IN>) {
+ if (/^%%EndProlog/) {
+ print OUT $encoding_string;
+ $texps_data > 0 or die "$Error File `texps.pro' not found!\n";
+ print OUT $texps_string unless $texps_found;
+ foreach (@font_list) {
+ my $fontname = $_;
+ print $PRT "*** Adding font `$fontname'\n"
+ if $::opt_debug;
+ my ($dummy1, $dummy2, $err);
+ if ($font_count{$fontname} > 1) {
+ $fonts_merged++;
+ print $PRT "*** Merging font `$fontname' ($font_count{$fontname}).\n"
+ unless $::opt_quiet;
+ ($dummy1, $font_txt{$fontname}, $dummy2, $err) =
+ get_font($font_entry{$fontname});
+ $err == 0 or die "$Error Cannot merge font `$fontname'!\n";
+ }
+ print OUT $font_txt{$fontname};
+ }
+ print OUT $start_string,
+ $post_string,
+ $_;
+ print $PRT "*** %%EndProlog\n" if $::opt_debug;
+ init();
+ last;
+ }
+
+ if (/^%DVIPSBitmapFont: (\S+) (\S+) ([\d.]+) (\d+)/) {
+ my $bitmap_string = $_;
+ my $dvips_fontname = $1;
+ my $fontname = $2;
+ my $entry = "\\Font\{$1\}\{$2\}\{$3\}\{";
+ print $PRT "*** Font $1: $2 at $3pt, $4 chars\n" if $::opt_verbose;
+ my $line = "";
+ my $num = -1;
+ my $chars = $4;
+ my $count = 0;
+ while (<IN>) {
+ $bitmap_string .= $_;
+ last if /^%EndDVIPSBitmapFont/;
+ s/\r$//; # remove \r of possible DOS line ending
+ chomp;
+ $line .= " " . $_;
+ }
+ $line =~ s/<[0-9A-F ]*>/ /g;
+
+ print $PRT "*** <Font> $line\n" if $::opt_debug;
+
+ while ($line =~ /\s(\d+)\s+D(.*)/) {
+ $num = $1;
+ $count++;
+ $entry .= "$num,";
+ $line = $2;
+ while ($line =~ /^[\s\d\[]*I(.*)/) {
+ $num++;
+ $count++;
+ $entry .= "$num,";
+ $line = $1;
+ }
+ }
+ $chars == $count or
+ die "$Error Parse error, $count chars of $chars found " .
+ "($fontname)!\n";
+
+ $entry =~ s/,$//;
+ $entry .= "\}";
+
+ print $PRT "*** Font conversion of `$fontname' started.\n"
+ if $::opt_verbose;
+ my ($newfontname, $font_part, $start_part, $err) = get_font($entry);
+ if ($err == 0) {
+ print $PRT "*** Font conversion: `$fontname' -> `$newfontname'.\n"
+ unless $::opt_quiet;
+ if (defined($font_count{$newfontname})) {
+ $font_count{$newfontname}++;
+ $font_entry{$newfontname} .= "\n$entry";
+ }
+ else {
+ push @font_list, $newfontname;
+ $font_txt{$newfontname} = $font_part;
+ $font_count{$newfontname} = 1;
+ $font_entry{$newfontname} = $entry;
+ }
+ $start_part =~ s/\/Fa/\/$dvips_fontname/;
+ $start_string .= $start_part;
+ $fonts_converted++;
+ }
+ else {
+ print $PRT "!!! Failed font conversion of `$fontname'!\n";
+ $start_string .= $bitmap_string;
+ $fonts_misses++;
+ }
+
+ next;
+ }
+
+ $post_string .= $_;
+ }
+ next;
+ }
+
+ print OUT;
+}
+
+close(IN);
+close(OUT);
+
+if ($::opt_clean) {
+ print $PRT "*** clear temp files\n" if $::opt_verbose;
+ map {unlink} @cleanlist;
+}
+
+if (!$::opt_quiet) {
+ if ($blocks_found > 1) {
+ print $PRT "==> $blocks_found blocks.\n";
+ }
+ if ($fonts_misses) {
+ print $PRT "==> $fonts_misses font conversion",
+ (($fonts_misses > 1) ? "s" : ""),
+ " failed.\n";
+ }
+ if ($fonts_converted) {
+ print $PRT "==> ",
+ (($fonts_converted > 0) ? $fonts_converted : "No"),
+ " converted font",
+ (($fonts_converted > 1) ? "s" : ""),
+ ".\n";
+ if ($fonts_merged) {
+ print $PRT "==> $fonts_merged merged font",
+ (($fonts_merged > 1) ? "s" : ""),
+ ".\n";
+ }
+ }
+ else {
+ print $PRT "==> no fonts converted\n";
+ }
+}
+
+
+# get type 1 font
+# param: $entry: font entry as TeX string
+# return: $name: type 1 font name
+# $font: font file as string
+# $start: font definition after @start
+# $err: error indication
+sub get_font {
+ my $entry = shift;
+ my $name = "";
+ my $font = "";
+ my $start = "";
+ my $err = 0;
+ my @err = ("", "", "", 1);
+ local *OUT;
+ local *IN;
+
+ if ($::opt_usetex) {
+ ### write temp tex file
+ open(OUT, ">$texfile") or die "$Error Cannot write `$texfile'!\n";
+ print OUT <<'TEX_HEADER';
+\nonstopmode
+\nopagenumbers
+\def\Font#1#2#3#4{%
+ \expandafter\font\csname font@#1\endcsname=#2 at #3pt\relax
+ \csname font@#1\endcsname
+ \hbox to 0pt{%
+ \ScanChar#4,\NIL
+ \hss
+ }%
+}
+\def\ScanChar#1,#2\NIL{%
+ \char#1\relax
+ \ifx\\#2\\%
+ \else
+ \ReturnAfterFi{%
+ \ScanChar#2\NIL
+ }%
+ \fi
+}
+\long\def\ReturnAfterFi#1\fi{\fi#1}
+\noindent
+TEX_HEADER
+
+ print OUT "$entry\n\\bye\n";
+ close(OUT);
+
+ ### run tex
+ {
+ print $PRT "*** run TeX\n" if $::opt_verbose;
+
+ my $cmd = "$::opt_tex $tempfile";
+ print $PRT ">>> $cmd\n" if $::opt_verbose;
+ my @capture = `$cmd`;
+ if (!@capture) {
+ print $PRT "$Warning Cannot execute TeX!\n";
+ return @err;
+ }
+ if ($::opt_verbose) {
+ print $PRT @capture;
+ }
+ else {
+ foreach (@capture) {
+ print $PRT if /^!\s/;
+ }
+ }
+ if ($?) {
+ my $exitvalue = $?;
+ if ($exitvalue > 255) {
+ $exitvalue >>= 8;
+ print $PRT "$Warning Closing TeX (exit status: $exitvalue)!\n";
+ return @err;
+ }
+ print $PRT "$Warning Closing TeX ($exitvalue)!\n";
+ return @err;
+ }
+ }
+ }
+ else {
+ # write dvi directly
+
+ # DVI format description: dvitype.web
+ my $DVI_pre = 247;
+ my $DVI_id_byte = 2;
+ my $DVI_num = 25400000;
+ my $DVI_den = 473628672; # 7227 * 2^16
+ my $DVI_mag = 1000;
+ my @t = localtime(time);
+ my $DVI_comment = "$program $version output "
+ . sprintf("%04d/%02d/%02d %02d:%02d:%02d",
+ ($t[5] + 1900), ($t[4] + 1), $t[3], $t[2], $t[1], $t[0]);
+ my $DVI_comment_len = length($DVI_comment);
+ my $DVI_bop = 139;
+ my $DVI_eop = 140;
+ my $DVI_fontdef1 = 243;
+ my $DVI_fontdef2 = 244;
+ my $DVI_fontdef4 = 246;
+ my $DVI_design_size = 10; # an arbitrary value
+ # A wrong value will trigger a dvips warning
+ # (it can be seen in verbose mode):
+ # dvips: Design size mismatch in [...].tfm
+ # But other consequences could not be noticed.
+ # Thus a TFM lookup will be saved.
+ my $DVI_checksum = 0; # because of unknown checksum
+ my $DVI_fnt_num_0 = 171;
+ my $DVI_fnt1 = 235;
+ my $DVI_fnt2 = 236;
+ my $DVI_fnt4 = 238;
+ my $DVI_set1 = 128;
+ my $DVI_push = 141;
+ my $DVI_pop = 142;
+ my $DVI_post = 248;
+ my $DVI_u = 67108864; # 1024 pt, an arbitrary value
+ my $DVI_l = 67108864; # 1024 pt, an arbitrary value
+ my $DVI_post_post = 249;
+ my $DVI_trailing = 223;
+
+ open(OUT, ">$dvifile") or die "$Error Cannot write `$dvifile'!\n";
+ binmode(OUT);
+
+ # Preamble (pre)
+ print OUT pack("C2N3Ca$DVI_comment_len",
+ $DVI_pre, $DVI_id_byte, $DVI_num, $DVI_den, $DVI_mag,
+ $DVI_comment_len, $DVI_comment);
+ # Begin of page (bop)
+ my $pos_bop = tell(OUT);
+ print OUT pack("CN1x[N9]l", $DVI_bop, 1, -1);
+
+ my $font_defs = "";
+ my $font_num = 0;
+ foreach(split("\n", $entry)) {
+ my $font_def = "";
+ /\\Font\{[^}]*\}\{([^}]*)\}\{([^}]*)\}\{([^}]*)\}/ or
+ die "!!! Error: Internal parsing error!\n";
+ my $font_name = $1;
+ my $font_name_len = length($font_name);
+ my $font_size = $2;
+ my $font_chars = $3;
+
+ # define font
+ if ($font_num < 256) {
+ $font_def = pack("CC", $DVI_fontdef1, $font_num);
+ }
+ # The other cases are very unlikely, especially there are
+ # more than one font in the merging case only.
+ elsif ($font_num < 65536) {
+ $font_def = pack("Cn", $DVI_fontdef2, $font_num);
+ }
+ else {
+ $font_def = pack("CN", $DVI_fontdef4, $font_num);
+ }
+ $font_def .= pack("x[N]N2xCa$font_name_len",
+ ($font_size * 65536), $DVI_design_size,
+ $font_name_len, $font_name);
+ print OUT $font_def;
+ $font_defs .= $font_def;
+
+ # use font
+ my $fnt_num;
+ if ($font_num < 64) {
+ $fnt_num = pack("C", $DVI_fnt_num_0 + $font_num);
+ }
+ # Other cases are unlikely, see above.
+ elsif ($font_num < 256) {
+ $fnt_num = pack("CC", $DVI_fnt1, $font_num);
+ }
+ elsif ($font_num < 65536) {
+ $fnt_num = pack("Cn", $DVI_fnt2, $font_num);
+ }
+ else {
+ $fnt_num = pack("CN", $DVI_fnt4, $font_num);
+ }
+ print OUT $fnt_num;
+
+ # print characters
+ print OUT pack("C", $DVI_push);
+ foreach (split(",", $font_chars)) {
+ if ($_ < 128) {
+ print OUT pack("C", $_);
+ }
+ else {
+ print OUT pack("CC", $DVI_set1, $_);
+ }
+ }
+ print OUT pack("C", $DVI_pop);
+
+ $font_num++;
+ }
+
+ print OUT pack("C", $DVI_eop);
+
+ # Begin of postamble (post)
+ my $pos_post = tell(OUT);
+ print OUT pack("CN6n2",
+ $DVI_post, $pos_bop, $DVI_num, $DVI_den, $DVI_mag,
+ $DVI_l, $DVI_u, 1, 1);
+ print OUT $font_defs;
+ # End of postamble (post_post)
+ print OUT pack("CNC5",
+ $DVI_post_post, $pos_post, $DVI_id_byte,
+ $DVI_trailing, $DVI_trailing, $DVI_trailing, $DVI_trailing);
+ my $t_num = (4 - (tell(OUT) % 4)) % 4;
+ print OUT pack("C", $DVI_trailing) x $t_num;
+ close(OUT);
+ }
+
+ ### run dvips
+ {
+ print $PRT "*** run dvips\n" if $::opt_verbose;
+
+ my $cmd = "$::opt_dvips $::opt_options $dvips_resolution $tempfile";
+ print $PRT ">>> $cmd\n" if $::opt_verbose;
+ # dvips writes on stderr :-(
+ my @capture = `$cmd$err_redirect`;
+ if ($::opt_verbose) {
+ print $PRT @capture;
+ }
+ if ($?) {
+ my $exitvalue = $?;
+ if ($exitvalue > 255) {
+ $exitvalue >>= 8;
+ print $PRT "$Warning Closing dvips (exit status: $exitvalue)!\n";
+ return @err;
+ }
+ print $PRT "$Warning Closing dvips ($exitvalue)!\n";
+ return @err;
+ }
+ }
+
+ ### get font and start part
+ open(IN, $psfile) or die "$Error Cannot open `$psfile'!\n";
+
+ while (<IN>) {
+ ### get possible encoding files
+ if (/^%%BeginProcSet:\s*(.+)\.enc/) {
+ my $encoding_file = $1;
+ print $PRT "*** encoding file `$encoding_file.enc' found.\n"
+ if $::opt_debug;
+ next if defined($encoding_files{$encoding_file});
+ $encoding_files{$encoding_file} = "";
+ $encoding_string .= $_;
+ while (<IN>) {
+ $encoding_string .= $_;
+ last if /^%%EndProcSet/;
+ }
+ next;
+ }
+
+ ### get texps.pro if get_texps_pro() has failed
+ if ($texps_data == 0 && /^%%BeginProcSet: texps.pro/) {
+ $texps_string = $_;
+ while (<IN>) {
+ $texps_string .= $_;
+ last if /^%%EndProcSet/;
+ }
+ $texps_data = 1;
+ print $PRT "*** texps.pro extracted.\n" if $::opt_debug;
+ next;
+ }
+
+ if (/^%%BeginFont:\s*(\S+)/) {
+ $name = $1;
+ $font .= $_;
+ while (<IN>) {
+ $font .= $_;
+ last if /^%%EndFont/;
+ }
+ next;
+ }
+ if (/^\@start/) {
+ s/^\@start\s*//;
+ $start .= $_;
+ while (<IN>) {
+ last if /^%%EndProlog/;
+ $start .= $_;
+ }
+ if (($start =~ s/\s*end\s*$/\n/) != 1) {
+ $err = 1;
+ print $PRT "$Warning Parse error, `end' not found!\n";
+ }
+ print $PRT "*** start: $start" if $::opt_debug;
+ last;
+ }
+ }
+ close(IN);
+
+ if ($font eq "") {
+ print $PRT "$Warning `%%BeginFont' not found!\n";
+ return @err;
+ }
+ return ($name, $font, $start, $err);
+}
+
+
+# get_texps_pro
+# return: string with content of texps.pro
+sub get_texps_pro {
+ $texps_data = 0;
+ # get file name
+ my $backupWarn = $^W;
+ $^W = 0;
+ my $file = `$::opt_kpsewhich $texpsfile`;
+ $^W = $backupWarn;
+ if (!defined($file) or $file eq "") {
+ print $PRT "$Warning: Cannot find `$texpsfile' with kpsewhich!\n"
+ if $::opt_debug;
+ return "";
+ }
+ chomp $file;
+ print $PRT "*** texps.pro: $file\n" if $::opt_debug;
+
+ # read file
+ local *IN;
+ open(IN, $file) or die "$Error: Cannot open `$file'!\n";
+ my @lines = <IN>;
+ @lines > 0 or die "$Error: Empty file `$file'!\n";
+ chomp $lines[@lines-1];
+ my $str = "%%BeginProcSet: texps.pro\n";
+ $"="";
+ $str .= "@lines\n";
+ $"=" ";
+ $str .= "%%EndProcSet\n";
+ $texps_data = 1;
+ return $str;
+}
+
+__END__