[HarfBuzz] harfbuzz: Branch 'master' - 18 commits
Behdad Esfahbod
behdad at kemper.freedesktop.org
Thu Feb 14 10:12:27 PST 2013
src/hb-ot-layout-gpos-table.hh | 25
src/hb-ot-layout-gsub-table.hh | 9
src/hb-ot-layout-gsubgpos-private.hh | 378 ++++++----
src/hb-ot-layout-private.hh | 58 +
src/hb-ot-layout.cc | 10
src/hb-ot-map-private.hh | 41 -
src/hb-ot-map.cc | 56 -
src/hb-ot-shape-complex-arabic-fallback.hh | 2
src/hb-ot-shape-complex-arabic.cc | 16
src/hb-ot-shape-complex-default.cc | 2
src/hb-ot-shape-complex-indic-machine.rl | 2
src/hb-ot-shape-complex-indic.cc | 79 +-
src/hb-ot-shape-complex-myanmar-machine.rl | 2
src/hb-ot-shape-complex-myanmar.cc | 12
src/hb-ot-shape-complex-sea-machine.rl | 2
src/hb-ot-shape-complex-sea.cc | 10
src/hb-ot-shape-private.hh | 37
src/hb-ot-shape.cc | 14
test/shaping/texts/in-tree/shaper-indic/indic/script-malayalam/misc/dot-reph.txt | 10
19 files changed, 491 insertions(+), 274 deletions(-)
New commits:
commit cfc507c5432e6327e8484b07b9e091212653bc92
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Feb 14 10:40:12 2013 -0500
[Indic-like] Disable automatic joiner handling for basic shaping features
Not for Arabic, but for Indic-like scripts. ZWJ/ZWNJ have special
meanings in those scripts, so let font lookups take full control.
This undoes the regression caused by automatic-joiners handling
introduced two commits ago.
We only disable automatic joiner handling for the "basic shaping
features" of Indic, Myanmar, and SEAsian shapers. The "presentation
forms" and other features are still applied with automatic-joiner
handling.
This change also changes the test suite failure statistics, such that
a few scripts show more "failures". The most affected is Kannada.
However, upon inspection, we believe that in most, if not all, of the
new failures, we are producing results superior to Uniscribe. Hard to
count those!
Here's an example of what is fixed by the recent joiner-handling
changes:
https://bugs.freedesktop.org/show_bug.cgi?id=58714
New numbers, for future reference:
BENGALI: 353892 out of 354188 tests passed. 296 failed (0.0835714%)
DEVANAGARI: 707336 out of 707394 tests passed. 58 failed (0.00819911%)
GUJARATI: 366262 out of 366457 tests passed. 195 failed (0.0532122%)
GURMUKHI: 60706 out of 60747 tests passed. 41 failed (0.067493%)
KANNADA: 950680 out of 951913 tests passed. 1233 failed (0.129529%)
KHMER: 299074 out of 299124 tests passed. 50 failed (0.0167155%)
LAO: 53611 out of 53644 tests passed. 33 failed (0.0615167%)
MALAYALAM: 1047983 out of 1048334 tests passed. 351 failed (0.0334817%)
ORIYA: 42320 out of 42329 tests passed. 9 failed (0.021262%)
SINHALA: 271539 out of 271847 tests passed. 308 failed (0.113299%)
TAMIL: 1091753 out of 1091754 tests passed. 1 failed (9.15957e-05%)
TELUGU: 970555 out of 970573 tests passed. 18 failed (0.00185457%)
TIBETAN: 208469 out of 208469 tests passed. 0 failed (0%)
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 4a6c9c5..a709c32 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -261,6 +261,7 @@ struct hb_apply_context_t
hb_buffer_t *buffer;
hb_direction_t direction;
hb_mask_t lookup_mask;
+ bool auto_joiners;
recurse_func_t recurse_func;
unsigned int nesting_level_left;
unsigned int lookup_props;
@@ -272,11 +273,13 @@ struct hb_apply_context_t
hb_apply_context_t (unsigned int table_index_,
hb_font_t *font_,
hb_buffer_t *buffer_,
- hb_mask_t lookup_mask_) :
+ hb_mask_t lookup_mask_,
+ bool auto_joiners_) :
table_index (table_index_),
font (font_), face (font->face), buffer (buffer_),
direction (buffer_->props.direction),
lookup_mask (lookup_mask_),
+ auto_joiners (auto_joiners_),
recurse_func (NULL),
nesting_level_left (MAX_NESTING_LEVEL),
lookup_props (0),
@@ -292,8 +295,8 @@ struct hb_apply_context_t
{
inline matcher_t (void) :
lookup_props (0),
- ignore_zwnj (true),
- ignore_zwj (true),
+ ignore_zwnj (false),
+ ignore_zwj (false),
mask (-1),
#define arg1(arg) (arg) /* Remove the macro to see why it's needed! */
syllable arg1(0),
@@ -369,13 +372,16 @@ struct hb_apply_context_t
end (c->buffer->len)
{
matcher.set_lookup_props (c->lookup_props);
- /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */
- matcher.set_ignore_zwnj (context_match || c->table_index == 1);
- matcher.set_ignore_zwj (true);
+ if (c->auto_joiners)
+ {
+ /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */
+ matcher.set_ignore_zwnj (context_match || c->table_index == 1);
+ matcher.set_ignore_zwj (true);
+ }
if (!context_match)
{
- matcher.set_mask (c->lookup_mask);
- matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0);
+ matcher.set_mask (c->lookup_mask);
+ matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0);
}
}
inline void set_lookup_props (unsigned int lookup_props) { matcher.set_lookup_props (lookup_props); }
@@ -439,13 +445,16 @@ struct hb_apply_context_t
num_items (num_items_)
{
matcher.set_lookup_props (c->lookup_props);
- /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */
- matcher.set_ignore_zwnj (context_match || c->table_index == 1);
- matcher.set_ignore_zwj (true);
+ if (c->auto_joiners)
+ {
+ /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */
+ matcher.set_ignore_zwnj (context_match || c->table_index == 1);
+ matcher.set_ignore_zwj (true);
+ }
if (!context_match)
{
- matcher.set_mask (c->lookup_mask);
- matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0);
+ matcher.set_mask (c->lookup_mask);
+ matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0);
}
}
inline void set_lookup_props (unsigned int lookup_props) { matcher.set_lookup_props (lookup_props); }
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index 21a79d6..3c5a1e8 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -206,7 +206,8 @@ HB_INTERNAL hb_bool_t
hb_ot_layout_substitute_lookup (hb_font_t *font,
hb_buffer_t *buffer,
unsigned int lookup_index,
- hb_mask_t mask);
+ hb_mask_t mask,
+ hb_bool_t auto_joiners);
/* Should be called after all the substitute_lookup's are done */
HB_INTERNAL void
@@ -223,7 +224,8 @@ HB_INTERNAL hb_bool_t
hb_ot_layout_position_lookup (hb_font_t *font,
hb_buffer_t *buffer,
unsigned int lookup_index,
- hb_mask_t mask);
+ hb_mask_t mask,
+ hb_bool_t auto_joiners);
/* Should be called after all the position_lookup's are done */
HB_INTERNAL void
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index 62988ab..0349b32 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -666,11 +666,12 @@ hb_bool_t
hb_ot_layout_substitute_lookup (hb_font_t *font,
hb_buffer_t *buffer,
unsigned int lookup_index,
- hb_mask_t mask)
+ hb_mask_t mask,
+ hb_bool_t auto_joiners)
{
if (unlikely (lookup_index >= hb_ot_layout_from_face (font->face)->gsub_lookup_count)) return false;
- OT::hb_apply_context_t c (0, font, buffer, mask);
+ OT::hb_apply_context_t c (0, font, buffer, mask, auto_joiners);
const OT::SubstLookup& l = hb_ot_layout_from_face (font->face)->gsub->get_lookup (lookup_index);
@@ -715,11 +716,12 @@ hb_bool_t
hb_ot_layout_position_lookup (hb_font_t *font,
hb_buffer_t *buffer,
unsigned int lookup_index,
- hb_mask_t mask)
+ hb_mask_t mask,
+ hb_bool_t auto_joiners)
{
if (unlikely (lookup_index >= hb_ot_layout_from_face (font->face)->gpos_lookup_count)) return false;
- OT::hb_apply_context_t c (1, font, buffer, mask);
+ OT::hb_apply_context_t c (1, font, buffer, mask, auto_joiners);
const OT::PosLookup& l = hb_ot_layout_from_face (font->face)->gpos->get_lookup (lookup_index);
diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh
index 663b7d1..942e9f4 100644
--- a/src/hb-ot-map-private.hh
+++ b/src/hb-ot-map-private.hh
@@ -49,14 +49,16 @@ struct hb_ot_map_t
unsigned int shift;
hb_mask_t mask;
hb_mask_t _1_mask; /* mask for value=1, for quick access */
- hb_bool_t needs_fallback;
+ unsigned int needs_fallback : 1;
+ unsigned int auto_joiners : 1;
static int cmp (const feature_map_t *a, const feature_map_t *b)
{ return a->tag < b->tag ? -1 : a->tag > b->tag ? 1 : 0; }
};
struct lookup_map_t {
- unsigned int index;
+ unsigned short index;
+ unsigned short auto_joiners : 1;
hb_mask_t mask;
static int cmp (const lookup_map_t *a, const lookup_map_t *b)
@@ -136,7 +138,8 @@ struct hb_ot_map_t
HB_INTERNAL void add_lookups (hb_face_t *face,
unsigned int table_index,
unsigned int feature_index,
- hb_mask_t mask);
+ hb_mask_t mask,
+ bool auto_joiners);
hb_mask_t global_mask;
@@ -148,7 +151,8 @@ struct hb_ot_map_t
enum hb_ot_map_feature_flags_t {
F_NONE = 0x0000,
F_GLOBAL = 0x0001,
- F_HAS_FALLBACK = 0x0002
+ F_HAS_FALLBACK = 0x0002,
+ F_MANUAL_JOINERS = 0x0004
};
inline hb_ot_map_feature_flags_t
operator | (hb_ot_map_feature_flags_t l, hb_ot_map_feature_flags_t r)
diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc
index 7848186..2fbb6ce 100644
--- a/src/hb-ot-map.cc
+++ b/src/hb-ot-map.cc
@@ -33,7 +33,8 @@ void
hb_ot_map_t::add_lookups (hb_face_t *face,
unsigned int table_index,
unsigned int feature_index,
- hb_mask_t mask)
+ hb_mask_t mask,
+ bool auto_joiners)
{
unsigned int lookup_indices[32];
unsigned int offset, len;
@@ -53,6 +54,7 @@ hb_ot_map_t::add_lookups (hb_face_t *face,
return;
lookup->mask = mask;
lookup->index = lookup_indices[i];
+ lookup->auto_joiners = auto_joiners;
}
offset += len;
@@ -108,7 +110,10 @@ void hb_ot_map_t::substitute (const hb_ot_shape_plan_t *plan, hb_font_t *font, h
for (unsigned int pause_index = 0; pause_index < pauses[table_index].len; pause_index++) {
const pause_map_t *pause = &pauses[table_index][pause_index];
for (; i < pause->num_lookups; i++)
- hb_ot_layout_substitute_lookup (font, buffer, lookups[table_index][i].index, lookups[table_index][i].mask);
+ hb_ot_layout_substitute_lookup (font, buffer,
+ lookups[table_index][i].index,
+ lookups[table_index][i].mask,
+ lookups[table_index][i].auto_joiners);
buffer->clear_output ();
@@ -117,7 +122,9 @@ void hb_ot_map_t::substitute (const hb_ot_shape_plan_t *plan, hb_font_t *font, h
}
for (; i < lookups[table_index].len; i++)
- hb_ot_layout_substitute_lookup (font, buffer, lookups[table_index][i].index, lookups[table_index][i].mask);
+ hb_ot_layout_substitute_lookup (font, buffer, lookups[table_index][i].index,
+ lookups[table_index][i].mask,
+ lookups[table_index][i].auto_joiners);
}
void hb_ot_map_t::position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const
@@ -128,14 +135,18 @@ void hb_ot_map_t::position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_
for (unsigned int pause_index = 0; pause_index < pauses[table_index].len; pause_index++) {
const pause_map_t *pause = &pauses[table_index][pause_index];
for (; i < pause->num_lookups; i++)
- hb_ot_layout_position_lookup (font, buffer, lookups[table_index][i].index, lookups[table_index][i].mask);
+ hb_ot_layout_position_lookup (font, buffer, lookups[table_index][i].index,
+ lookups[table_index][i].mask,
+ lookups[table_index][i].auto_joiners);
if (pause->callback)
pause->callback (plan, font, buffer);
}
for (; i < lookups[table_index].len; i++)
- hb_ot_layout_position_lookup (font, buffer, lookups[table_index][i].index, lookups[table_index][i].mask);
+ hb_ot_layout_position_lookup (font, buffer, lookups[table_index][i].index,
+ lookups[table_index][i].mask,
+ lookups[table_index][i].auto_joiners);
}
void hb_ot_map_t::collect_lookups (unsigned int table_index, hb_set_t *lookups_out) const
@@ -232,6 +243,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m)
map->index[1] = feature_index[1];
map->stage[0] = info->stage[0];
map->stage[1] = info->stage[1];
+ map->auto_joiners = !(info->flags & F_MANUAL_JOINERS);
if ((info->flags & F_GLOBAL) && info->max_value == 1) {
/* Uses the global bit */
map->shift = 0;
@@ -264,7 +276,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m)
script_index[table_index],
language_index[table_index],
&required_feature_index))
- m.add_lookups (face, table_index, required_feature_index, 1);
+ m.add_lookups (face, table_index, required_feature_index, 1, true);
unsigned int pause_index = 0;
unsigned int last_num_lookups = 0;
@@ -272,7 +284,10 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m)
{
for (unsigned i = 0; i < m.features.len; i++)
if (m.features[i].stage[table_index] == stage)
- m.add_lookups (face, table_index, m.features[i].index[table_index], m.features[i].mask);
+ m.add_lookups (face, table_index,
+ m.features[i].index[table_index],
+ m.features[i].mask,
+ m.features[i].auto_joiners);
/* Sort lookups and merge duplicates */
if (last_num_lookups < m.lookups[table_index].len)
@@ -284,7 +299,10 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m)
if (m.lookups[table_index][i].index != m.lookups[table_index][j].index)
m.lookups[table_index][++j] = m.lookups[table_index][i];
else
+ {
m.lookups[table_index][j].mask |= m.lookups[table_index][i].mask;
+ m.lookups[table_index][j].auto_joiners &= m.lookups[table_index][i].auto_joiners;
+ }
m.lookups[table_index].shrink (j + 1);
}
diff --git a/src/hb-ot-shape-complex-arabic-fallback.hh b/src/hb-ot-shape-complex-arabic-fallback.hh
index c0dbff0..6f8e951 100644
--- a/src/hb-ot-shape-complex-arabic-fallback.hh
+++ b/src/hb-ot-shape-complex-arabic-fallback.hh
@@ -244,7 +244,7 @@ arabic_fallback_plan_shape (arabic_fallback_plan_t *fallback_plan,
{
for (unsigned int i = 0; i < ARABIC_NUM_FALLBACK_FEATURES; i++)
if (fallback_plan->lookup_array[i]) {
- OT::hb_apply_context_t c (0, font, buffer, fallback_plan->mask_array[i]);
+ OT::hb_apply_context_t c (0, font, buffer, fallback_plan->mask_array[i], true/*auto_joiners*/);
fallback_plan->lookup_array[i]->apply_string (&c, &fallback_plan->digest_array[i]);
}
}
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index b60e310..0beddc8 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -339,18 +339,18 @@ indic_features[] =
* Basic features.
* These features are applied in order, one at a time, after initial_reordering.
*/
- {HB_TAG('n','u','k','t'), F_GLOBAL},
- {HB_TAG('a','k','h','n'), F_GLOBAL},
- {HB_TAG('r','p','h','f'), F_NONE},
- {HB_TAG('r','k','r','f'), F_GLOBAL},
- {HB_TAG('p','r','e','f'), F_NONE},
- {HB_TAG('b','l','w','f'), F_NONE},
- {HB_TAG('h','a','l','f'), F_NONE},
- {HB_TAG('a','b','v','f'), F_NONE},
- {HB_TAG('p','s','t','f'), F_NONE},
- {HB_TAG('c','f','a','r'), F_NONE},
- {HB_TAG('v','a','t','u'), F_GLOBAL},
- {HB_TAG('c','j','c','t'), F_GLOBAL},
+ {HB_TAG('n','u','k','t'), F_MANUAL_JOINERS | F_GLOBAL},
+ {HB_TAG('a','k','h','n'), F_MANUAL_JOINERS | F_GLOBAL},
+ {HB_TAG('r','p','h','f'), F_MANUAL_JOINERS},
+ {HB_TAG('r','k','r','f'), F_MANUAL_JOINERS | F_GLOBAL},
+ {HB_TAG('p','r','e','f'), F_MANUAL_JOINERS},
+ {HB_TAG('b','l','w','f'), F_MANUAL_JOINERS},
+ {HB_TAG('h','a','l','f'), F_MANUAL_JOINERS},
+ {HB_TAG('a','b','v','f'), F_MANUAL_JOINERS},
+ {HB_TAG('p','s','t','f'), F_MANUAL_JOINERS},
+ {HB_TAG('c','f','a','r'), F_MANUAL_JOINERS},
+ {HB_TAG('v','a','t','u'), F_MANUAL_JOINERS | F_GLOBAL},
+ {HB_TAG('c','j','c','t'), F_MANUAL_JOINERS | F_GLOBAL},
/*
* Other features.
* These features are applied all at once, after final_reordering.
@@ -1003,8 +1003,9 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
do {
j--;
- /* A ZWJ disables CJCT, however, it's mere presence is enough
- * to disable ligation. No explicit action needed. */
+ /* ZWJ/ZWNJ should disable CJCT. They do that by simply
+ * being there, since we don't skip them for the CJCT
+ * feature (ie. F_MANUAL_JOINERS) */
/* A ZWNJ disables HALF. */
if (non_joiner)
diff --git a/src/hb-ot-shape-complex-myanmar.cc b/src/hb-ot-shape-complex-myanmar.cc
index 53a9ab4..e766973 100644
--- a/src/hb-ot-shape-complex-myanmar.cc
+++ b/src/hb-ot-shape-complex-myanmar.cc
@@ -107,12 +107,12 @@ collect_features_myanmar (hb_ot_shape_planner_t *plan)
unsigned int i = 0;
map->add_gsub_pause (initial_reordering);
for (; i < MYANMAR_BASIC_FEATURES; i++) {
- map->add_global_bool_feature (myanmar_features[i]);
+ map->add_feature (myanmar_features[i], 1, F_GLOBAL | F_MANUAL_JOINERS);
map->add_gsub_pause (NULL);
}
map->add_gsub_pause (final_reordering);
for (; i < MYANMAR_NUM_FEATURES; i++) {
- map->add_global_bool_feature (myanmar_features[i]);
+ map->add_feature (myanmar_features[i], 1, F_GLOBAL);
}
}
diff --git a/src/hb-ot-shape-complex-sea.cc b/src/hb-ot-shape-complex-sea.cc
index 387a4a1..c06612e 100644
--- a/src/hb-ot-shape-complex-sea.cc
+++ b/src/hb-ot-shape-complex-sea.cc
@@ -109,12 +109,12 @@ collect_features_sea (hb_ot_shape_planner_t *plan)
unsigned int i = 0;
map->add_gsub_pause (initial_reordering);
for (; i < SEA_BASIC_FEATURES; i++) {
- map->add_global_bool_feature (sea_features[i]);
+ map->add_feature (sea_features[i], 1, F_GLOBAL | F_MANUAL_JOINERS);
map->add_gsub_pause (NULL);
}
map->add_gsub_pause (final_reordering);
for (; i < SEA_NUM_FEATURES; i++) {
- map->add_global_bool_feature (sea_features[i]);
+ map->add_feature (sea_features[i], 1, F_GLOBAL | F_MANUAL_JOINERS);
}
}
commit 0b45479198d61d5135dad771e9c68408eb13f930
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Feb 14 10:46:52 2013 -0500
[OTLayout] Add fine-grained control over ZWJ matching
Not used yet. Next commit...
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index fe10589..4a6c9c5 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -293,6 +293,7 @@ struct hb_apply_context_t
inline matcher_t (void) :
lookup_props (0),
ignore_zwnj (true),
+ ignore_zwj (true),
mask (-1),
#define arg1(arg) (arg) /* Remove the macro to see why it's needed! */
syllable arg1(0),
@@ -303,6 +304,7 @@ struct hb_apply_context_t
typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, const void *data);
inline void set_ignore_zwnj (bool ignore_zwnj_) { ignore_zwnj = ignore_zwnj_; }
+ inline void set_ignore_zwj (bool ignore_zwj_) { ignore_zwj = ignore_zwj_; }
inline void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; }
inline void set_mask (hb_mask_t mask_) { mask = mask_; }
inline void set_syllable (uint8_t syllable_) { syllable = syllable_; }
@@ -335,8 +337,9 @@ struct hb_apply_context_t
if (!c->match_properties (info.codepoint, property, lookup_props))
return SKIP_YES;
- if (unlikely ((_hb_glyph_info_is_default_ignorable (&info) &&
- (ignore_zwnj || !_hb_glyph_info_is_zwnj (&info))) &&
+ if (unlikely (_hb_glyph_info_is_default_ignorable (&info) &&
+ (ignore_zwnj || !_hb_glyph_info_is_zwnj (&info)) &&
+ (ignore_zwj || !_hb_glyph_info_is_zwj (&info)) &&
!is_a_ligature (info)))
return SKIP_MAYBE;
@@ -346,6 +349,7 @@ struct hb_apply_context_t
protected:
unsigned int lookup_props;
bool ignore_zwnj;
+ bool ignore_zwj;
hb_mask_t mask;
uint8_t syllable;
match_func_t match_func;
@@ -367,6 +371,7 @@ struct hb_apply_context_t
matcher.set_lookup_props (c->lookup_props);
/* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */
matcher.set_ignore_zwnj (context_match || c->table_index == 1);
+ matcher.set_ignore_zwj (true);
if (!context_match)
{
matcher.set_mask (c->lookup_mask);
@@ -436,6 +441,7 @@ struct hb_apply_context_t
matcher.set_lookup_props (c->lookup_props);
/* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */
matcher.set_ignore_zwnj (context_match || c->table_index == 1);
+ matcher.set_ignore_zwj (true);
if (!context_match)
{
matcher.set_mask (c->lookup_mask);
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index cc4b590..21a79d6 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -53,14 +53,15 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *uni
{
info->unicode_props0() = ((unsigned int) unicode->general_category (info->codepoint)) |
(unicode->is_default_ignorable (info->codepoint) ? 0x80 : 0) |
- (info->codepoint == 0x200C ? 0x40 : 0);
+ (info->codepoint == 0x200C ? 0x40 : 0) |
+ (info->codepoint == 0x200D ? 0x20 : 0);
info->unicode_props1() = unicode->modified_combining_class (info->codepoint);
}
inline hb_unicode_general_category_t
_hb_glyph_info_get_general_category (const hb_glyph_info_t *info)
{
- return (hb_unicode_general_category_t) (info->unicode_props0() & 0x3F);
+ return (hb_unicode_general_category_t) (info->unicode_props0() & 0x1F);
}
inline void
@@ -87,6 +88,12 @@ _hb_glyph_info_is_zwnj (const hb_glyph_info_t *info)
return !!(info->unicode_props0() & 0x40);
}
+inline hb_bool_t
+_hb_glyph_info_is_zwj (const hb_glyph_info_t *info)
+{
+ return !!(info->unicode_props0() & 0x20);
+}
+
#define hb_ot_layout_from_face(face) ((hb_ot_layout_t *) face->shaper_data.ot)
commit 607feb7cff0e50f8738d2e49ca463fc9d7d494de
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Feb 14 07:43:13 2013 -0500
[OTLayout] Ignore default-ignorables when matching GSUB/GPOS
When matching lookups, be smart about default-ignorable characters.
In particular:
Do nothing specific about ZWNJ, but for the other default-ignorables:
If the lookup in question uses the ignorable character in a sequence,
then match it as we used to do. However, if the sequence match will
fail because the default-ignorable blocked it, try skipping the
ignorable character and continue.
The most immediate thing it means is that if Lam-Alef forms a ligature,
then Lam-ZWJ-Alef will do to. Finally!
One exception: when matching for GPOS, or for backtrack/lookahead of
GSUB, we ignore ZWNJ too. That's the right thing to do.
It certainly is possible to build fonts that this feature will result
in undesirable glyphs, but it's hard to think of a real-world case
that that would happen.
This *does* break Indic shaping right now, since Indic Unicode has
specific rules for what ZWJ/ZWNJ mean, and skipping ZWJ is breaking
those rules. That will be fixed in upcoming commits.
diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh
index 71e0aee..44f1c64 100644
--- a/src/hb-ot-layout-gpos-table.hh
+++ b/src/hb-ot-layout-gpos-table.hh
@@ -596,6 +596,7 @@ struct PairSet
unsigned int count = len;
for (unsigned int i = 0; i < count; i++)
{
+ /* TODO bsearch */
if (c->buffer->info[pos].codepoint == record->secondGlyph)
{
valueFormats[0].apply_value (c->font, c->direction, this,
diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index ec549a8..40ee5f2 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -638,9 +638,9 @@ struct Ligature
ligate_input (c,
count,
&component[1],
- ligGlyph,
match_glyph,
NULL,
+ ligGlyph,
is_mark_ligature,
total_component_count);
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 07989fa..fe10589 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -288,53 +288,137 @@ struct hb_apply_context_t
inline void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; }
inline void set_lookup (const Lookup &l) { lookup_props = l.get_props (); }
+ struct matcher_t
+ {
+ inline matcher_t (void) :
+ lookup_props (0),
+ ignore_zwnj (true),
+ mask (-1),
+#define arg1(arg) (arg) /* Remove the macro to see why it's needed! */
+ syllable arg1(0),
+#undef arg1
+ match_func (NULL),
+ match_data (NULL) {};
+
+ typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, const void *data);
+
+ inline void set_ignore_zwnj (bool ignore_zwnj_) { ignore_zwnj = ignore_zwnj_; }
+ inline void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; }
+ inline void set_mask (hb_mask_t mask_) { mask = mask_; }
+ inline void set_syllable (uint8_t syllable_) { syllable = syllable_; }
+ inline void set_match_func (match_func_t match_func_,
+ const void *match_data_)
+ { match_func = match_func_; match_data = match_data_; }
+
+ inline bool matches (const hb_glyph_info_t &info,
+ const USHORT *glyph_data) const
+ {
+ return (info.mask & mask) &&
+ (!syllable || syllable == info.syllable ()) &&
+ (!match_func || match_func (info.codepoint, *glyph_data, match_data));
+ }
+
+ enum may_skip_t {
+ SKIP_NO,
+ SKIP_YES,
+ SKIP_MAYBE
+ };
+
+ inline may_skip_t
+ may_skip (const hb_apply_context_t *c,
+ const hb_glyph_info_t &info) const
+ {
+ unsigned int property;
+
+ property = info.glyph_props();
+
+ if (!c->match_properties (info.codepoint, property, lookup_props))
+ return SKIP_YES;
+
+ if (unlikely ((_hb_glyph_info_is_default_ignorable (&info) &&
+ (ignore_zwnj || !_hb_glyph_info_is_zwnj (&info))) &&
+ !is_a_ligature (info)))
+ return SKIP_MAYBE;
+
+ return SKIP_NO;
+ }
+
+ protected:
+ unsigned int lookup_props;
+ bool ignore_zwnj;
+ hb_mask_t mask;
+ uint8_t syllable;
+ match_func_t match_func;
+ const void *match_data;
+ };
+
struct skipping_forward_iterator_t
{
inline skipping_forward_iterator_t (hb_apply_context_t *c_,
unsigned int start_index_,
unsigned int num_items_,
- bool context_match = false)
+ bool context_match = false) :
+ idx (start_index_),
+ c (c_),
+ match_glyph_data (NULL),
+ num_items (num_items_),
+ end (c->buffer->len)
{
- c = c_;
- lookup_props = c->lookup_props;
- idx = start_index_;
- num_items = num_items_;
- mask = context_match ? -1 : c->lookup_mask;
- syllable = context_match ? 0 : c->buffer->cur().syllable ();
- end = c->buffer->len;
- }
- inline void set_lookup_props (unsigned int lookup_props_)
- {
- lookup_props = lookup_props_;
- }
- inline bool has_no_chance (void) const
- {
- return unlikely (num_items && idx + num_items >= end);
+ matcher.set_lookup_props (c->lookup_props);
+ /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */
+ matcher.set_ignore_zwnj (context_match || c->table_index == 1);
+ if (!context_match)
+ {
+ matcher.set_mask (c->lookup_mask);
+ matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0);
+ }
}
- inline void reject (void)
+ inline void set_lookup_props (unsigned int lookup_props) { matcher.set_lookup_props (lookup_props); }
+ inline void set_syllable (unsigned int syllable) { matcher.set_syllable (syllable); }
+ inline void set_match_func (matcher_t::match_func_t match_func,
+ const void *match_data,
+ const USHORT glyph_data[])
{
- num_items++;
+ matcher.set_match_func (match_func, match_data);
+ match_glyph_data = glyph_data;
}
+
+ inline bool has_no_chance (void) const { return unlikely (num_items && idx + num_items >= end); }
+ inline void reject (void) { num_items++; match_glyph_data--; }
inline bool next (void)
{
assert (num_items > 0);
- do
+ matcher_t::may_skip_t skip;
+ while (!has_no_chance ())
{
- if (has_no_chance ())
- return false;
idx++;
- } while (c->should_skip (&c->buffer->info[idx], lookup_props));
- num_items--;
- return (c->buffer->info[idx].mask & mask) && (!syllable || syllable == c->buffer->info[idx].syllable ());
+ const hb_glyph_info_t &info = c->buffer->info[idx];
+
+ skip = matcher.may_skip (c, info);
+
+ if (unlikely (skip == matcher_t::SKIP_YES))
+ continue;
+
+ if (matcher.matches (info, match_glyph_data))
+ {
+ num_items--;
+ match_glyph_data++;
+ return true;
+ }
+
+ if (skip == matcher_t::SKIP_NO)
+ return false;
+ }
+ return false;
}
unsigned int idx;
protected:
hb_apply_context_t *c;
- unsigned int lookup_props;
+ matcher_t matcher;
+ const USHORT *match_glyph_data;
+
unsigned int num_items;
- hb_mask_t mask;
- uint8_t syllable;
unsigned int end;
};
@@ -343,47 +427,67 @@ struct hb_apply_context_t
inline skipping_backward_iterator_t (hb_apply_context_t *c_,
unsigned int start_index_,
unsigned int num_items_,
- bool context_match = false)
+ bool context_match = false) :
+ idx (start_index_),
+ c (c_),
+ match_glyph_data (NULL),
+ num_items (num_items_)
{
- c = c_;
- lookup_props = c->lookup_props;
- idx = start_index_;
- num_items = num_items_;
- mask = context_match ? -1 : c->lookup_mask;
- syllable = context_match ? 0 : c->buffer->cur().syllable ();
- }
- inline void set_lookup_props (unsigned int lookup_props_)
- {
- lookup_props = lookup_props_;
- }
- inline bool has_no_chance (void) const
- {
- return unlikely (idx < num_items);
+ matcher.set_lookup_props (c->lookup_props);
+ /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */
+ matcher.set_ignore_zwnj (context_match || c->table_index == 1);
+ if (!context_match)
+ {
+ matcher.set_mask (c->lookup_mask);
+ matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0);
+ }
}
- inline void reject (void)
+ inline void set_lookup_props (unsigned int lookup_props) { matcher.set_lookup_props (lookup_props); }
+ inline void set_syllable (unsigned int syllable) { matcher.set_syllable (syllable); }
+ inline void set_match_func (matcher_t::match_func_t match_func,
+ const void *match_data,
+ const USHORT glyph_data[])
{
- num_items++;
+ matcher.set_match_func (match_func, match_data);
+ match_glyph_data = glyph_data;
}
+
+ inline bool has_no_chance (void) const { return unlikely (idx < num_items); }
+ inline void reject (void) { num_items++; }
inline bool prev (void)
{
assert (num_items > 0);
- do
+ matcher_t::may_skip_t skip;
+ while (!has_no_chance ())
{
- if (has_no_chance ())
- return false;
idx--;
- } while (c->should_skip (&c->buffer->out_info[idx], lookup_props));
- num_items--;
- return (c->buffer->out_info[idx].mask & mask) && (!syllable || syllable == c->buffer->out_info[idx].syllable ());
+ const hb_glyph_info_t &info = c->buffer->out_info[idx];
+
+ skip = matcher.may_skip (c, info);
+
+ if (unlikely (skip == matcher_t::SKIP_YES))
+ continue;
+
+ if (matcher.matches (info, match_glyph_data))
+ {
+ num_items--;
+ match_glyph_data++;
+ return true;
+ }
+
+ if (skip == matcher_t::SKIP_NO)
+ return false;
+ }
+ return false;
}
unsigned int idx;
protected:
hb_apply_context_t *c;
- unsigned int lookup_props;
+ matcher_t matcher;
+ const USHORT *match_glyph_data;
+
unsigned int num_items;
- hb_mask_t mask;
- uint8_t syllable;
};
inline bool
@@ -435,18 +539,6 @@ struct hb_apply_context_t
return match_properties (info->codepoint, property, lookup_props);
}
- inline bool
- should_skip (hb_glyph_info_t *info,
- unsigned int lookup_props) const
- {
- unsigned int property;
-
- property = info->glyph_props();
-
- return !match_properties (info->codepoint, property, lookup_props);
- }
-
-
inline void set_class (hb_codepoint_t glyph_index, unsigned int class_guess) const
{
if (likely (has_glyph_classes))
@@ -591,6 +683,7 @@ static inline bool match_input (hb_apply_context_t *c,
TRACE_APPLY (NULL);
hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, count - 1);
+ skippy_iter.set_match_func (match_func, match_data, input);
if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
/*
@@ -623,8 +716,6 @@ static inline bool match_input (hb_apply_context_t *c,
{
if (!skippy_iter.next ()) return TRACE_RETURN (false);
- if (likely (!match_func (c->buffer->info[skippy_iter.idx].codepoint, input[i - 1], match_data))) return TRACE_RETURN (false);
-
unsigned int this_lig_id = get_lig_id (c->buffer->info[skippy_iter.idx]);
unsigned int this_lig_comp = get_lig_comp (c->buffer->info[skippy_iter.idx]);
@@ -659,13 +750,17 @@ static inline bool match_input (hb_apply_context_t *c,
}
static inline void ligate_input (hb_apply_context_t *c,
unsigned int count, /* Including the first glyph (not matched) */
- const USHORT input[] HB_UNUSED, /* Array of input values--start with second glyph */
+ const USHORT input[], /* Array of input values--start with second glyph */
+ match_func_t match_func,
+ const void *match_data,
hb_codepoint_t lig_glyph,
- match_func_t match_func HB_UNUSED,
- const void *match_data HB_UNUSED,
bool is_mark_ligature,
unsigned int total_component_count)
{
+ hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, count - 1);
+ skippy_iter.set_match_func (match_func, match_data, input);
+ if (skippy_iter.has_no_chance ()) return;
+
/*
* - If it *is* a mark ligature, we don't allocate a new ligature id, and leave
* the ligature to keep its old ligature id. This will allow it to attach to
@@ -700,8 +795,6 @@ static inline void ligate_input (hb_apply_context_t *c,
unsigned int last_num_components = get_lig_num_comps (c->buffer->cur());
unsigned int components_so_far = last_num_components;
- hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, count - 1);
-
if (!is_mark_ligature)
set_lig_props_for_ligature (c->buffer->cur(), lig_id, total_component_count);
c->replace_glyph (lig_glyph, klass);
@@ -709,6 +802,7 @@ static inline void ligate_input (hb_apply_context_t *c,
for (unsigned int i = 1; i < count; i++)
{
if (!skippy_iter.next ()) return;
+
while (c->buffer->idx < skippy_iter.idx)
{
if (!is_mark_ligature) {
@@ -749,18 +843,13 @@ static inline bool match_backtrack (hb_apply_context_t *c,
TRACE_APPLY (NULL);
hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->backtrack_len (), count, true);
- if (skippy_iter.has_no_chance ())
- return TRACE_RETURN (false);
+ skippy_iter.set_match_func (match_func, match_data, backtrack);
+ if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
for (unsigned int i = 0; i < count; i++)
- {
if (!skippy_iter.prev ())
return TRACE_RETURN (false);
- if (likely (!match_func (c->buffer->out_info[skippy_iter.idx].codepoint, backtrack[i], match_data)))
- return TRACE_RETURN (false);
- }
-
return TRACE_RETURN (true);
}
@@ -774,18 +863,13 @@ static inline bool match_lookahead (hb_apply_context_t *c,
TRACE_APPLY (NULL);
hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx + offset - 1, count, true);
- if (skippy_iter.has_no_chance ())
- return TRACE_RETURN (false);
+ skippy_iter.set_match_func (match_func, match_data, lookahead);
+ if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
for (unsigned int i = 0; i < count; i++)
- {
if (!skippy_iter.next ())
return TRACE_RETURN (false);
- if (likely (!match_func (c->buffer->info[skippy_iter.idx].codepoint, lookahead[i], match_data)))
- return TRACE_RETURN (false);
- }
-
return TRACE_RETURN (true);
}
@@ -818,6 +902,9 @@ static inline void recurse_lookups (context_t *c,
static inline bool apply_lookup (hb_apply_context_t *c,
unsigned int count, /* Including the first glyph */
+ const USHORT input[], /* Array of input values--start with second glyph */
+ match_func_t match_func,
+ const void *match_data,
unsigned int lookupCount,
const LookupRecord lookupRecord[] /* Array of LookupRecords--in design order */)
{
@@ -834,6 +921,11 @@ static inline bool apply_lookup (hb_apply_context_t *c,
* and we jump out of it. Not entirely disastrous. So we don't check
* for reverse lookup here.
*/
+
+ hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, count - 1);
+ skippy_iter.set_match_func (match_func, match_data, input);
+ uint8_t syllable = c->buffer->cur().syllable();
+
unsigned int i = 0;
if (lookupCount && 0 == lookupRecord->sequenceIndex)
{
@@ -849,6 +941,13 @@ static inline bool apply_lookup (hb_apply_context_t *c,
if (!done)
goto not_applied;
+ else
+ {
+ /* Reinitialize iterator. */
+ hb_apply_context_t::skipping_forward_iterator_t tmp (c, c->buffer->idx - 1, count - i);
+ tmp.set_syllable (syllable);
+ skippy_iter = tmp;
+ }
}
else
{
@@ -857,7 +956,6 @@ static inline bool apply_lookup (hb_apply_context_t *c,
c->buffer->next_glyph ();
i++;
}
- hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx - 1, count - i);
while (i < count)
{
if (!skippy_iter.next ()) return TRACE_RETURN (true);
@@ -882,6 +980,7 @@ static inline bool apply_lookup (hb_apply_context_t *c,
{
/* Reinitialize iterator. */
hb_apply_context_t::skipping_forward_iterator_t tmp (c, c->buffer->idx - 1, count - i);
+ tmp.set_syllable (syllable);
skippy_iter = tmp;
}
}
@@ -969,7 +1068,8 @@ static inline bool context_apply_lookup (hb_apply_context_t *c,
inputCount, input,
lookup_context.funcs.match, lookup_context.match_data)
&& apply_lookup (c,
- inputCount,
+ inputCount, input,
+ lookup_context.funcs.match, lookup_context.match_data,
lookupCount, lookupRecord);
}
@@ -1505,7 +1605,8 @@ static inline bool chain_context_apply_lookup (hb_apply_context_t *c,
lookup_context.funcs.match, lookup_context.match_data[2],
lookahead_offset)
&& apply_lookup (c,
- inputCount,
+ inputCount, input,
+ lookup_context.funcs.match, lookup_context.match_data[1],
lookupCount, lookupRecord);
}
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index b550fa8..cc4b590 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -43,6 +43,51 @@
#define syllable() var1.u8[2] /* GSUB/GPOS shaping boundaries */
#define lig_props() var1.u8[3] /* GSUB/GPOS ligature tracking */
+/* buffer var allocations, used during the entire shaping process */
+#define unicode_props0() var2.u8[0]
+#define unicode_props1() var2.u8[1]
+
+
+inline void
+_hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *unicode)
+{
+ info->unicode_props0() = ((unsigned int) unicode->general_category (info->codepoint)) |
+ (unicode->is_default_ignorable (info->codepoint) ? 0x80 : 0) |
+ (info->codepoint == 0x200C ? 0x40 : 0);
+ info->unicode_props1() = unicode->modified_combining_class (info->codepoint);
+}
+
+inline hb_unicode_general_category_t
+_hb_glyph_info_get_general_category (const hb_glyph_info_t *info)
+{
+ return (hb_unicode_general_category_t) (info->unicode_props0() & 0x3F);
+}
+
+inline void
+_hb_glyph_info_set_modified_combining_class (hb_glyph_info_t *info, unsigned int modified_class)
+{
+ info->unicode_props1() = modified_class;
+}
+
+inline unsigned int
+_hb_glyph_info_get_modified_combining_class (const hb_glyph_info_t *info)
+{
+ return info->unicode_props1();
+}
+
+inline hb_bool_t
+_hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info)
+{
+ return !!(info->unicode_props0() & 0x80);
+}
+
+inline hb_bool_t
+_hb_glyph_info_is_zwnj (const hb_glyph_info_t *info)
+{
+ return !!(info->unicode_props0() & 0x40);
+}
+
+
#define hb_ot_layout_from_face(face) ((hb_ot_layout_t *) face->shaper_data.ot)
/*
diff --git a/src/hb-ot-shape-private.hh b/src/hb-ot-shape-private.hh
index 74c5b19..9599f8e 100644
--- a/src/hb-ot-shape-private.hh
+++ b/src/hb-ot-shape-private.hh
@@ -33,10 +33,6 @@
-/* buffer var allocations, used during the entire shaping process */
-#define unicode_props0() var2.u8[0]
-#define unicode_props1() var2.u8[1]
-
struct hb_ot_shape_plan_t
@@ -89,44 +85,4 @@ struct hb_ot_shape_planner_t
};
-
-inline void
-_hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *unicode)
-{
- info->unicode_props0() = ((unsigned int) unicode->general_category (info->codepoint)) |
- (unicode->is_default_ignorable (info->codepoint) ? 0x80 : 0) |
- (info->codepoint == 0x200C ? 0x40 : 0);
- info->unicode_props1() = unicode->modified_combining_class (info->codepoint);
-}
-
-inline hb_unicode_general_category_t
-_hb_glyph_info_get_general_category (const hb_glyph_info_t *info)
-{
- return (hb_unicode_general_category_t) (info->unicode_props0() & 0x3F);
-}
-
-inline void
-_hb_glyph_info_set_modified_combining_class (hb_glyph_info_t *info, unsigned int modified_class)
-{
- info->unicode_props1() = modified_class;
-}
-
-inline unsigned int
-_hb_glyph_info_get_modified_combining_class (const hb_glyph_info_t *info)
-{
- return info->unicode_props1();
-}
-
-inline hb_bool_t
-_hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info)
-{
- return !!(info->unicode_props0() & 0x80);
-}
-
-inline hb_bool_t
-_hb_glyph_info_is_zwnj (const hb_glyph_info_t *info)
-{
- return !!(info->unicode_props0() & 0x40);
-}
-
#endif /* HB_OT_SHAPE_PRIVATE_HH */
commit ec5448667b30ad662401c2b4f5fc0da524c013fd
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Feb 14 11:25:10 2013 -0500
Add hb_ot_map_feature_flags_t
Code cleanup. No (intended) functional change.
diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh
index 344e914..663b7d1 100644
--- a/src/hb-ot-map-private.hh
+++ b/src/hb-ot-map-private.hh
@@ -145,6 +145,27 @@ struct hb_ot_map_t
hb_prealloced_array_t<pause_map_t, 1> pauses[2]; /* GSUB/GPOS */
};
+enum hb_ot_map_feature_flags_t {
+ F_NONE = 0x0000,
+ F_GLOBAL = 0x0001,
+ F_HAS_FALLBACK = 0x0002
+};
+inline hb_ot_map_feature_flags_t
+operator | (hb_ot_map_feature_flags_t l, hb_ot_map_feature_flags_t r)
+{ return hb_ot_map_feature_flags_t ((unsigned int) l | (unsigned int) r); }
+inline hb_ot_map_feature_flags_t
+operator & (hb_ot_map_feature_flags_t l, hb_ot_map_feature_flags_t r)
+{ return hb_ot_map_feature_flags_t ((unsigned int) l & (unsigned int) r); }
+inline hb_ot_map_feature_flags_t
+operator ~ (hb_ot_map_feature_flags_t r)
+{ return hb_ot_map_feature_flags_t (~(unsigned int) r); }
+inline hb_ot_map_feature_flags_t&
+operator |= (hb_ot_map_feature_flags_t &l, hb_ot_map_feature_flags_t r)
+{ l = l | r; return l; }
+inline hb_ot_map_feature_flags_t&
+operator &= (hb_ot_map_feature_flags_t& l, hb_ot_map_feature_flags_t r)
+{ l = l & r; return l; }
+
struct hb_ot_map_builder_t
{
@@ -153,10 +174,11 @@ struct hb_ot_map_builder_t
HB_INTERNAL hb_ot_map_builder_t (hb_face_t *face_,
const hb_segment_properties_t *props_);
- HB_INTERNAL void add_feature (hb_tag_t tag, unsigned int value, bool global, bool has_fallback = false);
+ HB_INTERNAL void add_feature (hb_tag_t tag, unsigned int value,
+ hb_ot_map_feature_flags_t flags);
inline void add_global_bool_feature (hb_tag_t tag)
- { add_feature (tag, 1, true, false); }
+ { add_feature (tag, 1, F_GLOBAL); }
inline void add_gsub_pause (hb_ot_map_t::pause_func_t pause_func)
{ add_pause (0, pause_func); }
@@ -177,8 +199,7 @@ struct hb_ot_map_builder_t
hb_tag_t tag;
unsigned int seq; /* sequence#, used for stable sorting only */
unsigned int max_value;
- bool global; /* whether the feature applies value to every glyph in the buffer */
- bool has_fallback; /* whether to allocate bits even if feature not found */
+ hb_ot_map_feature_flags_t flags;
unsigned int default_value; /* for non-global features, what should the unset glyphs take */
unsigned int stage[2]; /* GSUB/GPOS */
diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc
index 62f7904..7848186 100644
--- a/src/hb-ot-map.cc
+++ b/src/hb-ot-map.cc
@@ -84,16 +84,16 @@ hb_ot_map_builder_t::hb_ot_map_builder_t (hb_face_t *face_,
}
}
-void hb_ot_map_builder_t::add_feature (hb_tag_t tag, unsigned int value, bool global, bool has_fallback)
+void hb_ot_map_builder_t::add_feature (hb_tag_t tag, unsigned int value,
+ hb_ot_map_feature_flags_t flags)
{
feature_info_t *info = feature_infos.push();
if (unlikely (!info)) return;
info->tag = tag;
info->seq = feature_infos.len;
info->max_value = value;
- info->global = global;
- info->has_fallback = has_fallback;
- info->default_value = global ? value : 0;
+ info->flags = flags;
+ info->default_value = (flags & F_GLOBAL) ? value : 0;
info->stage[0] = current_stage[0];
info->stage[1] = current_stage[1];
}
@@ -176,15 +176,15 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m)
if (feature_infos[i].tag != feature_infos[j].tag)
feature_infos[++j] = feature_infos[i];
else {
- if (feature_infos[i].global) {
- feature_infos[j].global = true;
+ if (feature_infos[i].flags & F_GLOBAL) {
+ feature_infos[j].flags |= F_GLOBAL;
feature_infos[j].max_value = feature_infos[i].max_value;
feature_infos[j].default_value = feature_infos[i].default_value;
} else {
- feature_infos[j].global = false;
+ feature_infos[j].flags &= ~F_GLOBAL;
feature_infos[j].max_value = MAX (feature_infos[j].max_value, feature_infos[i].max_value);
}
- feature_infos[j].has_fallback = feature_infos[j].has_fallback || feature_infos[i].has_fallback;
+ feature_infos[j].flags |= (feature_infos[i].flags & F_HAS_FALLBACK);
feature_infos[j].stage[0] = MIN (feature_infos[j].stage[0], feature_infos[i].stage[0]);
feature_infos[j].stage[1] = MIN (feature_infos[j].stage[1], feature_infos[i].stage[1]);
/* Inherit default_value from j */
@@ -200,7 +200,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m)
unsigned int bits_needed;
- if (info->global && info->max_value == 1)
+ if ((info->flags & F_GLOBAL) && info->max_value == 1)
/* Uses the global bit */
bits_needed = 0;
else
@@ -219,7 +219,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m)
language_index[table_index],
info->tag,
&feature_index[table_index]);
- if (!found && !info->has_fallback)
+ if (!found && !(info->flags & F_HAS_FALLBACK))
continue;
@@ -232,7 +232,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m)
map->index[1] = feature_index[1];
map->stage[0] = info->stage[0];
map->stage[1] = info->stage[1];
- if (info->global && info->max_value == 1) {
+ if ((info->flags & F_GLOBAL) && info->max_value == 1) {
/* Uses the global bit */
map->shift = 0;
map->mask = 1;
@@ -240,7 +240,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m)
map->shift = next_bit;
map->mask = (1 << (next_bit + bits_needed)) - (1 << next_bit);
next_bit += bits_needed;
- if (info->global)
+ if ((info->flags & F_GLOBAL))
m.global_mask |= (info->default_value << map->shift) & map->mask;
}
map->_1_mask = (1 << map->shift) & map->mask;
diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc
index 2c23da5..3a69f06 100644
--- a/src/hb-ot-shape-complex-arabic.cc
+++ b/src/hb-ot-shape-complex-arabic.cc
@@ -184,11 +184,11 @@ collect_features_arabic (hb_ot_shape_planner_t *plan)
map->add_gsub_pause (NULL);
for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++)
- map->add_feature (arabic_features[i], 1, false, i < 4); /* The first four features have fallback. */
+ map->add_feature (arabic_features[i], 1, i < 4 ? F_HAS_FALLBACK : F_NONE); /* The first four features have fallback. */
map->add_gsub_pause (NULL);
- map->add_feature (HB_TAG('r','l','i','g'), 1, true, true);
+ map->add_feature (HB_TAG('r','l','i','g'), 1, F_GLOBAL|F_HAS_FALLBACK);
map->add_gsub_pause (arabic_fallback_shape);
map->add_global_bool_feature (HB_TAG('c','a','l','t'));
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index bf82615..b60e310 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -329,7 +329,7 @@ static const indic_config_t indic_configs[] =
struct feature_list_t {
hb_tag_t tag;
- hb_bool_t is_global;
+ hb_ot_map_feature_flags_t flags;
};
static const feature_list_t
@@ -339,32 +339,32 @@ indic_features[] =
* Basic features.
* These features are applied in order, one at a time, after initial_reordering.
*/
- {HB_TAG('n','u','k','t'), true},
- {HB_TAG('a','k','h','n'), true},
- {HB_TAG('r','p','h','f'), false},
- {HB_TAG('r','k','r','f'), true},
- {HB_TAG('p','r','e','f'), false},
- {HB_TAG('b','l','w','f'), false},
- {HB_TAG('h','a','l','f'), false},
- {HB_TAG('a','b','v','f'), false},
- {HB_TAG('p','s','t','f'), false},
- {HB_TAG('c','f','a','r'), false},
- {HB_TAG('v','a','t','u'), true},
- {HB_TAG('c','j','c','t'), true},
+ {HB_TAG('n','u','k','t'), F_GLOBAL},
+ {HB_TAG('a','k','h','n'), F_GLOBAL},
+ {HB_TAG('r','p','h','f'), F_NONE},
+ {HB_TAG('r','k','r','f'), F_GLOBAL},
+ {HB_TAG('p','r','e','f'), F_NONE},
+ {HB_TAG('b','l','w','f'), F_NONE},
+ {HB_TAG('h','a','l','f'), F_NONE},
+ {HB_TAG('a','b','v','f'), F_NONE},
+ {HB_TAG('p','s','t','f'), F_NONE},
+ {HB_TAG('c','f','a','r'), F_NONE},
+ {HB_TAG('v','a','t','u'), F_GLOBAL},
+ {HB_TAG('c','j','c','t'), F_GLOBAL},
/*
* Other features.
* These features are applied all at once, after final_reordering.
*/
- {HB_TAG('i','n','i','t'), false},
- {HB_TAG('p','r','e','s'), true},
- {HB_TAG('a','b','v','s'), true},
- {HB_TAG('b','l','w','s'), true},
- {HB_TAG('p','s','t','s'), true},
- {HB_TAG('h','a','l','n'), true},
+ {HB_TAG('i','n','i','t'), F_NONE},
+ {HB_TAG('p','r','e','s'), F_GLOBAL},
+ {HB_TAG('a','b','v','s'), F_GLOBAL},
+ {HB_TAG('b','l','w','s'), F_GLOBAL},
+ {HB_TAG('p','s','t','s'), F_GLOBAL},
+ {HB_TAG('h','a','l','n'), F_GLOBAL},
/* Positioning features, though we don't care about the types. */
- {HB_TAG('d','i','s','t'), true},
- {HB_TAG('a','b','v','m'), true},
- {HB_TAG('b','l','w','m'), true},
+ {HB_TAG('d','i','s','t'), F_GLOBAL},
+ {HB_TAG('a','b','v','m'), F_GLOBAL},
+ {HB_TAG('b','l','w','m'), F_GLOBAL},
};
/*
@@ -428,12 +428,12 @@ collect_features_indic (hb_ot_shape_planner_t *plan)
unsigned int i = 0;
map->add_gsub_pause (initial_reordering);
for (; i < INDIC_BASIC_FEATURES; i++) {
- map->add_feature (indic_features[i].tag, 1, indic_features[i].is_global);
+ map->add_feature (indic_features[i].tag, 1, indic_features[i].flags);
map->add_gsub_pause (NULL);
}
map->add_gsub_pause (final_reordering);
for (; i < INDIC_NUM_FEATURES; i++) {
- map->add_feature (indic_features[i].tag, 1, indic_features[i].is_global);
+ map->add_feature (indic_features[i].tag, 1, indic_features[i].flags);
}
}
@@ -442,9 +442,9 @@ override_features_indic (hb_ot_shape_planner_t *plan)
{
/* Uniscribe does not apply 'kern'. */
if (hb_options ().uniscribe_bug_compatible)
- plan->map.add_feature (HB_TAG('k','e','r','n'), 0, true);
+ plan->map.add_feature (HB_TAG('k','e','r','n'), 0, F_GLOBAL);
- plan->map.add_feature (HB_TAG('l','i','g','a'), 0, true);
+ plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL);
}
@@ -532,7 +532,8 @@ data_create_indic (const hb_ot_shape_plan_t *plan)
indic_plan->pstf.init (&plan->map, HB_TAG('p','s','t','f'));
for (unsigned int i = 0; i < ARRAY_LENGTH (indic_plan->mask_array); i++)
- indic_plan->mask_array[i] = indic_features[i].is_global ? 0 : plan->map.get_1_mask (indic_features[i].tag);
+ indic_plan->mask_array[i] = (indic_features[i].flags & F_GLOBAL) ?
+ 0 : plan->map.get_1_mask (indic_features[i].tag);
return indic_plan;
}
diff --git a/src/hb-ot-shape-complex-myanmar.cc b/src/hb-ot-shape-complex-myanmar.cc
index 3f63770..53a9ab4 100644
--- a/src/hb-ot-shape-complex-myanmar.cc
+++ b/src/hb-ot-shape-complex-myanmar.cc
@@ -119,7 +119,7 @@ collect_features_myanmar (hb_ot_shape_planner_t *plan)
static void
override_features_myanmar (hb_ot_shape_planner_t *plan)
{
- plan->map.add_feature (HB_TAG('l','i','g','a'), 0, true);
+ plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL);
/*
* Note:
@@ -130,7 +130,7 @@ override_features_myanmar (hb_ot_shape_planner_t *plan)
* 'mkmk' however.
*/
if (hb_options ().uniscribe_bug_compatible)
- plan->map.add_feature (HB_TAG('m','a','r','k'), 0, true);
+ plan->map.add_feature (HB_TAG('m','a','r','k'), 0, F_GLOBAL);
}
diff --git a/src/hb-ot-shape-complex-sea.cc b/src/hb-ot-shape-complex-sea.cc
index c9bce6c..387a4a1 100644
--- a/src/hb-ot-shape-complex-sea.cc
+++ b/src/hb-ot-shape-complex-sea.cc
@@ -121,7 +121,7 @@ collect_features_sea (hb_ot_shape_planner_t *plan)
static void
override_features_sea (hb_ot_shape_planner_t *plan)
{
- plan->map.add_feature (HB_TAG('l','i','g','a'), 0, true);
+ plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL);
}
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 2a1bfb7..2d78a18 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -88,7 +88,7 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
break;
case HB_DIRECTION_RTL:
map->add_global_bool_feature (HB_TAG ('r','t','l','a'));
- map->add_feature (HB_TAG ('r','t','l','m'), 1, false);
+ map->add_feature (HB_TAG ('r','t','l','m'), 1, F_NONE);
break;
case HB_DIRECTION_TTB:
case HB_DIRECTION_BTT:
@@ -120,7 +120,9 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
for (unsigned int i = 0; i < num_user_features; i++) {
const hb_feature_t *feature = &user_features[i];
- map->add_feature (feature->tag, feature->value, (feature->start == 0 && feature->end == (unsigned int) -1));
+ map->add_feature (feature->tag, feature->value,
+ (feature->start == 0 && feature->end == (unsigned int) -1) ?
+ F_GLOBAL : F_NONE);
}
}
commit e7ffcfafb1108801ac504f18f820e497226bf07f
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Feb 14 11:05:56 2013 -0500
Clean-up add_bool_feature
diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh
index b140207..344e914 100644
--- a/src/hb-ot-map-private.hh
+++ b/src/hb-ot-map-private.hh
@@ -155,8 +155,8 @@ struct hb_ot_map_builder_t
HB_INTERNAL void add_feature (hb_tag_t tag, unsigned int value, bool global, bool has_fallback = false);
- inline void add_bool_feature (hb_tag_t tag, bool global = true, bool has_fallback = false)
- { add_feature (tag, 1, global, has_fallback); }
+ inline void add_global_bool_feature (hb_tag_t tag)
+ { add_feature (tag, 1, true, false); }
inline void add_gsub_pause (hb_ot_map_t::pause_func_t pause_func)
{ add_pause (0, pause_func); }
diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc
index 3374cfc..2c23da5 100644
--- a/src/hb-ot-shape-complex-arabic.cc
+++ b/src/hb-ot-shape-complex-arabic.cc
@@ -178,25 +178,25 @@ collect_features_arabic (hb_ot_shape_planner_t *plan)
* TODO: Add test cases for these two.
*/
- map->add_bool_feature (HB_TAG('c','c','m','p'));
- map->add_bool_feature (HB_TAG('l','o','c','l'));
+ map->add_global_bool_feature (HB_TAG('c','c','m','p'));
+ map->add_global_bool_feature (HB_TAG('l','o','c','l'));
map->add_gsub_pause (NULL);
for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++)
- map->add_bool_feature (arabic_features[i], false, i < 4); /* The first four features have fallback. */
+ map->add_feature (arabic_features[i], 1, false, i < 4); /* The first four features have fallback. */
map->add_gsub_pause (NULL);
- map->add_bool_feature (HB_TAG('r','l','i','g'), true, true);
+ map->add_feature (HB_TAG('r','l','i','g'), 1, true, true);
map->add_gsub_pause (arabic_fallback_shape);
- map->add_bool_feature (HB_TAG('c','a','l','t'));
+ map->add_global_bool_feature (HB_TAG('c','a','l','t'));
map->add_gsub_pause (NULL);
- map->add_bool_feature (HB_TAG('c','s','w','h'));
- map->add_bool_feature (HB_TAG('d','l','i','g'));
- map->add_bool_feature (HB_TAG('m','s','e','t'));
+ map->add_global_bool_feature (HB_TAG('c','s','w','h'));
+ map->add_global_bool_feature (HB_TAG('d','l','i','g'));
+ map->add_global_bool_feature (HB_TAG('m','s','e','t'));
}
#include "hb-ot-shape-complex-arabic-fallback.hh"
diff --git a/src/hb-ot-shape-complex-default.cc b/src/hb-ot-shape-complex-default.cc
index d406f8c..fad57f6 100644
--- a/src/hb-ot-shape-complex-default.cc
+++ b/src/hb-ot-shape-complex-default.cc
@@ -68,7 +68,7 @@ collect_features_default (hb_ot_shape_planner_t *plan)
}
for (; script_features && *script_features; script_features++)
- plan->map.add_bool_feature (*script_features);
+ plan->map.add_global_bool_feature (*script_features);
}
static hb_ot_shape_normalization_mode_t
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 4491daa..bf82615 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -419,21 +419,21 @@ collect_features_indic (hb_ot_shape_planner_t *plan)
/* Do this before any lookups have been applied. */
map->add_gsub_pause (setup_syllables);
- map->add_bool_feature (HB_TAG('l','o','c','l'));
+ map->add_global_bool_feature (HB_TAG('l','o','c','l'));
/* The Indic specs do not require ccmp, but we apply it here since if
* there is a use of it, it's typically at the beginning. */
- map->add_bool_feature (HB_TAG('c','c','m','p'));
+ map->add_global_bool_feature (HB_TAG('c','c','m','p'));
unsigned int i = 0;
map->add_gsub_pause (initial_reordering);
for (; i < INDIC_BASIC_FEATURES; i++) {
- map->add_bool_feature (indic_features[i].tag, indic_features[i].is_global);
+ map->add_feature (indic_features[i].tag, 1, indic_features[i].is_global);
map->add_gsub_pause (NULL);
}
map->add_gsub_pause (final_reordering);
for (; i < INDIC_NUM_FEATURES; i++) {
- map->add_bool_feature (indic_features[i].tag, indic_features[i].is_global);
+ map->add_feature (indic_features[i].tag, 1, indic_features[i].is_global);
}
}
diff --git a/src/hb-ot-shape-complex-myanmar.cc b/src/hb-ot-shape-complex-myanmar.cc
index a115064..3f63770 100644
--- a/src/hb-ot-shape-complex-myanmar.cc
+++ b/src/hb-ot-shape-complex-myanmar.cc
@@ -98,21 +98,21 @@ collect_features_myanmar (hb_ot_shape_planner_t *plan)
/* Do this before any lookups have been applied. */
map->add_gsub_pause (setup_syllables);
- map->add_bool_feature (HB_TAG('l','o','c','l'));
+ map->add_global_bool_feature (HB_TAG('l','o','c','l'));
/* The Indic specs do not require ccmp, but we apply it here since if
* there is a use of it, it's typically at the beginning. */
- map->add_bool_feature (HB_TAG('c','c','m','p'));
+ map->add_global_bool_feature (HB_TAG('c','c','m','p'));
unsigned int i = 0;
map->add_gsub_pause (initial_reordering);
for (; i < MYANMAR_BASIC_FEATURES; i++) {
- map->add_bool_feature (myanmar_features[i]);
+ map->add_global_bool_feature (myanmar_features[i]);
map->add_gsub_pause (NULL);
}
map->add_gsub_pause (final_reordering);
for (; i < MYANMAR_NUM_FEATURES; i++) {
- map->add_bool_feature (myanmar_features[i]);
+ map->add_global_bool_feature (myanmar_features[i]);
}
}
diff --git a/src/hb-ot-shape-complex-sea.cc b/src/hb-ot-shape-complex-sea.cc
index cfd0baa..c9bce6c 100644
--- a/src/hb-ot-shape-complex-sea.cc
+++ b/src/hb-ot-shape-complex-sea.cc
@@ -100,21 +100,21 @@ collect_features_sea (hb_ot_shape_planner_t *plan)
/* Do this before any lookups have been applied. */
map->add_gsub_pause (setup_syllables);
- map->add_bool_feature (HB_TAG('l','o','c','l'));
+ map->add_global_bool_feature (HB_TAG('l','o','c','l'));
/* The Indic specs do not require ccmp, but we apply it here since if
* there is a use of it, it's typically at the beginning. */
- map->add_bool_feature (HB_TAG('c','c','m','p'));
+ map->add_global_bool_feature (HB_TAG('c','c','m','p'));
unsigned int i = 0;
map->add_gsub_pause (initial_reordering);
for (; i < SEA_BASIC_FEATURES; i++) {
- map->add_bool_feature (sea_features[i]);
+ map->add_global_bool_feature (sea_features[i]);
map->add_gsub_pause (NULL);
}
map->add_gsub_pause (final_reordering);
for (; i < SEA_NUM_FEATURES; i++) {
- map->add_bool_feature (sea_features[i]);
+ map->add_global_bool_feature (sea_features[i]);
}
}
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index d529223..2a1bfb7 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -83,12 +83,12 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
switch (props->direction) {
case HB_DIRECTION_LTR:
- map->add_bool_feature (HB_TAG ('l','t','r','a'));
- map->add_bool_feature (HB_TAG ('l','t','r','m'));
+ map->add_global_bool_feature (HB_TAG ('l','t','r','a'));
+ map->add_global_bool_feature (HB_TAG ('l','t','r','m'));
break;
case HB_DIRECTION_RTL:
- map->add_bool_feature (HB_TAG ('r','t','l','a'));
- map->add_bool_feature (HB_TAG ('r','t','l','m'), false);
+ map->add_global_bool_feature (HB_TAG ('r','t','l','a'));
+ map->add_feature (HB_TAG ('r','t','l','m'), 1, false);
break;
case HB_DIRECTION_TTB:
case HB_DIRECTION_BTT:
@@ -100,7 +100,7 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
#define ADD_FEATURES(array) \
HB_STMT_START { \
for (unsigned int i = 0; i < ARRAY_LENGTH (array); i++) \
- map->add_bool_feature (array[i]); \
+ map->add_global_bool_feature (array[i]); \
} HB_STMT_END
if (planner->shaper->collect_features)
commit e7562f53fe6a506d2c6d59d6688e4fa468bba462
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Feb 14 11:05:36 2013 -0500
Fix compile warnings for ragel-generated machines
diff --git a/src/hb-ot-shape-complex-indic-machine.rl b/src/hb-ot-shape-complex-indic-machine.rl
index 11115c9..f9f07d8 100644
--- a/src/hb-ot-shape-complex-indic-machine.rl
+++ b/src/hb-ot-shape-complex-indic-machine.rl
@@ -103,7 +103,7 @@ main := |*
static void
find_syllables (hb_buffer_t *buffer)
{
- unsigned int p, pe, eof, ts HB_UNUSED, te, act;
+ unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED;
int cs;
hb_glyph_info_t *info = buffer->info;
%%{
diff --git a/src/hb-ot-shape-complex-myanmar-machine.rl b/src/hb-ot-shape-complex-myanmar-machine.rl
index 949fde6..51d42dd 100644
--- a/src/hb-ot-shape-complex-myanmar-machine.rl
+++ b/src/hb-ot-shape-complex-myanmar-machine.rl
@@ -102,7 +102,7 @@ main := |*
static void
find_syllables (hb_buffer_t *buffer)
{
- unsigned int p, pe, eof, ts HB_UNUSED, te, act;
+ unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED;
int cs;
hb_glyph_info_t *info = buffer->info;
%%{
diff --git a/src/hb-ot-shape-complex-sea-machine.rl b/src/hb-ot-shape-complex-sea-machine.rl
index 434be6b..46140fc 100644
--- a/src/hb-ot-shape-complex-sea-machine.rl
+++ b/src/hb-ot-shape-complex-sea-machine.rl
@@ -79,7 +79,7 @@ main := |*
static void
find_syllables (hb_buffer_t *buffer)
{
- unsigned int p, pe, eof, ts HB_UNUSED, te, act;
+ unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED;
int cs;
hb_glyph_info_t *info = buffer->info;
%%{
commit 4e51df73a337f7232a7dfa85df78a4f19b24771b
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Feb 14 07:42:42 2013 -0500
[OTLayout] Remove unused function
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 61814ad..07989fa 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -447,11 +447,6 @@ struct hb_apply_context_t
}
- inline bool should_skip_current_glyph (void) const
- {
- return should_skip (&buffer->cur(), lookup_props);
- }
-
inline void set_class (hb_codepoint_t glyph_index, unsigned int class_guess) const
{
if (likely (has_glyph_classes))
commit 8820bb235b1f63e4d93c8a2f5c08b44d89e06b78
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Feb 14 07:41:03 2013 -0500
[OTLayout] Port apply_lookup to skippy_iter
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 53be8f8..61814ad 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -839,19 +839,35 @@ static inline bool apply_lookup (hb_apply_context_t *c,
* and we jump out of it. Not entirely disastrous. So we don't check
* for reverse lookup here.
*/
- for (unsigned int i = 0; i < count; /* NOP */)
+ unsigned int i = 0;
+ if (lookupCount && 0 == lookupRecord->sequenceIndex)
{
- if (unlikely (c->buffer->idx == end))
- return TRACE_RETURN (true);
+ unsigned int old_pos = c->buffer->idx;
- if (i)
- while (c->should_skip_current_glyph ())
- {
- /* No lookup applied for this index */
- c->buffer->next_glyph ();
- if (unlikely (c->buffer->idx == end))
- return TRACE_RETURN (true);
- }
+ /* Apply a lookup */
+ bool done = c->recurse (lookupRecord->lookupListIndex);
+
+ lookupRecord++;
+ lookupCount--;
+ /* Err, this is wrong if the lookup jumped over some glyphs */
+ i += c->buffer->idx - old_pos;
+
+ if (!done)
+ goto not_applied;
+ }
+ else
+ {
+ not_applied:
+ /* No lookup applied for this index */
+ c->buffer->next_glyph ();
+ i++;
+ }
+ hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx - 1, count - i);
+ while (i < count)
+ {
+ if (!skippy_iter.next ()) return TRACE_RETURN (true);
+ while (c->buffer->idx < skippy_iter.idx)
+ c->buffer->next_glyph ();
if (lookupCount && i == lookupRecord->sequenceIndex)
{
@@ -864,15 +880,19 @@ static inline bool apply_lookup (hb_apply_context_t *c,
lookupCount--;
/* Err, this is wrong if the lookup jumped over some glyphs */
i += c->buffer->idx - old_pos;
- if (unlikely (c->buffer->idx == end))
- return TRACE_RETURN (true);
if (!done)
- goto not_applied;
+ goto not_applied2;
+ else
+ {
+ /* Reinitialize iterator. */
+ hb_apply_context_t::skipping_forward_iterator_t tmp (c, c->buffer->idx - 1, count - i);
+ skippy_iter = tmp;
+ }
}
else
{
- not_applied:
+ not_applied2:
/* No lookup applied for this index */
c->buffer->next_glyph ();
i++;
commit dfca269f069dae2f99990dac24da15d316eccb9f
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Feb 14 07:20:52 2013 -0500
[OTLayout] Port ligate_input to skippy_iter
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index eabbe45..53be8f8 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -705,13 +705,16 @@ static inline void ligate_input (hb_apply_context_t *c,
unsigned int last_num_components = get_lig_num_comps (c->buffer->cur());
unsigned int components_so_far = last_num_components;
+ hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, count - 1);
+
if (!is_mark_ligature)
set_lig_props_for_ligature (c->buffer->cur(), lig_id, total_component_count);
c->replace_glyph (lig_glyph, klass);
for (unsigned int i = 1; i < count; i++)
{
- while (c->should_skip_current_glyph ())
+ if (!skippy_iter.next ()) return;
+ while (c->buffer->idx < skippy_iter.idx)
{
if (!is_mark_ligature) {
unsigned int new_lig_comp = components_so_far - last_num_components +
commit 7e53415c2d8859e8b5948a2edb38c39a8f78b825
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Feb 14 06:24:30 2013 -0500
[OTLayout] Minor fix for apply_lookup()
Should NOT change behavior, since first glyph is a match.
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 752957b..eabbe45 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -840,13 +840,15 @@ static inline bool apply_lookup (hb_apply_context_t *c,
{
if (unlikely (c->buffer->idx == end))
return TRACE_RETURN (true);
- while (c->should_skip_current_glyph ())
- {
- /* No lookup applied for this index */
- c->buffer->next_glyph ();
- if (unlikely (c->buffer->idx == end))
- return TRACE_RETURN (true);
- }
+
+ if (i)
+ while (c->should_skip_current_glyph ())
+ {
+ /* No lookup applied for this index */
+ c->buffer->next_glyph ();
+ if (unlikely (c->buffer->idx == end))
+ return TRACE_RETURN (true);
+ }
if (lookupCount && i == lookupRecord->sequenceIndex)
{
commit 6880f7e19d44c50e45ecb86d26381aad956d9acb
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Feb 13 12:17:25 2013 -0500
[OTLayout] Make table type known to apply context
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 04b29eb..752957b 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -255,6 +255,7 @@ struct hb_apply_context_t
return ret;
}
+ unsigned int table_index; /* GSUB/GPOS */
hb_font_t *font;
hb_face_t *face;
hb_buffer_t *buffer;
@@ -268,9 +269,11 @@ struct hb_apply_context_t
unsigned int debug_depth;
- hb_apply_context_t (hb_font_t *font_,
+ hb_apply_context_t (unsigned int table_index_,
+ hb_font_t *font_,
hb_buffer_t *buffer_,
hb_mask_t lookup_mask_) :
+ table_index (table_index_),
font (font_), face (font->face), buffer (buffer_),
direction (buffer_->props.direction),
lookup_mask (lookup_mask_),
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index 291ff9a..62988ab 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -670,7 +670,7 @@ hb_ot_layout_substitute_lookup (hb_font_t *font,
{
if (unlikely (lookup_index >= hb_ot_layout_from_face (font->face)->gsub_lookup_count)) return false;
- OT::hb_apply_context_t c (font, buffer, mask);
+ OT::hb_apply_context_t c (0, font, buffer, mask);
const OT::SubstLookup& l = hb_ot_layout_from_face (font->face)->gsub->get_lookup (lookup_index);
@@ -719,7 +719,7 @@ hb_ot_layout_position_lookup (hb_font_t *font,
{
if (unlikely (lookup_index >= hb_ot_layout_from_face (font->face)->gpos_lookup_count)) return false;
- OT::hb_apply_context_t c (font, buffer, mask);
+ OT::hb_apply_context_t c (1, font, buffer, mask);
const OT::PosLookup& l = hb_ot_layout_from_face (font->face)->gpos->get_lookup (lookup_index);
diff --git a/src/hb-ot-shape-complex-arabic-fallback.hh b/src/hb-ot-shape-complex-arabic-fallback.hh
index 4fcd0a2..c0dbff0 100644
--- a/src/hb-ot-shape-complex-arabic-fallback.hh
+++ b/src/hb-ot-shape-complex-arabic-fallback.hh
@@ -244,7 +244,7 @@ arabic_fallback_plan_shape (arabic_fallback_plan_t *fallback_plan,
{
for (unsigned int i = 0; i < ARABIC_NUM_FALLBACK_FEATURES; i++)
if (fallback_plan->lookup_array[i]) {
- OT::hb_apply_context_t c (font, buffer, fallback_plan->mask_array[i]);
+ OT::hb_apply_context_t c (0, font, buffer, fallback_plan->mask_array[i]);
fallback_plan->lookup_array[i]->apply_string (&c, &fallback_plan->digest_array[i]);
}
}
commit 2c7d0b6b80d412de3fddd443ed1a485ea1cbb03c
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Feb 13 12:10:08 2013 -0500
[OTLayou] Unbreak backtrack matching
Was introduced by 28b9d502bb69a8045818d5f6113ded9c59a56bd7.
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index a9824eb..04b29eb 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -340,15 +340,14 @@ struct hb_apply_context_t
inline skipping_backward_iterator_t (hb_apply_context_t *c_,
unsigned int start_index_,
unsigned int num_items_,
- hb_mask_t mask_ = 0,
- bool match_syllable_ = true)
+ bool context_match = false)
{
c = c_;
lookup_props = c->lookup_props;
idx = start_index_;
num_items = num_items_;
- mask = mask_ ? mask_ : c->lookup_mask;
- syllable = match_syllable_ ? c->buffer->cur().syllable () : 0;
+ mask = context_match ? -1 : c->lookup_mask;
+ syllable = context_match ? 0 : c->buffer->cur().syllable ();
}
inline void set_lookup_props (unsigned int lookup_props_)
{
commit c074ebc466dcc9bcc0d8a5dd7e942dea974ff718
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Feb 13 11:22:42 2013 -0500
[OTLayout] Minor refactoring
diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh
index 91bdcc4..71e0aee 100644
--- a/src/hb-ot-layout-gpos-table.hh
+++ b/src/hb-ot-layout-gpos-table.hh
@@ -1029,8 +1029,9 @@ struct MarkBasePosFormat1
/* now we search backwards for a non-mark glyph */
hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->idx, 1);
+ skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
do {
- if (!skippy_iter.prev (LookupFlag::IgnoreMarks)) return TRACE_RETURN (false);
+ if (!skippy_iter.prev ()) return TRACE_RETURN (false);
/* We only want to attach to the first of a MultipleSubst sequence. Reject others. */
if (0 == get_lig_comp (c->buffer->info[skippy_iter.idx])) break;
skippy_iter.reject ();
@@ -1132,7 +1133,8 @@ struct MarkLigPosFormat1
/* now we search backwards for a non-mark glyph */
hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->idx, 1);
- if (!skippy_iter.prev (LookupFlag::IgnoreMarks)) return TRACE_RETURN (false);
+ skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
+ if (!skippy_iter.prev ()) return TRACE_RETURN (false);
/* The following assertion is too strong, so we've disabled it. */
if (!(c->buffer->info[skippy_iter.idx].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE)) {/*return TRACE_RETURN (false);*/}
@@ -1247,7 +1249,8 @@ struct MarkMarkPosFormat1
/* now we search backwards for a suitable mark glyph until a non-mark glyph */
hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->idx, 1);
- if (!skippy_iter.prev (c->lookup_props & ~LookupFlag::IgnoreFlags)) return TRACE_RETURN (false);
+ skippy_iter.set_lookup_props (c->lookup_props & ~LookupFlag::IgnoreFlags);
+ if (!skippy_iter.prev ()) return TRACE_RETURN (false);
if (!(c->buffer->info[skippy_iter.idx].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK)) { return TRACE_RETURN (false); }
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index bbbb9c1..a9824eb 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -281,9 +281,9 @@ struct hb_apply_context_t
has_glyph_classes (gdef.has_glyph_classes ()),
debug_depth (0) {}
- void set_recurse_func (recurse_func_t func) { recurse_func = func; }
- void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; }
- void set_lookup (const Lookup &l) { lookup_props = l.get_props (); }
+ inline void set_recurse_func (recurse_func_t func) { recurse_func = func; }
+ inline void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; }
+ inline void set_lookup (const Lookup &l) { lookup_props = l.get_props (); }
struct skipping_forward_iterator_t
{
@@ -293,12 +293,17 @@ struct hb_apply_context_t
bool context_match = false)
{
c = c_;
+ lookup_props = c->lookup_props;
idx = start_index_;
num_items = num_items_;
mask = context_match ? -1 : c->lookup_mask;
syllable = context_match ? 0 : c->buffer->cur().syllable ();
end = c->buffer->len;
}
+ inline void set_lookup_props (unsigned int lookup_props_)
+ {
+ lookup_props = lookup_props_;
+ }
inline bool has_no_chance (void) const
{
return unlikely (num_items && idx + num_items >= end);
@@ -307,7 +312,7 @@ struct hb_apply_context_t
{
num_items++;
}
- inline bool next (unsigned int lookup_props)
+ inline bool next (void)
{
assert (num_items > 0);
do
@@ -319,14 +324,11 @@ struct hb_apply_context_t
num_items--;
return (c->buffer->info[idx].mask & mask) && (!syllable || syllable == c->buffer->info[idx].syllable ());
}
- inline bool next (void)
- {
- return next (c->lookup_props);
- }
unsigned int idx;
protected:
hb_apply_context_t *c;
+ unsigned int lookup_props;
unsigned int num_items;
hb_mask_t mask;
uint8_t syllable;
@@ -342,11 +344,16 @@ struct hb_apply_context_t
bool match_syllable_ = true)
{
c = c_;
+ lookup_props = c->lookup_props;
idx = start_index_;
num_items = num_items_;
mask = mask_ ? mask_ : c->lookup_mask;
syllable = match_syllable_ ? c->buffer->cur().syllable () : 0;
}
+ inline void set_lookup_props (unsigned int lookup_props_)
+ {
+ lookup_props = lookup_props_;
+ }
inline bool has_no_chance (void) const
{
return unlikely (idx < num_items);
@@ -355,7 +362,7 @@ struct hb_apply_context_t
{
num_items++;
}
- inline bool prev (unsigned int lookup_props)
+ inline bool prev (void)
{
assert (num_items > 0);
do
@@ -367,14 +374,11 @@ struct hb_apply_context_t
num_items--;
return (c->buffer->out_info[idx].mask & mask) && (!syllable || syllable == c->buffer->out_info[idx].syllable ());
}
- inline bool prev (void)
- {
- return prev (c->lookup_props);
- }
unsigned int idx;
protected:
hb_apply_context_t *c;
+ unsigned int lookup_props;
unsigned int num_items;
hb_mask_t mask;
uint8_t syllable;
commit 407fc12466ef460d0edf11b89f0d04c4d724875f
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Feb 13 11:13:06 2013 -0500
[OTLayout] Remove bogus caching of glyph property
diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh
index 59d818e..91bdcc4 100644
--- a/src/hb-ot-layout-gpos-table.hh
+++ b/src/hb-ot-layout-gpos-table.hh
@@ -878,7 +878,7 @@ struct CursivePosFormat1
TRACE_APPLY (this);
/* We don't handle mark glyphs here. */
- if (c->property & HB_OT_LAYOUT_GLYPH_PROPS_MARK) return TRACE_RETURN (false);
+ if (c->buffer->cur().glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK) return TRACE_RETURN (false);
hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, 1);
if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
@@ -1028,17 +1028,16 @@ struct MarkBasePosFormat1
if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false);
/* now we search backwards for a non-mark glyph */
- unsigned int property;
hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->idx, 1);
do {
- if (!skippy_iter.prev (&property, LookupFlag::IgnoreMarks)) return TRACE_RETURN (false);
+ if (!skippy_iter.prev (LookupFlag::IgnoreMarks)) return TRACE_RETURN (false);
/* We only want to attach to the first of a MultipleSubst sequence. Reject others. */
if (0 == get_lig_comp (c->buffer->info[skippy_iter.idx])) break;
skippy_iter.reject ();
} while (1);
/* The following assertion is too strong, so we've disabled it. */
- if (!(property & HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH)) {/*return TRACE_RETURN (false);*/}
+ if (!(c->buffer->info[skippy_iter.idx].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH)) {/*return TRACE_RETURN (false);*/}
unsigned int base_index = (this+baseCoverage).get_coverage (c->buffer->info[skippy_iter.idx].codepoint);
if (base_index == NOT_COVERED) return TRACE_RETURN (false);
@@ -1132,12 +1131,11 @@ struct MarkLigPosFormat1
if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false);
/* now we search backwards for a non-mark glyph */
- unsigned int property;
hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->idx, 1);
- if (!skippy_iter.prev (&property, LookupFlag::IgnoreMarks)) return TRACE_RETURN (false);
+ if (!skippy_iter.prev (LookupFlag::IgnoreMarks)) return TRACE_RETURN (false);
/* The following assertion is too strong, so we've disabled it. */
- if (!(property & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE)) {/*return TRACE_RETURN (false);*/}
+ if (!(c->buffer->info[skippy_iter.idx].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE)) {/*return TRACE_RETURN (false);*/}
unsigned int j = skippy_iter.idx;
unsigned int lig_index = (this+ligatureCoverage).get_coverage (c->buffer->info[j].codepoint);
@@ -1248,11 +1246,10 @@ struct MarkMarkPosFormat1
if (likely (mark1_index == NOT_COVERED)) return TRACE_RETURN (false);
/* now we search backwards for a suitable mark glyph until a non-mark glyph */
- unsigned int property;
hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->idx, 1);
- if (!skippy_iter.prev (&property, c->lookup_props & ~LookupFlag::IgnoreFlags)) return TRACE_RETURN (false);
+ if (!skippy_iter.prev (c->lookup_props & ~LookupFlag::IgnoreFlags)) return TRACE_RETURN (false);
- if (!(property & HB_OT_LAYOUT_GLYPH_PROPS_MARK)) return TRACE_RETURN (false);
+ if (!(c->buffer->info[skippy_iter.idx].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK)) { return TRACE_RETURN (false); }
unsigned int j = skippy_iter.idx;
@@ -1474,7 +1471,7 @@ struct PosLookup : Lookup
inline bool apply_once (hb_apply_context_t *c) const
{
TRACE_APPLY (this);
- if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props, &c->property))
+ if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props))
return TRACE_RETURN (false);
return TRACE_RETURN (process (c));
}
@@ -1629,11 +1626,9 @@ inline bool PosLookup::apply_recurse_func (hb_apply_context_t *c, unsigned int l
const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos);
const PosLookup &l = gpos.get_lookup (lookup_index);
unsigned int saved_lookup_props = c->lookup_props;
- unsigned int saved_property = c->property;
c->set_lookup (l);
bool ret = l.apply_once (c);
c->lookup_props = saved_lookup_props;
- c->property = saved_property;
return ret;
}
diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index 2642acb..ec549a8 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -272,7 +272,8 @@ struct Sequence
TRACE_APPLY (this);
if (unlikely (!substitute.len)) return TRACE_RETURN (false);
- unsigned int klass = c->property & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE ? HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0;
+ unsigned int klass = c->buffer->cur().glyph_props() &
+ HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE ? HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0;
unsigned int count = substitute.len;
for (unsigned int i = 0; i < count; i++) {
set_lig_props_for_component (c->buffer->cur(), i);
@@ -1193,7 +1194,7 @@ struct SubstLookup : Lookup
inline bool apply_once (hb_apply_context_t *c) const
{
TRACE_APPLY (this);
- if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props, &c->property))
+ if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props))
return TRACE_RETURN (false);
return TRACE_RETURN (process (c));
}
@@ -1399,11 +1400,9 @@ inline bool SubstLookup::apply_recurse_func (hb_apply_context_t *c, unsigned int
const GSUB &gsub = *(hb_ot_layout_from_face (c->face)->gsub);
const SubstLookup &l = gsub.get_lookup (lookup_index);
unsigned int saved_lookup_props = c->lookup_props;
- unsigned int saved_property = c->property;
c->set_lookup (l);
bool ret = l.apply_once (c);
c->lookup_props = saved_lookup_props;
- c->property = saved_property;
return ret;
}
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index cb0eaa5..bbbb9c1 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -263,7 +263,6 @@ struct hb_apply_context_t
recurse_func_t recurse_func;
unsigned int nesting_level_left;
unsigned int lookup_props;
- unsigned int property; /* propety of first glyph */
const GDEF &gdef;
bool has_glyph_classes;
unsigned int debug_depth;
@@ -277,7 +276,7 @@ struct hb_apply_context_t
lookup_mask (lookup_mask_),
recurse_func (NULL),
nesting_level_left (MAX_NESTING_LEVEL),
- lookup_props (0), property (0),
+ lookup_props (0),
gdef (*hb_ot_layout_from_face (face)->gdef),
has_glyph_classes (gdef.has_glyph_classes ()),
debug_depth (0) {}
@@ -308,8 +307,7 @@ struct hb_apply_context_t
{
num_items++;
}
- inline bool next (unsigned int *property_out,
- unsigned int lookup_props)
+ inline bool next (unsigned int lookup_props)
{
assert (num_items > 0);
do
@@ -317,13 +315,13 @@ struct hb_apply_context_t
if (has_no_chance ())
return false;
idx++;
- } while (c->should_skip (&c->buffer->info[idx], lookup_props, property_out));
+ } while (c->should_skip (&c->buffer->info[idx], lookup_props));
num_items--;
return (c->buffer->info[idx].mask & mask) && (!syllable || syllable == c->buffer->info[idx].syllable ());
}
- inline bool next (unsigned int *property_out = NULL)
+ inline bool next (void)
{
- return next (property_out, c->lookup_props);
+ return next (c->lookup_props);
}
unsigned int idx;
@@ -357,8 +355,7 @@ struct hb_apply_context_t
{
num_items++;
}
- inline bool prev (unsigned int *property_out,
- unsigned int lookup_props)
+ inline bool prev (unsigned int lookup_props)
{
assert (num_items > 0);
do
@@ -366,13 +363,13 @@ struct hb_apply_context_t
if (has_no_chance ())
return false;
idx--;
- } while (c->should_skip (&c->buffer->out_info[idx], lookup_props, property_out));
+ } while (c->should_skip (&c->buffer->out_info[idx], lookup_props));
num_items--;
return (c->buffer->out_info[idx].mask & mask) && (!syllable || syllable == c->buffer->out_info[idx].syllable ());
}
- inline bool prev (unsigned int *property_out = NULL)
+ inline bool prev (void)
{
- return prev (property_out, c->lookup_props);
+ return prev (c->lookup_props);
}
unsigned int idx;
@@ -423,27 +420,22 @@ struct hb_apply_context_t
inline bool
check_glyph_property (hb_glyph_info_t *info,
- unsigned int lookup_props,
- unsigned int *property_out) const
+ unsigned int lookup_props) const
{
unsigned int property;
property = info->glyph_props();
- *property_out = property;
return match_properties (info->codepoint, property, lookup_props);
}
inline bool
should_skip (hb_glyph_info_t *info,
- unsigned int lookup_props,
- unsigned int *property_out) const
+ unsigned int lookup_props) const
{
unsigned int property;
property = info->glyph_props();
- if (property_out)
- *property_out = property;
return !match_properties (info->codepoint, property, lookup_props);
}
@@ -451,7 +443,7 @@ struct hb_apply_context_t
inline bool should_skip_current_glyph (void) const
{
- return should_skip (&buffer->cur(), lookup_props, NULL);
+ return should_skip (&buffer->cur(), lookup_props);
}
inline void set_class (hb_codepoint_t glyph_index, unsigned int class_guess) const
@@ -618,7 +610,7 @@ static inline bool match_input (hb_apply_context_t *c,
* ligate with a conjunct...)
*/
- bool is_mark_ligature = !!(c->property & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
+ bool is_mark_ligature = !!(c->buffer->cur().glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
unsigned int total_component_count = 0;
total_component_count += get_lig_num_comps (c->buffer->cur());
@@ -628,9 +620,7 @@ static inline bool match_input (hb_apply_context_t *c,
for (unsigned int i = 1; i < count; i++)
{
- unsigned int property;
-
- if (!skippy_iter.next (&property)) return TRACE_RETURN (false);
+ if (!skippy_iter.next ()) return TRACE_RETURN (false);
if (likely (!match_func (c->buffer->info[skippy_iter.idx].codepoint, input[i - 1], match_data))) return TRACE_RETURN (false);
@@ -651,7 +641,7 @@ static inline bool match_input (hb_apply_context_t *c,
return TRACE_RETURN (false);
}
- is_mark_ligature = is_mark_ligature && (property & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
+ is_mark_ligature = is_mark_ligature && (c->buffer->info[skippy_iter.idx].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
total_component_count += get_lig_num_comps (c->buffer->info[skippy_iter.idx]);
}
commit 6b1e3502e23c110dd810f854ba021f83baab1548
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Feb 13 11:02:54 2013 -0500
Remember ZWNJ
To be used in upcoming changes.
diff --git a/src/hb-ot-shape-private.hh b/src/hb-ot-shape-private.hh
index 23e80b7..74c5b19 100644
--- a/src/hb-ot-shape-private.hh
+++ b/src/hb-ot-shape-private.hh
@@ -94,14 +94,15 @@ inline void
_hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *unicode)
{
info->unicode_props0() = ((unsigned int) unicode->general_category (info->codepoint)) |
- (unicode->is_default_ignorable (info->codepoint) ? 0x80 : 0);
+ (unicode->is_default_ignorable (info->codepoint) ? 0x80 : 0) |
+ (info->codepoint == 0x200C ? 0x40 : 0);
info->unicode_props1() = unicode->modified_combining_class (info->codepoint);
}
inline hb_unicode_general_category_t
_hb_glyph_info_get_general_category (const hb_glyph_info_t *info)
{
- return (hb_unicode_general_category_t) (info->unicode_props0() & 0x7F);
+ return (hb_unicode_general_category_t) (info->unicode_props0() & 0x3F);
}
inline void
@@ -122,4 +123,10 @@ _hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info)
return !!(info->unicode_props0() & 0x80);
}
+inline hb_bool_t
+_hb_glyph_info_is_zwnj (const hb_glyph_info_t *info)
+{
+ return !!(info->unicode_props0() & 0x40);
+}
+
#endif /* HB_OT_SHAPE_PRIVATE_HH */
commit 1f91c39677f840a1f630696d16d083060069abf5
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Feb 13 09:38:40 2013 -0500
Indent
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 45b5825..4491daa 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -1304,7 +1304,8 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
while (new_reph_pos < base && !is_halant_or_coeng (info[new_reph_pos]))
new_reph_pos++;
- if (new_reph_pos < base && is_halant_or_coeng (info[new_reph_pos])) {
+ if (new_reph_pos < base && is_halant_or_coeng (info[new_reph_pos]))
+ {
/* ->If ZWJ or ZWNJ are following this halant, position is moved after it. */
if (new_reph_pos + 1 < base && is_joiner (info[new_reph_pos + 1]))
new_reph_pos++;
@@ -1356,7 +1357,8 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
while (new_reph_pos < base && !is_halant_or_coeng (info[new_reph_pos]))
new_reph_pos++;
- if (new_reph_pos < base && is_halant_or_coeng (info[new_reph_pos])) {
+ if (new_reph_pos < base && is_halant_or_coeng (info[new_reph_pos]))
+ {
/* ->If ZWJ or ZWNJ are following this halant, position is moved after it. */
if (new_reph_pos + 1 < base && is_joiner (info[new_reph_pos + 1]))
new_reph_pos++;
@@ -1455,9 +1457,11 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
}
if (new_pos > start && is_halant_or_coeng (info[new_pos - 1]))
+ {
/* -> If ZWJ or ZWNJ follow this halant, position is moved after it. */
if (new_pos < end && is_joiner (info[new_pos]))
new_pos++;
+ }
{
unsigned int old_pos = i;
commit a0cb9f33ee064628debe8e848094dfd661334640
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Feb 13 09:26:55 2013 -0500
[Indic] Improve base finding in final_reordering
Fixes 5 Malayalam failures!
MALAYALAM: 1048016 out of 1048334 tests passed. 318 failed (0.0303338%)
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 9304dde..45b5825 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -1186,6 +1186,13 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
base--;
break;
}
+ if (base == end && start < base &&
+ info[base - 1].indic_category() != OT_ZWJ)
+ base--;
+ while (start < base &&
+ (info[base].indic_category() == OT_H ||
+ info[base].indic_category() == OT_N))
+ base--;
/* o Reorder matras:
commit 126f39cd16cea87b2696f66467c83a585bd4c2cf
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Feb 13 08:29:21 2013 -0500
Add more dot-reph tests
diff --git a/test/shaping/texts/in-tree/shaper-indic/indic/script-malayalam/misc/dot-reph.txt b/test/shaping/texts/in-tree/shaper-indic/indic/script-malayalam/misc/dot-reph.txt
index 01b28dc..d158b8f 100644
--- a/test/shaping/texts/in-tree/shaper-indic/indic/script-malayalam/misc/dot-reph.txt
+++ b/test/shaping/texts/in-tree/shaper-indic/indic/script-malayalam/misc/dot-reph.txt
@@ -1,2 +1,12 @@
àµà´
àµà´àµà´àµà´°
+àµà´¨àµà´¨
+àµà´àµà´àµà´°àµ
+àµà´àµà´°àµ
+àµà´àµ
+àµà´
+à´àµà´àµà´°àµ
+à´àµà´àµà´°
+à´àµà´àµ
+à´àµà´
+à´àµà´°àµ
More information about the HarfBuzz
mailing list