[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