[OS X TeX] ttf2tex (was Times New Roman)

Mark Moll mmoll at cs.cmu.edu
Fri May 10 22:32:26 CEST 2002



On 5/10/02 1:50 PM, Bruce D'Arcus wrote:
> For anyone interested in simple installation of ttf fonts, take a look at ttf2tex. The latest version (0.5, I think) can even deal with setting up real smallcaps and old-style figures that are in fonts like Hoefler Text. The only trick is to convert to PC format ttf before running the script.
> Hopefully someone can write a script to put this stuff all in a nice i-Package.

I have used the attached script successfully to install fonts. YMMV.
-- 
Mark

#!/usr/bin/perl
#
# Install type1 or truetype font for TeX.
#
# Nguyen-Dai Quy, <Quy at linuxbe.org>
# Sat Apr 22 14:25:35 CEST 2000
#
# This Perl script is based on "famtool.pl" of Sebastian Rahtz
#------------------------------------------------------------
# All fonts (truetype and type1) should be renamed after "Fontname"
# of K. Berry (http://tug.org/fontname)
#
# 1) By default, all files will be installed into :
# <outdir>/<foundry>/<shortname>/
#                               /afm/*.afm
#                               /tfm/*.tfm
#                               /tex/*.fd
#                               /dvips/*.map
#                               /type1/*.pfb
#                               /vf/*.vf
#
# 2) With option -tds, all files will be installed under TeX Directory 
Structure like
# <outdir>/fonts/
#               /afm/<foundry>/<shortname>/*.afm
#               /tfm/<foundry>/<shortname>/*.tfm
#               /type1/<foundry>/<shortname>/*.pfb
#               /vf/<foundry>/<shortname>/*.vf
# <outdir>/dvips/config/*.map
# <outdir>/tex/latex/psnfss/<foundry>/*.fd
#--------------------------------------------------------------
use Getopt::Long;
my ($opt_fam,$opt_outdir,$opt_ttf,$opt_unicode,$opt_h,$opt_v,$opt_fd,$opt_sn);
my ($opt_sans,$opt_tt,$opt_test,$day,$month,$year);
my ($Family,$Foundry,$ShortName);
my ($afm_dir,$tfm_dir,$type1_dir,$vf_dir,$dvips_dir,$tex_dir);

&GetParams();
&CheckFiles();
&CheckProgram();
&ReadFontNames();
&CheckNames();
&WriteTestFile();
exit if $opt_test;
&MakeDirs();
&BuildFileList();
&Run_ttf2pt1();
#exit;
&Run_fontinst();
&Run_pltotf();
&Run_vptovf();
&BuildFileList;
&WriteStyFile();
&WriteMapFile();
&Install();
exit;
####################################################
sub Usage {
	$script=`basename $0`;
	chop $script;
	print <<EOT;
Install Truetype & Type1 fonts for TeX

Usage: $script [-h] -fam=<family> [-ttf] [-u] [-v] [-outdir=<dir>]
                [-tds] [-fd=<name>] [-sn=<name>]
Where:
   -ttf,--truetype        : Install from Truetype font
   -u,--unicode           : Truetype is Unicode font
   -f,--family=<name>     : Define Family name to install (ex: ptm,bhv,jvn,...)
   -o,--outdir=<dir>      : Output directory, default is current directory
   -tds                   : Use TeX Directory Structure tree for output files
   -fd,--foundry=<name>   : Use this Foundry name, not need supplier.map
   -sn,--shortname=<name> : Use this Short name, not not need typeface.map
   -sans,--sanserif       : sanserif font
   -tt,--typewriter       : typewriter family
   -test,--testonly       : Print only test file for family
   -v,--verbose           : Verbose mode
   -h,--help              : Print this message
Example : $script -v -ttf --unicode -tds -f jvn -o /usr/share/texmf
EOT
	exit;
}
####################################################
sub GetParams {
	my $res= GetOptions("help|h", \$opt_h,
		"truetype|ttf", \$opt_ttf,
		"unicode|u", \$opt_unicode,
		"foundry|fd=s", \$opt_fd,
		"shortname|sn=s", \$opt_sn,
		"sanserif|sans", \$opt_sans,
		"typewriter|tt", \$opt_tt,
		"verbose|v", \$opt_v,
		"family|fam|f=s", \$opt_fam,
		"outdir|o=s", \$opt_outdir,
		"testonly|test", \$opt_test,
		"tds", \$opt_tds);

	&Usage if ($opt_h || $opt_fam eq '' || $res eq 0 );
	
	if ($opt_outdir eq "") {
		$opt_outdir=".";
	} else {
		$opt_outdir =~ s/\/$//;
	}
	$Family=$opt_fam;
}
####################################################
sub CheckNames {
	$_=$Family;
	($sname,$fname) = /(.)(..)/;
	#if ($Foundry eq '') {
	if ($opt_fd ne '')	{
		$Foundry = $opt_fd;
	} else {
		$Foundry=$Foundries{$sname};
		die ("Error : Foundry not found !") if ($Foundry eq '');
	}
	#}
	#if ($ShortName eq '') {
	if ($opt_sn ne '') {
		$ShortName=$opt_sn;
	} else {
		$ShortName=$Shortnames{$fname};
		die ("Error : Shortname not found !") if ($ShortName eq '');
	}
	print "Foundry: $Foundry\n" if $opt_v;
	print "Shortname: $ShortName\n" if $opt_v;
}


####################################################
# for Truetype fonts
sub Run_ttf2pt1 {
	if ($opt_ttf) {
		my ($option,$rawname,$fontname);
		$option = '-l latin1' if $opt_unicode;
		for (grep(/$Family.*\.ttf/, at FileNames)) {
			s/\.ttf//;
			$rawname=$_;
			print "Running : ttf2pt1 $option -b $rawname.ttf $rawname\n" if $opt_v;
			`ttf2pt1 $option -b $rawname.ttf $rawname &> /dev/null`;

			# Fix fontname problem for AFM file
			print "  fixing AFM file ...\n" if $opt_v;
			`sed -e '/^FontName /s/_/-/' $rawname.afm > $rawname.new.afm`;
			`mv -f $rawname.new.afm $rawname.afm`;

			# fix for PFB file
			print "  fixing PFB file ...\n" if $opt_v;
			`t1disasm -o $rawname.ps $rawname.pfb &> /dev/null`;
			`sed -e "/PS-AdobeFont/s/_/-/" $rawname.ps > $rawname.new.ps`;
			`sed -e "/FontName /s/_/-/" $rawname.new.ps > $rawname.ps`;
			`t1asm -b $rawname.ps $rawname.pfb &> /dev/null`;
			`rm -f $rawname*.ps`;
		}
	}
}

####################################################
sub CheckFiles {
	my $fam = $Family;
	my $files = '';
	if (length($fam) != 3) {
		print "Error : Family name '$fam' not valid !\n";
		exit;
	}
	print "Family: $fam\n" if $opt_v;
	if ($opt_ttf) {
		$files=`ls $fam*.ttf 2> /dev/null`;
		if ($files eq '') {
			print "Error : Truetype fonts for family '$fam' not found !\n\n";
			exit;
		}
	} else {
		$files=`ls $fam*.afm 2> /dev/null`;
		if ($files eq '') {
			print "Error : AFM fonts for family '$fam' not found !\n\n";
			exit;
		}
	}
}
####################################################
sub CheckProgram {
	if ($opt_ttf) {
		my $prog=`which ttf2pt1 2> /dev/null`;
		if ($prog eq '') {
			print "Error : Program 'ttf2pt1' not found !\n\n";
			exit;
		} else {
			print "Found : $prog" if $opt_v;
		}
	}
}
####################################################
sub MakeDirs {
	#---- get date & time --------
	my ($sec,$min,$hour,$_mday,$_mon,$_year,$wday,$yday,$isdst) =
	          localtime(time);
	$year = $_year + 1900;
	$_mon = $_mon +1 ;
	if ($_mon < 10) { $_mon= "0" . $_mon; }
	$month = $_mon;
	if ($_mday < 10) { $_mday= "0" . $_mday; }
	$day = $_mday;
	#---------------
	if ($opt_tds) {
		$afm_dir="$opt_outdir/fonts/afm/$Foundry/$ShortName";
		$tfm_dir="$opt_outdir/fonts/tfm/$Foundry/$ShortName";
		$type1_dir="$opt_outdir/fonts/type1/$Foundry/$ShortName";
		$vf_dir="$opt_outdir/fonts/vf/$Foundry/$ShortName";
		$dvips_dir="$opt_outdir/dvips/config";
		$tex_dir="$opt_outdir/tex/latex/psnfss/$Foundry";
		$ttf_dir="$opt_outdir/fonts/ttf/";
		`mkdir -p $opt_outdir/fonts/{afm,tfm,type1,vf}/$Foundry/$ShortName`;
		`mkdir -p $opt_outdir/fonts/ttf`;
		`mkdir -p $opt_outdir/dvips/config`;
		`mkdir -p $opt_outdir/tex/latex/psnfss/$Foundry`;
	} else {
		$Outdir="$opt_outdir/$Foundry/$ShortName";
		$afm_dir="$Outdir/afm";
		$tfm_dir="$Outdir/tfm";
		$type1_dir="$Outdir/type1";
		$vf_dir="$Outdir/vf";
		$dvips_dir="$Outdir/dvips";
		$tex_dir="$Outdir/tex";
		$ttf_dir="";
		`mkdir -p $Outdir/{afm,tfm,type1,vf,dvips,tex}`;
	}
	if ($opt_v) {
		print "Installing directories:\n";
		print "  AFM   -> $afm_dir\n";
		print "  TFM   -> $tfm_dir\n";
		print "  TYPE1 -> $type1_dir\n";
		print "  VF    -> $vf_dir\n";
		print "  TTF   -> $ttf_dir\n" if ($ttf_dir neq "");
		print "  DVIPS -> $dvips_dir\n";
		print "  TEX   -> $tex_dir\n\n";
	}
}

####################################################
####################################################
sub GetFontName {
	my ($afm_file) = @_;
	my $fontname;
	# print " $afm_file -> " if $opt_v;
	open(AFM,$afm_file);
	while (<AFM>) {
		if (/^FontName /) {
			($fontname) = /^FontName ([A-z0-9\-]*)/;
			# print "$fontname\n" if $opt_v;
			return $fontname;
		}
	}
	close(AFM);
	return "";
}
#--------------------
####################################################
sub ReadFontNames {
	my ($c1,$c2,$c3,$c4);
	print "Reading typeface.map ...\n" if $opt_v;
	open(SH,"kpsewhich typeface.map |")
	  || die "cannot run kpsewhich to get supplier.map";
	$path=<SH>;
	chop $path;
	close(SH);
	open(INF,"$path") || die "cannot open $path";
	while (<INF>) {
		if(!/^@/) {
			($c1,$c2,$c3,$c4)=split;
			$Typefaces{$c1} = $c3;
			$Shortnames{$c1} = $c2;
		}
	}
	close(INF);
	print "Reading supplier.map ...\n" if $opt_v;
	open(SH,"kpsewhich supplier.map |")
	  ||  die "cannot run kpsewhich to get supplier.map";
	$path=<SH>;
	chop $path;
	close(SH);
	open(INF,"$path") || die "cannot open $path";
	while (<INF>){
		if (!/^@/) {
			($c1,$c2,$c3)=split;
			$Foundries{$c1} =$c2;
		}
	}
	close(INF);
}
####################################################
sub WriteMapFile {
	my $fam = $Family;
	my ($file,$fontname);
	print "Writing to MAP file $fam.map ...\n";
	open(MAP,"> $fam.map") || die ("Can not write to $fam.map");
	for (grep(/^$fam.*8a.*\.afm/, at FileNames)) {
		$file=$_;
		#print " file: $file\n" if $opt_v;
		$fontname = &GetFontName($file);
		$pfb_file = $file; $pfb_file =~ s/afm/pfb/;
		$basename = $file; $basename =~ s/\..*$//; $basename =~ s/8a[a-z]?$/8r/;
		print MAP "$basename $fontname \" TeXBase1Encoding ReEncodeFont \"".
		          " <8r.enc <$pfb_file\n";
		print "$basename $fontname \" TeXBase1Encoding ReEncodeFont \"".
		      " <8r.enc <$pfb_file\n" if $opt_v;
	}
	open LOG,"grep \"^Faking \" $fam*.log| " || die "cannot open grep for Faking";
	while (<LOG>) {
		($style,$fake,$real)=/Faking (.*) font (.*) from (.*)/;
		$real =~ s/8r/8a/;
		$fontname = &GetFontName("$real.afm") if (-e "$real.afm");
		print "$fake $fontname \" " if $opt_v;
		print MAP "$fake $fontname \" ";
		if ($style eq "oblique") {
			print ".167 SlantFont " if $opt_v;
			print MAP ".167 SlantFont ";
		}
		print "TeXBase1Encoding ReEncodeFont \" <8r.enc <$real.pfb\n" if $opt_v;
		print MAP "TeXBase1Encoding ReEncodeFont \" <8r.enc <$real.pfb\n";
	}
	close(LOG);
	close(MAP);
	print "\n" if $opt_v;
}
####################################################
sub WriteStyFile {
	my $fam = $Family;
	my $command='';
	open (STY,">$ShortName.sty") || die("Can not write to $ShortName.sty");
	print STY "\\ProvidesPackage{$ShortName}[$year/$month/$day Nguyen-Dai Quy]\n";
	print STY "\\renewcommand{";
	if ($opt_tt) {
		$command="\\ttdefault";
	} elsif ($opt_sans) {
		$command="\\sfdefault";
	} else {
		$command="\\rmdefault";
	}
	print STY "$command}{$fam}\n";
	print STY "\\endinput\n";
	close(STY);
}
sub WriteTestFile {
	my $fam = $Family;
	my @sizes=('tiny','scriptsize','footnotesize','small','normalsize',
	           'large','Large','LARGE','huge','Huge');
	my $str1= 'abcde fghij klmop qrstu vwxyz';
	my $str1a= ' ÈËÍÎ ·++,0/00 ÛÚÙ^ ÌÏÓÔ ???¸ Ò??'.
	           ' ...» À ¡¿¬f ""'÷ ÕÃOEoe ?Y"EUR< -->-';
	$str1 = $str1 . " " . (uc $str1) . $str1a;
	my $str2= '1234567890 \\&@\\$\\{\\}()\\string~\\%\\#*[]';
	my $selfont= "\\fontfamily{$fam}\\selectfont";
	open (TEST,"> testfont-$fam.tex")||  die("Can not write to testfont-$fam.tex");
	print TEST "\\documentclass[a4paper]{article}\n";
	print TEST "\\usepackage{geometry}\n";
	print TEST 
"\\geometry{a4paper,tmargin=2cm,bmargin=2cm,lmargin=2cm,rmargin=2cm}\n";
	print TEST "\\usepackage[T1]{fontenc}\n\\setlength{\\parindent}{0pt}\n";
	print TEST "\\renewcommand{\\rmdefault}{$fam}\n\\pagestyle{empty}\n";
	print TEST "\\begin{document}\n";
	print TEST "\\section*{$selfont Example font $ShortName ($fam)}\n";
	print TEST "$selfont\n";
	print TEST "\\par\\bigskip \\fbox{Normal} $str1 $str2 \\\\\n";
	foreach (@sizes) {
		print TEST "{\\$_ $_} ";
	}
	print TEST "\\\\\n\\par\\bigskip\n";
	print TEST "\\fbox{\\bfseries Bold} {\\bfseries $str1 
$str2}\\\\\n\\par\\bigskip\n";
	print TEST "\\fbox{\\itshape Italic} {\\itshape $str1 
