From 30bd763fa2fa4aceee51433ec9fc8dc28480b5d7 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 15 Apr 2009 22:56:15 -0400 Subject: [PATCH] Implement the first substitute() --- src/harfbuzz-buffer-private.h | 8 ++-- src/harfbuzz-buffer.c | 4 +- src/harfbuzz-buffer.h | 2 +- src/harfbuzz-gdef-private.h | 4 +- src/harfbuzz-gdef.c | 6 +-- src/harfbuzz-gdef.h | 2 +- src/harfbuzz-gpos.c | 8 ++-- src/harfbuzz-gpos.h | 2 +- src/harfbuzz-gsub.h | 2 +- src/hb-ot-layout-gsub-private.h | 88 +++++++++++++++++++++++++++++++++++++---- src/hb-ot-layout-open-private.h | 2 +- src/hb-ot-layout-private.h | 23 ++++++----- src/hb-ot-layout.cc | 54 +++++++++++++++++-------- src/hb-ot-layout.h | 2 +- 14 files changed, 151 insertions(+), 56 deletions(-) diff --git a/src/harfbuzz-buffer-private.h b/src/harfbuzz-buffer-private.h index 02ae336..dbecc7a 100644 --- a/src/harfbuzz-buffer-private.h +++ b/src/harfbuzz-buffer-private.h @@ -33,7 +33,7 @@ HB_BEGIN_HEADER -#define HB_GLYPH_PROPERTIES_UNKNOWN 0xFFFF +#define HB_GLYPH_PROPERTY_UNKNOWN 0xFFFF HB_INTERNAL void _hb_buffer_swap( HB_Buffer buffer ); @@ -83,9 +83,9 @@ _hb_buffer_allocate_ligid( HB_Buffer buffer ); #define OUT_GLYPH( pos ) (buffer->out_string[(pos)].gindex) #define OUT_ITEM( pos ) (&buffer->out_string[(pos)]) -#define CHECK_Property( layout, index, flags, property ) \ - (error = _hb_ot_layout_check_glyph_properties((layout), (index), (flags), (property)) \ - ? HB_Err_Ok : HB_Err_Not_Covered) +#define CHECK_Property( layout, index, flags, properties ) \ + ({unsigned int _p; error = _hb_ot_layout_check_glyph_property((layout), (index), (flags), (&_p)) \ + ? HB_Err_Ok : HB_Err_Not_Covered, *(properties) = _p; error;}) #define ADD_String( buffer, num_in, num_out, glyph_data, component, ligID ) \ ( ( error = _hb_buffer_add_output_glyphs( (buffer), \ diff --git a/src/harfbuzz-buffer.c b/src/harfbuzz-buffer.c index 568fbd8..3008c93 100644 --- a/src/harfbuzz-buffer.c +++ b/src/harfbuzz-buffer.c @@ -187,7 +187,7 @@ hb_buffer_add_glyph( HB_Buffer buffer, glyph->cluster = cluster; glyph->component = 0; glyph->ligID = 0; - glyph->gproperties = HB_GLYPH_PROPERTIES_UNKNOWN; + glyph->gproperty = HB_GLYPH_PROPERTY_UNKNOWN; buffer->in_length++; @@ -304,7 +304,7 @@ _hb_buffer_add_output_glyphs( HB_Buffer buffer, item->cluster = cluster; item->component = component; item->ligID = ligID; - item->gproperties = HB_GLYPH_PROPERTIES_UNKNOWN; + item->gproperty = HB_GLYPH_PROPERTY_UNKNOWN; } buffer->in_pos += num_in; diff --git a/src/harfbuzz-buffer.h b/src/harfbuzz-buffer.h index b134407..b89b3c4 100644 --- a/src/harfbuzz-buffer.h +++ b/src/harfbuzz-buffer.h @@ -38,7 +38,7 @@ typedef struct HB_GlyphItemRec_ { HB_UInt cluster; HB_UShort component; HB_UShort ligID; - HB_UShort gproperties; + HB_UShort gproperty; } HB_GlyphItemRec, *HB_GlyphItem; typedef struct HB_PositionRec_ { diff --git a/src/harfbuzz-gdef-private.h b/src/harfbuzz-gdef-private.h index 4a57520..e22b1b2 100644 --- a/src/harfbuzz-gdef-private.h +++ b/src/harfbuzz-gdef-private.h @@ -105,13 +105,13 @@ struct HB_LigGlyph_ HB_INTERNAL HB_Error _HB_GDEF_Add_Glyph_Property( HB_GDEFHeader* gdef, HB_UShort glyphID, - HB_UShort property ); + HB_UShort properties ); HB_INTERNAL HB_Error _HB_GDEF_Check_Property( HB_GDEFHeader* gdef, HB_GlyphItem item, HB_UShort flags, - HB_UShort* property ); + HB_UShort* properties ); HB_INTERNAL HB_Error _HB_GDEF_LoadMarkAttachClassDef_From_LookupFlags( HB_GDEFHeader* gdef, diff --git a/src/harfbuzz-gdef.c b/src/harfbuzz-gdef.c index 8fecf4c..1bda907 100644 --- a/src/harfbuzz-gdef.c +++ b/src/harfbuzz-gdef.c @@ -1074,14 +1074,14 @@ _HB_GDEF_Check_Property( HB_GDEFHeader* gdef, HB_UShort basic_glyph_class; HB_UShort desired_attachment_class; - if ( gitem->gproperties == HB_GLYPH_PROPERTIES_UNKNOWN ) + if ( gitem->gproperty == HB_GLYPH_PROPERTY_UNKNOWN ) { - error = HB_GDEF_Get_Glyph_Property( gdef, gitem->gindex, &gitem->gproperties ); + error = HB_GDEF_Get_Glyph_Property( gdef, gitem->gindex, &gitem->gproperty ); if ( error ) return error; } - *property = gitem->gproperties; + *property = gitem->gproperty; /* If the glyph was found in the MarkAttachmentClass table, * then that class value is the high byte of the result, diff --git a/src/harfbuzz-gdef.h b/src/harfbuzz-gdef.h index 84afe17..dc33d21 100644 --- a/src/harfbuzz-gdef.h +++ b/src/harfbuzz-gdef.h @@ -121,7 +121,7 @@ HB_Error HB_Done_GDEF_Table ( HB_GDEFHeader* gdef ); HB_Error HB_GDEF_Get_Glyph_Property( HB_GDEFHeader* gdef, HB_UShort glyphID, - HB_UShort* property ); + HB_UShort* properties ); HB_Error HB_GDEF_Build_ClassDefinition( HB_GDEFHeader* gdef, HB_UShort num_glyphs, diff --git a/src/harfbuzz-gpos.c b/src/harfbuzz-gpos.c index 560a291..c4e8a78 100644 --- a/src/harfbuzz-gpos.c +++ b/src/harfbuzz-gpos.c @@ -1783,7 +1783,7 @@ static HB_Error Lookup_CursivePos( GPOS_Instance* gpi, return HB_Err_Not_Covered; } - /* Glyphs not having the right GDEF properties will be ignored, i.e., + /* Glyphs not having the right GDEF property will be ignored, i.e., gpi->last won't be reset (contrary to user defined properties). */ if ( CHECK_Property( gpos->layout, IN_CURITEM(), flags, &property ) ) @@ -2224,7 +2224,7 @@ static HB_Error Lookup_MarkBasePos( GPOS_Instance* gpi, while ( i <= buffer->in_pos ) { - property = _hb_ot_layout_get_glyph_properties (gpos->layout, IN_GLYPH(j)); + property = _hb_ot_layout_get_glyph_property (gpos->layout, IN_GLYPH(j)); if ( !property ) return HB_Err_Not_Covered; @@ -2633,7 +2633,7 @@ static HB_Error Lookup_MarkLigPos( GPOS_Instance* gpi, while ( i <= buffer->in_pos ) { - property = _hb_ot_layout_get_glyph_properties (gpos->layout, IN_GLYPH(j)); + property = _hb_ot_layout_get_glyph_property (gpos->layout, IN_GLYPH(j)); if ( !property ) return HB_Err_Not_Covered; @@ -2960,7 +2960,7 @@ static HB_Error Lookup_MarkMarkPos( GPOS_Instance* gpi, j = buffer->in_pos - 1; while ( i <= buffer->in_pos ) { - property = _hb_ot_layout_get_glyph_properties (gpos->layout, IN_GLYPH(j)); + property = _hb_ot_layout_get_glyph_property (gpos->layout, IN_GLYPH(j)); if ( !property ) return HB_Err_Not_Covered; diff --git a/src/harfbuzz-gpos.h b/src/harfbuzz-gpos.h index b1aa135..0460e2b 100644 --- a/src/harfbuzz-gpos.h +++ b/src/harfbuzz-gpos.h @@ -145,7 +145,7 @@ HB_Error HB_GPOS_Query_Features( HB_GPOSHeader* gpos, HB_Error HB_GPOS_Add_Feature( HB_GPOSHeader* gpos, HB_UShort feature_index, - HB_UInt property ); + HB_UInt properties ); HB_Error HB_GPOS_Clear_Features( HB_GPOSHeader* gpos ); diff --git a/src/harfbuzz-gsub.h b/src/harfbuzz-gsub.h index b1e78ce..f4deac1 100644 --- a/src/harfbuzz-gsub.h +++ b/src/harfbuzz-gsub.h @@ -121,7 +121,7 @@ HB_Error HB_GSUB_Query_Features( HB_GSUBHeader* gsub, HB_Error HB_GSUB_Add_Feature( HB_GSUBHeader* gsub, HB_UShort feature_index, - HB_UInt property ); + HB_UInt properties ); HB_Error HB_GSUB_Clear_Features( HB_GSUBHeader* gsub ); diff --git a/src/hb-ot-layout-gsub-private.h b/src/hb-ot-layout-gsub-private.h index c8d5405..d8c1d8d 100644 --- a/src/hb-ot-layout-gsub-private.h +++ b/src/hb-ot-layout-gsub-private.h @@ -32,19 +32,89 @@ #include "hb-ot-layout-open-private.h" #include "hb-ot-layout-gdef-private.h" +#include "harfbuzz-buffer-private.h" /* XXX */ + +#define DEFINE_GET_GLYPH_COVERAGE(name) \ + inline hb_ot_layout_coverage_t get_##name (hb_codepoint_t glyph) const { \ + const Coverage &c = get_coverage (); \ + return c.get_coverage (glyph); \ + } + +#define SUBTABLE_SUBSTITUTE \ + bool substitute (hb_ot_layout_t *layout, \ + hb_buffer_t *buffer, \ + unsigned int context_length, \ + unsigned int nesting_level_left, \ + unsigned int lookup_flag) const struct SingleSubstFormat1 { friend struct SingleSubst; private: - inline bool substitute (hb_ot_layout_t *layout, - hb_buffer_t *buffer, - unsigned int context_length, - unsigned int nesting_level_left) const { -// if (get_coverage (IN_CURGLYPH())) -// return ; + DEFINE_GET_ACCESSOR (Coverage, coverage, coverage); + DEFINE_GET_GLYPH_COVERAGE (glyph_coverage); + + inline SUBTABLE_SUBSTITUTE { + hb_codepoint_t glyph_id; + hb_ot_layout_coverage_t index; + unsigned int property; + + HB_UNUSED (nesting_level_left); + + if (HB_UNLIKELY (context_length < 1)) + return false; + + if (!_hb_ot_layout_check_glyph_property (layout, IN_CURITEM (), lookup_flag, &property)) + return false; + + glyph_id = IN_CURGLYPH (); + + index = get_glyph_coverage (glyph_id); + if (-1 == index) + return false; + + glyph_id += deltaGlyphID; + _hb_buffer_replace_output_glyph (buffer, glyph_id, context_length == NO_CONTEXT); + + if ( _hb_ot_layout_has_new_glyph_classes (layout) ) + { + /* we inherit the old glyph class to the substituted glyph */ + _hb_ot_layout_set_glyph_property (layout, glyph_id, property); + } + + return true; +} + +#if 0 + + switch ( ss->SubstFormat ) + { + case 1: + value = (IN_CURGLYPH() + ss->ssf.ssf1.DeltaGlyphID ) & 0xFFFF; + if ( REPLACE_Glyph( buffer, value, nesting_level ) ) + return error; + break; + + case 2: + if ( index >= ss->ssf.ssf2.GlyphCount ) + return ERR(HB_Err_Invalid_SubTable); + value = ss->ssf.ssf2.Substitute[index]; + if ( REPLACE_Glyph( buffer, value, nesting_level ) ) + return error; + break; + + default: + return ERR(HB_Err_Invalid_SubTable); + } + + if ( _hb_ot_layout_has_new_glyph_classes (layout) ) + { + /* we inherit the old glyph class to the substituted glyph */ + + hb_ot_layout_set_glyph_class (layout, value, properties); } +#endif private: USHORT substFormat; /* Format identifier--format = 1 */ @@ -490,7 +560,8 @@ struct SubstLookupSubTable { hb_buffer_t *buffer, unsigned int context_length, unsigned int nesting_level_left, - unsigned int lookup_type) const { + unsigned int lookup_type, + unsigned int lookup_flag) const { } private: @@ -545,6 +616,7 @@ struct SubstLookup : Lookup { unsigned int context_length, unsigned int nesting_level_left) const { unsigned int lookup_type = get_type (); + unsigned int lookup_flag = get_flag (); if (HB_UNLIKELY (nesting_level_left == 0)) return false; @@ -553,7 +625,7 @@ struct SubstLookup : Lookup { for (unsigned int i = 0; i < get_subtable_count (); i++) if (get_subtable (i).substitute (layout, buffer, context_length, nesting_level_left, - lookup_type)) + lookup_type, lookup_flag)) return true; return false; diff --git a/src/hb-ot-layout-open-private.h b/src/hb-ot-layout-open-private.h index d5ca810..4123a43 100644 --- a/src/hb-ot-layout-open-private.h +++ b/src/hb-ot-layout-open-private.h @@ -671,7 +671,7 @@ struct Lookup { inline bool ignore_base_glyphs(void) const { return lookupFlag & LookupFlag::IgnoreBaseGlyphs; } inline bool ignore_ligatures (void) const { return lookupFlag & LookupFlag::IgnoreLigatures; } inline bool ignore_marks (void) const { return lookupFlag & LookupFlag::IgnoreMarks; } - inline bool get_mark_attachment_type (void) const { return lookupFlag & LookupFlag::MarkAttachmentType; } + inline unsigned int get_mark_attachment_type (void) const { return lookupFlag & LookupFlag::MarkAttachmentType; } inline unsigned int get_type (void) const { return lookupType; } inline unsigned int get_flag (void) const { return lookupFlag; } diff --git a/src/hb-ot-layout-private.h b/src/hb-ot-layout-private.h index a1be8aa..ae728eb 100644 --- a/src/hb-ot-layout-private.h +++ b/src/hb-ot-layout-private.h @@ -34,9 +34,7 @@ #include "harfbuzz-buffer.h" -typedef uint16_t hb_ot_layout_class_t; -typedef uint16_t hb_ot_layout_glyph_properties_t; -typedef uint16_t hb_ot_layout_lookup_flags_t; +typedef unsigned int hb_ot_layout_class_t; typedef int hb_ot_layout_coverage_t; /* -1 is not covered, >= 0 otherwise */ /* XXX #define HB_OT_LAYOUT_INTERNAL static */ @@ -51,15 +49,20 @@ HB_BEGIN_DECLS(); HB_OT_LAYOUT_INTERNAL hb_bool_t _hb_ot_layout_has_new_glyph_classes (hb_ot_layout_t *layout); -HB_OT_LAYOUT_INTERNAL hb_ot_layout_glyph_properties_t -_hb_ot_layout_get_glyph_properties (hb_ot_layout_t *layout, - hb_codepoint_t glyph); +HB_OT_LAYOUT_INTERNAL unsigned int +_hb_ot_layout_get_glyph_property (hb_ot_layout_t *layout, + hb_codepoint_t glyph); + +HB_OT_LAYOUT_INTERNAL void +_hb_ot_layout_set_glyph_property (hb_ot_layout_t *layout, + hb_codepoint_t glyph, + unsigned int property); HB_OT_LAYOUT_INTERNAL hb_bool_t -_hb_ot_layout_check_glyph_properties (hb_ot_layout_t *layout, - HB_GlyphItem gitem, - hb_ot_layout_lookup_flags_t lookup_flags, - hb_ot_layout_glyph_properties_t *property); +_hb_ot_layout_check_glyph_property (hb_ot_layout_t *layout, + HB_GlyphItem gitem, + 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 01923db..5a5e176 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -98,6 +98,8 @@ hb_ot_layout_destroy (hb_ot_layout_t *layout) * GDEF */ +/* XXX the public class_t is a mess */ + hb_bool_t hb_ot_layout_has_font_glyph_classes (hb_ot_layout_t *layout) { @@ -110,9 +112,9 @@ _hb_ot_layout_has_new_glyph_classes (hb_ot_layout_t *layout) return layout->new_gdef.len > 0; } -HB_OT_LAYOUT_INTERNAL hb_ot_layout_glyph_properties_t -_hb_ot_layout_get_glyph_properties (hb_ot_layout_t *layout, - hb_codepoint_t glyph) +HB_OT_LAYOUT_INTERNAL unsigned int +_hb_ot_layout_get_glyph_property (hb_ot_layout_t *layout, + hb_codepoint_t glyph) { hb_ot_layout_class_t klass; @@ -138,22 +140,22 @@ _hb_ot_layout_get_glyph_properties (hb_ot_layout_t *layout, } HB_OT_LAYOUT_INTERNAL hb_bool_t -_hb_ot_layout_check_glyph_properties (hb_ot_layout_t *layout, - HB_GlyphItem gitem, - hb_ot_layout_lookup_flags_t lookup_flags, - hb_ot_layout_glyph_properties_t *property) +_hb_ot_layout_check_glyph_property (hb_ot_layout_t *layout, + HB_GlyphItem gitem, + unsigned int lookup_flags, + unsigned int *property) { hb_ot_layout_glyph_class_t basic_glyph_class; - hb_ot_layout_glyph_properties_t desired_attachment_class; + unsigned int desired_attachment_class; - if (gitem->gproperties == HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN) + if (gitem->gproperty == HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN) { - gitem->gproperties = *property = _hb_ot_layout_get_glyph_properties (layout, gitem->gindex); - if (gitem->gproperties == HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED) + gitem->gproperty = *property = _hb_ot_layout_get_glyph_property (layout, gitem->gindex); + if (gitem->gproperty == HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED) return false; } - *property = gitem->gproperties; + *property = gitem->gproperty; /* If the glyph was found in the MarkAttachmentClass table, * then that class value is the high byte of the result, @@ -179,27 +181,42 @@ _hb_ot_layout_check_glyph_properties (hb_ot_layout_t *layout, if (desired_attachment_class) { if (basic_glyph_class == HB_OT_LAYOUT_GLYPH_CLASS_MARK && - *property != desired_attachment_class ) + *property != desired_attachment_class) return false; } return true; } +HB_OT_LAYOUT_INTERNAL void +_hb_ot_layout_set_glyph_property (hb_ot_layout_t *layout, + hb_codepoint_t glyph, + unsigned int property) +{ + hb_ot_layout_glyph_class_t klass; + + if (property & LookupFlag::MarkAttachmentType) + klass = HB_OT_LAYOUT_GLYPH_CLASS_MARK; + else + klass = (hb_ot_layout_glyph_class_t) property; + + hb_ot_layout_set_glyph_class (layout, glyph, klass); +} + hb_ot_layout_glyph_class_t hb_ot_layout_get_glyph_class (hb_ot_layout_t *layout, hb_codepoint_t glyph) { - hb_ot_layout_glyph_properties_t properties; + unsigned int property; hb_ot_layout_class_t klass; - properties = _hb_ot_layout_get_glyph_properties (layout, glyph); + property = _hb_ot_layout_get_glyph_property (layout, glyph); - if (properties & 0xFF00) + if (property & LookupFlag::MarkAttachmentType) return HB_OT_LAYOUT_GLYPH_CLASS_MARK; - return (hb_ot_layout_glyph_class_t) properties; + return (hb_ot_layout_glyph_class_t) property; } void @@ -212,6 +229,9 @@ hb_ot_layout_set_glyph_class (hb_ot_layout_t *layout, hb_ot_layout_class_t gdef_klass; int len = layout->new_gdef.len; + if (G_UNLIKELY (glyph > 65535)) + return; + if (glyph >= len) { int new_len; unsigned char *new_klasses; diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index c29485c..a6b9d37 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -91,7 +91,7 @@ typedef enum { HB_OT_LAYOUT_TABLE_TYPE_NONE } hb_ot_layout_table_type_t; -typedef uint16_t hb_ot_layout_feature_mask_t; +typedef uint32_t hb_ot_layout_feature_mask_t; #define HB_OT_LAYOUT_MAX_NESTING_LEVEL 100 -- 2.7.4