diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /info/maketexwork/ex-D-01 |
Initial commit
Diffstat (limited to 'info/maketexwork/ex-D-01')
-rw-r--r-- | info/maketexwork/ex-D-01 | 568 |
1 files changed, 568 insertions, 0 deletions
diff --git a/info/maketexwork/ex-D-01 b/info/maketexwork/ex-D-01 new file mode 100644 index 0000000000..391127e360 --- /dev/null +++ b/info/maketexwork/ex-D-01 @@ -0,0 +1,568 @@ +#!/usr/local/bin/perl +# +# MakeTeXPK.pl version 1.0, Copyright (C) 1993,94 by Norman Walsh. +# NO WARRANTY. Distribute freely under the GNU GPL. +# +# This script attempts to make a new TeX PK font, because one wasn't +# found. Parameters are: +# +# name dpi bdpi [[[magnification] mode] subdir] +# +# `name' is the name of the font, such as `cmr10' (*NOT* cmr10.mf). +# `dpi' is the resolution the font is needed at. +# `bdpi' is the base resolution, useful for figuring out the mode to +# make the font in. +# `magnification' is a string to pass to MF as the magnification. +# `mode' if supplied, is the mode to use. +# +# This script was designed with two goals in mind: to support recursive +# subdirectory searching for fonts and to provide support for PK files +# built from both MF fonts and PS fonts. It also supports the Sauter +# and DC fonts which can be built at any design size. +# +# This script was designed and tested with the following directory structure +# in mind: each typeface is stored in its own directory with appropriate +# subdirectories for font sources, metrics, and glyphs. The script may not +# work exactly right if you use a different directory structure (the font +# installation, in particular, will probably be incorrect). However, +# several other versions of MakeTeXPK exist which will handle simpler +# directory structures, so you need not feel compelled to use the one +# described here. +# +# For MF fonts: (... is usually something like /usr/local/lib/tex/fonts) +# +# .../typeface/src holds the sources +# /tfm holds the TFM files +# /glyphs root for glyphs +# /glyphs/mode holds the PK files for "mode". +# +# For PS fonts: (... is usually something like /usr/local/lib/tex/fonts) +# +# .../typeface/afm holds the AFM files +# /tfm holds the TFM files +# /vf holds the VF files +# /vpl holds the VPL files +# /glyphs root for glyphs +# /glyphs/pk/999dpi holds the PK files at 999 dpi created by ps2pk +# /glpyhs/type1 holds the type1 PFA/PFB sources for the fonts +# + +require "getopts.pl"; +$rc = &Getopts ('v'); # Get options from the user... + +$USE_MODE_IN_DEST = 1; # Does the destination directory name include + # the name of the mode? + +$VERBOSE = $opt_v || $ENV{"DEBUG_MAKETEXPK"}; # Verbose? + +chop($CWD = `pwd`); # Where are we? +$TEMPDIR = "/tmp/mkPK.$$"; # Where do temp files go? +$MFBASE = "&plain"; # What MF base do we use by default? + +# Where are fonts stored? +$TEXFONTS = $ENV{"TEXFONTS"} || ".:/usr/local/lib/fonts//"; + +# Define modes that should be used for base resolutions... +$DPI_MODES{300} = "laserwriter"; +$DPI_MODES{200} = "FAX"; +$DPI_MODES{360} = "lqhires"; +$DPI_MODES{400} = "nexthi"; +$DPI_MODES{600} = "QMSmoa"; +$DPI_MODES{100} = "nextscreen"; + +$DPI_MODES{100} = "videodisplayi"; +$DPI_MODES{110} = "videodisplayii"; +$DPI_MODES{118} = "videodisplayiii"; +$DPI_MODES{120} = "videodisplayiv"; +$DPI_MODES{124} = "videodisplayv"; +$DPI_MODES{130} = "videodisplayvi"; +$DPI_MODES{140} = "videodisplayvii"; +$DPI_MODES{150} = "videodisplayviii"; + +$DPI_MODES{72} = "MacTrueSize"; +$DPI_MODES{635} = "linolo"; +$DPI_MODES{1270} = "linohi"; +$DPI_MODES{2540} = "linosuper"; + +# Where are the DC fonts stored and what base names can be used? +$DCR_DIR = '/usr/local/lib/fonts/free/dc/src'; +@DCR_GEN = ('dcb','dcbom','dcbx','dcbxsl','dcbxti','dccsc','dcdunh','dcff', + 'dcfi','dcfib','dcitt','dcr','dcsl','dcsltt','dcss','dcssbx', + 'dcssi','dctcsc','dcti','dctt','dcu','dcvtt' ); + +# Where are the Sauter fonts stored and what base names can be used? +$SAUTER_DIR = '/usr/local/lib/fonts/free/sauter/src'; +@SAUTER_GEN = ('cmb','cmbizx','cmbozx','cmbsy','cmbszx','cmbx','cmbxsl', + 'cmbxti', 'cmbz', 'cmbzx', 'cmcsc', 'cmdszc', 'cmdunh', + 'cmex', 'cmff', 'cmfi', 'cmfib', 'cminch', 'cmitt', 'cmmi', + 'cmmib', 'cmr', 'cmrcz', 'cmrisz', 'cmritz', 'cmriz', + 'cmrotz', 'cmroz', 'cmrsz', 'cmrtz', 'cmruz', 'cmrz', + 'cmsl', 'cmsltt', 'cmss', 'cmssbx', 'cmssdc', 'cmssi', + 'cmssq', 'cmssqi', 'cmsy', 'cmtcsc', 'cmtex', 'cmti', + 'cmtt', 'cmu', 'cmvtt', 'czinch', 'czssq', 'czssqi', + 'lasy', 'lasyb'); + +$SAUTER_ROUNDING{11} = '10.954451'; +$SAUTER_ROUNDING{14} = '14.4'; +$SAUTER_ROUNDING{17} = '17.28'; +$SAUTER_ROUNDING{20} = '20.736'; +$SAUTER_ROUNDING{25} = '24.8832'; +$SAUTER_ROUNDING{30} = '29.8685984'; + +# Get the command line arguments... +($NAME, $DPI, $BDPI, $MAG, $MODE, $FORCEDEST, $EXTRA) = @ARGV; + +open (TTY, ">/dev/tty"); # Open the TTY (so we can print messages +select (TTY); $| = 1; select(STDOUT); # even if STDERR and STDOUT are both + # redirected) + +if ($VERBOSE) { + print TTY "$0: font name: $NAME\n"; + print TTY "$0: dpi: $DPI\n"; + print TTY "$0: base dpi: $BDPI\n"; + print TTY "$0: magnification: $MAG\n" if $MAG; + print TTY "$0: mode: $MODE\n" if $MODE; + print TTY "$0: force destination directory: $FORCEDEST\n" if $FORCEDEST; + print TTY "$0: extra: $EXTRA\n" if $EXTRA; +} + +# Make sure we got enough arguments, but not too many... +die "$0: Invalid arguments.\n" if ($BDPI eq "" || $EXTRA ne ""); + +# Calculate the magnification from the requested resolutions if no +# magnification string was provided. +if (!$MAG) { + $MAG = "$DPI/$BDPI"; + print TTY "$0: magnification: $MAG\n" if $VERBOSE; +} + +# Calculate the mode if the mode was not given. Die if we don't know +# what mode to use for the requested base resolution. +if ($MODE eq "") { + $MODE = $DPI_MODES{$BDPI}; + die "$0: No mode for ${BDPI}dpi base resolution.\n" if $MODE eq ""; + print TTY "$0: mode: $MODE\n" if $VERBOSE; +} + +######################################################################## + +# Really start the work... +print TTY "Attempting to build PK file for: $NAME at ${DPI}dpi.\n"; + +$mfFile = $NAME; +$mfFile =~ /^(.*[^0-9])(\d+)$/; +$mfBase = $1; +$mfSize = $2; + +# Presumably, we got here because the PK file doesn't exist. Let's look +# for the MF file or the PFA or PFB file... + +# ... it's more complicated than that... + +# If the font is from a PFA/B file, it may have the name "rxxx" or +# "xxx0" because virtual fonts extract glyphs from the "raw" font. +# We need to find the PFA/B file and install the font with the right name. +# I'm not sure what the best solution would really be, but this will work. +# Luckily, it gets installed with the right name 'cause we already +# figured that out... +# +# A better solution on Unix machines might be to make "xxx0.pfa" or +# "rxxx.pfa" a symbolic link to "xxx.pfa". But that won't work for other +# architectures... + +$t1source = ""; +$t1source = $1 if $mfFile =~ /^r(.*)$/; +$t1source = $1 if $mfFile =~ /^(.*)0$/ && ($t1source eq ""); + +if ($t1source) { + $fontSource = &find_fonts($TEXFONTS, + ("$mfFile.mf", "$mfFile.pfa", "$mfFile.pfb", + "$t1source.pfa", "$t1source.pfb")); +} else { + $fontSource = &find_fonts($TEXFONTS, + ("$mfFile.mf", "$mfFile.pfa", "$mfFile.pfb")); +} + +if ($fontSource) { + if ($fontSource =~ /\.pfa$/ || $fontSource =~ /\.pfb$/) { + print TTY "Building PK file from PostScript source.\n"; + &make_and_cd_tempdir(); + &make_from_ps($fontSource); + } elsif ($fontSource =~ /\.mf$/) { + local($fpath, $fname); + print TTY "Building PK file from MF source.\n"; + &make_and_cd_tempdir(); + + if ($fontSource =~ /^(.*)\/([^\/]*)$/) { + $fpath = $1; + $fname = $2; + + $fpath = $CWD if $fpath eq "."; + $fpath = "$CWD/.." if $fpath eq ".."; + } else { + $fpath = ""; + $fname = $fontSource; + } + + &make_from_mf($fpath, $fname); + } else { + print TTY "$0: Cannot build PK font for $NAME.\n"; + print TTY " " x length($0), " Unprepared for $fontSource.\n"; + die "\n"; + } +} else { + if (grep(/^$mfBase$/, @DCR_GEN)) { + + print TTY "Building PK file from DC source.\n"; + + &make_and_cd_tempdir(); + + $MFBASE = "&dxbase"; + open (MFFILE, ">$mfFile.mf"); + print MFFILE "gensize:=$mfSize; generate $mfBase;\n"; + close (MFFILE); + + &make_from_mf("$DCR_DIR","$mfFile.mf"); + + } elsif (grep(/^$mfBase$/, @SAUTER_GEN)) { + + print TTY "Building PK file from Sauter source.\n"; + + &make_and_cd_tempdir(); + + if (defined($SAUTER_ROUNDING{$mfSize})) { + $designSize = $SAUTER_ROUNDING{$mfSize}; + } else { + $designSize = $mfSize; + } + + open (MFFILE, ">$mfFile.mf"); + print MFFILE "design_size := $designSize;\n"; + print MFFILE "input b-$mfBase;\n"; + close (MFFILE); + + &make_from_mf("$SAUTER_DIR","$mfFile.mf"); + + } else { + print TTY "$0: Cannot build PK file. Can't find source.\n"; + die "\n"; + } +} + +&cleanup(); + +exit 0; + +######################################################################## + +sub run { + local(@cmd) = @_; + local($rc); + + open (SAVEOUT, ">&STDOUT"); + open (SAVEERR, ">&STDERR"); + close (STDOUT); + open (STDOUT, ">&TTY"); + close (STDERR); + open (STDERR, ">&TTY"); + + # Chdir seems to return a funny exit code. So do it internally... + # (this is a hack) + if (@cmd[0] eq "chdir") { + $rc = chdir(@cmd[1]); + $rc = !$rc; + } else { + $rc = system(@cmd); + } + + close (STDOUT); + open (STDOUT, ">&SAVEOUT"); + close (SAVEOUT); + + close (STDERR); + open (STDERR, ">&SAVEERR"); + close (SAVEERR); + + if ($rc) { + printf TTY "%s\n", "*" x 72; + print TTY "$0 error : system return code: $rc\n"; + print TTY "$0 failed: @cmd\n"; + printf TTY "%s\n", "*" x 72; + } + + $rc; +} + +sub make_and_cd_tempdir { + &run ("mkdir", "$TEMPDIR"); + &run ("chdir", "$TEMPDIR"); +} + +sub cleanup { + &run ("chdir", "$CWD"); + &run ("rm", "-rf", "$TEMPDIR"); +} + +sub install_font { + local($source_path, $font, $subdir, $mode) = @_; + local($pkdirs, @paths, $ptarget); + local($target) = ""; + + if ($VERBOSE) { + print "Install: source_path: $source_path\n"; + print "Install: font : $font\n"; + print "Install: subdir : $subdir\n"; + print "Install: mode : $mode\n"; + } + + $pkdirs = $ENV{"TEXPKS"} || $ENV{"PKFONTS"} || ""; + @paths = split(/:|;/,$pkdirs); + + # Need to find an installable target for the PK files. Try + # ../glyphs/$subdir and ../$subdir then give up and use the best $pkdirs + # path... + + if (!$target) { + ($ptarget = $source_path) =~ s#/[^/]*$##; + $target = "$ptarget/glyphs/$subdir" + if -d "$ptarget/glyphs/$subdir" + || (-d "$ptarget/glyphs" + && -w "$ptarget/glyphs" + && ! -f "$ptarget/glyphs/$subdir"); + } + + if (!$target) { + ($ptarget = $source_path) =~ s#/[^/]*$##; + $target = "$ptarget/$subdir" + if -d "$ptarget/$subdir" + || (-d $ptarget && -w $ptarget && ! -f "$ptarget/$subdir"); + + # what a minute, suppose we just made a font in the current + # directory...let's put the PK file there too... + if (! -d "$target" && ($source_path eq $CWD)) { + $target = $source_path; + $USE_MODE_IN_DEST = 0; + } + } + + while (!$target && ($ptarget = shift @paths)) { + $target = $ptarget if ($ptarget ne "." && $ptarget ne ".." + && -d $ptarget && -w $ptarget); + } + + if ($target) { + if (! -d $target) { + &run ("mkdir", "$target"); + &run ("chmod", "777", "$target"); + } + + if ($USE_MODE_IN_DEST) { + $target .= "/$mode"; + if (! -d $target) { + &run ("mkdir", "$target"); + &run ("chmod", "777", "$target"); + } + } + + print TTY "Installing $font in $target.\n"; + &run ("cp", "$font", "$target/fonttmp.$$"); + &run ("chdir", "$target"); + &run ("mv", "fonttmp.$$", "$font"); + &run ("chmod", "a+r", "$font"); + &run ("chdir", "$TEMPDIR"); + print STDOUT "$target/$font\n"; + } else { + print TTY "$0: Install failed: no where to put $font.\n"; + } +} + +sub make_from_mf { + local ($source_path, $source_file) = @_; + local ($mfsource, $mfinputs, $cmd); + local ($gfname, $pkname, $realdpi, $testdpi); + local ($cmpath); + + print "source_path: $source_path\n" if $VERBOSE; + print "source_file: $source_file\n" if $VERBOSE; + + &run ("chdir", "$TEMPDIR"); + + if (!$source_file) { + $mfsource = $source_path; + ($source_path = $mfsource) =~ s#/[^/]*$##; + ($source_file = $mfsource) =~ s#^.*/([^/]*)$#$1#; + } + + $mfinputs = $ENV{"MFINPUTS"}; + $mfinputs =~ s/^:*(.*):*$/$1/ if $mfinputs; + $ENV{"MFINPUTS"} = ".:$source_path"; + $ENV{"MFINPUTS"} .= ":$mfinputs" if $mfinputs; + + print "MFINPUTS: $ENV{MFINPUTS}\n" if $VERBOSE; + + $cmpath = "/usr/local/lib/fonts/free/cm/src"; + if (-d $cmpath && $ENV{"MFINPUTS"} !~ /$cmpath/) { + $ENV{"MFINPUTS"} .= ":$cmpath"; + } + + $cmd = "$MFBASE \\mode:=$MODE; mag:=$MAG; scrollmode; " . + "\\input $source_file"; + print TTY "virmf $cmd\n"; + + $saveTERM = $ENV{"TERM"}; + $saveDISPLAY = $ENV{"DISPLAY"}; + delete $ENV{"DISPLAY"}; + $ENV{"TERM"} = "vt100"; + + $rc = &run ("virmf", "$cmd"); + + $ENV{"DISPLAY"} = $saveDISPLAY; + $ENV{"TERM"} = $saveTERM; + + $realdpi = $DPI; + $gfname = "./$mfFile.${realdpi}gf"; + + for ($testdpi = $realdpi-2; $testdpi < $realdpi+3; $testdpi++) { + $gfname = "./$mfFile.${testdpi}gf", $realdpi = $testdpi + if ! -f $gfname && -f "./$mfFile.${testdpi}gf"; + } + + $gfname = "./$mfFile.${realdpi}gf"; + $pkname = "./$mfFile.${realdpi}pk"; + + $rc = &run ("gftopk", "$gfname", "$pkname"); + + &install_font($source_path, "$mfFile.${realdpi}pk", 'pk', "$MODE"); +} + +sub make_from_ps { + local ($source_path, $source_file) = @_; + local ($pssource, @cmd); + local ($basename, $afmFile, $afmtest, $part); + + &run ("chdir", "$TEMPDIR"); + + if (!$source_file) { + $pssource = $source_path; + ($source_path = $pssource) =~ s#/[^/]*$##; + ($source_file = $pssource) =~ s#^.*/([^/]*)$#$1#; + } + + # Need to find the AFM file... + $afmFile = ""; + ($basename = $source_file) =~ s/\.pf[ab]$//; + # First, look in ../afm: + ($afmtest = $source_path) =~ s#/[^/]*$##; + $afmtest .= "/afm/$basename.afm"; + $afmFile = $afmtest if -r $afmtest; + + # Then, look in ../../afm: + ($afmtest = $source_path) =~ s#/[^/]*$##; + $afmtest =~ s#/[^/]*$##; + $afmtest .= "/afm/$basename.afm"; + $afmFile = $afmtest if !$afmFile && -r $afmtest; + + die "$0: Cannot find AFM file for $source_file.\n" if !$afmFile; + + @cmd = ('ps2pk', "-a$afmFile", "-X$DPI", + "$source_path/$source_file", "./$mfFile.${DPI}pk"); + + foreach $part (@cmd) { + print TTY "$part "; + } + print TTY "\n"; + + $rc = &run (@cmd); + + &install_font($source_path, "$mfFile.${DPI}pk", 'pk', "${DPI}dpi"); +} + +sub find_fonts { +# This subroutine searches for font sources. It looks in all the directories +# in the path specified. Recursive searches are preformed on directories +# that end in //, !, or !!. The emTeX directive "!", which should search +# only one level deep, is treated exactly like "!!". +# + local($path, @fonts) = @_; + local(@dirs, $dir, $font); + local(@matches) = (); + local(@recursive_matches); + + $path =~ s/!!/\/\//g; + $path =~ s/!/\/\//g; + $path =~ s/\\/\//g; + + print TTY "CWD: ", `pwd` if $VERBOSE; + print TTY "Find: @fonts\n" if $VERBOSE; + print TTY "Path: $path\n" if $VERBOSE; + + @dirs = split(/:|;/, $path); + while (@dirs) { + $dir = shift @dirs; + next if !$dir; + + if ($dir =~ /\/\//) { + @recursive_matches = &recursive_search($dir, @fonts); + push (@matches, @recursive_matches) + if @recursive_matches; + } else { + $dir =~ s/\/*$//; # remove trailing /, if present + foreach $font (@fonts) { + push (@matches, "$dir/$font") + if -f "$dir/$font"; + } + } + } + + $font = shift @matches; + + if (@matches) { + print TTY "$0: Found more than one match.\n"; + print TTY " " x length($0), " Using: $font\n"; + } + + $font; +} + +sub recursive_search { + local($dir, @fonts) = @_; + local(@matches) = (); + local(@dirstack, $rootdir, $font, $fontmask); + + $dir =~ /^(.*)\/\/(.*)$/; + $rootdir = $1; + $fontmask = $2; + + $rootdir =~ s/\/*$//; # remove trailing /'s + + # Note: this perl script has to scan them all, the mask is meaningless. + # Especially since I'm looking for the font *source* not the TFM or + # PK file... + + $fontmask =~ s/\$MAKETEX_BASE_DPI/$BDPI/g; + $fontmask =~ s/\$MAKETEX_MAG/$MAG/g; + $fontmask =~ s/\$MAKETEX_MODE/$MODE/g; + + print TTY "Search root=$rootdir\n" if $VERBOSE; + print TTY "Search mask=$fontmask (ignored by $0)\n" if $VERBOSE; + + @dirstack = ($rootdir); + + while ($rootdir = shift @dirstack) { + opendir (SEARCHDIR, "$rootdir"); + while ($dir = scalar(readdir(SEARCHDIR))) { + if ($dir ne "." && $dir ne ".." && -d "$rootdir/$dir") { + push(@dirstack, "$rootdir/$dir"); + foreach $font (@fonts) { + if (-f "$rootdir/$dir/$font") { + print TTY "Matched: $rootdir/$dir/$font\n" if $VERBOSE; + push(@matches, "$rootdir/$dir/$font"); + } + } + } + } + closedir (SEARCHDIR); + } + + @matches; +} |