$str2}\\\\\n\\par\\bigskip\n";
	print TEST "\\fbox{\\bfseries\\itshape Bold-Italic}{\\bfseries\\itshape $str1 
$str2}\n\\par\n";
	print TEST "\\vfill\n\\rule{\\textwidth}{1pt}\\\\\n";
	print TEST "Created by {\\large\\itshape Perl} script of {\\Large\\bfseries 
NguyÍn--ai Qu?} <Quy\@linuxbe.org>\n";
	print TEST "\\end{document}\n";
	close(TEST);
}
####################################################
sub Run_fontinst {
	my $fam = $Family;
	open(TEX,"> $fam.tex")|| die ("Can not write to $fam.tex");
	print TEX "\\batchmode\n\\input fontinst.sty\n";
	print TEX "\\latinfamily{$fam}{";
	if ($opt_tt) {
		print TEX "\\hyphenchar\\font=-1";
	}
	print TEX "}\n\\bye\n";
	close(TEX);
	print "Running fontinst : tex $fam.tex\n" if $opt_v;
	`tex $fam.tex`;
}
####################################################
sub Run_pltotf {
	print "Running pltotf : PL -> TFM\n" if $opt_v;
	&BuildFileList;
	for (grep(/$Family.*\.pl/, at FileNames)){
		print "   pltotf $_\n" if $opt_v;
		`pltotf $_`;
	}
}
####################################################
sub Run_vptovf {
	print "Running vptovf : VPL -> VF\n" if $opt_v;
	for (grep(/$Family.*\.vpl/, at FileNames)){
		print "   vptovf $_\n" if $opt_v;
		`vptovf $_`;
	}
}
####################################################
sub BuildFileList {
     opendir(DIR,'.') || die ("ERROR: cannot open directory");
     @FileNames =grep(!/^\.\.?$/,readdir(DIR));
     closedir(DIR);
}
####################################################
sub Install {
	`rm -f $Family*.{pl,vpl,mtx,log,tex}`;
	print "Installing files ...\n" if $opt_v;
	print "   mv -f *$Family*.fd $tex_dir\n" if $opt_v;
	`mv -f *$Family*.fd $tex_dir`;
	`mv -f $ShortName.sty $tex_dir`;
	`mv -f testfont-$Family.tex $tex_dir`;
	print "   mv -f $Family*.map $dvips_dir\n" if $opt_v;
	`mv -f $Family*.map $dvips_dir`;
	print "   mv -f $Family*.afm $afm_dir\n" if $opt_v;
	`mv -f $Family*.afm $afm_dir`;
	print "   mv -f $Family*.tfm $tfm_dir\n" if $opt_v;
	`mv -f $Family*.tfm $tfm_dir`;
	print "   mv -f $Family*.vf $vf_dir\n" if $opt_v;
	`mv -f $Family*.vf $vf_dir`;
	print "   mv -f $Family*.pfb $type1_dir\n" if $opt_v;
	`mv -f $Family*.pfb $type1_dir`;
	if ($ttf_dir neq "") {
	    print "   cp -f $Family*.ttf $ttf_dir\n" if $opt_v;
	    `cp -f $Family*.ttf $ttf_dir`;
	}
	print "Done !\n" if $opt_v;
}
####################################################


-----------------------------------------------------------------
To UNSUBSCRIBE, send email to <info at email.esm.psu.edu> with
"unsubscribe macosx-tex" (no quotes) in the body.
For additional HELP, send email to <info at email.esm.psu.edu> with
"help" (no quotes) in the body.
-----------------------------------------------------------------




More information about the macostex-archives mailing list