Save the order in which features were added and use that when applying

Tue Jul 27 12:38:05 2004  Owen Taylor  <otaylor@redhat.com>

        * 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)
This commit is contained in:
Owen Taylor 2004-07-27 17:20:01 +00:00 committed by Owen Taylor
parent ae2daa972d
commit f42d5eca29
4 changed files with 58 additions and 33 deletions

View File

@ -6055,11 +6055,15 @@
FT_UShort* properties; FT_UShort* properties;
FT_UShort* index; FT_UShort* index;
/* Each feature can only be added once once */
if ( !gpos || if ( !gpos ||
feature_index >= gpos->FeatureList.FeatureCount ) feature_index >= gpos->FeatureList.FeatureCount ||
gpos->FeatureList.ApplyCount == gpos->FeatureList.FeatureCount )
return TT_Err_Invalid_Argument; return TT_Err_Invalid_Argument;
gpos->FeatureList.ApplyOrder[gpos->FeatureList.ApplyCount++] = feature_index;
properties = gpos->LookupList.Properties; properties = gpos->LookupList.Properties;
feature = gpos->FeatureList.FeatureRecord[feature_index].Feature; feature = gpos->FeatureList.FeatureRecord[feature_index].Feature;
@ -6083,6 +6087,8 @@
if ( !gpos ) if ( !gpos )
return TT_Err_Invalid_Argument; return TT_Err_Invalid_Argument;
gpos->FeatureList.ApplyCount = 0;
properties = gpos->LookupList.Properties; properties = gpos->LookupList.Properties;
for ( i = 0; i < gpos->LookupList.LookupCount; i++ ) for ( i = 0; i < gpos->LookupList.LookupCount; i++ )
@ -6132,37 +6138,38 @@
{ {
FT_Error error, retError = TTO_Err_Not_Covered; FT_Error error, retError = TTO_Err_Not_Covered;
GPOS_Instance gpi; GPOS_Instance gpi;
FT_UShort i, j, feature_index;
FT_UShort j; TTO_Feature feature;
FT_UShort* properties;
if ( !face || !gpos || if ( !face || !gpos ||
!buffer || buffer->in_length == 0 || buffer->in_pos >= buffer->in_length ) !buffer || buffer->in_length == 0 || buffer->in_pos >= buffer->in_length )
return TT_Err_Invalid_Argument; return TT_Err_Invalid_Argument;
properties = gpos->LookupList.Properties;
gpi.face = face; gpi.face = face;
gpi.gpos = gpos; gpi.gpos = gpos;
gpi.load_flags = load_flags; gpi.load_flags = load_flags;
gpi.r2l = r2l; gpi.r2l = r2l;
gpi.dvi = dvi; 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++ ) for ( j = 0; j < feature.LookupListCount; j++ )
if ( !properties || properties[j] )
{ {
error = Do_String_Lookup( &gpi, j, buffer ); error = Do_String_Lookup( &gpi, feature.LookupListIndex[j], buffer );
if ( error ) if ( error )
{ {
if ( error != TTO_Err_Not_Covered ) if ( error != TTO_Err_Not_Covered )
return error; return error;
} }
else else
retError = error; retError = error;
} }
}
error = Position_CursiveChain ( buffer ); error = Position_CursiveChain ( buffer );
if ( error ) if ( error )
return error; return error;

View File

