Common subdirectories: opentypeorig/.deps and opentype/.deps
Binary files opentypeorig/disasm.o and opentype/disasm.o differ
Only in opentypeorig: #ftxgsub.c#
diff -u opentypeorig/ftxgsub.c opentype/ftxgsub.c
--- opentypeorig/ftxgsub.c	2004-07-27 22:58:10.000000000 +0600
+++ opentype/ftxgsub.c	2004-08-25 12:24:51.000000000 +0600
@@ -3638,7 +3638,314 @@
   }
 
 
+  /*New code: Routine for handling GSUB lookup 8 */
 
+  FT_Error  Load_ReverseChainContextSubst(
+                     TTO_ReverseChainContextSubst*  rccs,
+                     FT_Stream                      stream )
+  {
+    FT_Error error;
+    FT_Memory memory = stream->memory;
+
+    FT_UShort                m, count;
+    /*FT_ULong               backtrack_offset, input_offset, lookahead_offset;*/
+
+    FT_UShort               nb = 0,  nl = 0;
+    FT_UShort               backtrack_count, lookahead_count;
+    FT_ULong                cur_offset, new_offset, base_offset;
+
+    TTO_Coverage*           b;
+    TTO_Coverage*           l;
+    FT_UShort*              sub;
+
+    if ( ACCESS_Frame( 2L ) )
+      return error;
+    rccs->SubstFormat = GET_UShort();
+ 
+
+    FORGET_Frame();   
+
+    base_offset = FILE_Pos() - 2;
+
+    if ( ACCESS_Frame( 2L ) )
+      return error;
+    
+    new_offset = GET_UShort() + base_offset;
+
+    FORGET_Frame();
+
+    cur_offset = FILE_Pos();
+     
+    if ( FILE_Seek( new_offset ) ||
+         ( error = Load_Coverage( &rccs->Coverage, stream ) ) != TT_Err_Ok )
+      return error;
+    (void)FILE_Seek( cur_offset );
+    
+    /* Input coverage loaded */
+    if ( ACCESS_Frame( 2L ) )
+      goto Fail5;
+   
+    
+    rccs->BacktrackGlyphCount = GET_UShort();
+    FORGET_Frame();
+
+    rccs->BacktrackCoverage = NULL;
+
+    backtrack_count = rccs->BacktrackGlyphCount;
+
+    if ( ALLOC_ARRAY( rccs->BacktrackCoverage, backtrack_count,
+                      TTO_Coverage ) )
+      return error;
+    
+    b = rccs->BacktrackCoverage;
+
+    for ( nb = 0; nb < backtrack_count; nb++ )
+    {
+      if ( ACCESS_Frame( 2L ) )
+        goto Fail4;
+
+      new_offset = GET_UShort() + base_offset;
+
+      FORGET_Frame();
+
+      cur_offset = FILE_Pos();
+      if ( FILE_Seek( new_offset ) ||
+           ( error = Load_Coverage( &b[nb], stream ) ) != TT_Err_Ok )
+        goto Fail4;
+      (void)FILE_Seek( cur_offset );
+    }
+
+    /* Backtrack coverage loaded */
+
+    if ( ACCESS_Frame( 2L ) )
+      goto Fail4;
+
+  
+    rccs->LookaheadGlyphCount = GET_UShort();
+    FORGET_Frame();
+
+    rccs->LookaheadCoverage = NULL;
+
+    lookahead_count = rccs->LookaheadGlyphCount;
+
+    if ( ALLOC_ARRAY( rccs->LookaheadCoverage, lookahead_count,
+                      TTO_Coverage ) )
+      goto Fail4;
+
+    l = rccs->LookaheadCoverage;
+  
+    for ( nl = 0; nl < lookahead_count; nl++ )
+    {
+      if ( ACCESS_Frame( 2L ) )
+        goto Fail2;
+
+      new_offset = GET_UShort() + base_offset;
+
+      FORGET_Frame();
+
+      cur_offset = FILE_Pos();
+      if ( FILE_Seek( new_offset ) ||
+           ( error = Load_Coverage( &l[nl], stream ) ) != TT_Err_Ok )
+        goto Fail2;
+      (void)FILE_Seek( cur_offset );
+    }
+   
+    if ( ACCESS_Frame( 2L ) )
+      goto Fail2;
+  
+    rccs->GlyphCount = GET_UShort();
+    FORGET_Frame();
+
+    rccs->Substitute = NULL;
+
+    count = rccs->GlyphCount;
+
+    if ( ALLOC_ARRAY( rccs->Substitute, count,
+                      FT_UShort ) )
+      goto Fail2;
+
+    sub = rccs->Substitute;
+
+    
+    if ( ACCESS_Frame( count * 2L ) )
+      goto Fail1;
+    
+    /* Loading Substitute */
+    int ncount = 0;
+    for(ncount = 0; ncount < count; ncount++)
+      sub[ncount] = GET_UShort();
+      
+      
+    FORGET_Frame();
+    
+    return TT_Err_Ok;
+
+     Fail1:
+    FREE( sub );
+    
+  Fail2:
+    for ( m = 0; m < nl; m++ )
+      Free_Coverage( &l[m], memory );
+
+    FREE( l );
+
+ 
+
+  Fail4:
+    for ( m = 0; m < nb; m++ )
+      Free_Coverage( &b[m], memory );
+
+    FREE( b );
+    return error;
+
+ Fail5:
+    Free_Coverage( &rccs->Coverage, memory );
+    return error;
+
+
+  }
+ void  Free_ReverseChainContextSubst( TTO_ReverseChainContextSubst*  rccs,
+				      FT_Memory               memory )
+  {  
+ 
+    FT_UShort      n, count;
+
+    TTO_Coverage*  c;
+
+    /* Freeing LookaheadCoverage */
+    if ( rccs->LookaheadCoverage )
+    {
+      count = rccs->LookaheadGlyphCount;
+      c     = rccs->LookaheadCoverage;
+
+      for ( n = 0; n < count; n++ )
+        Free_Coverage( &c[n], memory );
+
+      FREE( c );
+    }
+
+    /* Freeing BacktrackCoverage */
+    if ( rccs->BacktrackCoverage )
+    {
+      count = rccs->BacktrackGlyphCount;
+      c     = rccs->BacktrackCoverage;
+
+      for ( n = 0; n < count; n++ )
+        Free_Coverage( &c[n], memory );
+
+      FREE( c );
+    }
+
+
+    /* Freeing InputCoverage */
+    Free_Coverage( &rccs->Coverage, memory );
+
+  }
+  
+ 
+  static FT_Error  Lookup_ReverseChainContextSubst(
+                     TTO_GSUBHeader*         gsub,
+                     TTO_ReverseChainContextSubst*  rccs,
+		     OTL_Buffer              buffer,
+		     FT_ULong                string_index,
+                     FT_UShort               flags,
+                     FT_UShort               context_length,
+                     int                     nesting_level )
+  {
+    FT_UShort        index,input_index, i, j, property;
+    FT_UShort        bgc, lgc;
+    FT_Error         error;
+
+    TTO_Coverage*    bc;
+    TTO_Coverage*    lc;
+    TTO_GDEFHeader*  gdef;
+
+ 
+    gdef = gsub->gdef;
+
+    if ( CHECK_Property( gdef, IN_CURGLYPH( 0 ), flags, &property ) )
+      return error;
+
+    bgc = rccs->BacktrackGlyphCount;
+    lgc = rccs->LookaheadGlyphCount;
+
+    if ( context_length != 0xFFFF && context_length < 1 )
+      return TTO_Err_Not_Covered;
+
+    /* check whether context is too long; it is a first guess only */
+    
+    if ( bgc > buffer->out_pos || string_index +  lgc > buffer->in_length )
+      return TTO_Err_Not_Covered;
+    
+    if ( bgc )
+    {
+      /* Since we don't know in advance the number of glyphs to inspect,
+         we search backwards for matches in the backtrack glyph array    */
+
+      bc       = rccs->BacktrackCoverage;
+
+      for ( i = 0, j = string_index - 1; i < bgc; i++, j-- )
+      {
+        while ( CHECK_Property( gdef, IN_GLYPH( j ), flags, &property ) )
+        {
+          if ( error && error != TTO_Err_Not_Covered )
+            return error;
+
+	  if ( j + 1 == bgc - i )
+	    return TTO_Err_Not_Covered;
+	  j--;
+        }
+
+        error = Coverage_Index( &bc[i], IN_GLYPH( j ), &index );
+        if ( error )
+          return error;
+      }
+    }
+
+    j = string_index;
+   
+    error = Coverage_Index( &rccs->Coverage, IN_GLYPH( j ), &input_index );
+      
+    if ( error )
+        return error;
+
+    /* we are starting for lookahead glyphs right after the last context
+       glyph                                                             */
+
+    j += 1;
+    if( j >= buffer->in_length )
+      return TTO_Err_Not_Covered;
+  
+    lc       = rccs->LookaheadCoverage;
+
+    for ( i = 0; i < lgc; i++, j++ )
+    {
+      while ( CHECK_Property( gdef, IN_GLYPH( j ), flags, &property ) )
+      {
+        if ( error && error != TTO_Err_Not_Covered )
+          return error;
+
+	if ( j + lgc - i == buffer->in_length )
+	  return TTO_Err_Not_Covered;
+	j++;
+      }
+
+      error = Coverage_Index( &lc[i], IN_GLYPH( j ), &index );
+      if ( error )
+        return error;
+    }
+
+	FT_Short val;
+	val =  rccs->Substitute[input_index];
+	buffer->in_string[string_index].gindex = val;
+	
+	return error;
+     
+   
+  }
+
+
+ 
   /***********
    * GSUB API
    ***********/
@@ -4049,6 +4356,42 @@
   }
 
 
+  FT_Error  Apply_ReverseChainContextSubst( TTO_GSUBHeader*   gsub,
+					    FT_UShort         lookup_index,
+					    OTL_Buffer        buffer )
+  {
+  
+    FT_Error     error = TTO_Err_Not_Covered;
+    FT_ULong     subtable_Count, string_index;
+    FT_UShort    flags;
+    TTO_Lookup*  lo;      
+
+    if (buffer->in_length == 0)
+      return TTO_Err_Not_Covered;;
+    
+    lo    = &gsub->LookupList.Lookup[lookup_index];
+    flags = lo->LookupFlag;      
+    
+    for ( subtable_Count = 0; subtable_Count < lo->SubTableCount; subtable_Count++ )
+    {
+      string_index  = buffer->in_length - 1;
+      do
+      {
+	error = Lookup_ReverseChainContextSubst( gsub, &lo->SubTable[subtable_Count].st.gsub.reverse, buffer,string_index,
+						   flags,0xFFFF, 0 );
+	if ( error )
+	{
+	  if(error != TTO_Err_Not_Covered)
+	    return error;
+	}
+
+      }
+      while (string_index--);
+    }
+    return error;
+  }
+
+
   EXPORT_FUNC
   FT_Error  TT_GSUB_Add_Feature( TTO_GSUBHeader*  gsub,
                                  FT_UShort        feature_index,
@@ -4117,7 +4460,7 @@
     return TT_Err_Ok;
   }
 
-
+ 
   EXPORT_FUNC
   FT_Error  TT_GSUB_Apply_String( TTO_GSUBHeader*   gsub,
 				  OTL_Buffer        buffer )
@@ -4125,6 +4468,7 @@
     FT_Error          error, retError = TTO_Err_Not_Covered;
     FT_UShort         i, j, feature_index;
     TTO_Feature       feature;
+    FT_UShort*        properties =  gsub->LookupList.Properties;
 
     if ( !gsub ||
          !buffer || buffer->in_length == 0 || buffer->in_pos >= buffer->in_length )
@@ -4132,30 +4476,55 @@
 
     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, feature.LookupListIndex[j], buffer );
-	if ( error )
+
+	if(gsub->LookupList.Lookup[feature.LookupListIndex[j]].LookupType == GSUB_LOOKUP_REVERSE_CHAIN)
 	{
-	  if ( error != TTO_Err_Not_Covered )
-	    goto End;
+	 
+	  if ( ~IN_PROPERTIES( buffer->in_pos ) & properties[feature.LookupListIndex[j]] )
+	    error = Apply_ReverseChainContextSubst( gsub, feature.LookupListIndex[j], buffer);
+	  else
+	    error = TTO_Err_Not_Covered;
+
+	  if ( error )
+	  {
+	    if(error != TTO_Err_Not_Covered)
+	      return error;
+	  }
+	  else 
+	    retError = error;
+	        
 	}
 	else
-	  retError = error;
-        
-	error = otl_buffer_swap( buffer );
-	if ( error )
-	  goto End;
+	{
+
+	  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;
 
   End:
     return error;
+  
   }
 
 
Only in opentype: ftxgsub.c~
Only in opentype: ftxgsub (copy).c
diff -u opentypeorig/ftxgsub.h opentype/ftxgsub.h
--- opentypeorig/ftxgsub.h	2004-02-29 20:44:50.000000000 +0500
+++ opentype/ftxgsub.h	2004-08-23 09:35:39.000000000 +0600
@@ -39,7 +39,8 @@
 #define GSUB_LOOKUP_CONTEXT    5
 #define GSUB_LOOKUP_CHAIN      6
 #define GSUB_LOOKUP_EXTENSION  7
-
+/* New code*/
+#define GSUB_LOOKUP_REVERSE_CHAIN 8
 
 /* Use this if a feature applies to all glyphs */
 
@@ -467,6 +468,33 @@
   typedef struct TTO_ChainContextSubst_  TTO_ChainContextSubst;
 
 
+  /* New Code for reverse chain GSUB lookup type 8 */
+
+  /* LookupType 8 */
+  struct TTO_ReverseChainContextSubst_
+  {
+    FT_UShort               SubstFormat;  
+    TTO_Coverage            Coverage;
+                                        /*coverage table for input glyphs*/
+    FT_UShort               BacktrackGlyphCount;
+                                        /* number of backtrack glyphs    */
+    TTO_Coverage*           BacktrackCoverage;
+                                        /* array of backtrack Coverage
+                                           tables                        */
+    FT_UShort               LookaheadGlyphCount;
+                                        /* number of lookahead glyphs    */
+    TTO_Coverage*           LookaheadCoverage;
+                                        /* array of lookahead coverage
+                                           tables                        */
+    FT_UShort               GlyphCount;
+                                        /* number of Glyph ID's          */
+    FT_UShort*              Substitute;
+                                        /* array of substitute Glyph ID  */
+  };
+
+  typedef struct TTO_ReverseChainContextSubst_  TTO_ReverseChainContextSubst;
+
+
   union  TTO_GSUB_SubTable_
   {
     TTO_SingleSubst        single;
@@ -475,6 +503,9 @@
     TTO_LigatureSubst      ligature;
     TTO_ContextSubst       context;
     TTO_ChainContextSubst  chain;
+
+    /* Table Updated */
+    TTO_ReverseChainContextSubst  reverse;
   };
 
   typedef union TTO_GSUB_SubTable_  TTO_GSUB_SubTable;
Only in opentype: ftxgsub.h~
diff -u opentypeorig/ftxopen.c opentype/ftxopen.c
--- opentypeorig/ftxopen.c	2004-07-27 22:58:10.000000000 +0600
+++ opentype/ftxopen.c	2004-08-25 13:11:28.000000000 +0600
@@ -469,6 +469,10 @@
 
       case GSUB_LOOKUP_CHAIN:
         return Load_ChainContextSubst( &st->st.gsub.chain, stream );
+	
+	/* New entry for reverse chain */
+      case GSUB_LOOKUP_REVERSE_CHAIN:           
+        return Load_ReverseChainContextSubst( &st->st.gsub.reverse, stream );
 
       default:
         return TTO_Err_Invalid_GSUB_SubTable_Format;
@@ -536,6 +540,11 @@
         Free_ContextSubst( &st->st.gsub.context, memory );
         break;
 
+	/* New entry for reverse chain */      
+      case GSUB_LOOKUP_REVERSE_CHAIN:
+        Free_ReverseChainContextSubst( &st->st.gsub.reverse, memory );
+        break;
+
       case GSUB_LOOKUP_CHAIN:
         Free_ChainContextSubst( &st->st.gsub.chain, memory );
         break;
@@ -1165,7 +1174,7 @@
       crr[n].Class = GET_UShort();
 
       /* sanity check */
-
+      
       if ( crr[n].Start > crr[n].End ||
            crr[n].Class >= limit )
       {
Only in opentype: ftxopen.c~
diff -u opentypeorig/ftxopenf.h opentype/ftxopenf.h
--- opentypeorig/ftxopenf.h	2002-03-15 11:46:05.000000000 +0500
+++ opentype/ftxopenf.h	2004-08-09 09:05:25.000000000 +0600
@@ -74,6 +74,9 @@
                                FT_Stream          input );
   FT_Error  Load_ChainContextSubst( TTO_ChainContextSubst*  ccs,
                                     FT_Stream               input );
+  /* New code: Load function for LookupType 8 */
+  FT_Error  Load_ReverseChainContextSubst( TTO_ReverseChainContextSubst*  rccs,
+					   FT_Stream               input );
 
   void  Free_SingleSubst( TTO_SingleSubst*  ss,
 			  FT_Memory         memory );
@@ -87,7 +90,9 @@
 			   FT_Memory         memory );
   void  Free_ChainContextSubst( TTO_ChainContextSubst*  ccs,
 				FT_Memory               memory );
-
+  /* New code: Free memory used for LookupType 8 */
+  void  Free_ReverseChainContextSubst( TTO_ReverseChainContextSubst*  rccs,
+				       FT_Memory               memory );
 
   /* functions from ftxgpos.c */
 
Only in opentype: ftxopenf.h~
Only in opentype: #ftxopen.h#
Only in opentype: ftxopen.h~
Common subdirectories: opentypeorig/.libs and opentype/.libs
Only in opentype: NEWftxgsub (another copy).c
Only in opentype: otlbuffer.c~
Only in opentype: otlbuffer.h~
Binary files opentypeorig/ottest and opentype/ottest differ
Binary files opentypeorig/ottest.o and opentype/ottest.o differ
Only in opentype: with fillftxgsub.c
Only in opentype: With fillftxgsub.h
