Implement glyph properties
authorBehdad Esfahbod <behdad@behdad.org>
Thu, 24 Jan 2008 11:03:45 +0000 (06:03 -0500)
committerBehdad Esfahbod <behdad@behdad.org>
Thu, 24 Jan 2008 11:03:45 +0000 (06:03 -0500)
src/hb-ot-layout-gdef-private.h
src/hb-ot-layout-private.h
src/hb-ot-layout.cc
src/hb-ot-layout.h

index 39d2d87..5d4759f 100644 (file)
@@ -231,6 +231,12 @@ DEFINE_NULL_ASSERT_SIZE (LigCaretList, 4);
 struct GDEF {
   static const hb_tag_t Tag            = HB_TAG ('G','D','E','F');
 
+  static const hb_ot_layout_class_t UnclassifiedGlyph  = 0;
+  static const hb_ot_layout_class_t BaseGlyph          = 1;
+  static const hb_ot_layout_class_t LigatureGlyph      = 2;
+  static const hb_ot_layout_class_t MarkGlyph          = 3;
+  static const hb_ot_layout_class_t ComponentGlyph     = 4;
+
   STATIC_DEFINE_GET_FOR_DATA (GDEF);
   /* XXX check version here? */
 
@@ -240,12 +246,12 @@ struct GDEF {
   DEFINE_ACCESSOR (ClassDef, get_mark_attach_class_def, markAttachClassDef);
 
   /* Returns 0 if not found. */
-  inline int get_glyph_class (hb_ot_layout_glyph_t glyph_id) const {
+  inline hb_ot_layout_class_t get_glyph_class (hb_ot_layout_glyph_t glyph_id) const {
     return get_glyph_class_def ().get_class (glyph_id);
   }
 
   /* Returns 0 if not found. */
-  inline int get_mark_attachment_type (hb_ot_layout_glyph_t glyph_id) const {
+  inline hb_ot_layout_class_t get_mark_attachment_type (hb_ot_layout_glyph_t glyph_id) const {
     return get_mark_attach_class_def ().get_class (glyph_id);
   }
 
index 8327197..55f14f8 100644 (file)
 #include "hb-ot-layout.h"
 
 typedef uint16_t hb_ot_layout_class_t;
+typedef uint16_t hb_ot_layout_glyph_properties_t;
 typedef int hb_ot_layout_coverage_t;   /* -1 is not covered, >= 0 otherwise */
 
 struct GDEF;
 struct GSUB;
 struct GPOS;
 
-HB_BEGIN_DECLS();
-
 struct _HB_OT_Layout {
   const GDEF *gdef;
   const GSUB *gsub;
   const GPOS *gpos;
+
+  struct {
+    uint8_t *klasses;
+    unsigned int len;
+  } new_gdef;
+
 };
 
+
+HB_BEGIN_DECLS();
+
+static hb_ot_layout_glyph_properties_t
+_hb_ot_layout_get_glyph_properties (HB_OT_Layout         *layout,
+                                   hb_ot_layout_glyph_t  glyph);
+
 HB_END_DECLS();
 
 #endif /* HB_OT_LAYOUT_PRIVATE_H */
index 827aa23..5fc9f8f 100644 (file)
@@ -34,6 +34,8 @@
 #include "hb-ot-layout-gsub-private.h"
 
 #include <stdlib.h>
+#include <string.h>
+
 
 HB_OT_Layout *
 hb_ot_layout_create (const char *font_data,
@@ -57,18 +59,86 @@ hb_ot_layout_destroy (HB_OT_Layout *layout)
   free (layout);
 }
 
-hb_ot_layout_glyph_properties_t
-hb_ot_layout_get_glyph_properties (HB_OT_Layout                    *layout,
-                                  hb_ot_layout_glyph_t             glyph)
+static hb_ot_layout_glyph_properties_t
+_hb_ot_layout_get_glyph_properties (HB_OT_Layout         *layout,
+                                   hb_ot_layout_glyph_t  glyph)
 {
+  hb_ot_layout_class_t klass;
+
+  /* TODO old harfbuzz doesn't always parse mark attachments as it says it was
+   * introduced without a version bump, so it may not be safe */
+  klass = layout->gdef->get_mark_attachment_type (glyph);
+  if (klass)
+    return klass << 8;
+
+  klass = layout->gdef->get_glyph_class (glyph);
 
+  if (!klass && glyph < layout->new_gdef.len)
+    klass = layout->new_gdef.klasses[glyph];
+
+  switch (klass) {
+  default:
+  case GDEF::UnclassifiedGlyph:        return HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED;
+  case GDEF::BaseGlyph:                return HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH;
+  case GDEF::LigatureGlyph:    return HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE;
+  case GDEF::MarkGlyph:                return HB_OT_LAYOUT_GLYPH_CLASS_MARK;
+  case GDEF::ComponentGlyph:   return HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT;
+  }
 }
 
-void
-hb_ot_layout_set_glyph_properties (HB_OT_Layout                    *layout,
-                                  hb_ot_layout_glyph_t             glyph,
-                                  hb_ot_layout_glyph_properties_t  properties)
+hb_ot_layout_glyph_class_t
+hb_ot_layout_get_glyph_class (HB_OT_Layout         *layout,
+                             hb_ot_layout_glyph_t  glyph)
 {
+  hb_ot_layout_glyph_properties_t properties;
+  hb_ot_layout_class_t klass;
 
+  properties = _hb_ot_layout_get_glyph_properties (layout, glyph);
+
+  if (properties & 0xFF)
+    return HB_OT_LAYOUT_GLYPH_CLASS_MARK;
+
+  return (hb_ot_layout_glyph_class_t) properties;
 }
 
+void
+hb_ot_layout_set_glyph_class (HB_OT_Layout               *layout,
+                             hb_ot_layout_glyph_t        glyph,
+                             hb_ot_layout_glyph_class_t  klass)
+{
+  /* TODO optimize this, similar to old harfbuzz code for example */
+  /* TODO our semantics are a bit different from old harfbuzz code too */
+
+  hb_ot_layout_class_t gdef_klass;
+  int len = layout->new_gdef.len;
+
+  if (glyph >= len) {
+    int new_len;
+    uint8_t *new_klasses;
+
+    new_len = len == 0 ? 120 : 2 * len;
+    if (new_len > 65535)
+      new_len = 65535;
+    new_klasses = (uint8_t *) realloc (layout->new_gdef.klasses, new_len * sizeof (uint8_t));
+
+    if (G_UNLIKELY (!new_klasses))
+      return;
+      
+    memset (new_klasses + len, 0, new_len - len);
+
+    layout->new_gdef.klasses = new_klasses;
+    layout->new_gdef.len = new_len;
+  }
+
+  switch (klass) {
+  default:
+  case HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED:  gdef_klass = GDEF::UnclassifiedGlyph;   break;
+  case HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH:    gdef_klass = GDEF::BaseGlyph;           break;
+  case HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE:      gdef_klass = GDEF::LigatureGlyph;       break;
+  case HB_OT_LAYOUT_GLYPH_CLASS_MARK:          gdef_klass = GDEF::MarkGlyph;           break;
+  case HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT:     gdef_klass = GDEF::ComponentGlyph;      break;
+  }
+
+  layout->new_gdef.klasses[glyph] = gdef_klass;
+  return;
+}
index 8419d36..e0eb054 100644 (file)
@@ -38,9 +38,20 @@ typedef uint32_t hb_tag_t;
                                ((const char *) s)[2], \
                                ((const char *) s)[3]))
 
-typedef uint16_t hb_ot_layout_glyph_properties_t;
+typedef enum {
+  HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED        = 0x0000,
+  HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH  = 0x0002,
+  HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE    = 0x0004,
+  HB_OT_LAYOUT_GLYPH_CLASS_MARK                = 0x0008,
+  HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT   = 0x0010
+} hb_ot_layout_glyph_class_t;
+
 typedef uint16_t hb_ot_layout_glyph_t;
 
+/*
+ * HB_OT_Layout
+ */
+
 typedef struct _HB_OT_Layout HB_OT_Layout;
 
 HB_OT_Layout *
@@ -56,14 +67,14 @@ hb_ot_layout_create_sanitize (char *data,
                              make_writable_func);
 */
 
-hb_ot_layout_glyph_properties_t
-hb_ot_layout_get_glyph_properties (HB_OT_Layout                    *layout,
-                                  hb_ot_layout_glyph_t             glyph);
+hb_ot_layout_glyph_class_t
+hb_ot_layout_get_glyph_class (HB_OT_Layout              *layout,
+                             hb_ot_layout_glyph_t       glyph);
 
 void
-hb_ot_layout_set_glyph_properties (HB_OT_Layout                    *layout,
-                                  hb_ot_layout_glyph_t             glyph,
-                                  hb_ot_layout_glyph_properties_t  properties);
+hb_ot_layout_set_glyph_class (HB_OT_Layout              *layout,
+                             hb_ot_layout_glyph_t       glyph,
+                             hb_ot_layout_glyph_class_t klass);
 
 HB_END_DECLS();