Implement 'rand'
authorDavid Corbett <corbett.dav@husky.neu.edu>
Thu, 25 Jan 2018 19:22:03 +0000 (14:22 -0500)
committerBehdad Esfahbod <behdad@behdad.org>
Tue, 11 Sep 2018 08:47:59 +0000 (10:47 +0200)
src/hb-ot-layout-gsub-table.hh
src/hb-ot-layout-gsubgpos.hh
src/hb-ot-layout.cc
src/hb-ot-map.cc
src/hb-ot-map.hh
src/hb-ot-shape.cc

index 76a0ea6..db24a28 100644 (file)
@@ -534,16 +534,21 @@ struct AlternateSet
 
     if (unlikely (!count)) return_trace (false);
 
-    hb_mask_t glyph_mask = c->buffer->cur().mask;
-    hb_mask_t lookup_mask = c->lookup_mask;
+    if (c->random) {
+      c->random_state = (0x5DEECE66Dull * c->random_state + 11) & (((uint64_t) 1 << 48) - 1);
+      c->replace_glyph (alternates[(c->random_state >> 32) % count]);
+    } else {
+      hb_mask_t glyph_mask = c->buffer->cur().mask;
+      hb_mask_t lookup_mask = c->lookup_mask;
 
-    /* Note: This breaks badly if two features enabled this lookup together. */
-    unsigned int shift = hb_ctz (lookup_mask);
-    unsigned int alt_index = ((lookup_mask & glyph_mask) >> shift);
+      /* Note: This breaks badly if two features enabled this lookup together. */
+      unsigned int shift = hb_ctz (lookup_mask);
+      unsigned int alt_index = ((lookup_mask & glyph_mask) >> shift);
 
-    if (unlikely (alt_index > count || alt_index == 0)) return_trace (false);
+      if (unlikely (alt_index > count || alt_index == 0)) return_trace (false);
 
-    c->replace_glyph (alternates[alt_index - 1]);
+      c->replace_glyph (alternates[alt_index - 1]);
+    }
 
     return_trace (true);
   }
index 719a505..113433d 100644 (file)
@@ -480,6 +480,8 @@ struct hb_ot_apply_context_t :
 
   bool auto_zwnj;
   bool auto_zwj;
+  bool random;
+  uint64_t random_state;
   bool has_glyph_classes;
 
 
@@ -500,11 +502,17 @@ struct hb_ot_apply_context_t :
                        debug_depth (0),
                        auto_zwnj (true),
                        auto_zwj (true),
+                       random (false),
+                       random_state (0),
                        has_glyph_classes (gdef.has_glyph_classes ()) {}
 
   inline void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; }
   inline void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; }
   inline void set_auto_zwnj (bool auto_zwnj_) { auto_zwnj = auto_zwnj_; }
+  inline void set_random_state (uint64_t random_state_) {
+    random = true;
+    random_state = random_state_;
+  }
   inline void set_recurse_func (recurse_func_t func) { recurse_func = func; }
   inline void set_lookup_index (unsigned int lookup_index_) { lookup_index = lookup_index_; }
   inline void set_lookup_props (unsigned int lookup_props_)
index a1220f4..b31dbbc 100644 (file)
@@ -1268,6 +1268,14 @@ inline void hb_ot_map_t::apply (const Proxy &proxy,
       c.set_lookup_mask (lookups[table_index][i].mask);
       c.set_auto_zwj (lookups[table_index][i].auto_zwj);
       c.set_auto_zwnj (lookups[table_index][i].auto_zwnj);
+      if (lookups[table_index][i].random)
+      {
+       uint64_t random_state = 1;
+       for (unsigned int j = 0; j < buffer->len; j++)
+         random_state = 31 * random_state + buffer->info[j].codepoint;
+       c.set_random_state (random_state);
+       buffer->unsafe_to_break_all ();
+      }
       apply_string<Proxy> (&c,
                           proxy.table.get_lookup (lookup_index),
                           proxy.accels[lookup_index]);
index 29f52dc..fb320e2 100644 (file)
@@ -95,7 +95,8 @@ hb_ot_map_builder_t::add_lookups (hb_ot_map_t  &m,
                                  unsigned int  variations_index,
                                  hb_mask_t     mask,
                                  bool          auto_zwnj,
-                                 bool          auto_zwj)
+                                 bool          auto_zwj,
+                                 bool          random)
 {
   unsigned int lookup_indices[32];
   unsigned int offset, len;
@@ -122,6 +123,7 @@ hb_ot_map_builder_t::add_lookups (hb_ot_map_t  &m,
       lookup->index = lookup_indices[i];
       lookup->auto_zwnj = auto_zwnj;
       lookup->auto_zwj = auto_zwj;
+      lookup->random = random;
     }
 
     offset += len;
@@ -301,7 +303,8 @@ hb_ot_map_builder_t::compile (hb_ot_map_t  &m,
                       variations_index,
                       m.features[i].mask,
                       m.features[i].auto_zwnj,
-                      m.features[i].auto_zwj);
+                      m.features[i].auto_zwj,
+                      m.features[i].tag == HB_TAG ('r','a','n','d'));
 
       /* Sort lookups and merge duplicates */
       if (last_num_lookups < m.lookups[table_index].len)
index 32a9e7e..2518a49 100644 (file)
@@ -61,6 +61,7 @@ struct hb_ot_map_t
     unsigned short index;
     unsigned short auto_zwnj : 1;
     unsigned short auto_zwj : 1;
+    unsigned short random : 1;
     hb_mask_t mask;
 
     static int cmp (const void *pa, const void *pb)
@@ -206,7 +207,8 @@ struct hb_ot_map_builder_t
                                unsigned int  variations_index,
                                hb_mask_t     mask,
                                bool          auto_zwnj = true,
-                               bool          auto_zwj = true);
+                               bool          auto_zwj = true,
+                               bool          random = false);
 
   struct feature_info_t {
     hb_tag_t tag;
index 63102f6..f5aeb0d 100644 (file)
@@ -49,6 +49,7 @@ static hb_tag_t common_features[] = {
   HB_TAG('m','a','r','k'),
   HB_TAG('m','k','m','k'),
   HB_TAG('r','l','i','g'),
+  HB_TAG('r','a','n','d'),
 };