\input cwebmac
% This is the cweb file hbf2gf.w of the CJK package ver. 4.7.0  17-Oct-2006

% Copyright (C) 1994-2006  Werner Lemberg <wl@gnu.org>
%
% 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.7.0)}

\def\topofcontents{
  \null\vfill
  \centerline{\titlefont The {\ttitlefont hbf2gf} program}
  \vskip 20pt
  \centerline{(CJK Version 4.7.0)}
  \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.}\)\.{7.0)"}\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}(\\{argc},\39\\{argv}){}$\1\1\6
\&{int} \\{argc};\C{ argument count }\6
\&{char} ${}{*}\\{argv}[\,]{}$;\C{ argument values }\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\#\&{include} \.{<ctype.h>}\6
\8\#\&{include} \.{<stdio.h>}\6
\8\#\&{include} \.{<stdlib.h>}\6
\8\#\&{include} \.{<string.h>}\6
\8\#\&{include} \.{<time.h>}\6
\8\#\&{ifdef} \.{TM\_IN\_SYS\_TIME}\6
\8\#\&{include} \.{<sys/time.h>}\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
\&{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\&{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$\\{header}$ \5
\.{"\ hbf2gf\ output\ "}\par
\Y\B\4\X11:Prototypes\X${}\mathrel+\E{}$\6
\&{void} \\{write\_pre}(\&{void});\par
\fi

\M{14}
\Y\B\&{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\\{header}){}$;\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
\&{void} \\{write\_data}(\&{void});\par
\fi

\M{17}
\Y\B\&{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
\&{void} \\{write\_post}(\&{void});\par
\fi

\M{21}
\Y\B\&{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
\&{void} ${}\\{fputl}(\&{long},\39{}$\&{FILE} ${}{*}){}$;\par
\fi

\M{26}
\Y\B\&{void} ${}\\{fputl}(\\{num},\39\|f){}$\1\1\6
\&{long} \\{num};\6
\&{FILE} ${}{*}\|f;\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
\&{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
\&{void} \\{make\_pixel\_array}(\&{void});\par
\fi

\M{30}
\Y\B\&{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{}$(\&{unsigned} \&{char} ${}{*}){}$ \\{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
\8\#\&{ifdef} \.{\_\_GNUC\_\_}\6
\&{\_\_inline\_\_}\6
\8\#\&{endif}\6
\&{void} \\{read\_row}(\&{unsigned} \&{char} ${}{*}){}$;\par
\fi

\M{37}
\Y\B\8\#\&{ifdef} \.{\_\_GNUC\_\_}\6
\&{\_\_inline\_\_}\6
\8\#\&{endif}\6
\&{void} \\{read\_row}(\\{pixelrow})\1\1\6
\&{unsigned} \&{char} ${}{*}\\{pixelrow};\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{}$(\&{unsigned} \&{char} ${}{*}){}$ \\{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
\8\#\&{ifdef} \.{\_\_GNUC\_\_}\6
\&{\_\_inline\_\_}\6
\8\#\&{endif}\6
\&{void} \\{write\_row}(\&{unsigned} \&{char} ${}{*}){}$;\par
\fi

\M{40}
\Y\B\8\#\&{ifdef} \.{\_\_GNUC\_\_}\6
\&{\_\_inline\_\_}\6
\8\#\&{endif}\6
\&{void} \\{write\_row}(\\{pixelrow})\1\1\6
\&{unsigned} \&{char} ${}{*}\\{pixelrow};\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
\&{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\&{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
\&{void} \\{write\_pl}(\&{void});\par
\fi

\M{46}
\Y\B\&{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
\&{void} \\{write\_ovp}(\&{void});\par
\fi

\M{48}
\Y\B\&{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
\&{void} \\{write\_job}(\&{void});\par
\fi

\M{51}
\Y\B\&{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
\&{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\&{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
\&{int} \\{fsearch}(\&{char} ${}{*}){}$;\par
\fi

\M{65}
\Y\B\&{int} \\{fsearch}(\\{search\_string})\1\1\6
\&{char} ${}{*}\\{search\_string};\2\2{}$\6
${}\{{}$\1\6
\&{char} ${}{*}\|P,{}$ \|p;\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
${}\|P\K\\{search\_string};{}$\6
${}\|p\K\\{tolower}({*}\|P);{}$\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\|P)\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}({*}\|P)){}$\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}({*}\|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}({*}\|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
\&{void} \\{config\_error}(\&{char} ${}{*}){}$;\par
\fi

\M{68}
\Y\B\&{void} \\{config\_error}(\\{message})\1\1\6
\&{char} ${}{*}\\{message};\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}}. If you have a
version of
kpathsea older than~3.2, define \PB{\.{OLD\_KPATHSEA}} additionally. For
kpathsea
older than~3.0, \PB{\.{VERY\_OLD\_KPATHSEA}} must be also set. 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\#\&{ifdef} \.{VERY\_OLD\_KPATHSEA}\6
\8\#\&{include} \.{"kpathsea/proginit.h}\)\.{"}\6
\8\#\&{include} \.{"kpathsea/progname.h}\)\.{"}\6
\8\#\&{include} \.{"kpathsea/tex-glyph.}\)\.{h"}\6
\8\#\&{else}\6
\8\#\&{include} \.{"kpathsea/kpathsea.h}\)\.{"}\6
\8\#\&{endif}\7
\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\_LIBKPATHSEA})\6
\8\#\&{ifdef} \&{KPSEDLL} \C{ this is kpathsea 3.3 and newer }\6
\&{extern} \&{KPSEDLL} \&{char} ${}{*}\\{kpathsea\_version\_string};{}$\6
\8\#\&{else}\6
\&{extern} \&{DllImport} \&{char} ${}{*}\\{kpathsea\_version\_string};{}$\6
\8\#\&{endif}\6
\8\#\&{elif} \&{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
\&{char} ${}{*}\\{TeX\_search\_version}(\&{void}){}$;\par
\fi

\M{72}
\Y\B\&{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
\&{int} \\{dir\_setup}(\&{struct} \&{emtex\_dir} ${}{*},\39{}$\&{const} %
\&{char} ${}{*},\39{}$\&{const} \&{char} ${}{*},\39\&{unsigned});{}$\6
\&{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
\&{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\par
\fi

\M{76}
\Y\B\4\X2:Global variables\X${}\mathrel+\E{}$\6
\&{char} ${}\\{name\_buffer}[\.{FILE\_NAME\_LENGTH}+\T{1}]{}$;\par
\fi

\M{77}
\Y\B\&{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
\8\#\&{ifdef} \.{OLD\_KPATHSEA}\6
\\{kpse\_set\_progname}(\\{argv}[\T{0}]);\6
\8\#\&{else}\6
${}\\{kpse\_set\_program\_name}(\\{argv}[\T{0}],\39\.{"hbf2gf"});{}$\6
\8\#\&{endif}\7
\8\#\&{ifdef} \.{VERY\_OLD\_KPATHSEA}\6
${}\\{kpse\_init\_prog}(\.{"HBF2GF"},\39\T{300},\39\.{"cx"},\39\\{true},\39%
\.{"cmr10"});{}$\6
\8\#\&{else}\6
${}\\{kpse\_init\_prog}(\.{"HBF2GF"},\39\T{300},\39\.{"cx"},\39\.{"cmr10"}){}$;%
\7
\8\#\&{endif}\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
\&{char} ${}{*}{}$\\{TeX\_search\_cfg\_file}(\&{char} ${}{*});{}$\6
\&{char} ${}{*}{}$\\{TeX\_search\_hbf\_file}(\&{char} ${}{*}){}$;\par
\fi

\M{80}
\Y\B\8\#\&{if} \&{defined} (\.{HAVE\_LIBKPATHSEA})\6
\&{char} ${}{*}\\{TeX\_search\_cfg\_file}(\\{name}){}$\1\1\6
\&{char} ${}{*}\\{name};\2\2{}$\6
${}\{{}$\6
\8\#\&{ifdef} \.{OLD\_KPATHSEA}\1\6
\&{return} \\{kpse\_find\_file}${}(\\{name},\39\\{kpse\_dvips\_config\_format},%
\39\.{TRUE});{}$\6
\8\#\&{else}\6
\&{return} \\{kpse\_find\_file}${}(\\{name},\39\\{kpse\_program\_text\_format},%
\39\.{TRUE});{}$\6
\8\#\&{endif}\6
\4${}\}{}$\2\7
\&{char} ${}{*}\\{TeX\_search\_hbf\_file}(\\{name}){}$\1\1\6
\&{char} ${}{*}\\{name};$ $\{{}$\6
\8\#\&{ifdef} \.{VERY\_OLD\_KPATHSEA}\6
\&{return} \\{kpse\_find\_file}${}(\\{name},\39\\{kpse\_dvips\_header\_format},%
\39\.{TRUE});{}$\6
\8\#\&{else}\6
\8\#\&{ifndef} \&{KPSEDLL} \6
\&{return} \\{kpse\_find\_file}${}(\\{name},\39\\{kpse\_type1\_format},\39%
\.{TRUE});{}$\6
\8\#\&{else}\6
\&{return} \\{kpse\_find\_file}${}(\\{name},\39\\{kpse\_miscfonts\_format},\39%
\.{TRUE});{}$\6
\8\#\&{endif}\6
\8\#\&{endif}\6
$\}{}$\7
\8\#\&{elif} \&{defined} (\.{HAVE\_EMTEXDIR})\6
\&{char} ${}{*}\\{TeX\_search\_cfg\_file}(\\{name}){}$\1\1\6
\&{char} ${}{*}\\{name};\2\2{}$\6
${}\{{}$\1\6
\&{return} \\{file\_find}${}(\\{name},\39{\AND}\\{cfg\_path});{}$\6
\4${}\}{}$\2\7
\&{char} ${}{*}\\{TeX\_search\_hbf\_file}(\\{name}){}$\1\1\6
\&{char} ${}{*}\\{name};\2\2{}$\6
${}\{{}$\1\6
\&{return} \\{file\_find}${}(\\{name},\39{\AND}\\{hbf\_path});{}$\6
\4${}\}{}$\2\7
\8\#\&{elif} \&{defined} (\.{HAVE\_MIKTEX})\7
\&{char} ${}{*}\\{TeX\_search\_cfg\_file}(\\{name}){}$\1\1\6
\&{char} ${}{*}\\{name};\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
\&{char} ${}{*}\\{TeX\_search\_hbf\_file}(\\{name}){}$\1\1\6
\&{char} ${}{*}\\{name};\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
\&{char} ${}{*}\\{TeX\_search\_cfg\_file}(\\{name}){}$\1\1\6
\&{char} ${}{*}\\{name};\2\2{}$\6
${}\{{}$\1\6
\&{return} \\{name};\6
\4${}\}{}$\2\7
\&{char} ${}{*}\\{TeX\_search\_hbf\_file}(\\{name}){}$\1\1\6
\&{char} ${}{*}\\{name};\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 with 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
