[Indic] Towards multi-cluster syllables and final reordering
authorBehdad Esfahbod <behdad@behdad.org>
Wed, 9 May 2012 15:56:03 +0000 (17:56 +0200)
committerBehdad Esfahbod <behdad@behdad.org>
Wed, 9 May 2012 16:10:20 +0000 (18:10 +0200)
src/hb-ot-shape-complex-arabic.cc
src/hb-ot-shape-complex-indic-machine.rl
src/hb-ot-shape-complex-indic-private.hh
src/hb-ot-shape-complex-indic.cc
src/hb-ot-shape-complex-private.hh

index 746f2d7..ac7457e 100644 (file)
@@ -30,7 +30,7 @@
 
 
 /* buffer var allocations */
-#define arabic_shaping_action() complex_var_temporary_u16() /* arabic shaping action */
+#define arabic_shaping_action() complex_var_temporary_u8() /* arabic shaping action */
 
 
 /*
index 6406c24..907188a 100644 (file)
@@ -59,12 +59,17 @@ z = ZWJ|ZWNJ;
 matra_group = M N? H?;
 syllable_tail = SM? (VD VD?)?;
 
-action found_consonant_syllable { found_consonant_syllable (map, buffer, mask_array, last, p); }
-action found_vowel_syllable { found_vowel_syllable (map, buffer, mask_array, last, p); }
-action found_standalone_cluster { found_standalone_cluster (map, buffer, mask_array, last, p); }
-action found_non_indic { found_non_indic (map, buffer, mask_array, last, p); }
-
-action next_syllable { buffer->merge_clusters (last, p); last = p; }
+action found_consonant_syllable { initial_reordering_consonant_syllable (map, buffer, mask_array, last, p); }
+action found_vowel_syllable { initial_reordering_vowel_syllable (map, buffer, mask_array, last, p); }
+action found_standalone_cluster { initial_reordering_standalone_cluster (map, buffer, mask_array, last, p); }
+action found_non_indic { initial_reordering_non_indic (map, buffer, mask_array, last, p); }
+
+action next_syllable {
+  for (unsigned int i = last; i < p; i++)
+    info[i].indic_syllable() = syllable_serial;
+  last = p;
+  syllable_serial++;
+}
 
 consonant_syllable =   (c.N? (H.z?|z.H))* c.N? A? (H.z? | matra_group*)? syllable_tail %(found_consonant_syllable);
 vowel_syllable =       (Ra H)? V N? (z?.H.c | ZWJ.c)? matra_group* syllable_tail %(found_vowel_syllable);
@@ -88,15 +93,17 @@ find_syllables (const hb_ot_map_t *map, hb_buffer_t *buffer, hb_mask_t *mask_arr
 {
   unsigned int p, pe, eof;
   int cs;
+  hb_glyph_info_t *info = buffer->info;
   %%{
     write init;
-    getkey buffer->info[p].indic_category();
+    getkey info[p].indic_category();
   }%%
 
   p = 0;
   pe = eof = buffer->len;
 
   unsigned int last = 0;
+  uint8_t syllable_serial = 0;
   %%{
     write exec;
   }%%
index babb1fc..d65d3ac 100644 (file)
@@ -36,6 +36,7 @@
 /* buffer var allocations */
 #define indic_category() complex_var_persistent_u8_0() /* indic_category_t */
 #define indic_position() complex_var_persistent_u8_1() /* indic_matra_category_t */
+#define indic_syllable() complex_var_persistent_u8_2() /* serial */
 
 #define INDIC_TABLE_ELEMENT_TYPE uint8_t
 
index 86ed307..9868b5e 100644 (file)
@@ -163,6 +163,7 @@ _hb_ot_shape_complex_setup_masks_indic (hb_ot_map_t *map, hb_buffer_t *buffer, h
 {
   HB_BUFFER_ALLOCATE_VAR (buffer, indic_category);
   HB_BUFFER_ALLOCATE_VAR (buffer, indic_position);
+  HB_BUFFER_ALLOCATE_VAR (buffer, indic_syllable);
 
   /* We cannot setup masks here.  We save information about characters
    * and setup masks later on in a pause-callback. */
@@ -205,8 +206,8 @@ compare_indic_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
 }
 
 static void
-found_consonant_syllable (const hb_ot_map_t *map, hb_buffer_t *buffer, hb_mask_t *mask_array,
-                         unsigned int start, unsigned int end)
+initial_reordering_consonant_syllable (const hb_ot_map_t *map, hb_buffer_t *buffer, hb_mask_t *mask_array,
+                                      unsigned int start, unsigned int end)
 {
   unsigned int i;
   hb_glyph_info_t *info = buffer->info;
@@ -410,8 +411,8 @@ found_consonant_syllable (const hb_ot_map_t *map, hb_buffer_t *buffer, hb_mask_t
 
 
 static void
-found_vowel_syllable (const hb_ot_map_t *map, hb_buffer_t *buffer, hb_mask_t *mask_array,
-                     unsigned int start, unsigned int end)
+initial_reordering_vowel_syllable (const hb_ot_map_t *map, hb_buffer_t *buffer, hb_mask_t *mask_array,
+                                  unsigned int start, unsigned int end)
 {
   /* TODO
    * Not clear to me how this should work.  Do the matras move to before the
@@ -420,17 +421,17 @@ found_vowel_syllable (const hb_ot_map_t *map, hb_buffer_t *buffer, hb_mask_t *ma
 }
 
 static void
-found_standalone_cluster (const hb_ot_map_t *map, hb_buffer_t *buffer, hb_mask_t *mask_array,
-                         unsigned int start, unsigned int end)
+initial_reordering_standalone_cluster (const hb_ot_map_t *map, hb_buffer_t *buffer, hb_mask_t *mask_array,
+                                      unsigned int start, unsigned int end)
 {
   /* TODO
    * Easiest thing to do here is to convert the NBSP to consonant and
-   * call found_consonant_syllable.
+   * call initial_reordering_consonant_syllable.
    */
 }
 
 static void
-found_non_indic (const hb_ot_map_t *map, hb_buffer_t *buffer, hb_mask_t *mask_array,
+initial_reordering_non_indic (const hb_ot_map_t *map, hb_buffer_t *buffer, hb_mask_t *mask_array,
                 unsigned int start, unsigned int end)
 {
   /* Nothing to do right now.  If we ever switch to using the output
@@ -454,10 +455,8 @@ initial_reordering (const hb_ot_map_t *map,
 }
 
 static void
-final_reordering (const hb_ot_map_t *map,
-                 hb_face_t *face,
-                 hb_buffer_t *buffer,
-                 void *user_data HB_UNUSED)
+final_reordering_syllable (hb_buffer_t *buffer,
+                          unsigned int start, unsigned int end)
 {
   /* 4. Final reordering:
    *
@@ -533,9 +532,31 @@ final_reordering (const hb_ot_map_t *map,
    */
 
   /* TODO */
+  buffer->merge_clusters (start, end);
+}
 
 
+static void
+final_reordering (const hb_ot_map_t *map,
+                 hb_face_t *face,
+                 hb_buffer_t *buffer,
+                 void *user_data HB_UNUSED)
+{
+  unsigned int count = buffer->len;
+  if (!count) return;
+
+  hb_glyph_info_t *info = buffer->info;
+  unsigned int last = 0;
+  unsigned int last_syllable = info[0].indic_syllable();
+  for (unsigned int i = 1; i < count; i++)
+    if (last_syllable != info[i].indic_syllable()) {
+      final_reordering_syllable (buffer, last, i);
+      last = i;
+      last_syllable = info[last].indic_syllable();
+    }
+  final_reordering_syllable (buffer, last, count);
 
+  HB_BUFFER_DEALLOCATE_VAR (buffer, indic_syllable);
   HB_BUFFER_DEALLOCATE_VAR (buffer, indic_category);
   HB_BUFFER_DEALLOCATE_VAR (buffer, indic_position);
 }
index 3f99781..a4bc2f8 100644 (file)
 /* buffer var allocations, used by complex shapers */
 #define complex_var_persistent_u8_0()  var2.u8[0]
 #define complex_var_persistent_u8_1()  var2.u8[1]
+#define complex_var_persistent_u8_2()  var2.u8[2]
 #define complex_var_persistent_u16()   var2.u16[0]
-#define complex_var_temporary_u8_0()   var2.u8[2]
-#define complex_var_temporary_u8_1()   var2.u8[3]
-#define complex_var_temporary_u16()    var2.u16[1]
+#define complex_var_temporary_u8()     var2.u8[3]
 
 
 #define HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS \