[HarfBuzz] harfbuzz: Branch 'master'

2018-09-23 Thread Behdad Esfahbod
 src/hb-ot-shape-complex-hebrew.cc |2 
 src/hb-ot-shape-normalize.cc  |  126 --
 src/hb-ot-shape-normalize.hh  |7 +-
 3 files changed, 72 insertions(+), 63 deletions(-)

New commits:
commit 62d1e0852a5549a1b510ad46a4b89f12730bb708
Author: Behdad Esfahbod 
Date:   Sun Sep 23 21:32:18 2018 -0400

Prefer decomposed form if font has GPOS mark feature

Fixes https://github.com/harfbuzz/harfbuzz/issues/653

diff --git a/src/hb-ot-shape-complex-hebrew.cc 
b/src/hb-ot-shape-complex-hebrew.cc
index ba25258a..5ad8daf7 100644
--- a/src/hb-ot-shape-complex-hebrew.cc
+++ b/src/hb-ot-shape-complex-hebrew.cc
@@ -70,7 +70,7 @@ compose_hebrew (const hb_ot_shape_normalize_context_t *c,
 
   bool found = (bool) c->unicode->compose (a, b, ab);
 
-  if (!found && !c->plan->has_mark)
+  if (!found)
   {
   /* Special-case Hebrew presentation forms that are excluded from
* standard normalization, but wanted for old fonts. */
diff --git a/src/hb-ot-shape-normalize.cc b/src/hb-ot-shape-normalize.cc
index fd0b63ae..487fd96a 100644
--- a/src/hb-ot-shape-normalize.cc
+++ b/src/hb-ot-shape-normalize.cc
@@ -294,6 +294,14 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
   _hb_buffer_assert_unicode_vars (buffer);
 
   hb_ot_shape_normalization_mode_t mode = 
plan->shaper->normalization_preference;
+  if (mode == HB_OT_SHAPE_NORMALIZATION_MODE_AUTO)
+  {
+if (plan->has_mark)
+  mode = HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED;
+else
+  mode = HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS;
+  }
+
   const hb_ot_shape_normalize_context_t c = {
 plan,
 buffer,
@@ -358,65 +366,6 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
 
 i = end;
   }
-
-
-  if (mode == HB_OT_SHAPE_NORMALIZATION_MODE_NONE ||
-  mode == HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED)
-return;
-
-  /* Third round, recompose */
-
-  /* As noted in the comment earlier, we don't try to combine
-   * ccc=0 chars with their previous Starter. */
-
-  buffer->clear_output ();
-  count = buffer->len;
-  unsigned int starter = 0;
-  buffer->next_glyph ();
-  while (buffer->idx < count && buffer->successful)
-  {
-hb_codepoint_t composed, glyph;
-if (/* We don't try to compose a non-mark character with it's preceding 
starter.
-* This is both an optimization to avoid trying to compose every two 
neighboring
-* glyphs in most scripts AND a desired feature for Hangul.  Apparently 
Hangul
-* fonts are not designed to mix-and-match pre-composed syllables and 
Jamo. */
-   HB_UNICODE_GENERAL_CATEGORY_IS_MARK 
(_hb_glyph_info_get_general_category (>cur(
-{
-  if (/* If there's anything between the starter and this char, they 
should have CCC
-  * smaller than this character's. */
- (starter == buffer->out_len - 1 ||
-  info_cc (buffer->prev()) < info_cc (buffer->cur())) &&
- /* And compose. */
- c.compose (,
-buffer->out_info[starter].codepoint,
-buffer->cur().codepoint,
-) &&
- /* And the font has glyph for the composite. */
- font->get_nominal_glyph (composed, ))
-  {
-   /* Composes. */
-   buffer->next_glyph (); /* Copy to out-buffer. */
-   if (unlikely (!buffer->successful))
- return;
-   buffer->merge_out_clusters (starter, buffer->out_len);
-   buffer->out_len--; /* Remove the second composable. */
-   /* Modify starter and carry on. */
-   buffer->out_info[starter].codepoint = composed;
-   buffer->out_info[starter].glyph_index() = glyph;
-   _hb_glyph_info_set_unicode_props (>out_info[starter], buffer);
-
-   continue;
-  }
-}
-
-/* Blocked, or doesn't compose. */
-buffer->next_glyph ();
-
-if (info_cc (buffer->prev()) == 0)
-  starter = buffer->out_len - 1;
-  }
-  buffer->swap_buffers ();
-
   if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_CGJ)
   {
 /* For all CGJ, check if it prevented any reordering at all.
@@ -430,4 +379,63 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
_hb_glyph_info_unhide (>info[i]);
   }
   }
+
+
+  /* Third round, recompose */
+
+  if (mode == HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS ||
+  mode == 
HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT)
+return;
+  {
+/* As noted in the comment earlier, we don't try to combine
+ * ccc=0 chars with their previous Starter. */
+
+buffer->clear_output ();
+count = buffer->len;
+unsigned int starter = 0;
+buffer->next_glyph ();
+while (buffer->idx < count && buffer->successful)
+{
+  hb_codepoint_t composed, glyph;
+  if (/* We don't try to compose a non-mark character with it's preceding 
starter.
+  * This is both an optimization to avoid trying to compose every two 
neighboring
+  * glyphs in most scripts AND a 

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

2018-09-23 Thread Behdad Esfahbod
 .circleci/config.yml  |   52 ++
 src/hb-blob.cc|   27 +++
 src/hb-ot-post-table.hh   |1 
 src/hb.hh |4 ++-
 test/api/hb-subset-test.h |   12 +++---
 test/api/test-font.c  |1 
 test/api/test-ot-math.c   |4 +++
 test/api/test-set.c   |1 
 test/shaping/run-tests.py |2 -
 9 files changed, 99 insertions(+), 5 deletions(-)

New commits:
commit d7f21777e6a797758ab234555f5f7e07c87278f9
Author: Behdad Esfahbod 
Date:   Sun Sep 23 19:12:52 2018 -0400

[ot-font] Fix leak

Fixes https://github.com/harfbuzz/harfbuzz/issues/1171

I'm glad we have leak-detector bots now.

diff --git a/src/hb-ot-post-table.hh b/src/hb-ot-post-table.hh
index 5f27fd50..f81de37d 100644
--- a/src/hb-ot-post-table.hh
+++ b/src/hb-ot-post-table.hh
@@ -131,6 +131,7 @@ struct post
 {
   index_to_offset.fini ();
   free (gids_sorted_by_name.get ());
+  hb_blob_destroy (blob);
 }
 
 inline bool get_glyph_name (hb_codepoint_t glyph,
commit ae39a53f55e6b812defb4c7b48562651c9eb13a3
Author: Ebrahim Byagowi 
Date:   Sat Sep 22 14:22:17 2018 +0330

Add bots with address- and thread-sanitizer

diff --git a/.circleci/config.yml b/.circleci/config.yml
index 5ad1ae13..671f49d7 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -79,6 +79,54 @@ jobs:
   - run: make
   - run: LD_LIBRARY_PATH="$PWD/freetype-2.9/objs/.libs" make check || 
.ci/fail.sh
 
+  clang-asan:
+docker:
+  - image: ubuntu:18.04
+steps:
+  - checkout
+  - run: apt update || true
+  - run: apt install -y clang-6.0 binutils libtool autoconf automake make 
pkg-config gtk-doc-tools ragel libfreetype6-dev libglib2.0-dev libcairo2-dev 
libicu-dev libgraphite2-dev python python-pip
+  - run: pip install fonttools
+  - run: CPPFLAGS="-fsanitize=address" LDFLAGS="-fsanitize=address" 
CC=clang-6.0 CXX=clang++-6.0 ./autogen.sh --with-freetype --with-glib 
--with-cairo --with-icu --with-graphite2
+  - run: make
+  - run: make check || .ci/fail.sh
+
+  clang-msan:
+docker:
+  - image: ubuntu:18.04
+steps:
+  - checkout
+  - run: apt update || true
+  - run: apt install -y clang-6.0 binutils libtool autoconf automake make 
pkg-config ragel libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev 
libgraphite2-dev python python-pip
+  - run: pip install fonttools
+  - run: CPPFLAGS="-fsanitize=memory" LDFLAGS="-fsanitize=memory" 
CC=clang-6.0 CXX=clang++-6.0 ./autogen.sh --with-freetype --with-glib 
--with-cairo --with-icu --with-graphite2
+  - run: make
+  - run: make check || .ci/fail.sh
+
+  clang-tsan:
+docker:
+  - image: ubuntu:18.04
+steps:
+  - checkout
+  - run: apt update || true
+  - run: apt install -y clang-6.0 binutils libtool autoconf automake make 
pkg-config ragel libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev 
libgraphite2-dev python python-pip
+  - run: pip install fonttools
+  - run: CPPFLAGS="-fsanitize=thread" LDFLAGS="-fsanitize=thread" 
CC=clang-6.0 CXX=clang++-6.0 ./autogen.sh --with-freetype --with-glib 
--with-cairo --with-icu --with-graphite2
+  - run: make
+  - run: make check || .ci/fail.sh
+
+  clang-ubsan:
+docker:
+  - image: ubuntu:18.04
+steps:
+  - checkout
+  - run: apt update || true
+  - run: apt install -y clang-6.0 binutils libtool autoconf automake make 
pkg-config ragel libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev 
libgraphite2-dev python python-pip
+  - run: pip install fonttools
+  - run: CPPFLAGS="-fsanitize=undefined" LDFLAGS="-fsanitize=undefined" 
CC=clang-6.0 CXX=clang++-6.0 ./autogen.sh --with-freetype --with-glib 
--with-cairo --with-icu --with-graphite2
+  - run: make
+  - run: make check || .ci/fail.sh
+
   fedora-outoftreebuild:
 docker:
   - image: fedora
@@ -200,6 +248,10 @@ workflows:
   - alpine-O3-NOMMAP
   - archlinux-debug-O0-py3
   - clang-O3-O0
+  - clang-asan
+  - clang-msan
+  - clang-tsan
+  - clang-ubsan
   - fedora-outoftreebuild
 
   # cmake based builds
commit 24dd6c1a9d8d571c30dce4d39c1975b1d1cedc2a
Author: Matt Oliver 
Date:   Sun Sep 23 18:08:30 2018 +1000

src/hb-blob.cc: Fix mmap functionality with UWP.

diff --git a/src/hb-blob.cc b/src/hb-blob.cc
index a335df30..fca3c910 100644
--- a/src/hb-blob.cc
+++ b/src/hb-blob.cc
@@ -574,18 +574,45 @@ fail_without_close:
   wchar_t * wchar_file_name = (wchar_t *) malloc (sizeof (wchar_t) * size);
   if (unlikely (wchar_file_name == nullptr)) goto fail_without_close;
   mbstowcs (wchar_file_name, file_name, size);
+#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || 
WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
+  {
+CREATEFILE2_EXTENDED_PARAMETERS ceparams = { 0 };
+ceparams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
+

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

2018-09-23 Thread Behdad Esfahbod
 src/hb-ot-layout-gsubgpos.hh   |   23 ---
 src/hb-ot-shape-complex-indic.cc   |   21 -
 src/hb-ot-shape-complex-khmer.cc   |   21 ++---
 src/hb-ot-shape-complex-myanmar.cc |   15 ++-
 src/hb-ot-shape-complex-use.cc |   15 +--
 5 files changed, 69 insertions(+), 26 deletions(-)

New commits:
commit 3583fb03b14a10ec5ab5f9c480e150934101fd0b
Author: Behdad Esfahbod 
Date:   Sun Sep 23 22:33:38 2018 -0400

Simplify ZWJ-skipping a bit

Towards disabling ZWJ-skipping in certain GPOS contexts.

Part of https://github.com/flutter/flutter/issues/16886

diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh
index 6ff19e23..031b39b9 100644
--- a/src/hb-ot-layout-gsubgpos.hh
+++ b/src/hb-ot-layout-gsubgpos.hh
@@ -344,10 +344,10 @@ struct hb_ot_apply_context_t :
   match_glyph_data = nullptr;
   matcher.set_match_func (nullptr, nullptr);
   matcher.set_lookup_props (c->lookup_props);
-  /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */
+  /* Ignore ZWNJ if we are matching GPOS, or matching GSUB context and 
asked to. */
   matcher.set_ignore_zwnj (c->table_index == 1 || (context_match && 
c->auto_zwnj));
-  /* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if 
asked to. */
-  matcher.set_ignore_zwj  (c->table_index == 1 || (context_match || 
c->auto_zwj));
+  /* Ignore ZWJ if we are matching context, or asked to. */
+  matcher.set_ignore_zwj  (context_match || c->auto_zwj);
   matcher.set_mask (context_match ? -1 : c->lookup_mask);
 }
 inline void set_lookup_props (unsigned int lookup_props)
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 369078cb..c1aa1d0f 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -95,7 +95,8 @@ static const indic_config_t indic_configs[] =
  * Indic shaper.
  */
 
-struct feature_list_t {
+struct feature_list_t
+{
   hb_tag_t tag;
   hb_ot_map_feature_flags_t flags;
 };
@@ -130,7 +131,10 @@ indic_features[] =
   {HB_TAG('b','l','w','s'), F_GLOBAL},
   {HB_TAG('p','s','t','s'), F_GLOBAL},
   {HB_TAG('h','a','l','n'), F_GLOBAL},
-  /* Positioning features, though we don't care about the types. */
+  /*
+   * Positioning features.
+   * We don't care about the types.
+   */
   {HB_TAG('d','i','s','t'), F_GLOBAL},
   {HB_TAG('a','b','v','m'), F_GLOBAL},
   {HB_TAG('b','l','w','m'), F_GLOBAL},
@@ -158,12 +162,14 @@ enum {
   _BLWS,
   _PSTS,
   _HALN,
+
   _DIST,
   _ABVM,
   _BLWM,
 
   INDIC_NUM_FEATURES,
-  INDIC_BASIC_FEATURES = INIT /* Don't forget to update this! */
+  INDIC_BASIC_FEATURES = INIT, /* Don't forget to update this! */
+  INDIC_SUBST_FEATURES = _DIST /* Don't forget to update this! */
 };
 
 static void
@@ -199,14 +205,19 @@ collect_features_indic (hb_ot_shape_planner_t *plan)
 
   unsigned int i = 0;
   map->add_gsub_pause (initial_reordering);
+
   for (; i < INDIC_BASIC_FEATURES; i++) {
 map->add_feature (indic_features[i].tag, 1, indic_features[i].flags | 
F_MANUAL_ZWJ | F_MANUAL_ZWNJ);
 map->add_gsub_pause (nullptr);
   }
+
   map->add_gsub_pause (final_reordering);
-  for (; i < INDIC_NUM_FEATURES; i++) {
+
+  for (; i < INDIC_SUBST_FEATURES; i++)
 map->add_feature (indic_features[i].tag, 1, indic_features[i].flags | 
F_MANUAL_ZWJ | F_MANUAL_ZWNJ);
-  }
+
+  for (; i < INDIC_NUM_FEATURES; i++)
+map->add_feature (indic_features[i].tag, 1, indic_features[i].flags);
 
   map->add_global_bool_feature (HB_TAG('c','a','l','t'));
   map->add_global_bool_feature (HB_TAG('c','l','i','g'));
diff --git a/src/hb-ot-shape-complex-khmer.cc b/src/hb-ot-shape-complex-khmer.cc
index 0b5b50a9..7a88aaa2 100644
--- a/src/hb-ot-shape-complex-khmer.cc
+++ b/src/hb-ot-shape-complex-khmer.cc
@@ -32,7 +32,8 @@
  * Khmer shaper.
  */
 
-struct feature_list_t {
+struct feature_list_t
+{
   hb_tag_t tag;
   hb_ot_map_feature_flags_t flags;
 };
@@ -57,7 +58,10 @@ khmer_features[] =
   {HB_TAG('a','b','v','s'), F_GLOBAL},
   {HB_TAG('b','l','w','s'), F_GLOBAL},
   {HB_TAG('p','s','t','s'), F_GLOBAL},
-  /* Positioning features, though we don't care about the types. */
+  /*
+   * Positioning features.
+   * We don't care about the types.
+   */
   {HB_TAG('d','i','s','t'), F_GLOBAL},
   {HB_TAG('a','b','v','m'), F_GLOBAL},
   {HB_TAG('b','l','w','m'), F_GLOBAL},
@@ -77,12 +81,14 @@ enum {
   _ABVS,
   _BLWS,
   _PSTS,
+
   _DIST,
   _ABVM,
   _BLWM,
 
   KHMER_NUM_FEATURES,
-  KHMER_BASIC_FEATURES = _PRES /* Don't forget to update this! */
+  KHMER_BASIC_FEATURES = _PRES, /* Don't forget to update this! */
+  KHMER_SUBST_FEATURES = _DIST, /* Don't forget to update this! */
 };
 
 static void
@@ -121,15 +127,16 @@ collect_features_khmer (hb_ot_shape_planner_t *plan)
   map->add_global_bool_feature (HB_TAG('c','c','m','p'));
 
   unsigned int i = 0;
-  for (; i < KHMER_BASIC_FEATURES; i++) {
+  for (;