Re: Pango Feature Apply Order



I correct the last patch with an assumption :
Any Shape Engine appends its feature indices to its Rule Set by the
specific order it wants.
like what you've done in the patch of 
http://bugzilla.gnome.org/show_bug.cgi?id=122330 I've created a new
attribute ApplyOrder but for FeatureList not LookupList.

Best Regards,
	Soheil



On Sun, 2003-12-28 at 17:36, Owen Taylor wrote:
> How does your patch compare to the patch in:
> 
>  http://bugzilla.gnome.org/show_bug.cgi?id=122330
> 
> ?
> 
> Thanks,
> 					Owen
> 
> On Sun, Dec 28, 2003 at 05:04:33PM +0330, Soheil Hassas Yegnaneh wrote:
> > Dear All,
> > 
> > As OpenType specification says any script has a specific order of
> > features to apply (e.g. in Arabic, lookups of "ccmp" feature has to be
> > applied first and lookups of "dlig" feature has to be applied if user
> > asked for). But, current version of Pango applies lookups by order they
> > came in the font, instead of applying lookups by the order of the
> > features.
> > 
> > In order to fix this problem, I've modified TT_(GSUB|GPOS)_Apply_String
> > functions of pango/opentype/ftxg(sub|pos).c.
Index: pango/opentype/ftxgpos.c
===================================================================
RCS file: /usr/local/cvsroot/pango/pango/opentype/ftxgpos.c,v
retrieving revision 1.3
diff -u -d -r1.3 ftxgpos.c
--- pango/opentype/ftxgpos.c	28 Dec 2003 12:25:34 -0000	1.3
+++ pango/opentype/ftxgpos.c	29 Dec 2003 14:29:50 -0000
@@ -6220,6 +6220,11 @@
          feature_index >= gpos->FeatureList.FeatureCount )
       return TT_Err_Invalid_Argument;
 
+    /* 
+	Filling feature list ApplyCount by order of features listed in the RuleSet
+    */
+    gpos->FeatureList.ApplyOrder[gpos->FeatureList.ApplyCount++] = feature_index;
+
     properties = gpos->LookupList.Properties;
 
     feature = gpos->FeatureList.FeatureRecord[feature_index].Feature;
@@ -6228,6 +6233,8 @@
     for ( i = 0; i < feature.LookupListCount; i++ )
       properties[index[i]] |= property;
 
+    
+
     return TT_Err_Ok;
   }
 
@@ -6248,6 +6255,8 @@
     for ( i = 0; i < gpos->LookupList.LookupCount; i++ )
       properties[i] = 0;
 
+    gpos->FeatureList.ApplyCount = 0;
+
     return TT_Err_Ok;
   }
 
@@ -6295,11 +6304,14 @@
     FT_Error       error, retError = TTO_Err_Not_Covered;
     GPOS_Instance  gpi;
 
-    FT_UShort i,
-	      j;
+    FT_UShort         index,
+		      i,
+		      j;
 
-    FT_UShort* properties;
     TTO_Feature feature;
+    
+    FT_UShort* properties;
+
 
     if ( !face || !gpos ||
          !in || in->length == 0 || in->pos >= in->length )
@@ -6317,25 +6329,29 @@
       FREE( *out );
     if ( ALLOC_ARRAY( *out, in->length, TTO_GPOS_Data ) )
       return error;
-   for ( i = 0; i < gpos->FeatureList.FeatureCount; i++)
-    {
-      feature = gpos->FeatureList.FeatureRecord[i].Feature;
-                                                                                                                             
-      if(feature.LookupListIndex == NULL)
+    
+    for ( i = 0; i < gpos->FeatureList.ApplyCount; i++ )
+    { 
+      /* index of i'th feature */
+      index = gpos->FeatureList.ApplyOrder[i];
+      
+      if( index >= gpos->FeatureList.FeatureCount )
         continue;
 
-      for ( j = 0; j < gpos->LookupList.LookupCount; j++ )
-        if ( !properties || properties[j] )
+      feature = gpos->FeatureList.FeatureRecord[index].Feature;
+
+      for ( j = 0; j < feature.LookupListCount; j++ )
+        if (  !properties || properties[feature.LookupListIndex[j]] )
         {
-          error = Do_String_Lookup( &gpi, j, in, *out );
+          error = Do_String_Lookup( &gpi, feature.LookupListIndex[j], in, *out );
 	  if ( error )
-  	    {
+	    {
 	      if ( error != TTO_Err_Not_Covered )
 	        return error;
 	    }
 	  else
 	    retError = error;
-      }
+        }
     }
     error = Position_CursiveChain ( *out, in->length );
     if ( error )
Index: pango/opentype/ftxgsub.c
===================================================================
RCS file: /usr/local/cvsroot/pango/pango/opentype/ftxgsub.c,v
retrieving revision 1.3
diff -u -d -r1.3 ftxgsub.c
--- pango/opentype/ftxgsub.c	28 Dec 2003 12:25:34 -0000	1.3
+++ pango/opentype/ftxgsub.c	29 Dec 2003 14:29:46 -0000
@@ -521,8 +521,7 @@
     error = Coverage_Index( &ss->Coverage, in->string[in->pos], &index );
     if ( error )
       return error;
-    
-    printf("glyphID %0x", in->string[in->pos]);
+
     switch ( ss->SubstFormat )
     {
     case 1:
@@ -542,7 +541,7 @@
     default:
       return TTO_Err_Invalid_GSUB_SubTable;
     }
-    printf("value[0] %0x\n", value[0]);
+
     if ( gdef && gdef->NewGlyphClasses )
     {
       /* we inherit the old glyph class to the substituted glyph */
@@ -1204,14 +1203,11 @@
       return error;
 
     if ( property == TTO_MARK || property & IGNORE_SPECIAL_MARKS )
-      first_is_mark = TRUE; 
-    
+      first_is_mark = TRUE;
+
     error = Coverage_Index( &ls->Coverage, in->string[in->pos], &index );
     if ( error )
-    {
-      printf("Error: %xu \n", error);
       return error;
-    }
 
     if ( index >= ls->LigatureSetCount )
        return TTO_Err_Invalid_GSUB_SubTable;
@@ -1252,11 +1248,9 @@
         if ( s_in[j] != c[i - 1] )
           break;
       }
-       
-      printf("In Ligature Subst %lu %lu\n", i, j);
+
       if ( i == lig->ComponentCount )
       {
-	
         if ( gdef && gdef->NewGlyphClasses )
         {
           /* this is just a guess ... */
@@ -4219,26 +4213,24 @@
 
     lo    = &gsub->LookupList.Lookup[lookup_index];
     flags = lo->LookupFlag;
+
     for ( i = 0; i < lo->SubTableCount; i++ )
     {
       switch ( lo->LookupType )
       {
       case GSUB_LOOKUP_SINGLE:
-	printf("single\n");
         error = Lookup_SingleSubst( &lo->SubTable[i].st.gsub.single,
                                     in, out,
                                     flags, context_length, gsub->gdef );
         break;
 
       case GSUB_LOOKUP_MULTIPLE:
-	printf("multiple\n");
         error = Lookup_MultipleSubst( &lo->SubTable[i].st.gsub.multiple,
                                       in, out,
                                       flags, context_length, gsub->gdef );
         break;
 
       case GSUB_LOOKUP_ALTERNATE:
-	printf("Alternate\n");
         error = Lookup_AlternateSubst( gsub,
                                        &lo->SubTable[i].st.gsub.alternate,
                                        in, out,
@@ -4246,11 +4238,9 @@
         break;
 
       case GSUB_LOOKUP_LIGATURE:
-	printf("In ligature \n");
         error = Lookup_LigatureSubst( &lo->SubTable[i].st.gsub.ligature,
                                       in, out,
                                       flags, context_length, gsub->gdef );
-        printf("Out ligature\n");
         break;
 
       case GSUB_LOOKUP_CONTEXT:
@@ -4338,11 +4328,16 @@
          feature_index >= gsub->FeatureList.FeatureCount )
       return TT_Err_Invalid_Argument;
 
+    /* 
+	Filling feature list ApplyCount by order of features listed in the RuleSet
+    */
+    gsub->FeatureList.ApplyOrder[gsub->FeatureList.ApplyCount++] = feature_index;
+
     properties = gsub->LookupList.Properties;
 
     feature = gsub->FeatureList.FeatureRecord[feature_index].Feature;
     index   = feature.LookupListIndex;
-
+    
     for ( i = 0; i < feature.LookupListCount; i++ )
       properties[index[i]] |= property;
 
@@ -4366,6 +4361,8 @@
     for ( i = 0; i < gsub->LookupList.LookupCount; i++ )
       properties[i] = 0;
 
+    gsub->FeatureList.ApplyCount = 0;
+
     return TT_Err_Ok;
   }
 
@@ -4463,11 +4460,12 @@
   {
     FT_Error          error, retError = TTO_Err_Not_Covered;
     FT_Memory         memory = in->memory;
-    FT_UShort         i,
-		      j, 
-		      index;
+    FT_UShort         index,
+		      i,
+		      j;
 
     TTO_Feature feature;
+
     TTO_GSUB_String   tmp1;
     TTO_GSUB_String*  ptmp1;
     TTO_GSUB_String   tmp2;
@@ -4476,9 +4474,8 @@
 
     FT_UShort*        properties;
 
-
     if ( !gsub ||
-         !in || !out || in->length == 0 || in->pos >= in->length )
+         !in || !out || in->length == 0 || in->pos >= in->length || !(gsub->FeatureList.ApplyOrder) )
       return TT_Err_Invalid_Argument;
 
     properties = gsub->LookupList.Properties;
@@ -4526,38 +4523,40 @@
       goto End;
     MEM_Copy( tmp1.logClusters, in->logClusters,
 	      in->length * sizeof( FT_Int ) );
+  
+    for ( i = 0; i < gsub->FeatureList.ApplyCount; i++)
+    { 
+      /* index of i'th feature */
+      index = gsub->FeatureList.ApplyOrder[i];
+      
+      if( index >= gsub->FeatureList.FeatureCount )
+        continue;
 
-
-    for ( i = 0; i < gsub->FeatureList.FeatureCount; i++)
-    {
-      feature = gsub->FeatureList.FeatureRecord[i].Feature;
-
-      if(feature.LookupListIndex == NULL)
-	continue;
+      feature = gsub->FeatureList.FeatureRecord[index].Feature;
 
       for ( j = 0; j < feature.LookupListCount; j++ )
-        if ( properties[j] )
+        if ( properties[feature.LookupListIndex[j]] )
         {
           error = Do_String_Lookup( gsub, feature.LookupListIndex[j], ptmp1, ptmp2 );
           if ( error )
-	  {
+  	  {
 	    if ( error != TTO_Err_Not_Covered )
 	      goto End;
 	  }
 	  else
-	    retError = error; 
-
-        /* flipping `in' and `out', preparing the next loop */
+	    retError = error;
 
-        ptmp1->pos       = in->pos;
-        ptmp2->length    = ptmp2->pos;
-        ptmp2->pos       = in->pos;
-        ptmp2->max_ligID = ptmp1->max_ligID;
+          /* flipping `in' and `out', preparing the next loop */
+  
+          ptmp1->pos       = in->pos;
+          ptmp2->length    = ptmp2->pos;
+          ptmp2->pos       = in->pos;
+          ptmp2->max_ligID = ptmp1->max_ligID;
 
-        t     = ptmp2;
-        ptmp2 = ptmp1;
-        ptmp1 = t;
-      }
+          t     = ptmp2;
+          ptmp2 = ptmp1;
+          ptmp1 = t;
+        }
     }
 
   End:
Index: pango/opentype/ftxopen.c
===================================================================
RCS file: /usr/local/cvsroot/pango/pango/opentype/ftxopen.c,v
retrieving revision 1.2
diff -u -d -r1.2 ftxopen.c
--- pango/opentype/ftxopen.c	28 Dec 2003 12:08:44 -0000	1.2
+++ pango/opentype/ftxopen.c	29 Dec 2003 14:29:17 -0000
@@ -374,6 +374,10 @@
     if ( ALLOC_ARRAY( fl->FeatureRecord, count, TTO_FeatureRecord ) )
       return error;
 
+    if ( ALLOC_ARRAY( fl->ApplyOrder, count, FT_UShort ) )
+      goto Fail1;
+    fl->ApplyCount = 0;    
+
     fr = fl->FeatureRecord;
 
     for ( n = 0; n < count; n++ )
@@ -400,6 +404,9 @@
       Free_Feature( &fr[m].Feature, memory );
 
     FREE( fl->FeatureRecord );
+
+  Fail1:
+    FREE( fl->ApplyOrder );
     return error;
   }
 
@@ -421,7 +428,10 @@
         Free_Feature( &fr[n].Feature, memory );
 
       FREE( fr );
+
     }
+    if ( fl->ApplyOrder )
+	FREE(fl->ApplyOrder);
   }
 
 
@@ -944,7 +954,6 @@
          overflow and rounding errors                             */
 
       middle = max - ( ( max - min ) >> 1 );
-  printf("RR1:  md%lu mn%lu mx%lu rr%x glyphId%x\n", middle, min, max, array[middle], glyphID );
 
       if ( glyphID == array[middle] )
       {
@@ -992,8 +1001,7 @@
          overflow and rounding errors                             */
 
       middle = max - ( ( max - min ) >> 1 );
-      if(glyphID == 0x1d2 || glyphID == 0x253 || glyphID == 0x20f || glyphID == 0x1b9)
-	      printf("RR2:  md%lu mn%lu mx%lu rr%x glyphId%x\n", middle, min, max, rr[middle].Start, glyphID );
+
       if ( glyphID >= rr[middle].Start && glyphID <= rr[middle].End )
       {
         *index = rr[middle].StartCoverageIndex + glyphID - rr[middle].Start;
Index: pango/opentype/ftxopen.h
===================================================================
RCS file: /usr/local/cvsroot/pango/pango/opentype/ftxopen.h,v
retrieving revision 1.1.1.1
diff -u -d -r1.1.1.1 ftxopen.h
--- pango/opentype/ftxopen.h	17 Dec 2003 10:53:16 -0000	1.1.1.1
+++ pango/opentype/ftxopen.h	29 Dec 2003 14:29:17 -0000
@@ -117,6 +117,8 @@
   {
     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;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]