Implement the first substitute()
authorBehdad Esfahbod <behdad@behdad.org>
Thu, 16 Apr 2009 02:56:15 +0000 (22:56 -0400)
committerBehdad Esfahbod <behdad@behdad.org>
Mon, 2 Nov 2009 19:40:06 +0000 (14:40 -0500)
14 files changed:
src/harfbuzz-buffer-private.h
src/harfbuzz-buffer.c
src/harfbuzz-buffer.h
src/harfbuzz-gdef-private.h
src/harfbuzz-gdef.c
src/harfbuzz-gdef.h
src/harfbuzz-gpos.c
src/harfbuzz-gpos.h
src/harfbuzz-gsub.h
src/hb-ot-layout-gsub-private.h
src/hb-ot-layout-open-private.h
src/hb-ot-layout-private.h
src/hb-ot-layout.cc
src/hb-ot-layout.h

index 02ae336..dbecc7a 100644 (file)
@@ -33,7 +33,7 @@
 
 HB_BEGIN_HEADER
 
-#define HB_GLYPH_PROPERTIES_UNKNOWN 0xFFFF
+#define HB_GLYPH_PROPERTY_UNKNOWN 0xFFFF
 
 HB_INTERNAL void
 _hb_buffer_swap( HB_Buffer buffer );
@@ -83,9 +83,9 @@ _hb_buffer_allocate_ligid( HB_Buffer buffer );
 #define OUT_GLYPH( pos )       (buffer->out_string[(pos)].gindex)
 #define OUT_ITEM( pos )        (&buffer->out_string[(pos)])
 
-#define CHECK_Property( layout, index, flags, property )                                       \
-          (error = _hb_ot_layout_check_glyph_properties((layout), (index), (flags), (property)) \
-                ? HB_Err_Ok : HB_Err_Not_Covered)
+#define CHECK_Property( layout, index, flags, properties )                                     \
+          ({unsigned int _p; error = _hb_ot_layout_check_glyph_property((layout), (index), (flags), (&_p)) \
+                ? HB_Err_Ok : HB_Err_Not_Covered, *(properties) = _p; error;})
 
 #define ADD_String( buffer, num_in, num_out, glyph_data, component, ligID )             \
           ( ( error = _hb_buffer_add_output_glyphs( (buffer),                            \
index 568fbd8..3008c93 100644 (file)
@@ -187,7 +187,7 @@ hb_buffer_add_glyph( HB_Buffer buffer,
   glyph->cluster = cluster;
   glyph->component = 0;
   glyph->ligID = 0;
-  glyph->gproperties = HB_GLYPH_PROPERTIES_UNKNOWN;
+  glyph->gproperty = HB_GLYPH_PROPERTY_UNKNOWN;
   
   buffer->in_length++;
 
@@ -304,7 +304,7 @@ _hb_buffer_add_output_glyphs( HB_Buffer  buffer,
     item->cluster = cluster;
     item->component = component;
     item->ligID = ligID;
-    item->gproperties = HB_GLYPH_PROPERTIES_UNKNOWN;
+    item->gproperty = HB_GLYPH_PROPERTY_UNKNOWN;
   }
 
   buffer->in_pos  += num_in;
index b134407..b89b3c4 100644 (file)
@@ -38,7 +38,7 @@ typedef struct HB_GlyphItemRec_ {
   HB_UInt     cluster;
   HB_UShort   component;
   HB_UShort   ligID;
-  HB_UShort   gproperties;
+  HB_UShort   gproperty;
 } HB_GlyphItemRec, *HB_GlyphItem;
 
 typedef struct HB_PositionRec_ {
index 4a57520..e22b1b2 100644 (file)
@@ -105,13 +105,13 @@ struct  HB_LigGlyph_
 HB_INTERNAL HB_Error
 _HB_GDEF_Add_Glyph_Property( HB_GDEFHeader* gdef,
                             HB_UShort      glyphID,
-                            HB_UShort      property );
+                            HB_UShort      properties );
 
 HB_INTERNAL HB_Error
 _HB_GDEF_Check_Property( HB_GDEFHeader* gdef,
                         HB_GlyphItem   item,
                         HB_UShort      flags,
-                        HB_UShort*     property );
+                        HB_UShort*     properties );
 
 HB_INTERNAL HB_Error
 _HB_GDEF_LoadMarkAttachClassDef_From_LookupFlags( HB_GDEFHeader* gdef,
index 8fecf4c..1bda907 100644 (file)
@@ -1074,14 +1074,14 @@ _HB_GDEF_Check_Property( HB_GDEFHeader* gdef,
     HB_UShort basic_glyph_class;
     HB_UShort desired_attachment_class;
 
-    if ( gitem->gproperties == HB_GLYPH_PROPERTIES_UNKNOWN )
+    if ( gitem->gproperty == HB_GLYPH_PROPERTY_UNKNOWN )
     {
-      error = HB_GDEF_Get_Glyph_Property( gdef, gitem->gindex, &gitem->gproperties );
+      error = HB_GDEF_Get_Glyph_Property( gdef, gitem->gindex, &gitem->gproperty );
       if ( error )
        return error;
     }
 
-    *property = gitem->gproperties;
+    *property = gitem->gproperty;
 
     /* If the glyph was found in the MarkAttachmentClass table,
      * then that class value is the high byte of the result,
index 84afe17..dc33d21 100644 (file)
@@ -121,7 +121,7 @@ HB_Error  HB_Done_GDEF_Table ( HB_GDEFHeader* gdef );
 
 HB_Error  HB_GDEF_Get_Glyph_Property( HB_GDEFHeader*  gdef,
                                      HB_UShort        glyphID,
-                                     HB_UShort*       property );
+                                     HB_UShort*       properties );
 
 HB_Error  HB_GDEF_Build_ClassDefinition( HB_GDEFHeader*  gdef,
                                         HB_UShort        num_glyphs,
index 560a291..c4e8a78 100644 (file)
@@ -1783,7 +1783,7 @@ static HB_Error  Lookup_CursivePos( GPOS_Instance*    gpi,
     return HB_Err_Not_Covered;
   }
 
-  /* Glyphs not having the right GDEF properties will be ignored, i.e.,
+  /* Glyphs not having the right GDEF property will be ignored, i.e.,
      gpi->last won't be reset (contrary to user defined properties). */
 
   if ( CHECK_Property( gpos->layout, IN_CURITEM(), flags, &property ) )
@@ -2224,7 +2224,7 @@ static HB_Error  Lookup_MarkBasePos( GPOS_Instance*    gpi,
 
   while ( i <= buffer->in_pos )
   {
-    property = _hb_ot_layout_get_glyph_properties (gpos->layout, IN_GLYPH(j));
+    property = _hb_ot_layout_get_glyph_property (gpos->layout, IN_GLYPH(j));
     if ( !property )
       return HB_Err_Not_Covered;
 
@@ -2633,7 +2633,7 @@ static HB_Error  Lookup_MarkLigPos( GPOS_Instance*    gpi,
 
   while ( i <= buffer->in_pos )
   {
-    property = _hb_ot_layout_get_glyph_properties (gpos->layout, IN_GLYPH(j));
+    property = _hb_ot_layout_get_glyph_property (gpos->layout, IN_GLYPH(j));
     if ( !property )
       return HB_Err_Not_Covered;
 
@@ -2960,7 +2960,7 @@ static HB_Error  Lookup_MarkMarkPos( GPOS_Instance*    gpi,
   j = buffer->in_pos - 1;
   while ( i <= buffer->in_pos )
   {
-    property = _hb_ot_layout_get_glyph_properties (gpos->layout, IN_GLYPH(j));
+    property = _hb_ot_layout_get_glyph_property (gpos->layout, IN_GLYPH(j));
     if ( !property )
       return HB_Err_Not_Covered;
 
index b1aa135..0460e2b 100644 (file)
@@ -145,7 +145,7 @@ HB_Error  HB_GPOS_Query_Features( HB_GPOSHeader*  gpos,
 
 HB_Error  HB_GPOS_Add_Feature( HB_GPOSHeader*  gpos,
                               HB_UShort        feature_index,
-                              HB_UInt          property );
+                              HB_UInt          properties );
 
 HB_Error  HB_GPOS_Clear_Features( HB_GPOSHeader*  gpos );
 
index b1e78ce..f4deac1 100644 (file)
@@ -121,7 +121,7 @@ HB_Error  HB_GSUB_Query_Features( HB_GSUBHeader*  gsub,
 
 HB_Error  HB_GSUB_Add_Feature( HB_GSUBHeader*  gsub,
                               HB_UShort        feature_index,
-                              HB_UInt          property );
+                              HB_UInt          properties );
 
 HB_Error  HB_GSUB_Clear_Features( HB_GSUBHeader*  gsub );
 
index c8d5405..d8c1d8d 100644 (file)
 #include "hb-ot-layout-open-private.h"
 #include "hb-ot-layout-gdef-private.h"
 
+#include "harfbuzz-buffer-private.h" /* XXX */
+
+#define DEFINE_GET_GLYPH_COVERAGE(name) \
+  inline hb_ot_layout_coverage_t get_##name (hb_codepoint_t glyph) const { \
+    const Coverage &c = get_coverage (); \
+    return c.get_coverage (glyph); \
+  }
+
+#define SUBTABLE_SUBSTITUTE \
+       bool substitute (hb_ot_layout_t *layout, \
+                        hb_buffer_t    *buffer, \
+                        unsigned int    context_length, \
+                        unsigned int    nesting_level_left, \
+                        unsigned int    lookup_flag) const
 
 struct SingleSubstFormat1 {
 
   friend struct SingleSubst;
 
   private:
-  inline bool substitute (hb_ot_layout_t *layout,
-                         hb_buffer_t    *buffer,
-                         unsigned int    context_length,
-                         unsigned int    nesting_level_left) const {
-//    if (get_coverage (IN_CURGLYPH()))
-//      return ;
+  DEFINE_GET_ACCESSOR (Coverage, coverage, coverage);
+  DEFINE_GET_GLYPH_COVERAGE (glyph_coverage);
+
+  inline SUBTABLE_SUBSTITUTE {
+    hb_codepoint_t glyph_id;
+    hb_ot_layout_coverage_t index;
+    unsigned int property;
+
+    HB_UNUSED (nesting_level_left);
+
+    if (HB_UNLIKELY (context_length < 1))
+      return false;
+
+    if (!_hb_ot_layout_check_glyph_property (layout, IN_CURITEM (), lookup_flag, &property))
+      return false;
+
+    glyph_id = IN_CURGLYPH ();
+
+    index = get_glyph_coverage (glyph_id);
+    if (-1 == index)
+      return false;
+
+    glyph_id += deltaGlyphID;
+    _hb_buffer_replace_output_glyph (buffer, glyph_id, context_length == NO_CONTEXT);
+
+    if ( _hb_ot_layout_has_new_glyph_classes (layout) )
+    {
+      /* we inherit the old glyph class to the substituted glyph */
+      _hb_ot_layout_set_glyph_property (layout, glyph_id, property);
+    }
+
+    return true;
+}
+
+#if 0
+
+  switch ( ss->SubstFormat )
+  {
+  case 1:
+    value = (IN_CURGLYPH() + ss->ssf.ssf1.DeltaGlyphID ) & 0xFFFF;
+    if ( REPLACE_Glyph( buffer, value, nesting_level ) )
+      return error;
+    break;
+
+  case 2:
+    if ( index >= ss->ssf.ssf2.GlyphCount )
+      return ERR(HB_Err_Invalid_SubTable);
+    value = ss->ssf.ssf2.Substitute[index];
+    if ( REPLACE_Glyph( buffer, value, nesting_level ) )
+      return error;
+    break;
+
+  default:
+    return ERR(HB_Err_Invalid_SubTable);
+  }
+
+  if ( _hb_ot_layout_has_new_glyph_classes (layout) )
+  {
+    /* we inherit the old glyph class to the substituted glyph */
+
+    hb_ot_layout_set_glyph_class (layout, value, properties);
   }
+#endif
 
   private:
   USHORT       substFormat;            /* Format identifier--format = 1 */
@@ -490,7 +560,8 @@ struct SubstLookupSubTable {
                          hb_buffer_t    *buffer,
                          unsigned int    context_length,
                          unsigned int    nesting_level_left,
-                         unsigned int    lookup_type) const {
+                         unsigned int    lookup_type,
+                         unsigned int    lookup_flag) const {
   }
 
   private:
@@ -545,6 +616,7 @@ struct SubstLookup : Lookup {
                          unsigned int    context_length,
                          unsigned int    nesting_level_left) const {
     unsigned int lookup_type = get_type ();
+    unsigned int lookup_flag = get_flag ();
 
     if (HB_UNLIKELY (nesting_level_left == 0))
       return false;
@@ -553,7 +625,7 @@ struct SubstLookup : Lookup {
     for (unsigned int i = 0; i < get_subtable_count (); i++)
       if (get_subtable (i).substitute (layout, buffer,
                                       context_length, nesting_level_left,
-                                      lookup_type))
+                                      lookup_type, lookup_flag))
        return true;
 
     return false;
index d5ca810..4123a43 100644 (file)
@@ -671,7 +671,7 @@ struct Lookup {
   inline bool ignore_base_glyphs(void) const { return lookupFlag & LookupFlag::IgnoreBaseGlyphs; }
   inline bool ignore_ligatures (void) const { return lookupFlag & LookupFlag::IgnoreLigatures; }
   inline bool ignore_marks     (void) const { return lookupFlag & LookupFlag::IgnoreMarks; }
-  inline bool get_mark_attachment_type (void) const { return lookupFlag & LookupFlag::MarkAttachmentType; }
+  inline unsigned int get_mark_attachment_type (void) const { return lookupFlag & LookupFlag::MarkAttachmentType; }
 
   inline unsigned int get_type (void) const { return lookupType; }
   inline unsigned int get_flag (void) const { return lookupFlag; }
index a1be8aa..ae728eb 100644 (file)
@@ -34,9 +34,7 @@
 #include "harfbuzz-buffer.h"
 
 
-typedef uint16_t hb_ot_layout_class_t;
-typedef uint16_t hb_ot_layout_glyph_properties_t;
-typedef uint16_t hb_ot_layout_lookup_flags_t;
+typedef unsigned int hb_ot_layout_class_t;
 typedef int hb_ot_layout_coverage_t;   /* -1 is not covered, >= 0 otherwise */
 
 /* XXX #define HB_OT_LAYOUT_INTERNAL static */
@@ -51,15 +49,20 @@ HB_BEGIN_DECLS();
 HB_OT_LAYOUT_INTERNAL hb_bool_t
 _hb_ot_layout_has_new_glyph_classes (hb_ot_layout_t *layout);
 
-HB_OT_LAYOUT_INTERNAL hb_ot_layout_glyph_properties_t
-_hb_ot_layout_get_glyph_properties (hb_ot_layout_t *layout,
-                                   hb_codepoint_t  glyph);
+HB_OT_LAYOUT_INTERNAL unsigned int
+_hb_ot_layout_get_glyph_property (hb_ot_layout_t *layout,
+                                 hb_codepoint_t  glyph);
+
+HB_OT_LAYOUT_INTERNAL void
+_hb_ot_layout_set_glyph_property (hb_ot_layout_t *layout,
+                                 hb_codepoint_t  glyph,
+                                 unsigned int    property);
 
 HB_OT_LAYOUT_INTERNAL hb_bool_t
-_hb_ot_layout_check_glyph_properties (hb_ot_layout_t                  *layout,
-                                     HB_GlyphItem                     gitem,
-                                     hb_ot_layout_lookup_flags_t      lookup_flags,
-                                     hb_ot_layout_glyph_properties_t *property);
+_hb_ot_layout_check_glyph_property (hb_ot_layout_t *layout,
+                                   HB_GlyphItem    gitem,
+                                   unsigned int    lookup_flags,
+                                   unsigned int   *property);
 
 HB_END_DECLS();
 
index 01923db..5a5e176 100644 (file)
@@ -98,6 +98,8 @@ hb_ot_layout_destroy (hb_ot_layout_t *layout)
  * GDEF
  */
 
+/* XXX the public class_t is a mess */
+
 hb_bool_t
 hb_ot_layout_has_font_glyph_classes (hb_ot_layout_t *layout)
 {
@@ -110,9 +112,9 @@ _hb_ot_layout_has_new_glyph_classes (hb_ot_layout_t *layout)
   return layout->new_gdef.len > 0;
 }
 
-HB_OT_LAYOUT_INTERNAL hb_ot_layout_glyph_properties_t
-_hb_ot_layout_get_glyph_properties (hb_ot_layout_t *layout,
-                                   hb_codepoint_t  glyph)
+HB_OT_LAYOUT_INTERNAL unsigned int
+_hb_ot_layout_get_glyph_property (hb_ot_layout_t *layout,
+                                 hb_codepoint_t  glyph)
 {
   hb_ot_layout_class_t klass;
 
@@ -138,22 +140,22 @@ _hb_ot_layout_get_glyph_properties (hb_ot_layout_t *layout,
 }
 
 HB_OT_LAYOUT_INTERNAL hb_bool_t
-_hb_ot_layout_check_glyph_properties (hb_ot_layout_t                  *layout,
-                                     HB_GlyphItem                     gitem,
-                                     hb_ot_layout_lookup_flags_t      lookup_flags,
-                                     hb_ot_layout_glyph_properties_t *property)
+_hb_ot_layout_check_glyph_property (hb_ot_layout_t *layout,
+                                   HB_GlyphItem    gitem,
+                                   unsigned int    lookup_flags,
+                                   unsigned int   *property)
 {
   hb_ot_layout_glyph_class_t basic_glyph_class;
-  hb_ot_layout_glyph_properties_t desired_attachment_class;
+  unsigned int desired_attachment_class;
 
-  if (gitem->gproperties == HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN)
+  if (gitem->gproperty == HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN)
   {
-    gitem->gproperties = *property = _hb_ot_layout_get_glyph_properties (layout, gitem->gindex);
-    if (gitem->gproperties == HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED)
+    gitem->gproperty = *property = _hb_ot_layout_get_glyph_property (layout, gitem->gindex);
+    if (gitem->gproperty == HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED)
       return false;
   }
 
-  *property = gitem->gproperties;
+  *property = gitem->gproperty;
 
   /* If the glyph was found in the MarkAttachmentClass table,
    * then that class value is the high byte of the result,
@@ -179,27 +181,42 @@ _hb_ot_layout_check_glyph_properties (hb_ot_layout_t                  *layout,
   if (desired_attachment_class)
   {
     if (basic_glyph_class == HB_OT_LAYOUT_GLYPH_CLASS_MARK &&
-        *property != desired_attachment_class )
+        *property != desired_attachment_class)
       return false;
   }
 
   return true;
 }
 
+HB_OT_LAYOUT_INTERNAL void
+_hb_ot_layout_set_glyph_property (hb_ot_layout_t *layout,
+                                 hb_codepoint_t  glyph,
+                                 unsigned int    property)
+{
+  hb_ot_layout_glyph_class_t klass;
+
+  if (property & LookupFlag::MarkAttachmentType)
+    klass = HB_OT_LAYOUT_GLYPH_CLASS_MARK;
+  else
+    klass = (hb_ot_layout_glyph_class_t) property;
+
+  hb_ot_layout_set_glyph_class (layout, glyph, klass);
+}
+
 
 hb_ot_layout_glyph_class_t
 hb_ot_layout_get_glyph_class (hb_ot_layout_t *layout,
                              hb_codepoint_t  glyph)
 {
-  hb_ot_layout_glyph_properties_t properties;
+  unsigned int property;
   hb_ot_layout_class_t klass;
 
-  properties = _hb_ot_layout_get_glyph_properties (layout, glyph);
+  property = _hb_ot_layout_get_glyph_property (layout, glyph);
 
-  if (properties & 0xFF00)
+  if (property & LookupFlag::MarkAttachmentType)
     return HB_OT_LAYOUT_GLYPH_CLASS_MARK;
 
-  return (hb_ot_layout_glyph_class_t) properties;
+  return (hb_ot_layout_glyph_class_t) property;
 }
 
 void
@@ -212,6 +229,9 @@ hb_ot_layout_set_glyph_class (hb_ot_layout_t             *layout,
   hb_ot_layout_class_t gdef_klass;
   int len = layout->new_gdef.len;
 
+  if (G_UNLIKELY (glyph > 65535))
+    return;
+
   if (glyph >= len) {
     int new_len;
     unsigned char *new_klasses;
index c29485c..a6b9d37 100644 (file)
@@ -91,7 +91,7 @@ typedef enum {
   HB_OT_LAYOUT_TABLE_TYPE_NONE
 } hb_ot_layout_table_type_t;
 
-typedef uint16_t hb_ot_layout_feature_mask_t;
+typedef uint32_t hb_ot_layout_feature_mask_t;
 
 #define HB_OT_LAYOUT_MAX_NESTING_LEVEL         100