Advanced Search
Apple Developer Connection
Member Login Log In | Not a Member? Contact ADC

 
 
 
 
 
 
 


 
 
 
 
 
 
 
 
 

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 );

}