📄 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 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 "ttcmap.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_TRACE3(( "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_TRACE3(( "found table.\n" )); return entry; } } FT_TRACE3(( "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; } /* In theory, we should check the values of `search_range', */ /* `entry_selector', and `range_shift' to detect non-SFNT based files */ /* whose header might also start with 0x100000L (yes, these exist). */ /* */ /* Very unfortunately, many TrueType fonts don't have these fields */ /* set correctly and we must ignore them to support them. An alternative */ /* way to check the font file is thus to: */ /* */ /* - check that `num_tables' is valid */ /* - look for a "head" table, check its size, and parse it to */ /* see if 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 will generally be invalid. */ /* */ static FT_Error sfnt_dir_check( FT_Stream stream, FT_ULong offset, FT_UInt num_tables ) { FT_Error error; FT_UInt nn, has_head = 0; 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[] = {#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 'num_tables' is 0, read the table count from the file */ if ( num_tables == 0 ) { if ( FT_STREAM_SEEK( offset ) || FT_STREAM_SKIP( 4 ) || FT_READ_USHORT( num_tables ) || FT_STREAM_SKIP( 6 ) ) goto Bad_Format; if ( offset + 12 + num_tables*16 > stream->size ) goto Bad_Format; } else if ( FT_STREAM_SEEK( offset + 12 ) ) goto Bad_Format; for ( nn = 0; nn < num_tables; nn++ ) { TT_TableRec table; if ( FT_STREAM_READ_FIELDS( sfnt_dir_entry_fields, &table ) ) goto Bad_Format; if ( table.Offset + table.Length > stream->size && table.Tag != glyx_tag && table.Tag != locx_tag ) goto Bad_Format; if ( table.Tag == TTAG_head ) { FT_UInt32 magic; 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 || FT_STREAM_SEEK( table.Offset + 12 ) || FT_READ_ULONG( magic ) || magic != 0x5F0F3CF5UL ) goto Bad_Format; if ( FT_STREAM_SEEK( offset + 28 + 16*nn ) ) goto Bad_Format; } } if ( has_head == 0 ) goto Bad_Format; Exit: return error; Bad_Format: error = SFNT_Err_Unknown_File_Format; goto Exit; } /*************************************************************************/ /* */ /* <Function> */ /* tt_face_load_sfnt_header */ /* */ /* <Description> */ /* Loads the header of a SFNT font file. Supports collections. */ /* */ /* <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, ignored otherwise. */ /* */ /* <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' */ /* */ /* The header will be checked whether it is valid by looking at the */ /* values of `search_range', `entry_selector', and `range_shift'. */ /* */ FT_LOCAL_DEF( FT_Error ) tt_face_load_sfnt_header( TT_Face face, FT_Stream stream, FT_Long face_index, SFNT_Header sfnt ) { FT_Error error; FT_ULong format_tag, offset; FT_Memory memory = stream->memory; static const FT_Frame_Field sfnt_header_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 }; 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 }; FT_TRACE2(( "tt_face_load_sfnt_header: %08p, %ld\n", face, face_index )); face->ttc_header.tag = 0; face->ttc_header.version = 0; face->ttc_header.count = 0; face->num_tables = 0; /* first of all, read the first 4 bytes. If it is `ttcf', then the */ /* file is a TrueType collection, otherwise it can be any other */ /* kind of font. */ /* */ offset = FT_STREAM_POS(); if ( FT_READ_ULONG( format_tag ) ) goto Exit; if ( format_tag == TTAG_ttcf ) { FT_Int n; FT_TRACE3(( "tt_face_load_sfnt_header: file is a collection\n" )); /* It is a TrueType collection, i.e. a file containing several */ /* font files. Read the font directory now */ if ( FT_STREAM_READ_FIELDS( ttc_header_fields, &face->ttc_header ) ) goto Exit; /* now read the offsets of each font in the file */ if ( FT_NEW_ARRAY( face->ttc_header.offsets, face->ttc_header.count ) || FT_FRAME_ENTER( face->ttc_header.count * 4L ) ) goto Exit; for ( n = 0; n < face->ttc_header.count; n++ ) face->ttc_header.offsets[n] = FT_GET_ULONG(); FT_FRAME_EXIT(); /* check face index */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -