[HarfBuzz] harfbuzz-ng: Branch 'master'

Behdad Esfahbod behdad at kemper.freedesktop.org
Tue Apr 10 14:20:18 PDT 2012


 src/gen-arabic-table.py                 |   32 ++++++++++++++++++++++----------
 src/hb-ot-shape-complex-arabic-table.hh |   28 +++++++++++++++++++---------
 src/hb-ot-shape-complex-arabic.cc       |   31 +++++++++++++++++++++++++++++++
 src/hb-ot-shape-complex-misc.cc         |    4 ++--
 4 files changed, 74 insertions(+), 21 deletions(-)

New commits:
commit 939c010211b063f78874a3b72b032c1ed9a13b87
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Apr 10 17:20:05 2012 -0400

    Implement Arabic fallback shaping mandatory ligatures

diff --git a/src/gen-arabic-table.py b/src/gen-arabic-table.py
index 6549cb4..2d3c881 100755
--- a/src/gen-arabic-table.py
+++ b/src/gen-arabic-table.py
@@ -133,11 +133,7 @@ def print_shaping_table(f):
 	print "#define SHAPING_TABLE_LAST	0x%04X" % max_u
 	print
 
-	print
-	print "static const uint16_t ligature_table[][3] ="
-	print "{"
-
-	ligas = []
+	ligas = {}
 	for pair in ligatures.keys ():
 		for shape in ligatures[pair]:
 			c = ligatures[pair][shape]
@@ -147,11 +143,27 @@ def print_shaping_table(f):
 				liga = (shapes[pair[0]]['medial'], shapes[pair[1]]['final'])
 			else:
 				raise Exception ("Unexpected shape", shape)
-			ligas.append (liga + (c,))
-	ligas.sort ()
-	for liga in ligas:
-		value = ', '.join ("0x%04X" % c for c in liga)
-		print "  {%s}, /* U+%04X %s */" % (value, liga[2], names[liga[2]])
+			if liga[0] not in ligas:
+				ligas[liga[0]] = []
+			ligas[liga[0]].append ((liga[1], c))
+	max_i = max (len (ligas[l]) for l in ligas)
+	print
+	print "static const struct {"
+	print " uint16_t first;"
+	print " struct {"
+	print "   uint16_t second;"
+	print "   uint16_t ligature;"
+	print " } ligatures[%d];" % max_i
+	print "} ligature_table[] ="
+	print "{"
+	keys = ligas.keys ()
+	keys.sort ()
+	for first in keys:
+
+		print "  { 0x%04X, {" % (first)
+		for liga in ligas[first]:
+			print "    { 0x%04X, 0x%04X }, /* %s */" % (liga[0], liga[1], names[liga[1]])
+		print "  }},"
 
 	print "};"
 	print
diff --git a/src/hb-ot-shape-complex-arabic-table.hh b/src/hb-ot-shape-complex-arabic-table.hh
index e0b27f8..df85086 100644
--- a/src/hb-ot-shape-complex-arabic-table.hh
+++ b/src/hb-ot-shape-complex-arabic-table.hh
@@ -914,16 +914,26 @@ static const uint16_t shaping_table[][4] =
 #define SHAPING_TABLE_LAST	0x06D3
 
 
-static const uint16_t ligature_table[][3] =
+static const struct {
+ uint16_t first;
+ struct {
+   uint16_t second;
+   uint16_t ligature;
+ } ligatures[4];
+} ligature_table[] =
 {
-  {0xFEDF, 0xFE82, 0xFEF5}, /* U+FEF5 ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM */
-  {0xFEDF, 0xFE84, 0xFEF7}, /* U+FEF7 ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM */
-  {0xFEDF, 0xFE88, 0xFEF9}, /* U+FEF9 ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM */
-  {0xFEDF, 0xFE8E, 0xFEFB}, /* U+FEFB ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM */
-  {0xFEE0, 0xFE82, 0xFEF6}, /* U+FEF6 ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM */
-  {0xFEE0, 0xFE84, 0xFEF8}, /* U+FEF8 ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM */
-  {0xFEE0, 0xFE88, 0xFEFA}, /* U+FEFA ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM */
-  {0xFEE0, 0xFE8E, 0xFEFC}, /* U+FEFC ARABIC LIGATURE LAM WITH ALEF FINAL FORM */
+  { 0xFEDF, {
+    { 0xFE88, 0xFEF9 }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM */
+    { 0xFE82, 0xFEF5 }, /* ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM */
+    { 0xFE8E, 0xFEFB }, /* ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM */
+    { 0xFE84, 0xFEF7 }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM */
+  }},
+  { 0xFEE0, {
+    { 0xFE88, 0xFEFA }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM */
+    { 0xFE82, 0xFEF6 }, /* ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM */
+    { 0xFE8E, 0xFEFC }, /* ARABIC LIGATURE LAM WITH ALEF FINAL FORM */
+    { 0xFE84, 0xFEF8 }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM */
+  }},
 };
 
 
diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc
index 991f7cf..c44c27c 100644
--- a/src/hb-ot-shape-complex-arabic.cc
+++ b/src/hb-ot-shape-complex-arabic.cc
@@ -87,6 +87,16 @@ static hb_codepoint_t get_arabic_shape (hb_codepoint_t u, unsigned int shape)
   return u;
 }
 
+static uint16_t get_ligature (hb_codepoint_t first, hb_codepoint_t second)
+{
+  if (unlikely (!second)) return 0;
+  for (unsigned i = 0; i < ARRAY_LENGTH (ligature_table); i++)
+    if (ligature_table[i].first == first)
+      for (unsigned j = 0; j < ARRAY_LENGTH (ligature_table[i].ligatures); j++)
+	if (ligature_table[i].ligatures[j].second == second)
+	  return ligature_table[i].ligatures[j].ligature;
+  return 0;
+}
 
 static const hb_tag_t arabic_syriac_features[] =
 {
@@ -198,8 +208,29 @@ static void
 arabic_fallback_shape (hb_buffer_t *buffer)
 {
   unsigned int count = buffer->len;
+
+  /* Shape to presentation forms */
   for (unsigned int i = 0; i < count; i++)
     buffer->info[i].codepoint = get_arabic_shape (buffer->info[i].codepoint, buffer->info[i].arabic_shaping_action());
+
+  /* Mandatory ligatures */
+  buffer->clear_output ();
+  for (buffer->idx = 0; buffer->idx + 1 < count;) {
+    uint16_t ligature = get_ligature (buffer->info[buffer->idx].codepoint,
+				      buffer->info[buffer->idx + 1].codepoint);
+    if (likely (!ligature)) {
+      buffer->next_glyph ();
+      continue;
+    }
+
+    buffer->replace_glyphs (2, 1, &ligature);
+
+    /* Technically speaking we can skip marks and stuff, like the GSUB path does.
+     * But who cares, we're in fallback! */
+  }
+  for (; buffer->idx < count;)
+      buffer->next_glyph ();
+  buffer->swap_buffers ();
 }
 
 void
diff --git a/src/hb-ot-shape-complex-misc.cc b/src/hb-ot-shape-complex-misc.cc
index d893eb3..23a5b52 100644
--- a/src/hb-ot-shape-complex-misc.cc
+++ b/src/hb-ot-shape-complex-misc.cc
@@ -132,7 +132,7 @@ _hb_ot_shape_complex_setup_masks_thai (hb_ot_map_t *map, hb_buffer_t *buffer)
   unsigned int count = buffer->len;
   for (buffer->idx = 0; buffer->idx < count;)
   {
-    if (!IS_SARA_AM (buffer->info[buffer->idx].codepoint)) {
+    if (likely (!IS_SARA_AM (buffer->info[buffer->idx].codepoint))) {
       buffer->next_glyph ();
       continue;
     }
@@ -141,7 +141,7 @@ _hb_ot_shape_complex_setup_masks_thai (hb_ot_map_t *map, hb_buffer_t *buffer)
     uint16_t decomposed[2] = {NIKHAHIT_FROM_SARA_AM (buffer->info[buffer->idx].codepoint),
 			      SARA_AA_FROM_SARA_AM (buffer->info[buffer->idx].codepoint)};
     buffer->replace_glyphs (1, 2, decomposed);
-    if (buffer->in_error)
+    if (unlikely (buffer->in_error))
       return;
 
     /* Ok, let's see... */



More information about the HarfBuzz mailing list