Save the order in which features were added and use that when applying
authorOwen Taylor <otaylor@redhat.com>
Tue, 27 Jul 2004 17:20:01 +0000 (17:20 +0000)
committerOwen Taylor <otaylor@src.gnome.org>
Tue, 27 Jul 2004 17:20:01 +0000 (17:20 +0000)
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)

src/ftxgpos.c
src/ftxgsub.c
src/ftxopen.c
src/ftxopen.h

index 0651732..c92dfea 100644 (file)
     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;
     if ( !gpos )
       return TT_Err_Invalid_Argument;
 
+    gpos->FeatureList.ApplyCount = 0;
+
     properties = gpos->LookupList.Properties;
 
     for ( i = 0; i < gpos->LookupList.LookupCount; i++ )
   {
     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;
index 04dc466..4687629 100644 (file)
     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;
     if ( !gsub )
       return TT_Err_Invalid_Argument;
 
+    gsub->FeatureList.ApplyCount = 0;
+
     properties = gsub->LookupList.Properties;
 
     for ( i = 0; i < gsub->LookupList.LookupCount; i++ )
                                  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;
 
index 2325f6a..46d3cc7 100644 (file)
 
     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;
       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;
   }
 
index 482bcb5..3d4f0fb 100644 (file)
@@ -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;