📄 ttload.c
字号:
/******************************************************************* * * ttload.c 1.0 * * TrueType Tables Loader. * * Copyright 1996-1999 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 "tttypes.h"#include "ttdebug.h"#include "ttcalc.h"#include "ttfile.h"#include "tttables.h"#include "ttobjs.h"#include "ttmemory.h"#include "tttags.h"#include "ttload.h"/* required by the tracing mode */#undef TT_COMPONENT#define TT_COMPONENT trace_load/* In all functions, the stream is taken from the 'face' object */#define DEFINE_LOCALS DEFINE_LOAD_LOCALS( face->stream )#define DEFINE_LOCALS_WO_FRAME DEFINE_LOAD_LOCALS_WO_FRAME( face->stream )/******************************************************************* * * Function : LookUp_TrueType_Table * * Description : Looks for a TrueType table by name. * * Input : face face table to look for * tag searched tag * * Output : Index of table if found, -1 otherwise. * ******************************************************************/ EXPORT_FUNC Long TT_LookUp_Table( PFace face, ULong tag ) { UShort i; PTRACE4(( "TT_LookUp_Table( %08lx, %c%c%c%c )\n", (Long)face, (Char)(tag >> 24), (Char)(tag >> 16), (Char)(tag >> 8), (Char)(tag) )); for ( i = 0; i < face->numTables; i++ ) if ( face->dirTables[i].Tag == tag ) return i; PTRACE4(( " Could not find table!\n" )); return -1; }/******************************************************************* * * Function : Load_TrueType_Collection * * Description : Loads the TTC table directory into face table. * * Input : face face record to look for * * Output : Error code. * ******************************************************************/ static TT_Error Load_TrueType_Collection( PFace face ) { DEFINE_LOCALS; ULong n; PTRACE3(( "Load_TrueType_Collection( %08lx )\n", (long)face )); if ( FILE_Seek ( 0L ) || ACCESS_Frame( 12L ) ) return error; face->ttcHeader.Tag = GET_Tag4(); face->ttcHeader.version = GET_Long(); face->ttcHeader.DirCount = GET_Long(); FORGET_Frame(); if ( face->ttcHeader.Tag != TTAG_ttcf ) { face->ttcHeader.Tag = 0; face->ttcHeader.version = 0; face->ttcHeader.DirCount = 0; face->ttcHeader.TableDirectory = NULL; PTRACE3(("skipped.\n")); return TT_Err_File_Is_Not_Collection; } if ( ALLOC_ARRAY( face->ttcHeader.TableDirectory, face->ttcHeader.DirCount, ULong ) || ACCESS_Frame( face->ttcHeader.DirCount * 4L ) ) return error; for ( n = 0; n < face->ttcHeader.DirCount; n++ ) face->ttcHeader.TableDirectory[n] = GET_ULong(); FORGET_Frame(); PTRACE3(( "collections directory loaded.\n" )); return TT_Err_Ok; }/******************************************************************* * * Function : Load_TrueType_Directory * * Description : Loads the table directory into face table. * * Input : face face record to look for * * faceIndex the index of the TrueType font, when * we're opening a collection. * * Output : SUCCESS on success. FAILURE on error. * ******************************************************************/ LOCAL_FUNC TT_Error Load_TrueType_Directory( PFace face, ULong faceIndex ) { DEFINE_LOCALS; UShort n, limit; TTableDir tableDir; PTableDirEntry entry; PTRACE2(("Load_TT_Directory( %08lx, %ld )\n", (long)face, faceIndex)); error = Load_TrueType_Collection( face ); if ( error ) { if ( error != TT_Err_File_Is_Not_Collection ) return error; /* the file isn't a collection, exit if we're asking */ /* for a collected font */ if ( faceIndex != 0 ) return error; /* Now skip to the beginning of the file */ if ( FILE_Seek( 0L ) ) return error; } else { /* The file is a collection. Check the font index */ if ( faceIndex >= face->ttcHeader.DirCount ) return TT_Err_Invalid_Argument; /* select a TrueType font in the ttc file */ if ( FILE_Seek( face->ttcHeader.TableDirectory[faceIndex] ) ) return error; } if ( ACCESS_Frame( 12L ) ) return error; tableDir.version = GET_Long(); tableDir.numTables = GET_UShort(); tableDir.searchRange = GET_UShort(); tableDir.entrySelector = GET_UShort(); tableDir.rangeShift = GET_UShort(); FORGET_Frame(); PTRACE2(( "-- Tables count : %12u\n", tableDir.numTables )); PTRACE2(( "-- Format version : %08lx\n", tableDir.version )); /* Check that we have a 'sfnt' format there */ if ( tableDir.version != 0x00010000 && /* MS fonts */ tableDir.version != 0x74727565 && /* Mac fonts */ tableDir.version != 0x00000000 ) /* some Korean fonts */ { PERROR(( "!! invalid file format" )); return TT_Err_Invalid_File_Format; } face->numTables = tableDir.numTables; if ( ALLOC_ARRAY( face->dirTables, face->numTables, TTableDirEntry ) ) return error; if ( ACCESS_Frame( face->numTables * 16L ) ) return error; limit = face->numTables; entry = face->dirTables; for ( n = 0; n < limit; n++ ) { /* loop through the tables and get all entries */ entry->Tag = GET_Tag4(); entry->CheckSum = GET_ULong(); entry->Offset = GET_Long(); entry->Length = GET_Long(); PTRACE2(( " %c%c%c%c - %08lx - %08lx\n", (Char)(entry->Tag >> 24), (Char)(entry->Tag >> 16), (Char)(entry->Tag >> 8 ), (Char)(entry->Tag), entry->Offset, entry->Length )); entry++; } FORGET_Frame(); PTRACE2(( "Directory loaded\n\n" )); return TT_Err_Ok; }/******************************************************************* * * Function : Load_TrueType_MaxProfile * * Description : Loads the maxp table into face table. * * Input : face face table to look for * * Output : Error code. * ******************************************************************/ LOCAL_FUNC TT_Error Load_TrueType_MaxProfile( PFace face ) { DEFINE_LOCALS; Long i; PMaxProfile maxProfile = &face->maxProfile; PTRACE2(( "Load_TT_MaxProfile( %08lx )\n", (long)face )); if ( ( i = TT_LookUp_Table( face, TTAG_maxp ) ) < 0 ) return TT_Err_Max_Profile_Missing; if ( FILE_Seek( face->dirTables[i].Offset ) ) /* seek to maxprofile */ return error; if ( ACCESS_Frame( 32L ) ) /* read into frame */ return error; /* read frame data into face table */ maxProfile->version = GET_ULong(); maxProfile->numGlyphs = GET_UShort(); maxProfile->maxPoints = GET_UShort(); maxProfile->maxContours = GET_UShort(); maxProfile->maxCompositePoints = GET_UShort(); maxProfile->maxCompositeContours = GET_UShort(); maxProfile->maxZones = GET_UShort(); maxProfile->maxTwilightPoints = GET_UShort(); maxProfile->maxStorage = GET_UShort(); maxProfile->maxFunctionDefs = GET_UShort(); maxProfile->maxInstructionDefs = GET_UShort(); maxProfile->maxStackElements = GET_UShort(); maxProfile->maxSizeOfInstructions = GET_UShort(); maxProfile->maxComponentElements = GET_UShort(); maxProfile->maxComponentDepth = GET_UShort(); FORGET_Frame(); /* XXX : an adjustement that is necessary to load certain */ /* broken fonts like "Keystrokes MT" :-( */ /* */ /* We allocate 64 function entries by default when */ /* the maxFunctionDefs field is null. */ if (maxProfile->maxFunctionDefs == 0) maxProfile->maxFunctionDefs = 64; face->numGlyphs = maxProfile->numGlyphs; face->maxPoints = MAX( maxProfile->maxCompositePoints, maxProfile->maxPoints ); face->maxContours = MAX( maxProfile->maxCompositeContours, maxProfile->maxContours ); face->maxComponents = maxProfile->maxComponentElements + maxProfile->maxComponentDepth; /* XXX: Some fonts have maxComponents set to 0; we will */ /* then use 16 of them by default. */ if ( face->maxComponents == 0 ) face->maxComponents = 16; /* We also increase maxPoints and maxContours in order to support */ /* some broken fonts. */ face->maxPoints += 8; face->maxContours += 4; PTRACE2(( "GASP loaded.\n" )); return TT_Err_Ok; }/******************************************************************* * * Function : Load_TrueType_Gasp * * Description : Loads the TrueType Gasp table into the face * table. * * Input : face face table to look for * * Output : Error code. * ******************************************************************/ LOCAL_FUNC TT_Error Load_TrueType_Gasp( PFace face ) { DEFINE_LOCALS; Long i; UShort j; TGasp* gas; GaspRange* gaspranges; PTRACE2(( "Load_TT_Gasp( %08lx )\n", (long)face )); if ( ( i = TT_LookUp_Table( face, TTAG_gasp ) ) < 0 ) return TT_Err_Ok; /* gasp table is not required */ if ( FILE_Seek( face->dirTables[i].Offset ) || ACCESS_Frame( 4L ) ) return error; gas = &face->gasp; gas->version = GET_UShort(); gas->numRanges = GET_UShort(); FORGET_Frame(); PTRACE3(( "number of ranges = %d\n", gas->numRanges )); if ( ALLOC_ARRAY( gaspranges, gas->numRanges, GaspRange ) || ACCESS_Frame( gas->numRanges * 4L ) ) goto Fail; face->gasp.gaspRanges = gaspranges; for ( j = 0; j < gas->numRanges; j++ ) { gaspranges[j].maxPPEM = GET_UShort(); gaspranges[j].gaspFlag = GET_UShort(); PTRACE3(( " [max:%d flag:%d]", gaspranges[j].maxPPEM, gaspranges[j].gaspFlag )); } PTRACE3(("\n")); FORGET_Frame(); PTRACE2(( "GASP loaded\n" )); return TT_Err_Ok; Fail: FREE( gaspranges ); gas->numRanges = 0; return error; }/******************************************************************* * * Function : Load_TrueType_Header * * Description : Loads the TrueType header table into the face * table. * * Input : face face table to look for * * Output : Error code. * ******************************************************************/ LOCAL_FUNC TT_Error Load_TrueType_Header( PFace face ) { DEFINE_LOCALS; Long i; TT_Header* header; PTRACE2(( "Load_TT_Header( %08lx )\n", (long)face )); if ( ( i = TT_LookUp_Table( face, TTAG_head ) ) < 0 ) { PTRACE0(( "Font Header is missing !!\n" )); return TT_Err_Header_Table_Missing; } if ( FILE_Seek( face->dirTables[i].Offset ) || ACCESS_Frame( 54L ) ) return error; header = &face->fontHeader; header->Table_Version = GET_ULong(); header->Font_Revision = GET_ULong(); header->CheckSum_Adjust = GET_Long(); header->Magic_Number = GET_Long(); header->Flags = GET_UShort(); header->Units_Per_EM = GET_UShort(); header->Created [0] = GET_Long(); header->Created [1] = GET_Long(); header->Modified[0] = GET_Long(); header->Modified[1] = GET_Long(); header->xMin = GET_Short(); header->yMin = GET_Short(); header->xMax = GET_Short(); header->yMax = GET_Short(); header->Mac_Style = GET_UShort(); header->Lowest_Rec_PPEM = GET_UShort(); header->Font_Direction = GET_Short(); header->Index_To_Loc_Format = GET_Short(); header->Glyph_Data_Format = GET_Short(); FORGET_Frame(); PTRACE2(( " Units per EM : %8u\n", header->Units_Per_EM )); PTRACE2(( " IndexToLoc : %8d\n", header->Index_To_Loc_Format )); PTRACE2(( "Font Header Loaded.\n" )); return TT_Err_Ok; }/******************************************************************* * * Function : Load_TrueType_Metrics * * Description : Loads the horizontal or vertical metrics table * into face object. * * Input : face * vertical set to true when loading the vmtx table, * or false for hmtx * * Output : Error code. * ******************************************************************/ static TT_Error Load_TrueType_Metrics( PFace face, Bool vertical ) { DEFINE_LOCALS; Long n, num_shorts, num_shorts_checked, num_longs; PLongMetrics* longs; PShortMetrics* shorts; PLongMetrics long_metric; PTRACE2(( "Load_TT_%s_Metrics( %08lx )\n", vertical ? "Vertical" : "Horizontal", (long)face )); if ( vertical ) { /* The table is optional, quit silently if it wasn't found */ /* XXX : Some fonts have a valid vertical header with a non-null */ /* "number_of_VMetrics" fields, but no corresponding */ /* 'vmtx' table to get the metrics from (e.g. mingliu) */ /* */ /* For safety, we set the field to 0 ! */ /* */ n = TT_LookUp_Table( face, TTAG_vmtx );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -