📄 harfbuzz-open.c
字号:
/******************************************************************* * * Copyright 1996-2000 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * Copyright 2006 Behdad Esfahbod * * This is part of HarfBuzz, an OpenType Layout engine library. * * See the file name COPYING for licensing information. * ******************************************************************/#include "harfbuzz-impl.h"#include "harfbuzz-open-private.h"/*************************** * Script related functions ***************************//* LangSys */static FT_Error Load_LangSys( HB_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 FT_Err_Ok;}static void Free_LangSys( HB_LangSys* ls, FT_Memory memory ){ FREE( ls->FeatureIndex );}/* Script */static FT_Error Load_Script( HB_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; HB_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 ) ) != FT_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 = HB_Err_Empty_Script; goto Fail2; } FORGET_Frame(); s->LangSysRecord = NULL; if ( ALLOC_ARRAY( s->LangSysRecord, count, HB_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 ) ) != FT_Err_Ok ) goto Fail1; (void)FILE_Seek( cur_offset ); } return FT_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( HB_Script* s, FT_Memory memory ){ FT_UShort n, count; HB_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 _HB_OPEN_Load_ScriptList( HB_ScriptList* sl, FT_Stream stream ){ FT_Error error; FT_Memory memory = stream->memory; FT_UShort n, script_count; FT_ULong cur_offset, new_offset, base_offset; HB_ScriptRecord* sr; base_offset = FILE_Pos(); if ( ACCESS_Frame( 2L ) ) return error; script_count = GET_UShort(); FORGET_Frame(); sl->ScriptRecord = NULL; if ( ALLOC_ARRAY( sl->ScriptRecord, script_count, HB_ScriptRecord ) ) return error; sr = sl->ScriptRecord; sl->ScriptCount= 0; for ( n = 0; n < script_count; n++ ) { if ( ACCESS_Frame( 6L ) ) goto Fail; sr[sl->ScriptCount].ScriptTag = GET_ULong(); new_offset = GET_UShort() + base_offset; FORGET_Frame(); cur_offset = FILE_Pos(); if ( FILE_Seek( new_offset ) ) goto Fail; error = Load_Script( &sr[sl->ScriptCount].Script, stream ); if ( error == FT_Err_Ok ) sl->ScriptCount += 1; else if ( error != HB_Err_Empty_Script ) goto Fail; (void)FILE_Seek( cur_offset ); } /* Empty tables are harmless and generated by fontforge. * See http://bugzilla.gnome.org/show_bug.cgi?id=347073 */#if 0 if ( sl->ScriptCount == 0 ) { error = HB_Err_Invalid_SubTable; goto Fail; }#endif return FT_Err_Ok;Fail: for ( n = 0; n < sl->ScriptCount; n++ ) Free_Script( &sr[n].Script, memory ); FREE( sl->ScriptRecord ); return error;}void _HB_OPEN_Free_ScriptList( HB_ScriptList* sl, FT_Memory memory ){ FT_UShort n, count; HB_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( HB_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 FT_Err_Ok;}static void Free_Feature( HB_Feature* f, FT_Memory memory ){ FREE( f->LookupListIndex );}/* FeatureList */FT_Error _HB_OPEN_Load_FeatureList( HB_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; HB_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, HB_FeatureRecord ) ) return error; if ( ALLOC_ARRAY( fl->ApplyOrder, count, FT_UShort ) ) goto Fail2; fl->ApplyCount = 0; fr = fl->FeatureRecord; for ( n = 0; n < count; n++ ) { if ( ACCESS_Frame( 6L ) ) goto Fail1; 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 ) ) != FT_Err_Ok ) goto Fail1; (void)FILE_Seek( cur_offset ); } return FT_Err_Ok;Fail1: for ( m = 0; m < n; m++ ) Free_Feature( &fr[m].Feature, memory ); FREE( fl->ApplyOrder );Fail2: FREE( fl->FeatureRecord ); return error;}void _HB_OPEN_Free_FeatureList( HB_FeatureList* fl, FT_Memory memory){ FT_UShort n, count; HB_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 ); } FREE( fl->ApplyOrder );}/******************************** * 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( HB_SubTable* st, FT_Stream stream, HB_Type table_type, FT_UShort lookup_type ){ if ( table_type == HB_Type_GSUB ) return _HB_GSUB_Load_SubTable ( &st->st.gsub, stream, lookup_type ); else return _HB_GPOS_Load_SubTable ( &st->st.gpos, stream, lookup_type );}static void Free_SubTable( HB_SubTable* st, HB_Type table_type, FT_UShort lookup_type, FT_Memory memory ){ if ( table_type == HB_Type_GSUB ) _HB_GSUB_Free_SubTable ( &st->st.gsub, memory, lookup_type ); else _HB_GPOS_Free_SubTable ( &st->st.gpos, memory, lookup_type );}/* Lookup */static FT_Error Load_Lookup( HB_Lookup* l, FT_Stream stream, HB_Type type ){ FT_Error error; FT_Memory memory = stream->memory; FT_UShort n, m, count; FT_ULong cur_offset, new_offset, base_offset; HB_SubTable* st; FT_Bool is_extension = FALSE; base_offset = FILE_Pos(); if ( ACCESS_Frame( 6L ) ) return error; l->LookupType = GET_UShort(); l->LookupFlag = GET_UShort(); count = l->SubTableCount = GET_UShort(); FORGET_Frame(); l->SubTable = NULL; if ( ALLOC_ARRAY( l->SubTable, count, HB_SubTable ) ) return error; st = l->SubTable; if ( ( type == HB_Type_GSUB && l->LookupType == HB_GSUB_LOOKUP_EXTENSION ) || ( type == HB_Type_GPOS && l->LookupType == HB_GPOS_LOOKUP_EXTENSION ) ) is_extension = TRUE; for ( n = 0; n < count; n++ ) { if ( ACCESS_Frame( 2L ) ) goto Fail; new_offset = GET_UShort() + base_offset; FORGET_Frame(); cur_offset = FILE_Pos(); if ( is_extension ) { if ( FILE_Seek( new_offset ) || ACCESS_Frame( 8L ) ) goto Fail; if (GET_UShort() != 1) /* format should be 1 */ goto Fail; l->LookupType = GET_UShort(); new_offset += GET_ULong(); FORGET_Frame(); } if ( FILE_Seek( new_offset ) || ( error = Load_SubTable( &st[n], stream, type, l->LookupType ) ) != FT_Err_Ok ) goto Fail; (void)FILE_Seek( cur_offset ); } return FT_Err_Ok;Fail: for ( m = 0; m < n; m++ ) Free_SubTable( &st[m], type, l->LookupType, memory ); FREE( l->SubTable ); return error;}static void Free_Lookup( HB_Lookup* l, HB_Type type, FT_Memory memory){ FT_UShort n, count; HB_SubTable* st; if ( l->SubTable ) { count = l->SubTableCount; st = l->SubTable; for ( n = 0; n < count; n++ ) Free_SubTable( &st[n], type, l->LookupType, memory ); FREE( st ); }}/* LookupList */FT_Error _HB_OPEN_Load_LookupList( HB_LookupList* ll, FT_Stream stream, HB_Type type ){ FT_Error error; FT_Memory memory = stream->memory; FT_UShort n, m, count; FT_ULong cur_offset, new_offset, base_offset; HB_Lookup* l; base_offset = FILE_Pos(); if ( ACCESS_Frame( 2L ) ) return error; count = ll->LookupCount = GET_UShort(); FORGET_Frame(); ll->Lookup = NULL; if ( ALLOC_ARRAY( ll->Lookup, count, HB_Lookup ) ) return error; if ( ALLOC_ARRAY( ll->Properties, count, FT_UInt ) ) goto Fail2; l = ll->Lookup; for ( n = 0; n < count; n++ ) { if ( ACCESS_Frame( 2L ) ) goto Fail1; new_offset = GET_UShort() + base_offset; FORGET_Frame(); cur_offset = FILE_Pos(); if ( FILE_Seek( new_offset ) || ( error = Load_Lookup( &l[n], stream, type ) ) != FT_Err_Ok ) goto Fail1; (void)FILE_Seek( cur_offset ); } return FT_Err_Ok;Fail1: FREE( ll->Properties ); for ( m = 0; m < n; m++ ) Free_Lookup( &l[m], type, memory );Fail2: FREE( ll->Lookup ); return error;}void _HB_OPEN_Free_LookupList( HB_LookupList* ll, HB_Type type, FT_Memory memory ){ FT_UShort n, count; HB_Lookup* l; FREE( ll->Properties ); if ( ll->Lookup ) { count = ll->LookupCount; l = ll->Lookup; for ( n = 0; n < count; n++ ) Free_Lookup( &l[n], type, memory ); FREE( l ); }}/***************************** * Coverage related functions *****************************//* CoverageFormat1 */static FT_Error Load_Coverage1( HB_CoverageFormat1* cf1, FT_Stream stream ){ FT_Error error; FT_Memory memory = stream->memory; FT_UShort n, count; FT_UShort* ga; if ( ACCESS_Frame( 2L ) ) return error; count = cf1->GlyphCount = GET_UShort(); FORGET_Frame(); cf1->GlyphArray = NULL; if ( ALLOC_ARRAY( cf1->GlyphArray, count, FT_UShort ) ) return error; ga = cf1->GlyphArray; if ( ACCESS_Frame( count * 2L ) ) { FREE( cf1->GlyphArray ); return error; } for ( n = 0; n < count; n++ ) ga[n] = GET_UShort(); FORGET_Frame(); return FT_Err_Ok;}static void Free_Coverage1( HB_CoverageFormat1* cf1, FT_Memory memory){ FREE( cf1->GlyphArray );}/* CoverageFormat2 */static FT_Error Load_Coverage2( HB_CoverageFormat2* cf2, FT_Stream stream )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -