summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pango/opentype/hb-ot-layout-gpos-private.h22
-rw-r--r--pango/opentype/hb-ot-layout.cc13
-rw-r--r--pango/opentype/hb-ot-layout.h5
-rw-r--r--pango/pango-ot-info.c97
-rw-r--r--pango/pango-ot-private.h5
-rw-r--r--pango/pango-ot-ruleset.c32
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 */
/**