diff --git a/src/hb-font.cc b/src/hb-font.cc index c6fca1c9e..b82fd2877 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -27,11 +27,11 @@ #include "hb-private.h" #include "hb-font-private.h" +#include "hb-ot-layout-private.h" #include "hb-open-file-private.hh" #include "hb-blob.h" - /* * hb_font_callbacks_t */ @@ -167,6 +167,8 @@ _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); + /* XXX sanitize */ + const OpenTypeFontFile &ot_file = OpenTypeFontFile::get_for_data (data); const OpenTypeFontFace &ot_face = ot_file.get_face (face->index); @@ -219,7 +221,7 @@ 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); + _hb_ot_layout_init (face); return face; } @@ -230,14 +232,15 @@ hb_face_create_for_data (hb_blob_t *blob, { hb_face_t *face; - face = hb_face_create_for_tables (_hb_face_get_table, NULL, NULL); + if (!HB_OBJECT_DO_CREATE (face)) + return &_hb_face_nil; - 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; - } + face->blob = hb_blob_reference (blob); + face->index = index; + face->get_table = _hb_face_get_table; + face->user_data = face; + + _hb_ot_layout_init (face); return face; } @@ -259,7 +262,7 @@ hb_face_destroy (hb_face_t *face) { HB_OBJECT_DO_DESTROY (face); - _hb_ot_layout_fini (&face->ot_layout); + _hb_ot_layout_fini (face); hb_blob_destroy (face->blob); diff --git a/src/hb-ot-layout-private.h b/src/hb-ot-layout-private.h index d3f3abbbb..404301448 100644 --- a/src/hb-ot-layout-private.h +++ b/src/hb-ot-layout-private.h @@ -49,6 +49,10 @@ struct _hb_ot_layout_t { hb_face_t *face; /* XXX can do without this */ + hb_blob_t *gdef_blob; + hb_blob_t *gsub_blob; + hb_blob_t *gpos_blob; + const struct GDEF *gdef; const struct GSUB *gsub; const struct GPOS *gpos; @@ -79,11 +83,10 @@ struct _hb_ot_layout_context_t void -_hb_ot_layout_init (hb_ot_layout_t *layout, - hb_face_t *face); +_hb_ot_layout_init (hb_face_t *face); void -_hb_ot_layout_fini (hb_ot_layout_t *layout); +_hb_ot_layout_fini (hb_face_t *face); /* diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index c7158bd08..eef768d18 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -40,53 +40,52 @@ void -_hb_ot_layout_init (hb_ot_layout_t *layout) +_hb_ot_layout_init (hb_face_t *face) { - layout->gdef = NULL; - layout->gsub = NULL; - layout->gpos = NULL; + hb_ot_layout_t *layout = &face->ot_layout; + + /* XXX sanitize */ + + layout->gdef_blob = hb_face_get_table (face, HB_OT_TAG_GDEF); + layout->gdef = &GDEF::get_for_data (hb_blob_lock (layout->gdef_blob)); + + layout->gsub_blob = hb_face_get_table (face, HB_OT_TAG_GSUB); + layout->gsub = &GSUB::get_for_data (hb_blob_lock (layout->gsub_blob)); + + layout->gpos_blob = hb_face_get_table (face, HB_OT_TAG_GPOS); + layout->gpos = &GPOS::get_for_data (hb_blob_lock (layout->gpos_blob)); } void -_hb_ot_layout_fini (hb_ot_layout_t *layout) +_hb_ot_layout_fini (hb_face_t *face) { -} + hb_ot_layout_t *layout = &face->ot_layout; -static hb_ot_layout_t * -_hb_ot_face_get_layout (hb_face_t *face) -{ - return &face->ot_layout; + hb_blob_unlock (layout->gdef_blob); + hb_blob_unlock (layout->gsub_blob); + hb_blob_unlock (layout->gpos_blob); + + hb_blob_destroy (layout->gdef_blob); + hb_blob_destroy (layout->gsub_blob); + hb_blob_destroy (layout->gpos_blob); } static const GDEF& _get_gdef (hb_face_t *face) { -#if 0 - if (HB_UNLIKELY (!layout->face)) - return Null(GDEF); - - 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->gdef; -#endif + return HB_LIKELY (face->ot_layout.gdef) ? *face->ot_layout.gdef : Null(GDEF); } static const GSUB& _get_gsub (hb_face_t *face) { - return Null(GSUB); + return HB_LIKELY (face->ot_layout.gsub) ? *face->ot_layout.gsub : Null(GSUB); } static const GPOS& _get_gpos (hb_face_t *face) { - return Null(GPOS); + return HB_LIKELY (face->ot_layout.gpos) ? *face->ot_layout.gpos : Null(GPOS); }