3 # BuildFoundries: Given a Foundry file, generate groff font description
4 # files and a "download" file so gropdf can embed fonts in PDF output.
6 # Copyright (C) 2011-2020 Free Software Foundation, Inc.
7 # Written by Deri James <deri@chuzzlewit.myzen.co.uk>
9 # This file is part of groff.
11 # groff is free software; you can redistribute it and/or modify it under
12 # the terms of the GNU General Public License as published by the Free
13 # Software Foundation, either version 3 of the License, or
14 # (at your option) any later version.
16 # groff is distributed in the hope that it will be useful, but WITHOUT
17 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 # You should have received a copy of the GNU General Public License
22 # along with this program. If not, see <http://www.gnu.org/licenses/>.
28 my $pathsep='@PATH_SEPARATOR@';
34 GetOptions("check" => \$check, "dirURW=s" => \$dirURW,
35 "strict" => \$beStrict);
37 (my $progname = $0) =~s @.*/@@;
39 my @d=(split(':',shift||'../devps'));
41 chdir $where if $where ne '';
42 my (%flg,@downloadpreamble,%download);
43 my $GSpath=FindGSpath();
45 my $foundry=''; # the default foundry
50 CheckFoundry("Foundry.in");
55 LoadDownload("download"); # not required
56 LoadFoundry("Foundry");
69 open(F,"<$fn") or Die("file '$fn' not found or not readable");
75 s/\r$//; # in case edited in windows
77 s/\s*#.*?$//; # remove comments
90 if (lc($r[0]) eq 'foundry')
92 Warn("\nThe path(s) used for searching:\n".join(':',@{$foundrypath})."\n") if $notFoundFont;
95 push(@{$foundrypath},$dirURW) if $dirURW;
96 push(@{$foundrypath},(split(':',$r[2])),@{$devps});
97 foreach my $j (0..$#{$foundrypath})
99 if (defined($foundrypath->[$j])
100 && $foundrypath->[$j]=~m'\s*\(gs\)')
102 splice(@{$foundrypath},$j,1,@{$GSpath});
110 # 1=IsBase Y/N (one of PDFs 14 base fonts)
116 my $gfont=($foundry eq '')?$r[0]:"$foundry-$r[0]";
120 # Don't run afmtodit; just copy the groff font
121 # description file for grops.
123 my $gropsfnt=LocateFile($devps,$r[0],0);
124 if ($gropsfnt ne '' and -r "$gropsfnt")
126 my $psfont=UseGropsVersion($gropsfnt);
127 # To be embeddable in PDF, the font file name itself
128 # needs to be located and written to "download".
129 if (!PutDownload($psfont,
130 LocatePF($foundrypath,$r[5]),
133 if (uc($r[1]) ne 'Y')
136 my $fns=join(', ',split('!',$r[5]));
137 Warn("groff font '$gfont' will not be"
138 . " available for PDF output; unable"
139 . " to locate font file(s): $fns");
144 Notice("copied grops font $gfont") if $gotf;
149 Warn("Can't read grops font '$r[0]' for Foundry '$foundry'");
154 # Use afmtodit to create a groff font description file.
155 my $afmfile=LocateAF($foundrypath,$r[5]);
158 $sub=\&Die if ($beStrict);
159 &$sub("cannot locate AFM file for font '$gfont'");
162 my $psfont=RunAfmtodit($gfont,$afmfile,$r[2],$r[3],$r[4]);
166 if (!PutDownload($psfont,LocatePF($foundrypath,$r[5]),uc($r[1])))
168 unlink $gfont; # Unable to find the postscript file for the font just created by afmtodit
172 Notice("generated $gfont");
177 Warn("Failed to create groff font '$gfont' by running afmtodit");
185 Warn("\nThe path(s) used for searching:\n".join(':',@{$foundrypath})."\n") if $notFoundFont;
197 $enc="-e 'enc/$enc'" if $enc;
198 $map="'map/$map'" if $map;
200 my $cmd='afmtodit -c -dDESC';
202 foreach my $f (split('',$flags))
204 if (!exists($flg{$f}))
206 Warn("Can't use undefined flag '$f' in calling afmtodit for groff font '$gfont'");
213 system("$cmd $enc '$afmfile' $map $gfont");
221 if (open(GF,"<$gfont"))
224 my @ps=grep(/^internalname /,@gf);
225 if ($#ps == 0) # Just 1 match
227 (undef,$psfont)=split(' ',$ps[0],2);
232 Warn("Unexpected format for grops font '$gfont' for Foundry '$foundry' - ignoring");
246 return(LocateFile($path,$file,1));
254 return(LocateFile($path,$file,0));
262 return(substr($files,1)) if substr($files,0,1) eq '*';
264 foreach my $p (@{$path})
266 next if !defined($p) or $p eq ';' or $p eq ':';
271 next if $p=~m/^\%rom\%/; # exclude %rom% paths (from (gs))
273 foreach my $file (reverse(split('!',$files)))
277 if (!($file=~s/\..+$/.afm/))
286 # path given with file name so no need to search the paths
293 if ($tryafm and $file=~s'type1/'afm/'i)
304 if ($path eq '(tex)')
306 my $res=`kpsewhich $file`;
319 if ($tryafm and $ap=~s'type1/'afm/'i)
334 my (@res)=`@GHOSTSCRIPT@ -h 2>/dev/null`;
343 if ($stg==1 and $l=~m/^Search path:/)
349 if (substr($l,0,1) ne ' ')
356 $pathsep=';' if substr($l,-1) eq ';';
357 push(@{$buildpath},(split("$pathsep",$l)));
369 my (@gfa)=split('/',$gfont);
370 my $gfontbase=pop(@gfa);
372 if (open(GF,"<$gfont"))
375 my @ps=grep(/^internalname /,@gf);
376 if ($#ps == 0) # Just 1 match
378 (undef,$psfont)=split(' ',$ps[0],2);
383 Warn("Unexpected format for grops font '$gfont' for Foundry '$foundry' - ignoring");
390 if (open(GF,">$gfontbase"))
399 Warn("Failed to create new font '$gfont' for Foundry '$foundry'");
404 Warn("Failed to locate postscript internalname in grops font '$gfont' for Foundry '$foundry'");
411 Warn("Failed to open grops font '$gfont' for Foundry '$foundry'");
422 my $key="$foundry $psfont";
424 delete($download{$key}), return 0 if ($pffile eq '');
426 $pffile='*'.$pffile if $IsBase14 eq 'Y'; # This signals to gropdf to only edmbed if -e given
427 $download{$key}=$pffile;
436 return if !open(F,"<$fn");
441 s/\r$//; # in case edited in windows
443 if (substr($_,0,1) eq '#' or $_ eq '')
445 # Preserve comments at top of download file
447 push(@downloadpreamble,$_);
451 s/\s*#.*?$//; # remove comments
455 my (@r)=split(/\t+/);
458 $download{$key}=$r[2];
466 print join("\n",@downloadpreamble),"\n";
468 foreach my $k (sort keys %download)
470 my ($f,$ps)=split(/ /,$k);
471 print "$f\t$ps\t$download{$k}\n";
482 Msg("warning: line $lct: $msg");
493 print STDERR "$progname: $msg\n";
502 open(F,"<$fn") or Die("file '$fn' not found or not readable");
507 s/\r$//; # in case edited in windows
509 s/\s*#.*?$//; # remove comments
520 if (lc($r[0]) eq 'foundry')
524 push(@{$foundrypath},$dirURW) if $dirURW;
525 push(@{$foundrypath},(split(':',$r[2])),$devps);
526 foreach my $j (0..$#{$foundrypath})
528 if ($foundrypath->[$j]=~m'\s*\(gs\)')
530 splice(@{$foundrypath},$j,1,@{$GSpath});
538 # 1=IsBase Y/N (one of PDFs 14 base fonts)
544 my $gfont=($foundry eq '')?$r[0]:"$foundry-$r[0]";
548 # Don't run afmtodit, just copy the grops font file
551 my $gropsfnt=LocateFile([$devps],$r[0],0);
553 if ($gropsfnt ne '' and -r "$gropsfnt")
564 # We need to run afmtodit to create this groff font
565 $notFoundFont|=2 if !LocateAF($foundrypath,$r[5]);
566 $notFoundFont|=1 if !LocatePF($foundrypath,$r[5]);
578 # vim: set cindent noexpandtab shiftwidth=4 softtabstop=4 textwidth=72: