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

Behdad Esfahbod behdad at kemper.freedesktop.org
Fri Mar 30 00:30:40 UTC 2018


 Makefile.am                                             |    3 
 README.python.md                                        |   12 -
 README.wine.md                                          |   40 +++
 RELEASING.md                                            |   25 +-
 src/Makefile.am                                         |    2 
 src/gen-arabic-table.py                                 |  174 +++++++---------
 src/gen-def.py                                          |    2 
 src/gen-indic-table.py                                  |  135 ++++++------
 src/gen-unicode-ranges.py                               |    8 
 src/gen-use-table.py                                    |   17 +
 src/hb-common.cc                                        |   60 +++--
 src/hb-ft.cc                                            |   44 ++--
 src/hb-glib.cc                                          |    7 
 src/hb-graphite2.cc                                     |   10 
 src/hb-graphite2.h                                      |    4 
 src/hb-icu.cc                                           |    7 
 src/hb-ot-font.cc                                       |    7 
 src/hb-ot-shape-complex-indic-table.cc                  |    2 
 src/hb-shape.cc                                         |    7 
 src/hb-shaper.cc                                        |    9 
 src/hb-ucdn.cc                                          |    7 
 src/hb-uniscribe.cc                                     |    8 
 src/sample.py                                           |    5 
 test/fuzzing/run-shape-fuzzer-tests.py                  |    3 
 test/fuzzing/run-subset-fuzzer-tests.py                 |    3 
 test/shaping/data/text-rendering-tests/extract-tests.py |    3 
 test/shaping/hb_test_tools.py                           |    7 
 test/shaping/run-tests.py                               |    3 
 test/subset/run-tests.py                                |    2 
 29 files changed, 366 insertions(+), 250 deletions(-)

