📄 ftxopen.c
字号:
/******************************************************************* * * ftxopen.c * * TrueType Open common table support. * * 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/ftstream.h>#include <freetype/internal/ftmemory.h>#include <freetype/internal/tttypes.h>#include "fterrcompat.h"#include "ftxopen.h"#include "ftxopenf.h" /*************************** * Script related functions ***************************/ /* LangSys */ static FT_Error Load_LangSys( TTO_LangSys* ls, FT_Stream stream ) { FT_Error error; FT_Memory memory = stream->memory; FT_UShort n, count; FT_UShort* fi; if ( ACCESS_Frame( 6L ) ) return error; ls->LookupOrderOffset = GET_UShort(); /* should be 0 */ ls->ReqFeatureIndex = GET_UShort(); count = ls->FeatureCount = GET_UShort(); FORGET_Frame(); ls->FeatureIndex = NULL; if ( ALLOC_ARRAY( ls->FeatureIndex, count, FT_UShort ) ) return error; if ( ACCESS_Frame( count * 2L ) ) { FREE( ls->FeatureIndex ); return error; } fi = ls->FeatureIndex; for ( n = 0; n < count; n++ ) fi[n] = GET_UShort(); FORGET_Frame(); return TT_Err_Ok; } static void Free_LangSys( TTO_LangSys* ls, FT_Memory memory ) { FREE( ls->FeatureIndex ); } /* Script */ static FT_Error Load_Script( TTO_Script* s, FT_Stream stream ) { FT_Error error; FT_Memory memory = stream->memory; FT_UShort n, m, count; FT_ULong cur_offset, new_offset, base_offset; TTO_LangSysRecord* lsr; base_offset = FILE_Pos(); if ( ACCESS_Frame( 2L ) ) return error; new_offset = GET_UShort() + base_offset; FORGET_Frame(); if ( new_offset != base_offset ) /* not a NULL offset */ { cur_offset = FILE_Pos(); if ( FILE_Seek( new_offset ) || ( error = Load_LangSys( &s->DefaultLangSys, stream ) ) != TT_Err_Ok ) return error; (void)FILE_Seek( cur_offset ); } else { /* we create a DefaultLangSys table with no entries */ s->DefaultLangSys.LookupOrderOffset = 0; s->DefaultLangSys.ReqFeatureIndex = 0xFFFF; s->DefaultLangSys.FeatureCount = 0; s->DefaultLangSys.FeatureIndex = NULL; } if ( ACCESS_Frame( 2L ) ) goto Fail2; count = s->LangSysCount = GET_UShort(); /* safety check; otherwise the official handling of TrueType Open fonts won't work */ if ( s->LangSysCount == 0 && s->DefaultLangSys.FeatureCount == 0 ) { error = TTO_Err_Invalid_SubTable; goto Fail2; } FORGET_Frame(); s->LangSysRecord = NULL; if ( ALLOC_ARRAY( s->LangSysRecord, count, TTO_LangSysRecord ) ) goto Fail2; lsr = s->LangSysRecord; for ( n = 0; n < count; n++ ) { if ( ACCESS_Frame( 6L ) ) goto Fail1; lsr[n].LangSysTag = GET_ULong(); new_offset = GET_UShort() + base_offset; FORGET_Frame(); cur_offset = FILE_Pos(); if ( FILE_Seek( new_offset ) || ( error = Load_LangSys( &lsr[n].LangSys, stream ) ) != TT_Err_Ok ) goto Fail1; (void)FILE_Seek( cur_offset ); } return TT_Err_Ok; Fail1: for ( m = 0; m < n; m++ ) Free_LangSys( &lsr[m].LangSys, memory ); FREE( s->LangSysRecord ); Fail2: Free_LangSys( &s->DefaultLangSys, memory ); return error; } static void Free_Script( TTO_Script* s, FT_Memory memory ) { FT_UShort n, count; TTO_LangSysRecord* lsr; Free_LangSys( &s->DefaultLangSys, memory ); if ( s->LangSysRecord ) { count = s->LangSysCount; lsr = s->LangSysRecord; for ( n = 0; n < count; n++ ) Free_LangSys( &lsr[n].LangSys, memory ); FREE( lsr ); } } /* ScriptList */ FT_Error Load_ScriptList( TTO_ScriptList* sl, FT_Stream stream ) { FT_Error error; FT_Memory memory = stream->memory; FT_UShort n, m, count; FT_ULong cur_offset, new_offset, base_offset; TTO_ScriptRecord* sr; base_offset = FILE_Pos(); if ( ACCESS_Frame( 2L ) ) return error; count = sl->ScriptCount = GET_UShort(); FORGET_Frame(); sl->ScriptRecord = NULL; if ( ALLOC_ARRAY( sl->ScriptRecord, count, TTO_ScriptRecord ) ) return error; sr = sl->ScriptRecord; n = 0; for ( m = 0; m < count; m++ ) { if ( ACCESS_Frame( 6L ) ) goto Fail; sr[n].ScriptTag = GET_ULong(); new_offset = GET_UShort() + base_offset; FORGET_Frame(); cur_offset = FILE_Pos(); if ( (FILE_Seek( new_offset )) || ( error = Load_Script( &sr[n].Script, stream ) ) != TT_Err_Ok ) --sl->ScriptCount; else n++; (void)FILE_Seek( cur_offset ); } return TT_Err_Ok; Fail: for ( m = 0; m < n; m++ ) Free_Script( &sr[m].Script, memory ); FREE( sl->ScriptRecord ); return error; } void Free_ScriptList( TTO_ScriptList* sl, FT_Memory memory ) { FT_UShort n, count; TTO_ScriptRecord* sr; if ( sl->ScriptRecord ) { count = sl->ScriptCount; sr = sl->ScriptRecord; for ( n = 0; n < count; n++ ) Free_Script( &sr[n].Script, memory ); FREE( sr ); } } /********************************* * Feature List related functions *********************************/ /* Feature */ static FT_Error Load_Feature( TTO_Feature* f, FT_Stream stream ) { FT_Error error; FT_Memory memory = stream->memory; FT_UShort n, count; FT_UShort* lli; if ( ACCESS_Frame( 4L ) ) return error; f->FeatureParams = GET_UShort(); /* should be 0 */ count = f->LookupListCount = GET_UShort(); FORGET_Frame(); f->LookupListIndex = NULL; if ( ALLOC_ARRAY( f->LookupListIndex, count, FT_UShort ) ) return error; lli = f->LookupListIndex; if ( ACCESS_Frame( count * 2L ) ) { FREE( f->LookupListIndex ); return error; } for ( n = 0; n < count; n++ ) lli[n] = GET_UShort(); FORGET_Frame(); return TT_Err_Ok; } static void Free_Feature( TTO_Feature* f, FT_Memory memory ) { FREE( f->LookupListIndex ); } /* FeatureList */ FT_Error Load_FeatureList( TTO_FeatureList* fl, FT_Stream stream ) { FT_Error error; FT_Memory memory = stream->memory; FT_UShort n, m, count; FT_ULong cur_offset, new_offset, base_offset; TTO_FeatureRecord* fr; base_offset = FILE_Pos(); if ( ACCESS_Frame( 2L ) ) return error; count = fl->FeatureCount = GET_UShort(); FORGET_Frame(); fl->FeatureRecord = NULL; if ( ALLOC_ARRAY( fl->FeatureRecord, count, TTO_FeatureRecord ) ) return error; fr = fl->FeatureRecord; for ( n = 0; n < count; n++ ) { if ( ACCESS_Frame( 6L ) ) goto Fail; fr[n].FeatureTag = GET_ULong(); new_offset = GET_UShort() + base_offset; FORGET_Frame(); cur_offset = FILE_Pos(); if ( FILE_Seek( new_offset ) || ( error = Load_Feature( &fr[n].Feature, stream ) ) != TT_Err_Ok ) goto Fail; (void)FILE_Seek( cur_offset ); } return TT_Err_Ok; Fail: for ( m = 0; m < n; m++ ) Free_Feature( &fr[m].Feature, memory ); FREE( fl->FeatureRecord ); return error; } void Free_FeatureList( TTO_FeatureList* fl, FT_Memory memory) { FT_UShort n, count; TTO_FeatureRecord* fr; if ( fl->FeatureRecord ) { count = fl->FeatureCount; fr = fl->FeatureRecord; for ( n = 0; n < count; n++ ) Free_Feature( &fr[n].Feature, memory ); FREE( fr ); } } /******************************** * Lookup List related functions ********************************/ /* the subroutines of the following two functions are defined in ftxgsub.c and ftxgpos.c respectively */ /* SubTable */ static FT_Error Load_SubTable( TTO_SubTable* st, FT_Stream stream, TTO_Type table_type, FT_UShort lookup_type ) { if ( table_type == GSUB ) switch ( lookup_type ) { case GSUB_LOOKUP_SINGLE: return Load_SingleSubst( &st->st.gsub.single, stream ); case GSUB_LOOKUP_MULTIPLE: return Load_MultipleSubst( &st->st.gsub.multiple, stream ); case GSUB_LOOKUP_ALTERNATE: return Load_AlternateSubst( &st->st.gsub.alternate, stream ); case GSUB_LOOKUP_LIGATURE: return Load_LigatureSubst( &st->st.gsub.ligature, stream ); case GSUB_LOOKUP_CONTEXT: return Load_ContextSubst( &st->st.gsub.context, stream ); case GSUB_LOOKUP_CHAIN: return Load_ChainContextSubst( &st->st.gsub.chain, stream ); default: return TTO_Err_Invalid_GSUB_SubTable_Format; } else switch ( lookup_type ) { case GPOS_LOOKUP_SINGLE: return Load_SinglePos( &st->st.gpos.single, stream ); case GPOS_LOOKUP_PAIR: return Load_PairPos( &st->st.gpos.pair, stream ); case GPOS_LOOKUP_CURSIVE: return Load_CursivePos( &st->st.gpos.cursive, stream ); case GPOS_LOOKUP_MARKBASE: return Load_MarkBasePos( &st->st.gpos.markbase, stream ); case GPOS_LOOKUP_MARKLIG: return Load_MarkLigPos( &st->st.gpos.marklig, stream ); case GPOS_LOOKUP_MARKMARK: return Load_MarkMarkPos( &st->st.gpos.markmark, stream ); case GPOS_LOOKUP_CONTEXT: return Load_ContextPos( &st->st.gpos.context, stream ); case GPOS_LOOKUP_CHAIN: return Load_ChainContextPos( &st->st.gpos.chain, stream );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -