This manual documents how to install and run the GNU font utilities. It corresponds to version REPLACE-WITH-VERSION (released in REPLACE-WITH-MONTH-YEAR).
The introduction briefly describes the purpose and philosophy of the font utilities. The overview gives details on their general usage, especially how they interact, and describes various things which are common to all or most of the programs.
The first part of this master menu lists the major nodes in this Info document, including the index. The rest of the menu lists all the lower level nodes in the document.
--- The Detailed Node Listing ---
Installation
Prerequisites
Overview
Creating fonts
Command-line options
Specifying character codes
Bugs
Bug reporting
File formats
Encoding files
Imageto
Imageto usage
IMGrotate
IMGrotate usage
Fontconvert
Invoking Fontconvert
Charspace
CMI files
fontdimen command
Limn
Limn algorithm
Fitting the bitmap curve
BZRto
Metafont and BZRto
CCC files
BZR files
BZR characters
BPLtoBZR
BPL files
BPL characters
XBfe
XBfe usage
XBfe shape editing
BZRedit
BZRedit usage
Editing BPL files
GSrenderfont
GSrenderfont usage
Enhancements
This manual corresponds to version REPLACE-WITH-VERSION of the GNU font utilities.
You can manipulate fonts in various ways using the utilities: conversion of a scanned image to a bitmap font, hand-editing of bitmaps, conversion of a bitmap font to an outline font, and more. More generally, you can start with a scanned image of artwork and work your way through to a finished font with side bearings, accented characters, ligatures, and so on.
The font formats recognized by these programs are primarily those used by the (freely available) TeX typesetting system developed by Donald E. Knuth from 1977–1990. The filenames, font searching, and other aspects of their usage are also based on TeX. They also support output of PostScript Type 1 fonts.
Some of this software was originally written as part of the research program in digital typography at the University of Massachusetts at Boston, directed by Robert A. Morris. The staff at UMB, Rick Martin in particular, has been kind enough to let us to continue to use their computers, despite our completing the Master's program there in 1989.
See Prereqs, for what you need to have installed before you can compile these programs.
After that, here's what to do:
sh configure in the top-level directory. This tries to figure
out system dependencies and the installation prefix.
See The configure script (Kpathsearch library), for options and other information about configure.
make install.
If you encounter problems anywhere along the line, let us know. Known problems are listed below (see Problems). See Bugs, for details on how to submit a useful bug report.
To compile and use these programs, the following are necessary:
PLtoTF and
GFtoPK.
gawk. This is only needed if you want to
use GSrenderfont.
See the section below for information on how to get all these programs.
The canonical source for all GNU software, including the GNU C compiler, GNU make, and Ghostscript, is prep.ai.mit.edu:pub/gnu. That directory is replicated at many other sites around the world, including:
wuarchive.wustl.edu, ftp.cs.widener.edu,
uxc.cso.uiuc.edu
gatekeeper.dec.com:/pub/GNU
src.doc.ic.ac.uk:/gnu, ftp.informatik.tu-muenchen.de,
ftp.informatik.rwth-aachen.de:/pub/gnu
ugle.unit.no
ftp.denet.dk
archive.eu.net
archie.oz.au:/gnu (`archie.oz' or `archie.oz.au' for ACSnet)
ftp.cs.titech.ac.jp, utsun.s.u-tokyo.ac.jp:/ftpsync/prep,
cair.kaist.ac.kr:/pub/gnu
You can also order tapes with GNU software from the Free Software Foundation (thereby supporting the development of the font utilities and the rest of the GNU project); send mail to `gnu@prep.ai.mit.edu' for the latest prices and ordering information, or retrieve the file DISTRIB from a GNU archive.
The canonical source for the X window system is export.lcs.mit.edu:pub/R5. That directory is also shadowed at many other sites, including `gatekeeper.dec.com'. The FSF also sells X distribution tapes.
TeX is more scattered. A complete Unix TeX distribution is available by ordering a tape from the University of Washington (send email to `elisabet@u.washington.edu'. Three archives with complete (and identical) TeX collections:
ftp.uni-stuttgart.de:/soft/tex
ftp.tex.ac.uk:/pub/archive
pip.shsu.edu:/tex-archive
The canonical sources for just Web2C—the port of just TeX, Metafont, and friends to Unix, without DVI processors, fonts, macro packages, etc.—are:
ftp.cs.umb.edu:pub/tex/ (Boston) ics.uci.edu:TeX/ (California) ftp.th-darmstadt.de:pub/tex/src/web2c/ (Germany)
At all these sites, the files to retrieve are web.tar.Z and web2c.tar.Z.
The DVI-to-PostScript driver we recommend is Tom Rokicki's Dvips, and the X window system driver we recommend is Paul Vojta's XDvi. These programs are available from, respectively,
labrea.stanford.edu:pub/dvips*
export.lcs.mit.edu:contrib/xdvi.tar.Z
We have modified XDvi and Dvips to use the same path searching code as the current distribution of TeX and these font utilities; the modified versions are available from ftp.cs.umb.edu:pub/tex.
To use Metafont, you must have a file defining output devices. (See Metafont and BZRto.) We recommend you obtain modes.mf from
ftp.cs.umb.edu:pub/tex/modes.mf
You can retrieve the document describing all the details of the naming scheme for TeX fonts from
ftp.cs.umb.edu:pub/tex/fontname.tar.Z
This section lists some things which have caused trouble during installation. If you encounter other problems, please send a bug report. See Bugs, for how to submit a useful bug report.
__Xsi...), and furthermore that the multibyte functions need
to specifically call the dynamic linking functions.)
The file lib/dlsym.c (from the MIT X distribution) defines the
dlsym, dlclose, and dlopen symbols, so static
linking should work now.
If the current setup fails, it might work to change `-lXaw' in
the definition of X_libraries in lib/defs.make to
the full pathname of the Xaw library.
fmod: the routine takes two doubles, not one.
We simply corrected our system include file.
You may get compiler warnings for the file widgets/Bitmap.c at
the lines which use the Xt function XtIsRealized on systems which
define NULL as (void *) 0. The reason is that macro
definition of XtIsRealized in <X11/IntrinsicP.h>
incorrectly compares the result of XtWindowOfObject to
NULL, instead of 0. If the warnings bother you, fix
IntrinsicP.h.
XAPPLRESDIR environment variable to that
directory. See the tutorial on resources that comes with the MIT X
distribution (mit/doc/tutorial/resources.txt) for more
information.
Good luck.
This chapter gives an overview of what you do to create fonts using these programs. It also describes some things which are common to all the programs.
Throughout this document, we refer to various source files in the implementation. If you can read C programs, you may find these references useful as points of entry into the source when you are confused about some program's behavior, or are just curious.
Following is a pictorial representation of the typical order in which these programs are used, as well as their input and output.
GSrenderfont is not in the picture since it is intended for an entirely separate purpose (namely, making bitmaps from PostScript outlines). Fontconvert also has many functions which are not needed for the basic task of font creation from scanned images.
---------------
/ --------------------- | fontconvert |
/ ---------------
| ^ ^
scanned v |---------------| |
image TFM v v
and IFI ----------- GF ------------- TFM, GF -------- BZR
========> | imageto | ======> | charspace | =========> | limn | ======...
^ ----------- ------------- ^ --------
| ^ | (continued)
v CMI v
------------- --------
| imgrotate | | xbfe |
------------- --------
Metafont source ------ GF
|=====================> | mf | =========
(continued) | ------
|
BZR --------- TFM
... ======> | bzrto |========|=======================
--------- |
^ |
| | PostScript Type 3 (pf3)
CCC |======================
|
|
| BPL ------------ BZR
|=========> | bpltobzr | =====
------------
See File formats, for more information on these file formats.
The previous section described pictorially the usual order in which these programs are used. This section will do the same in words.
Naturally, you may not need to go through all the steps described here. For example, if you are not starting with a scanned image, but already have a bitmap font, then the first step—running Imageto—is irrelevant.
Here is a description of the usual font creation process, starting with a scanned image of a type specimen and ending with fonts which can be used by Ghostscript, TeX, etc.
An alternative to the above steps is to run Imageto with the `-epsf' option. This outputs an Encapsulated PostScript file with the image given as a simple PostScript bitmap. Then you can use Ghostscript or some other PostScript interpreter to look at the EPS file. This method is simpler, but has the disadvantage of using much more disk space, and needing a PostScript interpreter.
\table
or \sample commands to produce a font table. Next, print or
preview the DVI file that TeX outputs, as before. This will probably
reveal problems in your IFI file, e.g., that not all the characters are
present, or that they are not in the right positions. So you need to
iterate until the image is correctly processed.
testfont.tex should have come with your TeX distribution. If for some reason you do not have it, you can use the one distributed in the data directory.
At any rate, given a bitmap font f you then run Charspace (see Charspace) to add side bearings to f, producing a new bitmap font, say g, and a corresponding TFM file g.tfm. To do this, you must prepare a CMI file specifying the side bearings. See CMI files, for a description of CMI files.
Although Limn will (should) always be able to fit some sort of outline to the bitmaps, you can get the best results only by fiddling with the (unfortunately numerous) parameters. See Invoking Limn.
As you get closer to a finished font, you may want to prepare a CCC file (see CCC files) to tell BZRto how construct composite characters (pre-accented `A's, for example) to complete the font.
Briefly, to do the former, run Metafont with a mode of whatever
device you wish (the mode localfont will get you the most
common local device, if Metafont has been installed properly). Then you
can use testfont.tex to get a font sample, as described above.
To do the latter, run Metafont with no assignment to mode. This
should get you proof mode. You can then use GFtoDVI to get a DVI
file with one character per page, showing you the control points Limn
chose for the outlines.
Inevitably, as one problem gets fixed you notice new ones ...
This section gives a real-life example of font creation for the Garamond roman typeface, which we worked on concomitantly with developing the programs. We started from a scanned type specimen of 30 point Monotype Garamond, scanned using a Xerox 9700 scanner loaned to us from Interleaf, Inc. (Thanks to Paul English and others at Interleaf for this loan.)
To begin, we used Imageto as follows to look at the image file we had scanned (see Viewing an image). Each line is a separate command.
imageto -strips ggmr.img
fontconvert -tfm ggmrsp.1200
echo ggmrsp | tex strips.tex
xdvi -p 1200 -s 10 strips.dvi
ASCII encoding.
imageto -print-guidelines -print-clean-info -encoding=gnulatin ggmr.img
.notdef lines to ggmr.ifi as appropriate.
imageto -verbose -baselines=121,130,120 \
-designsize=30 -encoding=gnulatin ggmr.img
fontconvert -verbose -gf -tfm -filter-passes=3 -filter-size=3 \
ggmr30.1200 -output=ggmr30a
charspace -verbose -cmi=ggmr.1200cmi ggmr30a.1200 -output=ggmr30b
limn -verbose -corner-surround=4 -filter-surround=6 \
-filter-alternative-surround=3 -subdivide-surround=6 \
-tangent-surround=6 ggmr30b.1200
bzrto -verbose -metafont ggmr30b -output=ggmr30B
mf '\mode:=localfont; input ggmr30B'
echo ggmr30B | tex sample
dvips sample
fontconvert -verbose -gf -tfm -designsize=26 ggmr30b.1200 -output=ggmr26c
proof mode, followed by GFtoDVI, so we could
see how well Limn did at choosing the control points for the outlines.
See Proofing with Metafont. (The nodisplays tells Metafont
not to bother displaying each character in a window online.)
mf '\mode:=proof; nodisplays; input ggmr26D'
gftodvi ggmr26D.3656gf
Since these programs do not have counterparts on historical Unix
systems, they need not conform to an existing interface. We chose to
have all the programs use the GNU function getopt_long_only to
parse command lines.
As a result, you can give the options in any order, interspersed as you wish with non-option arguments; you can use `-' or `--' to start an option; you can use any unambiguous abbreviation for an option name; you can separate option names and values with either `=' or one or more spaces; and you can use filenames that would otherwise look like options by putting them after an option `--'.
By convention, all the programs accept only one non-option argument, which is taken to be the name of the main input file.
If a particular option with a value is given more than once, it is the last value which is used.
For example, the following command line specifies the options `foo', `bar', and `verbose'; gives the value `abc' to the `baz' option, and the value `xyz' to the `quux' option; and specifies the filename -myfile-.
-foo --bar -verb -abc=baz -quux karl -quux xyz -- -myfile-
By convention, all the programs accept only one non-option argument, which they take to be the name of the main input file.
Usually this is the name of a bitmap font. By their nature, bitmap fonts are for a particular resolution. You can specify the resolution in two ways: with the `-dpi' option (see the next section), or by giving an extension to the font name on the command line.
For example, you could specify the font foo at a resolution of
300dpi to the program program in either of these two ways
(`$ ' being the shell prompt):
$ program foo.300
$ program -dpi=300 foo
You can also say, e.g., `program foo.300gf', but the `gf' is ignored. These programs always look for a given font in PK format before looking for it in GF format, under the assumption that if both fonts exist, and have the same stem, they are the same.
See File lookups (Kpathsearch library), for more details of the filename lookup.
Certain options are available in all or most of the programs. Rather than writing identical descriptions in the chapters for each of the programs, they are described here.
This first table lists common options which do not convey anything about the input. They merely direct the program to print additional output.
This second table lists common options which change the program's behavior in more substantive ways.
-end'Most of the programs allow you to specify character codes for various purposes. Character codes are always parsed in the same way (using the routines in lib/charcode.c and lib/charspec.c).
You can specify the character code directly, as a numeric value, or indirectly, as a character name to be looked up in an encoding vector.
If a string being parsed as a character code is more than one character long, or starts with a non-digit, it is always looked up as a name in an encoding vector before being considered as a numeric code. We do this because you can always specify a particular value in one of the numeric formats, if that's what you want.
The encoding vector used varies with the program; you can always define an explicit encoding vector with the `-encoding' option. If you don't specify one explicitly, programs which must have an encoding vector use a default; programs which can proceed without one do not. See Encoding files, for more details on encoding vectors.
As a practical matter, the only character names which have length one are the 52 letters, `A'–`Z', `a'–`z'. In virtually all common cases, the encoding vector and the underlying character set both have these in their ASCII positions. (The exception is machines that use the EBCDIC encoding.)
The following variations for numeric character codes are allowed. The examples all assume the character set is ASCII.
Character codes must be between zero and 255 (decimal), inclusive.
The programs have a few common conventions for how to specify option values that are more complicated than simple numbers or strings.
Some options take not a single value, but a list. In this case, the individual values are separated by commas or whitespace, as in `-omit=1,2,3' or `-omit="1 2 3"'. Although using whitespace to separate the values is less convenient when typing them interactively, it is useful when you have a list that is so long you want to put it in the file. Then you can use cat in conjunction with shell quoting to get the value: `-omit="`cat file`"'.
Other options take a list of values, but each value is a keyword and a corresponding quantity, as in `-fontdimens name:real,name,real'.
Finally, a few options take percentages, which you specify as an integer between 0 and 100, inclusive.
These programs use the same environment variables and algorithms for finding font files as does (the Unix port of) TeX and its friends.
You specify the default paths in the top-level Makefile. The
environment variables TEXFONTS, PKFONTS, TEXPKS,
and GFFONTS override those paths. Both the default paths and the
environment variable values should consist of a colon-separated list of
directories.
Specifically, a TFM file is looked for along the path specified by
TEXFONTS; a GF file along GFFONTS, then TEXFONTS; a
PK file along PKFONTS, then TEXPKS, then TEXFONTS.
See Path specifications (Kpathsea library), for details of interpretation of environment variable values.
Naming font files has always been a difficult proposition at best. On the one hand, the names should be as portable as possible, so the fonts themselves can be used on almost any platform. On the other hand, the names should be as descriptive and comprehensive as possible. The best compromise we have been able to work out is described in a separate document: Introduction (Filenames for TeX fonts). See Archives, for where to obtain.
Filenames for GNU project fonts should start with `g', for the “source” abbreviation of “GNU”.
Aside from a general font naming scheme, when developing fonts you must keep the different versions straight. We do this by appending a “version letter” `a', `b', ... to the main bitmap filename. For example, the original Garamond roman font we scanned was a 30 point size, so the main filename was ggmr30 (`g' for GNU, `gm' for Garamond, `r' for roman). As we ran the font through the various programs, we named the output ggmr30b, ggmr30c, and so on.
Since the outline fonts produced by BZRto are scalable, we do not include the design size in their names. (BZRto removes a trailing number from the input name by default.)
(This chapter is adapted from the analogous one in the GCC manual, written by Richard Stallman.)
Your bug reports are essential in making these programs reliable.
Reporting a bug may help you by bringing a solution to your problem, or it may not. (If it does not, look in the service directory, which is part of the GNU CC and GNU Emacs distributions.) In any case, the principal function of a bug report is to help the entire community by making the next release work better.
Send bug reports for the GNU font utilities, or for their documentation,
to the address bug-gnu-utils@prep.ai.mit.edu. We also welcome
suggestions for improvements, no matter how small.
In order for a bug report to serve its purpose, you must include the information that makes for fixing the bug, as described below.
Thanks (in advance)!
If you are not sure whether you have found a bug, here are some guidelines:
bzrto -mf, that is a bug. You can run the TeX utility
programs GFtype and TFtoPL to check the validity of a GF or TFM file.
The purpose of a bug report is to enable someone to fix the bug if it is not known. It isn't important what happens if the bug is already known. Therefore, always write your bug reports on the assumption that the bug is not known.
Sometimes people give a few sketchy facts and ask, “Does this ring a bell?” or “Should this be happening?” This cannot help us fix a bug, so it is basically useless. We can only respond by asking for the details below, so we can investigate. You might as well expedite matters by sending them to begin with.
Try to make your bug report self-contained. If we ask you for more information, it is best if you include all the original information in your response, as well as the new information. We might have discarded the previous message, or even if we haven't, it takes us time to search for it. Similarly, if you've reported bugs before, it is still best to send all the information; we can't possibly remember what environment everyone uses!
To enable us to fix a bug, please include all the information below. If the bug was in compilation or installation, as opposed to in actually running one of the programs, the last two items are irrelevant. But in that case, please also make sure it is not a known problem before reporting it. See Problems.
You should include all of the following in your bug report:
Bugs typically apply to a single character in a font; you can find out what character is being processed with the `-verbose' option. It should then be straightforward to cut that single character out of the font with either the `-range' option and/or the `fontconvert' program, to make a new (very small) font. It is easier for us to deal with small files.
But if you don't want to take the time to break up the font, please send in the bug report anyway (with the entire font). We much prefer that to you not reporting the bug at all!
In other words, we need enough information so that we can run the offending program under the debugger, so we can find out what's happening. Without all the command-line arguments, or the input file in question, we cannot do this. Since you must have found the bug by running the program with a particular set of options and on a particular input file, you already have this information; all you need to do is send it!
Here are some things that are not necessary to include in a bug report.
Often people who encounter a bug spend a lot of time investigating which changes to the input file or command-line options will make the bug go away and which changes will not affect it.
This is often time consuming and not very useful, because the way we will find the bug is by running a single example under the debugger with breakpoints, not by pure deduction from a series of examples. You might as well save your time for something else.
A patch for the bug is useful if it is a good one. But don't omit the necessary information, such as the test case, on the assumption that a patch is all we need. We might see problems with your patch and decide to fix the problem another way, or we might not understand the patch at all. Without an example, we won't be able to verify that the bug is fixed.
Also, if we can't understand what bug you are trying to fix, or why your patch should be an improvement, we won't install it. A test case will help us to understand.
See Sending Patches for GNU CC (GCC Manual), for more details on the best way to write changes.
Such guesses are not useful, and often wrong. It is impossible to guess correctly without using the debugger to find the facts, so you might as well save your imagination for other things!
It is just as important to report bugs in the documentation as in the programs. If you want to do something using these programs, and reading the manual doesn't tell you how, that is probably a bug. In fact, the best way to report it is something like: “I want to do x; I looked in the manual in sections a and b, but they didn't explain it.”
If your bug report makes it clear that you've actually made an attempt to find the answers using the manual, we will be much more likely to take action (since we won't have to search the manual ourselves).
These programs use various data files to specify font encodings, auxliary information for a font, and other things. Some of these data files are distributed in the directory data; others must be constructed on a font-by-font basis.
If the environment variable FONTUTIL_LIB is set, data files are
looked up along the path it specifies, using the same algorithm as is
used for font searching (see Font searching). Otherwise, the
default path is set in the top-level Makefile.
The following sections (in other chapters of the manual) also describe file formats:
For the sake of brevity, we do not spell out every abbreviation (typically of file format names) in the manual every time we use it. This section collects and defines all the common abbreviations we use.
eexec-encrypted Type 1
font.
Data files read by these programs are text files that share certain syntax elements:
isspace) are ignored at the beginning of
a line.
A line can be as long as you want.
The encoding of a font specifies the mapping from character codes (an integer, typically between zero and 255) to the characters themselves; e.g., does a character with code 92 wind up printing as a backslash (as it does under the ASCII encoding) or as a double left quote (as it does under the most common TeX font encoding)? Put another way, the encoding is the arrangement of the characters in the font.
It is sad but true that no single encoding has been widely adopted, even for basic text fonts. (Text fonts and, say, math fonts or symbol fonts will clearly have different encodings.) Every typesetting program and/or font source seems to come up with a new encoding; GNU is no exception (see below). Therefore, when you decide on the encoding for the fonts you create, you should choose whatever is most convenient for the typesetting programs you intend to run it with. (Decent typesetting systems would make it trivial to set font encodings; unfortunately, almost nothing is decent in that regard!)
The encoding file format we invented is a font-format-independent
representation of an encoding. Encoding files are “data files” which
have the basic syntax elements described above (see Common file syntax). They are usually named with the extension .enc.
The first nonblank non-comment line in an encoding file is a string to put into TFM files as the “coding scheme” to describe the encoding; some common coding schemes are `TeX text', `TeX math symbol', `Adobe standard'. Case is irrelevant; that is, any programs which use the coding scheme should pay no attention to its case.
Thereafter, each nonblank non-comment line defines the character for the corresponding code: the first such line defines the character with code zero, the next with code one, and so on.
Each character consists of a name, optionally followed by ligature information. (All fonts using the same encoding should have the same ligatures, it seems to us.)
The character name in an encoding file is an arbitrary sequence of
nonblank characters (except it can't include a %, since that
starts a comment). Conventionally, it consists of only lowercase
letters, except where an uppercase letter is actually involved. (For
example, eacute is a lowercase e with an acute accent;
Eacute is an uppercase E with an acute accent.
If a character code has no equivalent character in the font, i.e., the
font table has a “blank spot”, you should use the name .notdef
for that code. This is the only name you can usefully give more than
once. If any other name is used more than once, the results are
undefined.
To avoid unnecessary proliferation of character names, you should use names from existing .enc files where possible. All the .enc files we have created are distributed in the data directory.
The ligature information for a character in an encoding file is optional. More than one ligature specification may be given. Each specification looks like:
lig second-char =: lig-char
This means that a ligature character lig-char should be present in the font for the current character (the one being defined on this line of the encoding file) followed by second-char. You give second-char and lig-char as character codes (see Specifying character codes). For example, in most text encodings (which involve Latin characters), some variation on the following line will be present:
f lig f =: 013 lig i =: 014 lig l =: 015
This will produce a ligature in the font such that when a typesetting program sees the two character sequence `ff' in the input, it replaces those two characters in the output with the single character at position octal 13 (presumably the `fi' ligature) of the font; when it sees `fi', the character at position octal 14 is output; when it sees `fl', the character at position octal 15 is output.
Metafont version 2 allows a more general ligature scheme; if there is a demand for it, it wouldn't be hard to add.
When we started making fonts for the GNU project, we had to decide on some font encoding. We hoped to use an existing one, but none that we found seemed suitable: the TeX font encodings, including the “Cork encoding” described in TUGboat 11#4, lacked many standard PostScript characters; conversely, the standard PostScript encodings lacked useful TeX characters. Since we knew that Ghostscript and TeX would be the two main applications using the fonts, we thought it unacceptable to favor one at the expense of the other.
Therefore, we invented two new encodings. The first one, “GNU Latin text” (distributed in data/gnulatin.enc), is based on ISO Latin 1, and is close to a superset of both the basic TeX text encoding and the Adobe standard text encoding. We felt it was best to use ISO Latin 1 as the foundation, since some existing systems actually use ISO Latin 1 instead of ASCII. We also left the first eight positions open, so particular fonts could add more ligatures or other unusual characters.
The second, “GNU Latin text complement” (distributed in data/gnulcomp.enc), includes the remaining pre-accented characters from the Cork encoding, the PostScript expert encoding, swash characters, small caps, etc.
When a program reads a TFM file, it's given an arbitrary string (at best) for the coding scheme. To be useful, it needs to find the corresponding encoding file. We couldn't think of any way to name our .enc files that would allow the filename to be guessed automatically. Therefore, we invented another data file which maps the TFM coding scheme strings to our .enc filenames.
This file is distributed as data/encoding.map. See Common file syntax, for a description of the common syntax elements.
Each nonblank non-comment line in encoding.map has two entries: the first word (contiguous nonblank characters) is the .enc filename; the rest of the line, after ignoring whitespace, is the string in the TFM file. This should be the same string that appears on the first line of the .enc file (see Encoding files).
Programs should ignore case when using the coding scheme string.
Here is the coding scheme map file we distribute:
adobestd Adobe standard
ascii ASCII
dvips dvips
dvips TeX text + adobestandardencoding
gnulatin GNU Latin text
gnulcomp GNU Latin text complement
psymbol PostScript Symbol
texlatin Extended TeX Latin
textext TeX text
zdingbat Zapf Dingbats
Imageto converts an image file (currently either in portable bitmap format (PBM) or GEM's IMG format) to either a bitmap font or an Encapsulated PostScript file (EPSF). An image file is simply a large bitmap.
If the output is a font, it can be constructed either by outputting a constant number of scanlines from the image as each “character” or (more usually) by extracting the “real” characters from the image.
The current selection of input formats is rather arbitrary. We implemented the IMG format because that is what our scanner outputs, and the PBM format because Ghostscript can output it (see GSrenderfont). Other formats could easily be added.
Usually there are two prerequisites to extracting a usable font from an image file. First, looking at the image, so you can see what you've got. Second, preparing the IFI file describing the contents of the image: the character codes to output, any baseline adjustment (as for, e.g., `j'), and how many pieces each character has. Each is a separate invocation of Imageto; the first time with either the `-strips' or `-epsf' option, the second time with neither.
In the second step, Imageto considers the input image as a series of image rows. Each image row consists of all the scanlines between a nonblank scanline and the next entirely blank scanline. (A scanline is a single horizontal row of pixels in the image.) Within each image row, Imageto looks top-to-bottom, left-to-right, for bounding boxes: closed contours, i.e., an area whose edge you can trace with a pencil without lifting it.
For example, in the following image Imageto would find two image rows, the first from scanlines 1 to scanline 7, the second consisting of only scanline 10. There are six bounding boxes in the first image row, only one in the second. (This example also shows some typical problems in scanned images: the baseline of the `m' is not aligned with those of the `i', `j', and `l'; a meaningless black line is present; the `i' and `j' overlap.)
01234567890123456789
0
1 x
2 x x x
3 x
4 x x x xxxxx
5 x x x x x x
6 x x x x
7 xx
8
9
10 xxxxxxxxxxxxxxx
Typically, the first step in extracting a font from an image is to see exactly what is in the image. (Clearly, this is unnecessary if you already know what your image file contains.)
The simplest way to get a look at the image file, if you have Ghostscript or some other suitable PostScript interpreter, is to convert the image file into an EPSF file with the `-epsf' option. Here is a possible invocation:
imageto -epsf ggmr.img
Here we read an input file ggmr.img; the output is ggmr.eps. You can then view the EPS file with
gs ggmr.eps
(presuming that gs invokes your PostScript interpreter).
If you don't have both a suitable PostScript interpreter and enough disk space to store the EPS file (it uses approximately twice as much disk space as the original image), the above won't work. Instead, to view the image you must make a font with the `-strips' option:
imageto -strips ggmr.img
The output of this will be ggmrsp.1200gf (our image having a resolution of 1200 dpi). Although the GF font cannot be conveniently viewed directly, you can use TeX and your favorite DVI processor to look at it, as follows:
fontconvert -tfm ggmrsp.1200
echo ggmrsp | tex strips
This outputs in strips.dvi, which you can view with your favorite DVI driver. (See Archives, for how to obtain the DVI drivers for PostScript and X we recommend.)
strips.tex is distributed in the imageto directory.
Once you can see what is in the image, the next step is to prepare the IFI file (see IFI files) corresponding to its characters. Imageto relies completely on the IFI files to describe the image; it makes no attempt at optical character recognition, i.e., guessing what the characters are from their shapes.
You must also decide on a few more aspects of the output font, which you specify with options:
For instance, in the example image in Imageto usage, it would be best to specify `-baselines=2,0'. The `2' is scanline #5 in that image. The `0' is an arbitrary value for scanline #10, which we will ignore via the IFI file (see IFI files).
For each character written, the `-print-guidelines' option produces output on the terminal that looks like:
75 (K) 5/315
This means that character code 75, whose name in the encoding file is `K', has its bottom row at row 5, and its top row at row 315; i.e., the character has five blank rows above the origin. This is almost certainly wrong (the letter `K' should sit on the typesetting baseline), so we would want to adjust the baseline upwards to 0 via an individual character baseline adjustment of 5 in the IFI file (see IFI files).
The final invocation to produce the font might look something like this:
imageto -baselines=121,130,120 -designsize=26 ggmr
The output from this would be ggmr26.1200gf.
Your image may not be completely “clean”, i.e., the scanning process may have introduced artifacts: black lines at the edge of the paper; blotches where the original had a speck of dirt or ink; broken lines where the image had a continuous line. To get a correct output font, you must correct these problems.
To remove blotches, you can simply put .notdef in the appropriate
place in the IFI file. You can find the “appropriate place” when you
look at the output font; some character will be nothing but a (possibly
tiny) speck, and all the characters following will be in the wrong
position.
The `-print-clean-info' option might also help you to diagnose which bounding boxes are being assigned to which characters, when you are in doubt. Here is an example of its output:
[Cleaning 149x383 bitmap:
checking (0
checking (0
checking (0
checking (113
106]
The final `106' is the character code output (ASCII `j'). The size of the overall bitmap which contains the `j' is 149 pixels wide and 383 pixels high. The bitmap contained four bounding boxes, the last two of which belonged to the `j' and were kept, and the first two from the adjacent character (`i') and were erased. (As shown in the example image above, the tail of the `j' often overlaps the `i' in type specimens.)
If the image has blobs you have not removed with .notdef, you
will see a small bounding box in this output. The numbers shown are in
“bitmap coordinates”: (0,0) is the upper left-hand pixel of the
bitmap.
If a blotch appears outside of the row of characters, Imageto will consider it to be its own (very small) image row. If you are using `-baselines', you must specify an arbitrary value corresponding to the blotch, even though the bounding box in the image will be ignored. See the section above for an example.
An image font information (IFI) file is a text file which describes the contents of an image file. You yourself must create it; as we will see, the information it contains usually cannot be determined automatically.
If your image file is named foo.img (or foo.pbm), it is customary to name the corresponding IFI file foo.ifi. That is what Imageto looks for by default. If you name it something else, you must specify the name with the `-ifi-file' option.
Imageto does not look for an IFI file if either the `-strips' or `-epsf' options were specified.
Each nonblank non-comment line in the IFI file represents a a sequence of bounding boxes in the image, and a corresponding character in the output font. See Common file syntax, for a description of syntax elements common to all data files processed by these programs, including comments.
Each line has one to five entries, separated by spaces and/or tabs. If a line contains fewer than five entries, suitable defaults (as described below) are taken for the missing trailing entries. (It is impossible to supply a value for entry #3, say, without also supplying values for entries #1 and #2.)
Here is the meaning of each entry, in order:
.notdef, or if the character name is not specified in the
encoding, Imageto just throws away the bounding boxes. See Encoding files, for general information on encoding files.
-2.
You can run Charspace (see Charspace) to add side bearings to a font semi-automatically. This is usually less work than trying to guess at numbers here.
Here is a possible IFI file for the image in Imageto usage. We throw away the black line that is the second image row. (Imagine that it is a scanner artifact.)
% IFI file for example image.
i 0 2
j 0 2
l
m 1
.notdef % Ignore the black line at the bottom.
This section describes the options that Imageto accepts. See Command-line options, for general option syntax.
The main input filename (see Main input file) is called image-name below.
IMGrotate rotates an IMG file, either 90 or 180 degrees clockwise. We call the latter—somewhat inaccurately—a “flip”. (We haven't needed other rotation angles, so we haven't implemented them.)
The IMG format is an image format output by a few programs, including the one that drives the scanner we have. (Again, we haven't needed other image formats, so we haven't implemented them.)
Both the input and output are IMG files.
The current implementation of IMGrotate uses an extremely slow and stupid algorithm, because it was a quick hack. It would be useful to replace it with a better algorithm. See Program features, for a reference.
The physical construction of a source to be scanned may make it hard or impossible to end up with an upright image. But the task of extracting characters from an image is complicated by allowing for a rotated image. Hence this program to turn rotated images upright.
By default, the name of the output file is the same as the input file; both are extended with .img if necessary. If this would result in the output overwriting the input, `x' is prepended to the output name.
You specify clockwise rotation of an image with the option `-rotate-clockwise'. This rotates the input 90 degrees clockwise. For example, the following (an `h' on its side):
*****
*
*
***********
turns upright.
You specify “flip” rotation of an image with the option `-flip'. This flips the input end for end and reverses left and right, i.e., does a 180 degree rotation. For example, the following (an `h' upside down and backwards):
* *
* *
* *
***
*
*
*
turns upright.
This section describes the options that IMGrotate accepts. See Command-line options, for general option syntax.
The name of the main input file (see Main input file) is called image-name below.
Fontconvert performs manipulations on bitmap fonts: conversion to other formats, merging multiple fonts, adjusting individual characters, moving characters around within a font, ...
The input is either a GF or a PK bitmap font, and in some circumstances, a TFM file. (See File format abbreviations.) The output varies according to the options specified.
In the following sections we describe all the options Fontconvert accepts, grouped according to general function.
The following table describes the options which affect the output file(s) Fontconvert writes. You can specify as many as you like. If you don't specify any, the default is to write nothing at all.
In the following, font-name stands for the root part of the main input file (see Main input file). The output filenames here are the defaults; you can override them with the `-output-file' option (see Miscellaneous options).
This is mainly useful in conjunction with options that change the characters in the input font in some way.
If an existing TFM file is found, then Fontconvert uses it (by default) for the TFM header information, and for the ligature and kern information. Unless the `-baseline-adjust', `-column-split', filtering, or randomizing options were specified, Fontconvert also uses it for the character dimensions. (Those options radically change the appearance and size of the characters, so using the dimensions of the originals would be inappropriate.)
See Fontwide information options, for how to specify the global TFM information yourself, overriding the default.
The following table describes the options which affect the set of characters Fontconvert writes.
If a character appears in more than one font, its first appearance is the one that counts. Fontconvert issues a warning about such repeated characters.
The design size, resolution, and other global information in the output font is always taken from the main input font, not from the concatenated fonts.
The new characters have codes charspec, charspec+1, ..., charspec+n. (These character codes are subject to the remapping specified by `-remap'; see below. Any previous characters at those codes are overwritten.)
The bitmaps of the new characters are slices from the original character: 0 to column col_1-1, ..., col_n to the bitmap width. You specify the column numbers in bitmap coordinates, i.e., the first column is numbered zero.
To split more than one character, simply specify `-column-split' for each.
This option is useful when two different characters in a scanned image of a font were printed so closely together that their images overlap. In this case, Imageto cannot break the characters apart, because they are a single bounding box. But you can split them with this option; you have to use your best judgement for the exact column at which to split. (Probably judicious hand-editing with XBfe (see XBfe) will be necessary after you do this.)
The following options affect individual characters.
When any of them are specified, the dimensions of the output character are likely to be quite different than those of the input characters; therefore, Fontconvert does not copy the TFM information (when writing a TFM file) from an existing TFM file.
For the pixel at coordinate (x,y), Fontconvert looks at its neighbors in rows y − half-cell-size, ..., y-1, y+1, ..., y + half-cell-size, and similarly for the columns.
Fontconvert computes the average intensity of this square; if the result is greater than intensity, it outputs a black pixel at (x,y); a white one, otherwise.
This process is repeated for every pixel in every character, and every character is filtered passes times.
The default is to do no filtering, i.e., passes is zero. The default for half-cell-size is one; the default for intensity is .5.
For each black pixel, a first random number between zero and one is compared to probability. If it is greater, nothing happens. Otherwise, a second random number is chosen, this one between -distance and distance. The pixel is “moved” that far horizontally. Then repeat for the vertical axis.
The default is to do no randomization, i.e., distance is zero. The default for probability is .2.
These options provide a way for you to set the global information in TFM and GF files. They override the default values (which are taken from the input bitmap or TFM files).
You might want to use this after seeing the Metafont or PostScript fonts output by BZRto, and deciding they look too small. For example, the original Garamond type specimen we scanned was (nominally) printed in 30pt. But when scaled down to 10pt via Metafont, the characters looked too small. So we ran Fontconvert with `-designsize=26' on the bitmap font made from the original image, and then reran Limn, BZRto, and Metafont to see the result. (We settled on 26 after several trials.) See Creating fonts, for a description of all the steps in creating fonts from scanned images.
These options are the generic ones accepted by most (in some cases, all) programs. See Common options.
If filename does not have a suffix, extend filename with whatever is appropriate for the output format(s). In the case of GF and TFM output, if this would overwrite the input, prepend an `x' to the output name.
By default, use the name of the main input font for filename.
Charspace lets you add side bearings (the blank spaces on either side of a character) to a bitmap font. This is necessary because scanned images typically do not include side bearing information, and therefore Imageto (see Imageto) cannot determine it.
The input is a bitmap (GF or PK) font, together with one or more CMI files (see CMI files), which specify character metric information. If a corresponding TFM file exists, it is read to get default values for the character dimensions (Charspace promptly overwrites the widths). The output is a TFM file and (typically) a revised GF file with the new width information.
The basic idea for Charspace came from Harry Smith, via Walter Tracy's book Letters of Credit. See charspace/README for the full citation.
Charspace makes no attempt to be intelligent about the side bearings it computes; it just follows the instructions in the CMI files.
The CMI files must be created by human hands, since the information they contain usually cannot be determined automatically. See the next section for the details on what CMI files contain.
We supply one CMI file, common.cmi (distributed in the data directory), which defines more-or-less typeface-independent definitions for most common characters. Charspace reads common.cmi before any of the CMI files you supply, so your definitions override its.
common.cmi can be used for all typefaces because its definitions
are entirely symbolic; therefore, your CMI file must define actual
values for the identifiers it uses. For example, common.cmi
defines the right side bearing of `K' to be uc-min-sb; you
yourself must define uc-min-sb.
You must also define side bearings for characters not in common.cmi. And you can redefine side bearings that are in common.cmi, if you find its definitions unsuitable.
Once you have prepared a CMI file, you can run Charspace, e.g.:
charspace -verbose -encoding=enc-file fontname.dpi \
-output-file=out-fontname
where enc-file specifies the encoding, fontname the input font, dpi the resolution, and out-fontname the name of the output font.
With these options, Charspace will write files out-fontname.tfm and out-fontname.dpigf. You can then run TeX on testfont.tex, telling TeX to use the font out-fontname. This produces a DVI file which you can print or preview as you usually do with TeX documents.
This will probably reveal problems in your CMI file, e.g., the spacing for some characters or character combinations will be poor. So you need to iterate.
However, if you are planning to eventually run your bitmap font through Limn (see Limn) and BZRto (see BZRto) to make an outline font, there's little point in excessively fine-tuning the spacing of the original bitmap font. The reason is that the generated outline font will inevitably rasterize differently than the original bitmaps, and the change in character shapes will almost certainly affect the spacing.
Character metric information (CMI) files are free-format text files which (primarily) describe the side bearings for characters in a font. Side bearings are the blank spaces to the left and right of a character which makeprinted type easier to read, as well as more pleasing visually.
In addition to side bearing definitions, CMI files can also contain kerns, which insert or remove space between particular letter pairs, and font dimensions, global information about the font stored in the TFM file (see TFM fontdimens).
If your font is named foo.300gf (or ... pk), it is customary to name the corresponding CMI file foo.300cmi. That is what Charspace looks for by default. If you name it something else, you must use the `-cmi-files' option to tell Charspace its name. It is reasonable to use the resolution as part of the CMI filename, since the values written in it are (for the most part) in pixels.
See Common file syntax, for a precise description of syntax elements common to all data files processed by these programs, including comments.
See the file data/ggmr.1200cmi in the distribution for an example.
In the following sections, we describe the individual commands, the tokens that comprise them, and the way Charspace processes them.
Tokens in a CMI file are one of the following.
isspace)
not listed above, and terminated by a whitespace character.
In some contexts, an identifier is taken as a character name—a name from the encoding file Charspace is using, either the default or one you specified with `-encoding' (see Invoking Charspace). See Encoding files, for the definition of encoding files.
In all other cases, identifiers are internal to Charspace. The particular commands describe the semantics which apply to them.
Some identifiers are reserved, i.e., they cannot be used in any context except as described in the following sections. Reserved words are always shown in typewriter type.
An expression in a CMI file is one of: a number, an identifier, or a number followed by an identifier. This last, as in `.75 foo', denotes multiplication.
char command
The char command specifies both side bearings for a single
character. It has the form:
char charname expr1 , expr2
where:
width (charname). If these
expressions contain identifiers, the values of those identifiers are not
resolved until after Charspace has read all the CMI files.
Giving the side bearings symbolically is useful when the character definition is intended to be used for more than one typeface. For example, common.cmi (see Charspace usage) contains:
char K H-sb , uc-min-sb
char L H-sb , uc-min-sb
Then the CMI file you write for a particular font can define H-sb
and uc-min-sb, and not have to redefine the side bearings for
K and L.
char-width command
The char-width command specifies the set width and left side
bearing as a percentage of the total remaining space for a single
character. It has the form:
char-width charname width-expr , lsb-%-expr
where:
The char-width command is useful when you want a character to
have a particular set width, since it's much simpler to specify that
width and the left side bearing (and let the program compute the right
side bearing) than to somehow estimate the bitmap width and then choose
the side bearings to add up to the desired set width.
For example, in most fonts, the numerals all have the same width, to
ease typesetting of columns of them in tables. Thus, common.cmi
defines eight (the name for the numeral `8') as follows:
char-width eight numeral-width , eight-lsb-percent
Since the numeral width is traditionally one-half the em width of
the font, common.cmi defines numeral-width as
enspace, which in turn is defined to be half the quad
fontdimen.
eight-lsb-percent is defined to be `.5', thus centering the
`8'.
The other numerals are also defined to have width numeral-width,
but the lsb-percents vary according to the character shapes.
define command
The define command defines an identifier as a number. This is
useful to give a symbolic name to a constant used in more than one
character or fontdimen definition, for ease of change.
It has the form:
define id expr
The identifier id is defined to be the expression expr. Any
previous definition of id is replaced. The id can be used
prior to the define command; Charspace doesn't try to resolve any
definitions in the CMI files until after all files have been read.
kern command
The kern command defines a space to insert or remove between two
particular characters. The kerning information is written only to the
TFM file. It has the form:
kern name1 name2 expr
where name1 and name2 are character names, as in
the char command (see char command), and expr is the
amount of the kern in pixels.
For example:
kern F dot -7.5
would put an entry in the TFM file's kerning table such that when TeX typesets a `F' followed by a `.', it inserts an additional space equivalent to -7.5 pixels in the resolution of Charspace's input font, i.e., it moves the two characters closer together.
codingscheme command
The codingscheme command defines the encoding scheme to be used
for the output files. (See Encoding files, for a full description of
font encodings.) It has the form:
codingscheme string-constant
where string-constant is a coding scheme string; for example, `"GNU Latin text"'. This string is looked up in the data file encoding.map to find the name of the corresponding encoding file (see Coding scheme map file).
fontdimen command
The fontdimen command defines a font parameter to be put in the
TFM file. It has the form:
fontdimen fontdimen-name expr
where fontdimen-name is any of the fontdimen names listed in the section below, and expr gives the new value of the fontdimen, in pixels.
For example, common.cmi (see Charspace usage) makes the following definitions:
fontdimen quad designsize
fontdimen space .333 quad
This defines the fontdimen quad, which determines the
width of the em dimension in TeX, to be the same as the design
size of the font. (This is traditionally the case, although it is not a
hard-and-fast rule.) Then it defines the fontdimen space, which
is the normal interword space in TeX, to be one-third of the quad.
Because of the way that Charspace processes the CMI files
(see CMI processing), if you redefine the quad fontdimen in
another CMI file, the value of space will change correspondingly.
The section below lists all the TFM fontdimen names Charspace recognizes, and their meaning to TeX.
This section lists all the TFM fontdimens recognized by these programs: all those recognized by TeX, plus a few others we thought would prove useful when writing TeX macros.
A fontdimen is an arbitrary number, in all cases but one
(slant, see below) measured in printer's points, which is
associated with a particular font. Their values are stored in the TFM
file for the font. We also refer, context permitting, to fontdimens as
“font parameters”, or simply “parameters”.
Fontdimens affect many aspects of TeX's behavior: the interword spacing, accent placement, and math formula construction. The math fontdimens in particular are fairly obscure; if you don't have a firm grasp on how TeX constructs math formulas, the explanations below will probably be meaningless to you, and—unless you're making a font for math typesetting—can be ignored.
The common.cmi file which Charspace reads sets reasonable defaults for the fontdimens relevant to normal text typesetting.
When TeX (or other programs) scale a font, its fontdimen values are scaled proportionally to the design size. For example, suppose the designsize of some font f is 10pt, and some fontdimen in f has the value 7.5pt. Then if the font is used scaled to 20pt, the fontdimen's value is scaled to 15pt.
You can get the table of fontdimen values in a particular TFM file by running the standard TeX utility program PLtoTF and inspecting its (human-readable text) output.
In our programs and in PLtoTF, fontdimens are typically shown by their names. But each also has a number, starting at 1. You can use either the number or the name on the command line (in the argument to the `-fontdimens' option). The numbers are given in parentheses after the name in the table below.
In a few cases (fontdimens 8–13), the same number fontdimen has two different names, and two different meanings. This does not cause problems in practice, because these fontdimens are used only in the TeX math symbol and math extension fonts, which TeX can distinguish via its “math families” (see The TeXbook for the details).
slant (1)slant parameter is not scaled
with the font when it is loaded. It defines the “slant per pt” of the
font; for example, a slant of 0.2 means a 1pt-high
character stem would end 0.2pt to the right of where it began.
This value is typical for slanted or italic fonts; for normal upright
fonts, slant is zero, naturally. TeX uses this to position
accents.
space (2)space parameter defines the normal interword space of the
font. This is typically about one-third of the design size, but it
varies according to the type design: a narrow, spiky typeface will
have a small interword space relative to a wide, regular one.
Exception: in math fonts, the interword space is zero.
stretch (3)stretch parameter defines the interword stretch of the font.
This is typically about one-half of the space parameter. TeX
is reluctant to increase interword spacing beyond the width
space + stretch. In monospaced fonts, the stretch
is typically zero.
shrink (4)shrink parameter defines the interword shrink of the font.
This is typically about one-third of the space parameter. TeX
does not decrease interword spacing beyond the width space
- shrink. In monospaced fonts, the shrink is typically zero.
xheight (5)xheight parameter defines the x-height of the font, i.e., the
main body size. The height of the lowercase `x' is often used for this,
since neither the top nor the bottom of `x' are curves. There is no
hard-and-fast rule in TeX that the x-height must equal the height of
`x', however.
This fontdimen defines the value of the ex dimension in TeX.
TeX also uses this to position: it assumes the accents in the font
are properly positioned over a character that is exactly 1ex high.
quad (6)quad fontdimen defines the value of the em dimension
in TeX. This is often the same as the design size of the font, but
as usual, that's not an absolute requirement.
Typesetters often use ems and exs instead of hardwiring
dimensions in terms of (say) points; that way, experimenting with
different fonts for a particular job does not require changing the
dimensions.
extraspace (7)extraspace fontdimen defines the space TeX puts at the end
of sentence. (Technically, when the \spacefactor is 20000 or
more.) This is typically about one-sixth of the normal interword space.
num1 (8)num2 (9)num3 (10)denom1 (11)denom2 (12)sup1 (13)sup2 (14)sup3 (15)sub1 (16)sub2 (17)supdrop (18)subdrop (19)delim1 (20)delim2 (21)axisheight (22)defaultrulethickness (8)bigopspacing1 (9)bigopspacing2 (10)bigopspacing3 (11)bigopspacing4 (12)bigopspacing5 (13)leadingheight (23)leadingheight parameter defines the height component of the
recommended leading for this font. Leading is the
baseline-to-baseline distance when setting lines of type.
TeX does not automatically use this fontdimen, and the standard TeX fonts do not define it, but you may wish to include it in new fonts for the benefit of future TeX macros. This fontdimen is a GNU extension.
leadingdepth (24)leadingdepth parameters defines the depth of the recommended
leading for this font. See leadingheight directly above. This
fontdimen is a GNU extension.
fontsize (25)fontsize parameter is the design size of the font. This is
needed for TeX macros to find the font's design size. This fontdimen
is a GNU extension.
version (26)version parameter identifies a particular version of the TFM
file. Whenever the character dimensions, kerns, or ligature table for a
font changes, it is good to increment the version number. It is also good
to keep such changes to a minimum, since they can change the line breaks
and page breaks in documents typeset with previous versions. This
fontdimen is a GNU extension.
Here are some further details on how Charspace processes the CMI files:
define foo bar
define bar 1.0
char A foo , bar
is valid, and defines both side bearings of `A' to be 1.0. (See the preceding sections for the definition of the various commands allowed in CMI files.)
define foo bar
will elicit no complaint, if `foo' is not needed to make the output files.
define bar 100
define foo 2 bar
define bar 1
char A foo , foo
defines both side bearings of `A' to be 2, not 200.
designsize, to be the
design size of the input font (in pixels). It can be redefined like any
other identifier.
If you can read programs in the C language, you may find it instructive to examine the implementation of CMI file processing in the source files charspace/char.c and charspace/cmi.y. The source provides the full details of CMI processing.
This section describes the options that Charspace accepts. See Command-line options, for general option syntax.
The root of the main input fontname is called font-name below.
codingscheme command
(see codingscheme command).
If a TFM file font-name.tfm exists, it is also read for default ligature, headerbyte, and fontdimen information. Definitions in the CMI files override those in such a TFM file.
If filename has a suffix, and `-no-gf' was not specified, Charspace complains and gives up, since it can't output two files with the same name.
By default, use the name of the main input font for filename.
xheight fontdimen
(see TFM fontdimens); default is 120 (ASCII `x'). (It is
reasonable to use 120 instead of whatever `x' is in the underlying
character set because most font encoding schemes are based on ASCII
regardless of the host computer's character set.)
These days, fonts to be used on computers are represented in one of two ways: as a bitmap font, which specifies each individual pixel in the image of a character; and/or as an outline font, which specifies the image as a collection of mathematically-specified curves. Each method has its own advantages and disadvantages; typesetting programs, page description languages, and output devices can generally deal with both.
Limn converts a font from a bitmap to an outline by fitting curves to the pixels. Non-shape-related information in the bitmap font, such as that for the side bearings, is preserved in the outline output.
Specifically, the input is a bitmap (GF or PK) font. The output is a BZR outline font (see BZR files), which can then be converted to (for example) Metafont or PostScript with BZRto (see BZRto).
There is a fair amount of literature on converting bitmaps to outlines. We found three particularly helpful: Philip Schneider's Master's thesis on his system Phoenix; Michael Plass and Maureen Stone's article `Curve-fitting with piecewise parametric cubics' published in SIGGRAPH; and Jakob Gonczarowski's article `A fast approach to auto-tracing (with parametric cubics)' in the RIDT 91 conference proceedings. See the file limn/README for the full citations.
Limn can always (barring bugs, of course) fit some sort of outline to the bitmap input. But its default fit is likely to be far from the ideal: character features may disappear, curves distorted, straight lines turned into curves and curves into straight lines, and on and on.
To control the fitting process, you must specify options to override Limn's defaults. To describe those options, we must describe the algorithm Limn uses to do the fitting, which we do in this section. We mention the options at the appropriate point.
The next section summarizes all the options, in alphabetical order.
Here is a schematic of the algorithm. The subsections below go into detail for each step. Except for the very first step, this is implemented in limn/fit.c.
find pixel outlines
for each pixel outline:
find corners
for each curve list:
remove knees
filter
if too small:
fit with straight line
otherwise fit with spline:
set initial t values
find tangents
fit with one spline
while error > reparameterize-threshold
if error > error-threshold
if linearity < line-threshold
revert bad lines
align endpoints
The first step in the conversion from a character shape represented as a bitmap to a list of mathematical curves is to find all the cyclical outlines (i.e., closed curves) in the bitmap image. The resulting list is called a pixel outline list. Each pixel outline in the list consists of the pixel coordinates of each edge on the outline.
For example, the pixel outline list for an `i' has two elements: one for the dot, and one for the stem. The pixel outline list for an `o' also has two elements: one for the outside of the shape, and one for the inside.
But we must differentiate between an outside outline (whose interior is to be filled with black to render the character) and an inside outline (whose interior is to be filled with white). Limn's convention is to write the pixel coordinates for outside outlines in counterclockwise order, and those for inside outlines in clockwise order.
This counterclockwise movement of outside outlines is required by the Type 1 format used for PostScript fonts, which is why we adopted that convention for Limn.
For example, consider a pixel outline consisting of a single black pixel at the origin. The pixel has four corners, and hence the outline will have four coordinates. Limn looks for starting pixels from top to bottom, left to right, within a bitmap image. Thus, the list of pixel coordinates will start at (0,1) and proceed counterclockwise: (0,0) (1,0) (1,1). Here is a picture:
start => (0,1)<-(1,1)
| ^
v |
(0
Because finding pixel outlines does not involve approximation or estimation, there are no options to control the process. Put another way, Limn will always find the correct pixel coordinates for each outline.
Once these pixel outlines have been found, each is then processed independently; i.e., all the remaining steps, described in the following sections, operate on each pixel outline individually.
The source code for this is in limn/pxl-outline.c and lib/edge.c.
Recall that our final goal is to fit splines, i.e., continuous curves, to the discrete bitmap image. To that end, Limn looks for corners in each pixel outline (see the previous section)—points where the outline makes such a sharp turn that a single curve cannot possibly fit well. Two corners mark the endpoints of a curve.
We call the result a curve list, i.e., a list of curves on the pixel outline: the first curve begins at that first corner and continues through the second corner; and so on, until the last, which begins with the last corner found and continues through the first corner. (Each pixel outline is cyclic by definition; again, see the previous section.)
The corner-finding algorithm described below works fairly well in practice, but you will probably need to adjust the parameters it uses. Finding good corners is perhaps the most important part of the entire fitting algorithm: missing a corner usually leads to a sharp point in the original image being rounded off to almost nothing; finding an extraneous corner usually leads to an extremely ugly blob.
Here is Limn's basic strategy for guessing if a given point p is a corner: compute the total displacement (in both x and y) for some number n of points before p; do the same for n points after p; find the angle a between those two vectors; if that angle is less than some threshold, p is a corner.
The threshold is 100 degrees by default; you can change this with the `-corner-threshold' option. You can see the angles at the chosen corners via `-log'.
However, when Limn finds a point p whose angle is below `corner-threshold', it won't necessarily take p as the corner. Instead, it continues looking for another `corner-surround' points; if it finds another point q whose angle is less than that of p, q will become the corner. (And then Limn looks for another `corner-surround' points beyond q, and so on.)
This continued searching prevents having two corners near each other, which is usually wrong, if the angles at the two would-be corners are approximately the same. On the other hand, sometimes there are extremely sharp turns in the outline within `corner-surround' pixels; in that case, one does want nearby corners after all.
So Limn has one more option, `-corner-always-threshold'. If the angle at a point is below this value (60 degrees by default), then that point is considered a corner, regardless of how close it is to other corners. The search for another corner within `corner-surround' pixels continues, however.
For each curve in the curve list determined by the corners on the pixel outline (see the previous section), Limn next removes knees—points on the inside of the outline that form a “right angle” with its predecessor and successor. That is, either (1) its predecessor differs only in x, and its successor only in y; or (2) its predecessor differs only in y, and its successor only in x.
It is hard to describe in words, but here is a picture:
**
X*
*
The point `X' is a knee, if we're moving in a clockwise direction.
Such a “right angle” point can be on either the inside or the outside of the outline. Points on the inside do nothing useful, they just slow things down and, more importantly, make the curve being fit less accurate. So we remove them. But points on the outside help to define the shape of the curve, so we keep those. (For example, if `X' was moved up one diagonally, we certainly want it as a part of the curve.)
Although we haven't found a case where removing knees produces an inferior result, there's no theory about it always helping. Also, you may just be curious what difference it makes (as we were when we programmed the operation). So Limn provides an option `-keep-knees'; if you specify it, Limn simply skips this step.
After generating the final pixel coordinates for each curve (see the previous sections), Limn next filters the curves to smooth them. Before this step, all the coordinates are on integer boundaries, which makes the curves rather bumpy and difficult to fit well.
To filter a point p, Limn does the following:
Repeatedly filtering a curve leads to even more smoothing, at the expense of fidelity to the original. By default, Limn filters each curve 4 times; you can change this with the `-filter-iterations' option.
If the curve has less than five points, filtering is omitted altogether, since such a short curve tends to collapse down to a single point.
The most important filtering parameter is the number n of surrounding points which are used to produce the new point. Limn has two different possibilities for this, to keep features from disappearing in the original curve. Let's call these possibilities n and alt_n; typically alt_n is smaller than n. Limn computes the total distance along the curve both coming into and going out of the point p for both n and alt_n surrounding points. Then it computes the angles between the in and out vectors for both. If those two angles differ by more than some threshold (10 degrees by default; you can change it with the `-filter-epsilon' option), then Limn uses alt_n to compute the new point; otherwise, it uses n.
Geometrically, this means that if using n points would result in a much different new point than using alt_n, use the latter, smaller number, thus (hopefully) distorting the curve less.
Limn uses 2 for n and 1 for alt_n by default. You can use the options `-filter-surround' and `-filter-alternative-surround' to change them. If the resolution of the input font is not 300dpi, you should scale them proportionately. (For a 1200dpi font, we've had good results with `-filter-surround=12' and `filter-alternative-surround= 6'.)
The steps in the previous sections are preliminary to the main fitting process. But once we have the final coordinates for each (bitmap) curve, we can proceed to fit it with some kind of continuous (mathematical) function: Limn uses both straight lines (polynomials of degree 1) and Bezier splines (degree 3).
To begin with, to use a spline the curve must have at least four points. If it has fewer, we simply use the line going through its first and last points. (There is no point in doing a fancy “best fit” for this case, since the original curve is so short.)
Otherwise, if the curve has four or more points, we try to fit it with a (piece of a) Bezier cubic spline. This spline is represented as a starting point, an ending point, and two “control points”. Limn uses the endpoints of the curve as the endpoints of the spline, and adjusts the control points to try to match the curve.
A complete description of the geometric and mathematical properties of Bezier cubics is beyond the scope of this document. See a computer graphics textbook for the details.
We will use the terms “splines”, “cubics”, “Bezier splines”, “cubic splines”, and so on interchangeably, as is common practice. (Although Bezier splines are not the only kind of cubic splines, they are the only kind we use.)
The sections below describe the spline-fitting process in more detail.
Limn must have some way to relate the discrete curve made from the original bitmap to the continuous spline being fitted to that curve. This is done by associating another number, traditionally called t, with each point on the curve.
Imagine moving along the spline through the points on the curve. Then t for a point p corresponds to how far along the spline you have traveled to get to p. In practice, of course, the spline does not perfectly fit all the points, and so Limn adjusts the t values to improve the fit (see Reparameterization). (It also adjusts the spline itself, as mentioned above.)
Limn initializes the t value for each point on the curve using a method called chord-length parameterization. The details of how this works do not affect how you use the program, so we will omit them here. (See the Plass & Stone article cited in limn/README if you're curious about them.)
As mentioned above, Limn moves the control points on the spline to optimally fit the bitmap. But it cannot just move them arbitrarily, because it must make sure that the spline fitting one part of the bitmap blends smoothly with those fit to adjacent parts.
Technically, this smooth blending is called continuity, and it comes in degrees. Limn is concerned with the first two degrees: zero- and first-order. Zero-order continuity between two curves simply means the curves are connected; first-order geometric (G1) continuity means the tangents to each curve at the point of connection have the same direction. (There are other kinds of continuity besides “geometric”, but they are not important for our purposes.)
Informally, this means that the final shape will not abruptly turn at the point where two splines meet. (Any computer graphics textbook will discuss the properties of tangents, continuity, and splines, if you're unfamiliar with the subject.)
To achieve G1 continuity, Limn puts the first control point of a spline on a line going in the direction of the tangent to the start of the spline; and it puts the second control point on a line in the direction of the tangent to the end of the spline. (It would be going far afield to prove that this together with the properties of Bezier splines imply G1 continuity, but they do. See Schneider's thesis referenced in limn/README for a complete mathematical treatment.)
For the purposes of using Limn, the important thing is that Limn must compute the tangents to the spline at the beginning and end, and must do so accurately in order to achieve a good fit to the bitmap. Since Limn has available only samples (i.e., the pixel coordinates) of the curve being fit, it cannot compute the true tangent. Instead, it must approximate the tangent by looking at some number of coordinates on either side of a point. By default, the number is 3, but you can specify a different number with the `-tangent-surround' option. If the resolution of the input font is different than 300dpi, or if the outline Limn fits to the bitmap seems off, you will want to scale it proportionately.
At last, after all the preprocessing steps described in the previous sections, we can actually fit a spline to the bitmap. Subject to the tangent constraints (see the previous section), Limn finds the spline which minimizes the error—the overall distance to the pixel coordinates.
More precisely, Limn uses a least-squares error metric to measure the “goodness” of the fit. This metric minimizes the sum of the squares of the distance between each point on the bitmap curve and its corresponding point on the fitted spline. (It is appropriate to square the distance because it is equally bad for the fitted spline to diverge from the curve in a positive or negative direction.)
The correspondence between the fitted spline and the bitmap curve is defined by the t value that is associated with each point (see Initializing t).
For a given set of t values and given endpoints on the spline, the control points which minimize the least-squares metric are unique. The formula which determines them is derived in Schneider's thesis (see the reference in limn/README); Limn implements that formula.
Once we have the control points, we can ask how well the resulting spline actually does fit the bitmap curve. Limn can do two things to improve the fit: change the t values (reparameterization); or break the curve into two pieces and then try to fit each piece separately (subdivision).
The following two sections describe these operations in more detail.
Reparameterization changes the t value for each point p on the bitmap curve, thus changing the place on the spline which corresponds to p. Given these new t values, Limn will then fit a new spline (see the previous section) to the bitmap, one which presumably matches it more closely.
Reparameterization is almost always a win. Only if the initial fit (see Initializing t) was truly terrible will reparameterization be a waste of time, and be omitted in favor of immediate subdivision (see the next section).
Limn sets the default threshold for not reparameterizing to be 30 “square pixels” (this number is compared to the least-squares error; see the previous section). This is usually only exceeded in cases such as that of an outline of `o', where one spline cannot possibly fit the entire more-or-less oval outline. You can change the threshold with the option `-reparameterize-threshold'.
If the error is less than `reparameterize-threshold', Limn reparameterizes and refits the curve until the difference in the error from the last iteration is less than some percentage (10 by default; you can change this with the option `-reparameterize-improve').
After Limn has given up reparameterization (either because the initial fit did not meet the `reparameterize-threshold', or because the error did not decrease by at least `reparameterize-improve'), the final error is compared to another threshold, 2.0 by default. (You can specify this with the option `-error-threshold'.) If the error is larger, Limn subdivides the bitmap curve (see the next section) and fits each piece separately. Otherwise, Limn saves the fitted spline and goes on to the next piece of the pixel outline.
When Limn cannot fit a bitmap curve within the `error-threshold' (see the previous section), it must subdivide the curve into two pieces and fit each independently, applying the fitting algorithm recursively.
As a strategy to improve the fit, subdivision is inferior to reparameterization, because it increases the number of splines in the character definition. This increases the memory required to store the character, and also the time to render it. However, subdivision is unavoidable in some circumstances: for example, the outlines on an `o' cannot be fit by a single spline.
For the initial guess of the point at which to subdivide, Limn chooses the point of worst error—the point where the fitted spline is farthest from the bitmap curve. Although this is usually a good choice, minimizing the chance that further subdivision will be necessary, occasionally it is not the best: in order to preserve straight lines, it is better to subdivide at the point where a straight becomes a curve if that point is close to the worst point. For example, this happens where a serif joins the stem.
Limn has three options to control this process:
Because fitting a shorter curve is easier, this process will always terminate. (Eventually the curve will be short enough to fit with a straight line (see Fitting the bitmap curve), if nothing else.)
Upon accepting a fitted spline (see the previous sections), Limn checks if a straight line would fit the curve as well. If so, that is preferable, since it is much faster to render straight lines than cubic splines.
More precisely, after fitting a cubic spline to a particular (segment of a) curve, Limn finds the straight line between the spline's endpoints, and computes the average distance (see Finding the spline) between the line and the curve. If the result is less than some threshold, 1 by default, then the spline is provisionally (see the next section) changed to a line.
You can change the theshold with the `-line-threshold' option.
Once an entire curve (i.e., the bitmap outline between two corners; see Finding corners) has been fit, Limn checks for straight lines that are adjacent to splines. Unless such lines fit the bitmap extremely well, they must be changed to splines.
The reason is that the point at which the line and spline meet will be a visible “bump” in the typeset character unless the two blend smoothly. Where two splines meet, the continuity is guaranteed from the way we constructed the splines (see Finding tangents). But where a line and spline meet, nothing makes the join smooth.
For example, if the outline of a `o' has been subdivided many times (as typically happens), a spline may end up fitting just a few pixels—so few that a line would fit just as well. The actions described in the previous section will therefore change the spline to a line. But since the adjacent parts of the `o' are being fit with curves, that line will result in a noticeable flat spot in the final output. So we must change it back to a spline.
We want this reversion to be more likely for short curves than long curves, since short curves are more likely to be the result of a small piece of a curved shape. So Limn divides the total distance between the fitted line and the bitmap curve by the square of the curve length, and compares the result to a threshold, .01 by default. You can change this with the `-line-reversion-threshold' option.
After fitting a mathematical outline of splines and lines to a pixel outline (see Finding pixel outlines), Limn aligns the endpoints on the fitted outline. This involves simply checking each spline to see if its starting point and ending point (in either axis) are “close enough” to each other. If they are, then they are made equal to their average.
This is useful because even a slight offset of the endpoints can be produce a noticeable result, especially for straight lines and corners.
By default, “close enough” is half a pixel. You can change this with the `-align-threshold' option.
While experimenting with the various fitting options listed in the preceding sections, you may find it useful to see the results of the fitting online. Limn can display the filtered (see Filtering curves) bitmap and the fitted outline online if it is run under the X window system and you specify `-do-display'.
Ordinarily, Limn stops at the end of fitting every character for you to hit return, so you have a chance to examine the result. If you just want to get a brief glimpse or something, you can specify `-display-continue'. Then Limn won't stop.
If you specify `-do-display', you must set the environment variable
DISPLAY to the X server you want Limn to use. For example, in
Bourne-compatible shells, you might do:
DISPLAY=:0 ; export DISPLAY
The output is shown on a grid, in which each square represents several pixels in the input. Corners are shown as filled squares; other pixels are shown as hollow squares.
Limn has several options that change the appearance of the online output:
You can change the size of the window Limn creates with the
geometry resource in your .Xdefaults file (see the
documentation in the file mit/doc/tutorials/resources.txt in the
X distribution if you aren't
familiar with X resources). The class name is Limn. For
example:
Limn*geometry: 300x400-0-0
makes the window 300 pixels wide, 400 pixels high, and located in the lower right corner of the screen.
This section lists the options that Limn accepts in alphabetic order. The previous section described many of these options in the context of the fitting algorithm.
See Command-line options, for general option syntax.
The root of the main input fontname is called font-name below.
DISPLAY environment variable can be opened.
See Displaying fitting online.
BZRto translates an outline font that's in our home-grown BZR outline font format (described below) to some other form: Metafont, Type 1 PostScript, Type 3 PostScript, or BPL.
BPL format is simply a human-readable form of BZR files. See BPL files. We discuss the other output forms below.
Besides straight format conversion, BZRto can also:
Metafont is a language for specifying graphic shapes, particularly characters in a font of a type, as well as the name of the program which interprets the language. It is commonly used to generate fonts for TeX and related software (TeX and Metafont were developed more-or-less simultaneously by Donald Knuth during the years 1977–1985). See Archives, for how to obtain the Metafont program.
BZRto generates a Metafont font foo.mf from the input file foo10.bzr (the `10' being the design size of the input) if you specify the `-metafont' option, as in:
bzrto -metafont foo
Presuming Metafont has been installed properly at your site, you can then make both a TFM and a GF file for foo at a size of 10pt and rasterized for your most common output device with the command:
mf '\mode:=localfont; input foo'
(The single quotes are not seen by Metafont; they just protect the backslash and semicolon from interpretation by your shell.)
The assignment to mode tells Metafont the name of your output
device. localfont should be a synonym for some real output
device, defined when Metafont was installed. The GF file will be named
foo.dpigf, where dpi is the resolution of the
localfont device.
Given the TFM and GF file, you can now use the font in TeX.
We described above how to get Metafont output at a size of 10pt.
To generate a GF file for a font foo at a different size, assign
to designsize on the command line, as follows:
mf '\mode:=localfont; designsize:=integer; input foo
For example, if localfont corresponds to a 300dpi
device, and you specify `designsize:=6', this command creates
foo.180gf, i.e., a 40% reduction from
foo.300gf.
In some cases, it may be more convenient to specify a magnification
factor than a new point size. (For example, this is the case if you are
enlarging or reducing an entire document by some constant factor, as
with TeX's \magnification command.) You can do this by
assigning to mag:
mf '\mode:=localfont; mag:=real; input foo
By default, mag is 1.0. You can also assign to both mag
and designsize. For example, if you set designsize to 5
and mag to 4, the output will be a 20pt font.
Although the Metafont language allows nonlinear scaling of fonts, so that the 6pt font would not simply be a reduced version of the 10pt font, BZRto cannot take advantage of this sophistication. The reason is that BZR files specify a single set of outlines, and the nonlinear scaling cannot be deduced from that. Perhaps we will extend the programs someday to handle interpolation between outlines of different sizes.
While creating fonts, it is useful to enlarge the character shapes enough to be able to make out small details. This blowing-up process is called proofing. Metafont works together with GFtoDVI, another program created as part of the TeX project, to do this.
You can make two kinds of proofs with Metafont: gray proofs and
smoke proofs. Metafont calls the former proof mode, and
the latter smoke mode. proof mode is the default, so if
you do not assign to mode at all, you get gray proofs. To get
smoke proofs for a font foo, you run Metafont as follows:
mf '\mode:=smoke; input foo'
(See the preceding sections for general information on running
Metafont.) In proof or smoke mode, by default Metafont
will display the characters online as it runs (if you are on a terminal
capable of this, e.g., running under X). If you aren't interested in
seeing this online output, you can say `nodisplays;' on the command
line.
In both kinds of proofs, the font is produced at a very high resolution,
typically thousands of pixels per inch, to minimize (or eliminate)
distortion due to rasterization difficulties. To be more precise, the
resolution is chosen so that the designsize of the font fills
proof_size inches; by default, proof_size is 7, which
works well enough for both letter-size and A4 paper.
In order to calculate this, Metafont must also know the resolution of
the final output device. This is called proof_resolution, and is
300 by default.
You can change the values of proof_size and
proof_resolution on the command line; the actual calculation is
done in bzrsetup.mf.
After running Metafont, you will have a GF file, e.g., foo.2602gf. You can then make a DVI file you can preview or print with:
gftodvi foo.2602gf
This creates foo.dvi. In the DVI output from GFtoDVI, each character in the font has its own page. Some additional information is also present, as follows:
In proof mode, the character shapes are printed in a “gray”
font, and the starting and ending points of each spline (or line) in the
character outline are shown. (Thus, you can see if Limn did a good job
choosing those points.) If you set proofing > 2, the
control points for each spline will also be shown. If a point would
otherwise overlap with others on the output, an equation is put off to
the right defining where it appears.
In smoke mode, the character shapes are printed in black; if you
put the output on the wall and stand back, you can get an idea of how
the font is coming along. The character is also shown at its true size
off to the right (assuming you have made the font at the true-size
resolution, of course).
You may find that the extra information to the right of the character
(“overflow equations” in proof mode; the true-size character in
smoke mode) is being lost off the edge of the page. You can
change where GFtoDVI puts this with the `-overflow-label-offset'
option to GFtoDVI.
See the Metafontbook and the GFtoDVI documentation for more details.
The Type 1 font format, invented by Adobe Systems, Inc., is the most common representation for PostScript fonts. Adobe first published its specification in the book Adobe Type 1 Font Format in 1990. It defines a limited set of operations; general PostScript programs cannot be represented as Type 1 fonts. It also defines hints—ways of improving characters' appearances at low resolution and/or small sizes—which cannot be represented in PostScript proper.
BZRto generates a Type 1 font foo.gsf from the input file foo10.bzr (the `10' being the design size of the input) if you specify the `-pstype1' option, as in:
bzrto -pstype1 foo
The file foo.gsf consists only of plain text (it's not really “human-readable”, since Type 1 format requires encryption of the character outlines).
Although Type 1 format also allows for encryption of the entire font, this is not required, and BZRto does not do it. Some deficient PostScript interpreters do not recognize unencrypted fonts; but Ghostscript, the GNU quasi-PostScript interpreter, has no trouble. We do not know of any utilities for encrypting an unencrypted Type 1 font, but presumably such a program would not be hard to write.
Type 3 PostScript fonts are not defined in a singular format, as are Type 1 fonts (see the previous section). Rather, they are general PostScript programs which happen to meet the PostScript language's (liberal) requirements for being a font. They can therefore be used with any PostScript interpreter.
BZRto generates a Type 3 font foo.pf3 from an input BZR file foo.bzr if you specify the `-pstype3' option, as in:
bzrto -pstype3 foo
We do not know of any conventional extension for Type 3 fonts; we made up pf3 to stand for “PostScript font Type 3”.
The most important part of a Type 3 font is the BuildChar
routine, which does the actual rendering from the character program.
Unlike Type 1 fonts, whose BuildChar routine is built into the
PostScript interpreter, each Type 3 font supplies its own
BuildChar routine.
The Type 3 fonts output by BZRto use a BuildChar routine defined
in a separate file bzrbuildch.PS (distributed in the bzr
directory). They use the PostScript run command to read that
file; so if you want to download one to a printer (which naturally will
not have access to the file on your computer), you must replace the
run command with the contents of the file. For PostScript
interpreters which run on a host computer, such as Ghostscript, you have
to install bzrbuildch.PS in a directory where it will be found,
but you need not modify the fonts.
The CCC (composite character construction) language allows you to define new characters in terms of existing ones. This is useful for building such characters as pre-accented A's (from a piece accent and an `A').
A CCC file consists of a sequence of character definitions, each of which looks like:
define name = statements end
where name is a character name, presumably from the encoding file specified with the `-encoding' option (see Invoking BZRto). See Character names, for the details of character names.
We describe the possible statements below.
You may also include comments starting with a `%' character and continuing to the end of the line.
setchar statementsTo use an existing character as part of a new character, you can use
either the setchar or setcharbb statement. They both take
a character name in parentheses as their argument, as in:
setchar ( name )
setcharbb ( name )
See Character names, for the details of character names.
The difference between the two commands lies in their treatment of the
existing character's sidebearings: the setchar command includes
them, and setcharbb does not. setcharbb also removes
any white space above and below the character shapes, as is usually
present in accent characters.
This difference lets you construct characters without worrying about interaction between their side bearings. For example, you could make an `A' with an acute accent centered over the body of the `A' as follows:
define Aacute =
setchar (A)
hmove -.5 width (A)
vmove height (A)
setcharbb (acute)
end
(See the next section for a description of the hmove and
vmove commands.) Without the setcharbb command, this
definition would be complicated by the side bearings on the acute
character.
move statements
To change the current position in a CCC file, you can use the
hmove or vmove command; as you might expect, the former
moves horizontally and the latter vertically.
Both take a single argument: a dimension, which is an optional
real number followed by a unit of measure. The real number is a
multiplying factor. For example, one of the units is pt
(signifying printer's points, as usual), so the command `hmove 3pt'
moves three points to the right (a pretty small distance).
Here are the possible units of measure:
If the character name does not exist, an error is given, and the command ignored.
This section describes the options that BZRto accepts. See Command-line options, for general option syntax.
The root of the main input fontname is called font-name below.
Times-BoldItalic.
The default is unknown.
Times. The default is to use FontName up to the first
`-'.
Bold. If
FontName contains one of the strings `Black', `Book',
`Bold', `Demi', `ExtraBold', `Light', `Heavy',
`Regular', `Semibold', or `Ultra', that is the
weight. Otherwise, BZRto uses `Medium'.
true or false'true.
Otherwise, it's false.
UniqueID. This avoids unlikely-but-possible conflicts
with existing fonts.
All values except FontName and UniqueID go in
the FontInfo dictionary.
This section describes the technical definition of the BZR file format. It is intended for programmers who wish to write other programs which read or write such files. The present distribution includes a subroutine library which can be shared among programs (Limn, BPLtoBZR, and BZRto all use it); new programs can and probably should use the existing library as well. The source code is in the bzr directory.
The BZR file format shares the philosophy of the TeX project file formats (DVI, GF, PK, etc.): machine-independence; compactness; and easy interpretation.
BZR files have three parts: a preamble, character definitions, and a postamble. We describe each below, as well as some general considerations.
This section describes some general conventions of the BZR format.
In the following sections, we use the notation name[n] to mean that some constituent name of the BZR file takes up n bytes. If name is all capital letters, it is an opcode, i.e., a command byte, and therefore we give no [n] after name, since all opcodes are a single byte. The numerical value of each opcode is given in the source file bzr/bzr_opcodes.h.
Some values in BZR files are “pointers”. These values give the location of some other byte in the file. The first byte is numbered 0, the next byte numbered 1, and so on.
Besides commands which actually define the font, the BZR format has a
NO_OP command, which does nothing. Any number of NO_OP's
can occur between the preamble and the character definitions, between
character definitions and commands within characters, between the
character definitions and the postamble, and after the postamble. But
they may not occur within the preamble, the postamble, or between a
command and its parameters.
Besides simple integers, BZR format uses a fixed-point representation of real numbers called a scaled, which is three bytes: two bytes of fraction and one byte of integer. We can get away with such a small range because almost all numbers are scaled by the design size; i.e., in a 10-point font, a designsize-scaled value of 1.0 would represent 10 points (quite a large distance, relatively speaking).
In fact, designsize-scaled numbers are typically less than 1.0, so the BZR format provides for abbreviating such, thus making the font smaller, as detailed in the following sections.
Negative numbers are represented in 2's complement notation, and multibyte values are stored in BigEndian order, regardless of the conventions of the host computer. This makes a BZR font file portable between different architectures.
The preamble of a BZR file has two components, the font's design size
and a comment: designsize[3], k[1],
comment[k].
See BZR format introduction, for general information about BZR files and for the definition of the types used here.
The designsize is a scaled number in printer's points.
The k-byte long comment typically identifies the
source and creation date of the BZR file.
BZR characters consist of an identifying command, metric
information, shape information, and a terminating EOC command.
We describe these parts below.
BZR format provides two ways to start characters: an abbreviated one, which saves space in common cases, and a longer form which (we hope) will always suffice.
The short form looks like this:
BOC_ABBREVcharcode[1]set-width[2]llx[2]lly[2]urx[2]ury[2]
The long form:
BOCcharcode[1]set-width[3]llx[3]lly[3]urx[3]ury[3]
Here is a description of these components:
BOC or BOC_ABBREV opcode byte introduces the character.
charcode defines the character code in question.
set-width defines the set width of the character, given as a
design-size scaled, in printer's points.
llx ... ury (which stand for “lower left x”,
“lower left y”, “upper right x”, and “upper right
y”) define the bounding box for this character. The values are
designsize-scaled, in printer's points. The bounding box is not
guaranteed to be the tightest possible, because it is difficult to
compute the exact path of any splines in the character shape (see BZR character shapes).
As with other formats, the left side bearing is defined by llx,
and the right side bearing by set-width − urx.
See BZR format introduction, for general information about BZR files and for the definition of the types used here.
In the BZR format, a character shape is defined as a sequence of (non-contiguous) closed paths, i.e., outlines. Each path can contain straight lines and Bezier cubic splines. As a BZR-reading program interprets the character definition, it keeps track of a “current point”, which is initially undefined.
Each path—and therefore also the character shape itself—starts with a
path command: PATH, x[3], y[3]. This
finishes off any previous outline and starts a new one, setting the
current point to (x,y). x and y are
designsize-scaled values in printer's points.
After a path command has started an outline, a sequence of zero or more line and/or spline commands, intermixed in any order, follows. (A path command followed by another path command is allowed, but does nothing useful.)
Although the BZR format itself does not require it, for the font to work properly when translated to some other formats, the “outside curves” must be drawn counterclockwise, and the inside ones clockwise.
The BZR format defines both abbreviated and long versions of both straight line and spline commands, as follows.
The abbreviated line command is:
LINE_ABBREVex[2]ey[2]
which defines a straight line from the current point to
(ex,ey). ex and ey are designsize-scaled numbers
in points. After drawing the line, the current point is set to
(ex,ey).
The long form of the line command differs only in starting with a
LINE opcode, and the coordinate parameters being three bytes long,
instead of two.
The spline commands are analogous. Here is the abbreviated form:
SPLINE_ABBREVc1x[2]c1y[2]c2x[2]c2y[2]ex[2]ey[2]
This defines a Bezier spline with initial point the
current point, control points (c1x,c1y) and (c2x,c2y), and
ending point (ex,ey). The current point is then set to
(ex,ey). As with the line commands, the coordinate parameters
are designsize-scaled in units of points.
Also as with the line commands, the long form of the spline command
differs only in starting with a SPLINE opcode and the other
parameters being three bytes long instead of two.
The postamble of a BZR file consists of the following. See BZR format introduction, for general information about BZR files and for the definition of the types used here.
POSTllx[3]lly[3]urx[3]ury[3] character locators (see below)POST_POSTnchars[1]post-ptr[4]id[1] 1 to any number ofNO_OP's
Here is a description of these components:
llx ... ury are all designsize-scaled
numbers. They define the bounding box for the entire font, which is
simply the smallest box that encloses all the characters. See BZR character beginnings.
BOC. There are
two forms of character locators: one abbreviates the common case of the
pointer being less than 65536; the other allows for a full four-byte
pointer value.
More precisely, an abbreviated character locator consists of:
CHAR_LOC_ABBREV charcode[1] pointer[2]
and a long character locator consists of:
CHAR_LOCcharcode[1]pointer[4]
nchars is the number of characters defined in the BZR file.
post-ptr points to the POST byte.
id identifies the version of BZR format; this is currently 75.
This way of ending BZR files makes it straightforward to process a BZR
file from end to beginning, even though it must of course be written
beginning to end. The BZR-reading program can position itself at the
end of the file, skip over the NO_OP bytes at the end to the
id byte, and then read the pointer to the postamble proper, which
provides enough information to read each character individually. This
eliminates the need to read the entire (potentially large) BZR file into
memory before doing any processing.
BPLtoBZR translates a human-readable (and -editable) text file in BPL format (see below) to the binary BZR (Bezier) font format.
Of the two, only BZR files can be changed into font formats which typesetting programs can use. So after editing a BPL file, you need to run this program. BZRedit likewise invokes it when necessary (see BZRedit).
Bezier property list (BPL) files are free-format text files which describe an outline font. They are a transliteration of the binary BZR font format (see BZR files).
A BPL file is a sequence of entries of the form
(property-name value1 value2 ...)
The property-name is one of a small set of keywords understood by BPLtoBZR. The values vary depending on the property being defined. BPL files have four types of values: unsigned integers, reals, strings (enclosed in typewriter double-quote `"' marks), and real strings (realstr for short)—a real number in quotes. See Editing BPL files, for an explanation of why realstrs are necessary.
A semicolon not inside a string constant begins a comment, which continues until the end of the line.
BPL files have three parts: a preamble, character definitions, and a postamble. They must appear in that order. In many cases, the order in which you give the properties within a part is also significant.
The preamble of a BPL file consists of the following three properties:
(fontfile string). This merely documents the filename of
the BZR font from which BZRto made this BPL file. It is ignored.
(fontcomment string). This is an arbitrary string written
as the “comment” in the BZR file. BZR-reading programs ignore this
comment. It typically identifies the source and time of
creation. If string is longer than 255 characters, it is
truncated (due to limitations of the BZR format).
(designsize real). The design size of the font, in
printer's points.
A BPL file must have one or more character definitions. These have the following form:
(char unsigned
width
bounding-box
outline1
outline2
...
)
The unsigned number directly after the char command
specifies the character code. If it is larger than 255 (the maximum
character code in BZR files, and all other font formats the font
utilities deal with) then BPLtoBZR issues a warning and uses its value
modulo 256.
The other pieces are specified as properties:
(width realstr). The set width of the character in
printer's points.
(bb llx lly urx ury). The bounding box
of the character in printer's points, defined by the lower-left x
coordinate and the upper-right y coordinate. Each value is a
realstr. The left side bearing is defined by llx, and the right
side bearing is defined by the difference between the set width and
urx.
Each outline specifies a geometrical outline, i.e., a closed curve. For example, an `o' would have two outlines. If the character is entirely blank, the BPL file has no outlines at all.
The outline property is somewhat more complex than the rest, so we describe it below.
You specify an outline in a BPL file as a sequence of straight lines and cubic splines, in any order:
(outline start-x start-y
piece1 piece2 ...
)
start-x and start-y are realstrs which specify the initial position for drawing this outline. Each successive piece of the outline is relative to a current point, and also updates the current point.
At least one piece must be present. Each piece can be one of the following two properties:
line x y. Draw a straight line from the current
point to (x,y). Then set the current point to (x,y).
x and y are realstrs.
spline c1x c1y c2x c2y ex ey.
Draw the Bezier cubic using the current point as the starting point,
(c1x,c1y) and (c2x,c2y) as the control
points, and (ex,ey) as the endpoint. Then set the
current point to the endpoint. All coordinates are realstrs.
If the last point the last piece of the outline is not the same
as the starting point, the result is undefined.
The final piece of a BPL file is the postamble. It has two components:
(fontbb llx lly urx ury). Defines the
bounding box for the entire font in the same way as the bb
property defines the bounding box for a character. See BPL characters.
(nchars unsigned). The number of characters in the BPL
file. This is purely for informational purposes; BPLtoBZR ignores it.
This section describes the options that BPLtoBZR accepts. See Command-line options, for general option syntax.
XBfe (X Bitmap Font Editor) allows you to hand-edit a bitmap font—both the shapes (i.e., the pixels) and the metric information (set widths, side bearings, and kerning tables).
The input is both a bitmap (GF or PK) font and a corresponding TFM file. If you have only a bitmap font for some reason, you can make a TFM file with Fontconvert (see Fontconvert output options). XBfe outputs (at your command) the edited files in the current directory with the same name, thus possibly replacing the input file.
XBfe is intended to edit existing fonts, not create new ones. For example, it does not provide a way to create new characters in a font. (you can add characters to a font using Fontconvert, though; see Character selection options). In terms of its interaction with the other font utilities, it is most useful for making character shapes more amenable to Limn's outline fitting (see Limn).
XBfe attempts to follow established user interface conventions for X programs:
AsciiText widget, which is Emacs-like bindings.
.../mit/doc/tutorials/resources.txt
in the X distribution if you aren't familiar with X resources. The
class name is XBfe. The font utilities distribution comes with
an application resource file XBfe (which must be installed for
the program to function properly); see that file for possibilities of
what you might change.
The sections below describe the specific operations XBfe provides.
This section describes a few operations which do not directly involve editing, but rather managing of the editing session itself.
To exit XBfe, click on the `Exit' button. Any changes made since the last save are lost.
To save changes, click on the `Save' button. The new files are
written in the current directory—unless that would overwrite the input
files, in which case they are written to the directory /tmp (or
the value of the environment variable TMPDIR, if it's set). When
you exit XBfe normally, the files are moved from the temporary directory
to your current directory, thus possibly overwriting the input.
To go back to the last saved version of a character you are editing, click on the `Revert' button. This is useful when you've made changes you didn't intend. If you exit without saving first, all changes (since the last save) will be lost, as mentioned above.
You can move to the previous character in the font, i.e., the one with the character code next smallest to the current one, by clicking on the `Prev' button. Similarly, you can move to the next character by clicking on the `Next' button. You can move to a specified character by typing its character code in the `Char' item and hitting <RET>. See Specifying character codes, for the various possibilities for character codes.
The most basic operation for editing character bitmaps is to change black pixels to white or the reverse; put another way, inverting the pixel the mouse is on. You do this by clicking the third mouse button.
Technically, this is just a special case of changing more than one pixel: when you press the third button, the current pixel inverts; then, as you move the mouse, the pixels it touches change to the color the first pixel changed to. Thus, if you press the third button on a white pixel, the mouse effectively becomes a “black pen” (until you release the button).
XBfe supports selection, pasting, and filling operations on a rectangle of pixels, as follows.
To select an arbitrary rectangle, press the left mouse button to determine the first corner; then move the mouse (with the button still down) to update the other corner of the rectangle; and release the button to define the rectangle. (If you release the button when the mouse is off the character bitmap, the selection rectangle remains unchanged.)
Once a rectangle has been selected, you can paste it, either within the same character from which it was selected, or in a different character. To do this, press the middle button; this outlines the region that will be changed; as you move the mouse (with the button still down), the outline moves accordingly; when you release the middle button, the selected rectangle is pasted onto the current bitmap, erasing whatever was in the affected area.
Pasting has several variations: if you have the Alt (a.k.a. Meta) key down when you release the middle button, the selection is flipped vertically; if the Control key is down, the selection is flipped horizontally; and if both are down, the selection is flipped in both directions. Here is a minimal example:
original vertical horizontal both ** * ** * * ** * **
This is useful when pasting serifs, since serifs are attached to the main stems in different orientations. (Incidentally, making the serif shapes consist of exactly the same pixels may actually make the serifs look different, because of surrounding character features or the difference in orientation. But it is still a good place to start.)
You can also fill the selected rectangle, i.e., change it to entirely black or white, by holding the <Alt> key down and pressing the right mouse button. The selection is filled with the color of the pixel the mouse is on. This is how you entirely erase a portion of the bitmap.
You can enlarge the bitmap on all four sides by clicking on the `Expand' button; i.e., this adds one blank row at the top and bottom, and one blank column at the left and right. This is useful when you need to fill out a truncated curve, lengthen a stem or serif, etc.
XBfe correspondingly changes the side bearings and baseline position so that the origin of the character does not change. In other words, the new row at the bottom is below the baseline, and the new columns are in what was the side bearing space. You can change the baselines with Fontconvert (see Character manipulation options, and the side bearings with Charspace (see Charspace).
You can change the left side bearing for the current character by typing the new value in the `lsb' item (and hitting <RET>, as always for information you type). Likewise for the right side bearing and the `rsb' item. The side bearing values must be integers.
XBfe shows a box with any kerns for the current character. Each item in the kern box looks like `code: kern', where code is the character code (in decimal) of the character kerned with, and kern is the kern distance (in pixels). You can edit the kern distances just as with the side bearings; the values here are real numbers.
You can add new kerns by typing the character code of the new kerned-with character in the `Add kern' item; then a kern item with that code is added to the kern box, with a distance of zero (which you can then change to whatever you want). Similarly, you can delete a kern by typing the character code in the `Del kern' item.
This section describes the options that XBfe accepts. See Command-line options, for general option syntax.
You can't use `=' here to separate the option name and value.
You can also set this value by setting the resource `expansion' in .Xdefaults.
In addition to the above options, XBfe also accepts the standard X toolkit options (and resources), such as `-display' to specify the X server to use. See the documentation for any X program for a description of these options. Unlike the options above, you cannot use `--' to start X toolkit options, nor can you use `=' to separate option names and values; for example, neither `--display host:0' nor `-display=host:0' are recognized.
BZRedit allows hand-editing of outline fonts in the BZR font format output by Limn (see Limn).
It is written in GNU Emacs Lisp, and thus works only inside GNU Emacs (see Top (GNU Emacs Manual)). It uses Ghostscript to display the character images, and thus you must have Ghostscript installed to use it. See Archives, for information on how to obtain GNU software.
BZRedit provides only a simple form of editing: you change the textual representation of the BZR font in an Emacs buffer; when you wish to see the image corresponding to the particular character you have been editing, you type an explicit command to tell Emacs to send the image in PostScript form to a Ghostscript subprocess.
BZRedit uses BPL format for the “textual representation”. See BPL files, for the precise details on what BPL files contain; however, you will probably find them fairly self-explanatory.
A more featureful editor would allow interactive manipulation of the outlines, say via a mouse in an X window. It would also be useful to allow adding or editing of hints (additional commands which improve rasterization at low resolution and/or small sizes); right now, none of the programs do anything at all about hints.
The sections below detail using BZRedit.
BZRedit is contained in the file bzrto/bzredit.el. Installation of the font utilities (see Installation) copies this file into a directory where Emacs can find it. But you still need to tell Emacs what functions bzredit.el defines. To do this, put the following definitions into either your own .emacs file (see The Init File: .emacs (GNU Emacs Lisp Manual)), if you are the only person planning to use BZRedit, or into the system initialization file default.el (see Summary: Sequence of Actions at Start Up (GNU Emacs Lisp Manual)), for a public installation:
(autoload 'bpl-mode "bzredit" "Mode for editing BPL files." t)
(autoload 'bzredit "bzredit" "Set up to editing a BZR file." t)
If you want the first function to be called automatically when you visit a file with extension .bpl, you can add the following code to (presumably) the same file:
(setq auto-mode-alist
(append auto-mode-alist (list '("\\.bpl\\'" . bpl-mode))))
If you do not do this, then to make the editing commands (described in the following sections) available you must type M-x bpl-mode after visiting a BPL file.
To edit a BZR file, type M-x bzredit to Emacs. (See the previous section for how to make this function known to Emacs.) This will ask you for the filename of the BZR font. After typing the filename, type RET.
The bzredit function then calls BZRto with the `-text'
option (see BZRto) to produce a BPL file—the textual form of the
BZR font. Then it calls bpl-mode and makes the resulting buffer
visible (if it isn't already).
The next section describes bpl-mode.
To edit a BPL file in bpl-mode, the usual Emacs editing commands
work: cursor motion, deletion, and insertion all work just as with
normal text files.
Here is an example of a piece of a BPL file. See BPL files, for a full description of BPL files.
(char 0 ; hex 0x0
(width "6.263")
(bb "0.241" "5.782" "-0.241" "6.745")
(outline "0.482" "6.745"
(line "1.445" "6.504")
(line "1.445" "0.241")
(line "0.482" "0.241")
(line "3.613" "0.000")
(spline "1.682" "1.264" "2.409" "4.436" "2.409" "6.504")
...
)
)
The most usual editing session is changing the numbers in the
line and spline commands, which are the coordinates that
determine the character outline. But you can do anything you want:
change a line to spline (and add the requisite other
coordinates) or vice versa, change the set width, etc.
You must retain the quotation marks around the floating-point numbers, however. (They are necessary because Emacs 18 does not recognize floating-point constants.) If you inadvertently delete one, then when you go to display the edited character (see below), you will get an error from Emacs.
When bpl-mode is first invoked, it starts up Ghostscript in a
subprocess. The section below describes the details of this. It is
Ghostscript which does the actual displaying.
bpl-mode provides three additional commands (we show the default
bindings in parentheses):
bpl-quit (C-c q and C-c C-q), which kills the
Ghostscript subprocess and then removes the BPL buffer from the screen.
bpl-quit does not convert the BPL file (back) to BZR form; that's
left for you to do by hand.
bpl-erasepage (C-c e and C-c C-e), which sends an
erasepage command to Ghostscript, thus erasing whatever is
currently displayed.
bpl-show-char (C-c c and C-c C-c), which sends to
Ghostscript a PostScript translation of the character that point is in.
bpl-mode calls bpl-mode-hook as its last action. You can
define this to take additional actions if you like.
As mentioned above, BZRedit uses Ghostscript, the GNU PostScript interpreter, to display the character images. See Archives, for how to obtain Ghostscript.
BZRedit assumes that Ghostscript's default output device is the correct one to use—presumably a window on an X display. The actual default depends on how Ghostscript was installed.
The following variables control various attributes of the Ghostscript output:
The resolution at which Ghostscript renders images, in pixels per inch. Default is 300.
GSrenderfont uses Ghostscript to rasterize a PostScript outline font at a particular point size and resolution. The final result is a bitmap font in PK form, which can be used by any DVI-processing program, unlike the original PostScript font. In particular, you can then use your favorite previewer with TeX documents which use PostScript fonts.
An alternative to using such PK fonts is to use a DVI-to-PostScript translator and then use Ghostscript or Ghostview directly on the result. The PostScript file consumes quite a bit of disk space, however; also, the extra step after running TeX can be quite inconvenient.
An alternative to using GSrenderfont is the standalone C program
ps2pk. It does the same job: rasterizing PostScript fonts. It
is available by ftp from `ftp.urc.tue.nl'.
Besides Ghostscript, GSrenderfont uses gawk (GNU Awk), the
standard Unix utilities tail and wc, the standard TeX
utility gftopk, another programs from this distribution
(Imageto), and one small program written expressly for it,
bbcount. Since this last is of doubtful value for anything but
GSrenderfont, it is not documented here. See gsrenderfont/main.c
if you are interested in what it does.
GSrenderfont has nothing in particular to do with the main task of creating typefaces, but it seemed a small enough job (given the other programs' existence) and widely enough asked for to be worthwhile.
GSrenderfont needs several bits of information to do its job, as described in the sections below.
GSrenderfont needs two names to do its job: the PostScript font name (e.g., `Times-Roman'), and the output filename (e.g., ptmr). (The PostScript font name cannot also be used as the filename because of its length. At best, the result would be unwieldy, and at worst, invalid because of operating system restrictions.) If the font is not known to Ghostscript (i.e., in its Fontmap file), then an input filename is also needed.
You can explicitly specify the first with the `-font' option, the second with the `-output-file' option, and the third with a non-option argument. If you specify them all, as in
gsrenderfont -font=Myfont -out=test myfont.ps
then GSrenderfont simply uses what you've given.
But if you specify only the font name or the input filename, GSrenderfont tries to guess the other using a mapping file. On each line of this file the first (whitespace-delimited) word is the filename (possibly preceded by an `r'; see Introduction (Filenames for fonts), for why), the second word is the PostScript font name, and any remaining stuff is ignored. Unlike the other data files, GSrenderfont does not use path searching to find this file; it just uses the default:
/usr/local/lib/tex/dvips/psfonts.map
unless you specify a different file with the `-map' option. The reason for this is that psfonts.map should contain all the PostScript fonts in use at your site.
GSrenderfont complains and gives up if you specify neither the PostScript font name nor the input filename. It also gives up if it can't determine the filename from the PostScript name or vice versa.
The default for the output filename is the input filename.
For convenience, GSrenderfont allows you to independently specify the point size and the resolution of the output font: the `-point-size' option, as an integer in points, and the latter with `-dpi' in pixels per inch. The defaults are 10pt and 300dpi.
Because PostScript fonts are (in practice) linearly scaled, however, GSrenderfont does not put the point size in the output filename. Instead, it simply computes the final resolution as the `dpi' multiplied by the `point-size' divided by 10. This assumes that the default size of the fonts as used in TeX is 10pt, which is true for the PostScript fonts distributed with Dvips.
For example, supposing the output filename is ptmr, and you specify `-point-size=12', the bitmap font will be named ptmr.360pk.
You specify the encoding for the new bitmap font with the `-encoding' option; the default is to use the encoding of the input font. GSrenderfont reads the same encoding files as the other programs. See Encoding files.
As with all other data files in the other programs, GSrenderfont
searches for the encoding file using the path specified by the
environment variable FONTUTIL_LIB if it is set; otherwise it uses
the default path set during compilation. See Font searching, for the
details of the path searching algorithm.
This section describes the options that GSrenderfont accepts. See Command-line options, for general option syntax.
You must specify either `-font' or a single non-option argument, so GSrenderfont knows what font to work on. See the previous section for more details.
/usr/local/lib/tex/dvips/psfonts.map
Like all software, the font utilities can all be (probably endlessly) improved. Following are some possible projects.
If you would like to contribute, send mail to `bug-gnu-utils@prep.ai.mit.edu' first, so we can coordinate the work.
The original purpose of these programs was to create fonts for Ghostscript, the GNU PostScript-compatible interpreter written by Peter Deutsch. Adobe and many other vendors sell fonts which Ghostscript can use, but they place many restrictions on the use of those fonts. These restrictions certainly include modification and copying; in some cases, they even include using the font on more than one printer or display! These restrictions are contrary to the aims of the GNU project.
Obviously we cannot compete in volume with Adobe, Bitstream, or other vendors, all of whom probably have dozens if not hundreds of people working on nothing but font production, and additional people hired as programmers in support. The present authors (both working half-time) are the entire FSF “font production” department, both for design and for programming.
Fortunately, we do not need to compete in volume (certainly we haven't needed the thousands of Adobe fonts in our practice as typographers). Our aim is to produce the basic typefaces for typography: Garamond, Bodoni, Gill Sans, Univers, Baskerville, and perhaps a few others. If someone wants some other typeface, they could use our programs to make it, and, we hope, contribute it back to GNU for others to use.
We do need volunteers to help create fonts for the GNU project. You do
not need to be an expert type designer to help, but you do need to know
enough about TeX and/or PostScript to be able to install and test new
fonts. Example: if you know neither (1) the purpose of TeX utility
program gftopk nor (2) what the PostScript scalefont
command does, you probably need more experience before you can help.
If you can volunteer, the first step is to compile the font utilities (see Installation). After that, contact us at `karl@gnu.ai.mit.edu'. I will get you a scanned type specimen image. See Creating fonts, for how to use these utilities to turn that into a font you can use in TeX or PostScript.
Here are some possible projects:
FontInfo information.
pnmrotate, which mentions that article, in the PBMplus
distribution could perhaps be adapted.
libstring_to_bitmap (in font.c) which
understands kerns and ligatures.
In addition, one general enhancement would be to allow more than 256 characters per font. The bitmap formats allow this already, and the TFM format has some support for it.
Two other smaller general improvements: combine multiple `-range' options; allow for omitting ranges.
We didn't worry about making the programs work with any C compiler; instead, we used GNU C extensions where they were useful. Likewise for GNU make.
We allowed ourselves this luxury because these programs are not historical utilities which people would expect to find on any Unix system. Rather, they are application programs. Perhaps having them work only with other GNU programs will encourage people to switch to GNU programs, or at least become aware of them.
It probably would not be too hard to change the programs to work with other ANSI C compilers. Changing them to work with old C compilers would be more painful. Thus far, the dependency on GCC hasn't proved a serious problem, because GCC runs on so many machines.
It would be dull but straightforward to write Makefiles for the programs which didn't use any of GNU make's special features. As with GCC, though, GNU make is so widely available that we haven't felt it necessary to do so.
The one exception is to this are the dozen or so files in the lib and include directories which implement the path searching algorithm. Because these files are shared with the TeX, Dvips, and XDvi distributions, they are written to work with old C compilers.
See Archives, for information on how to obtain GCC and the other programs mentioned. See Portability as it applies to GNU (GNU Coding Standards), for more discussion of the portability of GNU programs in general.
This section describes some of the conventions we used in the organization of the source code. See Top (GNU Coding Standards), for the general GNU conventions.
In our sources, .c files include config.h first, which in turn includes global.h, which includes types.h and other header files which define ubiquitous identifiers.
.h files, on the other hand, do not include config.h. They only include whatever headers are needed to define what they themselves use—typically including but not limited to types.h.
All .h files are protected with #ifndef unique-symbol.
The upshot of these conventions is that headers can be included in any order, as many times as necessary. In a .c file, only those headers which define symbols needed in the C source need be included, without worrying that some headers depend on others. (ANSI C defines its headers to follow these same rules.)
Virtually all .c files—the only exceptions are (sometimes)
main.c and some library files—have a corresponding .h
file, which defines all the public symbols (e.g., non-static
routines and types). in the .h file are intended to explain the
external interface; comments in the .c file assume you already
know what's in the .h file, to avoid having the same information
in two places, and try to explain only implementation details.
Therefore, a .c file should always include its corresponding .h file, to ensure consistency between the definitions and the declarations. GCC 2's `-Wmissing-prototypes' option can be used to check this.
The main program is always in a file named main.c. Typically it
loops through all the characters in the input font, doing something with
them. Parsing arguments is also done in main.c, in a function
named read_command_line, using getopt. See Command-line options, for more information on option parsing.
The configure script used to determine system dependencies is generated by GNU Autoconf from configure.in. When configure runs, it creates include/c-auto.h from include/c-auto.h.in to record what it discovers. config.h includes this file.
We access members of most structure types via macros instead of with
. or -> directly. We pass and return whole structures
without hesitation; this has not resulted in any noticeable performance
loss. When we use pointers to structures, it's almost always because we
need a distinguishable value (i.e., NULL).
When a function has no side effects (e.g., assignments to global
variables), and does not examine any values except its arguments (e.g.
if a pointer is passed, it does not examine the data pointed to),
we declare it const. (This is a GNU C extension.)
Copyright © 1989, 1991 Free Software Foundation, Inc.
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software—to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too.
When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.
We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.
Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and modification follow.
Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does.
You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.
These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program.
In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.
The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.
If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code.
If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.
This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.
Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and “any later version”, you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation.
If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found.
one line to give the program's name and a brief idea of what it does.
Copyright (C) yyyy name of author
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; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items—whatever suits your program.
You should also get your employer (if you work as a programmer) or your school, if any, to sign a “copyright disclaimer” for the program, if necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
signature of Ty Coon, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License.
+ in Imageto verbose output: Invoking Imageto-align-threshold: Invoking Limn-align-threshold: Aligning endpoints-baseline-adjust: Character manipulation options-baselines: Invoking Imageto-baselines: Image to font conversion-baselines and blotches: Dirty images-ccc-file: Invoking BZRto-cmi-files: Invoking Charspace-column-split: Character selection options-concat: Invoking BZRto-concat: Character selection options-corner-always-threshold: Invoking Limn-corner-always-threshold: Finding corners-corner-surround: Invoking Limn-corner-surround: Finding corners-corner-threshold: Invoking Limn-corner-threshold: Finding corners-designsize: Fontwide information options-designsize: Invoking Imageto-designsize: Image to font conversion-display: Invoking XBfe-display: Displaying fitting online-display-continue: Invoking Limn-display-continue: Displaying fitting online-display-grid-size: Invoking Limn-display-grid-size: Displaying fitting online-display-pixel-size: Invoking Limn-display-pixel-size: Displaying fitting online-display-rectangle-size: Invoking Limn-display-rectangle-size: Displaying fitting online-do-display: Invoking Limn-dpi: Invoking GSrenderfont-dpi: GSrenderfont output size-dpi: Invoking XBfe-dpi: Invoking Limn-dpi: Invoking Charspace-dpi: Miscellaneous options-dpi: Invoking Imageto-dpi: Common options-encoding: Invoking GSrenderfont-encoding: Invoking BZRto-encoding: Invoking Charspace-encoding: Miscellaneous options-encoding: Invoking Imageto-epsf: Fontconvert output options-epsf: Invoking Imageto-epsf: Viewing an image-error-threshold: Invoking Limn-expansion: Invoking XBfe-filter-alternative-surround: Invoking Limn-filter-alternative-surround: Filtering curves-filter-epsilon: Invoking Limn-filter-epsilon: Filtering curves-filter-iterations: Invoking Limn-filter-iterations: Filtering curves-filter-passes: Character manipulation options-filter-percent: Invoking Limn-filter-percent: Filtering curves-filter-size: Character manipulation options-filter-surround: Invoking Limn-filter-surround: Filtering curves-filter-threshold: Character manipulation options-flip: Invoking IMGrotate-font: Invoking GSrenderfont-font: GSrenderfont font names-fontdimens: Invoking Charspace-fontdimens: Fontwide information options-gf: Fontconvert output options-help: Invoking GSrenderfont-help: Invoking XBfe-help: Invoking BPLtoBZR-help: Invoking BZRto-help: Invoking Limn-help: Invoking Charspace-help: Miscellaneous options-help: Invoking IMGrotate-help: Invoking Imageto-help: Common options-ifi-file: Invoking Imageto-initial-char: Invoking XBfe-input-format: Invoking Imageto-keep-knees: Invoking Limn-line-reversion-threshold: Invoking Limn-line-threshold: Invoking Limn-line-threshold: Changing splines to lines-log: Invoking Limn-log: Common options-map: Invoking GSrenderfont-map: GSrenderfont font names-metafont: Invoking BZRto-metafont: Metafont and BZRto-mf: Invoking BZRto-nchars: Invoking Imageto-no-gf: Invoking Charspace-oblique-angle: Invoking BZRto-omit: Character selection options-output-file: Invoking GSrenderfont-output-file: GSrenderfont font names-output-file: Invoking XBfe-output-file: Invoking BPLtoBZR-output-file: Invoking BZRto-output-file: Invoking Limn-output-file: Invoking Charspace-output-file: Miscellaneous options-output-file: Invoking IMGrotate-output-file: Invoking Imageto-output-file: Common options-overflow-label-offset: Proofing with Metafont-point-size: Invoking GSrenderfont-point-size: GSrenderfont output size-print-clean-info: Invoking Imageto-print-clean-info example: Dirty images-print-guidelines: Invoking Imageto-print-guidelines: Image to font conversion-print-guidelines example: Image to font conversion-ps-font-info: Invoking BZRto-pstype1: Invoking BZRto-pstype1: Type 1 and BZRto-pstype3: Invoking BZRto-pstype3: Type 3 and BZRto-random: Character manipulation options-random-threshold: Character manipulation options-range: Invoking BPLtoBZR-range: Invoking BZRto-range: Invoking Limn-range: Invoking Charspace-range: Character selection options-range: Invoking Imageto-range: Common options-remap: Character selection options-reparameterize-improve: Invoking Limn-reparameterize-improve: Reparameterization-reparameterize-threshold: Invoking Limn-reparameterize-threshold: Reparameterization-rotate-clockwise: Invoking IMGrotate-rotate-clockwise: Clockwise rotation-static: Problems-strips: Invoking Imageto-strips: Viewing an image-subdivide-search: Invoking Limn-subdivide-search: Subdivision-subdivide-surround: Invoking Limn-subdivide-surround: Subdivision-subdivide-threshold: Invoking Limn-subdivide-threshold: Subdivision-tangent-surround: Invoking Limn-tangent-surround: Finding tangents-text: Invoking BZRto-text: Fontconvert output options-tfm: Fontconvert output options-tfm-header: Fontwide information options-trace-scanlines: Invoking Imageto-verbose: Invoking GSrenderfont-verbose: Invoking BPLtoBZR-verbose: Invoking BZRto-verbose: Invoking Limn-verbose: Invoking Charspace-verbose: Miscellaneous options-verbose: Invoking IMGrotate-verbose: Invoking Imageto-verbose: Common options-version: Invoking GSrenderfont-version: Invoking XBfe-version: Invoking BPLtoBZR-version: Invoking BZRto-version: Invoking Limn-version: Invoking Charspace-version: Miscellaneous options-version: Invoking IMGrotate-version: Invoking Imageto-version: Common options-Wmissing-prototypes: Implementation-xheight-char: Invoking Charspace. in Imageto verbose output: Invoking Imageto.emacs: BZRedit installation.enc suffix: Encoding files.notdef: Character names.notdef, removing blotches with: Dirty images.Xdefaults: Invoking XBfe.Xdefaults: XBfe usage.Xdefaults: Displaying fitting online/bin/ld: Problems/tmp: Controlling XBfe/usr/local/lib/tex/dvips/psfonts.map: GSrenderfont font names\magnification: Metafont output at any size\spacefactor: TFM fontdimens\strutbox: TFM fontdimensAacute character, constructing: CCC setcharAsciiText widget: XBfe usageawk: GSrenderfontaxisheight fontdimen: TFM fontdimensbb BPL property: BPL charactersbbcount: GSrenderfontbbheight CCC dimension: CCC movebbwidth CCC dimension: CCC movebdftops: File format abbreviationsbigopspacing1 fontdimen: TFM fontdimensbigopspacing2 fontdimen: TFM fontdimensbigopspacing3 fontdimen: TFM fontdimensbigopspacing4 fontdimen: TFM fontdimensbigopspacing5 fontdimen: TFM fontdimensBitmap.c: ProblemsBOC: BZR character beginningsBOC_ABBREV: BZR character beginningsbpl-erasepage: Editing BPL filesbpl-mode: Editing BPL filesbpl-mode-hook: Editing BPL filesbpl-quit: Editing BPL filesbpl-show-char: Editing BPL filesbpltobzr: BPLtoBZRBuildChar in Type 3 fonts: Type 3 and BZRtobyron.u.washington.edu: Archivesbzr source directory: BZR filesbzr-gs-dpi: BZRedit and Ghostscriptbzr-gs-height: BZRedit and Ghostscriptbzr-gs-width: BZRedit and Ghostscriptbzr_opcodes.h: BZR format introductionbzrbuildch.PS: Type 3 and BZRtobzredit: Editing BZR filesbzredit: BZReditbzredit.el: BZRedit installationbzrsetup.mf, computing proof values: Proofing with Metafontbzrto: BZRtoC-c c: Editing BPL filesC-c C-C: Editing BPL filesC-c C-e: Editing BPL filesC-c C-q: Editing BPL filesC-c e: Editing BPL filesC-c q: Editing BPL filescapheight CCC dimension: CCC movechar BPL property: BPL characterschar CMI command: char commandchar-width CMI command: char-width commandchar.c: CMI processingCHAR_LOC opcode in BZR files: BZR postambleCHAR_LOC_ABBREV opcode in BZR files: BZR postamblechar-width command: char-width commandcharcode.c: Specifying character codescharspace: Charspacecharspec.c: Specifying character codescmi.y: CMI processingcodingscheme CMI command: codingscheme commandcomment BPL property: BPL filescommon.cmi: Invoking Charspacecommon.cmi: TFM fontdimenscommon.cmi: Charspace usagecommon.cmi, numerals in: char-width commandconfigure, creation of: Implementationdefault.el: BZRedit installationdefaultrulethickness fontdimen: TFM fontdimensdefine CMI command: define commanddelim1 fontdimen: TFM fontdimensdelim2 fontdimen: TFM fontdimensdenom1 fontdimen: TFM fontdimensdenom2 fontdimen: TFM fontdimensdepth CCC dimension: CCC movedesignsize and proofing: Proofing with Metafontdesignsize BPL property: BPL preambledesignsize CCC dimension: CCC movedesignsize Metafont parameter: Metafont output at any sizedesignsize predefined for CMI files: CMI processingDISPLAY environment variable: Displaying fitting onlineDISTRIB: Archivesdlclose: Problemsdlopen: Problemsdlsym: Problemsdvips: Archivesedge.c: Finding pixel outlinesem CCC dimension: CCC moveem TeX dimension: TFM fontdimensencoding.map: codingscheme commandencoding.map: Coding scheme map fileEOC opcode in BZR files: BZR characterserasepage: Editing BPL filesex TeX dimension: TFM fontdimensexpansion resource: Invoking XBfeexport.lcs.mit.edu: Archivesextraspace fontdimen: TFM fontdimensFamilyName in PostScript fonts: Invoking BZRtofit.c: Limn algorithmfmod, wrong prototype for: Problemsfont.c: Program featuresfontbb BPL property: BPL postamblefontcomment BPL property: BPL preamblefontconvert: Fontconvertfontdepth CCC dimension: CCC movefontdimen CMI command: fontdimen commandfontfile BPL property: BPL preambleFontInfo: Program featuresFontInfo: Invoking BZRtoFontmap: GSrenderfont font namesFontName in PostScript fonts: Invoking BZRtofontname.texi: Archivesfontsize fontdimen: TFM fontdimensFONTUTIL_LIB environment variable: File formatsftp.cs.umb.edu: Archivesftp.th-darmstadt.de: Archivesconst: Implementationgatekeeper.dec.com: Archivesgawk: GSrenderfontgawk prerequisite to GSrenderfont: Prereqsgcc: Prereqsgeometry resource: Displaying fitting onlinegetopt_long_only: Command-line optionsGFFONTS environment variable: Font searchinggftodvi: Proofing with Metafontgftopk: GSrenderfontgftopk: File format abbreviationsgftopk: Prereqsgftype, checking validity font: Bug criteriaggmr.1200cmi: CMI filesggmr.ifi: Font creation exampleghostview: GSrenderfontgnulatin.enc: GNU encodingsGNUmakefile, editing: Installationgs: Viewing an imagegs: Prereqsgsrenderfont: GSrenderfontgsrenderfont/main.c: GSrenderfontheight CCC dimension: CCC movebpl-mode: Editing BPL filesics.uci.edu: Archivesimageto: Imagetoimageto/main.c: Problemsimgrotate: IMGrotateinclude/c-auto.h, creation of: Implementationinclude/c-auto.h, editing: InstallationIntrinsicP.h: ProblemsisFixedPitch in PostScript fonts: Invoking BZRtoisspace: CMI tokensisspace: Common file syntaxItalicAngle in PostScript fonts: Invoking BZRtokern CMI command: kern commandlabrea.stanford.edu: Archivesleadingdepth fontdimen: TFM fontdimensleadingheight fontdimen: TFM fontdimensbpl-mode: Editing BPL fileschar command: char commandchar-width command: char-width commandlimn: LimnLimn resource file: Problemsline BPL property: BPL outlinesLINE opcode in BZR files: BZR character shapesLINE_ABBREV opcode in BZR files: BZR character shapeslocalfont Metafont mode: Metafont and BZRto