📄 ttload.c
字号:
* Input : face * * Output : Error code. * ******************************************************************/ LOCAL_FUNC TT_Error Load_TrueType_CMap( PFace face ) { DEFINE_LOCALS; Long off, table_start; Long n, limit; TCMapDir cmap_dir; TCMapDirEntry entry_; PCMapTable cmap; PTRACE2(( "CMaps " )); if ( ( n = TT_LookUp_Table( face, TTAG_cmap ) ) < 0 ) return TT_Err_CMap_Table_Missing; table_start = face->dirTables[n].Offset; if ( ( FILE_Seek( table_start ) ) || ( ACCESS_Frame( 4L ) ) ) /* 4 bytes cmap header */ return error; cmap_dir.tableVersionNumber = GET_UShort(); cmap_dir.numCMaps = GET_UShort(); FORGET_Frame(); off = FILE_Pos(); /* save offset to cmapdir[] which follows */ /* save space in face table for cmap tables */ if ( ALLOC_ARRAY( face->cMaps, cmap_dir.numCMaps, TCMapTable ) ) return error; face->numCMaps = cmap_dir.numCMaps; limit = face->numCMaps; cmap = face->cMaps; for ( n = 0; n < limit; n++ ) { if ( FILE_Seek( off ) || ACCESS_Frame( 8L ) ) return error; /* extra code using entry_ for platxxx could be cleaned up later */ cmap->loaded = FALSE; cmap->platformID = entry_.platformID = GET_UShort(); cmap->platformEncodingID = entry_.platformEncodingID = GET_UShort(); entry_.offset = GET_Long(); FORGET_Frame(); off = FILE_Pos(); if ( FILE_Seek( table_start + entry_.offset ) || ACCESS_Frame( 6L ) ) return error; cmap->format = GET_UShort(); cmap->length = GET_UShort(); cmap->version = GET_UShort(); FORGET_Frame(); cmap->offset = FILE_Pos(); cmap++; } PTRACE2(( "loaded\n" )); return TT_Err_Ok; }/******************************************************************* * * Function : Load_TrueType_Programs * * Description : Loads the font (fpgm) and cvt programs into the * face table. * * Input : face * * Output : Error code. * ******************************************************************/ LOCAL_FUNC TT_Error Load_TrueType_Programs( PFace face ) { DEFINE_LOCALS_WO_FRAME; Long n; PTRACE2(( "Font program " )); /* The font program is optional */ if ( ( n = TT_LookUp_Table( face, TTAG_fpgm ) ) < 0 ) { face->fontProgram = NULL; face->fontPgmSize = 0; PTRACE2(( "is missing!\n" )); } else { face->fontPgmSize = face->dirTables[n].Length; if ( ALLOC( face->fontProgram, face->fontPgmSize ) || FILE_Read_At( face->dirTables[n].Offset, (void*)face->fontProgram, face->fontPgmSize ) ) return error; PTRACE2(( "loaded, %12d bytes\n", face->fontPgmSize )); } PTRACE2(( "Prep program " )); if ( ( n = TT_LookUp_Table( face, TTAG_prep ) ) < 0 ) { face->cvtProgram = NULL; face->cvtPgmSize = 0; PTRACE2(( "is missing!\n" )); } else { face->cvtPgmSize = face->dirTables[n].Length; if ( ALLOC( face->cvtProgram, face->cvtPgmSize ) || FILE_Read_At( face->dirTables[n].Offset, (void*)face->cvtProgram, face->cvtPgmSize ) ) return error; PTRACE2(( "loaded, %12d bytes\n", face->cvtPgmSize )); } return TT_Err_Ok; }/******************************************************************* * * Function : Load_TrueType_OS2 * * Description : Loads the OS2 Table. * * Input : face * * Output : Error code. * ******************************************************************/ LOCAL_FUNC TT_Error Load_TrueType_OS2( PFace face ) { DEFINE_LOCALS; Long i; TT_OS2* os2; PTRACE2(( "OS/2 Table " )); /* We now support old Mac fonts where the OS/2 table doesn't */ /* exist. Simply put, we set the `version' field to 0xFFFF */ /* and test this value each time we need to access the table. */ if ( ( i = TT_LookUp_Table( face, TTAG_OS2 ) ) < 0 ) { PTRACE2(( "is missing\n!" )); face->os2.version = 0xFFFF; error = TT_Err_Ok; return TT_Err_Ok; } if ( FILE_Seek( face->dirTables[i].Offset ) || ACCESS_Frame( 78L ) ) return error; os2 = &face->os2; os2->version = GET_UShort(); os2->xAvgCharWidth = GET_Short(); os2->usWeightClass = GET_UShort(); os2->usWidthClass = GET_UShort(); os2->fsType = GET_Short(); os2->ySubscriptXSize = GET_Short(); os2->ySubscriptYSize = GET_Short(); os2->ySubscriptXOffset = GET_Short(); os2->ySubscriptYOffset = GET_Short(); os2->ySuperscriptXSize = GET_Short(); os2->ySuperscriptYSize = GET_Short(); os2->ySuperscriptXOffset = GET_Short(); os2->ySuperscriptYOffset = GET_Short(); os2->yStrikeoutSize = GET_Short(); os2->yStrikeoutPosition = GET_Short(); os2->sFamilyClass = GET_Short(); for ( i = 0; i < 10; i++ ) os2->panose[i] = GET_Byte(); os2->ulUnicodeRange1 = GET_ULong(); os2->ulUnicodeRange2 = GET_ULong(); os2->ulUnicodeRange3 = GET_ULong(); os2->ulUnicodeRange4 = GET_ULong(); for ( i = 0; i < 4; i++ ) os2->achVendID[i] = GET_Byte(); os2->fsSelection = GET_UShort(); os2->usFirstCharIndex = GET_UShort(); os2->usLastCharIndex = GET_UShort(); os2->sTypoAscender = GET_Short(); os2->sTypoDescender = GET_Short(); os2->sTypoLineGap = GET_Short(); os2->usWinAscent = GET_UShort(); os2->usWinDescent = GET_UShort(); FORGET_Frame(); if ( os2->version >= 0x0001 ) { /* only version 1 tables */ if ( ACCESS_Frame( 8L ) ) /* read into frame */ return error; os2->ulCodePageRange1 = GET_ULong(); os2->ulCodePageRange2 = GET_ULong(); FORGET_Frame(); } else { os2->ulCodePageRange1 = 0; os2->ulCodePageRange2 = 0; } PTRACE2(( "loaded\n" )); return TT_Err_Ok; }/******************************************************************* * * Function : Load_TrueType_PostScript * * Description : Loads the post table into face table. * * Input : face face table to look for * * Output : SUCCESS on success. FAILURE on error. * ******************************************************************/ LOCAL_FUNC TT_Error Load_TrueType_PostScript( PFace face ) { DEFINE_LOCALS; Long i; TT_Postscript* post = &face->postscript; PTRACE2(( "PostScript " )); if ( ( i = TT_LookUp_Table( face, TTAG_post ) ) < 0 ) return TT_Err_Post_Table_Missing; if ( FILE_Seek( face->dirTables[i].Offset ) || ACCESS_Frame( 32L ) ) return error; /* read frame data into face table */ post->FormatType = GET_ULong(); post->italicAngle = GET_ULong(); post->underlinePosition = GET_Short(); post->underlineThickness = GET_Short(); post->isFixedPitch = GET_ULong(); post->minMemType42 = GET_ULong(); post->maxMemType42 = GET_ULong(); post->minMemType1 = GET_ULong(); post->maxMemType1 = GET_ULong(); FORGET_Frame(); /* we don't load the glyph names, we do that in a */ /* library extension (ftxpost). */ PTRACE2(( "loaded\n" )); return TT_Err_Ok; }/******************************************************************* * * Function : Load_TrueType_Hdmx * * Description : Loads the horizontal device metrics table. * * Input : face face object to look for * * Output : SUCCESS on success. FAILURE on error. * ******************************************************************/ LOCAL_FUNC TT_Error Load_TrueType_Hdmx( PFace face ) { DEFINE_LOCALS; TT_Hdmx_Record* rec; TT_Hdmx hdmx; Long table; UShort n, num_glyphs; Long record_size; hdmx.version = 0; hdmx.num_records = 0; hdmx.records = 0; face->hdmx = hdmx; if ( ( table = TT_LookUp_Table( face, TTAG_hdmx ) ) < 0 ) return TT_Err_Ok; if ( FILE_Seek( face->dirTables[table].Offset ) || ACCESS_Frame( 8L ) ) return error; hdmx.version = GET_UShort(); hdmx.num_records = GET_Short(); record_size = GET_Long(); FORGET_Frame(); /* Only recognize format 0 */ if ( hdmx.version != 0 ) return TT_Err_Ok; if ( ALLOC( hdmx.records, sizeof ( TT_Hdmx_Record ) * hdmx.num_records ) ) return error; num_glyphs = face->numGlyphs; record_size -= num_glyphs+2; rec = hdmx.records; for ( n = 0; n < hdmx.num_records; n++ ) { /* read record */ if ( ACCESS_Frame( 2L ) ) goto Fail; rec->ppem = GET_Byte(); rec->max_width = GET_Byte(); FORGET_Frame(); if ( ALLOC( rec->widths, num_glyphs ) || FILE_Read( rec->widths, num_glyphs ) ) goto Fail; /* skip padding bytes */ if ( record_size > 0 ) if ( FILE_Skip( record_size ) ) goto Fail; rec++; } face->hdmx = hdmx; return TT_Err_Ok; Fail: for ( n = 0; n < hdmx.num_records; n++ ) FREE( hdmx.records[n].widths ); FREE( hdmx.records ); return error; }/******************************************************************* * * Function : Free_TrueType_Hdmx * * Description : Frees the horizontal device metrics table. * * Input : face face object to look for * * Output : TT_Err_Ok. * ******************************************************************/ LOCAL_FUNC TT_Error Free_TrueType_Hdmx( PFace face ) { UShort n; if ( !face ) return TT_Err_Ok; for ( n = 0; n < face->hdmx.num_records; n++ ) FREE( face->hdmx.records[n].widths ); FREE( face->hdmx.records ); face->hdmx.num_records = 0; return TT_Err_Ok; }/******************************************************************* * * Function : Load_TrueType_Any * * Description : Loads any font table into client memory. Used by * the TT_Get_Font_Data() API function. * * Input : face face object to look for * * tag tag of table to load. Use the value 0 if you * want to access the whole font file, else set * this parameter to a valid TrueType table tag * that you can forge with the MAKE_TT_TAG * macro. * * offset starting offset in the table (or the file * if tag == 0 ) * * buffer address of target buffer * * length address of decision variable : * * if length == NULL : * load the whole table. returns an * an error if 'offset' == 0 !! * * if *length == 0 : * exit immediately, returning the * length of the given table, or of * the font file, depending on the * value of 'tag' * * if *length != 0 : * load the next 'length' bytes of * table or font, starting at offset * 'offset' (in table or font too). * * Output : Error condition * ******************************************************************/ LOCAL_FUNC TT_Error Load_TrueType_Any( PFace face, ULong tag, Long offset, void* buffer, Long* length ) { TT_Stream stream; TT_Error error; Long table; ULong size; if ( tag != 0 ) { /* look for tag in font directory */ table = TT_LookUp_Table( face, tag ); if ( table < 0 ) return TT_Err_Table_Missing; offset += face->dirTables[table].Offset; size = face->dirTables[table].Length; } else /* tag = 0 -- the use want to access the font file directly */ size = TT_Stream_Size( face->stream ); if ( length && *length == 0 ) { *length = size; return TT_Err_Ok; } if ( length ) size = *length; if ( !USE_Stream( face->stream, stream ) ) (void)FILE_Read_At( offset, buffer, size ); DONE_Stream( stream ); return error; }/* END */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -