TypeWriter
User Documentation
Version 1.1
Introduction
TypeWriter is a font tool for generating font information
from a binary font in a human readable format (dumping) . The generated
output can be viewed, changed and then used to rewrite the font table (fusing).
The current version is a prototype or technology
demonstration. It is not supposed to be a finished product and has therefore
limited capabilities and various shortcomings.
User Guide
The two main menus in TypeWriter are the "Dump
Font" and "Fuse Font" in the "File" menu. Both commands open a window containing
three panels. All messages regarding dumping and fusing like error messages
or success messages will be displayed in the top panel. Only one of the
two lower panels are visible at one time. They can be accessed through
the controls above the display which is are named "Preview" and "Table"
respectively. The table panel displays and lets you create and change the
table definition files. Table definition files are text files whose contents
are a sequence of statements (basically a program) which can be interpreted
by TypeWriter. The data types and the syntax are described in the following
sections. At the end of this document you can find a few examples of table
definitions. It comes with a set of table definitions for font tables that
can be found in most font files. The other panel will contain the output
of a dump action, the textual representation of the font table as described
by the table definition file.

To be able to dump a font table, the user must
select a font file and a table definition file by pressing the respective
buttons at the bottom of the window. Only then will the "Dump" button be
enabled. To be able to fuse a font table a dump file must be selected as
well as a font file and a table definition file. By pressing the third
button on the bottom left a dialog appears that lets you select a dump
file.
By pressing the "Dump" or "Fuse" button, the dump
or fuse will start respectively. The progress of the current action can
be viewed in a floating progress window. The action will either stop when
an error is encountered in the table definition or dump file, the user
cancelled the action by pressing the "Cancel" button or when the action
succeeds.

If an error occurs while processing a font
(for example an unknown variable in a table definition file) an error message
will be displayed in the message panel and the processing of the font will
be stopped.
The user will be asked to save any changes made
to either the table definition, the dump or the font when closing the window
or quitting the application. He can also explicitly save any change by
selecting the "Save", "Save As" or the "Save Font" menu items respectively.
Depending on the current open visible panel either the table definition
or the textual representation of the font will be saved be the "Save"/"Save
As" commands.
As mentioned above, the progress of the dump or
fuse process is visible in the progress window which can be made visible
or can be hidden by selecting the "Show Progress" or "Hide Progress" menus
respectively.

The "Preferences" dialog (an item in the "Edit"
menu) lets you change the comment characters that will precede the comments
in the dump files. It also lets you change the priority of the dump/fuse
process. By giving a higher priority to the application the dump/fuse process
can be speeded up significantly but will negatively affect the response
time to user action.
Data Types
This section describes the data types currently
recognised by TypeWriter. Some of them are directly representing the data
types used in TrueType font files (described in the TrueType reference
manual).
The following is a list of available data types:
| UInt8 |
unsigned integer (1 byte) |
| UInt16 |
unsigned integer (2 bytes) |
| UInt32 |
unsigned integer (4 bytes) |
| SInt8 |
signed integer (1 byte) |
| SInt16 |
signed integer (2 bytes) |
| SInt32 |
signed integer (4 bytes) |
| Fixed |
16.16-bit signed fixed-point number (4 bytes) |
| FlagByte |
binary flags (1 byte - 8 flags) |
| FlagByte2 |
binary flags (2 bytes - 16 flags) |
| FlagByte4 |
binary flags (4 bytes - 32 flags) |
| Byte |
byte (8 bits) |
| Byte2 |
word (16 bits) |
| Byte4 |
long (32 bits) |
| Hex |
hexadecimal number (1 byte) |
| Hex2 |
hexadecimal number (2 bytes) |
| Hex4 |
hexadecimal number (4 bytes) |
| Str255 |
string (255 bytes) |
| FourCharCode |
four byte code |
| LongDateTime |
international date/time representing a date in
seconds since 24:00h, 1.1.1904 (8 bytes) |
Keywords
This section explains the keywords that TypeWriter
recognises (in addition to the above mentioned data types).
| If |
Conditional branch |
| EndIf |
End of conditional branch block |
| DoWhile |
Loop |
| EndDo |
End of loop block |
| GoTo |
Jump to label |
| Stop |
Terminate program execution |
| Rem/// |
Comment for table definition file (no output written
to dump file) |
| Comment |
Comment for dump file (will be written to dump
file) |
| BlankLine |
Writes an empty line to the dump |
| WriteLine |
Write a string to the dump file. Only one variable
can be detected in the string. A ëcarriage returní will be added to the
string. |
| WriteString |
Write a string to the dump file. Only one variable
can be detected in the string. No CR will be added to the string. |
| WriteChar |
Write a character to the dump file. The argument
can be either decimal number or a UInt8/Byte variable. |
| Flush |
Flush the write buffer (writes CR) |
| ReadIn |
Read data from table (the amount is described
by the size of the variable).
Note: the table position will be advanced by the
size of the variable. |
| ReadInSize |
Read data from the table (the amount is described
by the second argument).
Note: the table position will be advanced by the
second argument. |
| ReadInOffset |
Read data from table (the amount is described
by the size of the variable the offset from the current table position
with the second argument).
Note: the table position will not be advanced. |
| ReadInSizeOffset |
Read data from table (the amount is described
by the second argument the offset from the current table position with
the third argument).
Note: the table position will not be advanced. |
| Rewind |
Reset the current table positionto the beginning
of the table. |
| RewindBy |
Rewind the current table position by the amount
specified in argument. |
| ForwardBy |
Move current table position forward |
| GetTablePosition |
Get the current table position |
| SetTablePosition |
Set the current table position |
| GetFontTableSize |
Retrieves the size of a particular table (the
second argument specifies the table name) |
| FontName |
Retrieves the font name |
| NumOfGlyphsInFont |
Retrieves the number of glyphs in a font |
| UnitsPerEm |
Retrieves the units per em |
| IndexToLocFormat |
Reads the ëIndexToLocFormatí field of the ëheadí
table (for loca tables) |
| NumOfLongHorMetrics |
Reads the ëNumOfLongHorMetricsí field of the ëhheaí
table (for ëhtmxí tables) |
Simplified Specification
DoWhile <Condition>
EndDo <>
If <Condition>
EndIf <>
Note: <Condition> ::= <Variable>
<Operator> <Variable/Literal>
GoTo <Label>
Rem <String>
// <String>
Version <Fixed Literal>
Comment <String Mixed Constants and
Variable>
BlankLine <>
DumpTable <String>
WriteLine <String Mixed Constants
and Variable>
WriteString <String Mixed Constants
and Variable>
WriteChar <Number Variable/Literal>
Flush <>
ReadIn <Variable>
ReadInSize <Variable> <ByteCount>
ReadInOffset <Offset> <Variable>
<ByteCount>
ReadInSizeOffset <Offset> <Variable>
<ByteCount>
GetTablePosition <Number Variable>
SetTablePosition <Number Variable/Literal>
Rewind <>
RewindBy <Number Variable/Literal>
ForwardBy <Number Variable/Literal>
FontName <String Variable>
UnitsPerEm <Variable>
GetFontTableSize <Variable>
IndexToLocFormat <Variable>
NumOfLongHorMetrics <Variable>
NumOfGlyphsInFont <Variable>
Assignment/Arithematic Operators
<Variable> = <Variable/Literal>
Note: No Expressions
<Variable> += <Variable/Literal>
<Variable> -= <Variable/Literal>
<Variable> *= <Variable/Literal>
<Variable> /= <Variable/Literal>
<Variable> %= <Variable/Literal>
<Variable> &= <Variable/Literal>
<Variable> |= <Variable/Literal>
Conditional Operators
<Variable> == <Variable/Literal>
<Variable> != <Variable/Literal>
<Variable> >= <Variable/Literal>
<Variable> <= <Variable/Literal>
<Variable> > <Variable/Literal>
<Variable> < <Variable/Literal>
Header
Each table definition file must have a header.
The torso of a table definition looks like this:
TypeWriterTemplate
Table table name
Version version number
Type Dump/Fuse/DumpFuse
{
...table definition...
}
Each table definition file must have a header.
The header is also used to recognise a table definition when trying to
open a file.
In addition, each dump file automatically receives
a header in form of a comment. It is also used to recognise the file type.
An example of a dump file header is the following line:
// TypeWriterDump (this line is automatically
created - do not edit or remove)
Examples
Below are three examples of table definitions including
a "head" table definition, a "post" table definition and a "loca" table
definition. They show the use of most of the standard data types and controls
that TypeWriter supports at the moment.
Keywords in the examples are shown in bold while
variable names are shown in italic.
Example 1: ëheadí table definition
The first example is a head table definition. It
is straight-forward and doesnít need any complex statements. First, all
the information is read from the head table and then simply written out.
Rem head definition file
Rem Copyright: © 1998-1999
by Apple Computer, Inc., all rights reserved.
TypeWriterTemplate
Table head
Version 1.0
Type DumpFuse
{
Fixed version;
Fixed fontRevision;
UInt32 checkSumAdjust;
UInt32 magicNumber;
FlagByte2 flags;
UInt16 unitsPerEm;
LongDateTime created;
LongDateTime modified;
SInt16 xMin;
SInt16 yMin;
SInt16 xMax;
SInt16 yMax;
UInt16 macStyle;
UInt16 lowestRecPPEM;
SInt16 fontDirectionHint;
SInt16 indexToLocFormat;
SInt16 glyphDataFormat;
Str255 fntName;
Rewind ();
Rem get the font name
FontName( fntName
);
Rem start collecting the head
table information
ReadIn ( version );
ReadIn ( fontRevision
);
ReadIn ( checkSumAdjust
);
ReadIn ( magicNumber);
ReadIn ( flags);
ReadIn ( unitsPerEm
);
ReadIn ( created );
ReadIn ( modified
);
ReadIn ( xMin );
ReadIn ( yMin );
ReadIn ( xMax );
ReadIn ( yMax );
ReadIn ( macStyle
);
ReadIn ( lowestRecPPEM
);
ReadIn ( fontDirectionHint
);
ReadIn ( indexToLocFormat
);
ReadIn ( glyphDataFormat
);
Rewind ();
Rem start writing out the
head table information
Comment ( Dump of head table,
'$fntName' );
BlankLine ();
WriteLine ( head version:
$version );
WriteLine ( head fontRevision:
$fontRevision );
WriteLine ( head checkSumAdjust:
$checkSumAdjust );
WriteLine ( head magicNumber:
$magicNumber);
WriteLine ( head flags: $flags);
WriteLine ( head unitsPerEm:
$unitsPerEm );
WriteLine ( head created:
$created );
WriteLine ( head modified:
$modified );
WriteLine ( head xMin: $xMin
);
WriteLine ( head yMin: $yMin
);
WriteLine ( head xMax: $xMax
);
WriteLine ( head yMax: $yMax
);
WriteLine ( head macStyle:
$macStyle );
WriteLine ( head lowestRecPPEM:
$lowestRecPPEM );
WriteLine ( head fontDirectionHint:
$fontDirectionHint );
WriteLine ( head indexToLocFormat:
$indexToLocFormat );
WriteLine ( head glyphDataFormat:
$glyphDataFormat );
BlankLine ();
Comment ( End of dump of
head table, '$myName' );
}
Example 2: ëlocaí table definition
The next example shows a loca table definition.
A loca table is more complex than a head table and itís table definition
needs control statements.
Rem actual loca def file
Rem Copyright: © 1998-1999
by Apple Computer, Inc., all rights reserved.
TypeWriterTemplate
Table loca
Version 1.0
Type DumpFuse
{
UInt16 locaIndex;
UInt16 numOfGlyphs;
UInt16 shortOffset;
UInt32 longOffset;
UInt16 glyphIndex;
Str255 fntName;
Rewind ();
Rem the next two calls are
built-in TyepWriter functions
Rem we need version information
from the head table
IndexToLocFormat ( locaIndex
);
Rem the number of glyphs must
be stored in the maxp table
NumOfGlyphsInFont ( numOfGlyphs
);
FontName ( fntName
);
Comment ( Dump of loca table,
$fntName );
BlankLine ();
Comment ( IndexToLocFormat
from the head table is: $locaIndex );
BlankLine ();
glyphIndex = 0;
If locaIndex == 0
DoWhile glyphIndex
< numOfGlyphs
ReadIn ( shortOffset
);
WriteLine ( Glyph Index :
$glyphIndex, Offset : $shortOffset );
glyphIndex += 1;
EndDo
EndIf
If locaIndex == 1
DoWhile glyphIndex
< numOfGlyphs
ReadIn ( longOffset
);
WriteLine ( Glyph Index :
$glyphIndex, Offset : $longOffset );
glyphIndex += 1;
EndDo
EndIf
BlankLine ();
Comment ( End of dump of
loca table, '$fntName' );
}
Example 3: ëpostí table definition
The last example shows a post table definition.
It is uses various control statements and is an example of a more complex
table definition.
// post table def file
// Copyright: © 1998-1999
by Apple Computer, Inc., all rights reserved.
TypeWriterTemplate
Table post
Version 1.0
Type Dump
{
// post table header
Str255 sfntName;
Fixed version;
Fixed italicAngle;
SInt16 underlinePos;
SInt16 underlineThick;
UInt16 isFixedPitch;
UInt16 reserved1;
UInt32 minMemType42;
UInt32 maxMemType42;
UInt32 minMemType1;
UInt32 maxMemType1;
// common variables
UInt16 index;
UInt16 tempIndex;
UInt16 numOfGlyphs;
UInt32 tablePos;
UInt32 oldTablePos;
// post 2 subtable
UInt16 numOfNewGlyphs;
UInt16 glyphNameIndex;
UInt8 nameLen;
Str255 name;
// post 2.5 subtable
SInt8 offSet;
Rewind ();
FontName (
sfntName );
Comment ( Start of post table
dump, $sfntName );
BlankLine ();
ReadIn (
version );
ReadIn ( italicAngle );
ReadIn (
underlinePos
);
ReadIn (
underlineThick
);
ReadIn (
isFixedPitch
);
ReadIn (
reserved1 );
ReadIn (
minMemType42
);
ReadIn (
maxMemType42
);
ReadIn (
minMemType1 );
ReadIn (
maxMemType1 );
WriteLine ( Format Version:
$version );
WriteLine ( Italic Angle:
$italicAngle );
WriteLine ( Underline Position:
$underlinePos );
WriteLine ( Underline Thickness:
$underlineThick );
WriteLine ( Fixed Pitch/Monospaced:
$isFixedPitch );
WriteLine ( Reserved: $reserved1);
WriteLine ( Type 42 Min Memory
Usage: $minMemType42 );
WriteLine ( Type 42 Max Memory
Usage: $maxMemType42 );
WriteLine ( Type 1 Min Memory
Usage: $minMemType1 );
WriteLine ( Type 1 Min Memory
Usage: $maxMemType1 );
BlankLine ();
If version ==
1.0
Comment ( Note: 'post'
format 1.0 has no subtable );
EndIf
If version ==
2.0
Comment ( post format
2.0 );
GetTablePosition (
oldTablePos
);
ReadIn (
numOfGlyphs
);
WriteLine ( Number of Glyphs:
$numOfGlyphs );
index = 0;
DoWhile index <
numOfGlyphs
ReadIn ( glyphNameIndex
);
If glyphNameIndex ==
0
WriteLine ( Index:
$index, Glyph Name Index: $glyphNameIndex, Not Defined) ;
EndIf
If glyphNameIndex
> 0
If glyphNameIndex
< 258
WriteLine ( Index:
$index, Glyph Name Index: $glyphNameIndex, Standard Macintosh
Name );
EndIf
EndIf
If glyphNameIndex
>= 258
If glyphNameIndex
<= 32767
tablePos = oldTablePos;
// numberOfGlyphs + array,
all 2 byte
tablePos += 2;
tablePos += numOfGlyphs;
tablePos += numOfGlyphs;
numOfNewGlyphs = glyphNameIndex;
numOfNewGlyphs -= 258;
tempIndex = 0;
DoWhile tempIndex
<= numOfNewGlyphs
ReadInOffset ( nameLen,
tablePos
);
tablePos += 1;
ReadInSizeOffset ( name,
nameLen,
tablePos
);
tablePos += nameLen;
tempIndex += 1;
EndDo
WriteLine ( Index: $index,
Glyph Name Index: $glyphNameIndex, $nameLen, $name );
EndIf
EndIf
If glyphNameIndex >
32767
WriteLine ( Index:
$index, Glyph Name Index: $glyphNameIndex, Reserved );
EndIf
index += 1;
EndDo
EndIf
If version == 2.5
Comment ( post format
2.5 );
ReadIn ( numOfGlyphs
);
WriteLine ( Number of Glyphs:
$numOfGlyphs );
index = 0;
DoWhile index <
numOfGlyphs
ReadIn ( offSet
);
WriteLine ( Index: $index,
Offset to Standard: $offSet );
index += 1;
EndDo
EndIf
If version == 3.0
Comment ( Note: 'post'
format 3.0 has no subtable );
EndIf
If version == 4.0
Comment ( post format
4.0 );
NumOfGlyphsInFont ( numOfGlyphs
);
WriteLine ( Number of Glyphs:
$numOfGlyphs );
index = 0;
DoWhile index <
numOfGlyphs
ReadIn ( tempIndex
);
WriteLine ( Index: $index,
Character Code: $tempIndex );
EndDo
EndIf
BlankLine ();
Comment ( End of post table
dump, $sfntName );
}
|