[HarfBuzz] harfbuzz-ng: Branch 'master' - 9 commits
Behdad Esfahbod
behdad at kemper.freedesktop.org
Sat Jul 30 18:21:36 PDT 2011
src/hb-ot-layout.cc | 20 +++++++--
src/hb-ot-layout.h | 3 -
src/hb-ot-map-private.hh | 4 +
src/hb-ot-map.cc | 2
src/hb-ot-shape-complex-indic.cc | 85 +++++++++++++++++++++++++++++++++------
test/test-shape-complex.c | 29 ++++++-------
6 files changed, 111 insertions(+), 32 deletions(-)
New commits:
commit 07cedd81f48907b2e372cd2e963716bbded9ce29
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Sat Jul 30 21:16:51 2011 -0400
Minor
diff --git a/test/test-shape-complex.c b/test/test-shape-complex.c
index 6707acd..1963b5e 100644
--- a/test/test-shape-complex.c
+++ b/test/test-shape-complex.c
@@ -1030,6 +1030,7 @@ test_shape_complex (ft_fixture_t *f, gconstpointer user_data)
unsigned int i, len, expected_len;
hb_glyph_info_t *glyphs;
hb_bool_t fail;
+ GString *str;
g_assert (f->font);
@@ -1054,17 +1055,17 @@ test_shape_complex (ft_fixture_t *f, gconstpointer user_data)
break;
}
- if (fail) {
- GString *str = g_string_new ("");
- for (i = 0; i < len; i++)
- g_string_append_printf (str, " %4d", glyphs[i].codepoint);
- g_test_message ("Received glyphs: %s", str->str);
- g_string_truncate (str, 0);
- for (i = 0; i < expected_len; i++)
- g_string_append_printf (str, " %4d", data->glyphs[i]);
- g_test_message ("Expected glyphs: %s", str->str);
- g_string_free (str, TRUE);
+ str = g_string_new ("");
+ for (i = 0; i < len; i++)
+ g_string_append_printf (str, " %4d", glyphs[i].codepoint);
+ g_test_message ("Received glyphs: %s", str->str);
+ g_string_truncate (str, 0);
+ for (i = 0; i < expected_len; i++)
+ g_string_append_printf (str, " %4d", data->glyphs[i]);
+ g_test_message ("Expected glyphs: %s", str->str);
+ g_string_free (str, TRUE);
+ if (fail) {
g_test_message ("FAIL");
/* The glib test framework is useless, lets not fail for now,
* we can grep for FAIL/PASS and count manually. Sigh... */
commit ba7e85c104e68b4685c1b3b5c9a260fe0f6879df
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Sat Jul 30 21:11:53 2011 -0400
Cosmetic
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index cc51b9c..abfc633 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -433,6 +433,7 @@ found_consonant_syllable (const hb_ot_map_t *map, hb_buffer_t *buffer, hb_mask_t
i--;
/* -> until a consonant is found */
if (info[i].indic_category() == OT_C)
+ //if ((FLAG (info[i].indic_category()) & (FLAG (OT_C) | FLAG (OT_Ra))))
{
/* -> that does not have a below-base or post-base form
* (post-base forms have to follow below-base forms), */
commit f5bc2725cb892264ba223e0a49f7fd2c622a0730
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Sat Jul 30 21:08:10 2011 -0400
[Indic] For old-style Indic tables, move Halant around
In old-style Indic OT standards, the post-base Halants are moved after
their base. Emulate that by moving first post-base Halant to
post-last-consonant.
Brings test-shape-complex failures down from 88 to 54. Getting there!
diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh
index 2327e04..5e6aca3 100644
--- a/src/hb-ot-map-private.hh
+++ b/src/hb-ot-map-private.hh
@@ -60,6 +60,9 @@ struct hb_ot_map_t
return map ? map->_1_mask : 0;
}
+ inline hb_tag_t get_chosen_script (unsigned int table_index) const
+ { return chosen_script[table_index]; }
+
inline void substitute (hb_face_t *face, hb_buffer_t *buffer) const
{ apply (0, (hb_ot_map_t::apply_lookup_func_t) hb_ot_layout_substitute_lookup, face, buffer); }
inline void position (hb_font_t *font, hb_buffer_t *buffer) const
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index d51b508..cc51b9c 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -506,6 +506,26 @@ found_consonant_syllable (const hb_ot_map_t *map, hb_buffer_t *buffer, hb_mask_t
info[start].mask = mask_array[RPHF];
}
+ /* For old-style Indic script tags, move the first post-base Halant after
+ * last consonant. */
+ if ((map->get_chosen_script (0) & 0x000000FF) != '2') {
+ /* We should only do this for Indic scripts which have a version two I guess. */
+ for (i = base + 1; i < end; i++)
+ if (info[i].indic_category() == OT_H) {
+ unsigned int j;
+ for (j = end - 1; j > i; j--)
+ if ((FLAG (info[j].indic_category()) & (FLAG (OT_C) | FLAG (OT_Ra))))
+ break;
+ if (j > i) {
+ /* Move Halant to after last consonant. */
+ hb_glyph_info_t t = info[i];
+ memmove (&info[i], &info[i + 1], (j - i) * sizeof (info[0]));
+ info[j] = t;
+ }
+ break;
+ }
+ }
+
/* Attach ZWJ, ZWNJ, nukta, and halant to previous char to move with them. */
for (i = start + 1; i < end; i++)
if ((FLAG (info[i].indic_category()) &
commit c47a31fb4793b825f4be57e9cb1b10db352b9512
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Sat Jul 30 20:57:01 2011 -0400
[OT] Save chosen script tag
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index 5e2d6ac..e7a1f98 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -264,27 +264,39 @@ hb_bool_t
hb_ot_layout_table_choose_script (hb_face_t *face,
hb_tag_t table_tag,
const hb_tag_t *script_tags,
- unsigned int *script_index)
+ unsigned int *script_index,
+ hb_tag_t *chosen_script)
{
ASSERT_STATIC (Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX);
const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
while (*script_tags)
{
- if (g.find_script_index (*script_tags, script_index))
+ if (g.find_script_index (*script_tags, script_index)) {
+ if (chosen_script)
+ *chosen_script = *script_tags;
return TRUE;
+ }
script_tags++;
}
/* try finding 'DFLT' */
- if (g.find_script_index (HB_OT_TAG_DEFAULT_SCRIPT, script_index))
+ if (g.find_script_index (HB_OT_TAG_DEFAULT_SCRIPT, script_index)) {
+ if (chosen_script)
+ *chosen_script = HB_OT_TAG_DEFAULT_SCRIPT;
return FALSE;
+ }
/* try with 'dflt'; MS site has had typos and many fonts use it now :( */
- if (g.find_script_index (HB_OT_TAG_DEFAULT_LANGUAGE, script_index))
+ if (g.find_script_index (HB_OT_TAG_DEFAULT_LANGUAGE, script_index)) {
+ if (chosen_script)
+ *chosen_script = HB_OT_TAG_DEFAULT_LANGUAGE;
return FALSE;
+ }
if (script_index) *script_index = HB_OT_LAYOUT_NO_SCRIPT_INDEX;
+ if (chosen_script)
+ *chosen_script = HB_OT_LAYOUT_NO_SCRIPT_INDEX;
return FALSE;
}
diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h
index 6320437..447e35d 100644
--- a/src/hb-ot-layout.h
+++ b/src/hb-ot-layout.h
@@ -92,7 +92,8 @@ hb_bool_t
hb_ot_layout_table_choose_script (hb_face_t *face,
hb_tag_t table_tag,
const hb_tag_t *script_tags,
- unsigned int *script_index);
+ unsigned int *script_index,
+ hb_tag_t *chosen_script);
unsigned int
hb_ot_layout_table_get_feature_tags (hb_face_t *face,
diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh
index 84b4ccf..2327e04 100644
--- a/src/hb-ot-map-private.hh
+++ b/src/hb-ot-map-private.hh
@@ -123,6 +123,7 @@ struct hb_ot_map_t
hb_mask_t global_mask;
+ hb_tag_t chosen_script[2];
hb_prealloced_array_t<feature_map_t, 8> features;
hb_prealloced_array_t<lookup_map_t, 32> lookups[2]; /* GSUB/GPOS */
hb_prealloced_array_t<pause_map_t, 1> pauses[2]; /* GSUB/GPOS */
diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc
index 67035ba..ad1290f 100644
--- a/src/hb-ot-map.cc
+++ b/src/hb-ot-map.cc
@@ -134,7 +134,7 @@ hb_ot_map_builder_t::compile (hb_face_t *face,
unsigned int script_index[2], language_index[2];
for (unsigned int table_index = 0; table_index < 2; table_index++) {
hb_tag_t table_tag = table_tags[table_index];
- hb_ot_layout_table_choose_script (face, table_tag, script_tags, &script_index[table_index]);
+ hb_ot_layout_table_choose_script (face, table_tag, script_tags, &script_index[table_index], &m.chosen_script[table_index]);
hb_ot_layout_script_find_language (face, table_tag, script_index[table_index], language_tag, &language_index[table_index]);
}
commit 3a9b14dfdfc278b432890e1537672a4ca141a3b0
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Sat Jul 30 20:23:55 2011 -0400
Minor
diff --git a/test/test-shape-complex.c b/test/test-shape-complex.c
index bbb47df..6707acd 100644
--- a/test/test-shape-complex.c
+++ b/test/test-shape-complex.c
@@ -1056,13 +1056,13 @@ test_shape_complex (ft_fixture_t *f, gconstpointer user_data)
if (fail) {
GString *str = g_string_new ("");
- for (i = 0; i < expected_len; i++)
- g_string_append_printf (str, " %4d", data->glyphs[i]);
- g_test_message ("Expected glyphs: %s", str->str);
- g_string_truncate (str, 0);
for (i = 0; i < len; i++)
g_string_append_printf (str, " %4d", glyphs[i].codepoint);
g_test_message ("Received glyphs: %s", str->str);
+ g_string_truncate (str, 0);
+ for (i = 0; i < expected_len; i++)
+ g_string_append_printf (str, " %4d", data->glyphs[i]);
+ g_test_message ("Expected glyphs: %s", str->str);
g_string_free (str, TRUE);
g_test_message ("FAIL");
commit 8613193bbf28fe8951c900b68c4418a6fb929626
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Sat Jul 30 20:21:40 2011 -0400
[test] Fix problem with N'ko test direction
Old HarfBuzz test suite always shaped as left-to-right and hence had wrong
0x14db, direction expected glyphstring for N'ko. Doh!
Failures down from 92 to 88.
diff --git a/test/test-shape-complex.c b/test/test-shape-complex.c
index 6e22fa5..bbb47df 100644
--- a/test/test-shape-complex.c
+++ b/test/test-shape-complex.c
@@ -956,19 +956,19 @@ static const test_set_t tests_nko = {
},
{ "",
{ 0x7ca, 0x7ca, 0 },
- { 0x14db, 0x14d9, 0 }
+ { 0x14d9, 0x14db, 0 }
},
{ "",
{ 0x7ca, 0x7fa, 0x7ca, 0 },
- { 0x14db, 0x5ec, 0x14d9, 0 }
+ { 0x14d9, 0x5ec, 0x14db, 0 }
},
{ "",
{ 0x7ca, 0x7f3, 0x7ca, 0 },
- { 0x14db, 0x5e7, 0x14d9, 0 }
+ { 0x14d9, 0x5e7, 0x14db, 0 }
},
{ "",
{ 0x7ca, 0x7f3, 0x7fa, 0x7ca, 0 },
- { 0x14db, 0x5e7, 0x5ec, 0x14d9, 0 }
+ { 0x14d9, 0x5ec, 0x5e7, 0x14db, 0 }
},
{{0}}
}
commit fd06bf56110e73826b3d5c73ac964e2609450d46
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Sat Jul 30 20:14:44 2011 -0400
[Indic] Handle initial Ra+Halant in scripts that support Reph
Brings test-shape-complex failures down from 104 to 92. Way to go!
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index f054a07..d51b508 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -496,6 +496,16 @@ found_consonant_syllable (const hb_ot_map_t *map, hb_buffer_t *buffer, hb_mask_t
info[i].indic_position() = POS_PRE;
info[base].indic_position() = POS_BASE;
+
+ /* Handle beginning Ra */
+ if (start + 2 <= end &&
+ info[start].indic_category() == OT_Ra &&
+ info[start + 1].indic_category() == OT_H)
+ {
+ info[start].indic_position() = POS_POST;
+ info[start].mask = mask_array[RPHF];
+ }
+
/* Attach ZWJ, ZWNJ, nukta, and halant to previous char to move with them. */
for (i = start + 1; i < end; i++)
if ((FLAG (info[i].indic_category()) &
commit ee58f3bc75d2d071a71b94063bf12205a5871acb
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Sat Jul 30 19:15:53 2011 -0400
Minor
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 4376e7f..f054a07 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -406,6 +406,7 @@ found_consonant_syllable (const hb_ot_map_t *map, hb_buffer_t *buffer, hb_mask_t
unsigned int start, unsigned int end)
{
unsigned int i;
+ hb_glyph_info_t *info = buffer->info;
/* Comments from:
* https://www.microsoft.com/typography/otfntdev/devanot/shaping.aspx */
@@ -431,12 +432,12 @@ found_consonant_syllable (const hb_ot_map_t *map, hb_buffer_t *buffer, hb_mask_t
do {
i--;
/* -> until a consonant is found */
- if (buffer->info[i].indic_category() == OT_C)
+ if (info[i].indic_category() == OT_C)
{
/* -> that does not have a below-base or post-base form
* (post-base forms have to follow below-base forms), */
- if (buffer->info[i].indic_position() != POS_BELOW &&
- buffer->info[i].indic_position() != POS_POST)
+ if (info[i].indic_position() != POS_BELOW &&
+ info[i].indic_position() != POS_POST)
{
base = i;
break;
@@ -492,32 +493,32 @@ found_consonant_syllable (const hb_ot_map_t *map, hb_buffer_t *buffer, hb_mask_t
/* Reorder characters */
for (i = start; i < base; i++)
- buffer->info[i].indic_position() = POS_PRE;
- buffer->info[base].indic_position() = POS_BASE;
+ info[i].indic_position() = POS_PRE;
+ info[base].indic_position() = POS_BASE;
/* Attach ZWJ, ZWNJ, nukta, and halant to previous char to move with them. */
for (i = start + 1; i < end; i++)
- if ((FLAG (buffer->info[i].indic_category()) &
+ if ((FLAG (info[i].indic_category()) &
(FLAG (OT_ZWNJ) | FLAG (OT_ZWJ) | FLAG (OT_N) | FLAG (OT_H))))
- buffer->info[i].indic_position() = buffer->info[i - 1].indic_position();
+ info[i].indic_position() = info[i - 1].indic_position();
/* We do bubble-sort, skip malicious clusters attempts */
if (end - start > 20)
return;
/* Sit tight, rock 'n roll! */
- hb_bubble_sort (buffer->info + start, end - start, compare_indic_order);
+ hb_bubble_sort (info + start, end - start, compare_indic_order);
/* Setup masks now */
/* Pre-base */
for (i = start; i < base; i++)
- buffer->info[i].mask |= mask_array[HALF] | mask_array[AKHN];
+ info[i].mask |= mask_array[HALF] | mask_array[AKHN];
/* Base */
- buffer->info[base].mask |= mask_array[AKHN];
+ info[base].mask |= mask_array[AKHN];
/* Post-base */
for (i = base + 1; i < end; i++)
- buffer->info[i].mask |= mask_array[BLWF] | mask_array[PSTF];
+ info[i].mask |= mask_array[BLWF] | mask_array[PSTF];
}
commit 352372ae5ea0998e40cf9fe43c22b6b610a5764e
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Sat Jul 30 19:04:02 2011 -0400
[Indic] Categorize Ra in scripts that have Reph
Is the categorization correct? I don't know.
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 95f3f1f..4376e7f 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -234,6 +234,23 @@ static const struct consonant_position_t {
{0x0D35, POS_POST},
};
+/* XXX
+ * This is a hack for now. We should move this data into the main Indic table.
+ */
+static const hb_codepoint_t ra_chars[] = {
+ 0x0930, /* Devanagari */
+ 0x09B0, /* Bengali */
+ 0x09F0, /* Bengali */
+ 0x09F1, /* Bengali */
+//0x0A30, /* Gurmukhi */
+ 0x0AB0, /* Gujarati */
+ 0x0B30, /* Oriya */
+//0x0BB0, /* Tamil */
+//0x0C30, /* Telugu */
+ 0x0CB0, /* Kannada */
+//0x0D30, /* Malayalam */
+};
+
static int
compare_codepoint (const void *pa, const void *pb)
{
@@ -256,6 +273,15 @@ consonant_position (hb_codepoint_t u)
return record ? record->position : POS_BASE;
}
+static bool
+is_ra (hb_codepoint_t u)
+{
+ return !!bsearch (&u, ra_chars,
+ ARRAY_LENGTH (ra_chars),
+ sizeof (ra_chars[0]),
+ compare_codepoint);
+}
+
static const struct {
hb_tag_t tag;
@@ -358,8 +384,11 @@ _hb_ot_shape_complex_setup_masks_indic (hb_ot_map_t *map, hb_buffer_t *buffer)
buffer->info[i].indic_category() = type & 0x0F;
buffer->info[i].indic_position() = type >> 4;
- if (buffer->info[i].indic_category() == OT_C)
+ if (buffer->info[i].indic_category() == OT_C) {
buffer->info[i].indic_position() = consonant_position (buffer->info[i].codepoint);
+ if (is_ra (buffer->info[i].codepoint))
+ buffer->info[i].indic_category() = OT_Ra;
+ }
}
}
More information about the HarfBuzz
mailing list