diff options
-rw-r--r-- | pango/opentype/hb-ot-layout-gpos-private.h | 22 | ||||
-rw-r--r-- | pango/opentype/hb-ot-layout.cc | 13 | ||||
-rw-r--r-- | pango/opentype/hb-ot-layout.h | 5 | ||||
-rw-r--r-- | pango/pango-ot-info.c | 97 | ||||
-rw-r--r-- | pango/pango-ot-private.h | 5 | ||||
-rw-r--r-- | pango/pango-ot-ruleset.c | 32 |
6 files changed, 102 insertions, 72 deletions
diff --git a/pango/opentype/hb-ot-layout-gpos-private.h b/pango/opentype/hb-ot-layout-gpos-private.h index b0b95135..056131b2 100644 --- a/pango/opentype/hb-ot-layout-gpos-private.h +++ b/pango/opentype/hb-ot-layout-gpos-private.h @@ -843,16 +843,24 @@ struct PosLookup : Lookup { if (HB_UNLIKELY (!buffer->in_length)) return false; - _hb_buffer_clear_positions (buffer); + layout->gpos_info.last = 0xFFFF; /* no last valid glyph for cursive pos. */ + buffer->in_pos = 0; while (buffer->in_pos < buffer->in_length) { - if ((~IN_PROPERTIES (buffer->in_pos) & mask) && - position_once (layout, buffer)) - ret = true; - else - _hb_buffer_next_glyph (buffer); - + bool done; + if (~IN_PROPERTIES (buffer->in_pos) & mask) { + done = position_once (layout, buffer); + ret |= done; + } else { + done = false; + /* Contrary to properties defined in GDEF, user-defined properties + will always stop a possible cursive positioning. */ + layout->gpos_info.last = 0xFFFF; + } + + if (!done) + buffer->in_pos++; } return ret; diff --git a/pango/opentype/hb-ot-layout.cc b/pango/opentype/hb-ot-layout.cc index 46f45553..4bb2eb58 100644 --- a/pango/opentype/hb-ot-layout.cc +++ b/pango/opentype/hb-ot-layout.cc @@ -531,6 +531,19 @@ hb_ot_layout_substitute_lookup (hb_ot_layout_t *layout, return layout->gsub->substitute_lookup (layout, buffer, lookup_index, mask); } +/* + * GPOS + */ + +hb_bool_t +hb_ot_layout_position_lookup (hb_ot_layout_t *layout, + hb_buffer_t *buffer, + unsigned int lookup_index, + hb_ot_layout_feature_mask_t mask) +{ + return layout->gpos->position_lookup (layout, buffer, lookup_index, mask); +} + /* TODO dupped, until he old code can be removed */ diff --git a/pango/opentype/hb-ot-layout.h b/pango/opentype/hb-ot-layout.h index f6c0c448..f907b65b 100644 --- a/pango/opentype/hb-ot-layout.h +++ b/pango/opentype/hb-ot-layout.h @@ -207,6 +207,11 @@ hb_ot_layout_substitute_lookup (hb_ot_layout_t *layout, unsigned int lookup_index, hb_ot_layout_feature_mask_t mask); +hb_bool_t +hb_ot_layout_position_lookup (hb_ot_layout_t *layout, + hb_buffer_t *buffer, + unsigned int lookup_index, + hb_ot_layout_feature_mask_t mask); diff --git a/pango/pango-ot-info.c b/pango/pango-ot-info.c index fbd03772..cf309cc4 100644 --- a/pango/pango-ot-info.c +++ b/pango/pango-ot-info.c @@ -32,12 +32,6 @@ static void synthesize_class_def (PangoOTInfo *info); static GObjectClass *parent_class; -enum -{ - INFO_LOADED_GSUB = 1 << 1, - INFO_LOADED_GPOS = 1 << 2 -}; - GType pango_ot_info_get_type (void) { @@ -83,12 +77,6 @@ pango_ot_info_finalize (GObject *object) if (info->layout) hb_ot_layout_destroy (info->layout); - if (info->gpos) - { - HB_Done_GPOS_Table (info->gpos); - info->gpos = NULL; - } - parent_class->finalize (object); } @@ -285,29 +273,6 @@ synthesize_class_def (PangoOTInfo *info) FT_Set_Charmap (info->face, old_charmap); } -HB_GPOS -pango_ot_info_get_gpos (PangoOTInfo *info) -{ - g_return_val_if_fail (PANGO_IS_OT_INFO (info), NULL); - - if (!(info->loaded & INFO_LOADED_GPOS)) - { - HB_Error error; - - info->loaded |= INFO_LOADED_GPOS; - - if (FT_IS_SFNT (info->face)) - { - error = HB_Load_GPOS_Table (info->face, &info->gpos, _pango_ot_info_get_layout (info)); - - if (error && error != HB_Err_Not_Covered) - g_warning ("Error loading GPOS table 0x%04X", error); - } - } - - return info->gpos; -} - static hb_ot_layout_table_type_t get_hb_table_type (PangoOTTableType table_type) { @@ -582,3 +547,65 @@ _pango_ot_info_substitute (const PangoOTInfo *info, } } } + +void +_pango_ot_info_position (const PangoOTInfo *info, + const PangoOTRuleset *ruleset, + PangoOTBuffer *buffer) +{ + unsigned int i; + + for (i = 0; i < ruleset->rules->len; i++) + { + PangoOTRule *rule = &g_array_index (ruleset->rules, PangoOTRule, i); + hb_ot_layout_feature_mask_t mask; + unsigned int lookup_count, j; + + if (rule->table_type != PANGO_OT_TABLE_GPOS) + continue; + + mask = rule->property_bit; + lookup_count = hb_ot_layout_feature_get_lookup_count (info->layout, + HB_OT_LAYOUT_TABLE_TYPE_GSUB, + rule->feature_index); + + if (lookup_count) + _hb_buffer_clear_positions (buffer->buffer); + + for (j = 0; j < lookup_count; j++) + { + unsigned int lookup_index; + + lookup_index = hb_ot_layout_feature_get_lookup_index (info->layout, + HB_OT_LAYOUT_TABLE_TYPE_GSUB, + rule->feature_index, + j); + hb_ot_layout_position_lookup (info->layout, + buffer->buffer, + lookup_index, + rule->property_bit); + } + + if (lookup_count) + { + HB_UInt i, j; + HB_Position positions = buffer->buffer->positions; + + /* First handle all left-to-right connections */ + for (j = 0; j < buffer->buffer->in_length; j++) + { + if (positions[j].cursive_chain > 0) + positions[j].y_pos += positions[j - positions[j].cursive_chain].y_pos; + } + + /* Then handle all right-to-left connections */ + for (i = buffer->buffer->in_length; i > 0; i--) + { + j = i - 1; + + if (positions[j].cursive_chain < 0) + positions[j].y_pos += positions[j - positions[j].cursive_chain].y_pos; + } + } + } +} diff --git a/pango/pango-ot-private.h b/pango/pango-ot-private.h index c1ee4556..ba67e269 100644 --- a/pango/pango-ot-private.h +++ b/pango/pango-ot-private.h @@ -40,7 +40,6 @@ struct _PangoOTInfo FT_Face face; hb_ot_layout_t *layout; - HB_GPOS gpos; }; struct _PangoOTInfoClass @@ -92,7 +91,9 @@ hb_ot_layout_t *_pango_ot_info_get_layout (PangoOTInfo *info); void _pango_ot_info_substitute (const PangoOTInfo *info, const PangoOTRuleset *ruleset, PangoOTBuffer *buffer); -HB_GPOS pango_ot_info_get_gpos (PangoOTInfo *info); +void _pango_ot_info_position (const PangoOTInfo *info, + const PangoOTRuleset *ruleset, + PangoOTBuffer *buffer); G_END_DECLS diff --git a/pango/pango-ot-ruleset.c b/pango/pango-ot-ruleset.c index 23f37cb3..b5e27959 100644 --- a/pango/pango-ot-ruleset.c +++ b/pango/pango-ot-ruleset.c @@ -504,39 +504,15 @@ void pango_ot_ruleset_position (const PangoOTRuleset *ruleset, PangoOTBuffer *buffer) { - unsigned int i; - - HB_GPOS gpos = NULL; - g_return_if_fail (PANGO_IS_OT_RULESET (ruleset)); g_return_if_fail (ruleset->info != NULL); - for (i = 0; i < ruleset->rules->len; i++) - { - PangoOTRule *rule = &g_array_index (ruleset->rules, PangoOTRule, i); - - if (rule->table_type != PANGO_OT_TABLE_GPOS) - continue; - - if (!gpos) - { - gpos = pango_ot_info_get_gpos (ruleset->info); - - if (gpos) - HB_GPOS_Clear_Features (gpos); - else - return; - } - - HB_GPOS_Add_Feature (gpos, rule->feature_index, rule->property_bit); - } - - if (HB_GPOS_Apply_String (ruleset->info->face, gpos, 0, buffer->buffer, - FALSE /* enable device-dependant values */, - buffer->rtl) == HB_Err_Ok) - buffer->applied_gpos = TRUE; + _pango_ot_info_position (ruleset->info, + ruleset, + buffer); } + /* ruleset descriptions */ /** |