home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: SysTools
/
SysTools.zip
/
ft-beta.zip
/
freetype
/
lib
/
ttload.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-10-06
|
30KB
|
1,169 lines
/*******************************************************************
*
* ttload.c 1.0
*
* TrueType Tables Loader.
*
* Copyright 1996, 1997 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used
* modified and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*
******************************************************************/
#include "tttypes.h"
#include "tterror.h"
#include "ttcalc.h"
#include "ttfile.h"
#include "tttables.h"
#include "ttobjs.h"
#include "ttmemory.h"
#include "tttags.h"
#include "ttload.h"
/* In all functions, the stream is taken from the 'face' object */
#define DEFINE_LOCALS DEFINE_LOAD_LOCALS(face->stream)
#define DEFINE_LOCALS_WO_FRAME DEFINE_LOAD_LOCALS_WO_FRAME(face->stream)
/*******************************************************************
*
* Function : LookUp_TrueType_Table
*
* Description : Looks for a TrueType table by name.
*
* Input : face face table to look for
* tag searched tag
*
* Output : index of table if found, -1 otherwise.
*
******************************************************************/
Int LookUp_TrueType_Table( PFace face,
Long tag )
{
Int i;
for ( i = 0; i < face->numTables; i++ )
if ( face->dirTables[i].Tag == tag )
return i;
return -1;
}
/*******************************************************************
*
* Function : Load_TrueType_Collection
*
* Description : Loads the TTC table directory into face table.
*
* Input : face face record to look for
*
* Output : error code.
*
******************************************************************/
static TT_Error Load_TrueType_Collection( PFace face )
{
DEFINE_LOCALS;
Int n;
if ( FILE_Seek ( 0L ) ||
ACCESS_Frame( 12L ) )
return error;
face->ttcHeader.Tag = GET_Tag4();
face->ttcHeader.version = GET_Long();
face->ttcHeader.DirCount = GET_Long();
FORGET_Frame();
if ( face->ttcHeader.Tag != TTAG_ttcf )
{
face->ttcHeader.Tag = 0;
face->ttcHeader.version = 0;
face->ttcHeader.DirCount = 0;
face->ttcHeader.TableDirectory = NULL;
return TT_Err_File_Is_Not_Collection;
}
if ( ALLOC_ARRAY( face->ttcHeader.TableDirectory,
face->ttcHeader.DirCount,
ULong ) ||
ACCESS_Frame( face->ttcHeader.DirCount * 4L ) )
return error;
for ( n = 0; n < face->ttcHeader.DirCount; n++ )
face->ttcHeader.TableDirectory[n] = GET_ULong();
FORGET_Frame();
return TT_Err_Ok;
}
/*******************************************************************
*
* Function : Load_TrueType_Directory
*
* Description : Loads the table directory into face table.
*
* Input : face face record to look for
*
* faceIndex the index of the TrueType font, when
* we're opening a collection.
*
* Output : SUCCESS on success. FAILURE on error.
*
******************************************************************/
TT_Error Load_TrueType_Directory( PFace face, int faceIndex )
{
DEFINE_LOCALS;
Int n, limit;
TTableDir tableDir;
DebugTrace(( "Directory " ));
error = Load_TrueType_Collection( face );
if ( error )
{
if ( error != TT_Err_File_Is_Not_Collection )
return error;
/* the file isn't a collection, exit if we're asking */
/* for a collected font */
if ( faceIndex != 0 )
return error;
/* Now skip to the beginning of the file */
if ( FILE_Seek( 0 ) )
return error;
}
else
{
/* The file is a collection. Check the font index */
if ( faceIndex < 0 || faceIndex >= face->ttcHeader.DirCount )
return TT_Err_Bad_Argument;
/* select a TrueType font in the ttc file */
if ( FILE_Seek( face->ttcHeader.TableDirectory[faceIndex] ) )
return error;
}
if ( ACCESS_Frame( 12L ) )
return error;
tableDir.version = GET_Long();
tableDir.numTables = GET_UShort();
tableDir.searchRange = GET_UShort();
tableDir.entrySelector = GET_UShort();
tableDir.rangeShift = GET_UShort();
DebugTrace(( "Tables number : %12u\n", tableDir.numTables ));
FORGET_Frame();
/* Check that we have a 'sfnt' format there */
if ( tableDir.version != 0x00010000 )
return TT_Err_Invalid_File_Format;
face->numTables = tableDir.numTables;
if ( ALLOC_ARRAY( face->dirTables,
face->numTables,
TTableDirEntry ) )
return error;
if ( ACCESS_Frame( face->numTables*16L ) )
return error;
limit = face->numTables;
for ( n = 0; n < limit; n++ )
{ /* loop through the tables and get all entries */
face->dirTables[n].Tag = GET_Tag4();
face->dirTables[n].CheckSum = GET_ULong();
face->dirTables[n].Offset = GET_Long();
face->dirTables[n].Length = GET_Long();
}
FORGET_Frame();
DebugTrace(( "loaded\n" ));
return TT_Err_Ok;
}
/*******************************************************************
*
* Function : Load_TrueType_MaxProfile
*
* Description : Loads the maxp table into face table.
*
* Input : face face table to look for
*
* Output : error code
*
******************************************************************/
TT_Error Load_TrueType_MaxProfile( PFace face )
{
DEFINE_LOCALS;
Int i;
PMaxProfile maxProfile = &face->maxProfile;
DebugTrace(( "MaxProfile " ));
if ( ( i = LookUp_TrueType_Table( face, TTAG_maxp ) ) < 0 )
return TT_Err_Table_Missing;
if ( FILE_Seek( face->dirTables[i].Offset ) ) /* seek to maxprofile */
return error;
if ( ACCESS_Frame( 32L ) ) /* read into frame */
return error;
/* read frame data into face table */
maxProfile->version = GET_ULong();
maxProfile->numGlyphs = GET_UShort();
maxProfile->maxPoints = GET_UShort();
maxProfile->maxContours = GET_UShort();
maxProfile->maxCompositePoints = GET_UShort();
maxProfile->maxCompositeContours = GET_UShort();
maxProfile->maxZones = GET_UShort();
maxProfile->maxTwilightPoints = GET_UShort();
maxProfile->maxStorage = GET_UShort();
maxProfile->maxFunctionDefs = GET_UShort();
maxProfile->maxInstructionDefs = GET_UShort();
maxProfile->maxStackElements = GET_UShort();
maxProfile->maxSizeOfInstructions = GET_UShort();
maxProfile->maxComponentElements = GET_UShort();
maxProfile->maxComponentDepth = GET_UShort();
FORGET_Frame();
face->numGlyphs = maxProfile->numGlyphs;
face->maxPoints = MAX( maxProfile->maxCompositePoints,
maxProfile->maxPoints );
face->maxContours = MAX( maxProfile->maxCompositeContours,
maxProfile->maxContours );
face->maxComponents = maxProfile->maxComponentElements +
maxProfile->maxComponentDepth;
DebugTrace(( "loaded\n" ));
return TT_Err_Ok;
}
/*******************************************************************
*
* Function : Load_TrueType_Gasp
*
* Description : Load the TrueType Gasp table into the face
* table.
*
* Input : face face table to look for
*
* Output : error code
*
******************************************************************/
TT_Error Load_TrueType_Gasp( PFace face )
{
DEFINE_LOCALS;
Int i;
TGasp* gas;
GaspRange* gaspranges;
DebugTrace(( "Gasp " ));
if ( ( i = LookUp_TrueType_Table( face, TTAG_gasp ) ) < 0 )
return TT_Err_Ok; /* gasp table is not required */
if ( FILE_Seek( face->dirTables[i].Offset ) ||
ACCESS_Frame( 4L ) )
return error;
gas = &face->gasp;
gas->version = GET_UShort();
gas->numRanges = GET_UShort();
FORGET_Frame();
DebugTrace(( "numRanges=%d\n" ,gas->numRanges ));
if ( ALLOC_ARRAY( gaspranges, gas->numRanges, GaspRange ) ||
ACCESS_Frame( gas->numRanges * 4L ) )
goto Fail;
face->gasp.gaspRanges = gaspranges;
for ( i = 0; i < gas->numRanges; i++ )
{
gaspranges[i].maxPPEM = GET_UShort();
gaspranges[i].gaspFlag = GET_UShort();
DebugTrace(( "%d %d\n",
gaspranges[i].maxPPEM, gaspranges[i].gaspFlag ));
}
FORGET_Frame();
return TT_Err_Ok;
Fail:
FREE( gaspranges );
gas->numRanges = 0;
return error;
}
/*******************************************************************
*
* Function : Load_TrueType_Header
*
* Description : Load the TrueType header table into the face
* table.
*
* Input : face face table to look for
*
* Output : error code
*
******************************************************************/
TT_Error Load_TrueType_Header( PFace face )
{
DEFINE_LOCALS;
Int i;
TT_Header* header;
DebugTrace(( "Header " ));
if ( ( i = LookUp_TrueType_Table( face, TTAG_head ) ) < 0 )
return TT_Err_Table_Missing;
if ( FILE_Seek( face->dirTables[i].Offset ) ||
ACCESS_Frame( 54L ) )
return error;
header = &face->fontHeader;
header->Table_Version = GET_ULong();
header->Font_Revision = GET_ULong();
header->CheckSum_Adjust = GET_Long();
header->Magic_Number = GET_Long();
header->Flags = GET_UShort();
header->Units_Per_EM = GET_UShort();
header->Created [0] = GET_Long();
header->Created [1] = GET_Long();
header->Modified[0] = GET_Long();
header->Modified[1] = GET_Long();
header->xMin = GET_Short();
header->yMin = GET_Short();
header->xMax = GET_Short();
header->yMax = GET_Short();
header->Mac_Style = GET_UShort();
header->Lowest_Rec_PPEM = GET_UShort();
header->Font_Direction = GET_Short();
header->Index_To_Loc_Format = GET_Short();
header->Glyph_Data_Format = GET_Short();
DebugTrace(( "loaded\n" ));
DebugTrace(( "Units per EM : %12u\n",
face->fontHeader.Units_Per_EM ));
DebugTrace(( "IndexToLocFormat : %12d\n",
face->fontHeader.Index_To_Loc_Format ));
FORGET_Frame();
return TT_Err_Ok;
}
/*******************************************************************
*
* Function : Load_TrueType_Horizontal_Header
*
* Description : Loads the hhea table into face table.
*
* Input : face face table to look for
*
* Output : error code
*
******************************************************************/
TT_Error Load_TrueType_Horizontal_Header( PFace face )
{
DEFINE_LOCALS;
Int i;
TT_Horizontal_Header* hheader;
DebugTrace(( "Horizontal header " ));
if ( ( i = LookUp_TrueType_Table( face, TTAG_hhea ) ) < 0 )
return TT_Err_Table_Missing;
if ( FILE_Seek( face->dirTables[i].Offset ) ||
ACCESS_Frame( 36L ) )
return error;
hheader = &face->horizontalHeader;
hheader->Version = GET_ULong();
hheader->Ascender = GET_Short();
hheader->Descender = GET_Short();
hheader->Line_Gap = GET_Short();
hheader->advance_Width_Max = GET_UShort();
hheader->min_Left_Side_Bearing = GET_Short();
hheader->min_Right_Side_Bearing = GET_Short();
hheader->xMax_Extent = GET_Short();
hheader->caret_Slope_Rise = GET_Short();
hheader->caret_Slope_Run = GET_Short();
hheader->Reserved[0] = GET_Short();
hheader->Reserved[1] = GET_Short();
hheader->Reserved[2] = GET_Short();
hheader->Reserved[3] = GET_Short();
hheader->Reserved[4] = GET_Short();
hheader->metric_Data_Format = GET_Short();
hheader->number_Of_HMetrics = GET_UShort();
FORGET_Frame();
DebugTrace(( "loaded\n" ));
return TT_Err_Ok;
}
/*******************************************************************
*
* Function : Load_TrueType_Locations
*
* Description : Loads the location table into face table.
*
* Input : face face table to look for
*
* Output : error code
*
* NOTES :
*
* The Font Header *must* be loaded in the leading segment
* calling this function.
*
******************************************************************/
TT_Error Load_TrueType_Locations( PFace face )
{
DEFINE_LOCALS;
Int n, limit, LongOffsets;
DebugTrace(( "Locations " ));
LongOffsets = face->fontHeader.Index_To_Loc_Format;
if ( ( n = LookUp_TrueType_Table( face, TTAG_loca ) ) < 0 )
return TT_Err_Table_Missing;
if ( FILE_Seek( face->dirTables[n].Offset ) )
return error;
if ( LongOffsets != 0 )
{
face->numLocations =
(unsigned long)face->dirTables[n].Length >> 2;
DebugTrace(( "( 32 bits offsets ) : %12d ",
face->numLocations ));
if ( ALLOC_ARRAY( face->glyphLocations,
face->numLocations,
Long ) )
return error;
if ( ACCESS_Frame( face->numLocations * 4L ) )
return error;
limit = face->numLocations;
for ( n = 0; n < limit; n++ )
face->glyphLocations[n] = GET_Long();
FORGET_Frame();
}
else
{
face->numLocations =
(unsigned long)face->dirTables[n].Length >> 1;
DebugTrace(( "( 16 bits offsets ) : %12d ",
face->numLocations ));
if ( ALLOC_ARRAY( face->glyphLocations,
face->numLocations,
Long ) )
return error;
if ( ACCESS_Frame( face->numLocations * 2L ) )
return error;
limit = face->numLocations;
for ( n = 0; n < limit; n++ )
face->glyphLocations[n] =
(Long)((unsigned long)GET_UShort() * 2);
FORGET_Frame();
}
DebugTrace(( "loaded\n" ));
return TT_Err_Ok;
}
/*******************************************************************
*
* Function : Load_TrueType_Names
*
* Description : Loads the name table into face table.
*
* Input : face face table to look for
*
* Output : error code
*
******************************************************************/
TT_Error Load_TrueType_Names( PFace face )
{
DEFINE_LOCALS;
int i, bytes, n;
PByte storage;
TName_Table* names;
TNameRec* namerec;
DebugTrace(( "Names " ));
if ( (n = LookUp_TrueType_Table(face, TTAG_name) ) < 0 )
{
/* The name table is required so indicate failure. */
DebugTrace(( "is missing!\n" ));
return TT_Err_Table_Missing;
}
/* Seek to the beginning of the table and check the frame access. */
/* The names table has a 6 byte header. */
if ( FILE_Seek( face->dirTables[n].Offset ) ||
ACCESS_Frame( 6L ) )
return error;
names = &face->nameTable;
/* Load the initial names data. */
names->format = GET_UShort();
names->numNameRecords = GET_UShort();
names->storageOffset = GET_UShort();
FORGET_Frame();
/* Allocate the array of name records. */
if ( ALLOC_ARRAY( names->names,
names->numNameRecords,
TNameRec ) ||
ACCESS_Frame( names->numNameRecords * 12L ) )
{
names->numNameRecords = 0;
goto Fail;
}
/* Load the name records and determine how much storage is needed */
/* to hold the strings themselves. */
for ( i = bytes = 0; i < names->numNameRecords; i++ )
{
namerec = names->names + i;
namerec->platformID = GET_UShort();
namerec->encodingID = GET_UShort();
namerec->languageID = GET_UShort();
namerec->nameID = GET_UShort();
namerec->stringLength = GET_UShort();
namerec->stringOffset = GET_UShort();
/* check the ids */
if ( namerec->platformID <= 3 )
bytes += namerec->stringLength;
}
FORGET_Frame();
/* Allocate storage for the strings if they exist. */
names->storage = NULL;
if ( bytes > 0 )
{
if ( ALLOC( storage, bytes ) ||
FILE_Read_At( face->dirTables[n].Offset +
names->storageOffset,
(void*)storage,
bytes ) )
goto Fail_Storage;
names->storage = storage;
/* Go through and assign the string pointers to the name records. */
for ( i = 0; i < names->numNameRecords; i++ )
{
namerec = names->names + i;
if ( namerec->platformID <= 3)
namerec->string = storage + names->names[i].stringOffset;
else
{
namerec->string = NULL;
namerec->stringLength = 0;
}
}
}
#ifdef DEBUG
for ( i = 0; i < names->numNameRecords; i++ )
{
int j;
DebugTrace(( "%d %d %x %d ",
names->names[i].platformID,
names->names[i].encodingID,
names->names[i].languageID,
names->names[i].nameID ));
/* I know, that M$ encoded strings are unicode, */
/* but this works reasonable well for debugging purposes. */
for ( j = 0; j < names->names[i].stringLength; j++ )
{
if (names->names[i].string)
{
char c = *(names->names[i].string + j);
if ( (unsigned char)c < 128 )
DebugTrace(( "%c", c ));
}
}
DebugTrace(( "\n" ));
}
#endif
DebugTrace(( "loaded\n" ));
return TT_Err_Ok;
Fail_Storage :
FREE( storage );
Fail :
Free_TrueType_Names( face );
return error;
}
TT_Error Free_TrueType_Names( PFace face )
{
TName_Table* names = &face->nameTable;
/* free strings table */
FREE( names->names );
/* free strings storage */
FREE( names->storage );
names->numNameRecords = 0;
names->format = 0;
names->storageOffset = 0;
return TT_Err_Ok;
}
/*******************************************************************
*
* Function : Load_TrueType_CVT
*
* Description : Loads cvt table into resdent table.
*
* Input : face face table to look for
*
* Output : error code
*
******************************************************************/
TT_Error Load_TrueType_CVT( PFace face )
{
DEFINE_LOCALS;
long n;
Int limit;
DebugTrace(( "CVT " ));
if ( ( n = LookUp_TrueType_Table( face, TTAG_cvt ) ) < 0 )
{
DebugTrace(( "is missing!\n" ));
face->cvtSize = 0;
face->cvt = NULL;
return TT_Err_Ok;
}
face->cvtSize = face->dirTables[n].Length / 2;
if ( ALLOC_ARRAY( face->cvt,
face->cvtSize,
Short ) )
return error;
if ( FILE_Seek( face->dirTables[n].Offset ) ||
ACCESS_Frame( face->cvtSize * 2 ) )
return error;
limit = face->cvtSize;
for ( n = 0; n < limit; n++ )
face->cvt[n] = GET_Short();
FORGET_Frame();
DebugTrace(( "loaded\n" ));
return TT_Err_Ok;
}
/*******************************************************************
*
* Function : Load_TrueType_CMap
*
* Description : Loads the cmap directory in memory
* The cmaps themselves are loaded in ttcmap.c
*
* Input : face
*
* Output : error code
*
******************************************************************/
TT_Error Load_TrueType_CMap( PFace face )
{
DEFINE_LOCALS;
long off, table_start;
int n, limit;
TCMapDir cmap_dir;
TCMapDirEntry entry_;
PCMapTable cmap;
DebugTrace(( "CMaps " ));
if ( ( n = LookUp_TrueType_Table( face, TTAG_cmap ) ) < 0 )
return TT_Err_Table_Missing;
table_start = face->dirTables[n].Offset;
if ( ( FILE_Seek( table_start ) ) ||
( ACCESS_Frame ( 4L ) ) ) /* 4 bytes cmap header */
return error;
cmap_dir.tableVersionNumber = GET_UShort();
cmap_dir.numCMaps = GET_UShort();
FORGET_Frame();
off = FILE_Pos(); /* save offset to cmapdir[] which follows */
/* save space in face table for cmap tables */
if ( ALLOC_ARRAY( face->cMaps,
cmap_dir.numCMaps,
TCMapTable ) )
return error;
face->numCMaps = cmap_dir.numCMaps;
limit = face->numCMaps;
cmap = face->cMaps;
for ( n = 0; n < limit; n++ )
{
if ( FILE_Seek( off ) ||
ACCESS_Frame( 8L ) )
return error;
/* extra code using entry_ for platxxx could be cleaned up later */
cmap->loaded = FALSE;
cmap->platformID = entry_.platformID = GET_UShort();
cmap->platformEncodingID = entry_.platformEncodingID = GET_UShort();
entry_.offset = GET_Long();
FORGET_Frame();
off = FILE_Pos();
if ( FILE_Seek( table_start + entry_.offset ) ||
ACCESS_Frame( 6L ) )
return error;
cmap->format = GET_UShort();
cmap->length = GET_UShort();
cmap->version = GET_UShort();
FORGET_Frame();
cmap->offset = FILE_Pos();
cmap++;
}
DebugTrace(( "loaded\n" ));
return TT_Err_Ok;
}
/*******************************************************************
*
* Function : Load_TrueType_HMTX
*
* Description : Load the horizontal metrics table into face
* table.
*
* Input : face
*
* Output : error code
*
******************************************************************/
TT_Error Load_TrueType_HMTX( PFace face )
{
DEFINE_LOCALS;
Long n, nsmetrics, nhmetrics;
PTableHorMetrics plhm;
DebugTrace(( "HMTX " ));
if ( ( n = LookUp_TrueType_Table( face, TTAG_hmtx ) ) < 0 )
return TT_Err_Table_Missing;
nhmetrics = face->horizontalHeader.number_Of_HMetrics;
nsmetrics = face->maxProfile.numGlyphs - nhmetrics;
if ( nsmetrics < 0 ) /* sanity check */
{
DebugTrace(( "more hmetrics than glyphs!\n" ));
return TT_Err_Invalid_Horiz_Metrics;
}
if ( ALLOC_ARRAY( face->longHMetrics,
nhmetrics,
TLongHorMetric ) )
return error;
if ( ALLOC_ARRAY( face->shortMetrics,
nsmetrics,
Long ) )
return error;
if ( FILE_Seek( face->dirTables[n].Offset ) ||
ACCESS_Frame( face->dirTables[n].Length ) )
return error;
for ( n = 0; n < nhmetrics; n++ )
{
plhm = face->longHMetrics + n;
plhm->advance_Width = GET_Short();
plhm->lsb = GET_Short();
}
for ( n = 0; n < nsmetrics; n++ )
face->shortMetrics[n] = GET_Short();
FORGET_Frame();
DebugTrace(( "loaded\n" ));
return TT_Err_Ok;
}
/*******************************************************************
*
* Function : Load_TrueType_Programs
*
* Description : Load the font (fpgm) and cvt programs into the
* face table.
*
* Input : face
*
* Output : error code
*
******************************************************************/
TT_Error Load_TrueType_Programs( PFace face )
{
DEFINE_LOCALS_WO_FRAME;
int n;
DebugTrace(( "Font program " ));
/* The font program is optional */
if ( ( n = LookUp_TrueType_Table( face, TTAG_fpgm ) ) < 0 )
{
face->fontProgram = NULL;
face->fontPgmSize = 0;
DebugTrace(( "is missing!\n" ));
}
else
{
face->fontPgmSize = face->dirTables[n].Length;
if ( ALLOC( face->fontProgram,
face->fontPgmSize ) ||
FILE_Read_At( face->dirTables[n].Offset,
(void*)face->fontProgram,
face->fontPgmSize ) )
return error;
DebugTrace(( "loaded, %12d bytes\n", face->fontPgmSize ));
}
DebugTrace(( "Prep program " ));
if ( ( n = LookUp_TrueType_Table( face, TTAG_prep ) ) < 0 )
{
face->cvtProgram = NULL;
face->cvtPgmSize = 0;
DebugTrace(( "is missing!\n" ));
}
else
{
face->cvtPgmSize = face->dirTables[n].Length;
if ( ALLOC( face->cvtProgram,
face->cvtPgmSize ) ||
FILE_Read_At( face->dirTables[n].Offset,
(void*)face->cvtProgram,
face->cvtPgmSize ) )
return error;
DebugTrace(( "loaded, %12d bytes\n", face->cvtPgmSize ));
}
return TT_Err_Ok;
}
/*******************************************************************
*
* Function : Load_TrueType_OS2
*
* Description : Load the OS2 Table
*
* Input : face
*
* Output : error code
*
******************************************************************/
TT_Error Load_TrueType_OS2( PFace face )
{
DEFINE_LOCALS;
Int i;
TT_OS2* os2;
DebugTrace(( "OS/2 Table " ));
if ( (i = LookUp_TrueType_Table( face, TTAG_OS2 )) < 0 )
{
DebugTrace(( "is missing !!" ));
return TT_Err_Table_Missing;
}
if ( FILE_Seek( face->dirTables[i].Offset ) ||
ACCESS_Frame( 78L ) )
return error;
os2 = &face->os2;
os2->version = GET_UShort();
os2->xAvgCharWidth = GET_Short();
os2->usWeightClass = GET_UShort();
os2->usWidthClass = GET_UShort();
os2->fsType = GET_Short();
os2->ySubscriptXSize = GET_Short();
os2->ySubscriptYSize = GET_Short();
os2->ySubscriptXOffset = GET_Short();
os2->ySubscriptYOffset = GET_Short();
os2->ySuperscriptXSize = GET_Short();
os2->ySuperscriptYSize = GET_Short();
os2->ySuperscriptXOffset = GET_Short();
os2->ySuperscriptYOffset = GET_Short();
os2->yStrikeoutSize = GET_Short();
os2->yStrikeoutPosition = GET_Short();
os2->sFamilyClass = GET_Short();
for ( i = 0; i < 10; i++ )
os2->panose[i] = GET_Byte();
os2->ulUnicodeRange1 = GET_ULong();
os2->ulUnicodeRange2 = GET_ULong();
os2->ulUnicodeRange3 = GET_ULong();
os2->ulUnicodeRange4 = GET_ULong();
for ( i = 0; i < 4; i++ )
os2->achVendID[i] = GET_Byte();
os2->fsSelection = GET_UShort();
os2->usFirstCharIndex = GET_UShort();
os2->usLastCharIndex = GET_UShort();
os2->sTypoAscender = GET_UShort();
os2->sTypoDescender = GET_UShort();
os2->sTypoLineGap = GET_UShort();
os2->usWinAscent = GET_UShort();
os2->usWinDescent = GET_UShort();
FORGET_Frame();
if (os2->version >= 0x0001)
{
/* only version 1 tables */
if ( ACCESS_Frame( 8L ) ) /* read into frame */
return error;
os2->ulCodePageRange1 = GET_ULong();
os2->ulCodePageRange2 = GET_ULong();
FORGET_Frame();
}
else
{
os2->ulCodePageRange1 = 0;
os2->ulCodePageRange2 = 0;
}
DebugTrace(( "loaded\n" ));
return TT_Err_Ok;
}
/*******************************************************************
*
* Function : Load_TrueType_PostScript
*
* Description : Loads the post table into resident table.
*
* Input : resident resident table to look for
*
* Output : SUCCESS on success. FAILURE on error.
*
******************************************************************/
TT_Error Load_TrueType_PostScript( PFace face )
{
DEFINE_LOCALS;
Int i;
TT_Postscript* post = &face->postscript;
DebugTrace(( "PostScript " ));
if ( ( i = LookUp_TrueType_Table( face, TTAG_post ) ) < 0 )
return TT_Err_Table_Missing;
if ( FILE_Seek( face->dirTables[i].Offset ) ||
ACCESS_Frame( 32L ) )
return error;
/* read frame data into resident table */
post->FormatType = GET_ULong();
post->italicAngle = GET_ULong();
post->underlinePosition = GET_Short();
post->underlineThickness = GET_Short();
post->isFixedPitch = GET_ULong();
post->minMemType42 = GET_ULong();
post->maxMemType42 = GET_ULong();
post->minMemType1 = GET_ULong();
post->maxMemType1 = GET_ULong();
FORGET_Frame();
/* we don't load the glyph names, we'd rather do that in a */
/* library extension */
DebugTrace(( "loaded\n" ));
return TT_Err_Ok;
}
/* End */