\input cwebmac % This is the cweb file hbf2gf.w of the CJK package ver. 4.8.4 18-Apr-2015 % Copyright (C) 1994-2015 Werner Lemberg % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program in doc/COPYING; if not, write to the Free % Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, % MA 02110-1301 USA % To print this CWEB file you should (but not must) use the CWEAVE of the % c2cweb-package (found at the CTAN archives, e.g. ftp.dante.de) and then say % % cweave +ai hbf2gf.w % % This (fully compatible) CWEAVE can transform CWEB-files with alternative % output rules (look at the position of braces below!) the author (it's me % too :-) prefer. Otherwise this file will be formatted traditionally. \font\meta=logo10 \def\mf{{\meta META}\-{\meta FONT}} \def\Om{\char "0A} % Omega symbol \def\title{hbf2gf (CJK Version 4.8.4)} \def\topofcontents{ \null\vfill \centerline{\titlefont The {\ttitlefont hbf2gf} program} \vskip 20pt \centerline{(CJK Version 4.8.4)} \vfill} \def\botofcontents{ \vfill \noindent Copyright \copyright~1996-1999 by Werner Lemberg \bigskip\noindent Permission is granted to make and distribute verbatim copies of this document provided that the copyright notice and this permission notice are preserved on all copies. \smallskip\noindent Permission is granted to copy and distribute modified versions of this document under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one.} \pageno=\contentspagenumber \advance\pageno by 1 \let\maybe=\iftrue \fullpageheight=240mm \pageheight=223mm \pagewidth=158mm \setpage \frenchspacing \def\msdos{\.{msdos}} \N{1}{1}Introduction. This is the \.{hbf2gf} program by Werner Lemberg (\.{wl@gnu.org}). The ``banner line'' defined here should be changed whenever \.{hbf2gf} is modified. \Y\B\4\D$\\{banner}$ \5 \.{"hbf2gf\ (CJK\ ver.\ 4.}\)\.{8.4)"}\par \fi \M{2} \.{hbf2gf} is intended to convert Hanzi Bitmap Fonts (HBF) into \TeX\ generic font files (\.{GF} files) according to the \\{CJK} package, which \.{hbf2gf} is part of. The outline of \.{hbf2gf} is simple: a CJK (Chinese/Japanese/Korean) bitmap file will be scaled and written in at most \PB{\\{nmb\_files}} \.{GF} files, each file containing \PB{\T{256}}~characters (except the last and possibly the first one). In the normal case it's not necessary to compute the right value of \PB{\\{nmb\_files}} because \.{hbf2gf} will do this; you should use \PB{${-}% \T{1}$} instead to indicate this. See the last section for an example. Alternatively you can call \.{hbf2gf} similar to \mf, i.e., the program will compute one font on demand. This mode will be used if two or three input parameters instead of one are given: the font name, the horizontal resolution, and optionally a vertical scaling factor or resolution to allow modes for e.g.\ $300\times600\,\hbox{dpi}$ printers. \.{hbf2gf} will extract the configuration file name from the font name; if this file isn't found, the program exits with error code~\PB{\T{2}} (this is useful for scripts like \.{mktexpk}). If the configuration file is found but an error occurs while computing the font, error code~\PB{\T{1}} is returned. In case of success, the exit code is zero. The characters in the input font files are completely described by the HBF header file. This program uses the HBF API implementation of Ross Paterson (\.{ross@soi.city.ac.uk}; with small extensions). You will find a description of the HBF standard at \.{ftp.ifcss.org}. A batch file created by \.{hbf2gf} too (if the program computes a whole set of subfonts) will convert the \.{GF} files to \.{PK} files using \.{GFtoPK}, a part of every \TeX\ package. \Y\B\4\D$\.{TRUE}$ \5 \T{1}\par \B\4\D$\.{FALSE}$ \5 \T{0}\Y\par \B\4\D$\.{STRING\_LENGTH}$ \5 \T{255}\C{ the maximal length of an input string in the configuration file }\par \B\4\D$\.{FILE\_NAME\_LENGTH}$ \5 \T{1024}\C{ the maximal length (including the path) of a filename }\Y\par \Y\B\4\X2:Global variables\X${}\E{}$\6 \&{int} \\{nmb\_files}${}\K{-}\T{1}{}$;\C{ create all files by default }\6 \&{int} \\{unicode}${}\K\.{FALSE}{}$;\C{ whether a Unicode font should be processed }\7 \&{int} \\{testing}${}\K\.{FALSE}{}$;\C{ whether we test only the font name }\7 \&{int} \\{mf\_like}${}\K\.{FALSE}{}$;\C{ whether we are in the \mf-like mode }% \6 \&{int} \\{file\_number}${}\K\T{0}{}$;\C{ the subfont number }\7 \&{double} \\{x\_resolution}${}\K\T{0.0}{}$;\C{ the second and third input parameter }\6 \&{double} \\{y\_scale}${}\K\T{1.0}{}$;\7 \&{int} \\{pk\_files}${}\K\.{TRUE}{}$;\C{ command line options }\6 \&{int} \\{tfm\_files}${}\K\.{TRUE};{}$\6 \&{int} \\{long\_extension}${}\K\.{TRUE};{}$\6 \&{int} \\{quiet}${}\K\.{FALSE}{}$;\7 \&{char} ${}\\{config\_file}[\.{FILE\_NAME\_LENGTH}+\T{4}+\T{1}]{}$;\C{ we probably must add `\.{.cfg}' }\6 \&{char} ${}\\{output\_name}[\.{STRING\_LENGTH}+\T{1}]{}$;\7 \&{FILE} ${}{*}\\{config},{}$ ${}{*}\\{out};{}$\6 \&{HBF} ${}{*}\\{hbf}{}$;\7 \8\#\&{ifdef} ${}\msdos{}$\C{ if we compile under DOS or OS/2 }\6 \8\#\&{define} \.{WRITE\_BIN} \5\.{"wb"}\6 \8\#\&{define} \.{WRITE\_TXT} \5\.{"wt"}\6 \8\#\&{define} \.{READ\_BIN} \5\.{"rb"}\6 \8\#\&{define} \.{READ\_TXT} \5\.{"rt"}\6 \8\#\&{else}\6 \8\#\&{define} \.{WRITE\_BIN} \5\.{"w"}\6 \8\#\&{define} \.{WRITE\_TXT} \5\.{"w"}\6 \8\#\&{define} \.{READ\_BIN} \5\.{"r"}\6 \8\#\&{define} \.{READ\_TXT} \5\.{"r"}\6 \8\#\&{endif}\7 \&{int} \\{end\_of\_file}${}\K\.{FALSE}{}$;\par \As15, 19, 27, 38, 49, 53, 58, 60, 62, 70, 73\ETs76. \U4.\fi \M{3} One \.{PL} file will be created additionally, which describes the font metrics in a readable way. Because all CJK characters have identical bounding boxes, one metrics file is enough---the batch job created by \.{hbf2gf} calls \.{PLtoTF} to produce this \.{TFM} file and then copies it into \PB{\\{nmb\_files}} metrics files. There usually will be a discrepancy between the number of characters in the last \.{GF} file and the \.{TFM} file, but this does not harm. If you specify the \.{ofm\_file} option in the configuration file, an extended virtual property file (such files have the extension \.{.ovp}) for the \Om\ system is written; this will be then converted with \.{ovp2ovf} into an \.{OFM} and an \.{OVF} file to map all the subfonts into one large virtual font. \fi \N{1}{4}The main routine. The main routine takes \PB{\\{file\_name}}, \PB{\\{x\_resolution}}, and \PB{% \\{y\_scale}} as command line parameters if in \mf-like mode, otherwise \PB{\\{config\_file}} as the only argument. \PB{\\{read\_config}(\,)} scans the configuration file and fills the global variables, \PB{\\{write\_file}(\,)} writes the \.{GF} files, \PB{\\{write\_pl}(% \,)} and \PB{\\{write\_ovp}(\,)} write the \.{PL} and \.{OVP} files respectively, and \PB{\\{write\_job}(\,)} the batch file. \Y\B\X10:Include files\X\6 \X11:Prototypes\X\6 \X2:Global variables\X\7 \&{int} \\{main}(\&{int} \\{argc}${},\39{}$\&{char} ${}{*}\\{argv}[\,]){}$\1\1% \2\2\6 ${}\{{}$\1\6 \&{char} ${}{*}\|p;{}$\7 \X78:Initialize \TeX\ file searching\X\7 \X7:Scan options\X\7 \&{if} ${}(\R\\{quiet}){}$\1\5 ${}\\{printf}(\.{"\\n\%s\\n\\n"},\39\\{banner}){}$;\2\7 ${}\\{strncpy}(\\{config\_file},\39\\{argv}[\T{1}],\39\.{FILE\_NAME% \_LENGTH});{}$\6 ${}\\{config\_file}[\.{FILE\_NAME\_LENGTH}]\K\.{'\\0'}{}$;\7 \&{if} ${}(\\{argc}>\T{2}\V\\{testing}){}$\5 ${}\{{}$\1\6 \&{int} \|l${}\K\\{strlen}(\\{config\_file});{}$\7 \&{if} ${}(\|l>\T{2}){}$\1\5 ${}\\{config\_file}[\|l-\T{2}]\K\.{'\\0'}{}$;\C{ strip subfont number from file name }\2\6 \&{else}\5 ${}\{{}$\1\6 \&{if} ${}(\R\\{quiet}){}$\1\5 ${}\\{printf}(\.{"`\%s'\ can't\ be\ a\ sub}\)\.{font\ created\ by\ hbf2}\)\.{gf% \\n"},\39\\{config\_file});{}$\2\6 \\{exit}(\T{2});\6 \4${}\}{}$\2\7 ${}\\{mf\_like}\K\.{TRUE};{}$\6 \4${}\}{}$\2\7 \\{read\_config}(\,);\C{ will call \PB{\\{exit}(\T{1})} on errors }\7 \&{if} (\\{mf\_like})\1\5 \X8:Check other arguments\X\2\7 \X28:Initialize variables\X\7 \X9:Write files\X\7 \&{if} (\\{tfm\_files})\1\5 \\{write\_pl}(\,);\2\6 \&{if} (\\{ofm\_file})\1\5 \\{write\_ovp}(\,);\2\6 \&{if} ${}(\R\\{mf\_like}){}$\1\5 \\{write\_job}(\,);\2\7 \\{hbfClose}(\\{hbf});\7 \\{exit}(\T{0});\6 \&{return} \T{0};\C{ never reached }\6 \4${}\}{}$\2\par \fi \M{5} \Y\B\4\D$\.{VERSION}$ \6 \.{"\\n"}\6 \.{"Copyright\ (C)\ 1996-}\)\.{1999\ Werner\ Lemberg.}\)\.{\\n"}\6 \.{"There\ is\ NO\ warrant}\)\.{y.\ \ You\ may\ redistri}\)\.{bute\ this\ software\\n}\)\.{"}\6 \.{"under\ the\ terms\ of\ }\)\.{the\ GNU\ General\ Publ}\)\.{ic\ License\\n"}\6 \.{"and\ the\ HBF\ library}\)\.{\ copyright.\\n"}\6 \.{"\\n"}\6 \.{"For\ more\ informatio}\)\.{n\ about\ these\ matter}\)\.{s,\ see\ the\ files% \\n"}\6 \.{"named\ COPYING\ and\ h}\)\.{bf.c.\\n"}\6 \.{"\\n"}\par \Y\B\4\X5:Print version\X${}\E{}$\6 ${}\{{}$\1\6 \\{printf}(\.{"\\n"});\6 \\{printf}(\\{banner});\6 ${}\\{printf}(\.{"\ (\%s)\\n"},\39\\{TeX\_search\_version}(\,));{}$\6 \\{printf}(\.{VERSION});\6 \\{exit}(\T{0});\6 \4${}\}{}$\2\par \U7.\fi \M{6} \Y\B\4\D$\.{USAGE}$ \6 \.{"\\n"}\6 \.{"Usage:\ hbf2gf\ [-q]\ }\)\.{configuration\_file[.}\)\.{cfg]\\n"}\6 \.{"\ \ \ \ \ \ \ hbf2gf\ [opti}\)\.{ons]\ font\_name\ x\_res}\)\.{olution\ [y% \_scale\ |\ y}\)\.{\_resolution]\\n"}\6 \.{"\ \ \ \ \ \ \ hbf2gf\ -t\ [-}\)\.{q]\ font\_name\\n"}\6 \.{"\\n"}\6 \.{"\ \ Convert\ a\ font\ in}\)\.{\ HBF\ format\ to\ TeX's}\)\.{\ GF\ resp.\ PK% \ format.}\)\.{\\n"}\6 \.{"\\n"}\6 \.{"\ \ \ \ \ \ \ \ \ -q\ \ \ \ \ \ \ \ }\)\.{\ \ \ \ \ be\ silent\\n"}\6 \.{"\ \ \ \ \ \ \ \ \ -p\ \ \ \ \ \ \ \ }\)\.{\ \ \ \ \ don't\ produce\ a}\)\.{% \ PL\ file\\n"}\6 \.{"\ \ \ \ \ \ \ \ \ -g\ \ \ \ \ \ \ \ }\)\.{\ \ \ \ \ don't\ produce\ a}\)\.{% \ GF\ file\\n"}\6 \.{"\ \ \ \ \ \ \ \ \ -n\ \ \ \ \ \ \ \ }\)\.{\ \ \ \ \ use\ no\ resoluti}\)% \.{on\ in\ extension\ (onl}\)\.{y\ `.gf')\\n"}\6 \.{"\ \ \ \ \ \ \ \ \ -t\ \ \ \ \ \ \ \ }\)\.{\ \ \ \ \ test\ for\ font\_n}\)% \.{ame\ (returns\ 0\ on\ su}\)\.{ccess)\\n"}\6 \.{"\ \ \ \ \ \ \ \ \ --help\ \ \ \ }\)\.{\ \ \ \ \ print\ this\ mess}\)\.{age\ and\ exit\\n"}\6 \.{"\ \ \ \ \ \ \ \ \ --version\ }\)\.{\ \ \ \ \ print\ version\ n}\)\.{umber\ and\ exit\\n"}\6 \.{"\\n"}\par \Y\B\4\X6:Print help information\X${}\E{}$\6 ${}\{{}$\1\6 \\{printf}(\.{USAGE});\6 \\{exit}(\T{0});\6 \4${}\}{}$\2\par \U7.\fi \M{7} Three options can be specified to the program (\.{-p}, \.{-g}, and \.{-n}) if in \mf-like mode to suppress creation of a \.{PL} resp.\ a \.{GF} file, and to force a `\.{.gf}' extension (instead of e.g.\ `\.{.300gf}'). The corresponding setting of a particular switch in the configuration file is ignored then. Additionally, the option \.{-t} tests whether the specified subfont name leads to an \.{hbf2gf} configuration file. It returns 0 on success and prints out the name of that configuration file (provided the \.{-q} switch isn't set). This test isn't a thorough one; it only removes the last two characters and checks whether a configuration file with that name exists. \Y\B\4\X7:Scan options\X${}\E{}$\6 \&{if} ${}(\\{argc}\E\T{2}){}$\5 ${}\{{}$\1\6 \&{if} ${}(\\{strcmp}(\\{argv}[\T{1}],\39\.{"--help"})\E\T{0}){}$\1\5 \X6:Print help information\X\2\6 \&{else} \&{if} ${}(\\{strcmp}(\\{argv}[\T{1}],\39\.{"--version"})\E\T{0}){}$\1% \5 \X5:Print version\X\2\6 \4${}\}{}$\2\7 \&{while} ${}(\\{argc}>\T{1}){}$\5 ${}\{{}$\1\6 ${}\|p\K\\{argv}[\T{1}];{}$\6 \&{if} ${}(\|p[\T{0}]\I\.{'-'}){}$\1\5 \&{break};\2\6 \&{if} ${}(\|p[\T{1}]\E\.{'p'}){}$\1\5 ${}\\{tfm\_files}\K\.{FALSE};{}$\2\6 \&{else} \&{if} ${}(\|p[\T{1}]\E\.{'g'}){}$\1\5 ${}\\{pk\_files}\K\.{FALSE};{}$\2\6 \&{else} \&{if} ${}(\|p[\T{1}]\E\.{'n'}){}$\1\5 ${}\\{long\_extension}\K\.{FALSE};{}$\2\6 \&{else} \&{if} ${}(\|p[\T{1}]\E\.{'q'}){}$\1\5 ${}\\{quiet}\K\.{TRUE};{}$\2\6 \&{else} \&{if} ${}(\|p[\T{1}]\E\.{'t'}){}$\1\5 ${}\\{testing}\K\.{TRUE}{}$;\2\7 ${}\\{argv}\PP;{}$\6 ${}\\{argc}\MM;{}$\6 \4${}\}{}$\2\7 \&{if} (\\{testing})\5 ${}\{{}$\1\6 \&{if} ${}(\\{argc}\I\T{2}){}$\5 ${}\{{}$\1\6 ${}\\{fprintf}(\\{stderr},\39\.{"Need\ exactly\ one\ pa}\)\.{rameter\ for\ `-t'% \ opt}\)\.{ion.\\n"});{}$\6 ${}\\{fprintf}(\\{stderr},\39\.{"Try\ `hbf2gf\ --help'}\)\.{\ for\ more\ informatio}\)\.{n.\\n"});{}$\6 \\{exit}(\T{1});\6 \4${}\}{}$\2\6 \4${}\}{}$\2\6 \&{else} \&{if} ${}(\\{argc}<\T{2}\V\\{argc}>\T{4}){}$\5 ${}\{{}$\1\6 ${}\\{fprintf}(\\{stderr},\39\.{"Invalid\ number\ of\ p}\)\.{arameters.% \\n"});{}$\6 ${}\\{fprintf}(\\{stderr},\39\.{"Try\ `hbf2gf\ --help'}\)\.{\ for\ more\ informatio}\)\.{n.\\n"});{}$\6 \\{exit}(\T{1});\6 \4${}\}{}$\2\Y\par \U4.\fi \M{8} If the (optional) argument is larger than~\PB{\T{10}}, we treat it as a value for the vertical resolution (in dpi), otherwise as a vertical scaling factor. \Y\B\4\X8:Check other arguments\X${}\E{}$\6 ${}\{{}$\1\6 \&{if} (\\{unicode})\1\5 ${}\\{file\_number}\K{}$(\&{int}) \\{strtol}${}({\AND}\\{argv}[\T{1}][% \\{strlen}(\\{argv}[\T{1}])-\T{2}],\39{}$(\&{char} ${}{*}{*}){}$ ${}\NULL,\39% \T{16});{}$\2\6 \&{else}\1\5 ${}\\{file\_number}\K\\{atoi}({\AND}\\{argv}[\T{1}][\\{strlen}(\\{argv}[% \T{1}])-\T{2}]){}$;\2\7 ${}\\{x\_resolution}\K\\{atof}(\\{argv}[\T{2}]);{}$\6 \&{if} ${}(\\{x\_resolution}<\.{PRINTER\_MIN\_RES\_X}){}$\5 ${}\{{}$\1\6 ${}\\{fprintf}(\\{stderr},\39\.{"Invalid\ horizontal\ }\)\.{resolution% \\n"});{}$\6 \\{exit}(\T{1});\6 \4${}\}{}$\2\7 \&{if} ${}(\\{argc}>\T{3}){}$\5 ${}\{{}$\1\6 ${}\\{y\_scale}\K\\{atof}(\\{argv}[\T{3}]);{}$\6 \&{if} ${}(\\{y\_scale}<\T{0.01}){}$\5 ${}\{{}$\1\6 ${}\\{fprintf}(\\{stderr},\39\.{"Invalid\ vertical\ sc}\)\.{aling\ factor\ or\ reso}\)\.{lution\\n"});{}$\6 \\{exit}(\T{1});\6 \4${}\}{}$\2\6 \&{if} ${}(\\{y\_scale}>\T{10.0}){}$\1\5 ${}\\{y\_scale}\K{}$(\&{double}) \\{x\_resolution}${}/\\{y\_scale};{}$\2\6 \4${}\}{}$\2\6 \4${}\}{}$\2\par \U4.\fi \M{9} If \PB{\\{unicode}} is \PB{\.{TRUE}}, the start value of the running number appended to the base name of the output font files is taken from the HBF header file, otherwise it starts with~`\.{01}'. \PB{\\{min\_char}} represents the lower bound of the code range. If we are in \mf-like mode, \PB{\\{file\_number}} is taken from the command line, and \PB{\\{max\_numb}} will be set to~\PB{\T{1}}. \Y\B\4\X9:Write files\X${}\E{}$\6 ${}\{{}$\1\6 \&{int} \|j${},{}$ \\{max\_numb};\7 \&{if} ${}(\R\\{mf\_like}){}$\5 ${}\{{}$\1\6 ${}\\{file\_number}\K(\\{unicode}\E\.{TRUE}\?(\\{min\_char}\GG\T{8}):\T{1});{}$% \6 \&{if} ${}(\\{nmb\_files}\E{-}\T{1}){}$\1\5 ${}\\{max\_numb}\K(\\{unicode}\E\.{TRUE}\?\T{\^100}:\T{100});{}$\2\6 \&{else}\1\5 ${}\\{max\_numb}\K\\{nmb\_files};{}$\2\6 \4${}\}{}$\2\6 \&{else}\1\5 ${}\\{max\_numb}\K\T{1}{}$;\2\7 \&{for} ${}(\|j\K\T{0};{}$ ${}(\|j<\\{max\_numb})\W\R\\{end\_of\_file};{}$ ${}% \\{file\_number}\PP,\39\|j\PP){}$\1\5 \\{write\_file}(\,);\2\7 ${}\\{nmb\_files}\K\|j{}$;\C{ the real number of output font files }\6 \4${}\}{}$\2\par \U4.\fi \M{10} \Y\B\4\X10:Include files\X${}\E{}$\6 \8\#\&{ifdef} \.{HAVE\_CONFIG\_H}\6 \8\#\&{include} \.{}\6 \8\#\&{endif}\6 \8\#\&{include} \.{}\6 \8\#\&{include} \.{}\6 \8\#\&{include} \.{}\6 \8\#\&{include} \.{}\6 \8\#\&{include} \.{}\6 \8\#\&{ifdef} \.{TM\_IN\_SYS\_TIME}\6 \8\#\&{include} \.{}\6 \8\#\&{endif}\6 \8\#\&{include} \.{"hbf.h"}\par \A69. \U4.\fi \N{1}{11}The functions. The first function to be described is \PB{\\{write\_file}(\,)}. Each \.{GF} file consists of three sections: a preamble, a data section, and a postamble. The functions \PB{\\{write\_pre}(\,)}, \PB{\\{write\_data}(\,)}, and \PB{\\{write% \_post}(\,)} handle this. \Y\B\4\X11:Prototypes\X${}\E{}$\6 \&{static} \&{void} \\{write\_file}(\&{void});\par \As13, 16, 20, 25, 29, 36, 39, 41, 45, 47, 50, 54, 64, 67, 71, 74\ETs79. \U4.\fi \M{12} In \mf-like mode we create font file name extensions similar to \mf\ if the \.{-n} option isn't specified; otherwise only `\.{.gf}' will be appended. \Y\B\&{static} \&{void} \\{write\_file}(\&{void})\1\1\2\2\6 ${}\{{}$\1\6 \&{char} ${}\\{output\_file}[\.{FILE\_NAME\_LENGTH}+\T{1}];{}$\7 \&{if} (\\{pk\_files})\5 ${}\{{}$\1\6 \&{if} (\\{mf\_like})\5 ${}\{{}$\1\6 \&{if} (\\{unicode})\1\5 ${}\\{sprintf}(\\{output\_file},\39\.{"\%s\%02x.\%.0igf"},{}$\6 \\{output\_name}${},\39\\{file\_number},\39\\{long\_extension}\?(\&{int})(\\{x% \_resolution}+\T{0.5}):\T{0});{}$\2\6 \&{else}\1\5 ${}\\{sprintf}(\\{output\_file},\39\.{"\%s\%02i.\%.0igf"},{}$\6 \\{output\_name}${},\39\\{file\_number},\39\\{long\_extension}\?(\&{int})(\\{x% \_resolution}+\T{0.5}):\T{0});{}$\2\6 \4${}\}{}$\2\6 \&{else}\5 ${}\{{}$\1\6 \&{if} (\\{unicode})\1\5 ${}\\{sprintf}(\\{output\_file},\39\.{"\%s\%02x.gf"},\39\\{output\_name},\39% \\{file\_number});{}$\2\6 \&{else}\1\5 ${}\\{sprintf}(\\{output\_file},\39\.{"\%s\%02i.gf"},\39\\{output\_name},\39% \\{file\_number});{}$\2\6 \4${}\}{}$\2\6 \&{if} ${}(\R(\\{out}\K\\{fopen}(\\{output\_file},\39\.{WRITE\_BIN}))){}$\5 ${}\{{}$\1\6 ${}\\{fprintf}(\\{stderr},\39\.{"Couldn't\ open\ `\%s'\\}\)\.{n"},\39\\{output% \_file});{}$\6 \\{exit}(\T{1});\6 \4${}\}{}$\2\6 \&{if} ${}(\R\\{quiet}){}$\1\5 ${}\\{printf}(\.{"Writing\ `\%s'\ "},\39\\{output\_file}){}$;\2\7 \\{write\_pre}(\,);\6 \\{write\_data}(\,);\6 \\{write\_post}(\,);\6 \\{fclose}(\\{out});\7 \&{if} ${}(\R\\{quiet}){}$\1\5 \\{printf}(\.{"\\n"});\2\6 \4${}\}{}$\2\6 \&{else}\1\5 \\{write\_data}(\,);\2\6 \4${}\}{}$\2\par \fi \M{13} The preamble has two bytes at the very beginning, \PB{\.{PRE}} and \PB{\.{GF% \_ID}}. \PB{\.{PRE}} starts the preamble, and \PB{\.{GF\_ID}} is the Generic Font Identity Byte. The next bytes are a string in Pascal format containing a header, the date, and the time. Strings in Pascal format start with the length of the string and have no terminating NULL byte. \Y\B\4\D$\.{GF\_ID}$ \5 \T{131}\par \B\4\D$\.{PRE}$ \5 \T{247}\Y\par \B\4\D$\\{headertstring}$ \5 \.{"\ hbf2gf\ output\ "}\par \Y\B\4\X11:Prototypes\X${}\mathrel+\E{}$\6 \&{static} \&{void} \\{write\_pre}(\&{void});\par \fi \M{14} \Y\B\&{static} \&{void} \\{write\_pre}(\&{void})\1\1\2\2\6 ${}\{{}$\1\6 \&{char} \\{out\_s}[\T{40}]${},{}$ \|s[\T{20}];\6 \&{time\_t} \\{secs\_now};\6 \&{struct} \&{tm} ${}{*}\\{time\_now};{}$\7 ${}\\{strcpy}(\\{out\_s},\39\\{headertstring}){}$;\7 ${}\\{secs\_now}\K\\{time}(\NULL){}$;\C{ system date and time }\6 ${}\\{time\_now}\K\\{localtime}({\AND}\\{secs\_now});{}$\6 ${}\\{strftime}(\|s,\39\T{20},\39\.{"\%Y.\%m.\%d:\%H.\%M"},\39\\{time% \_now});{}$\6 ${}\\{strcat}(\\{out\_s},\39\|s){}$;\7 ${}\\{fputc}(\.{PRE},\39\\{out});{}$\6 ${}\\{fputc}(\.{GF\_ID},\39\\{out});{}$\6 ${}\\{fputc}(\\{strlen}(\\{out\_s}),\39\\{out});{}$\6 ${}\\{fputs}(\\{out\_s},\39\\{out});{}$\6 \4${}\}{}$\2\par \fi \M{15} \PB{\\{write\_data}(\,)} produces the middle part of the \.{GF} file. It first sets \PB{\\{char\_adr\_p}} equal to the address of \PB{\\{char\_adr}[\,]} which will contain file offsets of the compressed characters. \PB{\\{input\_size\_x}} and \PB{\\{input\_size\_y}} reflect the original dimensions of the bitmap font, \PB{\\{pk\_output\_size\_x}} and \PB{\\{pk\_output\_size\_y}} contain the width and height of the output character box (in pixels), \PB{\\{pk\_offset\_x}} and \PB{\\{pk\_offset\_y}} define the baseline of the font. The same names starting with `\\{tfm\_}' instead of `\\{pk\_}' are used for \.{TFM} files (values are multiples of design size). \PB{\\{mag\_x}} and \PB{\\{mag\_y}} hold the scaling factors which are needed to reach \PB{\\{design\_size}}. \PB{\\{slant}} defines the slant ($\Delta x / \Delta y$), \PB{\\{target\_size\_x}} and \PB{\\{target\_size\_y}} will be the final dimensions; \PB{$\\{magstep\_x}\K\\{target\_size\_x}/\\{design\_size}$} is % \TeX's \.{\\magstep}. The \CEE/ standard specifies that all global values will be automatically set to~\PB{\T{0}} if no initialization value is given. \Y\B\4\X2:Global variables\X${}\mathrel+\E{}$\6 \&{long} \\{char\_adr}[\T{256}];\6 \&{long} ${}{*}\\{char\_adr\_p}{}$;\7 \&{int} \\{pk\_offset\_x};\C{ horizontal offset (increase character width a bit; will be applied on both the left and the right side) }\6 \&{double} \\{tfm\_offset\_x};\6 \&{int} \\{pk\_offset\_y};\C{ vertical offset (must be configured to desired font size) }\6 \&{double} \\{tfm\_offset\_y};\7 \&{int} \\{input\_size\_x};\6 \&{int} \\{input\_size\_y};\6 \&{const} \&{char} ${}{*}\\{font\_encoding}{}$;\C{ taken from the HBF file }\6 \&{int} \\{pk\_width};\C{ without slant }\6 \&{int} \\{pk\_output\_size\_x};\C{ the output character box dimensions without offsets }\6 \&{double} \\{tfm\_output\_size\_x};\6 \&{int} \\{pk\_output\_size\_y};\6 \&{double} \\{tfm\_output\_size\_y};\7 \&{double} \\{design\_size}${}\K\T{10.0}{}$;\C{ in points }\6 \&{double} \\{target\_size\_x};\C{ in points }\6 \&{double} \\{target\_size\_y};\6 \&{double} \\{magstep\_x};\6 \&{double} \\{magstep\_y};\6 \&{double} \\{slant};\6 \&{int} \\{rotation};\7 \&{double} \\{mag\_x};\C{ horizontal and vertical magnification values }\6 \&{double} \\{mag\_y};\7 \&{int} \\{empty\_char};\C{ a flag whether the character does not exist or is empty }\6 \&{int} \\{last\_char};\C{ the last valid character in a \.{GF} file }\7 \&{int} \\{dot\_count};\C{ this counts the processed characters; every ten characters a dot is output to the screen }\par \fi \M{16} \Y\B\4\X11:Prototypes\X${}\mathrel+\E{}$\6 \&{static} \&{void} \\{write\_data}(\&{void});\par \fi \M{17} \Y\B\&{static} \&{void} \\{write\_data}(\&{void})\1\1\2\2\6 ${}\{{}$\1\6 ${}\\{dot\_count}\K\T{0};{}$\6 ${}\\{char\_adr\_p}\K\\{char\_adr}{}$;\7 \&{for} ${}(\\{last\_char}\K\T{0};{}$ ${}(\\{last\_char}<\T{256})\W\R\\{end\_of% \_file};{}$ ${}\\{last\_char}\PP){}$\1\5 \X18:Write character\X\2\6 \4${}\}{}$\2\par \fi \M{18} The code in this section saves the current file position first and calls \PB{\\{make\_pixel\_array}(\,)}, which expands and scales the character bitmap. \PB{\.{BOC}} (and \PB{\.{BOC1}}), the Begin Of Character command byte, must be followed by the character code and the dimensions of the character as explained in ``\mf---the program'' (corrected by vertical and horizontal offsets). \PB{\\{write\_coding}(\,)} compresses and outputs the bitmap; \PB{\.{EOC}} (End Of Character) finishes the current character. \Y\B\4\D$\.{BOC}$ \5 \T{67}\par \B\4\D$\.{BOC1}$ \5 \T{68}\C{ simplified version of \PB{\.{BOC}} }\par \B\4\D$\.{EOC}$ \5 \T{69}\par \Y\B\4\X18:Write character\X${}\E{}$\6 ${}\{{}$\1\6 \&{if} ${}(\\{dot\_count}\PP\MOD\T{10}\E\T{0}{}$)\C{ a progress report for impatient users }\1\6 \&{if} ${}(\\{pk\_files}\W\R\\{quiet}){}$\5 ${}\{{}$\1\6 \\{printf}(\.{"."});\6 \\{fflush}(\\{stdout});\6 \4${}\}{}$\2\2\7 ${}\\{empty\_char}\K\.{FALSE};{}$\6 \\{make\_pixel\_array}(\,);\6 \&{if} (\\{end\_of\_file})\1\5 \&{return};\2\7 \&{if} (\\{pk\_files})\5 ${}\{{}$\1\6 ${}{*}\\{char\_adr\_p}\K\\{ftell}(\\{out});{}$\6 ${}\\{char\_adr\_p}\PP{}$;\7 \&{if} (\\{empty\_char})\5 ${}\{{}$\1\6 ${}\\{fputc}(\.{BOC1},\39\\{out});{}$\6 \\{fputc}((\&{unsigned} \&{char}) \\{last\_char}${},\39\\{out});{}$\6 ${}\\{fputc}(\T{0},\39\\{out});{}$\6 ${}\\{fputc}(\T{0},\39\\{out});{}$\6 ${}\\{fputc}(\T{0},\39\\{out});{}$\6 ${}\\{fputc}(\T{0},\39\\{out});{}$\6 ${}\\{fputc}(\.{EOC},\39\\{out});{}$\6 \4${}\}{}$\2\6 \&{else}\5 ${}\{{}$\1\6 ${}\\{fputc}(\.{BOC},\39\\{out});{}$\6 ${}\\{fputl}(\\{last\_char},\39\\{out});{}$\6 ${}\\{fputl}({-}\T{1\$L},\39\\{out});{}$\6 ${}\\{fputl}(\\{pk\_offset\_x},\39\\{out});{}$\6 ${}\\{fputl}(\\{pk\_output\_size\_x}+\\{pk\_offset\_x},\39\\{out});{}$\6 ${}\\{fputl}(\\{pk\_offset\_y},\39\\{out});{}$\6 ${}\\{fputl}(\\{pk\_output\_size\_y}+\\{pk\_offset\_y},\39\\{out}){}$;\7 \\{write\_coding}(\,);\7 ${}\\{fputc}(\.{EOC},\39\\{out});{}$\6 \4${}\}{}$\2\6 \4${}\}{}$\2\6 \4${}\}{}$\2\par \U17.\fi \M{19} The current \.{GF} file will be completed with data written by \PB{\\{write\_post}(\,)}. The end consists of three sections: ``special'', ``post'', and ``postpost''. The first contains material not used by \TeX\ itself but which can be used by other programs like \.{GFtoDVI} or for documentary purposes (\PB{\\{coding}[\,]} and \PB{\\{comment}[\,]}). The second describes the font as a whole, and the last marks the end of the file. \PB{\\{pk\_total\_min\_x}} up to \PB{\\{pk\_total\_max\_y}} define the greatest bounding box of this file (including offsets); the horizontal character escapement after drawing the character is \PB{\\{pk\_dx}}. \PB{\\{tfm\_width}} is the width in multiples of the design size ignoring the target size. \Y\B\4\D$\.{\_2\_16}$ \5 \T{65536.0}\C{ $2^{16}$ }\par \B\4\D$\.{\_2\_20}$ \5 \T{1048576.0}\C{ $2^{20}$ }\par \Y\B\4\X2:Global variables\X${}\mathrel+\E{}$\6 \&{char} ${}\\{coding}[\.{STRING\_LENGTH}+\T{1}]{}$;\C{ a comment describing the font encoding }\6 \&{char} ${}\\{comment}[\.{STRING\_LENGTH}+\T{1}]{}$;\C{ a comment describing the font }\7 \&{unsigned} \&{long} \\{checksum};\7 \&{long} \\{pk\_total\_min\_x};\6 \&{long} \\{pk\_total\_max\_x};\6 \&{long} \\{pk\_total\_min\_y};\6 \&{long} \\{pk\_total\_max\_y};\7 \&{int} \\{dpi\_x};\C{ printer resolution }\6 \&{int} \\{dpi\_y};\6 \&{double} \\{ppp\_x};\C{ pixels per point }\6 \&{double} \\{ppp\_y};\par \fi \M{20} To clarify the meaning of these values see the sections about the metrics and configuration file also. \TeX\ defines that 72.27~points are exactly 1~inch. \Y\B\4\X11:Prototypes\X${}\mathrel+\E{}$\6 \&{static} \&{void} \\{write\_post}(\&{void});\par \fi \M{21} \Y\B\&{static} \&{void} \\{write\_post}(\&{void})\1\1\2\2\6 ${}\{{}$\1\6 \&{long} \\{special\_adr};\6 \&{long} \\{post\_adr};\7 \&{long} \\{designsize}${}\K\\{design\_size}*\.{\_2\_20}{}$;\C{ design size $* 2^{20}$ }\7 \&{int} \\{pk\_dx};\6 \&{long} \\{tfm\_width};\7 \&{int} \|i;\6 \&{long} \\{temp};\7 ${}\\{ppp\_x}\K\\{dpi\_x}/\T{72.27}*\\{magstep\_x};{}$\6 ${}\\{ppp\_y}\K\\{dpi\_y}/\T{72.27}*\\{magstep\_y}{}$;\7 ${}\\{pk\_total\_min\_x}\K\\{pk\_offset\_x};{}$\6 ${}\\{pk\_total\_max\_x}\K\\{pk\_output\_size\_x}+\T{2}*\\{pk\_offset\_x};{}$\6 ${}\\{pk\_total\_min\_y}\K\\{pk\_offset\_y};{}$\6 ${}\\{pk\_total\_max\_y}\K\\{pk\_output\_size\_y}+\\{pk\_offset\_y}{}$;\7 ${}\\{pk\_dx}\K\\{pk\_width}+\T{2}*\\{pk\_offset\_x}{}$;\C{ no slant }\6 ${}\\{tfm\_width}\K(\\{tfm\_output\_size\_x}+\T{2}*\\{tfm\_offset\_x})*\.{\_2% \_20}{}$;\C{ width in multiples of design size $* 2^{20}$ }\7 \X22:Special section\X\6 \X23:Post section\X\6 \X24:Postpost section\X\6 \4${}\}{}$\2\par \fi \M{22} \.{XXXn} will be followed by n~bytes representing the length of a string which follows immediately. \PB{\.{YYY}} is a 32~bit integer which is normally connected with the preceding string (but not used here). \PB{\\{special\_adr}} contains the address of the ``special section''. All items here are optional. \Y\B\4\D$\.{XXX1}$ \5 \T{239}\C{ these are all special command bytes }\par \B\4\D$\.{XXX2}$ \5 \T{240}\C{ not used }\par \B\4\D$\.{XXX3}$ \5 \T{241}\C{ not used }\par \B\4\D$\.{XXX4}$ \5 \T{242}\C{ not used }\Y\par \B\4\D$\.{YYY}$ \5 \T{243}\C{ not used }\par \Y\B\4\X22:Special section\X${}\E{}$\6 $\\{special\_adr}\K\\{ftell}(\\{out}){}$;\7 \&{if} ${}({*}\\{coding}){}$\5 ${}\{{}$\1\6 ${}\\{fputc}(\.{XXX1},\39\\{out}){}$;\C{ \PB{\.{XXX1}} implies a string length % \PB{$<$ \T{256}} }\6 ${}\\{fputc}(\\{strlen}(\\{coding}),\39\\{out});{}$\6 ${}\\{fputs}(\\{coding},\39\\{out});{}$\6 \4${}\}{}$\2\7 \&{if} ${}({*}\\{comment}){}$\5 ${}\{{}$\1\6 ${}\\{fputc}(\.{XXX1},\39\\{out});{}$\6 ${}\\{fputc}(\\{strlen}(\\{comment}),\39\\{out});{}$\6 ${}\\{fputs}(\\{comment},\39\\{out});{}$\6 \4${}\}{}$\2\par \U21.\fi \M{23} All character offsets collected in \PB{\\{char\_adr}} will be written to the output file. \PB{\\{fputl}(\,)} writes a 32~bit integer into a file. \PB{\.{CHAR\_LOC0}} (and \PB{\.{CHAR\_LOC}}) is the first byte of a character locator (i.e., offset, character code, and width information). \PB{\.{POST}} starts the postamble, and \PB{\\{post\_adr}} points to the beginning byte of the postamble. \Y\B\4\D$\.{POST}$ \5 \T{248}\Y\par \B\4\D$\.{CHAR\_LOC}$ \5 \T{245}\par \B\4\D$\.{CHAR\_LOC0}$ \5 \T{246}\C{ simplified version of \PB{\.{CHAR\_LOC}} }\par \Y\B\4\X23:Post section\X${}\E{}$\6 $\\{post\_adr}\K\\{ftell}(\\{out});{}$\6 ${}\\{fputc}(\.{POST},\39\\{out});{}$\6 ${}\\{fputl}(\\{special\_adr},\39\\{out}){}$;\7 ${}\\{fputl}(\\{designsize},\39\\{out});{}$\6 ${}\\{fputl}(\\{checksum},\39\\{out});{}$\6 ${}\\{fputl}(\\{ppp\_x}*\.{\_2\_16},\39\\{out});{}$\6 ${}\\{fputl}(\\{ppp\_y}*\.{\_2\_16},\39\\{out});{}$\6 ${}\\{fputl}(\\{pk\_total\_min\_x},\39\\{out});{}$\6 ${}\\{fputl}(\\{pk\_total\_max\_x},\39\\{out});{}$\6 ${}\\{fputl}(\\{pk\_total\_min\_y},\39\\{out});{}$\6 ${}\\{fputl}(\\{pk\_total\_max\_y},\39\\{out}){}$;\7 ${}\\{char\_adr\_p}\K\\{char\_adr}{}$;\7 \&{if} ${}(\\{pk\_dx}<\T{256}){}$\5 ${}\{{}$\1\6 \&{for} ${}(\|i\K\T{0};{}$ ${}\|i<\\{last\_char};{}$ ${}\|i\PP{}$)\C{ the character locators }\6 ${}\{{}$\1\6 ${}\\{fputc}(\.{CHAR\_LOC0},\39\\{out});{}$\6 ${}\\{fputc}(\|i,\39\\{out});{}$\6 ${}\\{fputc}(\\{pk\_dx},\39\\{out});{}$\6 ${}\\{fputl}(\\{tfm\_width},\39\\{out});{}$\6 ${}\\{fputl}({*}\\{char\_adr\_p}\PP,\39\\{out});{}$\6 \4${}\}{}$\2\6 \4${}\}{}$\2\6 \&{else}\C{ will only happen if \PB{$\.{MAX\_CHAR\_SIZE}\G\T{256}$} }\6 ${}\{{}$\1\6 \&{for} ${}(\|i\K\T{0};{}$ ${}\|i<\\{last\_char};{}$ ${}\|i\PP){}$\5 ${}\{{}$\1\6 ${}\\{fputc}(\.{CHAR\_LOC},\39\\{out});{}$\6 ${}\\{fputc}(\|i,\39\\{out});{}$\6 ${}\\{fputl}(\\{pk\_dx}*\.{\_2\_16},\39\\{out});{}$\6 ${}\\{fputl}(\T{0},\39\\{out});{}$\6 ${}\\{fputl}(\\{tfm\_width},\39\\{out});{}$\6 ${}\\{fputl}({*}\\{char\_adr\_p}\PP,\39\\{out});{}$\6 \4${}\}{}$\2\6 \4${}\}{}$\2\par \U21.\fi \M{24} \PB{\.{POSTPOST}} starts the section after the postamble. To get all information in a \.{GF} file, you must start here. The very last bytes of the file have the value \PB{\.{POSTPOST\_ID}} (the file is filled with at least 4 of these bytes until a file length of a multiple of~4 is reached). Going backwards a \PB{\.{GF\_ID}} will be next, then comes the address of the postamble section. Jumping to the postamble, a \PB{\.{POST}} byte comes first, then the address of the special section, and afterwards all character offsets. These offsets and addresses describe the whole file. \Y\B\4\D$\.{POSTPOST}$ \5 \T{249}\par \B\4\D$\.{POSTPOST\_ID}$ \5 \T{223}\par \Y\B\4\X24:Postpost section\X${}\E{}$\6 $\\{fputc}(\.{POSTPOST},\39\\{out});{}$\6 ${}\\{fputl}(\\{post\_adr},\39\\{out});{}$\6 ${}\\{fputc}(\.{GF\_ID},\39\\{out});{}$\6 ${}\\{temp}\K\\{ftell}(\\{out});{}$\6 ${}\|i\K(\&{int})(\\{temp}\MOD\T{4})+\T{4};{}$\6 \&{while} ${}(\|i\MM){}$\1\5 ${}\\{fputc}(\.{POSTPOST\_ID},\39\\{out}){}$;\2\par \U21.\fi \M{25} \TeX\ wants the most significant byte first. \Y\B\4\X11:Prototypes\X${}\mathrel+\E{}$\6 \&{static} \&{void} ${}\\{fputl}(\&{long},\39{}$\&{FILE} ${}{*}){}$;\par \fi \M{26} \Y\B\&{static} \&{void} \\{fputl}(\&{long} \\{num}${},\39{}$\&{FILE} ${}{*}% \|f){}$\1\1\2\2\6 ${}\{{}$\1\6 ${}\\{fputc}(\\{num}\GG\T{24},\39\|f);{}$\6 ${}\\{fputc}(\\{num}\GG\T{16},\39\|f);{}$\6 ${}\\{fputc}(\\{num}\GG\T{8},\39\|f);{}$\6 ${}\\{fputc}(\\{num},\39\|f);{}$\6 \4${}\}{}$\2\par \fi \M{27} \PB{\\{make\_pixel\_array}(\,)} scales a character into the array \PB{\\{out% \_char}[\,]} where each \\{byte} represents one pixel, contrary to the input file where each \\{bit} is used to store the character bitmap. \PB{\.{BLACK}} indicates a black pixel. The scaling routine was modeled after the program \.{pnmscale} of the \.{pbmplus} package. \.{pbmplus} was designed to handle arbitrary pictures, and bitmaps are only a special case of a graymap with values from~0 for white up to \PB{$\.{PIXEL\_MAXVAL}\K\T{255}$} for black. If \PB{\.{EOF}} is encountered, \PB{\\{end\_of\_file}} is set and the function returns immediately. \Y\B\4\D$\.{BLACK}$ \5 \T{1}\par \B\4\D$\.{WHITE}$ \5 \T{0}\Y\par \B\4\D$\.{PIXEL\_MAXVAL}$ \5 \T{255}\par \B\4\D$\.{SCALE}$ \5 \T{4096}\par \B\4\D$\.{HALFSCALE}$ \5 \T{2048}\Y\par \B\4\D$\.{MAX\_CHAR\_SIZE}$ \5 \T{1023}\par \Y\B\4\X2:Global variables\X${}\mathrel+\E{}$\6 \&{HBF\_CHAR} \\{code};\6 \&{const} \&{unsigned} \&{char} ${}{*}\\{bitmap}{}$;\C{ a proper input bitmap array will be allocated by the HBF API }\6 \&{const} \&{unsigned} \&{char} ${}{*}\\{bP}{}$;\7 \&{unsigned} \&{char} ${}\\{out\_char}[\.{MAX\_CHAR\_SIZE}*\.{MAX\_CHAR\_SIZE}+% \T{1}]{}$;\C{ the output bitmap array }\6 \&{unsigned} \&{char} ${}{*}\\{out\_char\_p}{}$;\7 \&{unsigned} \&{char} \\{pixelrow}[\.{MAX\_CHAR\_SIZE}];\6 \&{unsigned} \&{char} \\{temp\_pixelrow}[\.{MAX\_CHAR\_SIZE}];\6 \&{unsigned} \&{char} ${}\\{new\_pixelrow}[\.{MAX\_CHAR\_SIZE}+\T{1}]{}$;\C{ we need space to append a white pixel }\7 \&{int} \\{curr\_row};\C{ for \PB{\\{read\_row}(\,)} if we access the glyph rotated }\6 \&{long} \\{grayrow}[\.{MAX\_CHAR\_SIZE}];\7 \&{long} \\{s\_mag\_x}${},{}$ \\{s\_mag\_y}${},{}$ \\{s\_slant};\par \fi \M{28} We need to initialize the \PB{\\{grayrow}[\,]} array together with some other variables. Two steps are necessary to compute the \PB{\\{code}} if we are in the \mf-like mode. Assuming that we search the code \.{0xXXYY}, we first set \PB{\\{code}} to the value \.{0xXXAA}, where \.{0xAA} is equal to \PB{\\{min\_2\_byte}} (getting \PB{\\{offset}} as the number of remaining characters to reach the first character in our given subfont), then we increment \PB{\\{code}} (and decrement \PB{% \\{offset}}) until \PB{\\{offset}} equals~0. \Y\B\4\X28:Initialize variables\X${}\E{}$\6 ${}\{{}$\1\6 \&{int} \\{col}${},{}$ \\{offset};\7 \&{if} (\\{rotation})\5 ${}\{{}$\1\6 \&{int} \\{tmp};\7 ${}\\{tmp}\K\\{input\_size\_x};{}$\6 ${}\\{input\_size\_x}\K\\{input\_size\_y};{}$\6 ${}\\{input\_size\_y}\K\\{tmp};{}$\6 \4${}\}{}$\2\7 \&{if} (\\{mf\_like})\5 ${}\{{}$\1\6 ${}\\{target\_size\_x}\K\\{design\_size}*(\\{x\_resolution}/\\{dpi\_x});{}$\6 ${}\\{target\_size\_y}\K\\{design\_size}*(\\{x\_resolution}*\\{y\_scale}/\\{dpi% \_y});{}$\6 \4${}\}{}$\2\6 \&{else}\1\5 ${}\\{target\_size\_x}\K\\{target\_size\_y}\K\\{design\_size};{}$\2\6 ${}\\{magstep\_x}\K\\{target\_size\_x}/\\{design\_size};{}$\6 ${}\\{magstep\_y}\K\\{target\_size\_y}/\\{design\_size}{}$;\7 ${}\\{pk\_offset\_x}\K\\{offset\_x}*\\{magstep\_x}+\T{0.5};{}$\6 ${}\\{pk\_offset\_y}\K\\{offset\_y}*\\{magstep\_y}+\T{0.5};{}$\6 ${}\\{tfm\_offset\_x}\K\\{offset\_x}/(\\{dpi\_x}/\T{72.27})/\\{design% \_size};{}$\6 ${}\\{tfm\_offset\_y}\K\\{offset\_y}/(\\{dpi\_y}/\T{72.27})/\\{design% \_size}{}$;\7 ${}\\{pk\_width}\K\\{input\_size\_x}*\\{mag\_x}*\\{magstep\_x}+\T{0.5}{}$;\C{ without slant }\6 ${}\\{pk\_output\_size\_x}\K\\{input\_size\_x}*\\{mag\_x}*\\{magstep\_x}+% \\{input\_size\_y}*\\{mag\_y}*\\{magstep\_y}*\\{slant}+\T{0.5};{}$\6 ${}\\{pk\_output\_size\_y}\K\\{input\_size\_y}*\\{mag\_y}*\\{magstep\_y}+% \T{0.5};{}$\6 ${}\\{tfm\_output\_size\_x}\K\\{input\_size\_x}*\\{mag\_x}/(\\{dpi\_x}/% \T{72.27})/\\{design\_size};{}$\6 ${}\\{tfm\_output\_size\_y}\K\\{input\_size\_y}*\\{mag\_y}/(\\{dpi\_y}/% \T{72.27})/\\{design\_size};{}$\6 \&{if} ${}(\\{pk\_output\_size\_x}>\.{MAX\_CHAR\_SIZE}){}$\5 ${}\{{}$\1\6 ${}\\{fprintf}(\\{stderr},\39\.{"Output\ character\ bo}\)\.{x\ width\ too\ big% \\n"});{}$\6 \\{exit}(\T{1});\6 \4${}\}{}$\2\6 \&{if} ${}(\\{pk\_output\_size\_y}>\.{MAX\_CHAR\_SIZE}){}$\5 ${}\{{}$\1\6 ${}\\{fprintf}(\\{stderr},\39\.{"Output\ character\ bo}\)\.{x\ height\ too\ big% \\n"});{}$\6 \\{exit}(\T{1});\6 \4${}\}{}$\2\7 \&{for} ${}(\\{col}\K\T{0};{}$ ${}\\{col}<\\{input\_size\_x};{}$ ${}\PP% \\{col}){}$\1\5 ${}\\{grayrow}[\\{col}]\K\.{HALFSCALE}{}$;\2\7 \&{if} ${}(\R\\{mf\_like}){}$\1\5 ${}\\{code}\K(\\{min\_char}\AND\T{\^FF00})+\\{min\_2\_byte};{}$\2\6 \&{else}\5 ${}\{{}$\1\6 \&{if} ${}((\\{file\_number}<(\\{unicode}\?\T{0}:\T{1}))\V(\\{file\_number}\G% \T{\^100})){}$\5 ${}\{{}$\1\6 ${}\\{fprintf}(\\{stderr},\39\.{"Invalid\ subfile\ num}\)\.{ber\\n"});{}$\6 \\{exit}(\T{1});\6 \4${}\}{}$\2\7 \&{if} (\\{unicode})\5 ${}\{{}$\1\6 ${}\\{offset}\K\T{0};{}$\6 ${}\\{code}\K\\{file\_number}*\T{\^100};{}$\6 \4${}\}{}$\2\6 \&{else}\5 ${}\{{}$\1\6 ${}\\{offset}\K(\\{file\_number}-\T{1})*\T{256}\MOD\\{nmb\_2\_bytes};{}$\6 ${}\\{code}\K(\\{min\_char}\AND\T{\^FF00})+\\{min\_2\_byte}+(\\{file\_number}-% \T{1})*\T{256}/\\{nmb\_2\_bytes}*\T{\^100};{}$\6 \4${}\}{}$\2\7 \&{while} ${}(\\{offset}\MM){}$\1\6 \&{while} ${}(\R\\{b2\_codes}[\\{code}\PP\AND\T{\^FF}]{}$)\C{ eliminate invalid \PB{\\{b2\_codes}} }\1\6 ;\2\2\7 \&{if} ${}(\\{code}>\\{max\_char}){}$\5 ${}\{{}$\1\6 ${}\\{fprintf}(\\{stderr},\39\.{"Invalid\ subfile\ num}\)\.{ber\\n"});{}$\6 \\{exit}(\T{1});\6 \4${}\}{}$\2\6 \4${}\}{}$\2\6 ${}\\{s\_mag\_x}\K\\{mag\_x}*\\{magstep\_x}*\.{SCALE};{}$\6 ${}\\{s\_mag\_y}\K\\{mag\_y}*\\{magstep\_y}*\.{SCALE};{}$\6 ${}\\{s\_slant}\K\\{slant}*\.{SCALE};{}$\6 \4${}\}{}$\2\par \U4.\fi \M{29} All arrays of the \\{pixelrow} family contain gray values. While scaling with non-integer values a pixel of the input bitmap will normally not align with the pixel grid of the output bitmap (geometrically spoken). In this case we first compute the fractions of input pixel rows scaled vertically and add the corresponding gray values until a temporary row is produced. Then we repeat this procedure horizontally pixel by pixel and write the result into an output array. \Y\B\4\X11:Prototypes\X${}\mathrel+\E{}$\6 \&{static} \&{void} \\{make\_pixel\_array}(\&{void});\par \fi \M{30} \Y\B\&{static} \&{void} \\{make\_pixel\_array}(\&{void})\1\1\2\2\6 ${}\{{}$\1\6 \&{unsigned} \&{char} ${}{*}\\{prP};{}$\6 \&{unsigned} \&{char} ${}{*}\\{temp\_prP};{}$\6 \&{unsigned} \&{char} ${}{*}\\{new\_prP};{}$\6 \&{long} ${}{*}\\{grP}{}$;\7 \&{register} \&{unsigned} \&{char} ${}{*}\\{xP};{}$\6 \&{register} \&{unsigned} \&{char} ${}{*}\\{nxP}{}$;\7 \&{register} \&{int} \\{row}${},{}$ \\{col};\6 \&{int} \\{rows\_read}${}\K\T{0};{}$\6 \&{register} \&{int} \\{need\_to\_read\_row}${}\K\T{1}{}$;\7 \&{long} \\{frac\_row\_to\_fill}${}\K\.{SCALE};{}$\6 \&{long} \\{frac\_row\_left}${}\K\\{s\_mag\_y}{}$;\7 \&{int} \\{no\_code}${}\K\.{FALSE};{}$\7 ${}\\{prP}\K\\{pixelrow};{}$\6 ${}\\{temp\_prP}\K\\{temp\_pixelrow};{}$\6 ${}\\{new\_prP}\K\\{new\_pixelrow};{}$\6 ${}\\{grP}\K\\{grayrow};{}$\6 ${}\\{out\_char\_p}\K\\{out\_char}{}$;\C{ will be increased by \PB{\\{write% \_row}(\,)} }\7 \4\\{again}:\6 \&{if} ${}(\\{b2\_codes}[\\{code}\AND\T{\^FF}]{}$)\C{ a valid second byte? }\6 ${}\{{}$\1\6 \&{if} (\\{pk\_files})\5 ${}\{{}$\1\6 ${}\\{bitmap}\K\\{hbfGetBitmap}(\\{hbf},\39\\{code});{}$\6 ${}\\{bP}\K\\{bitmap}{}$;\C{ will be increased by \PB{\\{read\_row}(\,)} }\7 \&{if} ${}(\R\\{bitmap}){}$\1\5 ${}\\{empty\_char}\K\.{TRUE};{}$\2\6 \&{else}\1\5 \X31:Scale row by row\X\2\6 \4${}\}{}$\2\6 \4${}\}{}$\2\6 \&{else}\1\5 ${}\\{no\_code}\K\.{TRUE}{}$;\2\7 \&{if} ${}((\\{code}\AND\T{\^FF})\E\\{max\_2\_byte}){}$\1\5 ${}\\{code}\MRL{+{\K}}\T{\^FF}-(\\{max\_2\_byte}-\\{min\_2\_byte}){}$;\C{ go to next plane }\2\6 \&{if} ${}(\\{code}\G\\{max\_char}){}$\5 ${}\{{}$\1\6 ${}\\{end\_of\_file}\K\.{TRUE};{}$\6 \&{return};\6 \4${}\}{}$\2\7 ${}\\{code}\PP{}$;\7 \&{if} (\\{no\_code})\5 ${}\{{}$\1\6 ${}\\{no\_code}\K\.{FALSE};{}$\6 \&{goto} \\{again};\6 \4${}\}{}$\2\6 \4${}\}{}$\2\par \fi \M{31} \Y\B\4\X31:Scale row by row\X${}\E{}$\6 ${}\{{}$\1\6 \&{if} ${}(\\{pk\_output\_size\_y}\E\\{input\_size\_y}{}$)\C{ shortcut Y~scaling if possible }\1\6 ${}\\{temp\_prP}\K\\{prP}{}$;\2\7 ${}\\{curr\_row}\K\\{input\_size\_y}-\T{1}{}$;\C{ only needed for rotated glyphs }\6 \&{for} ${}(\\{row}\K\T{0};{}$ ${}\\{row}<\\{pk\_output\_size\_y};{}$ ${}\PP% \\{row}){}$\5 ${}\{{}$\1\6 \X32:Scale Y from \PB{\\{pixelrow}[\,]} into \PB{\\{temp\_pixelrow}[\,]}\X\6 \X34:Scale X from \PB{\\{temp\_pixelrow}[\,]} into \PB{\\{new\_pixelrow}[\,]} and write it into \PB{\\{out\_char}[\,]}\X\6 \4${}\}{}$\2\6 \4${}\}{}$\2\par \U30.\fi \M{32} \Y\B\4\X32:Scale Y from \PB{\\{pixelrow}[\,]} into \PB{\\{temp\_pixelrow}[\,]}% \X${}\E{}$\6 \&{if} ${}(\\{pk\_output\_size\_y}\E\\{input\_size\_y}{}$)\C{ shortcut Y~scaling if possible }\1\6 \\{read\_row}(\\{prP});\2\6 \&{else}\5 ${}\{{}$\1\6 \&{while} ${}(\\{frac\_row\_left}<\\{frac\_row\_to\_fill}){}$\5 ${}\{{}$\1\6 \&{if} (\\{need\_to\_read\_row})\1\6 \&{if} ${}(\\{rows\_read}<\\{input\_size\_y}){}$\5 ${}\{{}$\1\6 \\{read\_row}(\\{prP});\6 ${}\PP\\{rows\_read};{}$\6 \4${}\}{}$\2\2\7 \&{for} ${}(\\{col}\K\T{0},\39\\{xP}\K\\{prP};{}$ ${}\\{col}<\\{input\_size% \_x};{}$ ${}\PP\\{col},\39\PP\\{xP}){}$\1\5 ${}\\{grP}[\\{col}]\MRL{+{\K}}\\{frac\_row\_left}*({*}\\{xP}){}$;\2\7 ${}\\{frac\_row\_to\_fill}\MRL{-{\K}}\\{frac\_row\_left};{}$\6 ${}\\{frac\_row\_left}\K\\{s\_mag\_y};{}$\6 ${}\\{need\_to\_read\_row}\K\T{1};{}$\6 \4${}\}{}$\2\7 \X33:Produce a temporary row\X\6 \4${}\}{}$\2\par \U31.\fi \M{33} Now \PB{$\\{frac\_row\_left}\G\\{frac\_row\_to\_fill}$}, so we can produce a row. \Y\B\4\X33:Produce a temporary row\X${}\E{}$\6 \&{if} (\\{need\_to\_read\_row})\1\6 \&{if} ${}(\\{rows\_read}<\\{input\_size\_y}){}$\5 ${}\{{}$\1\6 \\{read\_row}(\\{prP});\6 ${}\PP\\{rows\_read};{}$\6 ${}\\{need\_to\_read\_row}\K\T{0};{}$\6 \4${}\}{}$\2\2\7 \&{for} ${}(\\{col}\K\T{0},\39\\{xP}\K\\{prP},\39\\{nxP}\K\\{temp\_prP};{}$ ${}% \\{col}<\\{input\_size\_x};{}$ ${}\PP\\{col},\39\PP\\{xP},\39\PP\\{nxP}){}$\5 ${}\{{}$\1\6 \&{register} \&{long} \|g;\7 ${}\|g\K\\{grP}[\\{col}]+\\{frac\_row\_to\_fill}*({*}\\{xP});{}$\6 ${}\|g\MRL{{/}{\K}}\.{SCALE};{}$\6 \&{if} ${}(\|g>\.{PIXEL\_MAXVAL}){}$\1\5 ${}\|g\K\.{PIXEL\_MAXVAL}{}$;\2\7 ${}{*}\\{nxP}\K\|g;{}$\6 ${}\\{grP}[\\{col}]\K\.{HALFSCALE};{}$\6 \4${}\}{}$\2\7 ${}\\{frac\_row\_left}\MRL{-{\K}}\\{frac\_row\_to\_fill};{}$\6 \&{if} ${}(\\{frac\_row\_left}\E\T{0}){}$\5 ${}\{{}$\1\6 ${}\\{frac\_row\_left}\K\\{s\_mag\_y};{}$\6 ${}\\{need\_to\_read\_row}\K\T{1};{}$\6 \4${}\}{}$\2\6 ${}\\{frac\_row\_to\_fill}\K\.{SCALE}{}$;\par \U32.\fi \M{34} To implement the slant we move the starting point \PB{\\{nxP}} to the right according to the corresponding \PB{\|y}~value. To simplify life only positive shift values are allowed. We always append a white pixel to avoid artefacts at the end of the line produced by the last line. This rule sets the second condition that the slant must not be greater than~\PB{\T{1}}---such a large slant would be unusable anyway for typesetting purposes. \Y\B\4\X34:Scale X from \PB{\\{temp\_pixelrow}[\,]} into \PB{\\{new\_pixelrow}[% \,]} and write it into \PB{\\{out\_char}[\,]}\X${}\E{}$\6 \&{if} ${}(\\{pk\_width}\E\\{input\_size\_x}\W\\{s\_slant}\E\T{0}{}$)\C{ shortcut X~scaling if possible }\1\6 \\{write\_row}(\\{temp\_prP});\2\6 \&{else}\5 ${}\{{}$\1\6 \&{register} \&{long} \|g${}\K\.{HALFSCALE};{}$\6 \&{register} \&{long} \\{frac\_col\_to\_fill}${}\K\.{SCALE};{}$\6 \&{register} \&{long} \\{frac\_col\_left};\6 \&{register} \&{int} \\{need\_col}${}\K\T{0};{}$\7 ${}\\{nxP}\K\\{new\_prP}{}$;\7 ${}\\{frac\_col\_left}\K(\\{pk\_output\_size\_y}-\\{row})*\\{s\_slant};{}$\6 \&{while} ${}(\\{frac\_col\_left}\G\\{frac\_col\_to\_fill}){}$\5 ${}\{{}$\1\6 ${}{*}(\\{nxP}\PP)\K\T{0};{}$\6 ${}\\{frac\_col\_left}\MRL{-{\K}}\\{frac\_col\_to\_fill};{}$\6 \4${}\}{}$\2\7 \&{if} ${}(\\{frac\_col\_left}>\T{0}){}$\1\5 ${}\\{frac\_col\_to\_fill}\MRL{-{\K}}\\{frac\_col\_left}{}$;\2\7 \&{for} ${}(\\{col}\K\T{0},\39\\{xP}\K\\{temp\_prP};{}$ ${}\\{col}<\\{input% \_size\_x};{}$ ${}\PP\\{col},\39\PP\\{xP}){}$\5 ${}\{{}$\1\6 ${}\\{frac\_col\_left}\K\\{s\_mag\_x};{}$\6 \&{while} ${}(\\{frac\_col\_left}\G\\{frac\_col\_to\_fill}){}$\5 ${}\{{}$\1\6 \&{if} (\\{need\_col})\5 ${}\{{}$\1\6 ${}\PP\\{nxP};{}$\6 ${}\|g\K\.{HALFSCALE};{}$\6 \4${}\}{}$\2\7 ${}\|g\MRL{+{\K}}\\{frac\_col\_to\_fill}*({*}\\{xP});{}$\6 ${}\|g\MRL{{/}{\K}}\.{SCALE};{}$\6 \&{if} ${}(\|g>\.{PIXEL\_MAXVAL}){}$\1\5 ${}\|g\K\.{PIXEL\_MAXVAL}{}$;\2\7 ${}{*}\\{nxP}\K\|g;{}$\6 ${}\\{frac\_col\_left}\MRL{-{\K}}\\{frac\_col\_to\_fill};{}$\6 ${}\\{frac\_col\_to\_fill}\K\.{SCALE};{}$\6 ${}\\{need\_col}\K\T{1};{}$\6 \4${}\}{}$\2\7 \&{if} ${}(\\{frac\_col\_left}>\T{0}){}$\5 ${}\{{}$\1\6 \&{if} (\\{need\_col})\5 ${}\{{}$\1\6 ${}\PP\\{nxP};{}$\6 ${}\|g\K\.{HALFSCALE};{}$\6 ${}\\{need\_col}\K\T{0};{}$\6 \4${}\}{}$\2\7 ${}\|g\MRL{+{\K}}\\{frac\_col\_left}*({*}\\{xP});{}$\6 ${}\\{frac\_col\_to\_fill}\MRL{-{\K}}\\{frac\_col\_left};{}$\6 \4${}\}{}$\2\6 \4${}\}{}$\2\7 \X35:Write out a row\X\6 \4${}\}{}$\2\par \U31.\fi \M{35} \Y\B\4\X35:Write out a row\X${}\E{}$\6 \&{if} ${}(\\{frac\_col\_to\_fill}>\T{0}){}$\5 ${}\{{}$\1\6 ${}\MM\\{xP};{}$\6 ${}\|g\MRL{+{\K}}\\{frac\_col\_to\_fill}*({*}\\{xP});{}$\6 \4${}\}{}$\2\7 \&{if} ${}(\R\\{need\_col}){}$\5 ${}\{{}$\1\6 ${}\|g\MRL{{/}{\K}}\.{SCALE};{}$\6 \&{if} ${}(\|g>\.{PIXEL\_MAXVAL}){}$\1\5 ${}\|g\K\.{PIXEL\_MAXVAL};{}$\2\6 ${}{*}\\{nxP}\K\|g;{}$\6 \4${}\}{}$\2\7 ${}{*}(\PP\\{nxP})\K\T{0}{}$;\C{ append a blank pixel }\7 \\{write\_row}(\\{new\_prP});\par \U34.\fi \M{36} \PB{\\{read\_row}(\,)} reads a row from \PB{\\{bitmap}[\,]} and converts it into a graymap row. If the \PB{\\{rotation}} flag has been set, we get the proper column instead (note that in this case \PB{\\{input\_size\_x}} already reflects the width of the rotated glyph). \Y\B\4\X11:Prototypes\X${}\mathrel+\E{}$\6 \&{static}\6 \8\#\&{ifdef} \.{\_\_GNUC\_\_}\6 \&{\_\_inline\_\_}\6 \8\#\&{endif}\6 \&{void} \\{read\_row}(\&{unsigned} \&{char} ${}{*}){}$;\par \fi \M{37} \Y\B\&{static}\6 \8\#\&{ifdef} \.{\_\_GNUC\_\_}\6 \&{\_\_inline\_\_}\6 \8\#\&{endif}\6 \&{void} \\{read\_row}(\&{unsigned} \&{char} ${}{*}\\{pixelrow}){}$\1\1\2\2\6 ${}\{{}$\1\6 \&{register} \&{int} \\{col}${},{}$ \\{bitshift}${},{}$ \\{offset};\6 \&{register} \&{unsigned} \&{char} ${}{*}\\{xP};{}$\6 \&{register} \&{unsigned} \&{char} \\{item}${}\K\T{0};{}$\7 \&{if} (\\{rotation})\5 ${}\{{}$\1\6 ${}\\{bitshift}\K\T{7}-(\\{curr\_row}\MOD\T{8});{}$\6 ${}\\{offset}\K(\\{input\_size\_y}+\T{7})/\T{8};{}$\6 ${}\\{bP}\K\\{bitmap}+\\{curr\_row}/\T{8};{}$\6 \&{for} ${}(\\{col}\K\T{0},\39\\{xP}\K\\{pixelrow};{}$ ${}\\{col}<\\{input% \_size\_x};{}$ ${}\PP\\{col},\39\PP\\{xP}){}$\5 ${}\{{}$\1\6 ${}{*}\\{xP}\K(({*}\\{bP}\GG\\{bitshift})\AND\T{1})\E\T{1}\?\.{PIXEL\_MAXVAL}:% \T{0};{}$\6 ${}\\{bP}\MRL{+{\K}}\\{offset};{}$\6 \4${}\}{}$\2\6 ${}\\{curr\_row}\MM;{}$\6 \4${}\}{}$\2\6 \&{else}\5 ${}\{{}$\1\6 ${}\\{bitshift}\K{-}\T{1};{}$\6 \&{for} ${}(\\{col}\K\T{0},\39\\{xP}\K\\{pixelrow};{}$ ${}\\{col}<\\{input% \_size\_x};{}$ ${}\PP\\{col},\39\PP\\{xP}){}$\5 ${}\{{}$\1\6 \&{if} ${}(\\{bitshift}\E{-}\T{1}){}$\5 ${}\{{}$\1\6 ${}\\{item}\K{*}(\\{bP}\PP){}$;\C{ increase input bitmap pointer }\6 ${}\\{bitshift}\K\T{7};{}$\6 \4${}\}{}$\2\6 ${}{*}\\{xP}\K((\\{item}\GG\\{bitshift})\AND\T{1})\E\T{1}\?\.{PIXEL\_MAXVAL}:% \T{0};{}$\6 ${}\MM\\{bitshift};{}$\6 \4${}\}{}$\2\6 \4${}\}{}$\2\6 \4${}\}{}$\2\par \fi \M{38} \PB{\\{write\_row}(\,)} converts the graymap back into a bitmap using a simple threshold. \Y\B\4\X2:Global variables\X${}\mathrel+\E{}$\6 \&{int} \\{threshold}${}\K\T{128}{}$;\par \fi \M{39} \Y\B\4\X11:Prototypes\X${}\mathrel+\E{}$\6 \&{static}\6 \8\#\&{ifdef} \.{\_\_GNUC\_\_}\6 \&{\_\_inline\_\_}\6 \8\#\&{endif}\6 \&{void} \\{write\_row}(\&{unsigned} \&{char} ${}{*}){}$;\par \fi \M{40} \Y\B\&{static}\6 \8\#\&{ifdef} \.{\_\_GNUC\_\_}\6 \&{\_\_inline\_\_}\6 \8\#\&{endif}\6 \&{void} \\{write\_row}(\&{unsigned} \&{char} ${}{*}\\{pixelrow}){}$\1\1\2\2\6 ${}\{{}$\1\6 \&{register} \&{int} \\{col};\6 \&{register} \&{unsigned} \&{char} ${}{*}\\{xP};{}$\7 \&{for} ${}(\\{col}\K\T{0},\39\\{xP}\K\\{pixelrow};{}$ ${}\\{col}<\\{pk\_output% \_size\_x};{}$ ${}\PP\\{col},\39\PP\\{xP}){}$\1\5 ${}{*}(\\{out\_char\_p}\PP)\K({*}\\{xP}\G\\{threshold})\?\T{1}:\T{0}{}$;\C{ increase output bitmap pointer }\2\6 \4${}\}{}$\2\par \fi \M{41} Now comes the most interesting routine. The pixel array will be compressed in sequences of black and white pixels. \PB{\.{SKIP0}}, \PB{\.{SKIP1}}, and \PB{\.{SKIP2}} indicate how many blank lines will be skipped. \PB{\.{PAINT\_}(\|x)} means that the next x~pixels will have the same color, then the color changes. \PB{\.{NEW\_ROW\_}(\|x)} is the first black pixel in the next row. An example: the pixel sequence 111100011001 [new row] 000111011110 will be output as 4 3 2 2 1 77 3 1 4 1. Commands with an ending~`n' in its name indicate that the next n~bytes should be read as the counter. Example: \PB{\.{SKIP1}}~26 means `skip the next 26~rows'. For further details please refer to ``\mf---the program''. \Y\B\4\D$\.{PAINT\_}(\|x)$ \5 (\|x)\C{ $0 \le x \le 63$ }\par \B\4\D$\.{PAINT1}$ \5 \T{64}\par \B\4\D$\.{PAINT2}$ \5 \T{65}\par \B\4\D$\.{PAINT3}$ \5 \T{66}\C{ not used }\Y\par \B\4\D$\.{SKIP0}$ \5 \T{70}\par \B\4\D$\.{SKIP1}$ \5 \T{71}\par \B\4\D$\.{SKIP2}$ \5 \T{72}\par \B\4\D$\.{SKIP3}$ \5 \T{73}\C{ not used }\Y\par \B\4\D$\.{NEW\_ROW\_}(\|x)$ \5 $((\|x)+\T{74}{}$)\C{ $0 \le x \le 164$ }\Y\par \B\4\D$\.{NOOP}$ \5 \T{244}\C{ not used }\par \Y\B\4\X11:Prototypes\X${}\mathrel+\E{}$\6 \&{static} \&{void} \\{write\_coding}(\&{void});\par \fi \M{42} The \PB{\&{goto} \\{start}} instruction causes some compilers to complain about ``Unreachable code $\ldots$'' or something similar. \Y\B\&{static} \&{void} \\{write\_coding}(\&{void})\1\1\2\2\6 ${}\{{}$\1\6 \&{register} \&{int} \\{count}${},{}$ \\{skip};\6 \&{register} \&{unsigned} \&{char} \\{paint};\6 \&{register} \&{int} \|x${},{}$ \|y;\6 \&{register} \&{unsigned} \&{char} ${}{*}\\{cp};{}$\7 ${}\|x\K\T{0};{}$\6 ${}\|y\K\T{0};{}$\6 ${}\\{cp}\K\\{out\_char}+\|y*\\{pk\_output\_size\_x}+\|x;{}$\6 ${}\\{count}\K\\{skip}\K\T{0};{}$\6 ${}\\{paint}\K\.{WHITE};{}$\6 \&{goto} \\{start};\7 \&{while} ${}(\|y<\\{pk\_output\_size\_y}){}$\5 ${}\{{}$\1\6 \X43:Search blank lines\X\6 \4\\{start}:\5 \X44:Process rest of line\X\6 ${}\|y\PP;{}$\6 \4${}\}{}$\2\6 \4${}\}{}$\2\Y\par \fi \M{43} \Y\B\4\X43:Search blank lines\X${}\E{}$\6 $\\{count}\K\T{0};{}$\6 ${}\|x\K\T{0};{}$\6 ${}\\{cp}\K\\{out\_char}+\|y*\\{pk\_output\_size\_x}+\|x{}$;\7 \&{while} ${}(\|x<\\{pk\_output\_size\_x}){}$\5 ${}\{{}$\1\6 \&{if} ${}({*}\\{cp}\E\\{paint}){}$\1\5 ${}\\{count}\PP;{}$\2\6 \&{else}\5 ${}\{{}$\1\6 \&{if} ${}(\\{skip}\E\T{0}){}$\5 ${}\{{}$\1\6 \&{if} ${}(\\{count}\Z\T{164}){}$\1\5 ${}\\{fputc}(\.{NEW\_ROW\_}(\\{count}),\39\\{out});{}$\2\6 \&{else}\5 ${}\{{}$\1\6 ${}\\{fputc}(\.{SKIP0},\39\\{out}){}$;\7 \&{if} ${}(\\{count}<\T{256}){}$\5 ${}\{{}$\1\6 ${}\\{fputc}(\.{PAINT1},\39\\{out});{}$\6 ${}\\{fputc}(\\{count},\39\\{out});{}$\6 \4${}\}{}$\2\6 \&{else}\5 ${}\{{}$\1\6 ${}\\{fputc}(\.{PAINT2},\39\\{out});{}$\6 ${}\\{fputc}(\\{count}\GG\T{8},\39\\{out});{}$\6 ${}\\{fputc}(\\{count}\AND\T{\^FF},\39\\{out});{}$\6 \4${}\}{}$\2\6 \4${}\}{}$\2\6 \4${}\}{}$\2\6 \&{else}\5 ${}\{{}$\1\6 \&{if} ${}(\\{skip}\E\T{1}){}$\1\5 ${}\\{fputc}(\.{SKIP0},\39\\{out});{}$\2\6 \&{else}\5 ${}\{{}$\1\6 \&{if} ${}(\\{skip}<\T{256}){}$\5 ${}\{{}$\1\6 ${}\\{fputc}(\.{SKIP1},\39\\{out});{}$\6 ${}\\{fputc}(\\{skip},\39\\{out});{}$\6 \4${}\}{}$\2\6 \&{else}\5 ${}\{{}$\1\6 ${}\\{fputc}(\.{SKIP2},\39\\{out});{}$\6 ${}\\{fputc}(\\{skip}\GG\T{8},\39\\{out});{}$\6 ${}\\{fputc}(\\{skip}\AND\T{\^FF},\39\\{out});{}$\6 \4${}\}{}$\2\6 \4${}\}{}$\2\6 ${}\\{skip}\K\T{0};{}$\6 \&{if} ${}(\\{count}<\T{64}){}$\1\5 ${}\\{fputc}(\.{PAINT\_}(\\{count}),\39\\{out});{}$\2\6 \&{else} \&{if} ${}(\\{count}<\T{256}){}$\5 ${}\{{}$\1\6 ${}\\{fputc}(\.{PAINT1},\39\\{out});{}$\6 ${}\\{fputc}(\\{count},\39\\{out});{}$\6 \4${}\}{}$\2\6 \&{else}\5 ${}\{{}$\1\6 ${}\\{fputc}(\.{PAINT2},\39\\{out});{}$\6 ${}\\{fputc}(\\{count}\GG\T{8},\39\\{out});{}$\6 ${}\\{fputc}(\\{count}\AND\T{\^FF},\39\\{out});{}$\6 \4${}\}{}$\2\6 \4${}\}{}$\2\6 ${}\\{count}\K\T{0};{}$\6 ${}\\{paint}\K\.{BLACK};{}$\6 \&{break};\6 \4${}\}{}$\2\6 ${}\|x\PP;{}$\6 ${}\\{cp}\PP;{}$\6 \4${}\}{}$\2\6 \&{if} ${}(\|x\G\\{pk\_output\_size\_x}){}$\5 ${}\{{}$\1\6 ${}\\{skip}\PP;{}$\6 ${}\|y\PP;{}$\6 \&{continue};\6 \4${}\}{}$\2\par \U42.\fi \M{44} \Y\B\4\X44:Process rest of line\X${}\E{}$\6 \&{while} ${}(\|x<\\{pk\_output\_size\_x}){}$\5 ${}\{{}$\1\6 \&{if} ${}({*}\\{cp}\E\\{paint}){}$\1\5 ${}\\{count}\PP;{}$\2\6 \&{else}\5 ${}\{{}$\1\6 \&{if} ${}(\\{count}<\T{64}){}$\1\5 ${}\\{fputc}(\.{PAINT\_}(\\{count}),\39\\{out});{}$\2\6 \&{else} \&{if} ${}(\\{count}<\T{256}){}$\5 ${}\{{}$\1\6 ${}\\{fputc}(\.{PAINT1},\39\\{out});{}$\6 ${}\\{fputc}(\\{count},\39\\{out});{}$\6 \4${}\}{}$\2\6 \&{else}\5 ${}\{{}$\1\6 ${}\\{fputc}(\.{PAINT2},\39\\{out});{}$\6 ${}\\{fputc}(\\{count}\GG\T{8},\39\\{out});{}$\6 ${}\\{fputc}(\\{count}\AND\T{\^FF},\39\\{out});{}$\6 \4${}\}{}$\2\6 ${}\\{count}\K\T{1};{}$\6 ${}\\{paint}\K\.{BLACK}-\\{paint};{}$\6 \4${}\}{}$\2\6 ${}\|x\PP;{}$\6 ${}\\{cp}\PP;{}$\6 \4${}\}{}$\2\6 \&{if} ${}(\\{paint}\E\.{BLACK}){}$\5 ${}\{{}$\1\6 \&{if} ${}(\\{count}<\T{64}){}$\1\5 ${}\\{fputc}(\.{PAINT\_}(\\{count}),\39\\{out});{}$\2\6 \&{else} \&{if} ${}(\\{count}<\T{256}){}$\5 ${}\{{}$\1\6 ${}\\{fputc}(\.{PAINT1},\39\\{out});{}$\6 ${}\\{fputc}(\\{count},\39\\{out});{}$\6 \4${}\}{}$\2\6 \&{else}\5 ${}\{{}$\1\6 ${}\\{fputc}(\.{PAINT2},\39\\{out});{}$\6 ${}\\{fputc}(\\{count}\GG\T{8},\39\\{out});{}$\6 ${}\\{fputc}(\\{count}\AND\T{\^FF},\39\\{out});{}$\6 \4${}\}{}$\2\6 ${}\\{paint}\K\.{WHITE};{}$\6 \4${}\}{}$\2\par \U42.\fi \N{1}{45}The font metrics file. This routine creates one \.{PL} file with the font properties. None of the \TeX\ font dimensions are needed because you never will use CJK fonts directly, and intercharacter stretching is handled by the \\{CJK} macro \.{\\CJKglue}. (Other packages may define similar commands.) The name of the \.{PL} file will contain the running two digits in \mf-like mode only. It makes sense \\{not} to compute the check sum automatically for two reasons. Firstly, since \TeX's checksum algorithm is based on the character width, the number of valid characters, and the designsize, there is a much higher chance that two subfonts from different HBF fonts have the same check sum than it is for ordinary fonts, because all characters have the same width, usually 256~characters in a subfont, and very often the same design size. Secondly, and this is more important, we create just one \.{TFM} file for all subfonts regardless of the real number of characters in a particular subfont. To have an identification string in the \.{TFM} file, we split it into single bytes and use the \.{HEADER} command repeatedly. \Y\B\4\X11:Prototypes\X${}\mathrel+\E{}$\6 \&{static} \&{void} \\{write\_pl}(\&{void});\par \fi \M{46} \Y\B\&{static} \&{void} \\{write\_pl}(\&{void})\1\1\2\2\6 ${}\{{}$\1\6 \&{int} \|i${},{}$ \\{pos};\6 \&{char} ${}\\{output\_file}[\.{FILE\_NAME\_LENGTH}+\T{1}];{}$\6 \&{long} \|t${},{}$ \\{sc};\6 \&{char} ${}{*}\|s;{}$\6 \&{char} \\{tfm\_header}[\,]${}\K\.{"Created\ by\ hbf2gf"};{}$\7 ${}\\{file\_number}\MM{}$;\C{ for \mf-like mode }\7 \&{if} (\\{mf\_like})\5 ${}\{{}$\1\6 \&{if} (\\{unicode})\1\5 ${}\\{sprintf}(\\{output\_file},\39\.{"\%s\%02x.pl"},\39\\{output\_name},\39% \\{file\_number});{}$\2\6 \&{else}\1\5 ${}\\{sprintf}(\\{output\_file},\39\.{"\%s\%02i.pl"},\39\\{output\_name},\39% \\{file\_number});{}$\2\6 \4${}\}{}$\2\6 \&{else}\1\5 ${}\\{sprintf}(\\{output\_file},\39\.{"\%s.pl"},\39\\{output\_name}){}$;\2\7 \&{if} ${}(\R(\\{out}\K\\{fopen}(\\{output\_file},\39\.{WRITE\_TXT}))){}$\5 ${}\{{}$\1\6 ${}\\{fprintf}(\\{stderr},\39\.{"Couldn't\ open\ `\%s'\\}\)\.{n"},\39\\{output% \_file});{}$\6 \\{exit}(\T{1});\6 \4${}\}{}$\2\6 \&{if} ${}(\R\\{quiet}){}$\1\5 ${}\\{printf}(\.{"\\nWriting\ `\%s'\\n"},\39\\{output\_file}){}$;\2\7 ${}\\{fprintf}(\\{out},{}$\6 \.{"\\n(FAMILY\ \%s\%d)"}\6 \.{"\\n(CODINGSCHEME\ CJK}\)\.{-\%s)"}${},\39\\{output\_name},\39\\{file% \_number},\39\\{font\_encoding}){}$;\7 ${}\\{fprintf}(\\{out},{}$\6 \.{"\\n(DESIGNSIZE\ R\ \%.6}\)\.{f)"}\6 \.{"\\n(COMMENT\ DESIGNSI}\)\.{ZE\ IS\ IN\ POINTS)"}\6 \.{"\\n(COMMENT\ OTHER\ SI}\)\.{ZES\ ARE\ MULTIPLES\ OF}\)\.{\ DESIGNSIZE)"}\6 \.{"\\n(CHECKSUM\ O\ \%lo)"}\6 \.{"\\n(FONTDIMEN"}\6 \.{"\\n\ \ \ (SLANT\ R\ \%.6f)}\)\.{"}\6 \.{"\\n\ \ \ (SPACE\ R\ 0.0)"}\6 \.{"\\n\ \ \ (STRETCH\ R\ 0.0}\)\.{)"}\6 \.{"\\n\ \ \ (SHRINK\ R\ 0.0)}\)\.{"}\6 \.{"\\n\ \ \ (XHEIGHT\ R\ 1.0}\)\.{)"}\6 \.{"\\n\ \ \ (QUAD\ R\ 1.0)"}\6 \.{"\\n\ \ \ (EXTRASPACE\ R\ }\)\.{0.0)"}\6 \.{"\\n\ \ \ )"}${},\39\\{design\_size},\39\\{checksum},\39\\{slant}){}$;\7 ${}\|s\K\\{tfm\_header};{}$\6 ${}\|i\K\\{strlen}(\|s);{}$\6 ${}\|t\K{}$((\&{long}) \|i)${}\LL\T{24};{}$\6 ${}\\{sc}\K\T{16};{}$\6 ${}\\{pos}\K\T{18}{}$;\7 ${}\\{fprintf}(\\{out},\39\.{"\\n"});{}$\6 \&{while} ${}(\|i>\T{0}){}$\5 ${}\{{}$\1\6 ${}\|t\MRL{{\OR}{\K}}((\&{long})({*}{}$(\&{unsigned} \&{char} ${}{*}){}$ \|s${}% \PP))\LL\\{sc};{}$\6 ${}\\{sc}\MRL{-{\K}}\T{8};{}$\6 \&{if} ${}(\\{sc}<\T{0}){}$\5 ${}\{{}$\1\6 ${}\\{fprintf}(\\{out},\39\.{"\\n(HEADER\ D\ \%d\ O\ \%l}\)\.{o)"},\39\\{pos},% \39\|t);{}$\6 ${}\|t\K\T{0};{}$\6 ${}\\{sc}\K\T{24};{}$\6 ${}\\{pos}\PP;{}$\6 \4${}\}{}$\2\6 ${}\|i\MM;{}$\6 \4${}\}{}$\2\6 \&{if} (\|t)\1\5 ${}\\{fprintf}(\\{out},\39\.{"\\n(HEADER\ D\ \%d\ O\ \%l}\)\.{o)"},\39\\{pos},% \39\|t);{}$\2\6 ${}\\{fprintf}(\\{out},\39\.{"\\n"}){}$;\7 \&{for} ${}(\|i\K\T{0};{}$ ${}\|i<\T{256};{}$ ${}\|i\PP){}$\5 ${}\{{}$\1\6 ${}\\{fprintf}(\\{out},{}$\6 \.{"\\n(CHARACTER\ O\ \%o"}\6 \.{"\\n\ \ \ (CHARWD\ R\ \%.6f}\)\.{)"}\6 \.{"\\n\ \ \ (CHARHT\ R\ \%.6f}\)\.{)"}\6 \.{"\\n\ \ \ (CHARDP\ R\ \%.6f}\)\.{)"}\6 \.{"\\n\ \ \ (CHARIC\ R\ \%.6f}\)\.{)"}\6 \.{"\\n\ \ \ )"}${},{}$\6 \|i${},\39\\{tfm\_output\_size\_x}+\T{2}*\\{tfm\_offset\_x},\39\\{tfm\_output% \_size\_y}+\\{tfm\_offset\_y},\39{-}\\{tfm\_offset\_y},\39\\{slant}*(\\{tfm% \_output\_size\_y}+\\{tfm\_offset\_y}));{}$\6 \4${}\}{}$\2\7 \\{fclose}(\\{out});\6 \4${}\}{}$\2\par \fi \N{1}{47}The extended virtual font file for \Om. The following is very similar to \PB{\\{write\_pl}(\,)}; we simply map the glyphs of the subfonts back to the original encoding positions. \Y\B\4\X11:Prototypes\X${}\mathrel+\E{}$\6 \&{static} \&{void} \\{write\_ovp}(\&{void});\par \fi \M{48} \Y\B\&{static} \&{void} \\{write\_ovp}(\&{void})\1\1\2\2\6 ${}\{{}$\1\6 \&{int} \|c${},{}$ \|i${},{}$ \\{nmb\_subfonts}${},{}$ \\{remainder}${},{}$ % \\{count}${},{}$ \\{pos};\6 \&{char} ${}\\{output\_file}[\.{FILE\_NAME\_LENGTH}+\T{1}];{}$\6 \&{long} \|t${},{}$ \\{sc};\6 \&{char} ${}{*}\|s;{}$\6 \&{char} \\{ofm\_header}[\,]${}\K\.{"Created\ by\ hbf2gf"};{}$\7 ${}\\{nmb\_subfonts}\K((\\{max\_char}-(\\{min\_char}\AND\T{\^FF00}))/\T{256}*% \\{nmb\_2\_bytes})/\T{256}+\T{1};{}$\6 ${}\\{remainder}\K((\\{max\_char}-(\\{min\_char}\AND\T{\^FF00}))/\T{256}*\\{nmb% \_2\_bytes})\MOD\T{256}{}$;\C{ correction for the last incomplete second byte range }\6 \&{for} ${}(\\{count}\K\T{0};{}$ ${}\\{count}<(\\{max\_char}\AND\T{\^FF});{}$ ${}\\{count}\PP){}$\1\6 \&{if} (\\{b2\_codes}[\\{count}])\1\5 ${}\\{remainder}\PP;{}$\2\2\6 \&{if} ${}(\\{remainder}\G\T{256}){}$\1\5 ${}\\{nmb\_subfonts}\PP{}$;\2\7 ${}\\{sprintf}(\\{output\_file},\39\.{"\%s.ovp"},\39\\{output\_name}){}$;\7 \&{if} ${}(\R(\\{out}\K\\{fopen}(\\{output\_file},\39\.{WRITE\_TXT}))){}$\5 ${}\{{}$\1\6 ${}\\{fprintf}(\\{stderr},\39\.{"Couldn't\ open\ `\%s'\\}\)\.{n"},\39\\{output% \_file});{}$\6 \\{exit}(\T{1});\6 \4${}\}{}$\2\6 \&{if} ${}(\R\\{quiet}){}$\1\5 ${}\\{printf}(\.{"\\nWriting\ `\%s'\\n"},\39\\{output\_file}){}$;\2\7 ${}\\{fprintf}(\\{out},{}$\6 \.{"\\n(VTITLE\ Omega\ vir}\)\.{tual\ font\ created\ by}\)\.{\ hbf2gf)"}\6 \.{"\\n(DESIGNSIZE\ R\ \%.6}\)\.{f)"}\6 \.{"\\n(COMMENT\ DESIGNSI}\)\.{ZE\ IS\ IN\ POINTS)"}\6 \.{"\\n(COMMENT\ OTHER\ SI}\)\.{ZES\ ARE\ MULTIPLES\ OF}\)\.{\ DESIGNSIZE)"}\6 \.{"\\n(CHECKSUM\ O\ \%lo)"}\6 \.{"\\n(FONTDIMEN"}\6 \.{"\\n\ \ \ (SLANT\ R\ \%.6f)}\)\.{"}\6 \.{"\\n\ \ \ (SPACE\ R\ 0.0)"}\6 \.{"\\n\ \ \ (STRETCH\ R\ 0.0}\)\.{)"}\6 \.{"\\n\ \ \ (SHRINK\ R\ 0.0)}\)\.{"}\6 \.{"\\n\ \ \ (XHEIGHT\ R\ 1.0}\)\.{)"}\6 \.{"\\n\ \ \ (QUAD\ R\ 1.0)"}\6 \.{"\\n\ \ \ (EXTRASPACE\ R\ }\)\.{0.0)"}\6 \.{"\\n\ \ \ )"}${},\39\\{design\_size},\39\\{checksum},\39\\{slant}){}$;\7 ${}\|s\K\\{ofm\_header};{}$\6 ${}\|i\K\\{strlen}(\|s);{}$\6 ${}\|t\K{}$((\&{long}) \|i)${}\LL\T{24};{}$\6 ${}\\{sc}\K\T{16};{}$\6 ${}\\{pos}\K\T{18}{}$;\7 ${}\\{fprintf}(\\{out},\39\.{"\\n"});{}$\6 \&{while} ${}(\|i>\T{0}){}$\5 ${}\{{}$\1\6 ${}\|t\MRL{{\OR}{\K}}((\&{long})({*}{}$(\&{unsigned} \&{char} ${}{*}){}$ \|s${}% \PP))\LL\\{sc};{}$\6 ${}\\{sc}\MRL{-{\K}}\T{8};{}$\6 \&{if} ${}(\\{sc}<\T{0}){}$\5 ${}\{{}$\1\6 ${}\\{fprintf}(\\{out},\39\.{"\\n(HEADER\ D\ \%d\ O\ \%l}\)\.{o)"},\39\\{pos},% \39\|t);{}$\6 ${}\|t\K\T{0};{}$\6 ${}\\{sc}\K\T{24};{}$\6 ${}\\{pos}\PP;{}$\6 \4${}\}{}$\2\6 ${}\|i\MM;{}$\6 \4${}\}{}$\2\6 \&{if} (\|t)\1\5 ${}\\{fprintf}(\\{out},\39\.{"\\n(HEADER\ D\ \%d\ O\ \%l}\)\.{o)"},\39\\{pos},% \39\|t);{}$\2\6 ${}\\{fprintf}(\\{out},\39\.{"\\n"}){}$;\7 \&{for} ${}(\|i\K\T{0};{}$ ${}\|i<\\{nmb\_subfonts};{}$ ${}\|i\PP){}$\5 ${}\{{}$\1\6 ${}\\{fprintf}(\\{out},{}$\6 \.{"\\n(MAPFONT\ D\ \%i"}\6 \.{"\\n\ \ \ (FONTNAME\ \%s\%0}\)\.{2i)"}\6 \.{"\\n\ \ \ (FONTCHECKSUM\ }\)\.{O\ \%lo)"}\6 \.{"\\n\ \ \ (FONTAT\ R\ 1.0)}\)\.{"}\6 \.{"\\n\ \ \ (FONTDSIZE\ R\ \%}\)\.{.6f)"}\6 \.{"\\n\ \ \ )"}${},\39\|i,\39\\{output\_name},\39\|i+\T{1},\39\\{checksum},\39% \\{design\_size});{}$\6 \4${}\}{}$\2\7 \&{for} ${}(\|c\K\\{min\_char},\39\|i\K\T{0},\39\\{count}\K\T{0};{}$ ${}\|c\Z% \\{max\_char};{}$ ${}\|c\PP){}$\5 ${}\{{}$\1\6 \&{if} ${}(\\{b2\_codes}[\|c\AND\T{\^FF}]\E\.{VALID\_SUBCODE}){}$\5 ${}\{{}$\1\6 ${}\\{fprintf}(\\{out},{}$\6 \.{"\\n(CHARACTER\ O\ \%o"}\6 \.{"\\n\ \ \ (CHARWD\ R\ \%.6f}\)\.{)"}\6 \.{"\\n\ \ \ (CHARHT\ R\ \%.6f}\)\.{)"}\6 \.{"\\n\ \ \ (CHARDP\ R\ \%.6f}\)\.{)"}\6 \.{"\\n\ \ \ (CHARIC\ R\ \%.6f}\)\.{)"}\6 \.{"\\n\ \ \ (MAP"}\6 \.{"\\n\ \ \ \ \ \ (SELECTFONT}\)\.{\ D\ \%i)"}\6 \.{"\\n\ \ \ \ \ \ (SETCHAR\ O\ }\)\.{\%o)"}\6 \.{"\\n\ \ \ \ \ \ )"}\6 \.{"\\n\ \ \ )"}${},{}$\6 \|c${},\39\\{tfm\_output\_size\_x}+\T{2}*\\{tfm\_offset\_x},\39\\{tfm\_output% \_size\_y}+\\{tfm\_offset\_y},\39{-}\\{tfm\_offset\_y},\39\\{slant}*(\\{tfm% \_output\_size\_y}+\\{tfm\_offset\_y}),\39\|i,\39\\{count}){}$;\7 ${}\\{count}\PP;{}$\6 \&{if} ${}(\\{count}\E\T{256}){}$\5 ${}\{{}$\1\6 ${}\\{count}\K\T{0};{}$\6 ${}\|i\PP;{}$\6 \4${}\}{}$\2\6 \4${}\}{}$\2\6 \&{else}\1\5 \&{continue};\2\6 \4${}\}{}$\2\7 \\{fclose}(\\{out});\6 \4${}\}{}$\2\par \fi \N{1}{49}The job file. This routine is the most system specific one. If your operating system needs a different outline, make appropriate changes here. You have to call this batch file after \.{hbf2gf} has finished (if not in \mf-like mode). It will transform the \.{GF} files into \.{PK} files and delete the now unnecessary \.{GF} files, then transform the \.{PL} file into a \.{TFM} file and copy it \PB{\\{nmb\_files}} times. The name of the job file is \PB{\\{output\_name}}. \Y\B\4\D$\.{EXTENSION\_LENGTH}$ \5 \T{8}\C{ the maximal length of a file extension }\Y\par \B\4\D$\.{GFTOPK\_NAME}$ \5 \.{"gftopk"}\par \B\4\D$\.{PLTOTF\_NAME}$ \5 \.{"pltotf"}\par \B\4\D$\.{OVP2OVF\_NAME}$ \5 \.{"ovp2ovf"}\par \Y\B\4\X2:Global variables\X${}\mathrel+\E{}$\6 \&{char} ${}\\{job\_extension}[\.{EXTENSION\_LENGTH}+\T{1}];{}$\6 \&{char} ${}\\{rm\_command}[\.{STRING\_LENGTH}+\T{1}];{}$\6 \&{char} ${}\\{cp\_command}[\.{STRING\_LENGTH}+\T{1}];{}$\6 \&{char} ${}\\{pk\_directory}[\.{STRING\_LENGTH}+\T{1}];{}$\6 \&{char} ${}\\{tfm\_directory}[\.{STRING\_LENGTH}+\T{1}]{}$;\7 \&{int} \\{ofm\_file}${}\K\.{FALSE}{}$;\par \fi \M{50} \Y\B\4\X11:Prototypes\X${}\mathrel+\E{}$\6 \&{static} \&{void} \\{write\_job}(\&{void});\par \fi \M{51} \Y\B\&{static} \&{void} \\{write\_job}(\&{void})\1\1\2\2\6 ${}\{{}$\1\6 \&{FILE} ${}{*}\\{out};{}$\6 \&{int} \|i${},{}$ \|j;\6 \&{char} ${}\\{buffer}[\.{FILE\_NAME\_LENGTH}+\T{1}];{}$\7 ${}\\{strcpy}(\\{buffer},\39\\{output\_name});{}$\6 ${}\\{strcat}(\\{buffer},\39\\{job\_extension});{}$\6 \&{if} ${}(\R(\\{out}\K\\{fopen}(\\{buffer},\39\.{WRITE\_TXT}))){}$\5 ${}\{{}$\1\6 ${}\\{fprintf}(\\{stderr},\39\.{"Couldn't\ open\ `\%s'\\}\)\.{n"},\39% \\{buffer});{}$\6 \\{exit}(\T{1});\6 \4${}\}{}$\2\6 \&{if} ${}(\R\\{quiet}){}$\1\5 ${}\\{printf}(\.{"\\nWriting\ `\%s'\\n"},\39\\{buffer}){}$;\2\7 \&{if} (\\{pk\_files})\5 ${}\{{}$\1\6 \&{if} (\\{unicode})\5 ${}\{{}$\1\6 \&{for} ${}(\|i\K(\\{min\_char}\GG\T{8}),\39\|j\K\T{0};{}$ ${}\|j<\\{nmb% \_files};{}$ ${}\|i\PP,\39\|j\PP){}$\1\5 ${}\\{fprintf}(\\{out},{}$\6 \.{"\%s\ \%s\%02x.gf\ \%s\%s\%0}\)\.{2x.\%.0ipk\\n"}\6 \.{"\%s\ \%s\%02x.gf\\n"}${},{}$\6 \.{GFTOPK\_NAME}${},\39\\{output\_name},\39\|i,{}$\6 \\{pk\_directory}${},\39\\{output\_name},\39\|i,\39\\{long\_extension}\?(% \&{int})(\\{dpi\_x}*\\{magstep\_x}+\T{0.5}):\T{0},{}$\6 \\{rm\_command}${},\39\\{output\_name},\39\|i);{}$\2\6 \4${}\}{}$\2\6 \&{else}\5 ${}\{{}$\1\6 \&{for} ${}(\|i\K\T{1};{}$ ${}\|i\Z\\{nmb\_files};{}$ ${}\|i\PP){}$\1\5 ${}\\{fprintf}(\\{out},{}$\6 \.{"\%s\ \%s\%02i.gf\ \%s\%s\%0}\)\.{2i.\%.0ipk\\n"}\6 \.{"\%s\ \%s\%02i.gf\\n"}${},{}$\6 \.{GFTOPK\_NAME}${},\39\\{output\_name},\39\|i,{}$\6 \\{pk\_directory}${},\39\\{output\_name},\39\|i,\39\\{long\_extension}\?(% \&{int})(\\{dpi\_x}*\\{magstep\_x}+\T{0.5}):\T{0},{}$\6 \\{rm\_command}${},\39\\{output\_name},\39\|i);{}$\2\6 \4${}\}{}$\2\6 \4${}\}{}$\2\7 \&{if} (\\{tfm\_files})\5 ${}\{{}$\1\6 ${}\\{fprintf}(\\{out},{}$\6 \.{"\\n"}\6 \.{"\%s\ \%s.pl\ \%s.tfm\\n"}\6 \.{"\%s\ \%s.pl\\n"}\6 \.{"\\n"}${},{}$\6 \.{PLTOTF\_NAME}${},\39\\{output\_name},\39\\{output\_name},{}$\6 \\{rm\_command}${},\39\\{output\_name}){}$;\7 \&{if} (\\{unicode})\5 ${}\{{}$\1\6 \&{for} ${}(\|i\K(\\{min\_char}\GG\T{8}),\39\|j\K\T{0};{}$ ${}\|j<\\{nmb% \_files};{}$ ${}\|i\PP,\39\|j\PP){}$\1\5 ${}\\{fprintf}(\\{out},{}$\6 \.{"\%s\ \%s.tfm\ \%s\%s\%02x.}\)\.{tfm\\n"}${},{}$\6 \\{cp\_command}${},\39\\{output\_name},\39\\{tfm\_directory},\39\\{output% \_name},\39\|i);{}$\2\6 \4${}\}{}$\2\6 \&{else}\5 ${}\{{}$\1\6 \&{for} ${}(\|i\K\T{1};{}$ ${}\|i\Z\\{nmb\_files};{}$ ${}\|i\PP){}$\1\5 ${}\\{fprintf}(\\{out},{}$\6 \.{"\%s\ \%s.tfm\ \%s\%s\%02i.}\)\.{tfm\\n"}${},{}$\6 \\{cp\_command}${},\39\\{output\_name},\39\\{tfm\_directory},\39\\{output% \_name},\39\|i);{}$\2\6 \4${}\}{}$\2\7 ${}\\{fprintf}(\\{out},{}$\6 \.{"\\n"}\6 \.{"\%s\ \%s.tfm"}${},{}$\6 \\{rm\_command}${},\39\\{output\_name});{}$\6 \4${}\}{}$\2\7 \&{if} (\\{ofm\_file})\5 ${}\{{}$\1\6 ${}\\{fprintf}(\\{out},{}$\6 \.{"\\n"}\6 \.{"\%s\ \%s.ovp\ \%s.ovf\ \%s}\)\.{.ofm\\n"}\6 \.{"\%s\ \%s.ovp\\n"}\6 \.{"\\n"}${},{}$\6 \.{OVP2OVF\_NAME}${},\39\\{output\_name},\39\\{output\_name},\39\\{output% \_name},{}$\6 \\{rm\_command}${},\39\\{output\_name});{}$\6 \4${}\}{}$\2\7 \\{fclose}(\\{out});\6 \4${}\}{}$\2\par \fi \N{1}{52}The configuration file. Here is a list with all necessary keywords (and parameters): \medskip \halign{\quad\.{#}\hfil&\quad#\hfil\cr hbf\_header & the HBF header file name of the input font(s). \cr output\_name & the name stem of the output files. \cr & Should be equal to the name of the configuration file in most cases.\cr & A running two digit decimal number starting with \.{01} will be appended. \cr & (For Unicode fonts see the keyword \.{unicode} below.) \cr } \bigskip And now all optional keywords: \medskip \halign{\quad\.{#}\hfil&\quad#\hfil\cr x\_offset & increases the character width. \cr & Will be applied on both sides; \cr & default is the value given in the HBF header (\.{HBF\_BITMAP\_BOUNDING\_BOX}) \cr & scaled to \\{design\/}size (in pixels). \cr y\_offset & shifts all characters up or down; \cr & default is the value given in the HBF header (\.{HBF\_BITMAP\_BOUNDING\_BOX}) \cr & scaled to \\{design\/}size (in pixels). \cr design\_size & the design size (in points) of the font. \cr & \.{x\_offset} and \.{y\_offset} refer to this size. \cr & Default is \PB{\T{10.0}} \cr target\_size & This command is obsolete now and will be ignored.\cr & \cr slant & the slant of the font (given as $\Delta x / \Delta y$). \cr & Only values in the range \PB{$\T{0}\Z\\{slant}\Z\T{1}$} are allowed. \cr & Default is \PB{\T{0.0}} \cr rotation & if set to `yes'. the glyphs are rotated 90~degrees counter-clockwise. \cr & The default offsets as given in the HBF header will be ignored (and set to~\PB{\T{0}}). \cr & Default is `no'. \cr & \cr mag\_x & \cr mag\_y & scaling values of the characters to reach design size. \cr & If only one magnification is given, x and y values are assumed to be equal. \cr & Default is \.{mag\_x} $=$ \.{mag\_y} $=$ \PB{\T{1.0}} \cr threshold & A value between \PB{\T{1}} and \PB{\T{254}} defining a threshold for converting the internal \cr & graymap into the output bitmap; lower values cut more pixels. \cr & Default value is \PB{\T{128}}. \cr & \cr comment & a comment describing the font; \cr & default is none. \cr & \cr nmb\_fonts & the number of the fonts. \cr & Default value is~\PB{${-}\T{1}$} for creating all fonts. \cr unicode & if `yes', a two digit hexadecimal number will be used as a running number, \cr & starting with the value of the first byte of the first code range. \cr & Default is `no'. \cr min\_char & the minimum of the encoding range. \cr & Specify this value if it is not identical to the lowest code value \cr & in the HBF file (to which it defaults). \cr & \cr dpi\_x & \cr dpi\_y & the horizontal and vertical resolution (in dpi) of the printer. \cr & If only one resolution is given, x and y values are assumed to be equal. \cr & Default is \PB{\T{300}}. \cr checksum & a checksum to identify the \.{GF} files with the appropriate \.{TFM} files. \cr & The default of this 32~bit unsigned integer is \PB{\T{0}}. \cr coding & a comment describing the coding scheme; \cr & default is none. \cr & \cr pk\_directory & the destination directory of the \.{PK} files; \cr & default: none. \cr & Attention! The batch file will not check whether this directory exists. \cr tfm\_directory & the destination directory of the \.{TFM} files; \cr & default: none. \cr & Attention! The batch file will not check whether this directory exists. \cr pk\_files & whether to create \.{PK} files or not; \cr & default is `yes'. \cr tfm\_files & whether to create \.{TFM} files or not; \cr & default is `yes'. \cr ofm\_file & whether to create an \.{OFM} and an \.{OVF} file or not; \cr & default is `no'. \cr long\_extension & if `yes', \.{PK} files will include the resolution in the extension \cr & (e.g. \.{gsso1201.300pk}). \cr & This affects the batch file only (default is `yes'). \cr rm\_command & this shell command removes files; \cr & default: `rm'. \cr cp\_command & this shell command copies files; \cr & default: `cp'. \cr job\_extension & the extension of the batch file which calls \.{GFtoPK} and \.{PLtoTF} \cr & to convert the \.{GF} and the \.{PL} files into \.{PK} and \.{TFM} files; \cr & default is none. \cr } \bigskip The searching algorithm (for the keywords) of \.{hbf2gf} is case insensitive; it makes no difference whether you write for example \.{comment} or \.{CommenT}. The keywords must start a line (be in the first column), and the corresponding parameters must be on the same line with the keyword and separated by at least one space or tabulator stop. Lines starting not with a keyword are ignored. Key values \\{are} case sensitive (except \.{yes} and \.{no}). The default system dependent values are for \UNIX/-like operating systems; if you use for example DOS, you must write \medskip \halign{\quad\.{#}\hfil&\quad\.{#}\hfil\cr long\_extension & no \cr rm\_command & del \cr cp\_command & copy \cr job\_extension & .bat \cr } \medskip Both the values \PB{\\{pk\_output\_size\_x}} and \PB{\\{pk\_output\_size\_y}} must not exceed \PB{\.{MAX\_CHAR\_SIZE}}; \.{x\_offset} and \.{y\_offset} are related to the design size (and not to the input size). In \mf-like mode, one \.{GF} file and one \.{PL} file will be computed (depending on the command line options \.{-g} and \.{-p}), taking \PB{\\{x\_resolution}} and \PB{\\{y\_scale}} from the command line. \.{nmb% \_fonts} will always be set to~\PB{\T{1}}; no job file will be created. \fi \M{53} \Y\B\4\D$\.{PRINTER\_MIN\_RES\_X}$ \5 \T{50}\par \B\4\D$\.{PRINTER\_MIN\_RES\_Y}$ \5 \T{50}\par \Y\B\4\X2:Global variables\X${}\mathrel+\E{}$\6 \&{char} ${}\\{Buffer}[\.{STRING\_LENGTH}+\T{1}]{}$;\par \fi \M{54} \Y\B\4\X11:Prototypes\X${}\mathrel+\E{}$\6 \&{static} \&{void} \\{read\_config}(\&{void});\par \fi \M{55} If \PB{\\{config\_file}} isn't found in \mf-like mode we assume that the font isn't a HBF font at all. \Y\B\&{static} \&{void} \\{read\_config}(\&{void})\1\1\2\2\6 ${}\{{}$\1\6 \&{HBF\_BBOX} ${}{*}\\{boxp};{}$\6 \&{char} ${}{*}\\{real\_config\_file};{}$\7 \X56:Handle extension\X\7 ${}\\{real\_config\_file}\K\\{TeX\_search\_cfg\_file}(\\{config\_file});{}$\6 \&{if} ${}(\R\\{real\_config\_file}){}$\5 ${}\{{}$\1\6 \&{if} (\\{mf\_like})\5 ${}\{{}$\1\6 \&{if} ${}(\R\\{quiet}){}$\1\5 ${}\\{printf}(\.{"Couldn't\ find\ `\%s'\\}\)\.{n"},\39\\{config\_file});{}$\2\6 \\{exit}(\T{2});\6 \4${}\}{}$\2\6 \&{else}\5 ${}\{{}$\1\6 ${}\\{fprintf}(\\{stderr},\39\.{"Couldn't\ find\ `\%s'\\}\)\.{n"},\39\\{config% \_file});{}$\6 \\{exit}(\T{1});\6 \4${}\}{}$\2\6 \4${}\}{}$\2\7 \&{if} ${}(\R(\\{config}\K\\{fopen}(\\{real\_config\_file},\39\.{READ% \_TXT}))){}$\5 ${}\{{}$\1\6 \&{if} ${}(\R\\{testing}){}$\5 ${}\{{}$\1\6 ${}\\{fprintf}(\\{stderr},\39\.{"Couldn't\ open\ `\%s'\\}\)\.{n"},\39\\{config% \_file});{}$\6 \\{exit}(\T{1});\6 \4${}\}{}$\2\6 \&{else}\C{ We reach this point only if no searching library is used }\6 ${}\{{}$\1\6 \&{if} ${}(\R\\{quiet}){}$\1\5 ${}\\{fprintf}(\\{stderr},\39\.{"Couldn't\ find\ or\ op}\)\.{en\ `\%s'\\n"},\39% \\{config\_file});{}$\2\6 \\{exit}(\T{2});\6 \4${}\}{}$\2\6 \4${}\}{}$\2\7 \&{if} (\\{testing})\5 ${}\{{}$\1\6 \&{if} ${}(\R\\{quiet}){}$\1\5 ${}\\{printf}(\.{"\%s\\n"},\39\\{real\_config\_file});{}$\2\6 \\{exit}(\T{0});\6 \4${}\}{}$\2\6 \X57:Necessary parameters\X\6 \X59:Optional parameters\X\7 \X61:Get code range\X\6 \X63:Get sub code range\X\7 \\{fclose}(\\{config});\6 \4${}\}{}$\2\par \fi \M{56} Here we check whether we have to add an extension. \Y\B\4\X56:Handle extension\X${}\E{}$\6 ${}\{{}$\1\6 \&{int} \|i${},{}$ \\{lastext}${}\K{-}\T{1};{}$\7 \&{for} ${}(\|i\K\T{0};{}$ \\{config\_file}[\|i]; ${}\|i\PP){}$\1\6 \&{if} ${}(\\{config\_file}[\|i]\E\.{'.'}){}$\1\5 ${}\\{lastext}\K\|i;{}$\2\6 \&{else} \&{if} ${}(\\{config\_file}[\|i]\E\.{'/'}\V\\{config\_file}[\|i]\E% \.{':'}\V\\{config\_file}[\|i]\E\.{'\\\\'}){}$\1\5 ${}\\{lastext}\K{-}\T{1}{}$;\2\2\7 \&{if} ${}(\\{lastext}\E{-}\T{1}){}$\1\5 ${}\\{strcat}(\\{config\_file},\39\.{".cfg"});{}$\2\6 \4${}\}{}$\2\par \U55.\fi \M{57} \Y\B\4\X57:Necessary parameters\X${}\E{}$\6 ${}\{{}$\1\6 \&{char} ${}\\{hbf\_header}[\.{STRING\_LENGTH}+\T{1}];{}$\6 \&{char} ${}{*}\\{real\_hbf\_header};{}$\7 \&{if} ${}(\R\\{fsearch}(\.{"hbf\_header"})){}$\1\5 \\{config\_error}(\.{"hbf\_header"});\2\6 \&{else}\1\5 ${}\\{strcpy}(\\{hbf\_header},\39\\{Buffer}){}$;\2\7 ${}\\{real\_hbf\_header}\K\\{TeX\_search\_hbf\_file}(\\{hbf\_header});{}$\6 \&{if} ${}(\R\\{real\_hbf\_header}){}$\5 ${}\{{}$\1\6 ${}\\{fprintf}(\\{stderr},\39\.{"Couldn't\ find\ `\%s'\\}\)\.{n"},\39\\{hbf% \_header});{}$\6 \\{exit}(\T{1});\6 \4${}\}{}$\2\7 ${}\\{hbfDebug}\K\T{1}{}$;\C{ we activate error messages of the HBF API while scanning the HBF header file }\7 \&{if} ${}(\R(\\{hbf}\K\\{hbfOpen}(\\{real\_hbf\_header}))){}$\1\5 \\{exit}(\T{1});\2\7 ${}\\{hbfDebug}\K\T{0}{}$;\7 ${}\\{boxp}\K\\{hbfBitmapBBox}(\\{hbf});{}$\6 ${}\\{input\_size\_x}\K\\{boxp}\MG\\{hbf\_height}{}$;\C{ will be checked later for rotation }\6 ${}\\{input\_size\_y}\K\\{boxp}\MG\\{hbf\_width};{}$\6 ${}\\{font\_encoding}\K\\{hbfProperty}(\\{hbf},\39\.{"HBF\_CODE\_SCHEME"}){}$;\7 \&{if} ${}(\R\\{fsearch}(\.{"output\_name"})){}$\1\5 \\{config\_error}(\.{"output\_name"});\2\6 \&{else}\1\5 ${}\\{strcpy}(\\{output\_name},\39\\{Buffer});{}$\2\6 \4${}\}{}$\2\par \U55.\fi \M{58} \Y\B\4\X2:Global variables\X${}\mathrel+\E{}$\6 \&{int} \\{offset\_x};\6 \&{int} \\{offset\_y};\7 \&{HBF\_CHAR} \\{user\_min\_char};\6 \&{int} \\{have\_min\_char}${}\K\.{FALSE}{}$;\par \fi \M{59} \Y\B\4\X59:Optional parameters\X${}\E{}$\6 ${}\{{}$\1\6 \&{if} (\\{fsearch}(\.{"nmb\_files"}))\1\5 ${}\\{nmb\_files}\K\\{atoi}(\\{Buffer});{}$\2\6 \&{if} (\\{fsearch}(\.{"unicode"}))\1\6 \&{if} ${}(\\{Buffer}[\T{0}]\E\.{'y'}\V\\{Buffer}[\T{0}]\E\.{'Y'}){}$\1\5 ${}\\{unicode}\K\.{TRUE};{}$\2\2\6 \&{if} (\\{fsearch}(\.{"min\_char"}))\5 ${}\{{}$\1\6 ${}\\{user\_min\_char}\K\\{strtoul}(\\{Buffer},\39{}$(\&{char} ${}{*}{*}){}$ ${}\NULL,\39\T{0});{}$\6 ${}\\{have\_min\_char}\K\.{TRUE};{}$\6 \4${}\}{}$\2\7 \&{if} ${}(\R\\{mf\_like}){}$\5 ${}\{{}$\1\6 \&{if} (\\{fsearch}(\.{"pk\_files"}))\1\6 \&{if} ${}(\\{Buffer}[\T{0}]\E\.{'n'}\V\\{Buffer}[\T{0}]\E\.{'N'}){}$\1\5 ${}\\{pk\_files}\K\.{FALSE};{}$\2\2\6 \&{if} (\\{fsearch}(\.{"tfm\_files"}))\1\6 \&{if} ${}(\\{Buffer}[\T{0}]\E\.{'n'}\V\\{Buffer}[\T{0}]\E\.{'N'}){}$\1\5 ${}\\{tfm\_files}\K\.{FALSE};{}$\2\2\6 \&{if} (\\{fsearch}(\.{"ofm\_file"}))\1\6 \&{if} ${}(\\{Buffer}[\T{0}]\E\.{'y'}\V\\{Buffer}[\T{0}]\E\.{'Y'}){}$\1\5 ${}\\{ofm\_file}\K\.{TRUE};{}$\2\2\6 \&{if} (\\{fsearch}(\.{"long\_extension"}))\1\6 \&{if} ${}(\\{Buffer}[\T{0}]\E\.{'n'}\V\\{Buffer}[\T{0}]\E\.{'N'}){}$\1\5 ${}\\{long\_extension}\K\.{FALSE};{}$\2\2\6 \4${}\}{}$\2\7 \&{if} (\\{fsearch}(\.{"slant"}))\1\5 ${}\\{slant}\K\\{atof}(\\{Buffer});{}$\2\6 \&{if} ${}(\\{slant}<\T{0.0}\V\\{slant}>\T{1.0}){}$\5 ${}\{{}$\1\6 ${}\\{fprintf}(\\{stderr},\39\.{"Invalid\ slant\\n"});{}$\6 \\{exit}(\T{1});\6 \4${}\}{}$\2\6 \&{if} (\\{fsearch}(\.{"rotation"}))\1\6 \&{if} ${}(\\{Buffer}[\T{0}]\E\.{'y'}\V\\{Buffer}[\T{0}]\E\.{'Y'}){}$\1\5 ${}\\{rotation}\K\.{TRUE}{}$;\2\2\7 \&{if} (\\{fsearch}(\.{"mag\_x"}))\1\5 ${}\\{mag\_x}\K\\{atof}(\\{Buffer});{}$\2\6 \&{if} (\\{fsearch}(\.{"mag\_y"}))\1\5 ${}\\{mag\_y}\K\\{atof}(\\{Buffer});{}$\2\6 \&{if} ${}(\R\\{mag\_x}\W\R\\{mag\_y}){}$\5 ${}\{{}$\1\6 ${}\\{mag\_x}\K\T{1.0};{}$\6 ${}\\{mag\_y}\K\T{1.0};{}$\6 \4${}\}{}$\2\6 \&{if} ${}(\\{mag\_x}\W\R\\{mag\_y}){}$\1\5 ${}\\{mag\_y}\K\\{mag\_x};{}$\2\6 \&{if} ${}(\\{mag\_y}\W\R\\{mag\_x}){}$\1\5 ${}\\{mag\_x}\K\\{mag\_y};{}$\2\6 \&{if} ${}(\\{mag\_x}\Z\T{0.0}){}$\5 ${}\{{}$\1\6 ${}\\{fprintf}(\\{stderr},\39\.{"Invalid\ horizontal\ }\)\.{magnification% \\n"});{}$\6 \\{exit}(\T{1});\6 \4${}\}{}$\2\6 \&{if} ${}(\\{mag\_y}\Z\T{0.0}){}$\5 ${}\{{}$\1\6 ${}\\{fprintf}(\\{stderr},\39\.{"Invalid\ vertical\ ma}\)\.{gnification% \\n"});{}$\6 \\{exit}(\T{1});\6 \4${}\}{}$\2\7 \&{if} (\\{fsearch}(\.{"dpi\_x"}))\1\5 ${}\\{dpi\_x}\K\\{atoi}(\\{Buffer});{}$\2\6 \&{if} (\\{fsearch}(\.{"dpi\_y"}))\1\5 ${}\\{dpi\_y}\K\\{atoi}(\\{Buffer});{}$\2\6 \&{if} ${}(\R\\{dpi\_x}\W\R\\{dpi\_y}){}$\5 ${}\{{}$\1\6 ${}\\{dpi\_x}\K\T{300};{}$\6 ${}\\{dpi\_y}\K\T{300};{}$\6 \4${}\}{}$\2\6 \&{if} ${}(\\{dpi\_x}\W\R\\{dpi\_y}){}$\1\5 ${}\\{dpi\_y}\K\\{dpi\_x};{}$\2\6 \&{if} ${}(\\{dpi\_y}\W\R\\{dpi\_x}){}$\1\5 ${}\\{dpi\_x}\K\\{dpi\_y};{}$\2\6 \&{if} ${}(\\{dpi\_x}\Z\.{PRINTER\_MIN\_RES\_X}){}$\5 ${}\{{}$\1\6 ${}\\{fprintf}(\\{stderr},\39\.{"Invalid\ horizontal\ }\)\.{printer\ resolution% \\n}\)\.{"});{}$\6 \\{exit}(\T{1});\6 \4${}\}{}$\2\6 \&{if} ${}(\\{dpi\_y}\Z\.{PRINTER\_MIN\_RES\_Y}){}$\5 ${}\{{}$\1\6 ${}\\{fprintf}(\\{stderr},\39\.{"Invalid\ vertical\ pr}\)\.{inter\ resolution% \\n"});{}$\6 \\{exit}(\T{1});\6 \4${}\}{}$\2\7 \&{if} (\\{fsearch}(\.{"design\_size"}))\1\5 ${}\\{design\_size}\K\\{atof}(\\{Buffer}){}$;\2\7 \&{if} (\\{fsearch}(\.{"x\_offset"}))\1\5 ${}\\{offset\_x}\K\\{atoi}(\\{Buffer});{}$\2\6 \&{else}\1\5 ${}\\{offset\_x}\K\\{rotation}\?\T{0}:(\\{boxp}\MG\\{hbf\_xDisplacement}*\\{mag% \_x}+\T{0.5});{}$\2\6 \&{if} (\\{fsearch}(\.{"y\_offset"}))\1\5 ${}\\{offset\_y}\K\\{atoi}(\\{Buffer});{}$\2\6 \&{else}\1\5 ${}\\{offset\_y}\K\\{rotation}\?\T{0}:(\\{boxp}\MG\\{hbf\_yDisplacement}*\\{mag% \_y}+\T{0.5});{}$\2\6 \&{if} ${}(\R\\{fsearch}(\.{"comment"})){}$\1\5 ${}\\{comment}[\T{0}]\K\.{'\\0'};{}$\2\6 \&{else}\1\5 ${}\\{strcpy}(\\{comment},\39\\{Buffer}){}$;\2\7 \&{if} (\\{fsearch}(\.{"threshold"}))\1\5 ${}\\{threshold}\K\\{atoi}(\\{Buffer});{}$\2\6 \&{if} ${}(\\{threshold}\Z\T{0}\V\\{threshold}\G\T{255}){}$\5 ${}\{{}$\1\6 ${}\\{fprintf}(\\{stderr},\39\.{"Invalid\ threshold\\n}\)\.{"});{}$\6 \\{exit}(\T{1});\6 \4${}\}{}$\2\7 \&{if} ${}(\R\\{fsearch}(\.{"checksum"})){}$\1\5 ${}\\{checksum}\K\T{0};{}$\2\6 \&{else}\1\5 ${}\\{checksum}\K\\{strtoul}(\\{Buffer},\39{}$(\&{char} ${}{*}{*}){}$ ${}\NULL,% \39\T{0}){}$;\2\7 \&{if} ${}(\R\\{fsearch}(\.{"coding"})){}$\1\5 ${}\\{coding}[\T{0}]\K\.{'\\0'};{}$\2\6 \&{else}\1\5 ${}\\{strcpy}(\\{coding},\39\\{Buffer}){}$;\2\7 \&{if} ${}(\R\\{fsearch}(\.{"pk\_directory"})){}$\1\5 ${}\\{pk\_directory}[\T{0}]\K\.{'\\0'};{}$\2\6 \&{else}\1\5 ${}\\{strcpy}(\\{pk\_directory},\39\\{Buffer}){}$;\2\7 \&{if} ${}(\R\\{fsearch}(\.{"tfm\_directory"})){}$\1\5 ${}\\{tfm\_directory}[\T{0}]\K\.{'\\0'};{}$\2\6 \&{else}\1\5 ${}\\{strcpy}(\\{tfm\_directory},\39\\{Buffer}){}$;\2\7 \&{if} (\\{fsearch}(\.{"rm\_command"}))\1\5 ${}\\{strcpy}(\\{rm\_command},\39\\{Buffer});{}$\2\6 \&{else}\1\5 ${}\\{strcpy}(\\{rm\_command},\39\.{"rm"}){}$;\2\7 \&{if} (\\{fsearch}(\.{"cp\_command"}))\1\5 ${}\\{strcpy}(\\{cp\_command},\39\\{Buffer});{}$\2\6 \&{else}\1\5 ${}\\{strcpy}(\\{cp\_command},\39\.{"cp"}){}$;\2\7 \&{if} ${}(\R\\{fsearch}(\.{"job\_extension"})){}$\1\5 ${}\\{job\_extension}[\T{0}]\K\.{'\\0'};{}$\2\6 \&{else}\5 ${}\{{}$\1\6 ${}\\{strncpy}(\\{job\_extension},\39\\{Buffer},\39\.{EXTENSION\_LENGTH});{}$\6 ${}\\{job\_extension}[\.{EXTENSION\_LENGTH}]\K\.{'\\0'};{}$\6 \4${}\}{}$\2\6 \4${}\}{}$\2\par \U55.\fi \M{60} The function \PB{\\{hbfGetCodeRange}(\,)} is an extension to the HBF API. Successive calls return the code ranges in ascending order; we only need the extrema of the whole code range. In case \PB{\\{min\_char}} has been supplied in the configuration file, we use that value instead. \Y\B\4\X2:Global variables\X${}\mathrel+\E{}$\6 \&{HBF\_CHAR} \\{min\_char}${},{}$ \\{max\_char};\par \fi \M{61} \Y\B\4\X61:Get code range\X${}\E{}$\6 ${}\{{}$\1\6 \&{const} \&{void} ${}{*}\\{cp};{}$\6 \&{HBF\_CHAR} \\{dummy};\7 ${}\\{cp}\K\\{hbfGetCodeRange}(\\{hbf},\39\NULL,\39{\AND}\\{min\_char},\39{% \AND}\\{max\_char});{}$\6 \&{for} ( ; ${}\\{cp}\I\NULL;{}$ ${}\\{cp}\K\\{hbfGetCodeRange}(\\{hbf},\39% \\{cp},\39{\AND}\\{dummy},\39{\AND}\\{max\_char})){}$\1\5 ;\2\7 \&{if} (\\{have\_min\_char})\1\5 ${}\\{min\_char}\K\\{user\_min\_char};{}$\2\6 \4${}\}{}$\2\par \U55.\fi \M{62} The function \PB{\\{hbfGetByte2Range}(\,)} is an extension to the HBF API. Successive calls return the byte~2 ranges in ascending order. We raise \PB{\.{VALID\_SUBCODE}} in the array \PB{\\{b2\_codes}[\,]} for all characters in subcode ranges. \Y\B\4\D$\.{VALID\_SUBCODE}$ \5 \T{1}\par \Y\B\4\X2:Global variables\X${}\mathrel+\E{}$\6 \&{char} \\{b2\_codes}[\T{256}];\6 \&{unsigned} \&{char} \\{min\_2\_byte}${},{}$ \\{max\_2\_byte};\6 \&{int} \\{nmb\_2\_bytes}${}\K\T{0}{}$;\par \fi \M{63} \Y\B\4\X63:Get sub code range\X${}\E{}$\6 ${}\{{}$\1\6 \&{const} \&{void} ${}{*}\\{b2r};{}$\6 \&{unsigned} \&{char} \\{dummy};\6 \&{int} \|i;\7 \&{for} ${}(\|i\K\T{0};{}$ ${}\|i<\T{256};{}$ ${}\|i\PP){}$\1\5 ${}\\{b2\_codes}[\|i]\K\T{0}{}$;\2\7 ${}\\{b2r}\K\\{hbfGetByte2Range}(\\{hbf},\39\NULL,\39{\AND}\\{min\_2\_byte},% \39{\AND}\\{max\_2\_byte});{}$\6 ${}\\{dummy}\K\\{min\_2\_byte};{}$\6 \&{for} ( ; ${}\\{b2r}\I\NULL;{}$ ${}\\{b2r}\K\\{hbfGetByte2Range}(\\{hbf},\39% \\{b2r},\39{\AND}\\{dummy},\39{\AND}\\{max\_2\_byte})){}$\5 ${}\{{}$\1\6 \&{for} ${}(\|i\K\\{dummy};{}$ ${}\|i\Z\\{max\_2\_byte};{}$ ${}\|i\PP){}$\1\5 ${}\\{b2\_codes}[\|i]\K\.{VALID\_SUBCODE};{}$\2\6 \4${}\}{}$\2\7 \&{for} ${}(\|i\K\T{0};{}$ ${}\|i<\T{256};{}$ ${}\|i\PP{}$)\C{ compute the number of valid \PB{\\{b2\_codes}} }\1\6 \&{if} ${}(\\{b2\_codes}[\|i]\E\.{VALID\_SUBCODE}){}$\1\5 ${}\\{nmb\_2\_bytes}\PP;{}$\2\2\6 \4${}\}{}$\2\par \U55.\fi \M{64} This search routine is case insignificant. Each keyword must start a line; the function checks whether the character before the keyword is a newline character (\PB{\.{'\\n'}}). It also checks the presence of a parameter and fills \PB{\\{Buffer}} if existent. \PB{\\{fsearch}(\,)} returns~1 on success. \Y\B\4\X11:Prototypes\X${}\mathrel+\E{}$\6 \&{static} \&{int} \\{fsearch}(\&{const} \&{char} ${}{*}){}$;\par \fi \M{65} \Y\B\&{static} \&{int} \\{fsearch}(\&{const} \&{char} ${}{*}\\{search% \_string}){}$\1\1\2\2\6 ${}\{{}$\1\6 \&{char} ${}{*}\|P,{}$ \|p;\6 \&{const} \&{char} ${}{*}\|Q;{}$\6 \&{char} ${}\\{temp\_buffer}[\.{STRING\_LENGTH}+\T{1}];{}$\6 \&{char} ${}\\{env\_name}[\.{STRING\_LENGTH}+\T{1}];{}$\6 \&{char} ${}{*}\\{env\_p};{}$\6 \&{char} ${}{*}\\{env\_value};{}$\6 \&{char} ${}{*}\\{Buf\_p};{}$\6 \&{int} \\{Ch}${},{}$ \\{ch}${},{}$ \\{old\_ch}${}\K\.{'\\n'};{}$\6 \&{int} \\{count}${}\K\.{STRING\_LENGTH};{}$\7 \\{rewind}(\\{config});\C{ we start at offset~0 }\7 \&{do}\5 ${}\{{}$\1\6 ${}\|Q\K\\{search\_string};{}$\6 ${}\|p\K\\{tolower}{}$((\&{unsigned} \&{char}) ${}{*}\|Q);{}$\6 ${}\\{Ch}\K\\{fgetc}(\\{config});{}$\6 ${}\\{ch}\K\\{tolower}(\\{Ch});{}$\6 \&{while} ${}(\R(\\{ch}\E\|p\W\\{old\_ch}\E\.{'\\n'})\W\\{Ch}\I\.{EOF}{}$)\C{ search first character of \PB{\\{search\_string}}; \PB{\.{'\\n'}} must be the character before }\6 ${}\{{}$\1\6 ${}\\{old\_ch}\K\\{ch};{}$\6 ${}\\{Ch}\K\\{fgetc}(\\{config});{}$\6 ${}\\{ch}\K\\{tolower}(\\{Ch});{}$\6 \4${}\}{}$\2\7 \&{for} ( ; ; \,)\5 ${}\{{}$\1\6 \&{if} ${}({*}(\PP\|Q)\E\.{'\\0'}){}$\1\6 \&{if} ${}((\\{Ch}\K\\{fgetc}(\\{config}))\E\.{'\ '}\V\\{Ch}\E\.{'\\t'}{}$)\C{ there must be a space or a tab stop after the keyword }\1\6 \&{goto} \\{success};\2\2\6 ${}\\{Ch}\K\\{fgetc}(\\{config});{}$\6 \&{if} ${}(\\{tolower}(\\{Ch})\I\\{tolower}{}$((\&{unsigned} \&{char}) ${}{*}% \|Q)){}$\1\5 \&{break};\2\6 \4${}\}{}$\2\6 \4${}\}{}$\2\5 \&{while} ${}(\\{Ch}\I\.{EOF}){}$;\7 \&{return} \T{0};\7 \4\\{success}:\5 ${}\|P\K\\{temp\_buffer}{}$;\7 \&{while} ${}((\\{Ch}\K\\{fgetc}(\\{config}))\E\.{'\ '}\V\\{Ch}\E\.{'\\t'}{}$)% \C{ remove leading blanks and tabs }\1\6 ;\2\6 \&{while} ${}(\\{Ch}\I\.{'\\n'}\W\MM\\{count}>\T{0}\W\\{Ch}\I\.{EOF}{}$)\C{ fill \PB{\\{Buffer}} }\6 ${}\{{}$\1\6 ${}{*}\|P\PP\K\\{Ch};{}$\6 ${}\\{Ch}\K\\{fgetc}(\\{config});{}$\6 \4${}\}{}$\2\6 ${}{*}\|P\K\.{'\\0'}{}$;\7 \&{if} ${}({*}\\{temp\_buffer}){}$\1\5 \X66:Check for environment variables\X\2\6 \&{else}\1\5 ${}{*}\\{Buffer}\K\.{'\\0'}{}$;\2\7 \&{return} ${}({*}\\{Buffer})\?\T{1}:\T{0}{}$;\C{ is there something in the buffer? }\6 \4${}\}{}$\2\par \fi \M{66} To make the configuration file more flexible we allow environment variables in the arguments. We scan the parameter stored in \PB{\\{temp\_buffer}} whether it contains a `\.{\$}' character. If yes, the following code fragment tries to get an environment variable name whose value will be then fetched with \PB{\\{getenv}(\,)}. An environment variable name recognized by \.{hbf2gf} must start with a letter or underscore; the other characters may be alphanumeric or an underscore. You can surround the environment variable name with braces to indicate where the name ends, e.g. \.{\$\{FOO\}}. The interpolated configuration parameter will be truncated to \PB{\.{STRING\_LENGTH}} characters. If you want to have `\.{\$}' you must write `\.{\$\$}'. Note that you should avoid to use such environment variables for specifying the location of the configuration file in case you have support for a file searching library like kpathsea. Its primary aim is to specify the target directories for the \.{pk\_directory} and the \.{tfm\_directory} keywords. \Y\B\4\X66:Check for environment variables\X${}\E{}$\6 ${}\{{}$\1\6 ${}\|P\K\\{temp\_buffer};{}$\6 ${}\\{Buf\_p}\K\\{Buffer};{}$\6 ${}\\{count}\K\.{STRING\_LENGTH}-\T{1}{}$;\7 \&{while} ${}({*}\|P\W\\{count}>\T{0}){}$\5 ${}\{{}$\1\6 ${}\\{env\_p}\K\\{env\_name}{}$;\7 \&{if} ${}({*}\|P\E\.{'\$'}){}$\5 ${}\{{}$\1\6 ${}\|P\PP;{}$\6 \&{if} ${}({*}\|P\E\.{'\$'}){}$\5 ${}\{{}$\1\6 ${}{*}(\\{Buf\_p}\PP)\K{*}(\|P\PP);{}$\6 ${}\\{count}\MM;{}$\6 \&{continue};\6 \4${}\}{}$\2\6 \&{while} ${}({*}\|P\E\.{'\{'}){}$\1\5 ${}\|P\PP;{}$\2\6 \&{if} ${}(\R{}$(\\{isalpha}((\&{unsigned} \&{char}) ${}{*}\|P)\V{*}\|P\E\.{'% \_'})){}$\5 ${}\{{}$\1\6 ${}\\{fprintf}(\\{stderr},{}$\6 \.{"Invalid\ environment}\)\.{\ variable\ name\ in\ co}\)\.{nfiguration\ file% \\n"});\6 \\{exit}(\T{1});\6 \4${}\}{}$\2\6 ${}{*}(\\{env\_p}\PP)\K{*}(\|P\PP);{}$\6 \&{while} ${}({*}\|P){}$\5 ${}\{{}$\1\6 \&{if} (\\{isalnum}((\&{unsigned} \&{char}) ${}{*}\|P)\V{*}\|P\E\.{'\_'}){}$\1\5 ${}{*}(\\{env\_p}\PP)\K{*}(\|P\PP);{}$\2\6 \&{else}\5 ${}\{{}$\1\6 \&{while} ${}({*}\|P\E\.{'\}'}){}$\1\5 ${}\|P\PP;{}$\2\6 ${}{*}\\{env\_p}\K\.{'\\0'};{}$\6 \&{break};\6 \4${}\}{}$\2\6 \4${}\}{}$\2\7 ${}\\{env\_value}\K\\{getenv}(\\{env\_name});{}$\6 \&{if} (\\{env\_value})\C{ append the environment value to \PB{\\{Buffer}} }\6 ${}\{{}$\1\6 \&{while} ${}({*}\\{env\_value}\W\\{count}>\T{0}){}$\5 ${}\{{}$\1\6 ${}{*}(\\{Buf\_p}\PP)\K{*}(\\{env\_value}\PP);{}$\6 ${}\\{count}\MM;{}$\6 \4${}\}{}$\2\6 \4${}\}{}$\2\6 \4${}\}{}$\2\6 \&{else}\5 ${}\{{}$\1\6 ${}{*}(\\{Buf\_p}\PP)\K{*}(\|P\PP);{}$\6 ${}\\{count}\MM;{}$\6 \4${}\}{}$\2\6 \4${}\}{}$\2\6 ${}{*}\\{Buf\_p}\K\.{'\\0'};{}$\6 \4${}\}{}$\2\par \U65.\fi \M{67} If an error occurs, \PB{\\{config\_error}(\,)} will leave the program with an error message. \Y\B\4\X11:Prototypes\X${}\mathrel+\E{}$\6 \&{static} \&{void} \\{config\_error}(\&{const} \&{char} ${}{*}){}$;\par \fi \M{68} \Y\B\&{static} \&{void} \\{config\_error}(\&{const} \&{char} ${}{*}% \\{message}){}$\1\1\2\2\6 ${}\{{}$\1\6 ${}\\{fprintf}(\\{stderr},\39\.{"Couldn't\ find\ `\%s'\ }\)\.{entry\ in\ configurati}\)\.{on\ file\\n"},\39\\{message});{}$\6 \\{exit}(\T{1});\6 \4${}\}{}$\2\par \fi \N{1}{69}File searching. We support three searching engines: emtexdir, kpathsea, and MiKTeX (which is a Win32 port of kpathsea). For emtexdir, define \PB{\.{HAVE\_EMTEXDIR}} while compiling. For kpathsea, define \PB{\.{HAVE\_LIBKPATHSEA}}. For MikTeX, define \PB{\.{HAVE\_MIKTEX}}. If none of these macros is defined, a simple \PB{% \\{fopen}(\,)} will be used instead. \Y\B\4\X10:Include files\X${}\mathrel+\E{}$\6 \8\#\&{if} \&{defined} (\.{HAVE\_LIBKPATHSEA})\6 \8\#\&{include} \.{"kpathsea/kpathsea.h}\)\.{"}\6 \8\#\&{elif} \&{defined} (\.{HAVE\_EMTEXDIR})\6 \8\#\&{include} \.{"emtexdir.h"}\6 \8\#\&{elif} \&{defined} (\.{HAVE\_MIKTEX})\6 \8\#\&{include} \.{"miktex.h"}\6 \8\#\&{endif}\par \fi \M{70} \Y\B\4\X2:Global variables\X${}\mathrel+\E{}$\6 \8\#\&{if} \&{defined} (\.{HAVE\_EMTEXDIR})\6 \&{char} \\{emtex\_version\_string}[\,]${}\K\.{"emTeXdir"};{}$\6 \8\#\&{elif} ${}\R{}$\&{defined} (\.{HAVE\_MIKTEX})\6 \&{char} \\{no\_version\_string}[\,]${}\K\.{"no\ search\ library"};{}$\6 \8\#\&{endif}\par \fi \M{71} \Y\B\4\X11:Prototypes\X${}\mathrel+\E{}$\6 \&{static} \&{const} \&{char} ${}{*}\\{TeX\_search\_version}(\&{void}){}$;\par \fi \M{72} \Y\B\&{static} \&{const} \&{char} ${}{*}\\{TeX\_search\_version}(\&{void}){}$\1% \1\2\2\6 ${}\{{}$\6 \8\#\&{if} \&{defined} (\.{HAVE\_LIBKPATHSEA})\1\6 \&{return} \\{kpathsea\_version\_string};\6 \8\#\&{elif} \&{defined} (\.{HAVE\_EMTEXDIR})\6 \&{return} \\{emtex\_version\_string};\6 \8\#\&{elif} \&{defined} (\.{HAVE\_MIKTEX})\7 \&{char} \\{buf}[\T{200}];\7 ${}\\{strcpy}(\\{buf},\39\.{"MiKTeX\ "});{}$\6 ${}\\{miktex\_get\_miktex\_version\_string\_ex}(\\{buf}+\T{7},\39{}$\&{sizeof} (\\{buf})${}-\T{7});{}$\6 \&{return} \\{buf};\6 \8\#\&{else}\6 \&{return} \\{no\_version\_string};\6 \8\#\&{endif}\6 \4${}\}{}$\2\par \fi \M{73} \Y\B\4\X2:Global variables\X${}\mathrel+\E{}$\6 \8\#\&{ifdef} \.{HAVE\_EMTEXDIR}\6 \&{struct} \&{emtex\_dir} \\{cfg\_path}${},{}$ \\{hbf\_path};\6 \8\#\&{endif}\par \fi \M{74} \Y\B\4\X11:Prototypes\X${}\mathrel+\E{}$\6 \8\#\&{ifdef} \.{HAVE\_EMTEXDIR}\6 \&{extern} \&{int} \\{setup\_list}(\&{struct} \&{emtex\_dir} ${}{*},\39{}$% \&{char} ${}{*},\39{}$\&{const} \&{char} ${}{*},\39\&{unsigned});{}$\6 \&{static} \&{int} \\{dir\_setup}(\&{struct} \&{emtex\_dir} ${}{*},\39{}$% \&{const} \&{char} ${}{*},\39{}$\&{const} \&{char} ${}{*},\39\&{unsigned});{}$\6 \&{static} \&{char} ${}{*}{}$\\{file\_find}(\&{char} ${}{*},\39{}$\&{struct} % \&{emtex\_dir} ${}{*});{}$\6 \8\#\&{endif}\par \fi \M{75} We slightly modify \PB{\\{emtex\_dir\_setup}(\,)} (from the file % \.{emtexdir.c}) to output a warning in case the environment variable \PB{\\{env}} isn't set properly. \Y\B\8\#\&{ifdef} \.{HAVE\_EMTEXDIR}\6 \&{static} \&{int} ${}\\{dir\_setup}(\\{ed},\39\\{env},\39\\{dir},\39% \\{flags}){}$\1\1\6 \&{struct} \&{emtex\_dir} ${}{*}\\{ed};{}$\6 \&{const} \&{char} ${}{*}\\{env};{}$\6 \&{const} \&{char} ${}{*}\\{dir};{}$\6 \&{unsigned} \\{flags};\2\2\6 ${}\{{}$\1\6 \&{const} \&{char} ${}{*}\\{val};{}$\6 \&{char} \\{path}[\T{260}];\7 ${}\\{ed}\MG\\{alloc}\K\T{0};{}$\6 ${}\\{ed}\MG\\{used}\K\T{0};{}$\6 ${}\\{ed}\MG\\{list}\K\NULL{}$;\7 \&{if} ${}(\\{env}\I\NULL\W(\\{val}\K\\{getenv}(\\{env}))\I\NULL){}$\1\5 \&{return} \\{setup\_list}${}(\\{ed},\39\\{path},\39\\{val},\39\\{flags});{}$\2% \6 \&{else}\1\5 ${}\\{fprintf}(\\{stderr},\39\.{"Environment\ variabl}\)\.{e\ `\%s'\ not\ set;\ use\ }\)\.{current\ directory\\n"},\39\\{env}){}$;\2\7 \&{return} \.{TRUE};\6 \4${}\}{}$\2\6 \8\#\&{endif}\par \fi \M{76} \Y\B\4\X2:Global variables\X${}\mathrel+\E{}$\6 \8\#\&{ifdef} \.{HAVE\_EMTEXDIR}\6 \&{char} ${}\\{name\_buffer}[\.{FILE\_NAME\_LENGTH}+\T{1}];{}$\6 \8\#\&{endif}\par \fi \M{77} \Y\B\8\#\&{ifdef} \.{HAVE\_EMTEXDIR}\6 \&{static} \&{char} ${}{*}\\{file\_find}(\\{name},\39\\{list}){}$\1\1\6 \&{char} ${}{*}\\{name};{}$\6 \&{struct} \&{emtex\_dir} ${}{*}\\{list};\2\2{}$\6 ${}\{{}$\1\6 \&{if} ${}(\\{emtex\_dir\_find}(\\{name\_buffer},\39{}$\&{sizeof} (\\{name% \_buffer})${},\39\\{list},\39\\{name},\39\.{EDF\_CWD})){}$\1\5 \&{return} \\{name\_buffer};\2\7 \&{return} ${}\NULL;{}$\6 \4${}\}{}$\2\6 \8\#\&{endif}\par \fi \M{78} For emtexdir we use the environment variables \.{HBFCFG} and \.{HBFONTS} for configuration resp.\ HBF header files. \Y\B\4\X78:Initialize \TeX\ file searching\X${}\E{}$\6 \8\#\&{if} \&{defined} (\.{HAVE\_LIBKPATHSEA})\6 $\\{kpse\_set\_program\_name}(\\{argv}[\T{0}],\39\.{"hbf2gf"});{}$\6 ${}\\{kpse\_init\_prog}(\.{"HBF2GF"},\39\T{300},\39\.{"cx"},\39\.{"cmr10"}){}$;% \7 \8\#\&{elif} \&{defined} (\.{HAVE\_EMTEXDIR})\6 \&{if} ${}(\R\\{dir\_setup}({\AND}\\{cfg\_path},\39\.{"HBFCFG"},\39\NULL,\39% \.{EDS\_BANG})){}$\5 ${}\{{}$\1\6 ${}\\{fprintf}(\\{stderr},\39\.{"Couldn't\ setup\ sear}\)\.{ch\ path\ for\ configur}\)\.{ation\ files\\n"});{}$\6 \\{exit}(\T{1});\6 \4${}\}{}$\2\6 \&{if} ${}(\R\\{dir\_setup}({\AND}\\{hbf\_path},\39\.{"HBFONTS"},\39\NULL,\39% \.{EDS\_BANG})){}$\5 ${}\{{}$\1\6 ${}\\{fprintf}(\\{stderr},\39\.{"Couldn't\ setup\ sear}\)\.{ch\ path\ for\ HBF\ head}\)\.{er\ files\\n"});{}$\6 \\{exit}(\T{1});\6 \4${}\}{}$\2\6 \8\#\&{endif}\par \U4.\fi \M{79} Finally, here are the searching routines. A special format in the kpathsea library for fonts which are neither PostScript nor TrueType (\.{MISCFONTS}) is available with version~3.3 and newer. For older versions we use the path for PostScript fonts (\.{T1FONTS}) to find HBF files. Configuration files are searched in the path specified within \.{TEXCONFIG} for old kpathsea versions, and within \.{HBF2GFINPUTS} for new versions. \Y\B\4\X11:Prototypes\X${}\mathrel+\E{}$\6 \&{static} \&{char} ${}{*}{}$\\{TeX\_search\_cfg\_file}(\&{char} ${}{*});{}$\6 \&{static} \&{char} ${}{*}{}$\\{TeX\_search\_hbf\_file}(\&{char} ${}{*}){}$;\par \fi \M{80} \Y\B\8\#\&{if} \&{defined} (\.{HAVE\_LIBKPATHSEA})\6 \&{static} \&{char} ${}{*}{}$\\{TeX\_search\_cfg\_file}(\&{char} ${}{*}% \\{name}){}$\1\1\2\2\6 ${}\{{}$\1\6 \&{return} \\{kpse\_find\_file}${}(\\{name},\39\\{kpse\_program\_text\_format},% \39\.{TRUE});{}$\6 \4${}\}{}$\2\7 \&{static} \&{char} ${}{*}{}$\\{TeX\_search\_hbf\_file}(\&{char} ${}{*}% \\{name}){}$\1\1\2\2\6 ${}\{{}$\1\6 \&{return} \\{kpse\_find\_file}${}(\\{name},\39\\{kpse\_miscfonts\_format},\39% \.{TRUE});{}$\6 \4${}\}{}$\2\7 \8\#\&{elif} \&{defined} (\.{HAVE\_EMTEXDIR})\7 \&{static} \&{char} ${}{*}{}$\\{TeX\_search\_cfg\_file}(\&{char} ${}{*}% \\{name}){}$\1\1\2\2\6 ${}\{{}$\1\6 \&{return} \\{file\_find}${}(\\{name},\39{\AND}\\{cfg\_path});{}$\6 \4${}\}{}$\2\7 \&{static} \&{char} ${}{*}{}$\\{TeX\_search\_hbf\_file}(\&{char} ${}{*}% \\{name}){}$\1\1\2\2\6 ${}\{{}$\1\6 \&{return} \\{file\_find}${}(\\{name},\39{\AND}\\{hbf\_path});{}$\6 \4${}\}{}$\2\7 \8\#\&{elif} \&{defined} (\.{HAVE\_MIKTEX})\7 \&{static} \&{char} ${}{*}{}$\\{TeX\_search\_cfg\_file}(\&{char} ${}{*}% \\{name}){}$\1\1\2\2\6 ${}\{{}$\1\6 \&{char} \\{result}[\.{\_MAX\_PATH}];\7 \&{if} ${}(\R\\{miktex\_find\_input\_file}(\.{"hbf2gf"},\39{*}\\{name},\39% \\{result})){}$\1\5 \&{return} \T{0};\2\6 \&{return} \\{strdup}(\\{result});\6 \4${}\}{}$\2\7 \&{static} \&{char} ${}{*}{}$\\{TeX\_search\_hbf\_file}(\&{char} ${}{*}% \\{name}){}$\1\1\2\2\6 ${}\{{}$\1\6 \&{char} \\{result}[\.{\_MAX\_PATH}];\7 \&{if} ${}(\R\\{miktex\_find\_miscfont\_file}({*}\\{name},\39\\{result})){}$\1\5 \&{return} \T{0};\2\6 \&{return} \\{strdup}(\\{result});\6 \4${}\}{}$\2\7 \8\#\&{else}\7 \&{static} \&{char} ${}{*}{}$\\{TeX\_search\_cfg\_file}(\&{char} ${}{*}% \\{name}){}$\1\1\2\2\6 ${}\{{}$\1\6 \&{return} \\{name};\6 \4${}\}{}$\2\7 \&{static} \&{char} ${}{*}{}$\\{TeX\_search\_hbf\_file}(\&{char} ${}{*}% \\{name}){}$\1\1\2\2\6 ${}\{{}$\1\6 \&{return} \\{name};\6 \4${}\}{}$\2\6 \8\#\&{endif}\par \fi \N{1}{81}An example. This is the example configuration file \.{b5so12.cfg} (for use with DOS or OS/2 and the emtexdir searching engine): \bigskip \halign{\quad\.{#}\hfil&\quad\.{#}\hfil\cr hbf\_header & et24.hbf \cr mag\_x & 2.076 \cr x\_offset & 3 \cr y\_offset & -8 \cr comment & fanti songti 24x24 pixel font scaled and adapted to 12 pt \cr & \cr design\_size & 12.0 \cr & \cr nmb\_fonts & -1 \cr & \cr output\_name & b5so12 \cr & \cr dpi\_x & 300 \cr checksum & 123456789 \cr coding & codingscheme Big 5 encoded TeX text \cr & \cr long\_extension & no \cr job\_extension & .cmd \cr rm\_command & del \cr cp\_command & copy \cr pk\_directory & \$HBF\_TARGET\\pk\\360dpi\\ \cr tfm\_directory & \$HBF\_TARGET\\tfm\\ \cr } \bigskip If you say e.g. \medskip \quad \.{set HBF\_TARGET=c:\\emtex\\texfonts} \medskip on your DOS prompt (or in your \.{autoexec.bat} file), then the interpolated value of the \.{tfm\_directory} keyword is \.{c:\\emtex\\texfonts\\tfm\\}. The HBF header file \.{et24.hbf} will be searched in the path specified by the \.{HBFCFG} environment variable. \bigskip The call \medskip \quad \.{hbf2gf b5so12.cfg} \medskip creates the files \medskip \quad \.{b5so1201.gf}, \.{b5so1202.gf}, $\ldots$ , \.{b5so1255.gf}, \.{b5so12.pl}, and \.{b5so12.cmd} \bigskip After calling \medskip \quad \.{b5so12.cmd} \medskip you will find the \.{PK} files in the \.{c:\\emtex\\texfonts\\pk\\360dpi} directory and the \.{TFM} files in the \.{c:\\emtex\\texfonts\\tfm} directory; all \.{GF} files and \.{b5so12.pl} will be deleted. \bigskip The call \medskip \quad \.{hbf2gf -n b5so1220 417} \medskip creates two files: \medskip \quad \.{b5so1220.gf} and \.{b5so1220.pl} \medskip using the configuration file \.{b5so12.cfg}. The \.{GF} file would be named \.{b5so1220.417gf} if the flag \.{-n} had not been used. \medskip It is possible to convert bitmap fonts to \.{PK} files almost automatically. The HBF header file already has the entry \.{HBF\_BITMAP\_BOUNDING\_BOX} which defines vertical and horizontal offsets (in pixels), but these values are not in all cases optimal. If you omit \.{x\_offset} and \.{y\_offset} in the configuration file, the third and fourth parameter of \.{HBF\_BITMAP\_BOUNDING\_BOX} is used, scaled to design size (to say it in other words: \.{x\_offset} and \.{y\_offset} will always apply to the design size to be synchronous with the \.{TFM} files). Don't confuse scaling and magnification: Scaling here means that you choose a (arbitrary) design size and compute scaling values (\.{mag\_x} and \.{mag\_y}) which scales the bitmap to this particular design size at a certain (arbitrarily chosen) resolution (\.{dpi\_x} and \.{dpi\_y}). Magnification means that the scaled bitmap will be then magnified to a certain target size while still using the font parameters (i.e., the \.{TFM} file) of the design size. In the sample, you have a $24 \times 24$ bitmap font which will be scaled to $12\,\hbox{pt}$ having a resolution of $300\,\hbox{dpi}$: \medskip \quad $1\,\hbox{pt}$ are $300 / 72.27 = 4.1511$ pixel; \quad $12\,\hbox{pt}$ are $4.1511 * 12 = 49.813$ pixel; \quad thus the theoretical scaling value is $49.813 / 24 = 2.076$. \medskip But especially for small sizes, this may not be the best value if the font should harmonize with, say, Knuth's Computer Modern fonts. I recommend to compute, say, 5~\.{PK} fonts, then check the CJK font with different \TeX\ fonts to see whether the offsets and/or the scaling value is good. The greater the design size the finer you can control the offsets---as an example you could use a design size of $30\,\hbox{pt}$ (nevertheless there is a compile-time constant \PB{\.{MAX\_CHAR\_SIZE}} which limits the maximal character size; default is 255~pixels). If you have found optimal offsets, you can produce many different magnifications of the CJK font using the same set of \.{TFM} files analogous to ordinary \TeX\ fonts; as a simplification, we assume that \.{PK} files with a resolution of $300\,\hbox{dpi}$ and a design size of $10\,\hbox{pt}$ have the extension `\.{.300pk}' (respectively come into a `\.{300dpi}' subdirectory)---this is the reason why in the above example for the $12\,\hbox{pt}$ design size a `\.{360dpi}' target directory has been used. Now we can use the following formula: $$ \\{needed\_dpi} = \\{your\_horizontal\_resolution} * {\\{your\_target\_size} \over 10.0} $$ Example: assuming that your printer has a resolution of $300\times400\,\hbox{dpi}$, and you want $14.4\,\hbox{pt}$: $$ 300 * {14.4 \over 10.0} = 432 $$ The vertical scaling value is $400 / 300 = 1.3333$. Use these values now to call \.{hbf2gf} in \mf-like mode: \quad \.{hbf2gf b5so1220 432 1.3333} \fi \N{1}{82}Index. \fi \inx \fin \con