From 590d55cbb9e21ef74dfd88eee51fd0a763958cd2 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 24 Jan 2008 19:13:50 -0500 Subject: [PATCH] [GDEF] Finish public API --- src/hb-common.h | 11 +++ src/hb-ot-layout-gdef-private.h | 28 ++++---- src/hb-ot-layout-open-private.h | 25 ++++--- src/hb-ot-layout-private.h | 23 ++---- src/hb-ot-layout.cc | 123 +++++++++++++++++++++++++++++--- src/hb-ot-layout.h | 29 ++++---- 6 files changed, 176 insertions(+), 63 deletions(-) diff --git a/src/hb-common.h b/src/hb-common.h index 9899a705d..c60ad8404 100644 --- a/src/hb-common.h +++ b/src/hb-common.h @@ -37,4 +37,15 @@ # define HB_END_DECLS() extern int hb_dummy_prototype (int) # endif /* !__cplusplus */ +typedef int hb_bool_t; + +typedef uint32_t hb_tag_t; +#define HB_TAG(a,b,c,d) ((hb_tag_t)(((uint8_t)a<<24)|((uint8_t)b<<16)|((uint8_t)c<<8)|(uint8_t)d)) +#define HB_TAG_STR(s) (HB_TAG(((const char *) s)[0], \ + ((const char *) s)[1], \ + ((const char *) s)[2], \ + ((const char *) s)[3])) + +typedef uint16_t hb_glyph_t; + #endif /* HB_COMMON_H */ diff --git a/src/hb-ot-layout-gdef-private.h b/src/hb-ot-layout-gdef-private.h index 5d4759f93..447ee0e4a 100644 --- a/src/hb-ot-layout-gdef-private.h +++ b/src/hb-ot-layout-gdef-private.h @@ -33,7 +33,7 @@ #define DEFINE_INDIRECT_GLYPH_ARRAY_LOOKUP(Type, name) \ - inline const Type& name (hb_ot_layout_glyph_t glyph_id) { \ + inline const Type& name (hb_glyph_t glyph_id) { \ const Coverage &c = get_coverage (); \ hb_ot_layout_coverage_t c_index = c.get_coverage (glyph_id); \ return (*this)[c_index]; \ @@ -72,13 +72,13 @@ struct AttachList { friend struct GDEF; private: - /* const AttachPoint& get_attach_points (hb_ot_layout_glyph_t glyph_id); */ + /* const AttachPoint& get_attach_points (hb_glyph_t glyph_id); */ DEFINE_INDIRECT_GLYPH_ARRAY_LOOKUP (AttachPoint, get_attach_points); private: /* AttachPoint tables, in Coverage Index order */ DEFINE_OFFSET_ARRAY_TYPE (AttachPoint, attachPoint, glyphCount); - DEFINE_ACCESSOR (Coverage, get_coverage, coverage); + DEFINE_GET_ACCESSOR (Coverage, coverage, coverage); private: Offset coverage; /* Offset to Coverage table -- from @@ -205,13 +205,13 @@ struct LigCaretList { friend struct GDEF; private: - /* const LigGlyph& get_lig_glyph (hb_ot_layout_glyph_t glyph_id); */ + /* const LigGlyph& get_lig_glyph (hb_glyph_t glyph_id); */ DEFINE_INDIRECT_GLYPH_ARRAY_LOOKUP (LigGlyph, get_lig_glyph); private: /* AttachPoint tables, in Coverage Index order */ DEFINE_OFFSET_ARRAY_TYPE (LigGlyph, ligGlyph, ligGlyphCount); - DEFINE_ACCESSOR (Coverage, get_coverage, coverage); + DEFINE_GET_ACCESSOR (Coverage, coverage, coverage); private: Offset coverage; /* Offset to Coverage table--from @@ -240,19 +240,17 @@ struct GDEF { STATIC_DEFINE_GET_FOR_DATA (GDEF); /* XXX check version here? */ - DEFINE_ACCESSOR (ClassDef, get_glyph_class_def, glyphClassDef); - DEFINE_ACCESSOR (AttachList, get_attach_list, attachList); - DEFINE_ACCESSOR (LigCaretList, get_lig_caret_list, ligCaretList); - DEFINE_ACCESSOR (ClassDef, get_mark_attach_class_def, markAttachClassDef); + DEFINE_GET_HAS_ACCESSOR (ClassDef, glyph_classes, glyphClassDef); + DEFINE_GET_HAS_ACCESSOR (AttachList, attach_list, attachList); + DEFINE_GET_HAS_ACCESSOR (LigCaretList, lig_caret_list, ligCaretList); + DEFINE_GET_HAS_ACCESSOR (ClassDef, mark_attachment_types, markAttachClassDef); - /* Returns 0 if not found. */ - 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); + inline hb_ot_layout_class_t get_glyph_class (hb_glyph_t glyph_id) const { + return get_glyph_classes ().get_class (glyph_id); } - /* Returns 0 if not found. */ - 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); + inline hb_ot_layout_class_t get_mark_attachment_type (hb_glyph_t glyph_id) const { + return get_mark_attachment_types ().get_class (glyph_id); } /* TODO get_attach and get_lig_caret */ diff --git a/src/hb-ot-layout-open-private.h b/src/hb-ot-layout-open-private.h index 3d125d987..94ff209bf 100644 --- a/src/hb-ot-layout-open-private.h +++ b/src/hb-ot-layout-open-private.h @@ -186,11 +186,16 @@ } -#define DEFINE_ACCESSOR(Type, name, Name) \ - inline const Type& name (void) const { \ +#define DEFINE_GET_ACCESSOR(Type, name, Name) \ + inline const Type& get_##name (void) const { \ if (HB_UNLIKELY (!Name)) return Null##Type; \ return *(const Type*)((const char*)this + Name); \ } +#define DEFINE_GET_HAS_ACCESSOR(Type, name, Name) \ + DEFINE_GET_ACCESSOR (Type, name, Name); \ + inline bool has_##name (void) const { \ + return Name != 0; \ + } @@ -633,7 +638,7 @@ struct CoverageFormat1 { /* GlyphIDs, in sorted numerical order */ DEFINE_ARRAY_TYPE (GlyphID, glyphArray, glyphCount); - inline hb_ot_layout_coverage_t get_coverage (hb_ot_layout_glyph_t glyph_id) const { + inline hb_ot_layout_coverage_t get_coverage (hb_glyph_t glyph_id) const { GlyphID gid; gid = glyph_id; // TODO: bsearch @@ -655,7 +660,7 @@ struct CoverageRangeRecord { friend struct CoverageFormat2; private: - inline hb_ot_layout_coverage_t get_coverage (hb_ot_layout_glyph_t glyph_id) const { + inline hb_ot_layout_coverage_t get_coverage (hb_glyph_t glyph_id) const { if (glyph_id >= start && glyph_id <= end) return startCoverageIndex + (glyph_id - start); return -1; @@ -677,7 +682,7 @@ struct CoverageFormat2 { /* CoverageRangeRecords, in sorted numerical start order */ DEFINE_ARRAY_TYPE (CoverageRangeRecord, rangeRecord, rangeCount); - inline hb_ot_layout_coverage_t get_coverage (hb_ot_layout_glyph_t glyph_id) const { + inline hb_ot_layout_coverage_t get_coverage (hb_glyph_t glyph_id) const { // TODO: bsearch for (unsigned int i = 0; i < rangeCount; i++) { int coverage = rangeRecord[i].get_coverage (glyph_id); @@ -707,7 +712,7 @@ struct Coverage { } } - hb_ot_layout_coverage_t get_coverage (hb_ot_layout_glyph_t glyph_id) const { + hb_ot_layout_coverage_t get_coverage (hb_glyph_t glyph_id) const { switch (u.coverageFormat) { case 1: return u.format1.get_coverage(glyph_id); case 2: return u.format2.get_coverage(glyph_id); @@ -736,7 +741,7 @@ struct ClassDefFormat1 { /* GlyphIDs, in sorted numerical order */ DEFINE_ARRAY_TYPE (USHORT, classValueArray, glyphCount); - inline hb_ot_layout_class_t get_class (hb_ot_layout_glyph_t glyph_id) const { + inline hb_ot_layout_class_t get_class (hb_glyph_t glyph_id) const { if (glyph_id >= startGlyph && glyph_id - startGlyph < glyphCount) return classValueArray[glyph_id - startGlyph]; return 0; @@ -755,7 +760,7 @@ struct ClassRangeRecord { friend struct ClassDefFormat2; private: - inline hb_ot_layout_class_t get_class (hb_ot_layout_glyph_t glyph_id) const { + inline hb_ot_layout_class_t get_class (hb_glyph_t glyph_id) const { if (glyph_id >= start && glyph_id <= end) return classValue; return 0; @@ -776,7 +781,7 @@ struct ClassDefFormat2 { /* ClassRangeRecords, in sorted numerical start order */ DEFINE_ARRAY_TYPE (ClassRangeRecord, rangeRecord, rangeCount); - inline hb_ot_layout_class_t get_class (hb_ot_layout_glyph_t glyph_id) const { + inline hb_ot_layout_class_t get_class (hb_glyph_t glyph_id) const { // TODO: bsearch for (int i = 0; i < rangeCount; i++) { int classValue = rangeRecord[i].get_class (glyph_id); @@ -805,7 +810,7 @@ struct ClassDef { } } - inline hb_ot_layout_class_t get_class (hb_ot_layout_glyph_t glyph_id) const { + hb_ot_layout_class_t get_class (hb_glyph_t glyph_id) const { switch (u.classFormat) { case 1: return u.format1.get_class(glyph_id); case 2: return u.format2.get_class(glyph_id); diff --git a/src/hb-ot-layout-private.h b/src/hb-ot-layout-private.h index 55f14f8ab..f5fc30e14 100644 --- a/src/hb-ot-layout-private.h +++ b/src/hb-ot-layout-private.h @@ -38,28 +38,15 @@ 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; - -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_ot_layout_get_glyph_properties (HB_OT_Layout *layout, + hb_glyph_t glyph); + +static hb_bool_t +_hb_ot_layout_has_new_glyph_classes (HB_OT_Layout *layout); HB_END_DECLS(); diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 5fc9f8f57..8b9b90541 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -37,6 +37,18 @@ #include +struct _HB_OT_Layout { + const GDEF *gdef; + const GSUB *gsub; +//const GPOS *gpos; + + struct { + unsigned char *klasses; + unsigned int len; + } new_gdef; + +}; + HB_OT_Layout * hb_ot_layout_create (const char *font_data, int face_index) @@ -59,9 +71,25 @@ hb_ot_layout_destroy (HB_OT_Layout *layout) free (layout); } +/* + * GDEF + */ + +hb_bool_t +hb_ot_layout_has_font_glyph_classes (HB_OT_Layout *layout) +{ + return layout->gdef->has_glyph_classes (); +} + +static hb_bool_t +_hb_ot_layout_has_new_glyph_classes (HB_OT_Layout *layout) +{ + return layout->new_gdef.len > 0; +} + 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_get_glyph_properties (HB_OT_Layout *layout, + hb_glyph_t glyph) { hb_ot_layout_class_t klass; @@ -86,9 +114,68 @@ _hb_ot_layout_get_glyph_properties (HB_OT_Layout *layout, } } +#if 0 +static bool +_hb_ot_layout_check_glyph_properties (HB_OT_Layout *layout, + HB_GlyphItem gitem, + HB_UShort flags, + HB_UShort* property) +{ + HB_Error error; + + if ( gdef ) + { + HB_UShort basic_glyph_class; + HB_UShort desired_attachment_class; + + if ( gitem->gproperties == HB_GLYPH_PROPERTIES_UNKNOWN ) + { + error = HB_GDEF_Get_Glyph_Property( gdef, gitem->gindex, &gitem->gproperties ); + if ( error ) + return error; + } + + *property = gitem->gproperties; + + /* If the glyph was found in the MarkAttachmentClass table, + * then that class value is the high byte of the result, + * otherwise the low byte contains the basic type of the glyph + * as defined by the GlyphClassDef table. + */ + if ( *property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS ) + basic_glyph_class = HB_GDEF_MARK; + else + basic_glyph_class = *property; + + /* Return Not_Covered, if, for example, basic_glyph_class + * is HB_GDEF_LIGATURE and LookFlags includes HB_LOOKUP_FLAG_IGNORE_LIGATURES + */ + if ( flags & basic_glyph_class ) + return HB_Err_Not_Covered; + + /* The high byte of LookupFlags has the meaning + * "ignore marks of attachment type different than + * the attachment type specified." + */ + desired_attachment_class = flags & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS; + if ( desired_attachment_class ) + { + if ( basic_glyph_class == HB_GDEF_MARK && + *property != desired_attachment_class ) + return HB_Err_Not_Covered; + } + } else { + *property = 0; + } + + return HB_Err_Ok; +} +#endif + + 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_get_glyph_class (HB_OT_Layout *layout, + hb_glyph_t glyph) { hb_ot_layout_glyph_properties_t properties; hb_ot_layout_class_t klass; @@ -103,23 +190,22 @@ hb_ot_layout_get_glyph_class (HB_OT_Layout *layout, void hb_ot_layout_set_glyph_class (HB_OT_Layout *layout, - hb_ot_layout_glyph_t glyph, + hb_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; + unsigned char *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)); + new_klasses = (unsigned char *) realloc (layout->new_gdef.klasses, new_len * sizeof (unsigned char)); if (G_UNLIKELY (!new_klasses)) return; @@ -142,3 +228,24 @@ hb_ot_layout_set_glyph_class (HB_OT_Layout *layout, layout->new_gdef.klasses[glyph] = gdef_klass; return; } + +void +hb_ot_layout_build_glyph_classes (HB_OT_Layout *layout, + uint16_t num_total_glyphs, + hb_glyph_t *glyphs, + unsigned char *klasses, + uint16_t count) +{ + int i; + + if (G_UNLIKELY (!count || !glyphs || !klasses)) + return; + + if (layout->new_gdef.len == 0) { + layout->new_gdef.klasses = (unsigned char *) calloc (num_total_glyphs, sizeof (unsigned char)); + layout->new_gdef.len = count; + } + + for (i = 0; i < count; i++) + hb_ot_layout_set_glyph_class (layout, glyphs[i], (hb_ot_layout_glyph_class_t) klasses[i]); +} diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index e0eb054e7..4ac6e380f 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -31,13 +31,6 @@ HB_BEGIN_DECLS(); -typedef uint32_t hb_tag_t; -#define HB_TAG(a,b,c,d) ((hb_tag_t)(((uint8_t)a<<24)|((uint8_t)b<<16)|((uint8_t)c<<8)|(uint8_t)d)) -#define HB_TAG_STR(s) (HB_TAG(((const char *) s)[0], \ - ((const char *) s)[1], \ - ((const char *) s)[2], \ - ((const char *) s)[3])) - typedef enum { HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED = 0x0000, HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH = 0x0002, @@ -46,8 +39,6 @@ typedef enum { HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT = 0x0010 } hb_ot_layout_glyph_class_t; -typedef uint16_t hb_ot_layout_glyph_t; - /* * HB_OT_Layout */ @@ -67,15 +58,29 @@ hb_ot_layout_create_sanitize (char *data, make_writable_func); */ +/* + * GDEF + */ + +hb_bool_t +hb_ot_layout_has_font_glyph_classes (HB_OT_Layout *layout); + 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_get_glyph_class (HB_OT_Layout *layout, + hb_glyph_t glyph); void hb_ot_layout_set_glyph_class (HB_OT_Layout *layout, - hb_ot_layout_glyph_t glyph, + hb_glyph_t glyph, hb_ot_layout_glyph_class_t klass); +void +hb_ot_layout_build_glyph_classes (HB_OT_Layout *layout, + uint16_t num_total_glyphs, + hb_glyph_t *glyphs, + unsigned char *klasses, + uint16_t count); + HB_END_DECLS(); #endif /* HB_OT_LAYOUT_H */