Clean up the SFNT_Interface. In this pass, we want to treat the font

directory (offset table and table directory) as a normal table like
the others.  This also means that TTC is no longer recognized there,
but in `init_face'.

* include/freetype/internal/sfnt.h (SFNT_Interface),
src/sfnt/sfdriver.c: `load_sfnt_header' and `load_directory' are
combined and renamed to `load_font_dir'.

* src/sfnt/ttload.h, src/sfnt/ttload.c:
s/sfnt_dir_check/check_table_dir/.
`sfnt_init' is moved to sfobjs.c and renamed to `sfnt_open_font'.
`tt_face_load_sfnt_header' and `tt_face_load_directory' are combined
and renamed to `tt_face_load_font_dir'.

* src/sfnt/sfobjs.c (sfnt_init_face): Recognize TTC here.
This commit is contained in:
Wu, Chia-I (吳佳一) 2006-02-14 07:01:29 +00:00
parent f5aa47beb0
commit 65863a5712
6 changed files with 160 additions and 267 deletions

View File

@ -1,3 +1,22 @@
2006-02-13 Chia-I Wu <b90201047@ntu.edu.tw>
Clean up the SFNT_Interface. In this pass, we want to treat the font
directory (offset table and table directory) as a normal table like
the others. This also means that TTC is no longer recognized there,
but in `init_face'.
* include/freetype/internal/sfnt.h (SFNT_Interface),
src/sfnt/sfdriver.c: `load_sfnt_header' and `load_directory' are
combined and renamed to `load_font_dir'.
* src/sfnt/ttload.h, src/sfnt/ttload.c:
s/sfnt_dir_check/check_table_dir/.
`sfnt_init' is moved to sfobjs.c and renamed to `sfnt_open_font'.
`tt_face_load_sfnt_header' and `tt_face_load_directory' are combined
and renamed to `tt_face_load_font_dir'.
* src/sfnt/sfobjs.c (sfnt_init_face): Recognize TTC here.
2006-02-13 Chia-I Wu <b90201047@ntu.edu.tw>
Clean up the SFNT_Interface. Table loading functions are now named

View File

@ -125,73 +125,6 @@ FT_BEGIN_HEADER
(*TT_Done_Face_Func)( TT_Face face );
/*************************************************************************/
/* */
/* <FuncType> */
/* TT_Load_SFNT_HeaderRec_Func */
/* */
/* <Description> */
/* Load the header of a SFNT font file. Supports collections. */
/* */
/* <Input> */
/* face :: A handle to the target face object. */
/* */
/* stream :: The input stream. */
/* */
/* face_index :: The index of the TrueType font, if we are opening a */
/* collection. */
/* */
/* <Output> */
/* sfnt :: The SFNT header. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* The stream cursor must be at the font file's origin. */
/* */
/* This function recognizes fonts embedded in a `TrueType */
/* collection'. */
/* */
/* This function checks that the header is valid by looking at the */
/* values of `search_range', `entry_selector', and `range_shift'. */
/* */
typedef FT_Error
(*TT_Load_SFNT_HeaderRec_Func)( TT_Face face,
FT_Stream stream,
FT_Long face_index,
SFNT_Header sfnt );
/*************************************************************************/
/* */
/* <FuncType> */
/* TT_Load_Directory_Func */
/* */
/* <Description> */
/* Load the table directory into a face object. */
/* */
/* <Input> */
/* face :: A handle to the target face object. */
/* */
/* stream :: The input stream. */
/* */
/* sfnt :: The SFNT header. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* The stream cursor must be on the first byte after the 4-byte font */
/* format tag. This is the case just after a call to */
/* TT_Load_Format_Tag(). */
/* */
typedef FT_Error
(*TT_Load_Directory_Func)( TT_Face face,
FT_Stream stream,
SFNT_Header sfnt );
/*************************************************************************/
/* */
/* <FuncType> */
@ -505,7 +438,7 @@ FT_BEGIN_HEADER
/* */
/* <Note> */
/* The function will use `face->goto_table' to seek the stream to */
/* the start of the table. */
/* the start of the table, except in loading font directory. */
/* */
typedef FT_Error
(*TT_Load_Table_Func)( TT_Face face,
@ -570,8 +503,10 @@ FT_BEGIN_HEADER
FT_Module_Requester get_interface;
TT_Load_Any_Func load_any;
TT_Load_SFNT_HeaderRec_Func load_sfnt_header;
TT_Load_Directory_Func load_directory;
/* load the font directory, i.e. the offset table and */
/* the table directory */
TT_Load_Table_Func load_font_dir;
/* these functions are called by `load_face' but they can also */
/* be called from external modules, if there is a need to do so */

View File

@ -386,8 +386,7 @@
sfnt_get_interface,
tt_face_load_any,
tt_face_load_sfnt_header,
tt_face_load_directory,
tt_face_load_font_dir,
tt_face_load_head,
tt_face_load_hhea,

View File

@ -345,6 +345,85 @@
}
/* Fill in face->ttc_header. If the font is not a TTC, it is */
/* synthesized into a TTC with one offset table. */
static FT_Error
sfnt_open_font( FT_Stream stream,
TT_Face face )
{
FT_Memory memory = stream->memory;
FT_Error error;
FT_ULong tag, offset;
static const FT_Frame_Field ttc_header_fields[] =
{
#undef FT_STRUCTURE
#define FT_STRUCTURE TTC_HeaderRec
FT_FRAME_START( 8 ),
FT_FRAME_LONG( version ),
FT_FRAME_LONG( count ),
FT_FRAME_END
};
face->ttc_header.tag = 0;
face->ttc_header.version = 0;
face->ttc_header.count = 0;
offset = FT_STREAM_POS();
if ( FT_READ_ULONG( tag ) )
return error;
if ( tag != 0x00010000UL &&
tag != TTAG_ttcf &&
tag != FT_MAKE_TAG( 'O', 'T', 'T', 'O' ) &&
tag != TTAG_true &&
tag != 0x00020000UL )
return SFNT_Err_Unknown_File_Format;
face->ttc_header.tag = TTAG_ttcf;
if ( tag == TTAG_ttcf )
{
FT_Int n;
FT_TRACE3(( "sfnt_open_font: file is a collection\n" ));
if ( FT_STREAM_READ_FIELDS( ttc_header_fields, &face->ttc_header ) )
return error;
/* now read the offsets of each font in the file */
if ( FT_NEW_ARRAY( face->ttc_header.offsets, face->ttc_header.count ) )
return error;
if ( FT_FRAME_ENTER( face->ttc_header.count * 4L ) )
return error;
for ( n = 0; n < face->ttc_header.count; n++ )
face->ttc_header.offsets[n] = FT_GET_ULONG();
FT_FRAME_EXIT();
}
else
{
FT_TRACE3(( "sfnt_open_font: synthesize TTC\n" ));
face->ttc_header.version = 1 << 16;
face->ttc_header.count = 1;
if ( FT_NEW( face->ttc_header.offsets) )
return error;
face->ttc_header.offsets[0] = offset;
}
return error;
}
FT_LOCAL_DEF( FT_Error )
sfnt_init_face( FT_Stream stream,
TT_Face face,
@ -355,7 +434,7 @@
FT_Error error;
FT_Library library = face->root.driver->root.library;
SFNT_Service sfnt;
SFNT_HeaderRec sfnt_header;
/* for now, parameters are unused */
FT_UNUSED( num_params );
@ -367,10 +446,7 @@
{
sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" );
if ( !sfnt )
{
error = SFNT_Err_Invalid_File_Format;
goto Exit;
}
return SFNT_Err_Invalid_File_Format;
face->sfnt = sfnt;
face->goto_table = sfnt->goto_table;
@ -378,24 +454,28 @@
FT_FACE_FIND_GLOBAL_SERVICE( face, face->psnames, POSTSCRIPT_CMAPS );
error = sfnt_open_font( stream, face );
if ( error )
return error;
FT_TRACE2(( "sfnt_init_face: %08p, %ld\n", face, face_index ));
if ( face_index < 0 )
face_index = 0;
if ( face_index >= face->ttc_header.count )
return SFNT_Err_Bad_Argument;
if ( FT_STREAM_SEEK( face->ttc_header.offsets[face_index] ) )
return error;
/* check that we have a valid TrueType file */
error = sfnt->load_sfnt_header( face, stream, face_index, &sfnt_header );
error = sfnt->load_font_dir( face, stream );
if ( error )
goto Exit;
face->format_tag = sfnt_header.format_tag;
face->num_tables = sfnt_header.num_tables;
/* Load font directory */
error = sfnt->load_directory( face, stream, &sfnt_header );
if ( error )
goto Exit;
return error;
face->root.num_faces = face->ttc_header.count;
if ( face->root.num_faces < 1 )
face->root.num_faces = 1;
Exit:
return error;
}

View File

@ -145,8 +145,8 @@
/* Type 42 fonts, and which are generally invalid. */
/* */
static FT_Error
sfnt_dir_check( SFNT_Header sfnt,
FT_Stream stream )
check_table_dir( SFNT_Header sfnt,
FT_Stream stream )
{
FT_Error error;
FT_UInt nn;
@ -156,7 +156,7 @@
const FT_ULong glyx_tag = FT_MAKE_TAG( 'g', 'l', 'y', 'x' );
const FT_ULong locx_tag = FT_MAKE_TAG( 'l', 'o', 'c', 'x' );
static const FT_Frame_Field sfnt_dir_entry_fields[] =
static const FT_Frame_Field table_dir_entry_fields[] =
{
#undef FT_STRUCTURE
#define FT_STRUCTURE TT_TableRec
@ -182,7 +182,7 @@
TT_TableRec table;
if ( FT_STREAM_READ_FIELDS( sfnt_dir_entry_fields, &table ) )
if ( FT_STREAM_READ_FIELDS( table_dir_entry_fields, &table ) )
return error;
if ( table.Offset + table.Length > stream->size &&
@ -194,6 +194,7 @@
{
FT_UInt32 magic;
#ifndef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
if ( table.Tag == TTAG_head )
#endif
@ -235,101 +236,19 @@
}
/* Fill in face->ttc_header. If the font is not a TTC, it is */
/* synthesized into a TTC with one offset table. */
static FT_Error
sfnt_init( FT_Stream stream,
TT_Face face )
{
FT_Memory memory = stream->memory;
FT_Error error;
FT_ULong tag, offset;
static const FT_Frame_Field ttc_header_fields[] =
{
#undef FT_STRUCTURE
#define FT_STRUCTURE TTC_HeaderRec
FT_FRAME_START( 8 ),
FT_FRAME_LONG( version ),
FT_FRAME_LONG( count ),
FT_FRAME_END
};
face->ttc_header.tag = 0;
face->ttc_header.version = 0;
face->ttc_header.count = 0;
offset = FT_STREAM_POS();
if ( FT_READ_ULONG( tag ) )
return error;
if ( tag != 0x00010000UL &&
tag != TTAG_ttcf &&
tag != FT_MAKE_TAG( 'O', 'T', 'T', 'O' ) &&
tag != TTAG_true &&
tag != 0x00020000UL )
return SFNT_Err_Unknown_File_Format;
face->ttc_header.tag = TTAG_ttcf;
if ( tag == TTAG_ttcf )
{
FT_Int n;
FT_TRACE3(( "sfnt_init: file is a collection\n" ));
if ( FT_STREAM_READ_FIELDS( ttc_header_fields, &face->ttc_header ) )
return error;
/* now read the offsets of each font in the file */
if ( FT_NEW_ARRAY( face->ttc_header.offsets, face->ttc_header.count ) )
return error;
if ( FT_FRAME_ENTER( face->ttc_header.count * 4L ) )
return error;
for ( n = 0; n < face->ttc_header.count; n++ )
face->ttc_header.offsets[n] = FT_GET_ULONG();
FT_FRAME_EXIT();
}
else
{
FT_TRACE3(( "sfnt_init: synthesize TTC\n" ));
face->ttc_header.version = 1 << 16;
face->ttc_header.count = 1;
if ( FT_NEW( face->ttc_header.offsets) )
return error;
face->ttc_header.offsets[0] = offset;
}
return error;
}
/*************************************************************************/
/* */
/* <Function> */
/* tt_face_load_sfnt_header */
/* tt_face_load_font_dir */
/* */
/* <Description> */
/* Loads the header of a SFNT font file. Supports collections. */
/* Loads the header of a SFNT font file. */
/* */
/* <Input> */
/* face :: A handle to the target face object. */
/* */
/* stream :: The input stream. */
/* */
/* face_index :: If the font is a collection, the number of the font */
/* in the collection. Must be zero otherwise. */
/* */
/* <Output> */
/* sfnt :: The SFNT header. */
/* */
@ -337,22 +256,19 @@
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* The stream cursor must be at the font file's origin. */
/* */
/* This function recognizes fonts embedded in a `TrueType collection' */
/* */
/* The header will be checked whether it is valid by looking at the */
/* values of `search_range', `entry_selector', and `range_shift'. */
/* The stream cursor must be at the beginning of the font directory. */
/* */
FT_LOCAL_DEF( FT_Error )
tt_face_load_sfnt_header( TT_Face face,
FT_Stream stream,
FT_Long face_index,
SFNT_Header sfnt )
tt_face_load_font_dir( TT_Face face,
FT_Stream stream )
{
FT_Error error;
SFNT_HeaderRec sfnt;
FT_Error error;
FT_Memory memory = stream->memory;
TT_TableRec* entry;
TT_TableRec* limit;
static const FT_Frame_Field sfnt_header_fields[] =
static const FT_Frame_Field offset_table_fields[] =
{
#undef FT_STRUCTURE
#define FT_STRUCTURE SFNT_HeaderRec
@ -366,101 +282,52 @@
};
FT_TRACE2(( "tt_face_load_sfnt_header: %08p, %ld\n",
face, face_index ));
FT_TRACE2(( "tt_face_load_font_dir: %08p\n", face ));
error = sfnt_init( stream, face );
if ( error )
return error;
/* read the offset table */
if ( face_index < 0 )
face_index = 0;
sfnt.offset = FT_STREAM_POS();
if ( face_index >= face->ttc_header.count )
return SFNT_Err_Bad_Argument;
sfnt->offset = face->ttc_header.offsets[face_index];
if ( FT_STREAM_SEEK( sfnt->offset ) )
return error;
/* read offset table */
if ( FT_READ_ULONG( sfnt->format_tag ) ||
FT_STREAM_READ_FIELDS( sfnt_header_fields, sfnt ) )
if ( FT_READ_ULONG( sfnt.format_tag ) ||
FT_STREAM_READ_FIELDS( offset_table_fields, &sfnt ) )
return error;
/* many fonts don't have these fields set correctly */
#if 0
if ( sfnt->search_range != 1 << ( sfnt->entry_selector + 4 ) ||
sfnt->search_range + sfnt->range_shift != sfnt->num_tables << 4 )
if ( sfnt.search_range != 1 << ( sfnt.entry_selector + 4 ) ||
sfnt.search_range + sfnt.range_shift != sfnt.num_tables << 4 )
return SFNT_Err_Unknown_File_Format;
#endif
return error;
}
/* load the table directory */
/*************************************************************************/
/* */
/* <Function> */
/* tt_face_load_directory */
/* */
/* <Description> */
/* Loads the table directory into a face object. */
/* */
/* <InOut> */
/* face :: A handle to the target face object. */
/* */
/* <Input> */
/* stream :: The input stream. */
/* */
/* sfnt :: The SFNT directory header. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* The stream cursor must be at the font file's origin. */
/* */
FT_LOCAL_DEF( FT_Error )
tt_face_load_directory( TT_Face face,
FT_Stream stream,
SFNT_Header sfnt )
{
FT_Error error;
FT_Memory memory = stream->memory;
TT_TableRec *entry, *limit;
FT_TRACE2(( "tt_face_load_directory: %08p\n", face ));
FT_TRACE2(( "-- Tables count: %12u\n", sfnt->num_tables ));
FT_TRACE2(( "-- Format version: %08lx\n", sfnt->format_tag ));
FT_TRACE2(( "-- Tables count: %12u\n", sfnt.num_tables ));
FT_TRACE2(( "-- Format version: %08lx\n", sfnt.format_tag ));
/* check first */
error = sfnt_dir_check( sfnt, stream );
error = check_table_dir( &sfnt, stream );
if ( error )
{
FT_TRACE2(( "tt_face_load_directory: directory checking failed!\n" ));
FT_TRACE2(( "tt_face_load_font_dir: invalid table directory!\n" ));
return error;
}
face->num_tables = sfnt->num_tables;
face->num_tables = sfnt.num_tables;
face->format_tag = sfnt.format_tag;
if ( FT_QNEW_ARRAY( face->dir_tables, face->num_tables ) )
goto Exit;
return error;
if ( FT_STREAM_SEEK( sfnt->offset + 12 ) ||
if ( FT_STREAM_SEEK( sfnt.offset + 12 ) ||
FT_FRAME_ENTER( face->num_tables * 16L ) )
goto Exit;
return error;
entry = face->dir_tables;
limit = entry + face->num_tables;
for ( ; entry < limit; entry++ )
{ /* loop through the tables and get all entries */
{
entry->Tag = FT_GET_TAG4();
entry->CheckSum = FT_GET_ULONG();
entry->Offset = FT_GET_LONG();
@ -477,9 +344,8 @@
FT_FRAME_EXIT();
FT_TRACE2(( "Directory loaded\n\n" ));
FT_TRACE2(( "table directory loaded\n\n" ));
Exit:
return error;
}

View File

@ -41,15 +41,9 @@ FT_BEGIN_HEADER
FT_LOCAL( FT_Error )
tt_face_load_sfnt_header( TT_Face face,
FT_Stream stream,
FT_Long face_index,
SFNT_Header sfnt );
tt_face_load_font_dir( TT_Face face,
FT_Stream stream );
FT_LOCAL( FT_Error )
tt_face_load_directory( TT_Face face,
FT_Stream stream,
SFNT_Header sfnt );
FT_LOCAL( FT_Error )
tt_face_load_any( TT_Face face,