From 23c86aa0009324433e78fcd0c47f2c0ff14b1949 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 3 Aug 2009 21:40:20 -0400 Subject: [PATCH] [HB] Use face_t directly instead of ot_layout_t --- src/TODO | 1 + src/hb-font-private.h | 4 + src/hb-font.cc | 74 +++++++++--- src/hb-font.h | 3 + src/hb-object-private.h | 36 +++--- src/hb-ot-layout-gdef-private.hh | 2 + src/hb-ot-layout-gpos-private.hh | 14 +-- src/hb-ot-layout-gsub-private.hh | 32 ++--- src/hb-ot-layout-gsubgpos-private.hh | 8 +- src/hb-ot-layout-private.h | 40 ++++--- src/hb-ot-layout.cc | 220 +++++++++++++++-------------------- 11 files changed, 237 insertions(+), 197 deletions(-) diff --git a/src/TODO b/src/TODO index 997de7c..3f60543 100644 --- a/src/TODO +++ b/src/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/src/hb-font-private.h b/src/hb-font-private.h index 8e0fe72..13f07b0 100644 --- a/src/hb-font-private.h +++ b/src/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/src/hb-font.cc b/src/hb-font.cc index dbe82ba..c6fca1c 100644 --- a/src/hb-font.cc +++ b/src/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/src/hb-font.h b/src/hb-font.h index 71f7eb7..b3c342f 100644 --- a/src/hb-font.h +++ b/src/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/src/hb-object-private.h b/src/hb-object-private.h index 4ef2823..1d90406 100644 --- a/src/hb-object-private.h +++ b/src/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/src/hb-ot-layout-gdef-private.hh b/src/hb-ot-layout-gdef-private.hh index b890099..560a07e 100644 --- a/src/hb-ot-layout-gdef-private.hh +++ b/src/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/src/hb-ot-layout-gpos-private.hh b/src/hb-ot-layout-gpos-private.hh index 8611848..5c817db 100644 --- a/src/hb-ot-layout-gpos-private.hh +++ b/src/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/src/hb-ot-layout-gsub-private.hh b/src/hb-ot-layout-gsub-private.hh index 38aa24b..37cc00b 100644 --- a/src/hb-ot-layout-gsub-private.hh +++ b/src/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/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh index 7a37509..13f9dba 100644 --- a/src/hb-ot-layout-gsubgpos-private.hh +++ b/src/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/src/hb-ot-layout-private.h b/src/hb-ot-layout-private.h index 447c750..d3f3abb 100644 --- a/src/hb-ot-layout-private.h +++ b/src/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/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 46517fa..c7158bd 100644 --- a/src/hb-ot-layout.cc +++ b/src/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); } -- 2.7.4