summaryrefslogtreecommitdiff
path: root/language/chinese/CJK/cjk-4.8.4/utils/hbf2gf/hbf2gf.w
diff options
context:
space:
mode:
Diffstat (limited to 'language/chinese/CJK/cjk-4.8.4/utils/hbf2gf/hbf2gf.w')
-rw-r--r--language/chinese/CJK/cjk-4.8.4/utils/hbf2gf/hbf2gf.w2816
1 files changed, 0 insertions, 2816 deletions
diff --git a/language/chinese/CJK/cjk-4.8.4/utils/hbf2gf/hbf2gf.w b/language/chinese/CJK/cjk-4.8.4/utils/hbf2gf/hbf2gf.w
deleted file mode 100644
index 434dd7f414..0000000000
--- a/language/chinese/CJK/cjk-4.8.4/utils/hbf2gf/hbf2gf.w
+++ /dev/null
@@ -1,2816 +0,0 @@
-% 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}}
-@s msdos TeX
-
-@s HBF int
-@s HBF_CHAR int
-@s HBF_BBOX int
-
-@s __inline__ int
-
-
-@* Introduction.
-This is the \.{hbf2gf} program by Werner Lemberg
-(\.{wl@@gnu.org}).
-
-The ``banner line'' defined here should be changed whenever \.{hbf2gf} is
-modified.
-
-@d banner
-"hbf2gf (CJK ver. 4.8.4)"
-
-
-@
-\.{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 |nmb_files| \.{GF} files, each
-file containing |256|~characters (except the last and possibly the first
-one). In the normal case it's not necessary to compute the right value of
-|nmb_files| because \.{hbf2gf} will do this; you should use |-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~|2| (this is useful for scripts like
-\.{mktexpk}). If the configuration file is found but an error occurs while
-computing the font, error code~|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.
-
-@d TRUE 1
-@d FALSE 0@#
-
-@d STRING_LENGTH 255
- /* the maximal length of an input string in the configuration file */
-@d FILE_NAME_LENGTH 1024
- /* the maximal length (including the path) of a filename */@#
-
-@<Global variables@>=
-int nmb_files = -1; /* create all files by default */
-int unicode = FALSE; /* whether a Unicode font should be processed */@#
-
-int testing = FALSE; /* whether we test only the font name */@#
-
-int mf_like = FALSE; /* whether we are in the \mf-like mode */
-int file_number = 0; /* the subfont number */@#
-
-double x_resolution = 0.0; /* the second and third input parameter */
-double y_scale = 1.0;@#
-
-int pk_files = TRUE; /* command line options */
-int tfm_files = TRUE;
-int long_extension = TRUE;
-int quiet = FALSE;@#
-
-char config_file[FILE_NAME_LENGTH + 4 + 1];
- /* we probably must add `\.{.cfg}' */
-char output_name[STRING_LENGTH + 1];@#
-
-FILE *config, *out;
-HBF *hbf;@#
-
-#ifdef msdos /* if we compile under DOS or OS/2 */
-#define WRITE_BIN "wb"
-#define WRITE_TXT "wt"
-#define READ_BIN "rb"
-#define READ_TXT "rt"
-#else
-#define WRITE_BIN "w"
-#define WRITE_TXT "w"
-#define READ_BIN "r"
-#define READ_TXT "r"
-#endif@#
-
-int end_of_file = FALSE;
-
-
-@
-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 |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.
-
-
-
-@* The main routine.
-The main routine takes |file_name|, |x_resolution|, and |y_scale| as command
-line parameters if in \mf-like mode, otherwise |config_file| as the only
-argument. |read_config()| scans the configuration file and fills the global
-variables, |write_file()| writes the \.{GF} files, |write_pl()| and
-|write_ovp()| write the \.{PL} and \.{OVP} files respectively, and
-|write_job()| the batch file.
-
-@c
-@<Include files@>@;
-@<Prototypes@>@;
-@<Global variables@>@;@#
-
-
-int main(int argc, char *argv[])
- {char *p;
-
- @<Initialize \TeX\ file searching@>@;@#
-
- @<Scan options@>@;@#
-
- if(!quiet)
- printf("\n%s\n\n", banner);@#
-
- strncpy(config_file, argv[1], FILE_NAME_LENGTH);
- config_file[FILE_NAME_LENGTH] = '\0';@#
-
- if(argc > 2 || testing)
- {int l = strlen(config_file);
-
- if(l > 2)
- config_file[l - 2] = '\0';
- /* strip subfont number from file name */
- else
- {if(!quiet)
- printf("`%s' can't be a subfont created by hbf2gf\n",
- config_file);
- exit(2);
- }@#
-
- mf_like = TRUE;
- }@#
-
- read_config(); /* will call |exit(1)| on errors */@#
-
- if(mf_like)
- @<Check other arguments@>@;@#
-
- @<Initialize variables@>@;@#
-
- @<Write files@>@;@#
-
- if(tfm_files)
- write_pl();
- if(ofm_file)
- write_ovp();
- if(!mf_like)
- write_job();@#
-
- hbfClose(hbf);@#
-
- exit(0);
- return 0; /* never reached */
- }
-
-
-@
-@d VERSION @/
-"\n"@/
-"Copyright (C) 1996-1999 Werner Lemberg.\n"@/
-"There is NO warranty. You may redistribute this software\n"@/
-"under the terms of the GNU General Public License\n"@/
-"and the HBF library copyright.\n"@/
-"\n"@/
-"For more information about these matters, see the files\n"@/
-"named COPYING and hbf.c.\n"@/
-"\n"
-
-@<Print version@>=
- {printf("\n");
- printf(banner);
- printf(" (%s)\n", TeX_search_version());
- printf(VERSION);
- exit(0);
- }
-
-
-@
-@d USAGE @/
-"\n"@/
-"Usage: hbf2gf [-q] configuration_file[.cfg]\n"@/
-" hbf2gf [options] font_name x_resolution [y_scale | y_resolution]\n"@/
-" hbf2gf -t [-q] font_name\n"@/
-"\n"@/
-" Convert a font in HBF format to TeX's GF resp. PK format.\n"@/
-"\n"@/
-" -q be silent\n"@/
-" -p don't produce a PL file\n"@/
-" -g don't produce a GF file\n"@/
-" -n use no resolution in extension (only `.gf')\n"@/
-" -t test for font_name (returns 0 on success)\n"@/
-" --help print this message and exit\n"@/
-" --version print version number and exit\n"@/
-"\n"
-
-@<Print help information@>=
- {printf(USAGE);
- exit(0);
- }
-
-
-@
-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.
-
-@<Scan options@>=
- if(argc == 2)
- {if(strcmp(argv[1], "--help") == 0)
- @<Print help information@>@;
- else if(strcmp(argv[1], "--version") == 0)
- @<Print version@>@;
- }@#
-
- while(argc > 1)
- {p = argv[1];
- if(p[0] != '-')
- break;
- if(p[1] == 'p')
- tfm_files = FALSE;
- else if(p[1] == 'g')
- pk_files = FALSE;
- else if(p[1] == 'n')
- long_extension = FALSE;
- else if(p[1] == 'q')
- quiet = TRUE;
- else if(p[1] == 't')
- testing = TRUE;@#
-
- argv++;
- argc--;
- }@#
-
- if(testing)
- {if(argc != 2)
- {fprintf(stderr, "Need exactly one parameter for `-t' option.\n");
- fprintf(stderr, "Try `hbf2gf --help' for more information.\n");
- exit(1);
- }
- }
- else if(argc < 2 || argc > 4)
- {fprintf(stderr, "Invalid number of parameters.\n");
- fprintf(stderr, "Try `hbf2gf --help' for more information.\n");
- exit(1);
- }@#
-
-
-@
-If the (optional) argument is larger than~|10|, we treat it as a value for
-the vertical resolution (in dpi), otherwise as a vertical scaling factor.
-
-@<Check other arguments@>=
- {if(unicode)
- file_number = (int)strtol(&argv[1][strlen(argv[1]) - 2],
- (char **)NULL, 16);
- else
- file_number = atoi(&argv[1][strlen(argv[1]) - 2]);@#
-
- x_resolution = atof(argv[2]);
- if(x_resolution < PRINTER_MIN_RES_X)
- {fprintf(stderr, "Invalid horizontal resolution\n");
- exit(1);
- }@#
-
- if(argc > 3)
- {y_scale = atof(argv[3]);
- if(y_scale < 0.01)
- {fprintf(stderr,
- "Invalid vertical scaling factor or resolution\n");
- exit(1);
- }
- if(y_scale > 10.0)
- y_scale = (double)x_resolution / y_scale;
- }
- }
-
-
-@
-If |unicode| is |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}'. |min_char| represents the lower bound of
-the code range.
-
-If we are in \mf-like mode, |file_number| is taken from the command line,
-and |max_numb| will be set to~|1|.
-
-@<Write files@>=
- {int j, max_numb;
-
- if(!mf_like)
- {file_number = (unicode == TRUE ? (min_char >> 8) : 1);
- if(nmb_files == -1)
- max_numb = (unicode == TRUE ? 0x100 : 100);
- else
- max_numb = nmb_files;
- }
- else
- max_numb = 1;@#
-
- for(j = 0; (j < max_numb) && !end_of_file; file_number++, j++)
- write_file();@#
-
- nmb_files = j; /* the real number of output font files */
- }
-
-
-@
-@<Include files@>=
-#ifdef HAVE_CONFIG_H
-#include <c-auto.h>
-#endif
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#ifdef TM_IN_SYS_TIME
-#include <sys/time.h>
-#endif
-#include "hbf.h"
-
-
-
-@* The functions.
-The first function to be described is |write_file()|. Each \.{GF} file
-consists of three sections: a preamble, a data section, and a postamble. The
-functions |write_pre()|, |write_data()|, and |write_post()| handle this.
-
-@<Prototypes@>=
-static void write_file(void);
-
-
-@
-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.
-
-@c
-static void write_file(void)
- {char output_file[FILE_NAME_LENGTH + 1];
-
-
- if(pk_files)
- {if(mf_like)
- {if(unicode)
- sprintf(output_file, "%s%02x.%.0igf",@/
- output_name, file_number,
- long_extension ? (int)(x_resolution + 0.5) : 0);
- else
- sprintf(output_file, "%s%02i.%.0igf",@/
- output_name, file_number,
- long_extension ? (int)(x_resolution + 0.5) : 0);
- }
- else
- {if(unicode)
- sprintf(output_file, "%s%02x.gf", output_name, file_number);
- else
- sprintf(output_file, "%s%02i.gf", output_name, file_number);
- }
- if(!(out = fopen(output_file, WRITE_BIN)))
- {fprintf(stderr, "Couldn't open `%s'\n", output_file);
- exit(1);
- }
- if(!quiet)
- printf("Writing `%s' ", output_file);@#
-
- write_pre();
- write_data();
- write_post();
- fclose(out);@#
-
- if(!quiet)
- printf("\n");
- }
- else
- write_data();
- }
-
-
-@
-The preamble has two bytes at the very beginning, |PRE| and |GF_ID|. |PRE|
-starts the preamble, and |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.
-
-@d GF_ID 131
-@d PRE 247@#
-
-@d header " hbf2gf output "
-
-@<Prototypes@>=
-static void write_pre(void);
-
-
-@
-@s tm int
-
-@c
-static void write_pre(void)
- {char out_s[40], s[20];
- time_t secs_now;
- struct tm *time_now;
-
-
- strcpy(out_s, header);@#
-
- secs_now = time(NULL); /* system date and time */
- time_now = localtime(&secs_now);
- strftime(s, 20, "%Y.%m.%d:%H.%M", time_now);
- strcat(out_s, s);@#
-
- fputc(PRE, out);
- fputc(GF_ID, out);
- fputc(strlen(out_s), out);
- fputs(out_s, out);
- }
-
-
-@
-|write_data()| produces the middle part of the \.{GF} file. It first sets
-|char_adr_p| equal to the address of |char_adr[]| which will contain file
-offsets of the compressed characters.
-
-|input_size_x| and |input_size_y| reflect the original dimensions of the
-bitmap font, |pk_output_size_x| and |pk_output_size_y| contain the width and
-height of the output character box (in pixels), |pk_offset_x| and
-|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). |mag_x| and |mag_y| hold the scaling factors
-which are needed to reach |design_size|. |slant| defines the slant ($\Delta
-x / \Delta y$), |target_size_x| and |target_size_y| will be the final
-dimensions; |magstep_x = target_size_x / design_size| is \TeX's
-\.{\\magstep}.
-
-The \CEE/ standard specifies that all global values will be automatically
-set to~|0| if no initialization value is given.
-
-@<Global...@>=
-long char_adr[256];
-long *char_adr_p;@#
-
-int pk_offset_x;
- /* horizontal offset (increase character width a bit; will be applied on
- both the left and the right side) */
-double tfm_offset_x;
-int pk_offset_y;
- /* vertical offset (must be configured to desired font size) */
-double tfm_offset_y;@#
-
-int input_size_x;
-int input_size_y;
-const char *font_encoding; /* taken from the HBF file */
-int pk_width; /* without slant */
-int pk_output_size_x;
- /* the output character box dimensions without offsets */
-double tfm_output_size_x;
-int pk_output_size_y;
-double tfm_output_size_y;@#
-
-double design_size = 10.0; /* in points */
-double target_size_x; /* in points */
-double target_size_y;
-double magstep_x;
-double magstep_y;
-double slant;
-int rotation;@#
-
-double mag_x; /* horizontal and vertical magnification values */
-double mag_y;@#
-
-int empty_char; /* a flag whether the character does not exist or is empty */
-int last_char; /* the last valid character in a \.{GF} file */@#
-
-int dot_count; /* this counts the processed characters;
- every ten characters a dot is output to the screen */
-
-
-@
-@<Prototypes@>=
-static void write_data(void);
-
-
-@
-@c
-static void write_data(void)
- {dot_count = 0;
- char_adr_p = char_adr;@#
-
- for(last_char = 0; (last_char < 256) && !end_of_file; last_char++)
- @<Write character@>@;
- }
-
-
-@
-The code in this section saves the current file position first and calls
-|make_pixel_array()|, which expands and scales the character bitmap.
-
-|BOC| (and |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).
-
-|write_coding()| compresses and outputs the bitmap; |EOC| (End Of Character)
-finishes the current character.
-
-@d BOC 67
-@d BOC1 68 /* simplified version of |BOC| */
-@d EOC 69
-
-@<Write character@>=
- {if(dot_count++ % 10 == 0) /* a progress report for impatient users */
- if(pk_files && !quiet)
- {printf(".");
- fflush(stdout);
- }@#
-
- empty_char = FALSE;
- make_pixel_array();
- if(end_of_file)
- return;@#
-
- if(pk_files)
- {*char_adr_p = ftell(out);
- char_adr_p++;@#
-
- if(empty_char)
- {fputc(BOC1, out);
- fputc((unsigned char)last_char, out);
- fputc(0, out);
- fputc(0, out);
- fputc(0, out);
- fputc(0, out);
- fputc(EOC, out);
- }
- else
- {fputc(BOC, out);
- fputl(last_char, out);
- fputl(-1L, out);
- fputl(pk_offset_x, out);
- fputl(pk_output_size_x + pk_offset_x, out);
- fputl(pk_offset_y, out);
- fputl(pk_output_size_y + pk_offset_y, out);@#
-
- write_coding();@#
-
- fputc(EOC, out);
- }
- }
- }
-
-
-@
-The current \.{GF} file will be completed with data written by
-|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 (|coding[]| and |comment[]|). The second describes the font as a
-whole, and the last marks the end of the file.
-
-|pk_total_min_x| up to |pk_total_max_y| define the greatest bounding box of
-this file (including offsets); the horizontal character escapement after
-drawing the character is |pk_dx|. |tfm_width| is the width in multiples of
-the design size ignoring the target size.
-
-@d _2_16 65536.0 /* $2^{16}$ */
-@d _2_20 1048576.0 /* $2^{20}$ */
-
-@<Global...@>=
-char coding[STRING_LENGTH + 1]; /* a comment describing the font encoding */
-char comment[STRING_LENGTH + 1]; /* a comment describing the font */@#
-
-unsigned long checksum;@#
-
-long pk_total_min_x;
-long pk_total_max_x;
-long pk_total_min_y;
-long pk_total_max_y;@#
-
-int dpi_x; /* printer resolution */
-int dpi_y;
-double ppp_x; /* pixels per point */
-double ppp_y;
-
-
-@
-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.
-
-@<Prototypes@>=
-static void write_post(void);
-
-
-@
-@c
-static void write_post(void)
- {long special_adr;
- long post_adr;@#
-
- long designsize = design_size * _2_20; /* design size $* 2^{20}$ */@#
-
- int pk_dx;
- long tfm_width;@#
-
- int i;
- long temp;
-
-
- ppp_x = dpi_x / 72.27 * magstep_x;
- ppp_y = dpi_y / 72.27 * magstep_y;@#
-
- pk_total_min_x = pk_offset_x;
- pk_total_max_x = pk_output_size_x + 2 * pk_offset_x;
- pk_total_min_y = pk_offset_y;
- pk_total_max_y = pk_output_size_y + pk_offset_y;@#
-
- pk_dx = pk_width + 2 * pk_offset_x; /* no slant */
- tfm_width = (tfm_output_size_x + 2 * tfm_offset_x) * _2_20;
- /* width in multiples of design size $* 2^{20}$ */@#
-
- @<Special section@>@;
- @<Post section@>@;
- @<Postpost section@>@;
- }
-
-
-@
-\.{XXXn} will be followed by n~bytes representing the length of a string
-which follows immediately. |YYY| is a 32~bit integer which is normally
-connected with the preceding string (but not used here). |special_adr|
-contains the address of the ``special section''. All items here are
-optional.
-
-@d XXX1 239 /* these are all special command bytes */
-@d XXX2 240 /* not used */
-@d XXX3 241 /* not used */
-@d XXX4 242 /* not used */@#
-
-@d YYY 243 /* not used */
-
-@<Special section@>=
- special_adr = ftell(out);@#
-
- if(*coding)
- {fputc(XXX1, out); /* |XXX1| implies a string length |< 256| */
- fputc(strlen(coding), out);
- fputs(coding, out);
- }@#
-
- if(*comment)
- {fputc(XXX1, out);
- fputc(strlen(comment), out);
- fputs(comment, out);
- }
-
-
-@
-All character offsets collected in |char_adr| will be written to the output
-file. |fputl()| writes a 32~bit integer into a file.
-
-|CHAR_LOC0| (and |CHAR_LOC|) is the first byte of a character locator
-(i.e., offset, character code, and width information). |POST| starts the
-postamble, and |post_adr| points to the beginning byte of the postamble.
-
-@d POST 248@#
-
-@d CHAR_LOC 245
-@d CHAR_LOC0 246 /* simplified version of |CHAR_LOC| */
-
-@<Post section@>=
- post_adr = ftell(out);
- fputc(POST, out);
- fputl(special_adr, out);@#
-
- fputl(designsize, out);
- fputl(checksum, out);
- fputl(ppp_x * _2_16, out);
- fputl(ppp_y * _2_16, out);
- fputl(pk_total_min_x, out);
- fputl(pk_total_max_x, out);
- fputl(pk_total_min_y, out);
- fputl(pk_total_max_y, out);@#
-
- char_adr_p = char_adr;@#
-
- if(pk_dx < 256)
- {for(i = 0; i < last_char; i++) /* the character locators */
- {fputc(CHAR_LOC0, out);
- fputc(i, out);
- fputc(pk_dx, out);
- fputl(tfm_width, out);
- fputl(*char_adr_p++, out);
- }
- }
- else /* will only happen if |MAX_CHAR_SIZE >= 256| */
- {for(i = 0; i < last_char; i++)
- {fputc(CHAR_LOC, out);
- fputc(i, out);
- fputl(pk_dx * _2_16, out);
- fputl(0, out);
- fputl(tfm_width, out);
- fputl(*char_adr_p++, out);
- }
- }
-
-
-@
-|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 |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
-|GF_ID| will be next, then comes the address of the postamble section.
-
-Jumping to the postamble, a |POST| byte comes first, then the address of
-the special section, and afterwards all character offsets. These offsets and
-addresses describe the whole file.
-
-@d POSTPOST 249
-@d POSTPOST_ID 223
-
-@<Postpost section@>=
- fputc(POSTPOST, out);
- fputl(post_adr, out);
- fputc(GF_ID, out);
- temp = ftell(out);
- i = (int)(temp % 4) + 4;
- while(i--)
- fputc(POSTPOST_ID, out);
-
-
-@
-\TeX\ wants the most significant byte first.
-
-@<Prototypes@>=
-static void fputl(long, FILE *);
-
-
-@
-@c
-static void fputl(long num, FILE *f)
- {fputc(num >> 24, f);
- fputc(num >> 16, f);
- fputc(num >> 8, f);
- fputc(num, f);
- }
-
-
-@
-|make_pixel_array()| scales a character into the array |out_char[]| where
-each \\{byte} represents one pixel, contrary to the input file where each
-\\{bit} is used to store the character bitmap. |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 |PIXEL_MAXVAL = 255| for black.
-
-If |EOF| is encountered, |end_of_file| is set and the function returns
-immediately.
-
-@d BLACK 1
-@d WHITE 0@#
-
-@d PIXEL_MAXVAL 255
-@d SCALE 4096
-@d HALFSCALE 2048@#
-
-@d MAX_CHAR_SIZE 1023
-
-@<Global...@>=
-HBF_CHAR code;
-const unsigned char *bitmap;
- /* a proper input bitmap array will be allocated by the HBF API */
-const unsigned char *bP;@#
-
-unsigned char out_char[MAX_CHAR_SIZE * MAX_CHAR_SIZE + 1];
- /* the output bitmap array */
-unsigned char *out_char_p;@#
-
-unsigned char pixelrow[MAX_CHAR_SIZE];
-unsigned char temp_pixelrow[MAX_CHAR_SIZE];
-unsigned char new_pixelrow[MAX_CHAR_SIZE + 1];
- /* we need space to append a white pixel */@#
-int curr_row; /* for |read_row()| if we access the glyph rotated */
-
-long grayrow[MAX_CHAR_SIZE];@#
-
-long s_mag_x, s_mag_y, s_slant;
-
-
-@
-We need to initialize the |grayrow[]| array together with some other
-variables.
-
-Two steps are necessary to compute the |code| if we are in the \mf-like
-mode. Assuming that we search the code \.{0xXXYY}, we first set |code| to
-the value \.{0xXXAA}, where \.{0xAA} is equal to |min_2_byte| (getting
-|offset| as the number of remaining characters to reach the first character
-in our given subfont), then we increment |code| (and decrement |offset|)
-until |offset| equals~0.
-
-@<Initialize variables@>=
- {int col, offset;
-
- if(rotation)
- {int tmp;
-
-
- tmp = input_size_x;
- input_size_x = input_size_y;
- input_size_y = tmp;
- }@#
-
- if(mf_like)
- {target_size_x = design_size * (x_resolution / dpi_x);
- target_size_y = design_size * (x_resolution * y_scale / dpi_y);
- }
- else
- target_size_x = target_size_y = design_size;
- magstep_x = target_size_x / design_size;
- magstep_y = target_size_y / design_size;@#
-
- pk_offset_x = offset_x * magstep_x + 0.5;
- pk_offset_y = offset_y * magstep_y + 0.5;
- tfm_offset_x = offset_x / (dpi_x / 72.27) / design_size;
- tfm_offset_y = offset_y / (dpi_y / 72.27) / design_size;@#
-
- pk_width = input_size_x * mag_x * magstep_x + 0.5; /* without slant */
- pk_output_size_x = input_size_x * mag_x * magstep_x +
- input_size_y * mag_y * magstep_y * slant + 0.5;
- pk_output_size_y = input_size_y * mag_y * magstep_y + 0.5;
- tfm_output_size_x = input_size_x * mag_x /
- (dpi_x / 72.27) / design_size;
- tfm_output_size_y = input_size_y * mag_y /
- (dpi_y / 72.27) / design_size;
- if(pk_output_size_x > MAX_CHAR_SIZE)
- {fprintf(stderr, "Output character box width too big\n");
- exit(1);
- }
- if(pk_output_size_y > MAX_CHAR_SIZE)
- {fprintf(stderr, "Output character box height too big\n");
- exit(1);
- }@#
-
- for(col = 0; col < input_size_x; ++col)
- grayrow[col] = HALFSCALE;@#
-
- if(!mf_like)
- code = (min_char & 0xFF00) + min_2_byte;
- else
- {if((file_number < (unicode ? 0 : 1)) || (file_number >= 0x100))
- {fprintf(stderr, "Invalid subfile number\n");
- exit(1);
- }@#
-
- if(unicode)
- {offset = 0;
- code = file_number * 0x100;
- }
- else
- {offset = (file_number - 1) * 256 % nmb_2_bytes;
- code = (min_char & 0xFF00) + min_2_byte +
- (file_number - 1) * 256 / nmb_2_bytes * 0x100;
- }@#
-
- while(offset--)
- while(!b2_codes[code++ & 0xFF])
- /* eliminate invalid |b2_codes| */
- ;@#
-
- if(code > max_char)
- {fprintf(stderr, "Invalid subfile number\n");
- exit(1);
- }
- }
-
- s_mag_x = mag_x * magstep_x * SCALE;
- s_mag_y = mag_y * magstep_y * SCALE;
- s_slant = slant * SCALE;
- }
-
-
-@
-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.
-
-
-@<Prototypes@>=
-static void make_pixel_array(void);
-
-
-@
-@c
-static void make_pixel_array(void)
- {unsigned char *prP;
- unsigned char *temp_prP;
- unsigned char *new_prP;
- long *grP;@#
-
- register unsigned char *xP;
- register unsigned char *nxP;@#
-
- register int row, col;
- int rows_read = 0;
- register int need_to_read_row = 1;@#
-
- long frac_row_to_fill = SCALE;
- long frac_row_left = s_mag_y;@#
-
- int no_code = FALSE;
-
-
- prP = pixelrow;
- temp_prP = temp_pixelrow;
- new_prP = new_pixelrow;
- grP = grayrow;
- out_char_p = out_char; /* will be increased by |write_row()| */@#
-
-again:
- if(b2_codes[code & 0xFF]) /* a valid second byte? */
- {if(pk_files)
- {bitmap = hbfGetBitmap(hbf, code);
- bP = bitmap;
- /* will be increased by |read_row()| */@#
-
- if(!bitmap)
- empty_char = TRUE;
- else
- @<Scale row by row@>@;
- }
- }
- else
- no_code = TRUE;@#
-
- if((code & 0xFF) == max_2_byte)
- code += 0xFF - (max_2_byte - min_2_byte); /* go to next plane */
- if(code >= max_char)
- {end_of_file = TRUE;
- return;
- }@#
-
- code++;@#
-
- if(no_code)
- {no_code = FALSE;
- goto again;
- }
- }
-
-
-@
-@<Scale row by row@>=
- {if(pk_output_size_y == input_size_y) /* shortcut Y~scaling if possible */
- temp_prP = prP;@#
-
- curr_row = input_size_y - 1; /* only needed for rotated glyphs */
- for(row = 0; row < pk_output_size_y; ++row)
- {@<Scale Y from |pixelrow[]| into |temp_pixelrow[]|@>@;
- @<Scale X from |temp_pixelrow[]| into |new_pixelrow[]|
- and write it into |out_char[]|@>@;
- }
- }
-
-
-@
-@<Scale Y from |pixelrow[]| into |temp_pixelrow[]|@>=
- if(pk_output_size_y == input_size_y)
- /* shortcut Y~scaling if possible */
- read_row(prP);
- else
- {while(frac_row_left < frac_row_to_fill)
- {if(need_to_read_row)
- if(rows_read < input_size_y)
- {read_row(prP);
- ++rows_read;
- }@#
-
- for(col = 0, xP = prP; col < input_size_x; ++col, ++xP)
- grP[col] += frac_row_left * (*xP);@#
-
- frac_row_to_fill -= frac_row_left;
- frac_row_left = s_mag_y;
- need_to_read_row = 1;
- }@#
-
- @<Produce a temporary row@>@;
- }
-
-
-@
-Now |frac_row_left >= frac_row_to_fill|, so we can produce a row.
-
-@<Produce a temporary row@>=
- if(need_to_read_row)
- if(rows_read < input_size_y)
- {read_row(prP);
- ++rows_read;
- need_to_read_row = 0;
- }@#
-
- for(col = 0, xP = prP, nxP = temp_prP;
- col < input_size_x; ++col, ++xP, ++nxP)
- {register long g;
-
-
- g = grP[col] + frac_row_to_fill * (*xP);
- g /= SCALE;
- if(g > PIXEL_MAXVAL)
- g = PIXEL_MAXVAL;@#
-
- *nxP = g;
- grP[col] = HALFSCALE;
- }@#
-
- frac_row_left -= frac_row_to_fill;
- if(frac_row_left == 0)
- {frac_row_left = s_mag_y;
- need_to_read_row = 1;
- }
- frac_row_to_fill = SCALE;
-
-
-@
-To implement the slant we move the starting point |nxP| to the right
-according to the corresponding |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~|1|---such a large slant would be unusable
-anyway for typesetting purposes.
-
-@<Scale X from |temp_pixelrow[]| into |new_pixelrow[]|
- and write it into |out_char[]|@>=
- if(pk_width == input_size_x && s_slant == 0)
- /* shortcut X~scaling if possible */
- write_row(temp_prP);
- else
- {register long g = HALFSCALE;
- register long frac_col_to_fill = SCALE;
- register long frac_col_left;
- register int need_col = 0;
-
-
- nxP = new_prP;@#
-
- frac_col_left = (pk_output_size_y - row) * s_slant;
- while(frac_col_left >= frac_col_to_fill)
- {*(nxP++) = 0;
- frac_col_left -= frac_col_to_fill;
- }@#
-
- if(frac_col_left > 0)
- frac_col_to_fill -= frac_col_left;@#
-
- for(col = 0, xP = temp_prP; col < input_size_x; ++col, ++xP)
- {frac_col_left = s_mag_x;
- while(frac_col_left >= frac_col_to_fill)
- {if(need_col)
- {++nxP;
- g = HALFSCALE;
- }@#
-
- g += frac_col_to_fill * (*xP);
- g /= SCALE;
- if(g > PIXEL_MAXVAL)
- g = PIXEL_MAXVAL;@#
-
- *nxP = g;
- frac_col_left -= frac_col_to_fill;
- frac_col_to_fill = SCALE;
- need_col = 1;
- }@#
-
- if(frac_col_left > 0)
- {if(need_col)
- {++nxP;
- g = HALFSCALE;
- need_col = 0;
- }@#
-
- g += frac_col_left * (*xP);
- frac_col_to_fill -= frac_col_left;
- }
- }@#
-
- @<Write out a row@>@;
- }
-
-
-@
-@<Write out a row@>=
- if(frac_col_to_fill > 0)
- {--xP;
- g += frac_col_to_fill * (*xP);
- }@#
-
- if(!need_col)
- {g /= SCALE;
- if(g > PIXEL_MAXVAL)
- g = PIXEL_MAXVAL;
- *nxP = g;
- }@#
-
- *(++nxP) = 0; /* append a blank pixel */@#
-
- write_row(new_prP);
-
-
-@
-|read_row()| reads a row from |bitmap[]| and converts it into a graymap row.
-If the |rotation| flag has been set, we get the proper column instead (note
-that in this case |input_size_x| already reflects the width of the rotated
-glyph).
-
-@<Prototypes@>=
-static
-#ifdef __GNUC__
-__inline__
-#endif
-void read_row(unsigned char *);
-
-
-@
-@c
-static
-#ifdef __GNUC__
-__inline__
-#endif
-void read_row(unsigned char *pixelrow)
- {register int col, bitshift, offset;
- register unsigned char *xP;
- register unsigned char item = 0;
-
- if(rotation)
- {bitshift = 7 - (curr_row % 8);
- offset = (input_size_y + 7) / 8;
- bP = bitmap + curr_row / 8;
- for(col = 0, xP = pixelrow; col < input_size_x; ++col, ++xP)
- {*xP = ((*bP >> bitshift) & 1) == 1 ? PIXEL_MAXVAL : 0;
- bP += offset;
- }
- curr_row--;
- }
- else
- {bitshift = -1;
- for(col = 0, xP = pixelrow; col < input_size_x; ++col, ++xP)
- {if(bitshift == -1)
- {item = *(bP++); /* increase input bitmap pointer */
- bitshift = 7;
- }
- *xP = ((item >> bitshift) & 1) == 1 ? PIXEL_MAXVAL : 0;
- --bitshift;
- }
- }
- }
-
-
-@
-|write_row()| converts the graymap back into a bitmap using a simple
-threshold.
-
-@<Global...@>=
-int threshold = 128;
-
-
-@
-@<Prototypes@>=
-static
-#ifdef __GNUC__
-__inline__
-#endif
-void write_row(unsigned char *);
-
-
-@
-@c
-static
-#ifdef __GNUC__
-__inline__
-#endif
-void write_row(unsigned char *pixelrow)
- {register int col;
- register unsigned char *xP;
-
- for(col = 0, xP = pixelrow; col < pk_output_size_x; ++col, ++xP)
- *(out_char_p++) = (*xP >= threshold) ? 1 : 0;
- /* increase output bitmap pointer */
- }
-
-
-@
-Now comes the most interesting routine. The pixel array will be compressed
-in sequences of black and white pixels.
-
-|SKIP0|, |SKIP1|, and |SKIP2| indicate how many blank lines will be skipped.
-|PAINT_(x)| means that the next x~pixels will have the same color, then the
-color changes. |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: |SKIP1|~26 means `skip the next
-26~rows'.
-
-For further details please refer to ``\mf---the program''.
-
-@d PAINT_(x) (x) /* $0 \le x \le 63$ */
-@d PAINT1 64
-@d PAINT2 65
-@d PAINT3 66 /* not used */@#
-
-@d SKIP0 70
-@d SKIP1 71
-@d SKIP2 72
-@d SKIP3 73 /* not used */@#
-
-@d NEW_ROW_(x) ((x) + 74) /* $0 \le x \le 164$ */@#
-
-@d NOOP 244 /* not used */
-
-@<Prototypes@>=
-static void write_coding(void);
-
-
-@
-The |goto start| instruction causes some compilers to complain about
-``Unreachable code $\ldots$'' or something similar.
-
-@c
-static void write_coding(void)
- {register int count, skip;
- register unsigned char paint;
- register int x, y;
- register unsigned char *cp;
-
- x = 0;
- y = 0;
- cp = out_char + y * pk_output_size_x + x;
- count = skip = 0;
- paint = WHITE;
- goto start;@#
-
- while (y < pk_output_size_y)
- {@<Search blank lines@>@;
-start:
- @<Process rest of line@>@;
- y++;
- }
- }@#
-
-
-@
-@<Search blank lines@>=
- count = 0;
- x = 0;
- cp = out_char + y * pk_output_size_x + x;@#
-
- while(x < pk_output_size_x)
- {if(*cp == paint)
- count++;
- else
- {if(skip == 0)
- {if(count <= 164)
- fputc(NEW_ROW_(count), out);
- else
- {fputc(SKIP0, out);@#
-
- if(count < 256)
- {fputc(PAINT1, out);
- fputc(count, out);
- }
- else
- {fputc(PAINT2, out);
- fputc(count >> 8, out);
- fputc(count & 0xFF, out);
- }
- }
- }
- else
- {if(skip == 1)
- fputc(SKIP0, out);
- else
- {if(skip < 256)
- {fputc(SKIP1, out);
- fputc(skip, out);
- }
- else
- {fputc(SKIP2, out);
- fputc(skip >> 8, out);
- fputc(skip & 0xFF, out);
- }
- }
- skip = 0;
- if(count < 64)
- fputc(PAINT_(count), out);
- else if(count < 256)
- {fputc(PAINT1, out);
- fputc(count, out);
- }
- else
- {fputc(PAINT2, out);
- fputc(count >> 8, out);
- fputc(count & 0xFF, out);
- }
- }
- count = 0;
- paint = BLACK;
- break;
- }
- x++;
- cp++;
- }
- if(x >= pk_output_size_x)
- {skip++;
- y++;
- continue;
- }
-
-
-@
-@<Process rest of line@>=
- while(x < pk_output_size_x)
- {if(*cp == paint)
- count++;
- else
- {if(count < 64)
- fputc(PAINT_(count), out);
- else if(count < 256)
- {fputc(PAINT1, out);
- fputc(count, out);
- }
- else
- {fputc(PAINT2, out);
- fputc(count >> 8, out);
- fputc(count & 0xFF, out);
- }
- count = 1;
- paint = BLACK - paint;
- }
- x++;
- cp++;
- }
- if(paint == BLACK)
- {if(count < 64)
- fputc(PAINT_(count), out);
- else if(count < 256)
- {fputc(PAINT1, out);
- fputc(count, out);
- }
- else
- {fputc(PAINT2, out);
- fputc(count >> 8, out);
- fputc(count & 0xFF, out);
- }
- paint = WHITE;
- }
-
-
-
-@* 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.
-
-@<Prototypes@>=
-static void write_pl(void);
-
-
-@
-@c
-static void write_pl(void)
- {int i, pos;
- char output_file[FILE_NAME_LENGTH + 1];
- long t, sc;
- char *s;
- char tfm_header[] = "Created by hbf2gf";
-
- file_number--; /* for \mf-like mode */@#
-
- if(mf_like)
- {if(unicode)
- sprintf(output_file, "%s%02x.pl", output_name, file_number);
- else
- sprintf(output_file, "%s%02i.pl", output_name, file_number);
- }
- else
- sprintf(output_file, "%s.pl", output_name);@#
-
- if(!(out = fopen(output_file, WRITE_TXT)))
- {fprintf(stderr, "Couldn't open `%s'\n", output_file);
- exit(1);
- }
- if(!quiet)
- printf("\nWriting `%s'\n", output_file);@#
-
- fprintf(out,@/
- "\n(FAMILY %s%d)"@/
- "\n(CODINGSCHEME CJK-%s)",
- output_name, file_number, font_encoding);@#
-
- fprintf(out,@/
- "\n(DESIGNSIZE R %.6f)"@/
- "\n(COMMENT DESIGNSIZE IS IN POINTS)"@/
- "\n(COMMENT OTHER SIZES ARE MULTIPLES OF DESIGNSIZE)"@/
- "\n(CHECKSUM O %lo)"@/
- "\n(FONTDIMEN"@/
- "\n (SLANT R %.6f)"@/
- "\n (SPACE R 0.0)"@/
- "\n (STRETCH R 0.0)"@/
- "\n (SHRINK R 0.0)"@/
- "\n (XHEIGHT R 1.0)"@/
- "\n (QUAD R 1.0)"@/
- "\n (EXTRASPACE R 0.0)"@/
- "\n )", design_size, checksum, slant);@#
-
- s = tfm_header;
- i = strlen(s);
- t = ((long)i) << 24;
- sc = 16;
- pos = 18;@#
-
- fprintf(out, "\n");
- while(i > 0)
- {t |= ((long)(*(unsigned char *)s++)) << sc;
- sc -= 8;
- if(sc < 0)
- {fprintf(out, "\n(HEADER D %d O %lo)", pos, t);
- t = 0;
- sc = 24;
- pos++;
- }
- i--;
- }
- if(t)
- fprintf(out, "\n(HEADER D %d O %lo)", pos, t);
- fprintf(out, "\n");@#
-
- for(i = 0; i < 256; i++)
- {fprintf(out,@/
- "\n(CHARACTER O %o"@/
- "\n (CHARWD R %.6f)"@/
- "\n (CHARHT R %.6f)"@/
- "\n (CHARDP R %.6f)"@/
- "\n (CHARIC R %.6f)"@/
- "\n )",@/
- i,
- tfm_output_size_x + 2 * tfm_offset_x,
- tfm_output_size_y + tfm_offset_y,
- -tfm_offset_y,
- slant * (tfm_output_size_y + tfm_offset_y));
- }@#
-
- fclose(out);
- }
-
-
-
-@* The extended virtual font file for \Om.
-The following is very similar to |write_pl()|; we simply map the glyphs
-of the subfonts back to the original encoding positions.
-
-@<Prototypes@>=
-static void write_ovp(void);
-
-
-@
-@c
-static void write_ovp(void)
- {int c, i, nmb_subfonts, remainder, count, pos;
- char output_file[FILE_NAME_LENGTH + 1];
- long t, sc;
- char *s;
- char ofm_header[] = "Created by hbf2gf";
-
- nmb_subfonts = ((max_char - (min_char & 0xFF00)) / 256 * nmb_2_bytes)
- / 256 + 1;
- remainder = ((max_char - (min_char & 0xFF00)) / 256 * nmb_2_bytes)
- % 256;@#
-
- /* correction for the last incomplete second byte range */
- for(count = 0; count < (max_char & 0xFF); count++)
- if(b2_codes[count])
- remainder++;
- if(remainder >= 256)
- nmb_subfonts++;@#
-
- sprintf(output_file, "%s.ovp", output_name);@#
-
- if(!(out = fopen(output_file, WRITE_TXT)))
- {fprintf(stderr, "Couldn't open `%s'\n", output_file);
- exit(1);
- }
- if(!quiet)
- printf("\nWriting `%s'\n", output_file);@#
-
- fprintf(out,@/
- "\n(VTITLE Omega virtual font created by hbf2gf)"@/
- "\n(DESIGNSIZE R %.6f)"@/
- "\n(COMMENT DESIGNSIZE IS IN POINTS)"@/
- "\n(COMMENT OTHER SIZES ARE MULTIPLES OF DESIGNSIZE)"@/
- "\n(CHECKSUM O %lo)"@/
- "\n(FONTDIMEN"@/
- "\n (SLANT R %.6f)"@/
- "\n (SPACE R 0.0)"@/
- "\n (STRETCH R 0.0)"@/
- "\n (SHRINK R 0.0)"@/
- "\n (XHEIGHT R 1.0)"@/
- "\n (QUAD R 1.0)"@/
- "\n (EXTRASPACE R 0.0)"@/
- "\n )", design_size, checksum, slant);@#
-
- s = ofm_header;
- i = strlen(s);
- t = ((long)i) << 24;
- sc = 16;
- pos = 18;@#
-
- fprintf(out, "\n");
- while(i > 0)
- {t |= ((long)(*(unsigned char *)s++)) << sc;
- sc -= 8;
- if(sc < 0)
- {fprintf(out, "\n(HEADER D %d O %lo)", pos, t);
- t = 0;
- sc = 24;
- pos++;
- }
- i--;
- }
- if(t)
- fprintf(out, "\n(HEADER D %d O %lo)", pos, t);
- fprintf(out, "\n");@#
-
- for(i = 0; i < nmb_subfonts; i++)
- {fprintf(out,@/
- "\n(MAPFONT D %i"@/
- "\n (FONTNAME %s%02i)"@/
- "\n (FONTCHECKSUM O %lo)"@/
- "\n (FONTAT R 1.0)"@/
- "\n (FONTDSIZE R %.6f)"@/
- "\n )", i, output_name, i + 1, checksum, design_size);
- }@#
-
- for(c = min_char, i = 0, count = 0; c <= max_char; c++)
- {if(b2_codes[c & 0xFF] == VALID_SUBCODE)
- {fprintf(out,@/
- "\n(CHARACTER O %o"@/
- "\n (CHARWD R %.6f)"@/
- "\n (CHARHT R %.6f)"@/
- "\n (CHARDP R %.6f)"@/
- "\n (CHARIC R %.6f)"@/
- "\n (MAP"@/
- "\n (SELECTFONT D %i)"@/
- "\n (SETCHAR O %o)"@/
- "\n )"@/
- "\n )",@/
- c,
- tfm_output_size_x + 2 * tfm_offset_x,
- tfm_output_size_y + tfm_offset_y,
- -tfm_offset_y,
- slant * (tfm_output_size_y + tfm_offset_y),
- i,
- count);@#
-
- count++;
- if(count == 256)
- {count = 0;
- i++;
- }
- }
- else
- continue;
- }@#
-
- fclose(out);
- }
-
-
-
-@* 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 |nmb_files| times. The name of the job file is
-|output_name|.
-
-@d EXTENSION_LENGTH 8 /* the maximal length of a file extension */@#
-
-@d GFTOPK_NAME "gftopk"
-@d PLTOTF_NAME "pltotf"
-@d OVP2OVF_NAME "ovp2ovf"
-
-@<Global...@>=
-char job_extension[EXTENSION_LENGTH + 1];
-char rm_command[STRING_LENGTH + 1];
-char cp_command[STRING_LENGTH + 1];
-char pk_directory[STRING_LENGTH + 1];
-char tfm_directory[STRING_LENGTH + 1];@#
-
-int ofm_file = FALSE;
-
-
-@
-@<Prototypes@>=
-static void write_job(void);
-
-
-@
-@c
-static void write_job(void)
- {FILE *out;
- int i, j;
- char buffer[FILE_NAME_LENGTH + 1];
-
-
- strcpy(buffer, output_name);
- strcat(buffer, job_extension);
- if(!(out = fopen(buffer, WRITE_TXT)))
- {fprintf(stderr, "Couldn't open `%s'\n", buffer);
- exit(1);
- }
- if(!quiet)
- printf("\nWriting `%s'\n", buffer);@#
-
- if(pk_files)
- {if(unicode)
- {for(i = (min_char >> 8), j = 0; j < nmb_files; i++, j++)
- fprintf(out,@/
- "%s %s%02x.gf %s%s%02x.%.0ipk\n"@/
- "%s %s%02x.gf\n",@/
- GFTOPK_NAME, output_name, i,@/
- pk_directory, output_name, i,
- long_extension ? (int)(dpi_x * magstep_x + 0.5) : 0,@/
- rm_command, output_name, i);
- }
- else
- {for(i = 1; i <= nmb_files; i++)
- fprintf(out,@/
- "%s %s%02i.gf %s%s%02i.%.0ipk\n"@/
- "%s %s%02i.gf\n",@/
- GFTOPK_NAME, output_name, i,@/
- pk_directory, output_name, i,
- long_extension ? (int)(dpi_x * magstep_x + 0.5) : 0,@/
- rm_command, output_name, i);
- }
- }@#
-
- if(tfm_files)
- {fprintf(out,@/
- "\n"@/
- "%s %s.pl %s.tfm\n"@/
- "%s %s.pl\n"@/
- "\n",@/
- PLTOTF_NAME, output_name, output_name,@/
- rm_command, output_name);@#
-
- if(unicode)
- {for(i = (min_char >> 8), j = 0; j < nmb_files; i++, j++)
- fprintf(out,@/
- "%s %s.tfm %s%s%02x.tfm\n",@/
- cp_command, output_name,
- tfm_directory, output_name, i);
- }
- else
- {for(i = 1; i <= nmb_files; i++)
- fprintf(out,@/
- "%s %s.tfm %s%s%02i.tfm\n",@/
- cp_command, output_name,
- tfm_directory, output_name, i);
- }@#
-
- fprintf(out,@/
- "\n"@/
- "%s %s.tfm",@/
- rm_command, output_name);
- }@#
-
- if(ofm_file)
- {fprintf(out,@/
- "\n"@/
- "%s %s.ovp %s.ovf %s.ofm\n"@/
- "%s %s.ovp\n"@/
- "\n",@/
- OVP2OVF_NAME, output_name, output_name, output_name,@/
- rm_command, output_name);
- }@#
-
- fclose(out);
- }
-
-
-
-@* 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 |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 |0 <= slant <= 1|
- are allowed. \cr
- & Default is |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~|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} $=$ |1.0|
- \cr
- threshold & A value between |1| and |254| defining a
- threshold for converting the internal \cr
- & graymap into the output bitmap; lower values
- cut more pixels. \cr
- & Default value is |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~|-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 |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 |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 |pk_output_size_x| and |pk_output_size_y| must not exceed
-|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
-|x_resolution| and |y_scale| from the command line. \.{nmb\_fonts} will
-always be set to~|1|; no job file will be created.
-
-
-@
-@d PRINTER_MIN_RES_X 50
-@d PRINTER_MIN_RES_Y 50
-
-@<Global...@>=
-char Buffer[STRING_LENGTH + 1];
-
-
-@
-@<Prototypes@>=
-static void read_config(void);
-
-
-@
-If |config_file| isn't found in \mf-like mode we assume that the font
-isn't a HBF font at all.
-
-@c
-static void read_config(void)
- {HBF_BBOX *boxp;
- char *real_config_file;
-
-
- @<Handle extension@>@;@#
-
- real_config_file = TeX_search_cfg_file(config_file);
- if(!real_config_file)
- {if(mf_like)
- {if(!quiet)
- printf("Couldn't find `%s'\n", config_file);
- exit(2);
- }
- else
- {fprintf(stderr, "Couldn't find `%s'\n", config_file);
- exit(1);
- }
- }@#
-
- if(!(config = fopen(real_config_file, READ_TXT)))
- {if(!testing)
- {fprintf(stderr, "Couldn't open `%s'\n", config_file);
- exit(1);
- }
- else /* We reach this point only if no searching library is used */
- {if(!quiet)
- fprintf(stderr, "Couldn't find or open `%s'\n", config_file);
- exit(2);
- }
- }@#
-
- if(testing)
- {if(!quiet)
- printf("%s\n", real_config_file);
- exit(0);
- }
-
- @<Necessary parameters@>@;
- @<Optional parameters@>@;@#
-
- @<Get code range@>@;
- @<Get sub code range@>@;@#
-
- fclose(config);
- }
-
-
-@
-Here we check whether we have to add an extension.
-
-@<Handle extension@>=
- {int i, lastext = -1;
-
- for(i = 0; config_file[i]; i++)
- if(config_file[i] == '.')
- lastext = i;
- else if (config_file[i] == '/' ||
- config_file[i] == ':' ||
- config_file[i] == '\\')
- lastext = -1;@#
-
- if(lastext == -1)
- strcat(config_file, ".cfg");
- }
-
-
-@
-@<Necess...@>=
- {char hbf_header[STRING_LENGTH + 1];
- char *real_hbf_header;
-
- if(!fsearch("hbf_header"))
- config_error("hbf_header");
- else
- strcpy(hbf_header, Buffer);@#
-
- real_hbf_header = TeX_search_hbf_file(hbf_header);
- if(!real_hbf_header)
- {fprintf(stderr, "Couldn't find `%s'\n", hbf_header);
- exit(1);
- }@#
-
- hbfDebug = 1; /* we activate error messages of the HBF API
- while scanning the HBF header file */@#
-
- if(!(hbf = hbfOpen(real_hbf_header)))
- exit(1);@#
-
- hbfDebug = 0;@#
-
- boxp = hbfBitmapBBox(hbf);
- input_size_x = boxp->hbf_height; /* will be checked later for rotation */
- input_size_y = boxp->hbf_width;
- font_encoding = hbfProperty(hbf, "HBF_CODE_SCHEME");@#
-
- if(!fsearch("output_name"))
- config_error("output_name");
- else
- strcpy(output_name, Buffer);
- }
-
-
-@
-@<Global...@>=
-int offset_x;
-int offset_y;@#
-
-HBF_CHAR user_min_char;
-int have_min_char = FALSE;
-
-@
-@<Opt...@>=
- {if(fsearch("nmb_files"))
- nmb_files = atoi(Buffer);
- if(fsearch("unicode"))
- if(Buffer[0] == 'y' || Buffer[0] == 'Y')
- unicode = TRUE;
- if(fsearch("min_char"))
- {user_min_char = strtoul(Buffer, (char **)NULL, 0);
- have_min_char = TRUE;
- }@#
-
- if(!mf_like)
- {if(fsearch("pk_files"))
- if(Buffer[0] == 'n' || Buffer[0] == 'N')
- pk_files = FALSE;
- if(fsearch("tfm_files"))
- if(Buffer[0] == 'n' || Buffer[0] == 'N')
- tfm_files = FALSE;
- if(fsearch("ofm_file"))
- if(Buffer[0] == 'y' || Buffer[0] == 'Y')
- ofm_file = TRUE;
- if(fsearch("long_extension"))
- if(Buffer[0] == 'n' || Buffer[0] == 'N')
- long_extension = FALSE;
- }@#
-
- if(fsearch("slant"))
- slant = atof(Buffer);
- if(slant < 0.0 || slant > 1.0)
- {fprintf(stderr, "Invalid slant\n");
- exit(1);
- }
- if(fsearch("rotation"))
- if(Buffer[0] == 'y' || Buffer[0] == 'Y')
- rotation = TRUE;@#
-
- if(fsearch("mag_x"))
- mag_x = atof(Buffer);
- if(fsearch("mag_y"))
- mag_y = atof(Buffer);
- if(!mag_x && !mag_y)
- {mag_x = 1.0;
- mag_y = 1.0;
- }
- if(mag_x && !mag_y)
- mag_y = mag_x;
- if(mag_y && !mag_x)
- mag_x = mag_y;
- if(mag_x <= 0.0)
- {fprintf(stderr, "Invalid horizontal magnification\n");
- exit(1);
- }
- if(mag_y <= 0.0)
- {fprintf(stderr, "Invalid vertical magnification\n");
- exit(1);
- }@#
-
- if(fsearch("dpi_x"))
- dpi_x = atoi(Buffer);
- if(fsearch("dpi_y"))
- dpi_y = atoi(Buffer);
- if(!dpi_x && !dpi_y)
- {dpi_x = 300;
- dpi_y = 300;
- }
- if(dpi_x && !dpi_y)
- dpi_y = dpi_x;
- if(dpi_y && !dpi_x)
- dpi_x = dpi_y;
- if(dpi_x <= PRINTER_MIN_RES_X)
- {fprintf(stderr, "Invalid horizontal printer resolution\n");
- exit(1);
- }
- if(dpi_y <= PRINTER_MIN_RES_Y)
- {fprintf(stderr, "Invalid vertical printer resolution\n");
- exit(1);
- }@#
-
- if(fsearch("design_size"))
- design_size = atof(Buffer);@#
-
- if(fsearch("x_offset"))
- offset_x = atoi(Buffer);
- else
- offset_x = rotation ? 0 : (boxp->hbf_xDisplacement * mag_x + 0.5);
- if(fsearch("y_offset"))
- offset_y = atoi(Buffer);
- else
- offset_y = rotation ? 0 : (boxp->hbf_yDisplacement * mag_y + 0.5);
- if(!fsearch("comment"))
- comment[0] = '\0';
- else
- strcpy(comment, Buffer);@#
-
- if(fsearch("threshold"))
- threshold = atoi(Buffer);
- if(threshold <= 0 || threshold >= 255)
- {fprintf(stderr, "Invalid threshold\n");
- exit(1);
- }@#
-
- if(!fsearch("checksum"))
- checksum = 0;
- else
- checksum = strtoul(Buffer, (char **)NULL, 0);@#
-
- if(!fsearch("coding"))
- coding[0] = '\0';
- else
- strcpy(coding, Buffer);@#
-
- if(!fsearch("pk_directory"))
- pk_directory[0] = '\0';
- else
- strcpy(pk_directory, Buffer);@#
-
- if(!fsearch("tfm_directory"))
- tfm_directory[0] = '\0';
- else
- strcpy(tfm_directory, Buffer);@#
-
- if(fsearch("rm_command"))
- strcpy(rm_command, Buffer);
- else
- strcpy(rm_command, "rm");@#
-
- if(fsearch("cp_command"))
- strcpy(cp_command, Buffer);
- else
- strcpy(cp_command, "cp");@#
-
- if(!fsearch("job_extension"))
- job_extension[0] = '\0';
- else
- {strncpy(job_extension, Buffer, EXTENSION_LENGTH);
- job_extension[EXTENSION_LENGTH] = '\0';
- }
- }
-
-
-@
-The function |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 |min_char| has been supplied in the configuration file, we use that
-value instead.
-
-@<Global...@>=
-HBF_CHAR min_char, max_char;
-
-
-@
-@<Get code range@>=
- {const void *cp;
- HBF_CHAR dummy;
-
- cp = hbfGetCodeRange(hbf, NULL, &min_char, &max_char);
- for(; cp != NULL; cp = hbfGetCodeRange(hbf, cp, &dummy, &max_char))
- ;@#
-
- if(have_min_char)
- min_char = user_min_char;
- }
-
-
-@
-The function |hbfGetByte2Range()| is an extension to the HBF API.
-
-Successive calls return the byte~2 ranges in ascending order. We raise
-|VALID_SUBCODE| in the array |b2_codes[]| for all characters in subcode
-ranges.
-
-@d VALID_SUBCODE 1
-
-@<Global...@>=
-char b2_codes[256];
-unsigned char min_2_byte, max_2_byte;
-int nmb_2_bytes = 0;
-
-
-@
-@<Get sub code range@>=
- {const void *b2r;
- unsigned char dummy;
- int i;
-
- for(i = 0; i < 256; i++)
- b2_codes[i] = 0;@#
-
- b2r = hbfGetByte2Range(hbf, NULL, &min_2_byte, &max_2_byte);
- dummy = min_2_byte;
- for(; b2r != NULL; b2r = hbfGetByte2Range(hbf, b2r, &dummy, &max_2_byte))
- {for(i = dummy; i <= max_2_byte; i++)
- b2_codes[i] = VALID_SUBCODE;
- }@#
-
- for(i = 0; i < 256; i++) /* compute the number of valid |b2_codes| */
- if(b2_codes[i] == VALID_SUBCODE)
- nmb_2_bytes++;
- }
-
-
-@
-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 (|'\n'|). It also checks the presence of a parameter and fills
-|Buffer| if existent. |fsearch()| returns~1 on success.
-
-@<Prototypes@>=
-static int fsearch(const char *);
-
-
-@
-@c
-static int fsearch(const char *search_string)
- {char *P, p;
- const char *Q;
- char temp_buffer[STRING_LENGTH + 1];
- char env_name[STRING_LENGTH + 1];
- char *env_p;
- char *env_value;
- char *Buf_p;
- int Ch, ch, old_ch = '\n';
- int count = STRING_LENGTH;
-
- rewind(config); /* we start at offset~0 */@#
-
- do
- {Q = search_string;
- p = tolower((unsigned char)*Q);
- Ch = fgetc(config);
- ch = tolower(Ch);
- while(!(ch == p && old_ch == '\n') && Ch != EOF)
- /* search first character of |search_string|;
- |'\n'| must be the character before */
- {old_ch = ch;
- Ch = fgetc(config);
- ch = tolower(Ch);
- }@#
-
- for(;;)
- {if(*(++Q) == '\0')
- if((Ch = fgetc(config)) == ' ' || Ch == '\t')
- /* there must be a space or a tab stop after the keyword */
- goto success;
- Ch = fgetc(config);
- if(tolower(Ch) != tolower((unsigned char)*Q))
- break;
- }
- }
- while(Ch != EOF);@#
-
- return 0;@#
-
-success:
- P = temp_buffer;@#
-
- while((Ch = fgetc(config)) == ' ' || Ch == '\t')
- /* remove leading blanks and tabs */
- ;
- while(Ch != '\n' && --count > 0 && Ch != EOF) /* fill |Buffer| */
- {*P++ = Ch;
- Ch = fgetc(config);
- }
- *P = '\0';@#
-
- if (*temp_buffer)
- @<Check for environment variables@>@;
- else
- *Buffer = '\0';@#
-
- return (*Buffer) ? 1 : 0; /* is there something in the buffer? */
- }
-
-
-@
-To make the configuration file more flexible we allow environment variables
-in the arguments. We scan the parameter stored in |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
-|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 |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.
-
-@<Check for environment variables@>=
- {P = temp_buffer;
- Buf_p = Buffer;
- count = STRING_LENGTH - 1;@#
-
- while(*P && count > 0)
- {env_p = env_name;@#
-
- if(*P == '$')
- {P++;
- if(*P == '$')
- {*(Buf_p++) = *(P++);
- count--;
- continue;
- }
- while(*P == '{') @q } @>
- P++;
- if(!(isalpha((unsigned char)*P) || *P == '_'))
- {fprintf(stderr,@/
- "Invalid environment variable name in configuration file\n");
- exit(1);
- }
- *(env_p++) = *(P++);
- while(*P)
- {if(isalnum((unsigned char)*P) || *P == '_')
- *(env_p++) = *(P++);
- else
- {@q { @> while(*P == '}')
- P++;
- *env_p = '\0';
- break;
- }
- }@#
-
- env_value = getenv(env_name);
- if(env_value) /* append the environment value to |Buffer| */
- {while(*env_value && count > 0)
- {*(Buf_p++) = *(env_value++);
- count--;
- }
- }
- }
- else
- {*(Buf_p++) = *(P++);
- count--;
- }
- }
- *Buf_p = '\0';
- }
-
-
-@
-If an error occurs, |config_error()| will leave the program with an error
-message.
-
-@<Prototypes@>=
-static void config_error(const char *);
-
-
-@
-@c
-static void config_error(const char *message)
- {fprintf(stderr, "Couldn't find `%s' entry in configuration file\n",
- message);
- exit(1);
- }
-
-
-
-@* File searching.
-
-We support three searching engines: emtexdir, kpathsea, and MiKTeX (which is
-a Win32 port of kpathsea). For emtexdir, define |HAVE_EMTEXDIR| while
-compiling. For kpathsea, define |HAVE_LIBKPATHSEA|. For MikTeX, define
-|HAVE_MIKTEX|. If none of these macros is defined, a simple |fopen()| will
-be used instead.
-
-@<Include files@>=
-#if defined(HAVE_LIBKPATHSEA)
-#include "kpathsea/kpathsea.h"
-
-#elif defined(HAVE_EMTEXDIR)
-#include "emtexdir.h"
-
-#elif defined(HAVE_MIKTEX)
-#include "miktex.h"
-#endif
-
-@
-@<Global variables@>=
-#if defined(HAVE_EMTEXDIR)
-char emtex_version_string[] = "emTeXdir";
-#elif !defined(HAVE_MIKTEX)
-char no_version_string[] = "no search library";
-#endif
-
-
-@
-@<Prototypes@>=
-static const char *TeX_search_version(void);
-
-
-@
-@c
-static const char *TeX_search_version(void)
- {
-#if defined(HAVE_LIBKPATHSEA)
- return kpathsea_version_string;
-#elif defined(HAVE_EMTEXDIR)
- return emtex_version_string;
-#elif defined(HAVE_MIKTEX)
- char buf[200];
-
- strcpy(buf, "MiKTeX ");
- miktex_get_miktex_version_string_ex(buf + 7, sizeof (buf) - 7);
-
- return buf;
-#else
- return no_version_string;
-#endif
- }
-
-
-@
-@s emtex_dir int
-
-@<Global variables@>=
-#ifdef HAVE_EMTEXDIR
-struct emtex_dir cfg_path, hbf_path;
-#endif
-
-
-@
-@<Prototypes@>=
-#ifdef HAVE_EMTEXDIR
-extern int setup_list(struct emtex_dir *, char *, const char *, unsigned);
-static int dir_setup(struct emtex_dir *, const char *, const char *, unsigned);
-static char *file_find(char *, struct emtex_dir *);
-#endif
-
-
-@
-We slightly modify |emtex_dir_setup()| (from the file \.{emtexdir.c}) to
-output a warning in case the environment variable |env| isn't set properly.
-
-@c
-#ifdef HAVE_EMTEXDIR
-static int dir_setup(ed, env, dir, flags)
- struct emtex_dir *ed;
- const char *env;
- const char *dir;
- unsigned flags;
-
- {const char *val;
- char path[260];
-
- ed->alloc = 0;
- ed->used = 0;
- ed->list = NULL;@#
-
- if(env != NULL && (val = getenv(env)) != NULL)
- return setup_list(ed, path, val, flags);
- else
- fprintf(stderr,
- "Environment variable `%s' not set; use current directory\n",
- env);@#
-
- return TRUE;
- }
-#endif
-
-
-@
-@<Global variables@>=
-#ifdef HAVE_EMTEXDIR
-char name_buffer[FILE_NAME_LENGTH + 1];
-#endif
-
-
-@
-@c
-#ifdef HAVE_EMTEXDIR
-static char *file_find(name, list)
- char *name;
- struct emtex_dir *list;
-
- {if(emtex_dir_find(name_buffer, sizeof(name_buffer), list, name, EDF_CWD))
- return name_buffer;@#
-
- return NULL;
- }
-#endif
-
-
-@
-For emtexdir we use the environment variables \.{HBFCFG} and \.{HBFONTS} for
-configuration resp.\ HBF header files.
-
-@<Initialize \TeX\ file searching@>=
-#if defined(HAVE_LIBKPATHSEA)
- kpse_set_program_name(argv[0], "hbf2gf");
- kpse_init_prog("HBF2GF", 300, "cx", "cmr10");@#
-
-#elif defined(HAVE_EMTEXDIR)
- if(!dir_setup(&cfg_path, "HBFCFG", NULL, EDS_BANG))
- {fprintf(stderr,
- "Couldn't setup search path for configuration files\n");
- exit(1);
- }
- if(!dir_setup(&hbf_path, "HBFONTS", NULL, EDS_BANG))
- {fprintf(stderr,
- "Couldn't setup search path for HBF header files\n");
- exit(1);
- }
-#endif
-
-
-@
-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.
-
-@<Prototypes@>=
-static char *TeX_search_cfg_file(char *);
-static char *TeX_search_hbf_file(char *);
-
-
-@
-@c
-#if defined(HAVE_LIBKPATHSEA)
-static char *TeX_search_cfg_file(char *name)
- {
- return kpse_find_file(name, kpse_program_text_format, TRUE);
- }@#
-
-
-static char *TeX_search_hbf_file(char *name)
- {
- return kpse_find_file(name, kpse_miscfonts_format, TRUE);
- }@#
-
-
-#elif defined(HAVE_EMTEXDIR)
-static char *TeX_search_cfg_file(char *name)
- {return file_find(name, &cfg_path);
- }@#
-
-
-static char *TeX_search_hbf_file(char *name)
- {return file_find(name, &hbf_path);
- }@#
-
-
-#elif defined(HAVE_MIKTEX)
-static char *TeX_search_cfg_file(char *name)
- {char result[_MAX_PATH];
-
- if (!miktex_find_input_file("hbf2gf", *name, result))
- return 0;
- return strdup(result);
- }@#
-
-
-static char *TeX_search_hbf_file(char *name)
- {char result[_MAX_PATH];
-
-
- if (!miktex_find_miscfont_file(*name, result))
- return 0;
- return strdup(result);
- }@#
-
-
-#else
-static char *TeX_search_cfg_file(char *name)
- {return name;
- }@#
-
-
-static char *TeX_search_hbf_file(char *name)
- {return name;
- }
-#endif
-
-
-
-@* 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 |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}
-
-
-
-@* Index.