From f42d5eca291dcdfb27d7fbf88391d6d381b8e9c4 Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Tue, 27 Jul 2004 17:20:01 +0000 Subject: [PATCH] Save the order in which features were added and use that when applying Tue Jul 27 12:38:05 2004 Owen Taylor * pango/opentype/ftxopen.[ch] pango/opentype/ftxgsub.c pango/opentype/ftxpos.c: Save the order in which features were added and use that when applying features. (Patch from Soheil Hassas Yeganeh, #122330) --- src/ftxgpos.c | 41 ++++++++++++++++++++++++----------------- src/ftxgsub.c | 34 +++++++++++++++++++++------------- src/ftxopen.c | 14 +++++++++++--- src/ftxopen.h | 2 ++ 4 files changed, 58 insertions(+), 33 deletions(-) diff --git a/src/ftxgpos.c b/src/ftxgpos.c index 065173259..c92dfead1 100644 --- a/src/ftxgpos.c +++ b/src/ftxgpos.c @@ -6055,11 +6055,15 @@ FT_UShort* properties; FT_UShort* index; - + /* Each feature can only be added once once */ + if ( !gpos || - feature_index >= gpos->FeatureList.FeatureCount ) + feature_index >= gpos->FeatureList.FeatureCount || + gpos->FeatureList.ApplyCount == gpos->FeatureList.FeatureCount ) return TT_Err_Invalid_Argument; + gpos->FeatureList.ApplyOrder[gpos->FeatureList.ApplyCount++] = feature_index; + properties = gpos->LookupList.Properties; feature = gpos->FeatureList.FeatureRecord[feature_index].Feature; @@ -6083,6 +6087,8 @@ if ( !gpos ) return TT_Err_Invalid_Argument; + gpos->FeatureList.ApplyCount = 0; + properties = gpos->LookupList.Properties; for ( i = 0; i < gpos->LookupList.LookupCount; i++ ) @@ -6132,37 +6138,38 @@ { FT_Error error, retError = TTO_Err_Not_Covered; GPOS_Instance gpi; - - FT_UShort j; - - FT_UShort* properties; - + FT_UShort i, j, feature_index; + TTO_Feature feature; if ( !face || !gpos || !buffer || buffer->in_length == 0 || buffer->in_pos >= buffer->in_length ) return TT_Err_Invalid_Argument; - properties = gpos->LookupList.Properties; - gpi.face = face; gpi.gpos = gpos; gpi.load_flags = load_flags; gpi.r2l = r2l; gpi.dvi = dvi; + + for ( i = 0; i < gpos->FeatureList.ApplyCount; i++ ) + { + /* index of i'th feature */ + feature_index = gpos->FeatureList.ApplyOrder[i]; + feature = gpos->FeatureList.FeatureRecord[feature_index].Feature; - for ( j = 0; j < gpos->LookupList.LookupCount; j++ ) - if ( !properties || properties[j] ) + for ( j = 0; j < feature.LookupListCount; j++ ) { - error = Do_String_Lookup( &gpi, j, buffer ); + error = Do_String_Lookup( &gpi, feature.LookupListIndex[j], buffer ); if ( error ) - { - if ( error != TTO_Err_Not_Covered ) - return error; - } + { + if ( error != TTO_Err_Not_Covered ) + return error; + } else retError = error; } - + } + error = Position_CursiveChain ( buffer ); if ( error ) return error; diff --git a/src/ftxgsub.c b/src/ftxgsub.c index 04dc466e4..468762922 100644 --- a/src/ftxgsub.c +++ b/src/ftxgsub.c @@ -4063,11 +4063,15 @@ FT_UShort* properties; FT_UShort* index; - + /* Each feature can only be added once once */ + if ( !gsub || - feature_index >= gsub->FeatureList.FeatureCount ) + feature_index >= gsub->FeatureList.FeatureCount || + gsub->FeatureList.ApplyCount == gsub->FeatureList.FeatureCount ) return TT_Err_Invalid_Argument; + gsub->FeatureList.ApplyOrder[gsub->FeatureList.ApplyCount++] = feature_index; + properties = gsub->LookupList.Properties; feature = gsub->FeatureList.FeatureRecord[feature_index].Feature; @@ -4091,6 +4095,8 @@ if ( !gsub ) return TT_Err_Invalid_Argument; + gsub->FeatureList.ApplyCount = 0; + properties = gsub->LookupList.Properties; for ( i = 0; i < gsub->LookupList.LookupCount; i++ ) @@ -4120,32 +4126,34 @@ OTL_Buffer buffer ) { FT_Error error, retError = TTO_Err_Not_Covered; - FT_UShort j; - - FT_UShort* properties; + FT_UShort i, j, feature_index; + TTO_Feature feature; if ( !gsub || !buffer || buffer->in_length == 0 || buffer->in_pos >= buffer->in_length ) return TT_Err_Invalid_Argument; - properties = gsub->LookupList.Properties; - - for ( j = 0; j < gsub->LookupList.LookupCount; j++ ) - if ( properties[j] ) + for ( i = 0; i < gsub->FeatureList.ApplyCount; i++) + { + feature_index = gsub->FeatureList.ApplyOrder[i]; + feature = gsub->FeatureList.FeatureRecord[feature_index].Feature; + + for ( j = 0; j < feature.LookupListCount; j++ ) { - error = Do_String_Lookup( gsub, j, buffer ); - if ( error ) + error = Do_String_Lookup( gsub, feature.LookupListIndex[j], buffer ); + if ( error ) { if ( error != TTO_Err_Not_Covered ) goto End; } else retError = error; - + error = otl_buffer_swap( buffer ); if ( error ) goto End; - } + } + } error = retError; diff --git a/src/ftxopen.c b/src/ftxopen.c index 2325f6a2c..46d3cc7e4 100644 --- a/src/ftxopen.c +++ b/src/ftxopen.c @@ -373,13 +373,17 @@ if ( ALLOC_ARRAY( fl->FeatureRecord, count, TTO_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 Fail; + goto Fail1; fr[n].FeatureTag = GET_ULong(); new_offset = GET_UShort() + base_offset; @@ -389,17 +393,21 @@ cur_offset = FILE_Pos(); if ( FILE_Seek( new_offset ) || ( error = Load_Feature( &fr[n].Feature, stream ) ) != TT_Err_Ok ) - goto Fail; + goto Fail1; (void)FILE_Seek( cur_offset ); } return TT_Err_Ok; - Fail: + Fail1: for ( m = 0; m < n; m++ ) Free_Feature( &fr[m].Feature, memory ); + FREE( fl->ApplyOrder ); + + Fail2: FREE( fl->FeatureRecord ); + return error; } diff --git a/src/ftxopen.h b/src/ftxopen.h index 482bcb5d2..3d4f0fb98 100644 --- a/src/ftxopen.h +++ b/src/ftxopen.h @@ -117,6 +117,8 @@ extern "C" { { FT_UShort FeatureCount; /* number of FeatureRecords */ TTO_FeatureRecord* FeatureRecord; /* array of FeatureRecords */ + FT_UShort* ApplyOrder; /* order to apply features */ + FT_UShort ApplyCount; /* number of elements in ApplyOrder */ }; typedef struct TTO_FeatureList_ TTO_FeatureList;