Make Check_Property() take a OTL_GlyphItem, add a gproperties field to
authorOwen Taylor <otaylor@redhat.com>
Mon, 26 Jul 2004 18:59:02 +0000 (18:59 +0000)
committerOwen Taylor <otaylor@src.gnome.org>
Mon, 26 Jul 2004 18:59:02 +0000 (18:59 +0000)
Mon Jul 26 14:49:22 2004  Owen Taylor  <otaylor@redhat.com>

        * ftxgdef.[ch] otlbuffer.[ch]: Make Check_Property() take a
        OTL_GlyphItem, add a gproperties field to OTLGlyphItem,
        and use that to cache the properties for a glyph.

        * ftxgsub.c ftxgdef.c: Adapt to Check_Property() changes.

        * otlbuffer.[ch] ftxgsub.c: Add otl_buffer_copy_output_glyph()
        to use when we are copying an unmodified glyph from input
        to output that preserves the cached properties.

src/ftxgdef.c
src/ftxgpos.c
src/ftxgsub.c
src/ftxopenf.h
src/otlbuffer.c
src/otlbuffer.h

index 9077490..a31bcc8 100644 (file)
 
 
   FT_Error  Check_Property( TTO_GDEFHeader*  gdef,
-                            FT_UShort        index,
+                           OTL_GlyphItem    gitem,
                             FT_UShort        flags,
                             FT_UShort*       property )
   {
     FT_Error  error;
 
-
     if ( gdef )
     {
       FT_UShort basic_glyph_class;
       FT_UShort desired_attachment_class;
-           
-      error = TT_GDEF_Get_Glyph_Property( gdef, index, property );
-      if ( error )
-        return error;
+
+      if ( gitem->gproperties == OTL_GLYPH_PROPERTIES_UNKNOWN )
+      {
+       error = TT_GDEF_Get_Glyph_Property( gdef, gitem->gindex, &gitem->gproperties );
+       if ( error )
+         return error;
+      }
+
+      *property = gitem->gproperties;
 
       /* If the glyph was found in the MarkAttachmentClass table,
        * then that class value is the high byte of the result,
index 27c38a3..72dc60d 100644 (file)
@@ -59,7 +59,9 @@
 
 
 #define IN_GLYPH( pos )        (buffer->in_string[(pos)].gindex)
+#define IN_ITEM( pos )         (&buffer->in_string[(pos)])
 #define IN_CURGLYPH( pos )     (buffer->in_string[(pos) + buffer->in_pos].gindex)
+#define IN_CURITEM( pos )      (&buffer->in_string[(pos) + buffer->in_pos])
 #define IN_PROPERTIES( pos )   (buffer->in_string[(pos)].properties)
 #define IN_LIGID( pos )        (buffer->in_string[(pos)].ligID)
 #define IN_COMPONENT( pos )    (buffer->in_string[(pos)].component)
     if ( context_length != 0xFFFF && context_length < 1 )
       return TTO_Err_Not_Covered;
 
-    if ( CHECK_Property( gpos->gdef, IN_CURGLYPH( 0 ), flags, &property ) )
+    if ( CHECK_Property( gpos->gdef, IN_CURITEM( 0 ), flags, &property ) )
       return error;
 
     error = Coverage_Index( &sp->Coverage, IN_CURGLYPH( 0 ), &index );
     if ( context_length != 0xFFFF && context_length < 2 )
       return TTO_Err_Not_Covered;
 
-    if ( CHECK_Property( gpos->gdef, IN_CURGLYPH( 0 ), flags, &property ) )
+    if ( CHECK_Property( gpos->gdef, IN_CURITEM( 0 ), flags, &property ) )
       return error;
 
     error = Coverage_Index( &pp->Coverage, IN_CURGLYPH( 0 ), &index );
     first_pos = buffer->in_pos;
     (buffer->in_pos)++;
 
-    while ( CHECK_Property( gpos->gdef, IN_CURGLYPH( 0 ),
+    while ( CHECK_Property( gpos->gdef, IN_CURITEM( 0 ),
                             flags, &property ) )
     {
       if ( error && error != TTO_Err_Not_Covered )
     /* Glyphs not having the right GDEF properties will be ignored, i.e.,
        gpi->last won't be reset (contrary to user defined properties). */
 
-    if ( CHECK_Property( gpos->gdef, IN_CURGLYPH( 0 ), flags, &property ) )
+    if ( CHECK_Property( gpos->gdef, IN_CURITEM( 0 ), flags, &property ) )
       return error;
 
     /* We don't handle mark glyphs here.  According to Andrei, this isn't
     if ( flags & IGNORE_BASE_GLYPHS )
       return TTO_Err_Not_Covered;
 
-    if ( CHECK_Property( gpos->gdef, IN_CURGLYPH( 0 ),
+    if ( CHECK_Property( gpos->gdef, IN_CURITEM( 0 ),
                          flags, &property ) )
       return error;
 
 
     mark_glyph = IN_CURGLYPH( 0 );
 
-    if ( CHECK_Property( gpos->gdef, mark_glyph, flags, &property ) )
+    if ( CHECK_Property( gpos->gdef, IN_CURITEM( 0 ), flags, &property ) )
       return error;
 
     error = Coverage_Index( &mlp->MarkCoverage, mark_glyph, &mark_index );
     if ( flags & IGNORE_MARKS )
       return TTO_Err_Not_Covered;
 
-    if ( CHECK_Property( gpos->gdef, IN_CURGLYPH( 0 ),
+    if ( CHECK_Property( gpos->gdef, IN_CURITEM( 0 ),
                          flags, &property ) )
       return error;
 
 
     gdef = gpos->gdef;
 
-    if ( CHECK_Property( gdef, IN_CURGLYPH( 0 ), flags, &property ) )
+    if ( CHECK_Property( gdef, IN_CURITEM( 0 ), flags, &property ) )
       return error;
 
     error = Coverage_Index( &cpf1->Coverage, IN_CURGLYPH( 0 ), &index );
 
       for ( i = 1, j = buffer->in_pos + 1; i < pr[k].GlyphCount; i++, j++ )
       {
-        while ( CHECK_Property( gdef, IN_GLYPH( j ), flags, &property ) )
+        while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
         {
           if ( error && error != TTO_Err_Not_Covered )
             return error;
 
     gdef = gpos->gdef;
 
-    if ( CHECK_Property( gdef, IN_CURGLYPH( 0 ), flags, &property ) )
+    if ( CHECK_Property( gdef, IN_CURITEM( 0 ), flags, &property ) )
       return error;
 
     /* Note: The coverage table in format 2 doesn't give an index into
 
       for ( i = 1, j = buffer->in_pos + 1; i < pr->GlyphCount; i++, j++ )
       {
-        while ( CHECK_Property( gdef, IN_GLYPH( j ), flags, &property ) )
+        while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
         {
           if ( error && error != TTO_Err_Not_Covered )
             goto End;
 
     gdef = gpos->gdef;
 
-    if ( CHECK_Property( gdef, IN_CURGLYPH( 0 ), flags, &property ) )
+    if ( CHECK_Property( gdef, IN_CURITEM( 0 ), flags, &property ) )
       return error;
 
     if ( context_length != 0xFFFF && context_length < cpf3->GlyphCount )
 
     for ( i = 1, j = 1; i < cpf3->GlyphCount; i++, j++ )
     {
-      while ( CHECK_Property( gdef, IN_GLYPH( j ), flags, &property ) )
+      while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
       {
         if ( error && error != TTO_Err_Not_Covered )
           return error;
 
     gdef = gpos->gdef;
 
-    if ( CHECK_Property( gdef, IN_CURGLYPH( 0 ), flags, &property ) )
+    if ( CHECK_Property( gdef, IN_CURITEM( 0 ), flags, &property ) )
       return error;
 
     error = Coverage_Index( &ccpf1->Coverage, IN_CURGLYPH( 0 ), &index );
 
         for ( i = 0, j = buffer->in_pos - 1; i < bgc; i++, j-- )
         {
-          while ( CHECK_Property( gdef, IN_GLYPH( j ), flags, &property ) )
+          while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
           {
             if ( error && error != TTO_Err_Not_Covered )
               return error;
 
       for ( i = 1, j = buffer->in_pos + 1; i < igc; i++, j++ )
       {
-        while ( CHECK_Property( gdef, IN_GLYPH( j ), flags, &property ) )
+        while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
         {
           if ( error && error != TTO_Err_Not_Covered )
             return error;
 
       for ( i = 0; i < lgc; i++, j++ )
       {
-        while ( CHECK_Property( gdef, IN_GLYPH( j ), flags, &property ) )
+        while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
         {
           if ( error && error != TTO_Err_Not_Covered )
             return error;
 
     gdef = gpos->gdef;
 
-    if ( CHECK_Property( gdef, IN_CURGLYPH( 0 ), flags, &property ) )
+    if ( CHECK_Property( gdef, IN_CURITEM( 0 ), flags, &property ) )
       return error;
 
     /* Note: The coverage table in format 2 doesn't give an index into
 
         for ( i = 0, j = buffer->in_pos - 1; i < bgc; i++, j-- )
         {
-          while ( CHECK_Property( gdef, IN_GLYPH( j ), flags, &property ) )
+          while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
           {
             if ( error && error != TTO_Err_Not_Covered )
               goto End1;
 
       for ( i = 1, j = buffer->in_pos + 1; i < igc; i++, j++ )
       {
-        while ( CHECK_Property( gdef, IN_GLYPH( j ), flags, &property ) )
+        while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
         {
           if ( error && error != TTO_Err_Not_Covered )
             goto End1;
 
       for ( i = 0; i < lgc; i++, j++ )
       {
-        while ( CHECK_Property( gdef, IN_GLYPH( j ), flags, &property ) )
+        while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
         {
           if ( error && error != TTO_Err_Not_Covered )
             goto End1;
 
     gdef = gpos->gdef;
 
-    if ( CHECK_Property( gdef, IN_CURGLYPH( 0 ), flags, &property ) )
+    if ( CHECK_Property( gdef, IN_CURITEM( 0 ), flags, &property ) )
       return error;
 
     bgc = ccpf3->BacktrackGlyphCount;
 
       for ( i = 0, j = buffer->in_pos - 1; i < bgc; i++, j-- )
       {
-        while ( CHECK_Property( gdef, IN_GLYPH( j ), flags, &property ) )
+        while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
         {
           if ( error && error != TTO_Err_Not_Covered )
             return error;
     for ( i = 0, j = buffer->in_pos; i < igc; i++, j++ )
     {
       /* We already called CHECK_Property for IN_GLYPH ( buffer->in_pos ) */
-      while ( j > buffer->in_pos && CHECK_Property( gdef, IN_GLYPH( j ), flags, &property ) )
+      while ( j > buffer->in_pos && CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
       {
         if ( error && error != TTO_Err_Not_Covered )
           return error;
 
     for ( i = 0; i < lgc; i++, j++ )
     {
-      while ( CHECK_Property( gdef, IN_GLYPH( j ), flags, &property ) )
+      while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
       {
         if ( error && error != TTO_Err_Not_Covered )
           return error;
index 4ca70d1..8da8ff4 100644 (file)
@@ -39,7 +39,9 @@
 
 
 #define IN_GLYPH( pos )      buffer->in_string[(pos)].gindex
+#define IN_ITEM( pos )       (&buffer->in_string[(pos)])
 #define IN_CURGLYPH( pos )   buffer->in_string[(pos) + buffer->in_pos].gindex
+#define IN_CURITEM( pos )    (&buffer->in_string[(pos) + buffer->in_pos])
 #define IN_PROPERTIES( pos ) buffer->in_string[(pos)].properties
 #define IN_LIGID( pos )      buffer->in_string[(pos)].ligID
 
     if ( context_length != 0xFFFF && context_length < 1 )
       return TTO_Err_Not_Covered;
 
-    if ( CHECK_Property( gdef, IN_CURGLYPH( 0 ), flags, &property ) )
+    if ( CHECK_Property( gdef, IN_CURITEM( 0 ), flags, &property ) )
       return error;
 
     error = Coverage_Index( &ss->Coverage, IN_CURGLYPH( 0 ), &index );
     if ( context_length != 0xFFFF && context_length < 1 )
       return TTO_Err_Not_Covered;
 
-    if ( CHECK_Property( gdef, IN_CURGLYPH( 0 ), flags, &property ) )
+    if ( CHECK_Property( gdef, IN_CURITEM( 0 ), flags, &property ) )
       return error;
 
     error = Coverage_Index( &ms->Coverage, IN_CURGLYPH( 0 ), &index );
     if ( context_length != 0xFFFF && context_length < 1 )
       return TTO_Err_Not_Covered;
 
-    if ( CHECK_Property( gdef, IN_CURGLYPH( 0 ), flags, &property ) )
+    if ( CHECK_Property( gdef, IN_CURITEM( 0 ), flags, &property ) )
       return error;
 
     error = Coverage_Index( &as->Coverage, IN_CURGLYPH( 0 ), &index );
     TTO_Ligature*  lig;
 
 
-    if ( CHECK_Property( gdef, IN_CURGLYPH( 0 ), flags, &property ) )
+    if ( CHECK_Property( gdef, IN_CURITEM( 0 ), flags, &property ) )
       return error;
 
     if ( property == TTO_MARK || property & IGNORE_SPECIAL_MARKS )
 
       for ( i = 1, j = buffer->in_pos + 1; i < lig->ComponentCount; i++, j++ )
       {
-        while ( CHECK_Property( gdef, IN_GLYPH( j ), flags, &property ) )
+        while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
         {
           if ( error && error != TTO_Err_Not_Covered )
             return error;
 
        for ( i = 0; i < lig->ComponentCount - 1; i++ )
        {
-         while ( CHECK_Property( gdef, IN_CURGLYPH( 0 ),
+         while ( CHECK_Property( gdef, IN_CURITEM( 0 ),
                                  flags, &property ) )
            if ( ADD_Glyph( buffer, IN_CURGLYPH( 0 ),
                            i, ligID ) )
 
     gdef = gsub->gdef;
 
-    if ( CHECK_Property( gdef, IN_CURGLYPH( 0 ), flags, &property ) )
+    if ( CHECK_Property( gdef, IN_CURITEM( 0 ), flags, &property ) )
       return error;
 
     error = Coverage_Index( &csf1->Coverage, IN_CURGLYPH( 0 ), &index );
 
       for ( i = 1, j = buffer->in_pos + 1; i < sr[k].GlyphCount; i++, j++ )
       {
-        while ( CHECK_Property( gdef, IN_GLYPH( j ), flags, &property ) )
+        while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
         {
           if ( error && error != TTO_Err_Not_Covered )
             return error;
 
     gdef = gsub->gdef;
 
-    if ( CHECK_Property( gdef, IN_CURGLYPH( 0 ), flags, &property ) )
+    if ( CHECK_Property( gdef, IN_CURITEM( 0 ), flags, &property ) )
       return error;
 
     /* Note: The coverage table in format 2 doesn't give an index into
 
       for ( i = 1, j = buffer->in_pos + 1; i < sr->GlyphCount; i++, j++ )
       {
-        while ( CHECK_Property( gdef, IN_GLYPH( j ), flags, &property ) )
+        while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
         {
           if ( error && error != TTO_Err_Not_Covered )
             goto End;
 
     gdef = gsub->gdef;
 
-    if ( CHECK_Property( gdef, IN_CURGLYPH( 0 ), flags, &property ) )
+    if ( CHECK_Property( gdef, IN_CURITEM( 0 ), flags, &property ) )
       return error;
 
     if ( context_length != 0xFFFF && context_length < csf3->GlyphCount )
 
     for ( i = 1, j = buffer->in_pos + 1; i < csf3->GlyphCount; i++, j++ )
     {
-      while ( CHECK_Property( gdef, IN_GLYPH( j ), flags, &property ) )
+      while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
       {
         if ( error && error != TTO_Err_Not_Covered )
           return error;
 
     gdef = gsub->gdef;
 
-    if ( CHECK_Property( gdef, IN_CURGLYPH( 0 ), flags, &property ) )
+    if ( CHECK_Property( gdef, IN_CURITEM( 0 ), flags, &property ) )
       return error;
 
     error = Coverage_Index( &ccsf1->Coverage, IN_CURGLYPH( 0 ), &index );
 
         for ( i = 0, j = buffer->in_pos - 1; i < bgc; i++, j-- )
         {
-          while ( CHECK_Property( gdef, IN_GLYPH( j ), flags, &property ) )
+          while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
           {
             if ( error && error != TTO_Err_Not_Covered )
               return error;
 
       for ( i = 1, j = buffer->in_pos + 1; i < igc; i++, j++ )
       {
-        while ( CHECK_Property( gdef, IN_GLYPH( j ), flags, &property ) )
+        while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
         {
           if ( error && error != TTO_Err_Not_Covered )
             return error;
 
       for ( i = 0; i < lgc; i++, j++ )
       {
-        while ( CHECK_Property( gdef, IN_GLYPH( j ), flags, &property ) )
+        while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
         {
           if ( error && error != TTO_Err_Not_Covered )
             return error;
     gdef = gsub->gdef;
     memory = gsub->memory;
 
-    if ( CHECK_Property( gdef, IN_CURGLYPH( 0 ), flags, &property ) )
+    if ( CHECK_Property( gdef, IN_CURITEM( 0 ), flags, &property ) )
       return error;
 
     /* Note: The coverage table in format 2 doesn't give an index into
 
         for ( i = 0, j = buffer->in_pos - 1; i < bgc; i++, j-- )
         {
-          while ( CHECK_Property( gdef, IN_GLYPH( j ), flags, &property ) )
+          while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
           {
             if ( error && error != TTO_Err_Not_Covered )
               goto End1;
 
       for ( i = 1, j = buffer->in_pos + 1; i < igc; i++, j++ )
       {
-        while ( CHECK_Property( gdef, IN_GLYPH( j ), flags, &property ) )
+        while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
         {
           if ( error && error != TTO_Err_Not_Covered )
             goto End1;
 
       for ( i = 0; i < lgc; i++, j++ )
       {
-        while ( CHECK_Property( gdef, IN_GLYPH( j ), flags, &property ) )
+        while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
         {
           if ( error && error != TTO_Err_Not_Covered )
             goto End1;
 
     gdef = gsub->gdef;
 
-    if ( CHECK_Property( gdef, IN_CURGLYPH( 0 ), flags, &property ) )
+    if ( CHECK_Property( gdef, IN_CURITEM( 0 ), flags, &property ) )
       return error;
 
     bgc = ccsf3->BacktrackGlyphCount;
 
       for ( i = 0, j = buffer->in_pos - 1; i < bgc; i++, j-- )
       {
-        while ( CHECK_Property( gdef, IN_GLYPH( j ), flags, &property ) )
+        while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
         {
           if ( error && error != TTO_Err_Not_Covered )
             return error;
     for ( i = 0, j = buffer->in_pos; i < igc; i++, j++ )
     {
       /* We already called CHECK_Property for IN_GLYPH( buffer->in_pos ) */
-      while ( j > buffer->in_pos && CHECK_Property( gdef, IN_GLYPH( j ), flags, &property ) )
+      while ( j > buffer->in_pos && CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
       {
         if ( error && error != TTO_Err_Not_Covered )
           return error;
 
     for ( i = 0; i < lgc; i++, j++ )
     {
-      while ( CHECK_Property( gdef, IN_GLYPH( j ), flags, &property ) )
+      while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
       {
         if ( error && error != TTO_Err_Not_Covered )
           return error;
       else
         error = TTO_Err_Not_Covered;
 
-      if ( error == TTO_Err_Not_Covered ) 
-        if ( ADD_Glyph( buffer, IN_CURGLYPH( 0 ), 0xFFFF, 0xFFFF ) )
+      if ( error == TTO_Err_Not_Covered )
+        if ( otl_buffer_copy_output_glyph ( buffer ) )
           return error;
     }
 
index 0c4db8b..4c5998e 100644 (file)
@@ -145,7 +145,7 @@ extern "C" {
                                 FT_UShort        property );
 
   FT_Error  Check_Property( TTO_GDEFHeader*  gdef,
-                            FT_UShort        index,
+                            OTL_GlyphItem    item,
                             FT_UShort        flags,
                             FT_UShort*       property );
 
index 6c9c036..9849fd5 100644 (file)
     glyph->cluster = cluster;
     glyph->component = 0;
     glyph->ligID = 0;
+    glyph->gproperties = OTL_GLYPH_PROPERTIES_UNKNOWN;
     
     buffer->in_length++;
 
       item->cluster = cluster;
       item->component = component;
       item->ligID = ligID;
+      item->gproperties = OTL_GLYPH_PROPERTIES_UNKNOWN;
     }
 
     buffer->in_pos  += num_in;
   }
 
   FT_Error
-  otl_buffer_add_output_glyph( OTL_Buffer buffer,
-                              FT_UInt    glyph_index,
+  otl_buffer_add_output_glyph( OTL_Buffer buffer,      
+                      FT_UInt    glyph_index,
                               FT_UShort  component,
                               FT_UShort  ligID )
   {
                                          &glyph_data, component, ligID );
   }
 
+  FT_Error
+  otl_buffer_copy_output_glyph ( OTL_Buffer buffer )
+  {  
+    FT_Error  error;
+
+    error = otl_buffer_ensure( buffer, buffer->out_pos + 1 );
+    if ( error )
+      return error;
+    
+    buffer->out_string[buffer->out_pos++] = buffer->out_string[buffer->in_pos++];
+    buffer->out_length = buffer->out_pos;
+
+    return FT_Err_Ok;
+  }
+
   FT_UShort
   otl_buffer_allocate_ligid( OTL_Buffer buffer )
   {
index 426b447..bcb4e3e 100644 (file)
 
 G_BEGIN_DECLS
 
+#define OTL_GLYPH_PROPERTIES_UNKNOWN 0xFFFF
+
   typedef struct OTL_GlyphItemRec_ {
     FT_UInt     gindex;
     FT_UInt     properties;
     FT_UInt     cluster;
     FT_UShort   component;
     FT_UShort   ligID;
+    FT_UShort   gproperties;
   } OTL_GlyphItemRec, *OTL_GlyphItem;
 
   typedef struct OTL_PositionRec_ {
@@ -91,6 +94,9 @@ G_BEGIN_DECLS
                                FT_UShort  component,
                                FT_UShort  ligID );
 
+  FT_Error
+  otl_buffer_copy_output_glyph ( OTL_Buffer buffer );
+
   FT_UShort
   otl_buffer_allocate_ligid( OTL_Buffer buffer );