📄 t2load.c
字号:
/***************************************************************************//* *//* t2load.c *//* *//* TrueType glyph data/program tables loader (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/ftobjs.h>#include <freetype/internal/ftstream.h>#include <freetype/internal/psnames.h>#include <freetype/internal/t2errors.h>#include <freetype/tttags.h>#ifdef FT_FLAT_COMPILE#include "t2load.h"#include "t2parse.h"#else#include <cff/t2load.h>#include <cff/t2parse.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_t2load /* read a CFF offset from memory */ static FT_ULong t2_get_offset( FT_Byte* p, FT_Byte off_size ) { FT_ULong result; for ( result = 0; off_size > 0; off_size-- ) { result <<= 8; result |= *p++; } return result; } static FT_Error t2_new_cff_index( CFF_Index* index, FT_Stream stream, FT_Bool load ) { FT_Error error; FT_Memory memory = stream->memory; FT_UShort count; MEM_Set( index, 0, sizeof ( *index ) ); index->stream = stream; if ( !READ_UShort( count ) && count > 0 ) { FT_Byte* p; FT_Byte offsize; FT_ULong data_size; FT_ULong* poff; /* there is at least one element; read the offset size, */ /* then access the offset table to compute the index's total size */ if ( READ_Byte( offsize ) ) goto Exit; index->stream = stream; index->count = count; index->off_size = offsize; data_size = (FT_ULong)( count + 1 ) * offsize; if ( ALLOC_ARRAY( index->offsets, count + 1, FT_ULong ) || ACCESS_Frame( data_size ) ) goto Exit; poff = index->offsets; p = (FT_Byte*)stream->cursor; for ( ; (FT_Short)count >= 0; count-- ) { poff[0] = t2_get_offset( p, offsize ); poff++; p += offsize; } FORGET_Frame(); index->data_offset = FILE_Pos(); data_size = poff[-1] - 1; if ( load ) { /* load the data */ if ( EXTRACT_Frame( data_size, index->bytes ) ) goto Exit; } else { /* skip the data */ if ( FILE_Skip( data_size ) ) goto Exit; } } Exit: if ( error ) FREE( index->offsets ); return error; } static void t2_done_cff_index( CFF_Index* index ) { if ( index->stream ) { FT_Stream stream = index->stream; FT_Memory memory = stream->memory; if ( index->bytes ) RELEASE_Frame( index->bytes ); FREE( index->offsets ); MEM_Set( index, 0, sizeof ( *index ) ); } } static FT_Error t2_explicit_cff_index( CFF_Index* index, FT_Byte*** table ) { FT_Error error = 0; FT_Memory memory = index->stream->memory; FT_UInt n, offset, old_offset; FT_Byte** t; *table = 0; if ( index->count > 0 && !ALLOC_ARRAY( t, index->count + 1, FT_Byte* ) ) { old_offset = 1; for ( n = 0; n <= index->count; n++ ) { offset = index->offsets[n]; if ( !offset ) offset = old_offset; t[n] = index->bytes + offset - 1; old_offset = offset; } *table = t; } return error; } FT_LOCAL_DEF FT_Error T2_Access_Element( CFF_Index* index, FT_UInt element, FT_Byte** pbytes, FT_ULong* pbyte_len ) { FT_Error error = 0; if ( index && index->count > element ) { /* compute start and end offsets */ FT_ULong off1, off2 = 0; off1 = index->offsets[element]; if ( off1 ) { do { element++; off2 = index->offsets[element]; } while ( off2 == 0 && element < index->count ); if ( !off2 ) off1 = 0; } /* access element */ if ( off1 ) { *pbyte_len = off2 - off1; if ( index->bytes ) { /* this index was completely loaded in memory, that's easy */ *pbytes = index->bytes + off1 - 1; } else { /* this index is still on disk/file, access it through a frame */ FT_Stream stream = index->stream; if ( FILE_Seek( index->data_offset + off1 - 1 ) || EXTRACT_Frame( off2 - off1, *pbytes ) ) goto Exit; } } else { /* empty index element */ *pbytes = 0; *pbyte_len = 0; } } else error = T2_Err_Invalid_Argument; Exit: return error; } FT_LOCAL_DEF void T2_Forget_Element( CFF_Index* index, FT_Byte** pbytes ) { if ( index->bytes == 0 ) { FT_Stream stream = index->stream; RELEASE_Frame( *pbytes ); } } FT_LOCAL_DEF FT_String* T2_Get_Name( CFF_Index* index, FT_UInt element ) { FT_Memory memory = index->stream->memory; FT_Byte* bytes; FT_ULong byte_len; FT_Error error; FT_String* name = 0; error = T2_Access_Element( index, element, &bytes, &byte_len ); if ( error ) goto Exit; if ( !ALLOC( name, byte_len + 1 ) ) { MEM_Copy( name, bytes, byte_len ); name[byte_len] = 0; } T2_Forget_Element( index, &bytes ); Exit: return name; } FT_LOCAL_DEF FT_String* T2_Get_String( CFF_Index* index, FT_UInt sid, PSNames_Interface* interface ) { /* if it is not a standard string, return it */ if ( sid > 390 ) return T2_Get_Name( index, sid - 391 ); /* that's a standard string, fetch a copy from the PSName module */ { FT_String* name = 0; const char* adobe_name = interface->adobe_std_strings( sid ); FT_UInt len; if ( adobe_name ) { FT_Memory memory = index->stream->memory; FT_Error error; len = (FT_UInt)strlen( adobe_name ); if ( !ALLOC( name, len + 1 ) ) { MEM_Copy( name, adobe_name, len ); name[len] = 0; } } return name; } } /*************************************************************************/ /*************************************************************************/ /*** ***/ /*** FD Select table support ***/ /*** ***/ /*************************************************************************/ /*************************************************************************/ static void CFF_Done_FD_Select( CFF_FD_Select* select, FT_Stream stream ) { if ( select->data ) RELEASE_Frame( select->data ); select->data_size = 0; select->format = 0; select->range_count = 0; } static FT_Error CFF_Load_FD_Select( CFF_FD_Select* select, FT_UInt num_glyphs, FT_Stream stream, FT_ULong offset ) { FT_Error error; FT_Byte format; FT_UInt num_ranges; /* read format */ if ( FILE_Seek( offset ) || READ_Byte( format ) ) goto Exit; select->format = format; select->cache_count = 0; /* clear cache */ switch ( format ) { case 0: /* format 0, that's simple */ select->data_size = num_glyphs; goto Load_Data; case 3: /* format 3, a tad more complex */ if ( READ_UShort( num_ranges ) ) goto Exit;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -