[HarfBuzz] harfbuzz: Branch 'master' - 10 commits

Behdad Esfahbod behdad at kemper.freedesktop.org
Wed Oct 3 18:19:56 UTC 2018


 azure-pipelines.yml              |   10 ++++
 src/Makefile.sources             |    1 
 src/hb-buffer.cc                 |   44 -------------------
 src/hb-buffer.hh                 |   52 +++++++++++++++++++----
 src/hb-ot-layout.hh              |   88 +++++++++++++++++++--------------------
 src/hb-ot-shape-complex-indic.cc |   25 +++++++----
 src/hb-ot-shape-complex-thai.cc  |    6 +-
 src/hb-ot-shape.cc               |   27 +++++++++++
 src/hb-unicode.hh                |    5 --
 test/api/hb-subset-test.h        |   13 +++--
 test/api/test-multithread.c      |   41 +++++++++++-------
 test/fuzzing/main.cc             |    6 ++
 12 files changed, 185 insertions(+), 133 deletions(-)

New commits:
commit 06922acbc4558699e43a4ed98ffb21f1e84abfc6
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Oct 3 20:19:17 2018 +0200

    Fix distcheck

diff --git a/src/Makefile.sources b/src/Makefile.sources
index 69ab155a..8b70381b 100644
--- a/src/Makefile.sources
+++ b/src/Makefile.sources
@@ -53,6 +53,7 @@ HB_BASE_sources = \
 	hb-static.cc \
 	hb-string-array.hh \
 	hb-unicode.hh \
+	hb-unicode-emoji-table.hh \
 	hb-unicode.cc \
 	hb-vector.hh \
 	hb-utf.hh \
commit 4eea2e279b019ac627b2b9e2234a194957971022
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Oct 3 20:16:03 2018 +0200

    [thai] Set continuation on decomposed nikhahit

diff --git a/src/hb-ot-shape-complex-thai.cc b/src/hb-ot-shape-complex-thai.cc
index a002c7d1..b687fe61 100644
--- a/src/hb-ot-shape-complex-thai.cc
+++ b/src/hb-ot-shape-complex-thai.cc
@@ -324,9 +324,9 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan,
     }
 
     /* Is SARA AM. Decompose and reorder. */
-    hb_codepoint_t decomposed[2] = {hb_codepoint_t (NIKHAHIT_FROM_SARA_AM (u)),
-				    hb_codepoint_t (SARA_AA_FROM_SARA_AM (u))};
-    buffer->replace_glyphs (1, 2, decomposed);
+    hb_glyph_info_t &nikhahit = buffer->output_glyph (NIKHAHIT_FROM_SARA_AM (u));
+    _hb_glyph_info_set_continuation (&nikhahit);
+    buffer->replace_glyph (SARA_AA_FROM_SARA_AM (u));
     if (unlikely (!buffer->successful))
       return;
 
commit 8edc91022c3943fb306cee26ed6eb85381b5ea76
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Oct 3 20:13:20 2018 +0200

    [indic] Reset continuation on inserted dottedcircle

diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index e92c9ed0..f1ae303a 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -334,7 +334,9 @@ data_destroy_indic (void *data)
 static void
 _output_with_dotted_circle (hb_buffer_t *buffer)
 {
-  buffer->output_glyph (0x25CCu);
+  hb_glyph_info_t &dottedcircle = buffer->output_glyph (0x25CCu);
+  _hb_glyph_info_reset_continuation (&dottedcircle);
+
   buffer->next_glyph ();
 }
 
commit 2a6f15213ec30e5eb07465dd9dc81c2c386cb1e0
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Oct 3 20:09:14 2018 +0200

    [buffer] Inline some more

diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index c9824ec3..b93b243c 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -369,37 +369,6 @@ hb_buffer_t::replace_glyphs (unsigned int num_in,
   out_len += num_out;
 }
 
-void
-hb_buffer_t::output_glyph (hb_codepoint_t glyph_index)
-{
-  if (unlikely (!make_room_for (0, 1))) return;
-
-  out_info[out_len] = info[idx];
-  out_info[out_len].codepoint = glyph_index;
-
-  out_len++;
-}
-
-void
-hb_buffer_t::output_info (const hb_glyph_info_t &glyph_info)
-{
-  if (unlikely (!make_room_for (0, 1))) return;
-
-  out_info[out_len] = glyph_info;
-
-  out_len++;
-}
-
-void
-hb_buffer_t::copy_glyph (void)
-{
-  if (unlikely (!make_room_for (0, 1))) return;
-
-  out_info[out_len] = info[idx];
-
-  out_len++;
-}
-
 bool
 hb_buffer_t::move_to (unsigned int i)
 {
@@ -442,19 +411,6 @@ hb_buffer_t::move_to (unsigned int i)
   return true;
 }
 
-void
-hb_buffer_t::replace_glyph (hb_codepoint_t glyph_index)
-{
-  if (unlikely (out_info != info || out_len != idx)) {
-    if (unlikely (!make_room_for (1, 1))) return;
-    out_info[out_len] = info[idx];
-  }
-  out_info[out_len].codepoint = glyph_index;
-
-  idx++;
-  out_len++;
-}
-
 
 void
 hb_buffer_t::set_masks (hb_mask_t    value,
diff --git a/src/hb-buffer.hh b/src/hb-buffer.hh
index bcaf066c..33ddcbc8 100644
--- a/src/hb-buffer.hh
+++ b/src/hb-buffer.hh
@@ -212,13 +212,46 @@ struct hb_buffer_t
 				   unsigned int num_out,
 				   const hb_codepoint_t *glyph_data);
 
-  HB_INTERNAL void replace_glyph (hb_codepoint_t glyph_index);
+  inline void replace_glyph (hb_codepoint_t glyph_index)
+  {
+    if (unlikely (out_info != info || out_len != idx)) {
+      if (unlikely (!make_room_for (1, 1))) return;
+      out_info[out_len] = info[idx];
+    }
+    out_info[out_len].codepoint = glyph_index;
+
+    idx++;
+    out_len++;
+  }
   /* Makes a copy of the glyph at idx to output and replace glyph_index */
-  HB_INTERNAL void output_glyph (hb_codepoint_t glyph_index);
-  HB_INTERNAL void output_info (const hb_glyph_info_t &glyph_info);
+  inline hb_glyph_info_t & output_glyph (hb_codepoint_t glyph_index)
+  {
+    if (unlikely (!make_room_for (0, 1))) return Crap(hb_glyph_info_t);
+
+    out_info[out_len] = info[idx];
+    out_info[out_len].codepoint = glyph_index;
+
+    out_len++;
+
+    return out_info[out_len - 1];
+  }
+  inline void output_info (const hb_glyph_info_t &glyph_info)
+  {
+    if (unlikely (!make_room_for (0, 1))) return;
+
+    out_info[out_len] = glyph_info;
+
+    out_len++;
+  }
   /* Copies glyph at idx to output but doesn't advance idx */
-  HB_INTERNAL void copy_glyph (void);
-  HB_INTERNAL bool move_to (unsigned int i); /* i is output-buffer index. */
+  inline void copy_glyph (void)
+  {
+    if (unlikely (!make_room_for (0, 1))) return;
+
+    out_info[out_len] = info[idx];
+
+    out_len++;
+  }
   /* Copies glyph at idx to output and advance idx.
    * If there's no output, just advance idx. */
   inline void
@@ -235,10 +268,11 @@ struct hb_buffer_t
 
     idx++;
   }
-
   /* Advance idx without copying to output. */
-  inline void skip_glyph (void) { idx++; }
-
+  inline void skip_glyph (void)
+  {
+    idx++;
+  }
   inline void reset_masks (hb_mask_t mask)
   {
     for (unsigned int j = 0; j < len; j++)
@@ -275,6 +309,8 @@ struct hb_buffer_t
 
 
   /* Internal methods */
+  HB_INTERNAL bool move_to (unsigned int i); /* i is output-buffer index. */
+
   HB_INTERNAL bool enlarge (unsigned int size);
 
   inline bool ensure (unsigned int size)
commit 6f39c22029867c6d00cf70d7df242a28ca8f12bc
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Oct 3 20:06:32 2018 +0200

    Add code

diff --git a/src/hb-ot-layout.hh b/src/hb-ot-layout.hh
index 24ff8ec5..d64489db 100644
--- a/src/hb-ot-layout.hh
+++ b/src/hb-ot-layout.hh
@@ -339,6 +339,11 @@ _hb_glyph_info_set_continuation (hb_glyph_info_t *info)
 {
   info->unicode_props() |= UPROPS_MASK_CONTINUATION;
 }
+static inline void
+_hb_glyph_info_reset_continuation (hb_glyph_info_t *info)
+{
+  info->unicode_props() &= ~ UPROPS_MASK_CONTINUATION;
+}
 static inline bool
 _hb_glyph_info_is_continuation (const hb_glyph_info_t *info)
 {
commit 19d50aa2620f1464da8e00185b746e46fb0d80c4
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Oct 3 20:05:28 2018 +0200

    [indic] Simplify dottedcircle

diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index dfb3d54d..e92c9ed0 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -332,6 +332,13 @@ data_destroy_indic (void *data)
 }
 
 static void
+_output_with_dotted_circle (hb_buffer_t *buffer)
+{
+  buffer->output_glyph (0x25CCu);
+  buffer->next_glyph ();
+}
+
+static void
 preprocess_text_indic (const hb_ot_shape_plan_t *plan,
 		       hb_buffer_t              *buffer,
 		       hb_font_t                *font)
@@ -401,7 +408,7 @@ preprocess_text_indic (const hb_ot_shape_plan_t *plan,
 	    break;
 	}
 	buffer->next_glyph ();
-	if (matched) { buffer->output_glyph (0x25CCu); buffer->next_glyph (); }
+	if (matched) _output_with_dotted_circle (buffer);
       }
       processed = true;
       break;
@@ -423,7 +430,7 @@ preprocess_text_indic (const hb_ot_shape_plan_t *plan,
 	    break;
 	}
 	buffer->next_glyph ();
-	if (matched) { buffer->output_glyph (0x25CCu); buffer->next_glyph (); }
+	if (matched) _output_with_dotted_circle (buffer);
       }
       processed = true;
       break;
@@ -460,7 +467,7 @@ preprocess_text_indic (const hb_ot_shape_plan_t *plan,
 	    break;
 	}
 	buffer->next_glyph ();
-	if (matched) { buffer->output_glyph (0x25CCu); buffer->next_glyph (); }
+	if (matched) _output_with_dotted_circle (buffer);
       }
       processed = true;
       break;
@@ -485,7 +492,7 @@ preprocess_text_indic (const hb_ot_shape_plan_t *plan,
 	    break;
 	}
 	buffer->next_glyph ();
-	if (matched) { buffer->output_glyph (0x25CCu); buffer->next_glyph (); }
+	if (matched) _output_with_dotted_circle (buffer);
       }
       processed = true;
       break;
@@ -504,7 +511,7 @@ preprocess_text_indic (const hb_ot_shape_plan_t *plan,
 	    break;
 	}
 	buffer->next_glyph ();
-	if (matched) { buffer->output_glyph (0x25CCu); buffer->next_glyph (); }
+	if (matched) _output_with_dotted_circle (buffer);
       }
       processed = true;
       break;
@@ -528,7 +535,7 @@ preprocess_text_indic (const hb_ot_shape_plan_t *plan,
 	    break;
 	}
 	buffer->next_glyph ();
-	if (matched) { buffer->output_glyph (0x25CCu); buffer->next_glyph (); }
+	if (matched) _output_with_dotted_circle (buffer);
       }
       processed = true;
       break;
@@ -547,7 +554,7 @@ preprocess_text_indic (const hb_ot_shape_plan_t *plan,
 	    break;
 	}
 	buffer->next_glyph ();
-	if (matched) { buffer->output_glyph (0x25CCu); buffer->next_glyph (); }
+	if (matched) _output_with_dotted_circle (buffer);
       }
       processed = true;
       break;
@@ -574,7 +581,7 @@ preprocess_text_indic (const hb_ot_shape_plan_t *plan,
 	    break;
 	}
 	buffer->next_glyph ();
-	if (matched) { buffer->output_glyph (0x25CCu); buffer->next_glyph (); }
+	if (matched) _output_with_dotted_circle (buffer);
       }
       processed = true;
       break;
commit 3b7831851052ecf2611a115cc2b80ef970d83df8
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Oct 3 19:44:15 2018 +0200

    [emoji] Mark emoji contination sequences as continuation
    
    This adds a new grapheme bit.  Not used yet.
    
    Part of https://github.com/harfbuzz/harfbuzz/issues/1159

diff --git a/src/hb-ot-layout.hh b/src/hb-ot-layout.hh
index 7a787b77..24ff8ec5 100644
--- a/src/hb-ot-layout.hh
+++ b/src/hb-ot-layout.hh
@@ -160,12 +160,12 @@ hb_ot_layout_position_finish_offsets (hb_font_t    *font,
 #define foreach_syllable(buffer, start, end) \
   for (unsigned int \
        _count = buffer->len, \
-       start = 0, end = _count ? _next_syllable (buffer, 0) : 0; \
+       start = 0, end = _count ? _hb_next_syllable (buffer, 0) : 0; \
        start < _count; \
-       start = end, end = _next_syllable (buffer, start))
+       start = end, end = _hb_next_syllable (buffer, start))
 
 static inline unsigned int
-_next_syllable (hb_buffer_t *buffer, unsigned int start)
+_hb_next_syllable (hb_buffer_t *buffer, unsigned int start)
 {
   hb_glyph_info_t *info = buffer->info;
   unsigned int count = buffer->len;
@@ -188,7 +188,7 @@ _next_syllable (hb_buffer_t *buffer, unsigned int start)
  *   * Whether it's one of the three Mongolian Free Variation Selectors,
  *     CGJ, or other characters that are hidden but should not be ignored
  *     like most other Default_Ignorable()s do during matching.
- *   * One free bit right now.
+ *   * Whether it's a grapheme continuation.
  *
  * The high-byte has different meanings, switched by the Gen-Cat:
  * - For Mn,Mc,Me: the modified Combining_Class.
@@ -202,6 +202,7 @@ enum hb_unicode_props_flags_t {
   UPROPS_MASK_IGNORABLE	= 0x0020u,
   UPROPS_MASK_HIDDEN	= 0x0040u, /* MONGOLIAN FREE VARIATION SELECTOR 1..3,
                                     * or TAG characters */
+  UPROPS_MASK_CONTINUATION=0x0080u,
 
   /* If GEN_CAT=FORMAT, top byte masks: */
   UPROPS_MASK_Cf_ZWJ	= 0x0100u,
@@ -220,6 +221,7 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer)
   if (u >= 0x80)
   {
     buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII;
+
     if (unlikely (unicode->is_default_ignorable (u)))
     {
       buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES;
@@ -245,24 +247,10 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer)
 	props |= UPROPS_MASK_HIDDEN;
       }
     }
-    else if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_NON_ENCLOSING_MARK (gen_cat)))
+
+    if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (gen_cat)))
     {
-      /* The above check is just an optimization to let in only things we need further
-       * processing on. */
-
-      /* Only Mn and Mc can have non-zero ccc:
-       * https://unicode.org/policies/stability_policy.html#Property_Value
-       * """
-       * Canonical_Combining_Class, General_Category
-       * All characters other than those with General_Category property values
-       * Spacing_Mark (Mc) and Nonspacing_Mark (Mn) have the Canonical_Combining_Class
-       * property value 0.
-       * 1.1.5+
-       * """
-       *
-       * Also, all Mn's that are Default_Ignorable, have ccc=0, hence
-       * the "else if".
-       */
+      props |= UPROPS_MASK_CONTINUATION;
       props |= unicode->modified_combining_class (u)<<8;
     }
   }
@@ -302,29 +290,6 @@ _hb_glyph_info_get_modified_combining_class (const hb_glyph_info_t *info)
 {
   return _hb_glyph_info_is_unicode_mark (info) ? info->unicode_props()>>8 : 0;
 }
-
-
-/* Loop over grapheme. Based on foreach_cluster(). */
-#define foreach_grapheme(buffer, start, end) \
-  for (unsigned int \
-       _count = buffer->len, \
-       start = 0, end = _count ? _next_grapheme (buffer, 0) : 0; \
-       start < _count; \
-       start = end, end = _next_grapheme (buffer, start))
-
-static inline unsigned int
-_next_grapheme (hb_buffer_t *buffer, unsigned int start)
-{
-  hb_glyph_info_t *info = buffer->info;
-  unsigned int count = buffer->len;
-
-  while (++start < count && _hb_glyph_info_is_unicode_mark (&info[start]))
-    ;
-
-  return start;
-}
-
-
 #define info_cc(info) (_hb_glyph_info_get_modified_combining_class (&(info)))
 
 static inline bool
@@ -369,6 +334,36 @@ _hb_glyph_info_unhide (hb_glyph_info_t *info)
   info->unicode_props() &= ~ UPROPS_MASK_HIDDEN;
 }
 
+static inline void
+_hb_glyph_info_set_continuation (hb_glyph_info_t *info)
+{
+  info->unicode_props() |= UPROPS_MASK_CONTINUATION;
+}
+static inline bool
+_hb_glyph_info_is_continuation (const hb_glyph_info_t *info)
+{
+  return info->unicode_props() & UPROPS_MASK_CONTINUATION;
+}
+/* Loop over grapheme. Based on foreach_cluster(). */
+#define foreach_grapheme(buffer, start, end) \
+  for (unsigned int \
+       _count = buffer->len, \
+       start = 0, end = _count ? _hb_next_grapheme (buffer, 0) : 0; \
+       start < _count; \
+       start = end, end = _hb_next_grapheme (buffer, start))
+
+static inline unsigned int
+_hb_next_grapheme (hb_buffer_t *buffer, unsigned int start)
+{
+  hb_glyph_info_t *info = buffer->info;
+  unsigned int count = buffer->len;
+
+  while (++start < count && _hb_glyph_info_is_continuation (&info[start]))
+    ;
+
+  return start;
+}
+
 static inline bool
 _hb_glyph_info_is_unicode_format (const hb_glyph_info_t *info)
 {
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 0cea9c66..9e73e358 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -275,10 +275,34 @@ struct hb_ot_shape_context_t
 static void
 hb_set_unicode_props (hb_buffer_t *buffer)
 {
+  /* Implement enough of Unicode Graphemes here that shaping
+   * in reverse-direction wouldn't break graphemes.  Namely,
+   * we mark all marks and ZWJ and ZWJ,Extended_Pictographic
+   * sequences as continuations.  The foreach_grapheme()
+   * macro uses this bit.
+   *
+   * https://www.unicode.org/reports/tr29/#Regex_Definitions
+   */
   unsigned int count = buffer->len;
   hb_glyph_info_t *info = buffer->info;
   for (unsigned int i = 0; i < count; i++)
+  {
     _hb_glyph_info_set_unicode_props (&info[i], buffer);
+
+    /* Marks are already set as continuation by the above line.
+     * Handle ZWJ-continuation. */
+    if (unlikely (_hb_glyph_info_is_zwj (&info[i])))
+    {
+      _hb_glyph_info_set_continuation (&info[i]);
+      if (i + 1 < count &&
+	  _hb_unicode_is_emoji_Extended_Pictographic (info[i + 1].codepoint))
+      {
+        i++;
+	_hb_glyph_info_set_unicode_props (&info[i], buffer);
+	_hb_glyph_info_set_continuation (&info[i]);
+      }
+    }
+  }
 }
 
 static void
diff --git a/src/hb-unicode.hh b/src/hb-unicode.hh
index eac52eaa..106fbf0a 100644
--- a/src/hb-unicode.hh
+++ b/src/hb-unicode.hh
@@ -381,11 +381,6 @@ DECLARE_NULL_INSTANCE (hb_unicode_funcs_t);
 	  FLAG (HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | \
 	  FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)))
 
-#define HB_UNICODE_GENERAL_CATEGORY_IS_NON_ENCLOSING_MARK(gen_cat) \
-	(FLAG_UNSAFE (gen_cat) & \
-	 (FLAG (HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK) | \
-	  FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)))
-
 
 /*
  * Ranges, used for bsearch tables.
commit 123326e20a30a51e25339c2eca272e4e6c847742
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Oct 3 19:19:51 2018 +0200

    Dotted-circle all marks, not just non-spacing, at text beginning

diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index dc88fa9b..0cea9c66 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -286,8 +286,7 @@ hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font)
 {
   if (!(buffer->flags & HB_BUFFER_FLAG_BOT) ||
       buffer->context_len[0] ||
-      _hb_glyph_info_get_general_category (&buffer->info[0]) !=
-      HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
+      !_hb_glyph_info_is_unicode_mark (&buffer->info[0]))
     return;
 
   if (!font->has_glyph (0x25CCu))
commit 4146c00caa29e53ee9a29def151f12792ac76596
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date:   Wed Oct 3 21:26:58 2018 +0330

    [test] Use an in-repo font for test-multithread (#1218)
    
    As Khaled's suggestion, hard-coded font paths was only for my own testing.

diff --git a/test/api/hb-subset-test.h b/test/api/hb-subset-test.h
index 0318fa7b..8f32d3db 100644
--- a/test/api/hb-subset-test.h
+++ b/test/api/hb-subset-test.h
@@ -51,13 +51,18 @@ static inline hb_face_t *
 hb_subset_test_open_font (const char *font_path)
 {
 #if GLIB_CHECK_VERSION(2,37,2)
-  char* path = g_test_build_filename (G_TEST_DIST, font_path, NULL);
+  char *path = g_test_build_filename (G_TEST_DIST, font_path, NULL);
 #else
-  char* path = g_strdup (font_path);
+  char *path = g_strdup (font_path);
 #endif
 
-  hb_blob_t* blob = hb_blob_create_from_file (path);
-  hb_face_t* face = hb_face_create (blob, 0);
+  hb_blob_t *blob = hb_blob_create_from_file (path);
+  if (hb_blob_get_length (blob) == 0)
+  {
+    printf ("The test font is not found.");
+    exit (1);
+  }
+  hb_face_t *face = hb_face_create (blob, 0);
   hb_blob_destroy (blob);
 
   g_free (path);
diff --git a/test/api/test-multithread.c b/test/api/test-multithread.c
index 508dd396..72a1a178 100644
--- a/test/api/test-multithread.c
+++ b/test/api/test-multithread.c
@@ -32,18 +32,10 @@
 #include <hb.h>
 #include <hb-ft.h>
 #include <hb-ot.h>
+#include <glib.h>
 
-static const char *text = "طرح‌نَما";
-static const char *path =
-#if defined(__linux__)
-		"/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf";
-#elif defined(__FreeBSD__)
-		"/usr/local/share/fonts/dejavu/DejaVuSans.ttf";
-#elif defined(_WIN32) || defined(_WIN64)
-		"C:\\Windows\\Fonts\\tahoma.ttf";
-#elif __APPLE__
-		"/Library/Fonts/Tahoma.ttf";
-#endif
+static char *font_path = "fonts/Inconsolata-Regular.abc.ttf";
+static char *text = "abc";
 
 static int num_threads = 30;
 static int num_iters = 200;
@@ -56,7 +48,7 @@ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 static void
 fill_the_buffer (hb_buffer_t *buffer)
 {
-  hb_buffer_add_utf8 (buffer, text, sizeof (text), 0, sizeof (text));
+  hb_buffer_add_utf8 (buffer, text, -1, 0, -1);
   hb_buffer_guess_segment_properties (buffer);
   hb_shape (font, buffer, NULL, 0);
 }
@@ -135,16 +127,33 @@ test_body (void)
 int
 main (int argc, char **argv)
 {
-  if (argc > 1)
-    num_threads = atoi (argv[1]);
+  g_test_init (&argc, &argv, NULL);
+
+#if GLIB_CHECK_VERSION(2,37,2)
+  gchar *default_path = g_test_build_filename (G_TEST_DIST, font_path, NULL);
+#else
+  gchar *default_path = g_strdup (font_path);
+#endif
+
+  char *path = argc > 1 ? argv[1] : (char *) default_path;
   if (argc > 2)
-    num_iters = atoi (argv[2]);
+    num_threads = atoi (argv[2]);
+  if (argc > 3)
+    num_iters = atoi (argv[3]);
+  if (argc > 4)
+    text = argv[4];
 
   // Dummy call to alleviate _guess_segment_properties thread safety-ness
   // https://github.com/harfbuzz/harfbuzz/issues/1191
   hb_language_get_default ();
 
   hb_blob_t *blob = hb_blob_create_from_file (path);
+  if (hb_blob_get_length (blob) == 0)
+  {
+    printf ("The test font is not found.");
+    return 1;
+  }
+
   hb_face_t *face = hb_face_create (blob, 0);
   font = hb_font_create (face);
 
@@ -167,5 +176,7 @@ main (int argc, char **argv)
   hb_face_destroy (face);
   hb_blob_destroy (blob);
 
+  g_free (default_path);
+
   return 0;
 }
diff --git a/test/fuzzing/main.cc b/test/fuzzing/main.cc
index 3ff8803e..b42d60c1 100644
--- a/test/fuzzing/main.cc
+++ b/test/fuzzing/main.cc
@@ -1,12 +1,18 @@
 #include "hb-fuzzer.hh"
 
 #include <stdio.h>
+#include <stdlib.h>
 #include <assert.h>
 
 int main(int argc, char **argv) {
   hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
   unsigned int len;
   const char *font_data = hb_blob_get_data (blob, &len);
+  if (len == 0)
+  {
+    printf ("The test font is not found.");
+    exit (1);
+  }
 
   for (int i = 1; i < argc; i++) {
     printf ("%s\n", argv[i]);
commit fde9b8852d7cd6224afeffcfe363f4b445ab1ece
Author: azure-pipelines[bot] <azure-pipelines[bot]@users.noreply.github.com>
Date:   Wed Oct 3 17:47:05 2018 +0000

    [ci] Add a test Azure Pipelines Linux bot
    
    Related #1219

diff --git a/azure-pipelines.yml b/azure-pipelines.yml
new file mode 100644
index 00000000..dfaa08d0
--- /dev/null
+++ b/azure-pipelines.yml
@@ -0,0 +1,10 @@
+pool:
+  vmImage: 'Ubuntu 16.04'
+
+steps:
+- script: |
+    apt install -y gcc binutils libtool autoconf automake make pkg-config gtk-doc-tools ragel libfreetype6-dev libfontconfig1-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev python python-pip
+    ./autogen.sh --with-freetype --with-glib --with-cairo --with-icu --with-graphite2 --with-fontconfig
+    make -j32
+    make check
+  displayName: 'make'


More information about the HarfBuzz mailing list