[pango/harfbuzz-ng: 33/57] [HB] Use face_t directly instead of ot_layout_t



commit b638ece392bb64c1f43767d98ddc3f446b282d43
Author: Behdad Esfahbod <behdad behdad org>
Date:   Mon Aug 3 21:40:20 2009 -0400

    [HB] Use face_t directly instead of ot_layout_t

 pango/opentype/TODO                             |    1 +
 pango/opentype/hb-font-private.h                |    4 +
 pango/opentype/hb-font.cc                       |   74 ++++++--
 pango/opentype/hb-font.h                        |    3 +
 pango/opentype/hb-object-private.h              |   36 +++--
 pango/opentype/hb-ot-layout-gdef-private.hh     |    2 +
 pango/opentype/hb-ot-layout-gpos-private.hh     |   14 +-
 pango/opentype/hb-ot-layout-gsub-private.hh     |   32 ++--
 pango/opentype/hb-ot-layout-gsubgpos-private.hh |    8 +-
 pango/opentype/hb-ot-layout-private.h           |   40 +++--
 pango/opentype/hb-ot-layout.cc                  |  220 ++++++++++-------------
 11 files changed, 237 insertions(+), 197 deletions(-)
---
diff --git a/pango/opentype/TODO b/pango/opentype/TODO
index 997de7c..3f60543 100644
--- a/pango/opentype/TODO
+++ b/pango/opentype/TODO
@@ -4,3 +4,4 @@
 - HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH vs LookupType::... mess
 - Rename LookupFlag::MarkAttachmentType to LookupFlag:IgnoreSpecialMarks
 - cmap14
+- size_t?
diff --git a/pango/opentype/hb-font-private.h b/pango/opentype/hb-font-private.h
index 8e0fe72..13f07b0 100644
--- a/pango/opentype/hb-font-private.h
+++ b/pango/opentype/hb-font-private.h
@@ -31,6 +31,8 @@
 
 #include "hb-font.h"
 
+#include "hb-ot-layout-private.h"
+
 HB_BEGIN_DECLS
 
 /*
@@ -82,6 +84,8 @@ struct _hb_face_t {
 
   hb_font_callbacks_t *fcallbacks;
   hb_unicode_callbacks_t *ucallbacks;
+
+  hb_ot_layout_t ot_layout;
 };
 
 
diff --git a/pango/opentype/hb-font.cc b/pango/opentype/hb-font.cc
index dbe82ba..c6fca1c 100644
--- a/pango/opentype/hb-font.cc
+++ b/pango/opentype/hb-font.cc
@@ -28,6 +28,7 @@
 
 #include "hb-font-private.h"
 
+#include "hb-open-file-private.hh"
 #include "hb-blob.h"
 
 
@@ -160,6 +161,33 @@ hb_unicode_callbacks_copy (hb_unicode_callbacks_t *other_ucallbacks)
  * hb_face_t
  */
 
+hb_blob_t *
+_hb_face_get_table (hb_tag_t tag, void *user_data)
+{
+  hb_face_t *face = (hb_face_t *) user_data;
+  const char *data = hb_blob_lock (face->blob);
+
+  const OpenTypeFontFile &ot_file = OpenTypeFontFile::get_for_data (data);
+  const OpenTypeFontFace &ot_face = ot_file.get_face (face->index);
+
+  const OpenTypeTable &table = ot_face.get_table_by_tag (tag);
+
+  hb_blob_t *blob = hb_blob_create_sub_blob (face->blob, table.offset, table.length);
+
+  hb_blob_unlock (face->blob);
+
+  return blob;
+}
+
+void
+_hb_face_destroy_blob (void *user_data)
+{
+  hb_face_t *face = (hb_face_t *) user_data;
+
+  hb_blob_destroy (face->blob);
+  face->blob = NULL;
+}
+
 static hb_face_t _hb_face_nil = {
   HB_REFERENCE_COUNT_INVALID, /* ref_count */
 
@@ -175,21 +203,6 @@ static hb_face_t _hb_face_nil = {
 };
 
 hb_face_t *
-hb_face_create_for_data (hb_blob_t    *blob,
-			 unsigned int  index)
-{
-  hb_face_t *face;
-
-  if (!HB_OBJECT_DO_CREATE (face))
-    return &_hb_face_nil;
-
-  face->blob = hb_blob_reference (blob);
-  face->index = index;
-
-  return face;
-}
-
-hb_face_t *
 hb_face_create_for_tables (hb_get_table_func_t  get_table,
 			   hb_destroy_func_t    destroy,
 			   void                *user_data)
@@ -206,6 +219,26 @@ hb_face_create_for_tables (hb_get_table_func_t  get_table,
   face->destroy = destroy;
   face->user_data = user_data;
 
+  _hb_ot_layout_init (&face->ot_layout, face);
+
+  return face;
+}
+
+hb_face_t *
+hb_face_create_for_data (hb_blob_t    *blob,
+			 unsigned int  index)
+{
+  hb_face_t *face;
+
+  face = hb_face_create_for_tables (_hb_face_get_table, NULL, NULL);
+
+  if (!HB_OBJECT_IS_INERT (face)) {
+    face->blob = hb_blob_reference (blob);
+    face->index = index;
+    face->destroy = _hb_face_destroy_blob,
+    face->user_data = face;
+  }
+
   return face;
 }
 
@@ -226,6 +259,8 @@ hb_face_destroy (hb_face_t *face)
 {
   HB_OBJECT_DO_DESTROY (face);
 
+  _hb_ot_layout_fini (&face->ot_layout);
+
   hb_blob_destroy (face->blob);
 
   if (face->destroy)
@@ -261,6 +296,15 @@ hb_face_set_unicode_callbacks (hb_face_t *face,
   face->ucallbacks = ucallbacks;
 }
 
+hb_blob_t *
+hb_face_get_table (hb_face_t *face,
+		   hb_tag_t tag)
+{
+  if (HB_UNLIKELY (!face || !face->get_table))
+    return hb_blob_create_empty ();
+
+  return face->get_table (tag, face->user_data);
+}
 
 
 /*
diff --git a/pango/opentype/hb-font.h b/pango/opentype/hb-font.h
index 71f7eb7..b3c342f 100644
--- a/pango/opentype/hb-font.h
+++ b/pango/opentype/hb-font.h
@@ -156,6 +156,9 @@ void
 hb_face_set_unicode_callbacks (hb_face_t *face,
 			       hb_unicode_callbacks_t *ucallbacks);
 
+hb_blob_t *
+hb_face_get_table (hb_face_t *face,
+		   hb_tag_t tag);
 
 
 /*
diff --git a/pango/opentype/hb-object-private.h b/pango/opentype/hb-object-private.h
index 4ef2823..1d90406 100644
--- a/pango/opentype/hb-object-private.h
+++ b/pango/opentype/hb-object-private.h
@@ -32,19 +32,24 @@
 
 typedef int hb_atomic_int_t;
 
+/* XXX add real atomic ops */
+#define _hb_atomic_fetch_and_add(AI, V) ((AI) += (V), (AI)-(V))
+#define _hb_atomic_int_get(AI) ((AI)+0)
+#define _hb_atomic_int_set(AI, VALUE) HB_STMT_START { (AI) = (VALUE); } HB_STMT_END
+
+
 /* Encapsulate operations on the object's reference count */
 typedef struct {
   hb_atomic_int_t ref_count;
 } hb_reference_count_t;
 
-/* XXX add real atomic ops */
-#define _hb_reference_count_inc(RC) ((RC).ref_count++)
-#define _hb_reference_count_dec_and_test(RC) ((RC).ref_count-- == 1)
+#define _hb_reference_count_inc(RC) _hb_atomic_fetch_and_add ((RC).ref_count, 1)
+#define _hb_reference_count_dec(RC) _hb_atomic_fetch_and_add ((RC).ref_count, -1)
 
 #define HB_REFERENCE_COUNT_INIT(RC, VALUE) ((RC).ref_count = (VALUE))
 
-#define HB_REFERENCE_COUNT_GET_VALUE(RC) ((RC).ref_count+0)
-#define HB_REFERENCE_COUNT_SET_VALUE(RC, VALUE) ((RC).ref_count = (VALUE), 0)
+#define HB_REFERENCE_COUNT_GET_VALUE(RC) _hb_atomic_int_get ((RC).ref_count)
+#define HB_REFERENCE_COUNT_SET_VALUE(RC, VALUE) _hb_atomic_int_set ((RC).ref_count, (VALUE))
 
 #define HB_REFERENCE_COUNT_INVALID_VALUE ((hb_atomic_int_t) -1)
 #define HB_REFERENCE_COUNT_INVALID {HB_REFERENCE_COUNT_INVALID_VALUE}
@@ -58,7 +63,7 @@ typedef struct {
 /* Helper macros */
 
 #define HB_OBJECT_IS_INERT(obj) \
-    ((obj) == NULL || HB_REFERENCE_COUNT_IS_INVALID ((obj)->ref_count))
+    (HB_REFERENCE_COUNT_IS_INVALID ((obj)->ref_count))
 
 #define HB_OBJECT_DO_INIT_EXPR(obj) \
     HB_REFERENCE_COUNT_INIT (obj->ref_count, 1)
@@ -70,33 +75,36 @@ typedef struct {
 
 #define HB_OBJECT_DO_CREATE(obj) \
   HB_LIKELY (( \
-	     (obj) = calloc (1, sizeof (*(obj))), \
+	     (obj) = /* XXX */(typeof (obj)) calloc (1, sizeof (*(obj))), \
 	     HB_OBJECT_DO_INIT_EXPR (obj), \
 	     (obj) \
 	     ))
 
 #define HB_OBJECT_DO_REFERENCE(obj) \
   HB_STMT_START { \
-    if (HB_OBJECT_IS_INERT (obj)) \
+    int old_count; \
+    if (HB_UNLIKELY (!(obj) || HB_OBJECT_IS_INERT (obj))) \
       return obj; \
-    assert (HB_REFERENCE_COUNT_HAS_REFERENCE (obj->ref_count)); \
-    _hb_reference_count_inc (obj->ref_count); \
+    old_count = _hb_reference_count_inc (obj->ref_count); \
+    assert (old_count > 0); \
     return obj; \
   } HB_STMT_END
 
 #define HB_OBJECT_DO_GET_REFERENCE_COUNT(obj) \
   HB_STMT_START { \
-    if (HB_OBJECT_IS_INERT (obj)) \
+    if (HB_UNLIKELY (!(obj) || HB_OBJECT_IS_INERT (obj))) \
       return 0; \
     return HB_REFERENCE_COUNT_GET_VALUE (obj->ref_count); \
   } HB_STMT_END
 
 #define HB_OBJECT_DO_DESTROY(obj) \
   HB_STMT_START { \
-    if (HB_OBJECT_IS_INERT (obj)) \
+    int old_count; \
+    if (HB_UNLIKELY (!(obj) || HB_OBJECT_IS_INERT (obj))) \
       return; \
-    assert (HB_REFERENCE_COUNT_HAS_REFERENCE (obj->ref_count)); \
-    if (!_hb_reference_count_dec_and_test (obj->ref_count)) \
+    old_count = _hb_reference_count_dec (obj->ref_count); \
+    assert (old_count > 0); \
+    if (old_count != 1) \
       return; \
   } HB_STMT_END
 
diff --git a/pango/opentype/hb-ot-layout-gdef-private.hh b/pango/opentype/hb-ot-layout-gdef-private.hh
index b890099..560a07e 100644
--- a/pango/opentype/hb-ot-layout-gdef-private.hh
+++ b/pango/opentype/hb-ot-layout-gdef-private.hh
@@ -29,6 +29,8 @@
 
 #include "hb-ot-layout-common-private.hh"
 
+#include "hb-font-private.h"
+
 
 struct GlyphClassDef : ClassDef
 {
diff --git a/pango/opentype/hb-ot-layout-gpos-private.hh b/pango/opentype/hb-ot-layout-gpos-private.hh
index 8611848..5c817db 100644
--- a/pango/opentype/hb-ot-layout-gpos-private.hh
+++ b/pango/opentype/hb-ot-layout-gpos-private.hh
@@ -394,7 +394,7 @@ struct PairPosFormat1
       return false;
 
     unsigned int j = buffer->in_pos + 1;
-    while (_hb_ot_layout_skip_mark (context->layout, IN_INFO (j), lookup_flag, NULL))
+    while (_hb_ot_layout_skip_mark (context->face, IN_INFO (j), lookup_flag, NULL))
     {
       if (HB_UNLIKELY (j == end))
 	return false;
@@ -459,7 +459,7 @@ struct PairPosFormat2
       return false;
 
     unsigned int j = buffer->in_pos + 1;
-    while (_hb_ot_layout_skip_mark (context->layout, IN_INFO (j), lookup_flag, NULL))
+    while (_hb_ot_layout_skip_mark (context->face, IN_INFO (j), lookup_flag, NULL))
     {
       if (HB_UNLIKELY (j == end))
 	return false;
@@ -794,7 +794,7 @@ struct MarkBasePosFormat1
     /* now we search backwards for a non-mark glyph */
     unsigned int count = buffer->in_pos;
     unsigned int i = 1, j = count - 1;
-    while (_hb_ot_layout_skip_mark (context->layout, IN_INFO (j), LookupFlag::IgnoreMarks, &property))
+    while (_hb_ot_layout_skip_mark (context->face, IN_INFO (j), LookupFlag::IgnoreMarks, &property))
     {
       if (HB_UNLIKELY (i == count))
 	return false;
@@ -912,7 +912,7 @@ struct MarkLigPosFormat1
     /* now we search backwards for a non-mark glyph */
     unsigned int count = buffer->in_pos;
     unsigned int i = 1, j = count - 1;
-    while (_hb_ot_layout_skip_mark (context->layout, IN_INFO (j), LookupFlag::IgnoreMarks, &property))
+    while (_hb_ot_layout_skip_mark (context->face, IN_INFO (j), LookupFlag::IgnoreMarks, &property))
     {
       if (HB_UNLIKELY (i == count))
 	return false;
@@ -1043,7 +1043,7 @@ struct MarkMarkPosFormat1
     /* now we search backwards for a suitable mark glyph until a non-mark glyph */
     unsigned int count = buffer->in_pos;
     unsigned int i = 1, j = count - 1;
-    while (_hb_ot_layout_skip_mark (context->layout, IN_INFO (j), lookup_flag, &property))
+    while (_hb_ot_layout_skip_mark (context->face, IN_INFO (j), lookup_flag, &property))
     {
       if (HB_UNLIKELY (i == count))
 	return false;
@@ -1252,7 +1252,7 @@ struct PosLookup : Lookup
     unsigned int lookup_flag = get_flag ();
     unsigned int property;
 
-    if (!_hb_ot_layout_check_glyph_property (context->layout, IN_CURINFO (), lookup_flag, &property))
+    if (!_hb_ot_layout_check_glyph_property (context->face, IN_CURINFO (), lookup_flag, &property))
       return false;
 
     for (unsigned int i = 0; i < get_subtable_count (); i++)
@@ -1338,7 +1338,7 @@ inline bool ExtensionPos::apply (APPLY_ARG_DEF) const
 
 static inline bool position_lookup (APPLY_ARG_DEF, unsigned int lookup_index)
 {
-  const GPOS &gpos = *(context->layout->gpos);
+  const GPOS &gpos = *(context->face->ot_layout.gpos);
   const PosLookup &l = gpos.get_lookup (lookup_index);
 
   if (HB_UNLIKELY (nesting_level_left == 0))
diff --git a/pango/opentype/hb-ot-layout-gsub-private.hh b/pango/opentype/hb-ot-layout-gsub-private.hh
index 38aa24b..37cc00b 100644
--- a/pango/opentype/hb-ot-layout-gsub-private.hh
+++ b/pango/opentype/hb-ot-layout-gsub-private.hh
@@ -46,8 +46,8 @@ struct SingleSubstFormat1
     _hb_buffer_replace_glyph (buffer, glyph_id);
 
     /* We inherit the old glyph class to the substituted glyph */
-    if (_hb_ot_layout_has_new_glyph_classes (context->layout))
-      _hb_ot_layout_set_glyph_property (context->layout, glyph_id, property);
+    if (_hb_ot_layout_has_new_glyph_classes (context->face))
+      _hb_ot_layout_set_glyph_property (context->face, glyph_id, property);
 
     return true;
   }
@@ -81,8 +81,8 @@ struct SingleSubstFormat2
     _hb_buffer_replace_glyph (buffer, glyph_id);
 
     /* We inherit the old glyph class to the substituted glyph */
-    if (_hb_ot_layout_has_new_glyph_classes (context->layout))
-      _hb_ot_layout_set_glyph_property (context->layout, glyph_id, property);
+    if (_hb_ot_layout_has_new_glyph_classes (context->face))
+      _hb_ot_layout_set_glyph_property (context->face, glyph_id, property);
 
     return true;
   }
@@ -137,14 +137,14 @@ struct Sequence
 				  0xFFFF, 0xFFFF);
 
     /* This is a guess only ... */
-    if (_hb_ot_layout_has_new_glyph_classes (context->layout))
+    if (_hb_ot_layout_has_new_glyph_classes (context->face))
     {
       if (property == HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE)
         property = HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH;
 
       unsigned int count = substitute.len;
       for (unsigned int n = 0; n < count; n++)
-	_hb_ot_layout_set_glyph_property (context->layout, substitute[n], property);
+	_hb_ot_layout_set_glyph_property (context->face, substitute[n], property);
     }
 
     return true;
@@ -229,8 +229,8 @@ struct AlternateSubstFormat1
     unsigned int alt_index = 0;
 
     /* XXX callback to user to choose alternate
-    if (context->layout->altfunc)
-      alt_index = (context->layout->altfunc)(context->layout, buffer,
+    if (context->face->altfunc)
+      alt_index = (context->face->altfunc)(context->layout, buffer,
 				    buffer->out_pos, glyph_id,
 				    alt_set.len, alt_set.array);
 				   */
@@ -243,8 +243,8 @@ struct AlternateSubstFormat1
     _hb_buffer_replace_glyph (buffer, glyph_id);
 
     /* We inherit the old glyph class to the substituted glyph */
-    if (_hb_ot_layout_has_new_glyph_classes (context->layout))
-      _hb_ot_layout_set_glyph_property (context->layout, glyph_id, property);
+    if (_hb_ot_layout_has_new_glyph_classes (context->face))
+      _hb_ot_layout_set_glyph_property (context->face, glyph_id, property);
 
     return true;
   }
@@ -297,7 +297,7 @@ struct Ligature
 
     for (i = 1, j = buffer->in_pos + 1; i < count; i++, j++)
     {
-      while (_hb_ot_layout_skip_mark (context->layout, IN_INFO (j), lookup_flag, &property))
+      while (_hb_ot_layout_skip_mark (context->face, IN_INFO (j), lookup_flag, &property))
       {
 	if (HB_UNLIKELY (j + count - i == end))
 	  return false;
@@ -311,8 +311,8 @@ struct Ligature
         return false;
     }
     /* This is just a guess ... */
-    if (_hb_ot_layout_has_new_glyph_classes (context->layout))
-      _hb_ot_layout_set_glyph_class (context->layout, ligGlyph,
+    if (_hb_ot_layout_has_new_glyph_classes (context->face))
+      _hb_ot_layout_set_glyph_class (context->face, ligGlyph,
 				     is_mark ? HB_OT_LAYOUT_GLYPH_CLASS_MARK
 					     : HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE);
 
@@ -338,7 +338,7 @@ struct Ligature
 
       for ( i = 1; i < count; i++ )
       {
-	while (_hb_ot_layout_skip_mark (context->layout, IN_CURINFO (), lookup_flag, NULL))
+	while (_hb_ot_layout_skip_mark (context->face, IN_CURINFO (), lookup_flag, NULL))
 	  _hb_buffer_add_output_glyph (buffer, IN_CURGLYPH (), i - 1, lig_id);
 
 	(buffer->in_pos)++;
@@ -636,7 +636,7 @@ struct SubstLookup : Lookup
     unsigned int lookup_flag = get_flag ();
     unsigned int property;
 
-    if (!_hb_ot_layout_check_glyph_property (context->layout, IN_CURINFO (), lookup_flag, &property))
+    if (!_hb_ot_layout_check_glyph_property (context->face, IN_CURINFO (), lookup_flag, &property))
       return false;
 
     for (unsigned int i = 0; i < get_subtable_count (); i++)
@@ -734,7 +734,7 @@ inline bool ExtensionSubst::apply (APPLY_ARG_DEF) const
 
 static inline bool substitute_lookup (APPLY_ARG_DEF, unsigned int lookup_index)
 {
-  const GSUB &gsub = *(context->layout->gsub);
+  const GSUB &gsub = *(context->face->ot_layout.gsub);
   const SubstLookup &l = gsub.get_lookup (lookup_index);
 
   if (HB_UNLIKELY (nesting_level_left == 0))
diff --git a/pango/opentype/hb-ot-layout-gsubgpos-private.hh b/pango/opentype/hb-ot-layout-gsubgpos-private.hh
index 7a37509..13f9dba 100644
--- a/pango/opentype/hb-ot-layout-gsubgpos-private.hh
+++ b/pango/opentype/hb-ot-layout-gsubgpos-private.hh
@@ -89,7 +89,7 @@ static inline bool match_input (APPLY_ARG_DEF,
 
   for (i = 1, j = buffer->in_pos + 1; i < count; i++, j++)
   {
-    while (_hb_ot_layout_skip_mark (context->layout, IN_INFO (j), lookup_flag, NULL))
+    while (_hb_ot_layout_skip_mark (context->face, IN_INFO (j), lookup_flag, NULL))
     {
       if (HB_UNLIKELY (j + count - i == end))
 	return false;
@@ -116,7 +116,7 @@ static inline bool match_backtrack (APPLY_ARG_DEF,
 
   for (unsigned int i = 0, j = buffer->out_pos - 1; i < count; i++, j--)
   {
-    while (_hb_ot_layout_skip_mark (context->layout, OUT_INFO (j), lookup_flag, NULL))
+    while (_hb_ot_layout_skip_mark (context->face, OUT_INFO (j), lookup_flag, NULL))
     {
       if (HB_UNLIKELY (j + 1 == count - i))
 	return false;
@@ -144,7 +144,7 @@ static inline bool match_lookahead (APPLY_ARG_DEF,
 
   for (i = 0, j = buffer->in_pos + offset; i < count; i++, j++)
   {
-    while (_hb_ot_layout_skip_mark (context->layout, OUT_INFO (j), lookup_flag, NULL))
+    while (_hb_ot_layout_skip_mark (context->face, OUT_INFO (j), lookup_flag, NULL))
     {
       if (HB_UNLIKELY (j + count - i == end))
 	return false;
@@ -182,7 +182,7 @@ static inline bool apply_lookup (APPLY_ARG_DEF,
    *      Should be easy for in_place ones at least. */
   for (unsigned int i = 0; i < count; i++)
   {
-    while (_hb_ot_layout_skip_mark (context->layout, IN_CURINFO (), lookup_flag, NULL))
+    while (_hb_ot_layout_skip_mark (context->face, IN_CURINFO (), lookup_flag, NULL))
     {
       if (HB_UNLIKELY (buffer->in_pos == end))
 	return true;
diff --git a/pango/opentype/hb-ot-layout-private.h b/pango/opentype/hb-ot-layout-private.h
index 447c750..d3f3abb 100644
--- a/pango/opentype/hb-ot-layout-private.h
+++ b/pango/opentype/hb-ot-layout-private.h
@@ -31,10 +31,12 @@
 
 #include "hb-ot-layout.h"
 
-#include "hb-font-private.h"
+#include "hb-font.h"
 #include "hb-buffer-private.h"
 
 
+HB_BEGIN_DECLS
+
 typedef unsigned int hb_ot_layout_class_t;
 
 /*
@@ -45,6 +47,8 @@ typedef struct _hb_ot_layout_t hb_ot_layout_t;
 
 struct _hb_ot_layout_t
 {
+  hb_face_t *face; /* XXX can do without this */
+
   const struct GDEF *gdef;
   const struct GSUB *gsub;
   const struct GPOS *gpos;
@@ -59,7 +63,7 @@ struct _hb_ot_layout_t
 typedef struct _hb_ot_layout_context_t hb_ot_layout_context_t;
 struct _hb_ot_layout_context_t
 {
-  hb_ot_layout_t *layout;
+  hb_face_t *face;
   hb_font_t *font;
 
   union info_t
@@ -74,40 +78,42 @@ struct _hb_ot_layout_context_t
 };
 
 
-HB_BEGIN_DECLS
+void
+_hb_ot_layout_init (hb_ot_layout_t *layout,
+		    hb_face_t      *face);
+
+void
+_hb_ot_layout_fini (hb_ot_layout_t *layout);
+
 
 /*
  * GDEF
  */
 
 HB_INTERNAL hb_bool_t
-_hb_ot_layout_has_new_glyph_classes (hb_ot_layout_t *layout);
-
-HB_INTERNAL unsigned int
-_hb_ot_layout_get_glyph_property (hb_ot_layout_t *layout,
-				  hb_codepoint_t  glyph);
+_hb_ot_layout_has_new_glyph_classes (hb_face_t *face);
 
 HB_INTERNAL void
-_hb_ot_layout_set_glyph_property (hb_ot_layout_t *layout,
+_hb_ot_layout_set_glyph_property (hb_face_t      *face,
 				  hb_codepoint_t  glyph,
 				  unsigned int    property);
 
 HB_INTERNAL void
-_hb_ot_layout_set_glyph_class (hb_ot_layout_t             *layout,
+_hb_ot_layout_set_glyph_class (hb_face_t                  *face,
 			       hb_codepoint_t              glyph,
 			       hb_ot_layout_glyph_class_t  klass);
 
 HB_INTERNAL hb_bool_t
-_hb_ot_layout_check_glyph_property (hb_ot_layout_t  *layout,
+_hb_ot_layout_check_glyph_property (hb_face_t    *face,
 				    hb_internal_glyph_info_t *ginfo,
-				    unsigned int     lookup_flags,
-				    unsigned int    *property);
+				    unsigned int  lookup_flags,
+				    unsigned int *property);
 
 HB_INTERNAL hb_bool_t
-_hb_ot_layout_skip_mark (hb_ot_layout_t  *layout,
-			  hb_internal_glyph_info_t *ginfo,
-			  unsigned int     lookup_flags,
-			  unsigned int    *property);
+_hb_ot_layout_skip_mark (hb_face_t    *face,
+			 hb_internal_glyph_info_t *ginfo,
+			 unsigned int  lookup_flags,
+			 unsigned int *property);
 
 HB_END_DECLS
 
diff --git a/pango/opentype/hb-ot-layout.cc b/pango/opentype/hb-ot-layout.cc
index 46517fa..eff5966 100644
--- a/pango/opentype/hb-ot-layout.cc
+++ b/pango/opentype/hb-ot-layout.cc
@@ -30,7 +30,6 @@
 
 #include "hb-ot-layout-private.h"
 
-#include "hb-open-file-private.hh"
 #include "hb-ot-layout-gdef-private.hh"
 #include "hb-ot-layout-gsub-private.hh"
 #include "hb-ot-layout-gpos-private.hh"
@@ -41,68 +40,56 @@
 
 
 void
-_hb_ot_layout_init (hb_ot_layout_t *layout,
-		    hb_face_t      *face)
+_hb_ot_layout_init (hb_ot_layout_t *layout)
 {
-  layout->gdef = &Null(GDEF);
-  layout->gsub = &Null(GSUB);
-  layout->gpos = &Null(GPOS);
+  layout->gdef = NULL;
+  layout->gsub = NULL;
+  layout->gpos = NULL;
 }
 
-#if 0
-hb_ot_layout_t *
-hb_ot_layout_create_for_data (const char *font_data,
-			      int         face_index)
+void
+_hb_ot_layout_fini (hb_ot_layout_t *layout)
 {
-  hb_ot_layout_t *layout;
-
-  if (HB_UNLIKELY (font_data == NULL))
-    return hb_ot_layout_create ();
-
-  layout = (hb_ot_layout_t *) calloc (1, sizeof (hb_ot_layout_t));
-
-  const OpenTypeFontFile &font = OpenTypeFontFile::get_for_data (font_data);
-  const OpenTypeFontFace &face = font.get_face (face_index);
-
-  layout->gdef = &GDEF::get_for_data (font.get_table_data (face.get_table_by_tag (GDEF::Tag)));
-  layout->gsub = &GSUB::get_for_data (font.get_table_data (face.get_table_by_tag (GSUB::Tag)));
-  layout->gpos = &GPOS::get_for_data (font.get_table_data (face.get_table_by_tag (GPOS::Tag)));
-
-  return layout;
 }
 
-hb_ot_layout_t *
-hb_ot_layout_create_for_tables (const char *gdef_data,
-				const char *gsub_data,
-				const char *gpos_data)
+static hb_ot_layout_t *
+_hb_ot_face_get_layout (hb_face_t *face)
 {
-  hb_ot_layout_t *layout;
-
-  if (HB_UNLIKELY (gdef_data == NULL && gsub_data == NULL && gpos_data == NULL))
-    return hb_ot_layout_create ();
+  return &face->ot_layout;
+}
 
-  layout = (hb_ot_layout_t *) calloc (1, sizeof (hb_ot_layout_t));
+static const GDEF&
+_get_gdef (hb_face_t *face)
+{
+#if 0
+  if (HB_UNLIKELY (!layout->face))
+    return Null(GDEF);
 
-  layout->gdef = &GDEF::get_for_data (gdef_data);
-  layout->gsub = &GSUB::get_for_data (gsub_data);
-  layout->gpos = &GPOS::get_for_data (gpos_data);
+  if (HB_UNLIKELY (!layout->gdef)) {
+    hb_blob_t *blob = hb_face_get_table (face, HB_OT_TAG_GDEF);
+    unsigned int length;
+    const char *data = hb_blob_get_data (blob, 
+  layout->gdef = &GDEF::get_for_data (font.get_table_data (face.get_table_by_tag (GDEF::Tag)));
+    layout->gdef = &Null(GDEF);
+  }
 
-  return layout;
-}
+  return *layout->gdef;
 #endif
+}
 
-void
-_hb_ot_layout_fini (hb_ot_layout_t *layout,
-		    hb_face_t      *face)
+static const GSUB&
+_get_gsub (hb_face_t *face)
 {
+  return Null(GSUB);
 }
 
-static hb_ot_layout_t *
-_hb_ot_face_get_layout (hb_face_t *face)
+static const GPOS&
+_get_gpos (hb_face_t *face)
 {
-  return NULL; /* XXX */
+  return Null(GPOS);
 }
 
+
 /*
  * GDEF
  */
@@ -112,26 +99,26 @@ _hb_ot_face_get_layout (hb_face_t *face)
 hb_bool_t
 hb_ot_layout_has_font_glyph_classes (hb_face_t *face)
 {
-  hb_ot_layout_t *layout = _hb_ot_face_get_layout (face);
-  return layout->gdef->has_glyph_classes ();
+  return _get_gdef (face).has_glyph_classes ();
 }
 
 HB_INTERNAL hb_bool_t
-_hb_ot_layout_has_new_glyph_classes (hb_ot_layout_t *layout)
+_hb_ot_layout_has_new_glyph_classes (hb_face_t *face)
 {
-  return layout->new_gdef.len > 0;
+  return face->ot_layout.new_gdef.len > 0;
 }
 
-HB_INTERNAL unsigned int
-_hb_ot_layout_get_glyph_property (hb_ot_layout_t *layout,
+static unsigned int
+_hb_ot_layout_get_glyph_property (hb_face_t      *face,
 				  hb_codepoint_t  glyph)
 {
   hb_ot_layout_class_t klass;
+  const GDEF &gdef = _get_gdef (face);
 
-  klass = layout->gdef->get_glyph_class (glyph);
+  klass = gdef.get_glyph_class (glyph);
 
-  if (!klass && glyph < layout->new_gdef.len)
-    klass = layout->new_gdef.klasses[glyph];
+  if (!klass && glyph < face->ot_layout.new_gdef.len)
+    klass = face->ot_layout.new_gdef.klasses[glyph];
 
   switch (klass) {
   default:
@@ -142,21 +129,21 @@ _hb_ot_layout_get_glyph_property (hb_ot_layout_t *layout,
   case GDEF::MarkGlyph:
 	/* 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);
+	klass = gdef.get_mark_attachment_type (glyph);
 	return HB_OT_LAYOUT_GLYPH_CLASS_MARK + (klass << 8);
   }
 }
 
 HB_INTERNAL hb_bool_t
-_hb_ot_layout_check_glyph_property (hb_ot_layout_t  *layout,
+_hb_ot_layout_check_glyph_property (hb_face_t    *face,
 				    hb_internal_glyph_info_t *ginfo,
-				    unsigned int     lookup_flags,
-				    unsigned int    *property_out)
+				    unsigned int  lookup_flags,
+				    unsigned int *property_out)
 {
   unsigned int property;
 
   if (ginfo->gproperty == HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN)
-    ginfo->gproperty = _hb_ot_layout_get_glyph_property (layout, ginfo->codepoint);
+    ginfo->gproperty = _hb_ot_layout_get_glyph_property (face, ginfo->codepoint);
   property = ginfo->gproperty;
   if (property_out)
     *property_out = property;
@@ -173,7 +160,7 @@ _hb_ot_layout_check_glyph_property (hb_ot_layout_t  *layout,
      * lookup_flags has the set index.
      */
     if (lookup_flags & LookupFlag::UseMarkFilteringSet)
-      return layout->gdef->mark_set_covers (lookup_flags >> 16, ginfo->codepoint);
+      return _get_gdef (face).mark_set_covers (lookup_flags >> 16, ginfo->codepoint);
 
     /* The second byte of lookup_flags has the meaning
      * "ignore marks of attachment type different than
@@ -187,15 +174,15 @@ _hb_ot_layout_check_glyph_property (hb_ot_layout_t  *layout,
 }
 
 HB_INTERNAL hb_bool_t
-_hb_ot_layout_skip_mark (hb_ot_layout_t  *layout,
+_hb_ot_layout_skip_mark (hb_face_t    *face,
 			 hb_internal_glyph_info_t *ginfo,
-			 unsigned int     lookup_flags,
-			 unsigned int    *property_out)
+			 unsigned int  lookup_flags,
+			 unsigned int *property_out)
 {
   unsigned int property;
 
   if (ginfo->gproperty == HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN)
-    ginfo->gproperty = _hb_ot_layout_get_glyph_property (layout, ginfo->codepoint);
+    ginfo->gproperty = _hb_ot_layout_get_glyph_property (face, ginfo->codepoint);
   property = ginfo->gproperty;
   if (property_out)
     *property_out = property;
@@ -208,7 +195,7 @@ _hb_ot_layout_skip_mark (hb_ot_layout_t  *layout,
 
     /* If using mark filtering sets, the high short of lookup_flags has the set index. */
     if (lookup_flags & LookupFlag::UseMarkFilteringSet)
-      return !layout->gdef->mark_set_covers (lookup_flags >> 16, ginfo->codepoint);
+      return !_get_gdef (face).mark_set_covers (lookup_flags >> 16, ginfo->codepoint);
 
     /* The second byte of lookup_flags has the meaning "ignore marks of attachment type
      * different than the attachment type specified." */
@@ -220,12 +207,16 @@ _hb_ot_layout_skip_mark (hb_ot_layout_t  *layout,
 }
 
 HB_INTERNAL void
-_hb_ot_layout_set_glyph_class (hb_ot_layout_t             *layout,
+_hb_ot_layout_set_glyph_class (hb_face_t                  *face,
 			       hb_codepoint_t              glyph,
 			       hb_ot_layout_glyph_class_t  klass)
 {
+  if (HB_OBJECT_IS_INERT (face))
+    return;
+
   /* TODO optimize this? similar to old harfbuzz code for example */
 
+  hb_ot_layout_t *layout = &face->ot_layout;
   hb_ot_layout_class_t gdef_klass;
   int len = layout->new_gdef.len;
 
@@ -265,18 +256,17 @@ _hb_ot_layout_set_glyph_class (hb_ot_layout_t             *layout,
 }
 
 HB_INTERNAL void
-_hb_ot_layout_set_glyph_property (hb_ot_layout_t *layout,
+_hb_ot_layout_set_glyph_property (hb_face_t      *face,
 				  hb_codepoint_t  glyph,
 				  unsigned int    property)
-{ _hb_ot_layout_set_glyph_class (layout, glyph, (hb_ot_layout_glyph_class_t) (property & 0xff)); }
+{ _hb_ot_layout_set_glyph_class (face, glyph, (hb_ot_layout_glyph_class_t) (property & 0xff)); }
 
 
 hb_ot_layout_glyph_class_t
 hb_ot_layout_get_glyph_class (hb_face_t      *face,
 			      hb_codepoint_t  glyph)
 {
-  hb_ot_layout_t *layout = _hb_ot_face_get_layout (face);
-  return (hb_ot_layout_glyph_class_t) (_hb_ot_layout_get_glyph_property (layout, glyph) & 0xff);
+  return (hb_ot_layout_glyph_class_t) (_hb_ot_layout_get_glyph_property (face, glyph) & 0xff);
 }
 
 void
@@ -284,8 +274,7 @@ hb_ot_layout_set_glyph_class (hb_face_t                 *face,
 			      hb_codepoint_t             glyph,
 			      hb_ot_layout_glyph_class_t klass)
 {
-  hb_ot_layout_t *layout = _hb_ot_face_get_layout (face);
-  _hb_ot_layout_set_glyph_class (layout, glyph, klass);
+  _hb_ot_layout_set_glyph_class (face, glyph, klass);
 }
 
 void
@@ -295,7 +284,10 @@ hb_ot_layout_build_glyph_classes (hb_face_t      *face,
 				  unsigned char  *klasses,
 				  uint16_t        count)
 {
-  hb_ot_layout_t *layout = _hb_ot_face_get_layout (face);
+  if (HB_OBJECT_IS_INERT (face))
+    return;
+
+  hb_ot_layout_t *layout = &face->ot_layout;
 
   if (HB_UNLIKELY (!count || !glyphs || !klasses))
     return;
@@ -306,7 +298,7 @@ hb_ot_layout_build_glyph_classes (hb_face_t      *face,
   }
 
   for (unsigned int i = 0; i < count; i++)
-    _hb_ot_layout_set_glyph_class (layout, glyphs[i], (hb_ot_layout_glyph_class_t) klasses[i]);
+    _hb_ot_layout_set_glyph_class (face, glyphs[i], (hb_ot_layout_glyph_class_t) klasses[i]);
 }
 
 hb_bool_t
@@ -315,8 +307,7 @@ hb_ot_layout_get_attach_points (hb_face_t      *face,
 				unsigned int   *point_count /* IN/OUT */,
 				unsigned int   *point_array /* OUT */)
 {
-  hb_ot_layout_t *layout = _hb_ot_face_get_layout (face);
-  return layout->gdef->get_attach_points (glyph, point_count, point_array);
+  return _get_gdef (face).get_attach_points (glyph, point_count, point_array);
 }
 
 hb_bool_t
@@ -328,8 +319,8 @@ hb_ot_layout_get_lig_carets (hb_face_t      *face,
 {
   hb_ot_layout_context_t context;
   context.font = font;
-  context.layout = _hb_ot_face_get_layout (face);
-  return context.layout->gdef->get_lig_carets (&context, glyph, caret_count, caret_array);
+  context.face = face;
+  return _get_gdef (face).get_lig_carets (&context, glyph, caret_count, caret_array);
 }
 
 /*
@@ -337,12 +328,12 @@ hb_ot_layout_get_lig_carets (hb_face_t      *face,
  */
 
 static const GSUBGPOS&
-get_gsubgpos_table (hb_ot_layout_t *layout,
-		    hb_tag_t        table_tag)
+get_gsubgpos_table (hb_face_t *face,
+		    hb_tag_t   table_tag)
 {
   switch (table_tag) {
-    case HB_OT_TAG_GSUB: return *(layout->gsub);
-    case HB_OT_TAG_GPOS: return *(layout->gpos);
+    case HB_OT_TAG_GSUB: return _get_gsub (face);
+    case HB_OT_TAG_GPOS: return _get_gpos (face);
     default:             return Null(GSUBGPOS);
   }
 }
@@ -352,8 +343,7 @@ unsigned int
 hb_ot_layout_table_get_script_count (hb_face_t *face,
 				     hb_tag_t   table_tag)
 {
-  hb_ot_layout_t *layout = _hb_ot_face_get_layout (face);
-  const GSUBGPOS &g = get_gsubgpos_table (layout, table_tag);
+  const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
 
   return g.get_script_count ();
 }
@@ -363,8 +353,7 @@ hb_ot_layout_table_get_script_tag (hb_face_t    *face,
 				   hb_tag_t      table_tag,
 				   unsigned int  script_index)
 {
-  hb_ot_layout_t *layout = _hb_ot_face_get_layout (face);
-  const GSUBGPOS &g = get_gsubgpos_table (layout, table_tag);
+  const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
 
   return g.get_script_tag (script_index);
 }
@@ -376,8 +365,7 @@ hb_ot_layout_table_find_script (hb_face_t    *face,
 				unsigned int *script_index)
 {
   ASSERT_STATIC (NO_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX);
-  hb_ot_layout_t *layout = _hb_ot_face_get_layout (face);
-  const GSUBGPOS &g = get_gsubgpos_table (layout, table_tag);
+  const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
 
   if (g.find_script_index (script_tag, script_index))
     return TRUE;
@@ -398,8 +386,7 @@ unsigned int
 hb_ot_layout_table_get_feature_count (hb_face_t *face,
 				      hb_tag_t   table_tag)
 {
-  hb_ot_layout_t *layout = _hb_ot_face_get_layout (face);
-  const GSUBGPOS &g = get_gsubgpos_table (layout, table_tag);
+  const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
 
   return g.get_feature_count ();
 }
@@ -409,8 +396,7 @@ hb_ot_layout_table_get_feature_tag (hb_face_t    *face,
 				    hb_tag_t      table_tag,
 				    unsigned int  feature_index)
 {
-  hb_ot_layout_t *layout = _hb_ot_face_get_layout (face);
-  const GSUBGPOS &g = get_gsubgpos_table (layout, table_tag);
+  const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
 
   return g.get_feature_tag (feature_index);
 }
@@ -422,8 +408,7 @@ hb_ot_layout_table_find_feature (hb_face_t    *face,
 				 unsigned int *feature_index)
 {
   ASSERT_STATIC (NO_INDEX == HB_OT_LAYOUT_NO_FEATURE_INDEX);
-  hb_ot_layout_t *layout = _hb_ot_face_get_layout (face);
-  const GSUBGPOS &g = get_gsubgpos_table (layout, table_tag);
+  const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
 
   if (g.find_feature_index (feature_tag, feature_index))
     return TRUE;
@@ -436,8 +421,7 @@ unsigned int
 hb_ot_layout_table_get_lookup_count (hb_face_t *face,
 				     hb_tag_t   table_tag)
 {
-  hb_ot_layout_t *layout = _hb_ot_face_get_layout (face);
-  const GSUBGPOS &g = get_gsubgpos_table (layout, table_tag);
+  const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
 
   return g.get_lookup_count ();
 }
@@ -448,8 +432,7 @@ hb_ot_layout_script_get_language_count (hb_face_t    *face,
 					hb_tag_t      table_tag,
 					unsigned int  script_index)
 {
-  hb_ot_layout_t *layout = _hb_ot_face_get_layout (face);
-  const Script &s = get_gsubgpos_table (layout, table_tag).get_script (script_index);
+  const Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index);
 
   return s.get_lang_sys_count ();
 }
@@ -460,8 +443,7 @@ hb_ot_layout_script_get_language_tag (hb_face_t    *face,
 				      unsigned int  script_index,
 				      unsigned int  language_index)
 {
-  hb_ot_layout_t *layout = _hb_ot_face_get_layout (face);
-  const Script &s = get_gsubgpos_table (layout, table_tag).get_script (script_index);
+  const Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index);
 
   return s.get_lang_sys_tag (language_index);
 }
@@ -474,8 +456,7 @@ hb_ot_layout_script_find_language (hb_face_t    *face,
 				   unsigned int *language_index)
 {
   ASSERT_STATIC (NO_INDEX == HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX);
-  hb_ot_layout_t *layout = _hb_ot_face_get_layout (face);
-  const Script &s = get_gsubgpos_table (layout, table_tag).get_script (script_index);
+  const Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index);
 
   if (s.find_lang_sys_index (language_tag, language_index))
     return TRUE;
@@ -495,8 +476,7 @@ hb_ot_layout_language_get_required_feature_index (hb_face_t    *face,
 						  unsigned int  language_index,
 						  unsigned int *feature_index)
 {
-  hb_ot_layout_t *layout = _hb_ot_face_get_layout (face);
-  const LangSys &l = get_gsubgpos_table (layout, table_tag).get_script (script_index).get_lang_sys (language_index);
+  const LangSys &l = get_gsubgpos_table (face, table_tag).get_script (script_index).get_lang_sys (language_index);
 
   if (feature_index) *feature_index = l.get_required_feature_index ();
 
@@ -509,8 +489,7 @@ hb_ot_layout_language_get_feature_count (hb_face_t    *face,
 					 unsigned int  script_index,
 					 unsigned int  language_index)
 {
-  hb_ot_layout_t *layout = _hb_ot_face_get_layout (face);
-  const LangSys &l = get_gsubgpos_table (layout, table_tag).get_script (script_index).get_lang_sys (language_index);
+  const LangSys &l = get_gsubgpos_table (face, table_tag).get_script (script_index).get_lang_sys (language_index);
 
   return l.get_feature_count ();
 }
@@ -522,8 +501,7 @@ hb_ot_layout_language_get_feature_index (hb_face_t    *face,
 					 unsigned int  language_index,
 					 unsigned int  num_feature)
 {
-  hb_ot_layout_t *layout = _hb_ot_face_get_layout (face);
-  const GSUBGPOS &g = get_gsubgpos_table (layout, table_tag);
+  const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
   const LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
 
   return l.get_feature_index (num_feature);
@@ -536,8 +514,7 @@ hb_ot_layout_language_get_feature_tag (hb_face_t    *face,
 				       unsigned int  language_index,
 				       unsigned int  num_feature)
 {
-  hb_ot_layout_t *layout = _hb_ot_face_get_layout (face);
-  const GSUBGPOS &g = get_gsubgpos_table (layout, table_tag);
+  const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
   const LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
   unsigned int feature_index = l.get_feature_index (num_feature);
 
@@ -554,8 +531,7 @@ hb_ot_layout_language_find_feature (hb_face_t    *face,
 				    unsigned int *feature_index)
 {
   ASSERT_STATIC (NO_INDEX == HB_OT_LAYOUT_NO_FEATURE_INDEX);
-  hb_ot_layout_t *layout = _hb_ot_face_get_layout (face);
-  const GSUBGPOS &g = get_gsubgpos_table (layout, table_tag);
+  const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
   const LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
 
   unsigned int num_features = l.get_feature_count ();
@@ -577,8 +553,7 @@ hb_ot_layout_feature_get_lookup_count (hb_face_t    *face,
 				       hb_tag_t      table_tag,
 				       unsigned int  feature_index)
 {
-  hb_ot_layout_t *layout = _hb_ot_face_get_layout (face);
-  const GSUBGPOS &g = get_gsubgpos_table (layout, table_tag);
+  const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
   const Feature &f = g.get_feature (feature_index);
 
   return f.get_lookup_count ();
@@ -590,8 +565,7 @@ hb_ot_layout_feature_get_lookup_index (hb_face_t    *face,
 				       unsigned int  feature_index,
 				       unsigned int  num_lookup)
 {
-  hb_ot_layout_t *layout = _hb_ot_face_get_layout (face);
-  const GSUBGPOS &g = get_gsubgpos_table (layout, table_tag);
+  const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
   const Feature &f = g.get_feature (feature_index);
 
   return f.get_lookup_index (num_lookup);
@@ -604,8 +578,7 @@ hb_ot_layout_feature_get_lookup_index (hb_face_t    *face,
 hb_bool_t
 hb_ot_layout_has_substitution (hb_face_t *face)
 {
-  hb_ot_layout_t *layout = _hb_ot_face_get_layout (face);
-  return layout->gsub != &Null(GSUB);
+  return &_get_gsub (face) != &Null(GSUB);
 }
 
 hb_bool_t
@@ -616,8 +589,8 @@ hb_ot_layout_substitute_lookup (hb_face_t                   *face,
 {
   hb_ot_layout_context_t context;
   context.font = NULL;
-  context.layout = _hb_ot_face_get_layout (face);
-  return context.layout->gsub->substitute_lookup (&context, buffer, lookup_index, mask);
+  context.face = face;
+  return _get_gsub (face).substitute_lookup (&context, buffer, lookup_index, mask);
 }
 
 /*
@@ -627,8 +600,7 @@ hb_ot_layout_substitute_lookup (hb_face_t                   *face,
 hb_bool_t
 hb_ot_layout_has_positioning (hb_face_t *face)
 {
-  hb_ot_layout_t *layout = _hb_ot_face_get_layout (face);
-  return layout->gpos != &Null(GPOS);
+  return &_get_gpos (face) != &Null(GPOS);
 }
 
 hb_bool_t
@@ -640,6 +612,6 @@ hb_ot_layout_position_lookup   (hb_face_t                   *face,
 {
   hb_ot_layout_context_t context;
   context.font = font;
-  context.layout = _hb_ot_face_get_layout (font->face);
-  return context.layout->gpos->position_lookup (&context, buffer, lookup_index, mask);
+  context.face = face;
+  return _get_gpos (face).position_lookup (&context, buffer, lookup_index, mask);
 }



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