@ -4063,11 +4063,15 @@
FT_UShort* properties; FT_UShort* properties;
FT_UShort* index; FT_UShort* index;
/* Each feature can only be added once once */
if ( !gsub || if ( !gsub ||
feature_index >= gsub->FeatureList.FeatureCount ) feature_index >= gsub->FeatureList.FeatureCount ||
gsub->FeatureList.ApplyCount == gsub->FeatureList.FeatureCount )
return TT_Err_Invalid_Argument; return TT_Err_Invalid_Argument;
gsub->FeatureList.ApplyOrder[gsub->FeatureList.ApplyCount++] = feature_index;
properties = gsub->LookupList.Properties; properties = gsub->LookupList.Properties;
feature = gsub->FeatureList.FeatureRecord[feature_index].Feature; feature = gsub->FeatureList.FeatureRecord[feature_index].Feature;
@ -4091,6 +4095,8 @@
if ( !gsub ) if ( !gsub )
return TT_Err_Invalid_Argument; return TT_Err_Invalid_Argument;
gsub->FeatureList.ApplyCount = 0;
properties = gsub->LookupList.Properties; properties = gsub->LookupList.Properties;
for ( i = 0; i < gsub->LookupList.LookupCount; i++ ) for ( i = 0; i < gsub->LookupList.LookupCount; i++ )
@ -4120,32 +4126,34 @@
OTL_Buffer buffer ) OTL_Buffer buffer )
{ {
FT_Error error, retError = TTO_Err_Not_Covered; FT_Error error, retError = TTO_Err_Not_Covered;
FT_UShort j; FT_UShort i, j, feature_index;
TTO_Feature feature;
FT_UShort* properties;
if ( !gsub || if ( !gsub ||
!buffer || buffer->in_length == 0 || buffer->in_pos >= buffer->in_length ) !buffer || buffer->in_length == 0 || buffer->in_pos >= buffer->in_length )
return TT_Err_Invalid_Argument; return TT_Err_Invalid_Argument;
properties = gsub->LookupList.Properties; for ( i = 0; i < gsub->FeatureList.ApplyCount; i++)
{
for ( j = 0; j < gsub->LookupList.LookupCount; j++ ) feature_index = gsub->FeatureList.ApplyOrder[i];
if ( properties[j] ) feature = gsub->FeatureList.FeatureRecord[feature_index].Feature;
for ( j = 0; j < feature.LookupListCount; j++ )
{ {
error = Do_String_Lookup( gsub, j, buffer ); error = Do_String_Lookup( gsub, feature.LookupListIndex[j], buffer );
if ( error ) if ( error )
{ {
if ( error != TTO_Err_Not_Covered ) if ( error != TTO_Err_Not_Covered )
goto End; goto End;
} }
else else
retError = error; retError = error;
error = otl_buffer_swap( buffer ); error = otl_buffer_swap( buffer );
if ( error ) if ( error )
goto End; goto End;
} }
}
error = retError; error = retError;

View File

@ -373,13 +373,17 @@
if ( ALLOC_ARRAY( fl->FeatureRecord, count, TTO_FeatureRecord ) ) if ( ALLOC_ARRAY( fl->FeatureRecord, count, TTO_FeatureRecord ) )
return error; return error;
if ( ALLOC_ARRAY( fl->ApplyOrder, count, FT_UShort ) )
goto Fail2;
fl->ApplyCount = 0;
fr = fl->FeatureRecord; fr = fl->FeatureRecord;
for ( n = 0; n < count; n++ ) for ( n = 0; n < count; n++ )
{ {
if ( ACCESS_Frame( 6L ) ) if ( ACCESS_Frame( 6L ) )
goto Fail; goto Fail1;
fr[n].FeatureTag = GET_ULong(); fr[n].FeatureTag = GET_ULong();
new_offset = GET_UShort() + base_offset; new_offset = GET_UShort() + base_offset;
@ -389,17 +393,21 @@
cur_offset = FILE_Pos(); cur_offset = FILE_Pos();
if ( FILE_Seek( new_offset ) || if ( FILE_Seek( new_offset ) ||
( error = Load_Feature( &fr[n].Feature, stream ) ) != TT_Err_Ok ) ( error = Load_Feature( &fr[n].Feature, stream ) ) != TT_Err_Ok )
goto Fail; goto Fail1;
(void)FILE_Seek( cur_offset ); (void)FILE_Seek( cur_offset );
} }
return TT_Err_Ok; return TT_Err_Ok;
Fail: Fail1:
for ( m = 0; m < n; m++ ) for ( m = 0; m < n; m++ )
Free_Feature( &fr[m].Feature, memory ); Free_Feature( &fr[m].Feature, memory );
FREE( fl->ApplyOrder );
Fail2:
FREE( fl->FeatureRecord ); FREE( fl->FeatureRecord );
return error; return error;
} }

View File

@ -117,6 +117,8 @@ extern "C" {
{ {
FT_UShort FeatureCount; /* number of FeatureRecords */ FT_UShort FeatureCount; /* number of FeatureRecords */
TTO_FeatureRecord* FeatureRecord; /* array 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; typedef struct TTO_FeatureList_ TTO_FeatureList;