2000-06-05 07:26:15 +02:00
|
|
|
/***************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* sfobjs.c */
|
|
|
|
/* */
|
|
|
|
/* SFNT object management (base). */
|
|
|
|
/* */
|
|
|
|
/* Copyright 1996-2000 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. */
|
|
|
|
/* */
|
|
|
|
/***************************************************************************/
|
|
|
|
|
|
|
|
|
A complete revision of FreeType 2's GNU makefiles (of the library):
Tons of unnecessary stuff have been removed; only the essential rules
have been retained.
The source files now depend on all header files in include/freetype,
include/freetype/config, and include/freetype/internal. This is not
optimal, I know, and I'll try to improve this, but it is better than
before (namely no dependencies on `internal').
FTDEBUG_SRC has been added (similar to FTSYS_SRC) -- I don't know
exactly whether this is really useful, but it doesn't harm.
There is now more documentation in the makefiles itself.
io-frames.html: Use of <th>, <code>, and <var> for better tagging.
Reactivating of FT_DEBUG_LEVEL_xxx macros.
Added a lot of #include directives to make `multi' builds possible -- note
that currently the modules cid, t1, and t1z have clashing structures and
functions which means that you can only use one of these three modules for a
multi build.
Added some missing function declarations to (local) header files.
Renamed some T1_Open_Face() to CID_Open_Face() in the cid module -- a lot
of other functions should be renamed also...
Replaced many FT_xxx stuff with T1_xxx in t1z driver -- this isn't finished
yet...
Fixed FT_Free() to allow a NULL pointer without an assertion (this has
always been a valid assumption in FreeType, at least in FT 1.x).
A lot of other, minor fixes (mostly documentation).
2000-06-11 05:46:57 +02:00
|
|
|
#include <freetype/internal/ftobjs.h>
|
2000-05-28 19:15:37 +02:00
|
|
|
#include <freetype/internal/sfnt.h>
|
|
|
|
#include <freetype/internal/psnames.h>
|
|
|
|
#include <freetype/ttnameid.h>
|
|
|
|
|
2000-06-05 07:26:15 +02:00
|
|
|
|
2000-05-28 19:15:37 +02:00
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* Get_Name */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
|
|
|
/* Returns a given ENGLISH name record in ASCII. */
|
|
|
|
/* */
|
|
|
|
/* <Input> */
|
|
|
|
/* face :: A handle to the source face object. */
|
|
|
|
/* */
|
|
|
|
/* nameid :: The name id of the name record to return. */
|
|
|
|
/* */
|
|
|
|
/* <Return> */
|
2000-06-05 07:26:15 +02:00
|
|
|
/* Character string. NULL if no name is present. */
|
2000-05-28 19:15:37 +02:00
|
|
|
/* */
|
|
|
|
static
|
|
|
|
FT_String* Get_Name( TT_Face face,
|
|
|
|
FT_UShort nameid )
|
|
|
|
{
|
|
|
|
FT_Memory memory = face->root.memory;
|
|
|
|
FT_UShort n;
|
|
|
|
TT_NameRec* rec;
|
|
|
|
FT_Bool wide_chars = 1;
|
|
|
|
|
2000-06-05 07:26:15 +02:00
|
|
|
|
2000-05-28 19:15:37 +02:00
|
|
|
rec = face->name_table.names;
|
|
|
|
for ( n = 0; n < face->name_table.numNameRecords; n++, rec++ )
|
|
|
|
{
|
|
|
|
if ( rec->nameID == nameid )
|
|
|
|
{
|
|
|
|
/* found the name - now create an ASCII string from it */
|
|
|
|
FT_Bool found = 0;
|
|
|
|
|
2000-06-05 07:26:15 +02:00
|
|
|
|
|
|
|
/* test for Microsoft English language */
|
2000-05-28 19:15:37 +02:00
|
|
|
if ( rec->platformID == TT_PLATFORM_MICROSOFT &&
|
|
|
|
rec->encodingID <= TT_MS_ID_UNICODE_CS &&
|
2000-06-05 07:26:15 +02:00
|
|
|
( rec->languageID & 0x3FF ) == 0x009 )
|
2000-05-28 19:15:37 +02:00
|
|
|
found = 1;
|
|
|
|
|
2000-06-05 07:26:15 +02:00
|
|
|
/* test for Apple Unicode encoding */
|
2000-05-28 19:15:37 +02:00
|
|
|
else if ( rec->platformID == TT_PLATFORM_APPLE_UNICODE )
|
|
|
|
found = 1;
|
|
|
|
|
2000-06-05 07:26:15 +02:00
|
|
|
/* test for Apple Roman */
|
2000-05-28 19:15:37 +02:00
|
|
|
else if ( rec->platformID == TT_PLATFORM_MACINTOSH &&
|
|
|
|
rec->languageID == TT_MAC_ID_ROMAN )
|
|
|
|
{
|
|
|
|
found = 1;
|
|
|
|
wide_chars = 0;
|
|
|
|
}
|
|
|
|
|
2000-06-05 07:26:15 +02:00
|
|
|
/* found a Unicode name */
|
2000-05-28 19:15:37 +02:00
|
|
|
if ( found )
|
|
|
|
{
|
|
|
|
FT_String* string;
|
|
|
|
FT_UInt len;
|
|
|
|
|
2000-06-05 07:26:15 +02:00
|
|
|
|
2000-05-28 19:15:37 +02:00
|
|
|
if ( wide_chars )
|
|
|
|
{
|
|
|
|
TT_UInt m;
|
|
|
|
|
2000-06-05 07:26:15 +02:00
|
|
|
|
2000-05-28 19:15:37 +02:00
|
|
|
len = (TT_UInt)rec->stringLength / 2;
|
|
|
|
if ( MEM_Alloc( string, len + 1 ) )
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
for ( m = 0; m < len; m ++ )
|
2000-06-05 07:26:15 +02:00
|
|
|
string[m] = rec->string[2 * m + 1];
|
2000-05-28 19:15:37 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
len = rec->stringLength;
|
|
|
|
if ( MEM_Alloc( string, len + 1 ) )
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
MEM_Copy( string, rec->string, len );
|
|
|
|
}
|
|
|
|
|
|
|
|
string[len] = '\0';
|
|
|
|
return string;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2000-06-05 07:26:15 +02:00
|
|
|
|
2000-05-28 19:15:37 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static
|
2000-06-05 07:26:15 +02:00
|
|
|
FT_Encoding find_encoding( int platform_id,
|
|
|
|
int encoding_id )
|
2000-05-28 19:15:37 +02:00
|
|
|
{
|
|
|
|
typedef struct TEncoding
|
|
|
|
{
|
|
|
|
int platform_id;
|
|
|
|
int encoding_id;
|
|
|
|
FT_Encoding encoding;
|
|
|
|
|
|
|
|
} TEncoding;
|
|
|
|
|
2000-06-05 07:26:15 +02:00
|
|
|
static const TEncoding tt_encodings[] =
|
2000-05-28 19:15:37 +02:00
|
|
|
{
|
2000-06-05 07:26:15 +02:00
|
|
|
{ TT_PLATFORM_ISO, -1, ft_encoding_unicode },
|
2000-05-28 19:15:37 +02:00
|
|
|
|
2000-06-05 07:26:15 +02:00
|
|
|
{ TT_PLATFORM_APPLE_UNICODE, -1, ft_encoding_unicode },
|
2000-05-28 19:15:37 +02:00
|
|
|
|
2000-06-05 07:26:15 +02:00
|
|
|
{ TT_PLATFORM_MACINTOSH, TT_MAC_ID_ROMAN, ft_encoding_apple_roman },
|
2000-05-28 19:15:37 +02:00
|
|
|
|
2000-06-05 07:26:15 +02:00
|
|
|
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_UNICODE_CS, ft_encoding_unicode },
|
|
|
|
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_SJIS, ft_encoding_sjis },
|
|
|
|
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_GB2312, ft_encoding_gb2312 },
|
|
|
|
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_BIG_5, ft_encoding_big5 },
|
|
|
|
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_WANSUNG, ft_encoding_wansung },
|
|
|
|
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_JOHAB, ft_encoding_johab }
|
2000-05-28 19:15:37 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
const TEncoding *cur, *limit;
|
|
|
|
|
2000-06-05 07:26:15 +02:00
|
|
|
|
2000-05-28 19:15:37 +02:00
|
|
|
cur = tt_encodings;
|
2000-06-05 07:26:15 +02:00
|
|
|
limit = cur + sizeof ( tt_encodings ) / sizeof ( tt_encodings[0] );
|
2000-05-28 19:15:37 +02:00
|
|
|
|
|
|
|
for ( ; cur < limit; cur++ )
|
|
|
|
{
|
2000-06-05 07:26:15 +02:00
|
|
|
if ( cur->platform_id == platform_id )
|
2000-05-28 19:15:37 +02:00
|
|
|
{
|
2000-06-05 07:26:15 +02:00
|
|
|
if ( cur->encoding_id == encoding_id ||
|
|
|
|
cur->encoding_id == -1 )
|
2000-05-28 19:15:37 +02:00
|
|
|
return cur->encoding;
|
|
|
|
}
|
|
|
|
}
|
2000-06-05 07:26:15 +02:00
|
|
|
|
2000-05-28 19:15:37 +02:00
|
|
|
return ft_encoding_none;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
LOCAL_FUNC
|
|
|
|
FT_Error SFNT_Init_Face( FT_Stream stream,
|
|
|
|
TT_Face face,
|
|
|
|
TT_Int face_index,
|
|
|
|
TT_Int num_params,
|
|
|
|
FT_Parameter* params )
|
|
|
|
{
|
2000-06-05 07:26:15 +02:00
|
|
|
FT_Error error;
|
|
|
|
SFNT_Interface* sfnt;
|
|
|
|
PSNames_Interface* psnames;
|
|
|
|
SFNT_Header sfnt_header;
|
2000-05-28 19:15:37 +02:00
|
|
|
|
|
|
|
/* for now, parameters are unused */
|
2000-06-05 07:26:15 +02:00
|
|
|
UNUSED( num_params );
|
|
|
|
UNUSED( params );
|
|
|
|
|
2000-05-28 19:15:37 +02:00
|
|
|
|
|
|
|
sfnt = (SFNT_Interface*)face->sfnt;
|
2000-06-05 07:26:15 +02:00
|
|
|
if ( !sfnt )
|
2000-05-28 19:15:37 +02:00
|
|
|
{
|
|
|
|
/* look-up the SFNT driver */
|
|
|
|
FT_Driver sfnt_driver;
|
|
|
|
|
2000-06-05 07:26:15 +02:00
|
|
|
|
2000-05-28 19:15:37 +02:00
|
|
|
sfnt_driver = FT_Get_Driver( face->root.driver->library, "sfnt" );
|
2000-06-05 07:26:15 +02:00
|
|
|
if ( !sfnt_driver )
|
2000-05-28 19:15:37 +02:00
|
|
|
{
|
|
|
|
error = FT_Err_Invalid_File_Format;
|
|
|
|
goto Exit;
|
|
|
|
}
|
|
|
|
|
2000-06-05 07:26:15 +02:00
|
|
|
sfnt = (SFNT_Interface*)( sfnt_driver->interface.format_interface );
|
|
|
|
if ( !sfnt )
|
2000-05-28 19:15:37 +02:00
|
|
|
{
|
|
|
|
error = FT_Err_Invalid_File_Format;
|
|
|
|
goto Exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
face->sfnt = sfnt;
|
|
|
|
face->goto_table = sfnt->goto_table;
|
|
|
|
}
|
|
|
|
|
|
|
|
psnames = (PSNames_Interface*)face->psnames;
|
2000-06-05 07:26:15 +02:00
|
|
|
if ( !psnames )
|
2000-05-28 19:15:37 +02:00
|
|
|
{
|
|
|
|
/* look-up the PSNames driver */
|
|
|
|
FT_Driver psnames_driver;
|
|
|
|
|
2000-06-05 07:26:15 +02:00
|
|
|
|
2000-05-28 19:15:37 +02:00
|
|
|
psnames_driver = FT_Get_Driver( face->root.driver->library, "psnames" );
|
2000-06-05 07:26:15 +02:00
|
|
|
if ( psnames_driver )
|
2000-05-28 19:15:37 +02:00
|
|
|
face->psnames = (PSNames_Interface*)
|
2000-06-05 07:26:15 +02:00
|
|
|
( psnames_driver->interface.format_interface );
|
2000-05-28 19:15:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* check that we have a valid TrueType file */
|
2000-05-29 22:37:41 +02:00
|
|
|
error = sfnt->load_sfnt_header( face, stream, face_index, &sfnt_header );
|
2000-06-05 07:26:15 +02:00
|
|
|
if ( error )
|
2000-06-05 16:32:32 +02:00
|
|
|
goto Exit;
|
2000-05-28 19:15:37 +02:00
|
|
|
|
2000-05-29 22:37:41 +02:00
|
|
|
face->format_tag = sfnt_header.format_tag;
|
|
|
|
face->num_tables = sfnt_header.num_tables;
|
|
|
|
|
2000-05-28 19:15:37 +02:00
|
|
|
/* Load font directory */
|
2000-05-29 22:37:41 +02:00
|
|
|
error = sfnt->load_directory( face, stream, &sfnt_header );
|
2000-06-05 07:26:15 +02:00
|
|
|
if ( error )
|
|
|
|
goto Exit;
|
2000-05-28 19:15:37 +02:00
|
|
|
|
|
|
|
face->root.num_faces = face->ttc_header.DirCount;
|
|
|
|
if ( face->root.num_faces < 1 )
|
|
|
|
face->root.num_faces = 1;
|
|
|
|
|
|
|
|
Exit:
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#undef LOAD_
|
2000-06-05 07:26:15 +02:00
|
|
|
#define LOAD_( x ) ( (error = sfnt->load_##x( face, stream )) != FT_Err_Ok )
|
2000-05-28 19:15:37 +02:00
|
|
|
|
|
|
|
|
|
|
|
LOCAL_FUNC
|
|
|
|
TT_Error SFNT_Load_Face( FT_Stream stream,
|
|
|
|
TT_Face face,
|
|
|
|
TT_Int face_index,
|
|
|
|
TT_Int num_params,
|
|
|
|
FT_Parameter* params )
|
|
|
|
{
|
2000-06-05 07:26:15 +02:00
|
|
|
FT_Error error;
|
|
|
|
SFNT_Interface* sfnt = (SFNT_Interface*)face->sfnt;
|
|
|
|
|
2000-05-28 19:15:37 +02:00
|
|
|
|
|
|
|
/* Load tables */
|
|
|
|
if ( LOAD_( header ) ||
|
|
|
|
LOAD_( max_profile ) ||
|
|
|
|
|
|
|
|
/* load the `hhea' & `hmtx' tables at once */
|
2000-06-05 07:26:15 +02:00
|
|
|
( error = sfnt->load_metrics( face, stream, 0 ) ) != FT_Err_Ok ||
|
2000-05-28 19:15:37 +02:00
|
|
|
|
|
|
|
/* try to load the `vhea' & `vmtx' at once if present */
|
2000-06-05 07:26:15 +02:00
|
|
|
( error = sfnt->load_metrics( face, stream, 1 ) ) != FT_Err_Ok ||
|
2000-05-28 19:15:37 +02:00
|
|
|
|
|
|
|
LOAD_( charmaps ) ||
|
|
|
|
LOAD_( names ) ||
|
|
|
|
LOAD_( os2 ) ||
|
|
|
|
LOAD_( psnames ) )
|
|
|
|
goto Exit;
|
|
|
|
|
|
|
|
/* the optional tables */
|
|
|
|
|
|
|
|
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
|
2000-06-05 07:26:15 +02:00
|
|
|
/* embedded bitmap support. */
|
|
|
|
if ( sfnt->load_sbits && LOAD_( sbits ) )
|
|
|
|
goto Exit;
|
|
|
|
#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
|
2000-05-28 19:15:37 +02:00
|
|
|
|
|
|
|
if ( LOAD_( hdmx ) ||
|
|
|
|
LOAD_( gasp ) ||
|
|
|
|
LOAD_( kerning ) ||
|
|
|
|
LOAD_( pclt ) )
|
|
|
|
goto Exit;
|
|
|
|
|
|
|
|
#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE
|
|
|
|
if ( ( error = TT_Extension_Create( face ) ) != FT_Err_Ok )
|
|
|
|
goto Exit;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
face->root.family_name = Get_Name( face, TT_NAME_ID_FONT_FAMILY );
|
|
|
|
face->root.style_name = Get_Name( face, TT_NAME_ID_FONT_SUBFAMILY );
|
|
|
|
|
|
|
|
/* now set up root fields */
|
|
|
|
{
|
|
|
|
FT_Face root = &face->root;
|
|
|
|
FT_Int flags;
|
|
|
|
TT_CharMap charmap;
|
|
|
|
TT_Int n;
|
|
|
|
FT_Memory memory;
|
|
|
|
|
2000-06-05 07:26:15 +02:00
|
|
|
|
2000-05-28 19:15:37 +02:00
|
|
|
memory = root->memory;
|
|
|
|
|
2000-06-05 07:26:15 +02:00
|
|
|
/*********************************************************************/
|
|
|
|
/* */
|
|
|
|
/* Compute face flags. */
|
|
|
|
/* */
|
2000-05-28 19:15:37 +02:00
|
|
|
flags = FT_FACE_FLAG_SCALABLE | /* scalable outlines */
|
|
|
|
FT_FACE_FLAG_SFNT | /* SFNT file format */
|
|
|
|
FT_FACE_FLAG_HORIZONTAL; /* horizontal data */
|
|
|
|
|
2000-06-05 07:26:15 +02:00
|
|
|
/* fixed width font? */
|
2000-05-28 19:15:37 +02:00
|
|
|
if ( face->postscript.isFixedPitch )
|
|
|
|
flags |= FT_FACE_FLAG_FIXED_WIDTH;
|
|
|
|
|
2000-06-05 07:26:15 +02:00
|
|
|
/* vertical information? */
|
2000-05-28 19:15:37 +02:00
|
|
|
if ( face->vertical_info )
|
|
|
|
flags |= FT_FACE_FLAG_VERTICAL;
|
|
|
|
|
|
|
|
/* kerning available ? */
|
|
|
|
if ( face->kern_pairs )
|
|
|
|
flags |= FT_FACE_FLAG_KERNING;
|
|
|
|
|
|
|
|
root->face_flags = flags;
|
|
|
|
|
2000-06-05 07:26:15 +02:00
|
|
|
/*********************************************************************/
|
|
|
|
/* */
|
|
|
|
/* Compute style flags. */
|
|
|
|
/* */
|
2000-05-28 19:15:37 +02:00
|
|
|
flags = 0;
|
|
|
|
|
|
|
|
if ( face->os2.version != 0xFFFF )
|
|
|
|
{
|
2000-06-05 07:26:15 +02:00
|
|
|
/* we have an OS/2 table; use the `fsSelection' field */
|
2000-05-28 19:15:37 +02:00
|
|
|
if ( face->os2.fsSelection & 1 )
|
|
|
|
flags |= FT_STYLE_FLAG_ITALIC;
|
|
|
|
|
|
|
|
if ( face->os2.fsSelection & 32 )
|
|
|
|
flags |= FT_STYLE_FLAG_BOLD;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2000-06-05 07:26:15 +02:00
|
|
|
/* this is an old Mac font, use the header field */
|
2000-05-28 19:15:37 +02:00
|
|
|
if ( face->header.Mac_Style & 1 )
|
|
|
|
flags |= FT_STYLE_FLAG_BOLD;
|
|
|
|
|
|
|
|
if ( face->header.Mac_Style & 2 )
|
|
|
|
flags |= FT_STYLE_FLAG_ITALIC;
|
|
|
|
}
|
|
|
|
|
|
|
|
face->root.style_flags = flags;
|
|
|
|
|
2000-06-05 07:26:15 +02:00
|
|
|
/*********************************************************************/
|
|
|
|
/* */
|
|
|
|
/* Polish the charmaps. */
|
|
|
|
/* */
|
|
|
|
/* Try to set the charmap encoding according to the platform & */
|
|
|
|
/* encoding ID of each charmap. */
|
|
|
|
/* */
|
2000-05-28 19:15:37 +02:00
|
|
|
charmap = face->charmaps;
|
|
|
|
root->num_charmaps = face->num_charmaps;
|
|
|
|
|
|
|
|
/* allocate table of pointers */
|
|
|
|
if ( ALLOC_ARRAY( root->charmaps, root->num_charmaps, FT_CharMap ) )
|
|
|
|
goto Exit;
|
|
|
|
|
|
|
|
for ( n = 0; n < root->num_charmaps; n++, charmap++ )
|
|
|
|
{
|
|
|
|
FT_Int platform = charmap->cmap.platformID;
|
|
|
|
FT_Int encoding = charmap->cmap.platformEncodingID;
|
|
|
|
|
2000-06-05 07:26:15 +02:00
|
|
|
|
2000-05-28 19:15:37 +02:00
|
|
|
charmap->root.face = (FT_Face)face;
|
|
|
|
charmap->root.platform_id = platform;
|
|
|
|
charmap->root.encoding_id = encoding;
|
2000-06-05 07:26:15 +02:00
|
|
|
charmap->root.encoding = find_encoding( platform, encoding );
|
2000-05-28 19:15:37 +02:00
|
|
|
|
2000-06-05 07:26:15 +02:00
|
|
|
/* now, set root->charmap with a unicode charmap */
|
|
|
|
/* wherever available */
|
|
|
|
if ( !root->charmap &&
|
|
|
|
charmap->root.encoding == ft_encoding_unicode )
|
2000-05-28 19:15:37 +02:00
|
|
|
root->charmap = (FT_CharMap)charmap;
|
|
|
|
|
|
|
|
root->charmaps[n] = (FT_CharMap)charmap;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
|
|
|
|
if ( face->num_sbit_strikes )
|
|
|
|
{
|
|
|
|
face->root.num_fixed_sizes = face->num_sbit_strikes;
|
|
|
|
if ( ALLOC_ARRAY( face->root.available_sizes,
|
|
|
|
face->num_sbit_strikes,
|
|
|
|
FT_Bitmap_Size ) )
|
|
|
|
return error;
|
|
|
|
|
2000-06-05 07:26:15 +02:00
|
|
|
for ( n = 0 ; n < face->num_sbit_strikes ; n++ )
|
|
|
|
{
|
|
|
|
face->root.available_sizes[n].width =
|
|
|
|
face->sbit_strikes[n].x_ppem;
|
|
|
|
face->root.available_sizes[n].height =
|
|
|
|
face->sbit_strikes[n].y_ppem;
|
|
|
|
}
|
2000-05-28 19:15:37 +02:00
|
|
|
}
|
|
|
|
else
|
2000-06-05 07:26:15 +02:00
|
|
|
#else /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
|
2000-05-28 19:15:37 +02:00
|
|
|
{
|
|
|
|
root->num_fixed_sizes = 0;
|
|
|
|
root->available_sizes = 0;
|
|
|
|
}
|
|
|
|
#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
|
|
|
|
|
2000-06-05 07:26:15 +02:00
|
|
|
/*********************************************************************/
|
|
|
|
/* */
|
|
|
|
/* Set up metrics. */
|
|
|
|
/* */
|
2000-05-28 19:15:37 +02:00
|
|
|
root->bbox.xMin = face->header.xMin;
|
|
|
|
root->bbox.yMin = face->header.yMin;
|
|
|
|
root->bbox.xMax = face->header.xMax;
|
|
|
|
root->bbox.yMax = face->header.yMax;
|
|
|
|
root->units_per_EM = face->header.Units_Per_EM;
|
|
|
|
|
2000-06-05 07:26:15 +02:00
|
|
|
/* The ascender/descender/height are computed from the OS/2 table */
|
|
|
|
/* when found. Otherwise, they're taken from the horizontal header. */
|
2000-05-28 19:15:37 +02:00
|
|
|
if ( face->os2.version != 0xFFFF )
|
|
|
|
{
|
|
|
|
root->ascender = face->os2.sTypoAscender;
|
|
|
|
root->descender = -face->os2.sTypoDescender;
|
|
|
|
root->height = root->ascender + root->descender +
|
|
|
|
face->os2.sTypoLineGap;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
root->ascender = face->horizontal.Ascender;
|
|
|
|
root->descender = face->horizontal.Descender;
|
|
|
|
root->height = root->ascender + root->descender +
|
|
|
|
face->horizontal.Line_Gap;
|
|
|
|
}
|
|
|
|
|
2000-06-05 07:26:15 +02:00
|
|
|
root->max_advance_width = face->horizontal.advance_Width_Max;
|
2000-05-28 19:15:37 +02:00
|
|
|
|
2000-06-05 07:26:15 +02:00
|
|
|
root->max_advance_height = face->vertical_info
|
|
|
|
? face->vertical.advance_Height_Max
|
|
|
|
: root->height;
|
2000-05-28 19:15:37 +02:00
|
|
|
|
|
|
|
root->underline_position = face->postscript.underlinePosition;
|
|
|
|
root->underline_thickness = face->postscript.underlineThickness;
|
|
|
|
|
|
|
|
/* root->max_points - already set up */
|
|
|
|
/* root->max_contours - already set up */
|
|
|
|
}
|
|
|
|
|
|
|
|
Exit:
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#undef LOAD_
|
|
|
|
|
|
|
|
|
|
|
|
LOCAL_FUNC
|
|
|
|
void SFNT_Done_Face( TT_Face face )
|
|
|
|
{
|
|
|
|
FT_Memory memory = face->root.memory;
|
|
|
|
SFNT_Interface* sfnt = face->sfnt;
|
|
|
|
|
2000-06-05 07:26:15 +02:00
|
|
|
|
|
|
|
if ( sfnt )
|
2000-05-28 19:15:37 +02:00
|
|
|
{
|
2000-06-05 07:26:15 +02:00
|
|
|
/* destroy the postscript names table if it is loaded */
|
|
|
|
if ( sfnt->free_psnames )
|
2000-05-28 19:15:37 +02:00
|
|
|
sfnt->free_psnames( face );
|
|
|
|
|
2000-06-05 07:26:15 +02:00
|
|
|
/* destroy the embedded bitmaps table if it is loaded */
|
|
|
|
if ( sfnt->free_sbits )
|
2000-05-28 19:15:37 +02:00
|
|
|
sfnt->free_sbits( face );
|
|
|
|
}
|
|
|
|
|
|
|
|
/* freeing the kerning table */
|
|
|
|
FREE( face->kern_pairs );
|
|
|
|
face->num_kern_pairs = 0;
|
|
|
|
|
|
|
|
/* freeing the collection table */
|
|
|
|
FREE( face->ttc_header.TableDirectory );
|
|
|
|
face->ttc_header.DirCount = 0;
|
|
|
|
|
|
|
|
/* freeing table directory */
|
|
|
|
FREE( face->dir_tables );
|
|
|
|
face->num_tables = 0;
|
|
|
|
|
|
|
|
/* freeing the character mapping tables */
|
|
|
|
if (sfnt && sfnt->load_charmaps )
|
|
|
|
{
|
|
|
|
FT_UShort n;
|
2000-06-05 07:26:15 +02:00
|
|
|
|
|
|
|
|
2000-05-28 19:15:37 +02:00
|
|
|
for ( n = 0; n < face->num_charmaps; n++ )
|
|
|
|
sfnt->free_charmap( face, &face->charmaps[n].cmap );
|
|
|
|
}
|
|
|
|
|
|
|
|
FREE( face->charmaps );
|
|
|
|
face->num_charmaps = 0;
|
|
|
|
|
|
|
|
FREE( face->root.charmaps );
|
|
|
|
face->root.num_charmaps = 0;
|
|
|
|
face->root.charmap = 0;
|
|
|
|
|
|
|
|
/* freeing the horizontal metrics */
|
|
|
|
FREE( face->horizontal.long_metrics );
|
|
|
|
FREE( face->horizontal.short_metrics );
|
|
|
|
|
|
|
|
/* freeing the vertical ones, if any */
|
|
|
|
if ( face->vertical_info )
|
|
|
|
{
|
|
|
|
FREE( face->vertical.long_metrics );
|
|
|
|
FREE( face->vertical.short_metrics );
|
|
|
|
face->vertical_info = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* freeing the gasp table */
|
|
|
|
FREE( face->gasp.gaspRanges );
|
|
|
|
face->gasp.numRanges = 0;
|
|
|
|
|
|
|
|
/* freeing the name table */
|
|
|
|
sfnt->free_names( face );
|
|
|
|
|
|
|
|
/* freeing the hdmx table */
|
|
|
|
sfnt->free_hdmx( face );
|
|
|
|
|
|
|
|
/* freeing family and style name */
|
|
|
|
FREE( face->root.family_name );
|
|
|
|
FREE( face->root.style_name );
|
|
|
|
|
|
|
|
/* freeing sbit size table */
|
|
|
|
face->root.num_fixed_sizes = 0;
|
|
|
|
if ( face->root.available_sizes )
|
|
|
|
FREE( face->root.available_sizes );
|
|
|
|
|
|
|
|
face->sfnt = 0;
|
|
|
|
}
|
|
|
|
|
2000-06-05 07:26:15 +02:00
|
|
|
|
|
|
|
/* END */
|