New commits:
commit 70d36543aa929320ff82a9ce589786e58adb1836
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date:   Fri Mar 30 05:00:28 2018 +0430

    Make atexit callbacks threadsafe (#930)

diff --git a/src/hb-common.cc b/src/hb-common.cc
index ce3d01b8..b16c9324 100644
--- a/src/hb-common.cc
+++ b/src/hb-common.cc
@@ -60,12 +60,12 @@ _hb_options_init (void)
 
 /**
  * hb_tag_from_string:
- * @str: (array length=len) (element-type uint8_t): 
- * @len: 
+ * @str: (array length=len) (element-type uint8_t):
+ * @len:
  *
- * 
  *
- * Return value: 
+ *
+ * Return value:
  *
  * Since: 0.9.2
  **/
@@ -90,10 +90,10 @@ hb_tag_from_string (const char *str, int len)
 
 /**
  * hb_tag_to_string:
- * @tag: 
- * @buf: (out caller-allocates) (array fixed-size=4) (element-type uint8_t): 
+ * @tag:
+ * @buf: (out caller-allocates) (array fixed-size=4) (element-type uint8_t):
+ *
  *
- * 
  *
  * Since: 0.9.5
  **/
@@ -118,12 +118,12 @@ const char direction_strings[][4] = {
 
 /**
  * hb_direction_from_string:
- * @str: (array length=len) (element-type uint8_t): 
- * @len: 
+ * @str: (array length=len) (element-type uint8_t):
+ * @len:
  *
- * 
  *
- * Return value: 
+ *
+ * Return value:
  *
  * Since: 0.9.2
  **/
@@ -146,11 +146,11 @@ hb_direction_from_string (const char *str, int len)
 
 /**
  * hb_direction_to_string:
- * @direction: 
+ * @direction:
  *
- * 
  *
- * Return value: (transfer none): 
+ *
+ * Return value: (transfer none):
  *
  * Since: 0.9.2
  **/
@@ -361,7 +361,7 @@ hb_language_to_string (hb_language_t language)
 /**
  * hb_language_get_default:
  *
- * 
+ *
  *
  * Return value: (transfer none):
  *
@@ -390,7 +390,7 @@ hb_language_get_default (void)
  *
  * Converts an ISO 15924 script tag to a corresponding #hb_script_t.
  *
- * Return value: 
+ * Return value:
  * An #hb_script_t corresponding to the ISO 15924 tag.
  *
  * Since: 0.9.2
@@ -439,7 +439,7 @@ hb_script_from_iso15924_tag (hb_tag_t tag)
  * corresponding #hb_script_t. Shorthand for hb_tag_from_string() then
  * hb_script_from_iso15924_tag().
  *
- * Return value: 
+ * Return value:
  * An #hb_script_t corresponding to the ISO 15924 tag.
  *
  * Since: 0.9.2
@@ -469,11 +469,11 @@ hb_script_to_iso15924_tag (hb_script_t script)
 
 /**
  * hb_script_get_horizontal_direction:
- * @script: 
+ * @script:
+ *
  *
- * 
  *
- * Return value: 
+ * Return value:
  *
  * Since: 0.9.2
  **/
@@ -613,13 +613,13 @@ hb_version_string (void)
 
 /**
  * hb_version_atleast:
- * @major: 
- * @minor: 
- * @micro: 
+ * @major:
+ * @minor:
+ * @micro:
  *
- * 
  *
- * Return value: 
+ *
+ * Return value:
  *
  * Since: 0.9.30
  **/
@@ -724,8 +724,14 @@ static HB_LOCALE_T C_locale;
 static void
 free_C_locale (void)
 {
-  if (C_locale)
-    HB_FREE_LOCALE (C_locale);
+retry:
+  HB_LOCALE_T locale = (HB_LOCALE_T) hb_atomic_ptr_get (&C_locale);
+
+  if (!hb_atomic_ptr_cmpexch (&C_locale, locale, nullptr))
+    goto retry;
+
+  if (locale)
+    HB_FREE_LOCALE (locale);
 }
 #endif
 
diff --git a/src/hb-ft.cc b/src/hb-ft.cc
index fc4b1122..e68960d5 100644
--- a/src/hb-ft.cc
+++ b/src/hb-ft.cc
@@ -109,7 +109,7 @@ _hb_ft_font_destroy (void *data)
  * @font:
  * @load_flags:
  *
- * 
+ *
  *
  * Since: 1.0.5
  **/
@@ -131,7 +131,7 @@ hb_ft_font_set_load_flags (hb_font_t *font, int load_flags)
  * hb_ft_font_get_load_flags:
  * @font:
  *
- * 
+ *
  *
  * Return value:
  * Since: 1.0.5
@@ -423,7 +423,12 @@ static hb_font_funcs_t *static_ft_funcs = nullptr;
 static
 void free_static_ft_funcs (void)
 {
-  hb_font_funcs_destroy (static_ft_funcs);
+retry:
+  hb_font_funcs_t *ft_funcs = (hb_font_funcs_t *) hb_atomic_ptr_get (&static_ft_funcs);
+  if (!hb_atomic_ptr_cmpexch (&static_ft_funcs, ft_funcs, nullptr))
+    goto retry;
+
+  hb_font_funcs_destroy (ft_funcs);
 }
 #endif
 
@@ -502,12 +507,12 @@ reference_table  (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
 
 /**
  * hb_ft_face_create:
- * @ft_face: (destroy destroy) (scope notified): 
+ * @ft_face: (destroy destroy) (scope notified):
  * @destroy:
  *
- * 
  *
- * Return value: (transfer full): 
+ *
+ * Return value: (transfer full):
  * Since: 0.9.2
  **/
 hb_face_t *
@@ -539,9 +544,9 @@ hb_ft_face_create (FT_Face           ft_face,
  * hb_ft_face_create_referenced:
  * @ft_face:
  *
- * 
  *
- * Return value: (transfer full): 
+ *
+ * Return value: (transfer full):
  * Since: 0.9.38
  **/
 hb_face_t *
@@ -559,11 +564,11 @@ hb_ft_face_finalize (FT_Face ft_face)
 
 /**
  * hb_ft_face_create_cached:
- * @ft_face: 
+ * @ft_face:
  *
- * 
  *
- * Return value: (transfer full): 
+ *
+ * Return value: (transfer full):
  * Since: 0.9.2
  **/
 hb_face_t *
@@ -584,12 +589,12 @@ hb_ft_face_create_cached (FT_Face ft_face)
 
 /**
  * hb_ft_font_create:
- * @ft_face: (destroy destroy) (scope notified): 
+ * @ft_face: (destroy destroy) (scope notified):
  * @destroy:
  *
- * 
  *
- * Return value: (transfer full): 
+ *
+ * Return value: (transfer full):
  * Since: 0.9.2
  **/
 hb_font_t *
@@ -664,9 +669,9 @@ hb_ft_font_changed (hb_font_t *font)
  * hb_ft_font_create_referenced:
  * @ft_face:
  *
- * 
  *
- * Return value: (transfer full): 
+ *
+ * Return value: (transfer full):
  * Since: 0.9.38
  **/
 hb_font_t *
@@ -685,7 +690,12 @@ static FT_Library ft_library;
 static
 void free_ft_library (void)
 {
-  FT_Done_FreeType (ft_library);
+retry:
+  FT_Library library = (FT_Library) hb_atomic_ptr_get (&ft_library);
+  if (!hb_atomic_ptr_cmpexch (&ft_library, library, nullptr))
+    goto retry;
+
+  FT_Done_FreeType (library);
 }
 #endif
 
diff --git a/src/hb-glib.cc b/src/hb-glib.cc
index 50c30e9c..246380a7 100644
--- a/src/hb-glib.cc
+++ b/src/hb-glib.cc
@@ -370,7 +370,12 @@ static hb_unicode_funcs_t *static_glib_funcs = nullptr;
 static
 void free_static_glib_funcs (void)
 {
-  hb_unicode_funcs_destroy (static_glib_funcs);
+retry:
+  hb_unicode_funcs_t *glib_funcs = (hb_unicode_funcs_t *) hb_atomic_ptr_get (&static_glib_funcs);
+  if (!hb_atomic_ptr_cmpexch (&static_glib_funcs, glib_funcs, nullptr))
+    goto retry;
+
+  hb_unicode_funcs_destroy (glib_funcs);
 }
 #endif
 
diff --git a/src/hb-icu.cc b/src/hb-icu.cc
index 552eaeca..c52e165b 100644
--- a/src/hb-icu.cc
+++ b/src/hb-icu.cc
@@ -351,7 +351,12 @@ static hb_unicode_funcs_t *static_icu_funcs = nullptr;
 static
 void free_static_icu_funcs (void)
 {
-  hb_unicode_funcs_destroy (static_icu_funcs);
+retry:
+  hb_unicode_funcs_t *icu_funcs = (hb_unicode_funcs_t *) hb_atomic_ptr_get (&static_icu_funcs);
+  if (!hb_atomic_ptr_cmpexch (&static_icu_funcs, icu_funcs, nullptr))
+    goto retry;
+
+  hb_unicode_funcs_destroy (icu_funcs);
 }
 #endif
 
diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc
index 0e373d30..5e7a6da0 100644
--- a/src/hb-ot-font.cc
+++ b/src/hb-ot-font.cc
@@ -217,7 +217,12 @@ static hb_font_funcs_t *static_ot_funcs = nullptr;
 static
 void free_static_ot_funcs (void)
 {
-  hb_font_funcs_destroy (static_ot_funcs);
+retry:
+  hb_font_funcs_t *ot_funcs = (hb_font_funcs_t *) hb_atomic_ptr_get (&static_ot_funcs);
+  if (!hb_atomic_ptr_cmpexch (&static_ot_funcs, ot_funcs, nullptr))
+    goto retry;
+
+  hb_font_funcs_destroy (ot_funcs);
 }
 #endif
 
diff --git a/src/hb-shape.cc b/src/hb-shape.cc
index 39355b33..c1e73656 100644
--- a/src/hb-shape.cc
+++ b/src/hb-shape.cc
@@ -51,7 +51,12 @@ static const char **static_shaper_list;
 static
 void free_static_shaper_list (void)
 {
-  free (static_shaper_list);
+retry:
+  const char **shaper_list = (const char **) hb_atomic_ptr_get (&static_shaper_list);
+  if (!hb_atomic_ptr_cmpexch (&static_shaper_list, shaper_list, nullptr))
+    goto retry;
+
+  free (shaper_list);
 }
 #endif
 
diff --git a/src/hb-shaper.cc b/src/hb-shaper.cc
index 2c44cf26..d44d8c91 100644
--- a/src/hb-shaper.cc
+++ b/src/hb-shaper.cc
@@ -44,8 +44,13 @@ static const hb_shaper_pair_t *static_shapers;
 static
 void free_static_shapers (void)
 {
-  if (unlikely (static_shapers != all_shapers))
-    free ((void *) static_shapers);
+retry:
+  hb_shaper_pair_t *shapers = (hb_shaper_pair_t *) hb_atomic_ptr_get (&static_shapers);
+  if (!hb_atomic_ptr_cmpexch (&static_shapers, shapers, nullptr))
+    goto retry;
+
+  if (unlikely (shapers != all_shapers))
+    free ((void *) shapers);
 }
 #endif
 
diff --git a/src/hb-ucdn.cc b/src/hb-ucdn.cc
index 9515bda2..02ea3667 100644
--- a/src/hb-ucdn.cc
+++ b/src/hb-ucdn.cc
@@ -237,7 +237,12 @@ static hb_unicode_funcs_t *static_ucdn_funcs = nullptr;
 static
 void free_static_ucdn_funcs (void)
 {
-  hb_unicode_funcs_destroy (static_ucdn_funcs);
+retry:
+  hb_unicode_funcs_t *ucdn_funcs = (hb_unicode_funcs_t *) hb_atomic_ptr_get (&static_ucdn_funcs);
+  if (!hb_atomic_ptr_cmpexch (&static_ucdn_funcs, ucdn_funcs, nullptr))
+    goto retry;
+
+  hb_unicode_funcs_destroy (ucdn_funcs);
 }
 #endif
 
diff --git a/src/hb-uniscribe.cc b/src/hb-uniscribe.cc
index e780f885..b4717a3d 100644
--- a/src/hb-uniscribe.cc
+++ b/src/hb-uniscribe.cc
@@ -223,11 +223,19 @@ struct hb_uniscribe_shaper_funcs_t {
 };
 static hb_uniscribe_shaper_funcs_t *uniscribe_funcs;
 
+#ifdef HB_USE_ATEXIT
 static inline void
 free_uniscribe_funcs (void)
 {
+retry:
+  hb_uniscribe_shaper_funcs_t *local_uniscribe_funcs =
+    (hb_uniscribe_shaper_funcs_t *) hb_atomic_ptr_get (&uniscribe_funcs);
+  if (!hb_atomic_ptr_cmpexch (&uniscribe_funcs, local_uniscribe_funcs, nullptr))
+    goto retry;
+
   free (uniscribe_funcs);
 }
+#endif
 
 static hb_uniscribe_shaper_funcs_t *
 hb_uniscribe_shaper_get_funcs (void)
commit d3a432a7b272917edb83f8fe8468120beb37206b
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date:   Fri Mar 30 04:58:47 2018 +0430

    [graphite] Make get_table threadsafe (#931)

diff --git a/src/hb-graphite2.cc b/src/hb-graphite2.cc
index 46fe1399..5d95ca57 100644
--- a/src/hb-graphite2.cc
+++ b/src/hb-graphite2.cc
@@ -79,10 +79,12 @@ static const void *hb_graphite2_get_table (const void *data, unsigned int tag, s
     p->blob = blob;
     p->tag = tag;
 
-    /* TODO Not thread-safe, but fairly harmless.
-     * We can do the double-checked pointer cmpexch thing here. */
-    p->next = face_data->tlist;
-    face_data->tlist = p;
+retry:
+    hb_graphite2_tablelist_t *tlist = (hb_graphite2_tablelist_t *) hb_atomic_ptr_get (&face_data->tlist);
+    p->next = tlist;
+
+    if (!hb_atomic_ptr_cmpexch (&face_data->tlist, tlist, p))
+      goto retry;
   }
 
   unsigned int tlen;
diff --git a/src/hb-graphite2.h b/src/hb-graphite2.h
index 82b1e64c..05c55deb 100644
--- a/src/hb-graphite2.h
+++ b/src/hb-graphite2.h
@@ -1,6 +1,6 @@
 /*
- * Copyright (C) 2011  Martin Hosken
- * Copyright (C) 2011  SIL International
+ * Copyright © 2011  Martin Hosken
+ * Copyright © 2011  SIL International
  *
  *  This is part of HarfBuzz, a text shaping library.
  *
commit 80395f14e8873f30d2c9a49e42fc9febf5c87e45
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date:   Thu Mar 29 22:00:41 2018 +0430

    Make gen-* scripts LC_ALL=C compatible (#942)

diff --git a/src/gen-arabic-table.py b/src/gen-arabic-table.py
index fc60ab41..ccecb406 100755
--- a/src/gen-arabic-table.py
+++ b/src/gen-arabic-table.py
@@ -2,14 +2,13 @@
 
 from __future__ import print_function, division, absolute_import
 
-import sys
-import os.path
+import io, os.path, sys
 
 if len (sys.argv) != 4:
 	print ("usage: ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt", file=sys.stderr)
 	sys.exit (1)
 
-files = [open (x) for x in sys.argv[1:]]
+files = [io.open (x, encoding='utf-8') for x in sys.argv[1:]]
 
 headers = [[files[0].readline (), files[0].readline ()], [files[2].readline (), files[2].readline ()]]
 headers.append (["UnicodeData.txt does not have a header."])
diff --git a/src/gen-indic-table.py b/src/gen-indic-table.py
index 1a5d7761..6252664c 100755
--- a/src/gen-indic-table.py
+++ b/src/gen-indic-table.py
@@ -2,7 +2,7 @@
 
 from __future__ import print_function, division, absolute_import
 
-import sys
+import io, sys
 
 if len (sys.argv) != 4:
 	print ("usage: ./gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt", file=sys.stderr)
@@ -32,7 +32,7 @@ ALLOWED_BLOCKS = [
 	'Myanmar Extended-A',
 ]
 
-files = [open (x) for x in sys.argv[1:]]
+files = [io.open (x, encoding='utf-8') for x in sys.argv[1:]]
 
 headers = [[f.readline () for i in range (2)] for f in files]
 
diff --git a/src/gen-use-table.py b/src/gen-use-table.py
index ea88cc33..b3876373 100755
--- a/src/gen-use-table.py
+++ b/src/gen-use-table.py
@@ -2,7 +2,7 @@
 
 from __future__ import print_function, division, absolute_import
 
-import sys
+import io, sys
 
 if len (sys.argv) != 5:
 	print ("usage: ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt", file=sys.stderr)
@@ -10,7 +10,7 @@ if len (sys.argv) != 5:
 
 BLACKLISTED_BLOCKS = ["Thai", "Lao", "Tibetan"]
 
-files = [open (x) for x in sys.argv[1:]]
+files = [io.open (x, encoding='utf-8') for x in sys.argv[1:]]
 
 headers = [[f.readline () for i in range (2)] for j,f in enumerate(files) if j != 2]
 headers.append (["UnicodeData.txt does not have a header."])
commit 26e0cbd834e7a8bab331b395257e9c21dde4c2b1
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date:   Thu Mar 29 21:22:47 2018 +0430

    Actual py3 compatibility making on gen-* scripts (#941)

diff --git a/src/gen-arabic-table.py b/src/gen-arabic-table.py
index a3bd3073..fc60ab41 100755
--- a/src/gen-arabic-table.py
+++ b/src/gen-arabic-table.py
@@ -9,7 +9,7 @@ if len (sys.argv) != 4:
 	print ("usage: ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt", file=sys.stderr)
 	sys.exit (1)
 
-files = [file (x) for x in sys.argv[1:]]
+files = [open (x) for x in sys.argv[1:]]
 
 headers = [[files[0].readline (), files[0].readline ()], [files[2].readline (), files[2].readline ()]]
 headers.append (["UnicodeData.txt does not have a header."])
@@ -229,9 +229,7 @@ def print_shaping_table(f):
 	print (" } ligatures[%d];" % max_i)
 	print ("} ligature_table[] =")
 	print ("{")
-	keys = ligas.keys ()
-	keys.sort ()
-	for first in keys:
+	for first in sorted (ligas.keys ()):
 
 		print ("  { 0x%04Xu, {" % (first))
 		for liga in ligas[first]:
diff --git a/src/gen-indic-table.py b/src/gen-indic-table.py
index 7627be31..1a5d7761 100755
--- a/src/gen-indic-table.py
+++ b/src/gen-indic-table.py
@@ -32,7 +32,7 @@ ALLOWED_BLOCKS = [
 	'Myanmar Extended-A',
 ]
 
-files = [file (x) for x in sys.argv[1:]]
+files = [open (x) for x in sys.argv[1:]]
 
 headers = [[f.readline () for i in range (2)] for f in files]
 
@@ -133,8 +133,7 @@ what = ["INDIC_SYLLABIC_CATEGORY", "INDIC_MATRA_CATEGORY"]
 what_short = ["ISC", "IMC"]
 for i in range (2):
 	print ()
-	vv = values[i].keys ()
-	vv.sort ()
+	vv = sorted (values[i].keys ())
 	for v in vv:
 		v_no_and = v.replace ('_And_', '_')
 		if v in short[i]:
@@ -180,8 +179,7 @@ def print_block (block, start, end, data):
 	if block:
 		last_block = block
 
-uu = data.keys ()
-uu.sort ()
+uu = sorted (data.keys ())
 
 last = -100000
 num = 0
@@ -228,7 +226,7 @@ print ("hb_indic_get_categories (hb_codepoint_t u)")
 print ("{")
 print ("  switch (u >> %d)" % page_bits)
 print ("  {")
-pages = set([u>>page_bits for u in starts+ends+singles.keys()])
+pages = set ([u>>page_bits for u in starts+ends+list (singles.keys ())])
 for p in sorted(pages):
 	print ("    case 0x%0Xu:" % p)
 	for u,d in singles.items ():
@@ -249,8 +247,7 @@ print ()
 print ("#undef _")
 for i in range (2):
 	print
-	vv = values[i].keys ()
-	vv.sort ()
+	vv = sorted (values[i].keys ())
 	for v in vv:
 		print ("#undef %s_%s" %
 			(what_short[i], short[i][v]))
diff --git a/src/gen-use-table.py b/src/gen-use-table.py
index 5726002a..ea88cc33 100755
--- a/src/gen-use-table.py
+++ b/src/gen-use-table.py
@@ -10,7 +10,7 @@ if len (sys.argv) != 5:
 
 BLACKLISTED_BLOCKS = ["Thai", "Lao", "Tibetan"]
 
-files = [file (x) for x in sys.argv[1:]]
+files = [open (x) for x in sys.argv[1:]]
 
 headers = [[f.readline () for i in range (2)] for j,f in enumerate(files) if j != 2]
 headers.append (["UnicodeData.txt does not have a header."])
@@ -126,6 +126,11 @@ property_names = [
 	'Overstruck',
 ]
 
+try:
+	basestring
+except NameError:
+	basestring = str
+
 class PropertyValue(object):
 	def __init__(self, name_):
 		self.name = name_
@@ -135,6 +140,8 @@ class PropertyValue(object):
 		return self.name == (other if isinstance(other, basestring) else other.name)
 	def __ne__(self, other):
 		return not (self == other)
+	def __hash__(self):
+		return hash(str(self))
 
 property_values = {}
 
@@ -398,8 +405,7 @@ def print_block (block, start, end, data):
 	if block:
 		last_block = block
 
-uu = data.keys ()
-uu.sort ()
+uu = sorted (data.keys ())
 
 last = -100000
 num = 0
diff --git a/test/shaping/hb_test_tools.py b/test/shaping/hb_test_tools.py
index de4516ee..8348dc26 100644
--- a/test/shaping/hb_test_tools.py
+++ b/test/shaping/hb_test_tools.py
@@ -514,7 +514,7 @@ class FileHelpers:
 	def open_file_or_stdin (f):
 		if f == '-':
 			return sys.stdin
-		return file (f)
+		return open (f)
 
 
 class Manifest:
@@ -533,7 +533,7 @@ class Manifest:
 		if os.path.isdir (s):
 
 			try:
-				m = file (os.path.join (s, "MANIFEST"))
+				m = open (os.path.join (s, "MANIFEST"))
 				items = [x.strip () for x in m.readlines ()]
 				for f in items:
 					for p in Manifest.read (os.path.join (s, f)):
commit cab2c2c08c67e7d1606c03700df3e4e9c0dc59fd
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date:   Thu Mar 29 12:48:47 2018 +0430

    Make more gen-* scripts py3 compatible (#940)

diff --git a/src/Makefile.am b/src/Makefile.am
index df45f73b..db265e21 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -295,7 +295,7 @@ arabic-table: gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt
 	$(AM_V_GEN) $(builddir)/$^ > hb-ot-shape-complex-arabic-table.hh \
 	|| ($(RM) hb-ot-shape-complex-arabic-table.hh; false)
 
-indic-table: gen-indic-table.py IndicSyllabicCategory-7.0.0.txt IndicMatraCategory-7.0.0.txt Blocks.txt
+indic-table: gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt
 	$(AM_V_GEN) $(builddir)/$^ > hb-ot-shape-complex-indic-table.cc \
 	|| ($(RM) hb-ot-shape-complex-indic-table.cc; false)
 
diff --git a/src/gen-arabic-table.py b/src/gen-arabic-table.py
index 59bd7601..a3bd3073 100755
--- a/src/gen-arabic-table.py
+++ b/src/gen-arabic-table.py
@@ -1,10 +1,12 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+
+from __future__ import print_function, division, absolute_import
 
 import sys
 import os.path
 
 if len (sys.argv) != 4:
-	print >>sys.stderr, "usage: ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt"
+	print ("usage: ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt", file=sys.stderr)
 	sys.exit (1)
 
 files = [file (x) for x in sys.argv[1:]]
@@ -65,9 +67,9 @@ def print_joining_table(f):
 		assert short not in short_value.values()
 		short_value[value] = short
 
-	print
+	print ()
 	for value,short in short_value.items():
-		print "#define %s	%s" % (short, value)
+		print ("#define %s	%s" % (short, value))
 
 	uu = sorted(values.keys())
 	num = len(values)
@@ -82,15 +84,15 @@ def print_joining_table(f):
 			ranges.append([u,u])
 		last = u
 
-	print
-	print "static const uint8_t joining_table[] ="
-	print "{"
+	print ()
+	print ("static const uint8_t joining_table[] =")
+	print ("{")
 	last_block = None
 	offset = 0
 	for start,end in ranges:
 
-		print
-		print "#define joining_offset_0x%04xu %d" % (start, offset)
+		print ()
+		print ("#define joining_offset_0x%04xu %d" % (start, offset))
 
 		for u in range(start, end+1):
 
@@ -99,53 +101,53 @@ def print_joining_table(f):
 
 			if block != last_block or u == start:
 				if u != start:
-					print
+					print ()
 				if block in all_blocks:
-					print "\n  /* %s */" % block
+					print ("\n  /* %s */" % block)
 				else:
-					print "\n  /* FILLER */"
+					print ("\n  /* FILLER */")
 				last_block = block
 				if u % 32 != 0:
-					print
-					print "  /* %04X */" % (u//32*32), "  " * (u % 32),
+					print ()
+					print ("  /* %04X */" % (u//32*32), "  " * (u % 32), end="")
 
 			if u % 32 == 0:
-				print
-				print "  /* %04X */ " % u,
-			sys.stdout.write("%s," % short_value[value])
-		print
+				print ()
+				print ("  /* %04X */ " % u, end="")
+			print ("%s," % short_value[value], end="")
+		print ()
 
 		offset += end - start + 1
-	print
+	print ()
 	occupancy = num * 100. / offset
-	print "}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy)
-	print
+	print ("}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy))
+	print ()
 
 	page_bits = 12;
-	print
-	print "static unsigned int"
-	print "joining_type (hb_codepoint_t u)"
-	print "{"
-	print "  switch (u >> %d)" % page_bits
-	print "  {"
+	print ()
+	print ("static unsigned int")
+	print ("joining_type (hb_codepoint_t u)")
+	print ("{")
+	print ("  switch (u >> %d)" % page_bits)
+	print ("  {")
 	pages = set([u>>page_bits for u in [s for s,e in ranges]+[e for s,e in ranges]])
 	for p in sorted(pages):
-		print "    case 0x%0Xu:" % p
+		print ("    case 0x%0Xu:" % p)
 		for (start,end) in ranges:
 			if p not in [start>>page_bits, end>>page_bits]: continue
 			offset = "joining_offset_0x%04xu" % start
-			print "      if (hb_in_range<hb_codepoint_t> (u, 0x%04Xu, 0x%04Xu)) return joining_table[u - 0x%04Xu + %s];" % (start, end, start, offset)
-		print "      break;"
-		print ""
-	print "    default:"
-	print "      break;"
-	print "  }"
-	print "  return X;"
-	print "}"
-	print
+			print ("      if (hb_in_range<hb_codepoint_t> (u, 0x%04Xu, 0x%04Xu)) return joining_table[u - 0x%04Xu + %s];" % (start, end, start, offset))
+		print ("      break;")
+		print ("")
+	print ("    default:")
+	print ("      break;")
+	print ("  }")
+	print ("  return X;")
+	print ("}")
+	print ()
 	for value,short in short_value.items():
-		print "#undef %s" % (short)
-	print
+		print ("#undef %s" % (short))
+	print ()
 
 def print_shaping_table(f):
 
@@ -186,9 +188,9 @@ def print_shaping_table(f):
 				shapes[items[0]] = {}
 			shapes[items[0]][shape] = c
 
-	print
-	print "static const uint16_t shaping_table[][4] ="
-	print "{"
+	print ()
+	print ("static const uint16_t shaping_table[][4] =")
+	print ("{")
 
 	keys = shapes.keys ()
 	min_u, max_u = min (keys), max (keys)
@@ -196,13 +198,13 @@ def print_shaping_table(f):
 		s = [shapes[u][shape] if u in shapes and shape in shapes[u] else 0
 		     for shape in  ['initial', 'medial', 'final', 'isolated']]
 		value = ', '.join ("0x%04Xu" % c for c in s)
-		print "  {%s}, /* U+%04X %s */" % (value, u, names[u] if u in names else "")
+		print ("  {%s}, /* U+%04X %s */" % (value, u, names[u] if u in names else ""))
 
-	print "};"
-	print
-	print "#define SHAPING_TABLE_FIRST	0x%04Xu" % min_u
-	print "#define SHAPING_TABLE_LAST	0x%04Xu" % max_u
-	print
+	print ("};")
+	print ()
+	print ("#define SHAPING_TABLE_FIRST	0x%04Xu" % min_u)
+	print ("#define SHAPING_TABLE_LAST	0x%04Xu" % max_u)
+	print ()
 
 	ligas = {}
 	for pair in ligatures.keys ():
@@ -218,52 +220,51 @@ def print_shaping_table(f):
 				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 ligature_set_t {"
-	print " uint16_t first;"
-	print " struct ligature_pairs_t {"
-	print "   uint16_t second;"
-	print "   uint16_t ligature;"
-	print " } ligatures[%d];" % max_i
-	print "} ligature_table[] ="
-	print "{"
+	print ()
+	print ("static const struct ligature_set_t {")
+	print (" uint16_t first;")
+	print (" struct ligature_pairs_t {")
+	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%04Xu, {" % (first)
+		print ("  { 0x%04Xu, {" % (first))
 		for liga in ligas[first]:
-			print "    { 0x%04Xu, 0x%04Xu }, /* %s */" % (liga[0], liga[1], names[liga[1]])
-		print "  }},"
+			print ("    { 0x%04Xu, 0x%04Xu }, /* %s */" % (liga[0], liga[1], names[liga[1]]))
+		print ("  }},")
 
-	print "};"
-	print
+	print ("};")
+	print ()
 
 
 
-print "/* == Start of generated table == */"
-print "/*"
-print " * The following table is generated by running:"
-print " *"
-print " *   ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt"
-print " *"
-print " * on files with these headers:"
-print " *"
+print ("/* == Start of generated table == */")
+print ("/*")
+print (" * The following table is generated by running:")
+print (" *")
+print (" *   ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt")
+print (" *")
+print (" * on files with these headers:")
+print (" *")
 for h in headers:
 	for l in h:
-		print " * %s" % (l.strip())
-print " */"
-print
-print "#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH"
-print "#define HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH"
-print
+		print (" * %s" % (l.strip()))
+print (" */")
+print ()
+print ("#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH")
+print ("#define HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH")
+print ()
 
 read_blocks (files[2])
 print_joining_table (files[0])
 print_shaping_table (files[1])
 
-print
-print "#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH */"
-print
-print "/* == End of generated table == */"
-
+print ()
+print ("#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH */")
+print ()
+print ("/* == End of generated table == */")
diff --git a/src/gen-def.py b/src/gen-def.py
index de35eb7d..9a997d65 100755
--- a/src/gen-def.py
+++ b/src/gen-def.py
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 
-from __future__ import print_function
+from __future__ import print_function, division, absolute_import
 
 import io, os, re, sys
 
diff --git a/src/gen-indic-table.py b/src/gen-indic-table.py
index 735b9015..7627be31 100755
--- a/src/gen-indic-table.py
+++ b/src/gen-indic-table.py
@@ -1,9 +1,11 @@
-#!/usr/bin/python
+#!/usr/bin/env python
+
+from __future__ import print_function, division, absolute_import
 
 import sys
 
 if len (sys.argv) != 4:
-	print >>sys.stderr, "usage: ./gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt"
+	print ("usage: ./gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt", file=sys.stderr)
 	sys.exit (1)
 
 ALLOWED_SINGLES = [0x00A0, 0x25CC]
@@ -87,21 +89,21 @@ for u in ALLOWED_SINGLES:
 	singles[u] = data[u]
 	del data[u]
 
-print "/* == Start of generated table == */"
-print "/*"
-print " * The following table is generated by running:"
-print " *"
-print " *   ./gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt"
-print " *"
-print " * on files with these headers:"
-print " *"
+print ("/* == Start of generated table == */")
+print ("/*")
+print (" * The following table is generated by running:")
+print (" *")
+print (" *   ./gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt")
+print (" *")
+print (" * on files with these headers:")
+print (" *")
 for h in headers:
 	for l in h:
-		print " * %s" % (l.strip())
-print " */"
-print
-print '#include "hb-ot-shape-complex-indic-private.hh"'
-print
+		print (" * %s" % (l.strip()))
+print (" */")
+print ()
+print ('#include "hb-ot-shape-complex-indic-private.hh"')
+print ()
 
 # Shorten values
 short = [{
@@ -130,7 +132,7 @@ for i in range (2):
 what = ["INDIC_SYLLABIC_CATEGORY", "INDIC_MATRA_CATEGORY"]
 what_short = ["ISC", "IMC"]
 for i in range (2):
-	print
+	print ()
 	vv = values[i].keys ()
 	vv.sort ()
 	for v in vv:
@@ -143,14 +145,14 @@ for i in range (2):
 				raise Exception ("Duplicate short value alias", v, all_shorts[i][s])
 			all_shorts[i][s] = v
 			short[i][v] = s
-		print "#define %s_%s	%s_%s	%s/* %3d chars; %s */" % \
-			(what_short[i], s, what[i], v.upper (), \
-			'	'* ((48-1 - len (what[i]) - 1 - len (v)) / 8), \
-			values[i][v], v)
-print
-print "#define _(S,M) INDIC_COMBINE_CATEGORIES (ISC_##S, IMC_##M)"
-print
-print
+		print ("#define %s_%s	%s_%s	%s/* %3d chars; %s */" %
+			(what_short[i], s, what[i], v.upper (),
+			'	'* ((48-1 - len (what[i]) - 1 - len (v)) // 8),
+			values[i][v], v))
+print ()
+print ("#define _(S,M) INDIC_COMBINE_CATEGORIES (ISC_##S, IMC_##M)")
+print ()
+print ()
 
 total = 0
 used = 0
@@ -158,20 +160,20 @@ last_block = None
 def print_block (block, start, end, data):
 	global total, used, last_block
 	if block and block != last_block:
-		print
-		print
-		print "  /* %s */" % block
+		print ()
+		print ()
+		print ("  /* %s */" % block)
 	num = 0
 	assert start % 8 == 0
 	assert (end+1) % 8 == 0
 	for u in range (start, end+1):
 		if u % 8 == 0:
-			print
-			print "  /* %04X */" % u,
+			print ()
+			print ("  /* %04X */" % u, end="")
 		if u in data:
 			num += 1
 		d = data.get (u, defaults)
-		sys.stdout.write ("%9s" % ("_(%s,%s)," % (short[0][d[0]], short[1][d[1]])))
+		print ("%9s" % ("_(%s,%s)," % (short[0][d[0]], short[1][d[1]])), end="")
 
 	total += end - start + 1
 	used += num
@@ -186,7 +188,7 @@ num = 0
 offset = 0
 starts = []
 ends = []
-print "static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {"
+print ("static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {")
 for u in uu:
 	if u <= last:
 		continue
@@ -206,54 +208,54 @@ for u in uu:
 			if last >= 0:
 				ends.append (last + 1)
 				offset += ends[-1] - starts[-1]
-			print
-			print
-			print "#define indic_offset_0x%04xu %d" % (start, offset)
+			print ()
+			print ()
+			print ("#define indic_offset_0x%04xu %d" % (start, offset))
 			starts.append (start)
 
 	print_block (block, start, end, data)
 	last = end
 ends.append (last + 1)
 offset += ends[-1] - starts[-1]
-print
-print
+print ()
+print ()
 occupancy = used * 100. / total
 page_bits = 12
-print "}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy)
-print
-print "INDIC_TABLE_ELEMENT_TYPE"
-print "hb_indic_get_categories (hb_codepoint_t u)"
-print "{"
-print "  switch (u >> %d)" % page_bits
-print "  {"
+print ("}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy))
+print ()
+print ("INDIC_TABLE_ELEMENT_TYPE")
+print ("hb_indic_get_categories (hb_codepoint_t u)")
+print ("{")
+print ("  switch (u >> %d)" % page_bits)
+print ("  {")
 pages = set([u>>page_bits for u in starts+ends+singles.keys()])
 for p in sorted(pages):
-	print "    case 0x%0Xu:" % p
+	print ("    case 0x%0Xu:" % p)
 	for u,d in singles.items ():
 		if p != u>>page_bits: continue
-		print "      if (unlikely (u == 0x%04Xu)) return _(%s,%s);" % (u, short[0][d[0]], short[1][d[1]])
+		print ("      if (unlikely (u == 0x%04Xu)) return _(%s,%s);" % (u, short[0][d[0]], short[1][d[1]]))
 	for (start,end) in zip (starts, ends):
 		if p not in [start>>page_bits, end>>page_bits]: continue
 		offset = "indic_offset_0x%04xu" % start
-		print "      if (hb_in_range<hb_codepoint_t> (u, 0x%04Xu, 0x%04Xu)) return indic_table[u - 0x%04Xu + %s];" % (start, end-1, start, offset)
-	print "      break;"
-	print ""
-print "    default:"
-print "      break;"
-print "  }"
-print "  return _(x,x);"
-print "}"
-print
-print "#undef _"
+		print ("      if (hb_in_range<hb_codepoint_t> (u, 0x%04Xu, 0x%04Xu)) return indic_table[u - 0x%04Xu + %s];" % (start, end-1, start, offset))
+	print ("      break;")
+	print ("")
+print ("    default:")
+print ("      break;")
+print ("  }")
+print ("  return _(x,x);")
+print ("}")
+print ()
+print ("#undef _")
 for i in range (2):
 	print
 	vv = values[i].keys ()
 	vv.sort ()
 	for v in vv:
-		print "#undef %s_%s" % \
-			(what_short[i], short[i][v])
-print
-print "/* == End of generated table == */"
+		print ("#undef %s_%s" %
+			(what_short[i], short[i][v]))
+print ()
+print ("/* == End of generated table == */")
 
 # Maintain at least 30% occupancy in the table */
 if occupancy < 30:
diff --git a/src/gen-unicode-ranges.py b/src/gen-unicode-ranges.py
index 3b59cd86..30249a8f 100644
--- a/src/gen-unicode-ranges.py
+++ b/src/gen-unicode-ranges.py
@@ -4,6 +4,8 @@
 # Input is a tab seperated list of unicode ranges from the otspec
 # (https://docs.microsoft.com/en-us/typography/opentype/spec/os2#ulunicoderange1).
 
+from __future__ import print_function, division, absolute_import
+
 import io
 import re
 import sys
@@ -11,7 +13,7 @@ import sys
 reload(sys)
 sys.setdefaultencoding('utf-8')
 
-print (u"""static Range os2UnicodeRangesSorted[] =
+print ("""static Range os2UnicodeRangesSorted[] =
 {""")
 
 args = sys.argv[1:]
@@ -47,6 +49,6 @@ for ranges in all_ranges:
   end = ("0x%X" % ranges[1]).rjust(8)
   bit = ("%s" % ranges[2]).rjust(3)
 
-  print "  {%s, %s, %s}, // %s" % (start, end, bit, ranges[3])
+  print ("  {%s, %s, %s}, // %s" % (start, end, bit, ranges[3]))
 
-print (u"""};""");
+print ("""};""")
diff --git a/src/gen-use-table.py b/src/gen-use-table.py
index ecbdfb95..5726002a 100755
--- a/src/gen-use-table.py
+++ b/src/gen-use-table.py
@@ -1,6 +1,7 @@
 #!/usr/bin/env python
 
-from __future__ import print_function
+from __future__ import print_function, division, absolute_import
+
 import sys
 
 if len (sys.argv) != 5:
diff --git a/src/hb-ot-shape-complex-indic-table.cc b/src/hb-ot-shape-complex-indic-table.cc
index 867cfb33..5817b834 100644
--- a/src/hb-ot-shape-complex-indic-table.cc
+++ b/src/hb-ot-shape-complex-indic-table.cc
@@ -430,7 +430,6 @@ hb_indic_get_categories (hb_codepoint_t u)
 }
 
 #undef _
-
 #undef ISC_A
 #undef ISC_Bi
 #undef ISC_BJN
@@ -466,7 +465,6 @@ hb_indic_get_categories (hb_codepoint_t u)
 #undef ISC_Vo
 #undef ISC_M
 #undef ISC_VI
-
 #undef IMC_B
 #undef IMC_BL
 #undef IMC_BR
diff --git a/src/sample.py b/src/sample.py
index 844fa4c8..8f97195f 100755
--- a/src/sample.py
+++ b/src/sample.py
@@ -1,7 +1,8 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 # -*- coding: utf-8 -*-
 
-from __future__ import print_function
+from __future__ import print_function, division, absolute_import
+
 import sys
 import array
 from gi.repository import HarfBuzz as hb
diff --git a/test/fuzzing/run-shape-fuzzer-tests.py b/test/fuzzing/run-shape-fuzzer-tests.py
index 43378d1b..fea0b01b 100755
--- a/test/fuzzing/run-shape-fuzzer-tests.py
+++ b/test/fuzzing/run-shape-fuzzer-tests.py
@@ -1,6 +1,7 @@
 #!/usr/bin/env python
 
-from __future__ import print_function
+from __future__ import print_function, division, absolute_import
+
 import sys, os, subprocess
 
 srcdir = os.environ.get ("srcdir", ".")
diff --git a/test/fuzzing/run-subset-fuzzer-tests.py b/test/fuzzing/run-subset-fuzzer-tests.py
index 229881a4..23575231 100755
--- a/test/fuzzing/run-subset-fuzzer-tests.py
+++ b/test/fuzzing/run-subset-fuzzer-tests.py
@@ -1,6 +1,7 @@
 #!/usr/bin/env python
 
-from __future__ import print_function
+from __future__ import print_function, division, absolute_import
+
 import sys, os, subprocess
 
 srcdir = os.environ.get ("srcdir", ".")
diff --git a/test/shaping/data/text-rendering-tests/extract-tests.py b/test/shaping/data/text-rendering-tests/extract-tests.py
index 8e5909fa..36963e5e 100755
--- a/test/shaping/data/text-rendering-tests/extract-tests.py
+++ b/test/shaping/data/text-rendering-tests/extract-tests.py
@@ -1,6 +1,7 @@
 #!/usr/bin/env python
 
-from __future__ import print_function
+from __future__ import print_function, division, absolute_import
+
 import sys
 import xml.etree.ElementTree as ET
 
diff --git a/test/shaping/hb_test_tools.py b/test/shaping/hb_test_tools.py
index f7e59434..de4516ee 100644
--- a/test/shaping/hb_test_tools.py
+++ b/test/shaping/hb_test_tools.py
@@ -1,6 +1,7 @@
 #!/usr/bin/env python
 
-from __future__ import print_function
+from __future__ import print_function, division, absolute_import
+
 import sys, os, re, difflib, unicodedata, errno, cgi
 from itertools import *
 
diff --git a/test/shaping/run-tests.py b/test/shaping/run-tests.py
index c65e7142..73b61c21 100755
--- a/test/shaping/run-tests.py
+++ b/test/shaping/run-tests.py
@@ -1,6 +1,7 @@
 #!/usr/bin/env python
 
-from __future__ import print_function
+from __future__ import print_function, division, absolute_import
+
 import sys, os, subprocess
 
 
diff --git a/test/subset/run-tests.py b/test/subset/run-tests.py
index 6d28b24d..0b119fee 100755
--- a/test/subset/run-tests.py
+++ b/test/subset/run-tests.py
@@ -3,7 +3,7 @@
 # Runs a subsetting test suite. Compares the results of subsetting via harfbuz
 # to subsetting via fonttools.
 
-from __future__ import print_function
+from __future__ import print_function, division, absolute_import
 
 import io
 from difflib import unified_diff
commit 5f7f0bfa1ecef6406cb9670b4eb057ea12c28730
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date:   Thu Mar 29 04:22:53 2018 +0430

    Add README.wine.md and touch some other docs (#939)

diff --git a/Makefile.am b/Makefile.am
index fde52564..eb46ceaa 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -9,7 +9,8 @@ SUBDIRS = src util test docs
 EXTRA_DIST = \
 	autogen.sh \
 	harfbuzz.doap \
-	README.python \
+	README.python.md \
+	README.wine.md \
 	BUILD.md \
 	RELEASING.md \
 	CMakeLists.txt \
diff --git a/README.python b/README.python.md
similarity index 83%
rename from README.python
rename to README.python.md
index cd312649..4c0ba9b2 100644
--- a/README.python
+++ b/README.python.md
@@ -2,11 +2,15 @@ To enable HarfBuzz bindings for Python among other languages, make sure
 you have latest version of gobject-introspection available.  On Ubuntu,
 you can install that this way:
 
-  sudo apt-get install libgirepository1.0-dev
+```bash
+sudo apt-get install libgirepository1.0-dev
+```
 
 And then run autogen.sh (if building from git), and then:
 
-  ./configure --with-gobject --enable-introspection
+```bash
+./configure --with-gobject --enable-introspection
+```
 
 Make sure that gobject-introspection is enabled then in the final report.
 
@@ -21,7 +25,9 @@ $prefix/lib/girepository-* directory.
 Make sure you have pygobject installed.  Then check that the following
 import works in your Python interpretter:
 
-  from gi.repository import HarfBuzz
+```python
+from gi.repository import HarfBuzz
+```
 
 If it does, you are ready to call HarfBuzz from Python!  Congratulations.
 See src/sample.py.
diff --git a/README.wine.md b/README.wine.md
new file mode 100644
index 00000000..851d2bf3
--- /dev/null
+++ b/README.wine.md
@@ -0,0 +1,40 @@
+For the development of HarfBuzz, the Microsoft shaping technology, Uniscribe,
+as a widely used and tested shaper is used as more-or-less OpenType reference
+implemenetation and that specially is important where OpenType specification
+is or wasn't that clear. For having access to Uniscribe on Linux/macOS these
+steps are recommended:
+
+1. Install Wine from your favorite package manager.
+
+2. And `mingw-w64` compiler.
+   With `brew` on macOS, you can have it like `brew install mingw-w64`
+
+3. Download and put [this](https://drive.google.com/open?id=0B3_fQkxDZZXXbWltRGd5bjVrUDQ)
+   on your `~/.local/i686-w64-mingw32`.
+
+4. Replace all the instances of `/home/behdad/.local/i586-mingw32msvc`
+   and `/home/behdad/.local/i686-w64-mingw32` with `<$HOME>/.local/i686-w64-mingw32`
+   on that folder. (`<$HOME>` replace it with `/home/XXX` or `/Users/XXX` on macOS)
+
+   Probably you shouldn't replace the ones are inside binaries.
+
+5. `NOCONFIGURE=1 ./autogen.sh && mkdir winbuild && cd winbuild`
+
+6. `../mingw32.sh --with-uniscribe && cd ..`
+
+7. `make -Cwinbuild`
+
+Now you can use hb-shape using `wine winbuild/util/hb-shape.exe` but if you like to
+to use the original Uniscribe,
+
+8. Bring a 32bit version of `usp10.dll` for youself from `C:\Windows\SysWOW64\usp10.dll` of your
+   Windows installation (asuming you have a 64-bit installation, otherwise `C:\Windows\System32\usp10.dll`)
+   that it is not a DirectWrite proxy ([for more info](https://en.wikipedia.org/wiki/Uniscribe)).
+   Rule of thumb, your `usp10.dll` should have a size more than 500kb, otherwise
+   it is designed to work with DirectWrite which Wine can't work with its original one.
+
+   Put the dll on the folder you are going to run the next command,
+
+9. `WINEDLLOVERRIDES="usp10=n" wine winbuild/util/hb-shape.exe fontname.ttf -u 0061,0062,0063 --shaper=uniscribe`
+
+(`0061,0062,0063` means `abc`, use test/shaping/hb-unicode-decode to generate ones you need)
diff --git a/RELEASING.md b/RELEASING.md
index dedcca8f..19456f1e 100644
--- a/RELEASING.md
+++ b/RELEASING.md
@@ -15,23 +15,26 @@ HarfBuzz release walk-through checklist:
 2. Based on severity of changes, decide whether it's a minor or micro release
    number bump,
 
-3. Make sure you have correct date and new version at the top of NEWS file,
+3. Search for REPLACEME on the repository and replace it with the chosen version
+   for the release.
 
-4. Bump version in configure.ac line 3,
+4. Make sure you have correct date and new version at the top of NEWS file,
 
-5. Do "make distcheck", if it passes, you get a tarball.
+5. Bump version in configure.ac line 3,
+
+6. Do "make distcheck", if it passes, you get a tarball.
    Otherwise, fix things and commit them separately before making release,
 
-6. "make release-files".  Enter your GPG password.  This creates a sha256 hash
+7. "make release-files".  Enter your GPG password.  This creates a sha256 hash
    and signs it.
 
-7. Now that you have release files built, commit NEWS and configure.ac changes.
+8. Now that you have release files built, commit NEWS and configure.ac changes.
    The commit message is simply the release number.  Eg. "1.4.7"
 
-8. Tag the release and sign it: Eg. "git tag -s 1.4.7 -m 1.4.7".  Enter your
+9. Tag the release and sign it: Eg. "git tag -s 1.4.7 -m 1.4.7".  Enter your
    GPG password again.
 
-9. Build win32 bundle.
+10. Build win32 bundle.
 
    a. Put contents of [this](https://drive.google.com/open?id=0B3_fQkxDZZXXbWltRGd5bjVrUDQ) on your `~/.local/i686-w64-mingw32`,
 
@@ -41,7 +44,7 @@ HarfBuzz release walk-through checklist:
 
    d. Back in the parent directory, run `./UPDATE.sh` (available below) to build win32 bundle.
 
-10. Copy all artefacts to users.freedesktop.org and move them into
+11. Copy all artefacts to users.freedesktop.org and move them into
     `/srv/www.freedesktop.org/www/software/harfbuzz/release` There should be four
     files.  Eg.:
  ```
@@ -51,15 +54,15 @@ HarfBuzz release walk-through checklist:
 -rw-r--r--  1 behdad eng 2895619 Jul 18 11:34 harfbuzz-1.4.7-win32.zip
 ```
 
-11. While doing that, quickly double-check the size of the .tar.bz2 and .zip
+12. While doing that, quickly double-check the size of the .tar.bz2 and .zip
     files against their previous releases to make sure nothing bad happened.
     They should be in the ballpark, perhaps slightly larger.  Sometimes they
     do shrink, that's not by itself a stopper.
 
-12. Push the commit and tag out: "git push --follow-tags".  Make sure it's
+13. Push the commit and tag out: "git push --follow-tags".  Make sure it's
     pushed both to freedesktop repo and github.
 
-13. Go to GitHub release page [here](https://github.com/harfbuzz/harfbuzz/releases),
+14. Go to GitHub release page [here](https://github.com/harfbuzz/harfbuzz/releases),
     edit the tag, upload artefacts and NEWS entry and save.
 
 


More information about the HarfBuzz mailing list