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