[HarfBuzz] harfbuzz: Branch 'master' - 5 commits
Behdad Esfahbod
behdad at kemper.freedesktop.org
Thu Jul 17 12:59:36 PDT 2014
src/hb-fallback-shape.cc | 36 +--
src/hb-ot-shape-complex-arabic.cc | 106 ++++++----
src/hb-ot-shape-complex-indic.cc | 15 -
src/hb-ot-shape-complex-myanmar.cc | 7
src/hb-ot-shape-complex-sea.cc | 7
src/hb-ot-shape-fallback.cc | 30 +-
src/hb-ot-shape.cc | 18 +
src/hb-unicode-private.hh | 3
test/shaping/Makefile.am | 2
test/shaping/fonts/sha1sum/813c2f8e5512187fd982417a7fb4286728e6f4a8.ttf |binary
test/shaping/fonts/sha1sum/8a9fea2a7384f2116e5b84a9b31f83be7850ce21.ttf |binary
test/shaping/fonts/sha1sum/MANIFEST | 4
test/shaping/fonts/sha1sum/a919b33197965846f21074b24e30250d67277bce.ttf |binary
test/shaping/fonts/sha1sum/ef86fe710cfea877bbe0dbb6946a1f88d0661031.ttf |binary
test/shaping/record-test.sh | 5
test/shaping/tests/MANIFEST | 1
test/shaping/tests/arabic-feature-order.tests | 3
test/shaping/tests/mongolian-variation-selector.tests | 1
18 files changed, 155 insertions(+), 83 deletions(-)
New commits:
commit 82f4d9d53f348f41b14b877c1ac77c0372c49caa
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Jul 17 15:57:37 2014 -0400
[arabic] Add note re disabled 'cswh'
diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc
index 1b4ebc9..b90abfe 100644
--- a/src/hb-ot-shape-complex-arabic.cc
+++ b/src/hb-ot-shape-complex-arabic.cc
@@ -184,6 +184,15 @@ collect_features_arabic (hb_ot_shape_planner_t *plan)
map->add_global_bool_feature (HB_TAG('c','a','l','t'));
map->add_gsub_pause (NULL);
+ /* The spec includes 'cswh'. Earlier versions of Windows
+ * used to enable this by default, but testing suggests
+ * that Windows 8 and later do not enable it by default,
+ * and spec now says 'Off by default'.
+ * We disabled this in ae23c24c32.
+ * Note that IranNastaliq uses this feature extensively
+ * to fixup broken glyph sequences. Oh well...
+ * Test case: U+0643,U+0640,U+0631. */
+ map->add_global_bool_feature (HB_TAG('c','s','w','h'));
map->add_global_bool_feature (HB_TAG('m','s','e','t'));
}
commit 615d00ea252739da57edbd980ff27e573f88ee7e
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Jul 17 13:36:09 2014 -0400
[arabic] Apply init/medi/isol/fini/... in separate stages
Follows the order of the Arabic/Syriac specs. Also don't stop
between rlig and calt in non-Arabic scripts.
Micro-tests for Arabic and Mongolian added for the latter.
diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc
index 3c59743..1b4ebc9 100644
--- a/src/hb-ot-shape-complex-arabic.cc
+++ b/src/hb-ot-shape-complex-arabic.cc
@@ -68,31 +68,30 @@ static unsigned int get_joining_type (hb_codepoint_t u, hb_unicode_general_categ
) ? JOINING_TYPE_T : JOINING_TYPE_U;
}
+#define FEATURE_IS_SYRIAC(tag) hb_in_range<unsigned char> ((unsigned char) (tag), '2', '3')
+
static const hb_tag_t arabic_features[] =
{
- HB_TAG('i','n','i','t'),
- HB_TAG('m','e','d','i'),
- HB_TAG('f','i','n','a'),
HB_TAG('i','s','o','l'),
- /* Syriac */
- HB_TAG('m','e','d','2'),
+ HB_TAG('f','i','n','a'),
HB_TAG('f','i','n','2'),
HB_TAG('f','i','n','3'),
+ HB_TAG('m','e','d','i'),
+ HB_TAG('m','e','d','2'),
+ HB_TAG('i','n','i','t'),
HB_TAG_NONE
};
/* Same order as the feature array */
enum {
- INIT,
- MEDI,
- FINA,
ISOL,
-
- /* Syriac */
- MED2,
+ FINA,
FIN2,
FIN3,
+ MEDI,
+ MED2,
+ INIT,
NONE,
@@ -145,14 +144,23 @@ collect_features_arabic (hb_ot_shape_planner_t *plan)
{
hb_ot_map_builder_t *map = &plan->map;
- /* For Language forms (in ArabicOT speak), we do the iso/fina/medi/init together,
- * then rlig and calt each in their own stage. This makes IranNastaliq's ALLAH
- * ligature work correctly. It's unfortunate though...
+ /* We apply features according to the Arabic spec, with pauses
+ * in between most.
*
- * This also makes Arial Bold in Windows7 work. See:
+ * The pause between init/medi/... and rlig is required. See eg:
* https://bugzilla.mozilla.org/show_bug.cgi?id=644184
*
- * TODO: Add test cases for these two.
+ * The pauses between init/medi/... themselves are not necessarily
+ * needed as only one of those features is applied to any character.
+ * The only difference it makes is when fonts have contextual
+ * substitutions. We now follow the order of the spec, which makes
+ * for better experience if that's what Uniscribe is doing.
+ *
+ * At least for Arabic, looks like Uniscribe has a pause between
+ * rlig and calt. Otherwise the IranNastaliq's ALLAH ligature won't
+ * work. However, testing shows that rlig and calt are applied
+ * together for Mongolian in Uniscribe. As such, we only add a
+ * pause for Arabic, not other scripts.
*/
map->add_gsub_pause (nuke_joiners);
@@ -163,12 +171,15 @@ 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, i < 4 ? F_HAS_FALLBACK : F_NONE); /* The first four features have fallback. */
-
- map->add_gsub_pause (NULL);
+ {
+ bool has_fallback = plan->props.script == HB_SCRIPT_ARABIC && !FEATURE_IS_SYRIAC (arabic_features[i]);
+ map->add_feature (arabic_features[i], 1, has_fallback ? F_HAS_FALLBACK : F_NONE);
+ map->add_gsub_pause (NULL);
+ }
map->add_feature (HB_TAG('r','l','i','g'), 1, F_GLOBAL|F_HAS_FALLBACK);
- map->add_gsub_pause (arabic_fallback_shape);
+ if (plan->props.script == HB_SCRIPT_ARABIC)
+ map->add_gsub_pause (arabic_fallback_shape);
map->add_global_bool_feature (HB_TAG('c','a','l','t'));
map->add_gsub_pause (NULL);
@@ -202,8 +213,9 @@ data_create_arabic (const hb_ot_shape_plan_t *plan)
arabic_plan->do_fallback = plan->props.script == HB_SCRIPT_ARABIC;
for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++) {
arabic_plan->mask_array[i] = plan->map.get_1_mask (arabic_features[i]);
- if (i < 4)
- arabic_plan->do_fallback = arabic_plan->do_fallback && plan->map.needs_fallback (arabic_features[i]);
+ arabic_plan->do_fallback = arabic_plan->do_fallback &&
+ !FEATURE_IS_SYRIAC (arabic_features[i]) &&
+ plan->map.needs_fallback (arabic_features[i]);
}
return arabic_plan;
diff --git a/test/shaping/Makefile.am b/test/shaping/Makefile.am
index 33f75ab..3f43aec 100644
--- a/test/shaping/Makefile.am
+++ b/test/shaping/Makefile.am
@@ -36,8 +36,10 @@ CLEANFILES += \
$(NULL)
TESTS = \
+ tests/arabic-feature-order.tests \
tests/context-matching.tests \
tests/indic-pref-blocking.tests \
+ tests/mongolian-variation-selector.tests \
$(NULL)
TEST_EXTENSIONS = \
diff --git a/test/shaping/fonts/sha1sum/813c2f8e5512187fd982417a7fb4286728e6f4a8.ttf b/test/shaping/fonts/sha1sum/813c2f8e5512187fd982417a7fb4286728e6f4a8.ttf
new file mode 100644
index 0000000..b728b27
Binary files /dev/null and b/test/shaping/fonts/sha1sum/813c2f8e5512187fd982417a7fb4286728e6f4a8.ttf differ
diff --git a/test/shaping/fonts/sha1sum/8a9fea2a7384f2116e5b84a9b31f83be7850ce21.ttf b/test/shaping/fonts/sha1sum/8a9fea2a7384f2116e5b84a9b31f83be7850ce21.ttf
new file mode 100644
index 0000000..875c699
Binary files /dev/null and b/test/shaping/fonts/sha1sum/8a9fea2a7384f2116e5b84a9b31f83be7850ce21.ttf differ
diff --git a/test/shaping/fonts/sha1sum/MANIFEST b/test/shaping/fonts/sha1sum/MANIFEST
index d1ff350..0e52060 100644
--- a/test/shaping/fonts/sha1sum/MANIFEST
+++ b/test/shaping/fonts/sha1sum/MANIFEST
@@ -1,6 +1,9 @@
226bc2deab3846f1a682085f70c67d0421014144.ttf
37033cc5cf37bb223d7355153016b6ccece93b28.ttf
4cce528e99f600ed9c25a2b69e32eb94a03b4ae8.ttf
+813c2f8e5512187fd982417a7fb4286728e6f4a8.ttf
+8a9fea2a7384f2116e5b84a9b31f83be7850ce21.ttf
+a919b33197965846f21074b24e30250d67277bce.ttf
d629e7fedc0b350222d7987345fe61613fa3929a.ttf
e207635780b42f898d58654b65098763e340f5c7.ttf
ef86fe710cfea877bbe0dbb6946a1f88d0661031.ttf
diff --git a/test/shaping/fonts/sha1sum/a919b33197965846f21074b24e30250d67277bce.ttf b/test/shaping/fonts/sha1sum/a919b33197965846f21074b24e30250d67277bce.ttf
new file mode 100644
index 0000000..d2f116e
Binary files /dev/null and b/test/shaping/fonts/sha1sum/a919b33197965846f21074b24e30250d67277bce.ttf differ
diff --git a/test/shaping/tests/MANIFEST b/test/shaping/tests/MANIFEST
index 024169d..1b577c7 100644
--- a/test/shaping/tests/MANIFEST
+++ b/test/shaping/tests/MANIFEST
@@ -1,3 +1,4 @@
+arabic-feature-order.tests
context-matching.tests
indic-pref-blocking.tests
mongolian-variation-selector.tests
diff --git a/test/shaping/tests/arabic-feature-order.tests b/test/shaping/tests/arabic-feature-order.tests
new file mode 100644
index 0000000..3e3cf6a
--- /dev/null
+++ b/test/shaping/tests/arabic-feature-order.tests
@@ -0,0 +1,3 @@
+fonts/sha1sum/813c2f8e5512187fd982417a7fb4286728e6f4a8.ttf:U+1820,U+180B:[uni2048.E81A=0+1550]
+fonts/sha1sum/8a9fea2a7384f2116e5b84a9b31f83be7850ce21.ttf:U+1820,U+180B:[uni2048.E81A=0+1550]
+fonts/sha1sum/a919b33197965846f21074b24e30250d67277bce.ttf:U+0644,U+0644,U+0647:[Lellah=0+1503]
commit d21e997035b16e9807dfb29c3605abb93f92f1ee
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Jul 17 15:27:46 2014 -0400
[test] Make record_test understand cmdline args to hb-shape
diff --git a/test/shaping/record-test.sh b/test/shaping/record-test.sh
index 384d87f..81087f7 100755
--- a/test/shaping/record-test.sh
+++ b/test/shaping/record-test.sh
@@ -3,7 +3,10 @@
dir=`mktemp --directory`
hb_shape=$1
-fontfile=$2
+shift
+fontfile=$1
+shift
+hb_shape="$hb_shape $@"
unicodes=`./hb-unicode-decode`
text=`./hb-unicode-encode "$unicodes"`
glyphs=`echo "$text" | $hb_shape "$fontfile"`
commit 7cd33f230441093dbfb1fec48f8c580ee8d9ef71
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Jul 17 14:22:11 2014 -0400
Micro optimization
diff --git a/src/hb-fallback-shape.cc b/src/hb-fallback-shape.cc
index ea54bb8..9d061a9 100644
--- a/src/hb-fallback-shape.cc
+++ b/src/hb-fallback-shape.cc
@@ -105,34 +105,36 @@ _hb_fallback_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
* shaper which many people unfortunately still request.
*/
- bool has_space;
hb_codepoint_t space;
- has_space = font->get_glyph (' ', 0, &space);
+ bool has_space = font->get_glyph (' ', 0, &space);
buffer->clear_positions ();
+ hb_direction_t direction = buffer->props.direction;
+ hb_unicode_funcs_t *unicode = buffer->unicode;
unsigned int count = buffer->len;
-
+ hb_glyph_info_t *info = buffer->info;
+ hb_glyph_position_t *pos = buffer->pos;
for (unsigned int i = 0; i < count; i++)
{
- if (has_space && buffer->unicode->is_default_ignorable (buffer->info[i].codepoint)) {
- buffer->info[i].codepoint = space;
- buffer->pos[i].x_advance = 0;
- buffer->pos[i].y_advance = 0;
+ if (has_space && unicode->is_default_ignorable (info[i].codepoint)) {
+ info[i].codepoint = space;
+ pos[i].x_advance = 0;
+ pos[i].y_advance = 0;
continue;
}
- font->get_glyph (buffer->info[i].codepoint, 0, &buffer->info[i].codepoint);
- font->get_glyph_advance_for_direction (buffer->info[i].codepoint,
- buffer->props.direction,
- &buffer->pos[i].x_advance,
- &buffer->pos[i].y_advance);
- font->subtract_glyph_origin_for_direction (buffer->info[i].codepoint,
- buffer->props.direction,
- &buffer->pos[i].x_offset,
- &buffer->pos[i].y_offset);
+ font->get_glyph (info[i].codepoint, 0, &info[i].codepoint);
+ font->get_glyph_advance_for_direction (info[i].codepoint,
+ direction,
+ &pos[i].x_advance,
+ &pos[i].y_advance);
+ font->subtract_glyph_origin_for_direction (info[i].codepoint,
+ direction,
+ &pos[i].x_offset,
+ &pos[i].y_offset);
}
- if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
+ if (HB_DIRECTION_IS_BACKWARD (direction))
hb_buffer_reverse (buffer);
return true;
diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc
index 5dd60a5..3c59743 100644
--- a/src/hb-ot-shape-complex-arabic.cc
+++ b/src/hb-ot-shape-complex-arabic.cc
@@ -223,6 +223,7 @@ static void
arabic_joining (hb_buffer_t *buffer)
{
unsigned int count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
unsigned int prev = (unsigned int) -1, state = 0;
/* Check pre-context */
@@ -241,19 +242,19 @@ arabic_joining (hb_buffer_t *buffer)
for (unsigned int i = 0; i < count; i++)
{
- unsigned int this_type = get_joining_type (buffer->info[i].codepoint, _hb_glyph_info_get_general_category (&buffer->info[i]));
+ unsigned int this_type = get_joining_type (info[i].codepoint, _hb_glyph_info_get_general_category (&info[i]));
if (unlikely (this_type == JOINING_TYPE_T)) {
- buffer->info[i].arabic_shaping_action() = NONE;
+ info[i].arabic_shaping_action() = NONE;
continue;
}
const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
if (entry->prev_action != NONE && prev != (unsigned int) -1)
- buffer->info[prev].arabic_shaping_action() = entry->prev_action;
+ info[prev].arabic_shaping_action() = entry->prev_action;
- buffer->info[i].arabic_shaping_action() = entry->curr_action;
+ info[i].arabic_shaping_action() = entry->curr_action;
prev = i;
state = entry->next_state;
@@ -269,7 +270,7 @@ arabic_joining (hb_buffer_t *buffer)
const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
if (entry->prev_action != NONE && prev != (unsigned int) -1)
- buffer->info[prev].arabic_shaping_action() = entry->prev_action;
+ info[prev].arabic_shaping_action() = entry->prev_action;
break;
}
}
@@ -299,8 +300,9 @@ setup_masks_arabic (const hb_ot_shape_plan_t *plan,
mongolian_variation_selectors (buffer);
unsigned int count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
- buffer->info[i].mask |= arabic_plan->mask_array[buffer->info[i].arabic_shaping_action()];
+ info[i].mask |= arabic_plan->mask_array[info[i].arabic_shaping_action()];
HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
}
@@ -312,9 +314,10 @@ nuke_joiners (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_buffer_t *buffer)
{
unsigned int count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
- if (_hb_glyph_info_is_zwj (&buffer->info[i]))
- _hb_glyph_info_flip_joiners (&buffer->info[i]);
+ if (_hb_glyph_info_is_zwj (&info[i]))
+ _hb_glyph_info_flip_joiners (&info[i]);
}
static void
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 5bb1f33..33215a3 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -635,8 +635,9 @@ setup_masks_indic (const hb_ot_shape_plan_t *plan HB_UNUSED,
* and setup masks later on in a pause-callback. */
unsigned int count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
- set_indic_properties (buffer->info[i]);
+ set_indic_properties (info[i]);
}
static void
@@ -673,10 +674,12 @@ update_consonant_positions (const hb_ot_shape_plan_t *plan,
{
hb_face_t *face = font->face;
unsigned int count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
- if (buffer->info[i].indic_position() == POS_BASE_C) {
- hb_codepoint_t consonant = buffer->info[i].codepoint;
- buffer->info[i].indic_position() = consonant_position_from_face (indic_plan, consonant, virama, face);
+ if (info[i].indic_position() == POS_BASE_C)
+ {
+ hb_codepoint_t consonant = info[i].codepoint;
+ info[i].indic_position() = consonant_position_from_face (indic_plan, consonant, virama, face);
}
}
}
@@ -1228,8 +1231,10 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
/* Note: This loop is extra overhead, but should not be measurable. */
bool has_broken_syllables = false;
unsigned int count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
- if ((buffer->info[i].syllable() & 0x0F) == broken_cluster) {
+ if ((info[i].syllable() & 0x0F) == broken_cluster)
+ {
has_broken_syllables = true;
break;
}
diff --git a/src/hb-ot-shape-complex-myanmar.cc b/src/hb-ot-shape-complex-myanmar.cc
index 8b2c00c..258ccc4 100644
--- a/src/hb-ot-shape-complex-myanmar.cc
+++ b/src/hb-ot-shape-complex-myanmar.cc
@@ -277,8 +277,9 @@ setup_masks_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
* and setup masks later on in a pause-callback. */
unsigned int count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
- set_myanmar_properties (buffer->info[i]);
+ set_myanmar_properties (info[i]);
}
static void
@@ -451,8 +452,10 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
/* Note: This loop is extra overhead, but should not be measurable. */
bool has_broken_syllables = false;
unsigned int count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
- if ((buffer->info[i].syllable() & 0x0F) == broken_cluster) {
+ if ((info[i].syllable() & 0x0F) == broken_cluster)
+ {
has_broken_syllables = true;
break;
}
diff --git a/src/hb-ot-shape-complex-sea.cc b/src/hb-ot-shape-complex-sea.cc
index a4adb8f..f08b7cc 100644
--- a/src/hb-ot-shape-complex-sea.cc
+++ b/src/hb-ot-shape-complex-sea.cc
@@ -174,8 +174,9 @@ setup_masks_sea (const hb_ot_shape_plan_t *plan HB_UNUSED,
* and setup masks later on in a pause-callback. */
unsigned int count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
- set_sea_properties (buffer->info[i]);
+ set_sea_properties (info[i]);
}
static void
@@ -278,8 +279,10 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
/* Note: This loop is extra overhead, but should not be measurable. */
bool has_broken_syllables = false;
unsigned int count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
- if ((buffer->info[i].syllable() & 0x0F) == broken_cluster) {
+ if ((info[i].syllable() & 0x0F) == broken_cluster)
+ {
has_broken_syllables = true;
break;
}
diff --git a/src/hb-ot-shape-fallback.cc b/src/hb-ot-shape-fallback.cc
index 89eab28..a774f95 100644
--- a/src/hb-ot-shape-fallback.cc
+++ b/src/hb-ot-shape-fallback.cc
@@ -167,11 +167,12 @@ _hb_ot_shape_fallback_position_recategorize_marks (const hb_ot_shape_plan_t *pla
hb_buffer_t *buffer)
{
unsigned int count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
- if (_hb_glyph_info_get_general_category (&buffer->info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) {
- unsigned int combining_class = _hb_glyph_info_get_modified_combining_class (&buffer->info[i]);
- combining_class = recategorize_combining_class (buffer->info[i].codepoint, combining_class);
- _hb_glyph_info_set_modified_combining_class (&buffer->info[i], combining_class);
+ if (_hb_glyph_info_get_general_category (&info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) {
+ unsigned int combining_class = _hb_glyph_info_get_modified_combining_class (&info[i]);
+ combining_class = recategorize_combining_class (info[i].codepoint, combining_class);
+ _hb_glyph_info_set_modified_combining_class (&info[i], combining_class);
}
}
@@ -181,8 +182,9 @@ zero_mark_advances (hb_buffer_t *buffer,
unsigned int start,
unsigned int end)
{
+ hb_glyph_info_t *info = buffer->info;
for (unsigned int i = start; i < end; i++)
- if (_hb_glyph_info_get_general_category (&buffer->info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
+ if (_hb_glyph_info_get_general_category (&info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
{
buffer->pos[i].x_advance = 0;
buffer->pos[i].y_advance = 0;
@@ -327,12 +329,13 @@ position_around_base (const hb_ot_shape_plan_t *plan,
unsigned int last_lig_component = (unsigned int) -1;
unsigned int last_combining_class = 255;
hb_glyph_extents_t cluster_extents = base_extents; /* Initialization is just to shut gcc up. */
+ hb_glyph_info_t *info = buffer->info;
for (unsigned int i = base + 1; i < end; i++)
- if (_hb_glyph_info_get_modified_combining_class (&buffer->info[i]))
+ if (_hb_glyph_info_get_modified_combining_class (&info[i]))
{
if (num_lig_components > 1) {
- unsigned int this_lig_id = _hb_glyph_info_get_lig_id (&buffer->info[i]);
- unsigned int this_lig_component = _hb_glyph_info_get_lig_comp (&buffer->info[i]) - 1;
+ unsigned int this_lig_id = _hb_glyph_info_get_lig_id (&info[i]);
+ unsigned int this_lig_component = _hb_glyph_info_get_lig_comp (&info[i]) - 1;
/* Conditions for attaching to the last component. */
if (!lig_id || lig_id != this_lig_id || this_lig_component >= num_lig_components)
this_lig_component = num_lig_components - 1;
@@ -355,7 +358,7 @@ position_around_base (const hb_ot_shape_plan_t *plan,
}
}
- unsigned int this_combining_class = _hb_glyph_info_get_modified_combining_class (&buffer->info[i]);
+ unsigned int this_combining_class = _hb_glyph_info_get_modified_combining_class (&info[i]);
if (last_combining_class != this_combining_class)
{
last_combining_class = this_combining_class;
@@ -391,13 +394,14 @@ position_cluster (const hb_ot_shape_plan_t *plan,
return;
/* Find the base glyph */
+ hb_glyph_info_t *info = buffer->info;
for (unsigned int i = start; i < end; i++)
- if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[i])))
+ if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i])))
{
/* Find mark glyphs */
unsigned int j;
for (j = i + 1; j < end; j++)
- if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[j])))
+ if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[j])))
break;
position_around_base (plan, font, buffer, i, j);
@@ -432,15 +436,13 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
{
if (!plan->has_kern) return;
- unsigned int count = buffer->len;
-
OT::hb_apply_context_t c (1, font, buffer);
c.set_lookup_mask (plan->kern_mask);
c.set_lookup_props (OT::LookupFlag::IgnoreMarks);
+ unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
hb_glyph_position_t *pos = buffer->pos;
-
for (unsigned int idx = 0; idx < count;)
{
OT::hb_apply_context_t::skipping_forward_iterator_t skippy_iter (&c, idx, 1);
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 736eefd..1f99014 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -227,8 +227,9 @@ static void
hb_set_unicode_props (hb_buffer_t *buffer)
{
unsigned int count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
- _hb_glyph_info_set_unicode_props (&buffer->info[i], buffer->unicode);
+ _hb_glyph_info_set_unicode_props (&info[i], buffer->unicode);
}
static void
@@ -263,8 +264,9 @@ static void
hb_form_clusters (hb_buffer_t *buffer)
{
unsigned int count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 1; i < count; i++)
- if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[i])))
+ if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i])))
buffer->merge_clusters (i - 1, i + 1);
}
@@ -382,8 +384,9 @@ hb_ot_map_glyphs_fast (hb_buffer_t *buffer)
{
/* Normalization process sets up glyph_index(), we just copy it. */
unsigned int count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
- buffer->info[i].codepoint = buffer->info[i].glyph_index();
+ info[i].codepoint = info[i].glyph_index();
}
static inline void
@@ -483,8 +486,9 @@ static inline void
zero_mark_widths_by_unicode (hb_buffer_t *buffer, bool adjust_offsets)
{
unsigned int count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
- if (_hb_glyph_info_get_general_category (&buffer->info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
+ if (_hb_glyph_info_get_general_category (&info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
{
if (adjust_offsets)
adjust_mark_offsets (&buffer->pos[i]);
@@ -496,8 +500,9 @@ static inline void
zero_mark_widths_by_gdef (hb_buffer_t *buffer, bool adjust_offsets)
{
unsigned int count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
- if (_hb_glyph_info_is_mark (&buffer->info[i]))
+ if (_hb_glyph_info_is_mark (&info[i]))
{
if (adjust_offsets)
adjust_mark_offsets (&buffer->pos[i]);
@@ -773,8 +778,9 @@ hb_ot_shape_glyphs_closure (hb_font_t *font,
bool mirror = hb_script_get_horizontal_direction (buffer->props.script) == HB_DIRECTION_RTL;
unsigned int count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
- add_char (font, buffer->unicode, mirror, buffer->info[i].codepoint, glyphs);
+ add_char (font, buffer->unicode, mirror, info[i].codepoint, glyphs);
hb_set_t lookups;
lookups.init ();
commit 164c13d73f67fdddba28e6409d76b4903e8ffab3
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Jul 17 14:16:38 2014 -0400
Another try to fix Mongolian free variation selectors
This reverts bf029281 and fixes it properly. That commit
was not enough as it was only inheriting the shaping_action
for prev_action, but not curr_action.
Micro-test added.
https://code.google.com/p/chromium/issues/detail?id=393896
diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc
index b7aa694..5dd60a5 100644
--- a/src/hb-ot-shape-complex-arabic.cc
+++ b/src/hb-ot-shape-complex-arabic.cc
@@ -225,8 +225,6 @@ arabic_joining (hb_buffer_t *buffer)
unsigned int count = buffer->len;
unsigned int prev = (unsigned int) -1, state = 0;
- HB_BUFFER_ALLOCATE_VAR (buffer, arabic_shaping_action);
-
/* Check pre-context */
if (!(buffer->flags & HB_BUFFER_FLAG_BOT))
for (unsigned int i = 0; i < buffer->context_len[0]; i++)
@@ -253,8 +251,7 @@ arabic_joining (hb_buffer_t *buffer)
const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
if (entry->prev_action != NONE && prev != (unsigned int) -1)
- for (; prev < i; prev++)
- buffer->info[prev].arabic_shaping_action() = entry->prev_action;
+ buffer->info[prev].arabic_shaping_action() = entry->prev_action;
buffer->info[i].arabic_shaping_action() = entry->curr_action;
@@ -275,9 +272,17 @@ arabic_joining (hb_buffer_t *buffer)
buffer->info[prev].arabic_shaping_action() = entry->prev_action;
break;
}
+}
-
- HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
+static void
+mongolian_variation_selectors (hb_buffer_t *buffer)
+{
+ /* Copy arabic_shaping_action() from base to Mongolian variation selectors. */
+ unsigned int count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
+ for (unsigned int i = 1; i < count; i++)
+ if (unlikely (hb_in_range (info[i].codepoint, 0x180Bu, 0x180Du)))
+ info[i].arabic_shaping_action() = info[i - 1].arabic_shaping_action();
}
static void
@@ -285,12 +290,19 @@ setup_masks_arabic (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
hb_font_t *font HB_UNUSED)
{
+ HB_BUFFER_ALLOCATE_VAR (buffer, arabic_shaping_action);
+
const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data;
arabic_joining (buffer);
+ if (plan->props.script == HB_SCRIPT_MONGOLIAN)
+ mongolian_variation_selectors (buffer);
+
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++)
buffer->info[i].mask |= arabic_plan->mask_array[buffer->info[i].arabic_shaping_action()];
+
+ HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
}
diff --git a/src/hb-unicode-private.hh b/src/hb-unicode-private.hh
index 6652015..a2c59da 100644
--- a/src/hb-unicode-private.hh
+++ b/src/hb-unicode-private.hh
@@ -122,8 +122,9 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
static inline hb_bool_t
is_variation_selector (hb_codepoint_t unicode)
{
+ /* U+180B..180D MONGOLIAN FREE VARIATION SELECTORs are handled in the
+ * Arabic shaper. No need to match them here. */
return unlikely (hb_in_ranges (unicode,
- 0x180Bu, 0x180Du, /* MONGOLIAN FREE VARIATION SELECTOR ONE..THREE */
0xFE00u, 0xFE0Fu, /* VARIATION SELECTOR-1..16 */
0xE0100u, 0xE01EFu)); /* VARIATION SELECTOR-17..256 */
}
diff --git a/test/shaping/fonts/sha1sum/MANIFEST b/test/shaping/fonts/sha1sum/MANIFEST
index 427f433..d1ff350 100644
--- a/test/shaping/fonts/sha1sum/MANIFEST
+++ b/test/shaping/fonts/sha1sum/MANIFEST
@@ -3,4 +3,5 @@
4cce528e99f600ed9c25a2b69e32eb94a03b4ae8.ttf
d629e7fedc0b350222d7987345fe61613fa3929a.ttf
e207635780b42f898d58654b65098763e340f5c7.ttf
+ef86fe710cfea877bbe0dbb6946a1f88d0661031.ttf
f499fbc23865022234775c43503bba2e63978fe1.ttf
diff --git a/test/shaping/fonts/sha1sum/ef86fe710cfea877bbe0dbb6946a1f88d0661031.ttf b/test/shaping/fonts/sha1sum/ef86fe710cfea877bbe0dbb6946a1f88d0661031.ttf
new file mode 100644
index 0000000..629c470
Binary files /dev/null and b/test/shaping/fonts/sha1sum/ef86fe710cfea877bbe0dbb6946a1f88d0661031.ttf differ
diff --git a/test/shaping/tests/mongolian-variation-selector.tests b/test/shaping/tests/mongolian-variation-selector.tests
index 043fa18..86a2fd1 100644
--- a/test/shaping/tests/mongolian-variation-selector.tests
+++ b/test/shaping/tests/mongolian-variation-selector.tests
@@ -1 +1,2 @@
fonts/sha1sum/37033cc5cf37bb223d7355153016b6ccece93b28.ttf:U+1826,U+180B,U+1826:[uni1826.E85E_ue.init1=0+599|uni1826.E856_ue.fina=2+750]
+fonts/sha1sum/ef86fe710cfea877bbe0dbb6946a1f88d0661031.ttf:U+1820,U+180B:[uni1820.E821_a.isol1=0+1199]
More information about the HarfBuzz
mailing list