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:
parent
ae2daa972d
commit
f42d5eca29
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue