📄 ttload.c
字号:
/***************************************************************************/
/* */
/* ttload.c */
/* */
/* Load the basic TrueType tables, i.e., tables that can be either in */
/* TTF or OTF fonts (body). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 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 <ft2build.h>
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_STREAM_H
#include FT_TRUETYPE_TAGS_H
#include "ttload.h"
#include "sferrors.h"
/*************************************************************************/
/* */
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
/* messages during execution. */
/* */
#undef FT_COMPONENT
#define FT_COMPONENT trace_ttload
/*************************************************************************/
/* */
/* <Function> */
/* tt_face_lookup_table */
/* */
/* <Description> */
/* Looks for a TrueType table by name. */
/* */
/* <Input> */
/* face :: A face object handle. */
/* */
/* tag :: The searched tag. */
/* */
/* <Return> */
/* A pointer to the table directory entry. 0 if not found. */
/* */
FT_LOCAL_DEF( TT_Table )
tt_face_lookup_table( TT_Face face,
FT_ULong tag )
{
TT_Table entry;
TT_Table limit;
FT_TRACE4(( "tt_face_lookup_table: %08p, `%c%c%c%c' -- ",
face,
(FT_Char)( tag >> 24 ),
(FT_Char)( tag >> 16 ),
(FT_Char)( tag >> 8 ),
(FT_Char)( tag ) ));
entry = face->dir_tables;
limit = entry + face->num_tables;
for ( ; entry < limit; entry++ )
{
/* For compatibility with Windows, we consider 0-length */
/* tables the same as missing tables. */
if ( entry->Tag == tag && entry->Length != 0 )
{
FT_TRACE4(( "found table.\n" ));
return entry;
}
}
FT_TRACE4(( "could not find table!\n" ));
return 0;
}
/*************************************************************************/
/* */
/* <Function> */
/* tt_face_goto_table */
/* */
/* <Description> */
/* Looks for a TrueType table by name, then seek a stream to it. */
/* */
/* <Input> */
/* face :: A face object handle. */
/* */
/* tag :: The searched tag. */
/* */
/* stream :: The stream to seek when the table is found. */
/* */
/* <Output> */
/* length :: The length of the table if found, undefined otherwise. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
FT_LOCAL_DEF( FT_Error )
tt_face_goto_table( TT_Face face,
FT_ULong tag,
FT_Stream stream,
FT_ULong* length )
{
TT_Table table;
FT_Error error;
table = tt_face_lookup_table( face, tag );
if ( table )
{
if ( length )
*length = table->Length;
if ( FT_STREAM_SEEK( table->Offset ) )
goto Exit;
}
else
error = SFNT_Err_Table_Missing;
Exit:
return error;
}
/* Here, we */
/* */
/* - check that `num_tables' is valid */
/* - look for a `head' table, check its size, and parse it to check */
/* whether its `magic' field is correctly set */
/* */
/* When checking directory entries, ignore the tables `glyx' and `locx' */
/* which are hacked-out versions of `glyf' and `loca' in some PostScript */
/* Type 42 fonts, and which are generally invalid. */
/* */
static FT_Error
check_table_dir( SFNT_Header sfnt,
FT_Stream stream )
{
FT_Error error;
FT_UInt nn;
FT_UInt has_head = 0, has_sing = 0, has_meta = 0;
FT_ULong offset = sfnt->offset + 12;
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 table_dir_entry_fields[] =
{
#undef FT_STRUCTURE
#define FT_STRUCTURE TT_TableRec
FT_FRAME_START( 16 ),
FT_FRAME_ULONG( Tag ),
FT_FRAME_ULONG( CheckSum ),
FT_FRAME_ULONG( Offset ),
FT_FRAME_ULONG( Length ),
FT_FRAME_END
};
if ( sfnt->num_tables == 0 ||
offset + sfnt->num_tables * 16 > stream->size )
return SFNT_Err_Unknown_File_Format;
if ( FT_STREAM_SEEK( offset ) )
return error;
for ( nn = 0; nn < sfnt->num_tables; nn++ )
{
TT_TableRec table;
if ( FT_STREAM_READ_FIELDS( table_dir_entry_fields, &table ) )
return error;
if ( table.Offset + table.Length > stream->size &&
table.Tag != glyx_tag &&
table.Tag != locx_tag )
return SFNT_Err_Unknown_File_Format;
if ( table.Tag == TTAG_head || table.Tag == TTAG_bhed )
{
FT_UInt32 magic;
#ifndef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
if ( table.Tag == TTAG_head )
#endif
has_head = 1;
/*
* The table length should be 0x36, but certain font tools make it
* 0x38, so we will just check that it is greater.
*
* Note that according to the specification, the table must be
* padded to 32-bit lengths, but this doesn't apply to the value of
* its `Length' field!
*
*/
if ( table.Length < 0x36 )
return SFNT_Err_Unknown_File_Format;
if ( FT_STREAM_SEEK( table.Offset + 12 ) ||
FT_READ_ULONG( magic ) )
return error;
if ( magic != 0x5F0F3CF5UL )
return SFNT_Err_Unknown_File_Format;
if ( FT_STREAM_SEEK( offset + ( nn + 1 ) * 16 ) )
return error;
}
else if ( table.Tag == TTAG_SING )
has_sing = 1;
else if ( table.Tag == TTAG_META )
has_meta = 1;
}
/* if `sing' and `meta' tables are present, there is no `head' table */
if ( has_head || ( has_sing && has_meta ) )
return SFNT_Err_Ok;
else
return SFNT_Err_Unknown_File_Format;
}
/*************************************************************************/
/* */
/* <Function> */
/* tt_face_load_font_dir */
/* */
/* <Description> */
/* Loads the header of a SFNT font file. */
/* */
/* <Input> */
/* face :: A handle to the target face object. */
/* */
/* stream :: The input stream. */
/* */
/* <Output> */
/* sfnt :: The SFNT header. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* The stream cursor must be at the beginning of the font directory. */
/* */
FT_LOCAL_DEF( FT_Error )
tt_face_load_font_dir( TT_Face face,
FT_Stream stream )
{
SFNT_HeaderRec sfnt;
FT_Error error;
FT_Memory memory = stream->memory;
TT_TableRec* entry;
TT_TableRec* limit;
static const FT_Frame_Field offset_table_fields[] =
{
#undef FT_STRUCTURE
#define FT_STRUCTURE SFNT_HeaderRec
FT_FRAME_START( 8 ),
FT_FRAME_USHORT( num_tables ),
FT_FRAME_USHORT( search_range ),
FT_FRAME_USHORT( entry_selector ),
FT_FRAME_USHORT( range_shift ),
FT_FRAME_END
};
FT_TRACE2(( "tt_face_load_font_dir: %08p\n", face ));
/* read the offset table */
sfnt.offset = FT_STREAM_POS();
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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -