📄 ttload.c
字号:
/***************************************************************************//* *//* ttload.c *//* *//* Load the basic TrueType tables, i.e., tables that can be either in *//* TTF or OTF fonts (body). *//* *//* 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. *//* *//***************************************************************************/#include <freetype/internal/ftdebug.h>#include <freetype/internal/tterrors.h>#include <freetype/internal/ftstream.h>#include <freetype/tttags.h>#ifdef FT_FLAT_COMPILE#include "ttload.h"#include "ttcmap.h"#else#include <sfnt/ttload.h>#include <sfnt/ttcmap.h>#endif /*************************************************************************/ /* */ /* 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_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_LookUp_Table( TT_Face face, FT_ULong tag ) { TT_Table* entry; TT_Table* limit; FT_TRACE3(( "TT_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++ ) { if ( entry->Tag == tag ) { FT_TRACE3(( "found table.\n" )); return entry; } } FT_TRACE3(( "could not find table!\n" )); return 0; } /*************************************************************************/ /* */ /* <Function> */ /* TT_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_Goto_Table( TT_Face face, FT_ULong tag, FT_Stream stream, FT_ULong* length ) { TT_Table* table; FT_Error error; table = TT_LookUp_Table( face, tag ); if ( table ) { if ( length ) *length = table->Length; if ( FILE_Seek( table->Offset ) ) goto Exit; } else error = TT_Err_Table_Missing; Exit: return error; } /*************************************************************************/ /* */ /* <Function> */ /* TT_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_Load_SFNT_Header( TT_Face face, FT_Stream stream, FT_Long face_index, SFNT_Header* sfnt ) { FT_Error error; FT_ULong format_tag; FT_Memory memory = stream->memory; const FT_Frame_Field sfnt_header_fields[] = {#undef FT_STRUCTURE#define FT_STRUCTURE SFNT_Header 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 }; const FT_Frame_Field ttc_header_fields[] = {#undef FT_STRUCTURE#define FT_STRUCTURE TTC_Header FT_FRAME_START( 8 ), FT_FRAME_LONG( version ), FT_FRAME_LONG( count ), FT_FRAME_END }; FT_TRACE2(( "TT_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. */ if ( READ_ULong( format_tag ) ) goto Exit; if ( format_tag == TTAG_ttcf ) { FT_Int n; FT_TRACE3(( "TT_Load_SFNT_Header: file is a collection\n" )); /* it's a TrueType collection, i.e. a file containing several */ /* font files. Read the font directory now */ if ( READ_Fields( ttc_header_fields, &face->ttc_header ) ) goto Exit; /* now read the offsets of each font in the file */ if ( ALLOC_ARRAY( face->ttc_header.offsets, face->ttc_header.count, FT_ULong ) || ACCESS_Frame( face->ttc_header.count * 4L ) ) goto Exit; for ( n = 0; n < face->ttc_header.count; n++ ) face->ttc_header.offsets[n] = GET_ULong(); FORGET_Frame(); /* check face index */ if ( face_index >= face->ttc_header.count ) { error = TT_Err_Bad_Argument; goto Exit; } /* seek to the appropriate TrueType file, then read tag */ if ( FILE_Seek( face->ttc_header.offsets[face_index] ) || READ_Long( format_tag ) ) goto Exit; } /* the format tag was read, now check the rest of the header */ sfnt->format_tag = format_tag; if ( READ_Fields( sfnt_header_fields, sfnt ) ) goto Exit; /* now, check the values of `num_tables', `seach_range', etc. */ { FT_UInt num_tables = sfnt->num_tables; FT_ULong entry_selector = 1L << sfnt->entry_selector; /* IMPORTANT: Many fonts have an incorrect `search_range' value, so */ /* we only check the `entry_selector' correctness here. */ /* */ if ( num_tables == 0 || entry_selector > num_tables || entry_selector * 2 <= num_tables ) { FT_TRACE2(( "TT_Load_SFNT_Header: file is not SFNT!\n" )); error = FT_Err_Unknown_File_Format; } } Exit: return error; } /*************************************************************************/ /* */ /* <Function> */ /* TT_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_Load_Directory( TT_Face face, FT_Stream stream, SFNT_Header* sfnt ) { FT_Error error; FT_Memory memory = stream->memory; TT_Table *entry, *limit; FT_TRACE2(( "TT_Load_Directory: %08p\n", face )); FT_TRACE2(( "-- Tables count: %12u\n", sfnt->num_tables )); FT_TRACE2(( "-- Format version: %08lx\n", sfnt->format_tag )); face->num_tables = sfnt->num_tables; if ( ALLOC_ARRAY( face->dir_tables, face->num_tables, TT_Table ) ) goto Exit; if ( ACCESS_Frame( face->num_tables * 16L ) ) goto Exit; entry = face->dir_tables; limit = entry + face->num_tables; for ( ; entry < limit; entry++ ) { /* loop through the tables and get all entries */ entry->Tag = GET_Tag4(); entry->CheckSum = GET_ULong(); entry->Offset = GET_Long(); entry->Length = GET_Long(); FT_TRACE2(( " %c%c%c%c - %08lx - %08lx\n", (FT_Char)( entry->Tag >> 24 ), (FT_Char)( entry->Tag >> 16 ), (FT_Char)( entry->Tag >> 8 ), (FT_Char)( entry->Tag ), entry->Offset, entry->Length )); } FORGET_Frame();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -