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

Behdad Esfahbod behdad at kemper.freedesktop.org
Fri Apr 10 12:21:10 PDT 2015


 configure.ac           |   19 ++++
 src/hb-face.cc         |    4 
 src/hb-font.cc         |    4 
 src/hb-shape-plan.cc   |    7 +
 test/api/test-font.c   |   10 +-
 test/api/test-object.c |   34 +++----
 util/Makefile.am       |   15 +++
 util/hb-fc-list.c      |  222 +++++++++++++++++++++++++++++++++++++++++++++++++
 util/hb-fc.cc          |  149 ++++++++++++++++++++++++++++++++
 util/hb-fc.h           |   46 ++++++++++
 10 files changed, 481 insertions(+), 29 deletions(-)

New commits:
commit 1086f21e546e2435d9da6024fd6afa7a36ba3707
Merge: 125cb08 fe97b65
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Apr 10 12:21:04 2015 -0700

    Merge branch 'hb-fc'

commit fe97b65a54a416229e28b1c931e5e01ca19f31d3
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Aug 6 16:49:51 2014 -0400

    [utils] Add hb-fc-list
    
    This is a tool that lists all fonts that can render a given string.
    It uses hb_shape() to do so, and as such is aware of HarfBuzz's
    normalizer.

diff --git a/configure.ac b/configure.ac
index 5baad1f..965a06c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -235,6 +235,24 @@ AM_CONDITIONAL(HAVE_CAIRO_FT, $have_cairo_ft)
 
 dnl ==========================================================================
 
+AC_ARG_WITH(fontconfig,
+	[AS_HELP_STRING([--with-fontconfig=@<:@yes/no/auto@:>@],
+			[Use fontconfig @<:@default=auto@:>@])],,
+	[with_fontconfig=auto])
+have_fontconfig=false
+if test "x$with_fontconfig" = "xyes" -o "x$with_fontconfig" = "xauto"; then
+	PKG_CHECK_MODULES(FONTCONFIG, fontconfig, have_fontconfig=true, :)
+fi
+if test "x$with_fontconfig" = "xyes" -a "x$have_fontconfig" != "xtrue"; then
+	AC_MSG_ERROR([fontconfig support requested but not found])
+fi
+if $have_fontconfig; then
+	AC_DEFINE(HAVE_FONTCONFIG, 1, [Have fontconfig library])
+fi
+AM_CONDITIONAL(HAVE_FONTCONFIG, $have_fontconfig)
+
+dnl ==========================================================================
+
 AC_ARG_WITH(icu,
 	[AS_HELP_STRING([--with-icu=@<:@yes/no/auto@:>@],
 			[Use ICU @<:@default=auto@:>@])],,
@@ -438,6 +456,7 @@ Font callbacks (the more the better):
 
 Tools used for command-line utilities:
 	Cairo:			${have_cairo}
+	Fontconfig:		${have_fontconfig}
 
 Additional shapers (the more the better):
 	Graphite2:		${have_graphite2}
diff --git a/util/Makefile.am b/util/Makefile.am
index 3f23bab..c179d7b 100644
--- a/util/Makefile.am
+++ b/util/Makefile.am
@@ -76,4 +76,19 @@ endif # HAVE_OT
 
 endif # HAVE_GLIB
 
+if HAVE_OT
+if HAVE_FONTCONFIG
+hb_fc_list_SOURCES = \
+	hb-fc.cc \
+	hb-fc.h \
+	hb-fc-list.c \
+	$(NULL)
+hb_fc_list_LDADD = \
+	$(LDADD) \
+	$(FONTCONFIG_LIBS) \
+	$(NULL)
+bin_PROGRAMS += hb-fc-list
+endif # HAVE_FONTCONFIG
+endif # HAVE_OT
+
 -include $(top_srcdir)/git.mk
diff --git a/util/hb-fc-list.c b/util/hb-fc-list.c
new file mode 100644
index 0000000..573d11e
--- /dev/null
+++ b/util/hb-fc-list.c
@@ -0,0 +1,222 @@
+/*
+ * Copyright © 2002 Keith Packard
+ * Copyright © 2014  Google, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the author(s) not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  The authors make no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#define HAVE_GETOPT_LONG 1 /* XXX */
+
+#include "hb-fc.h"
+
+#include <fontconfig/fontconfig.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#else
+#ifdef linux
+#define HAVE_GETOPT_LONG 1
+#endif
+#define HAVE_GETOPT 1
+#endif
+
+#ifndef HAVE_GETOPT
+#define HAVE_GETOPT 0
+#endif
+#ifndef HAVE_GETOPT_LONG
+#define HAVE_GETOPT_LONG 0
+#endif
+
+#if HAVE_GETOPT_LONG
+#undef  _GNU_SOURCE
+#define _GNU_SOURCE
+#include <getopt.h>
+const struct option longopts[] = {
+    {"verbose", 0, 0, 'v'},
+    {"format", 1, 0, 'f'},
+    {"quiet", 0, 0, 'q'},
+    {"version", 0, 0, 'V'},
+    {"help", 0, 0, 'h'},
+    {NULL,0,0,0},
+};
+#else
+#if HAVE_GETOPT
+extern char *optarg;
+extern int optind, opterr, optopt;
+#endif
+#endif
+
+static void
+usage (char *program, int error)
+{
+    FILE *file = error ? stderr : stdout;
+#if HAVE_GETOPT_LONG
+    fprintf (file, "usage: %s [-vqVh] [-f FORMAT] [--verbose] [--format=FORMAT] [--quiet] [--version] [--help] text [pattern] {element ...} \n",
+	     program);
+#else
+    fprintf (file, "usage: %s [-vqVh] [-f FORMAT] text [pattern] {element ...} \n",
+	     program);
+#endif
+    fprintf (file, "List fonts matching [pattern] that can render [text]\n");
+    fprintf (file, "\n");
+#if HAVE_GETOPT_LONG
+    fprintf (file, "  -v, --verbose        display entire font pattern verbosely\n");
+    fprintf (file, "  -f, --format=FORMAT  use the given output format\n");
+    fprintf (file, "  -q, --quiet          suppress all normal output, exit 1 if no fonts matched\n");
+    fprintf (file, "  -V, --version        display font config version and exit\n");
+    fprintf (file, "  -h, --help           display this help and exit\n");
+#else
+    fprintf (file, "  -v         (verbose) display entire font pattern verbosely\n");
+    fprintf (file, "  -f FORMAT  (format)  use the given output format\n");
+    fprintf (file, "  -q,        (quiet)   suppress all normal output, exit 1 if no fonts matched\n");
+    fprintf (file, "  -V         (version) display HarfBuzz version and exit\n");
+    fprintf (file, "  -h         (help)    display this help and exit\n");
+#endif
+    exit (error);
+}
+
+int
+main (int argc, char **argv)
+{
+    int			verbose = 0;
+    int			quiet = 0;
+    const FcChar8	*format = NULL;
+    int			nfont = 0;
+    int			i;
+    FcObjectSet		*os = 0;
+    FcFontSet		*fs;
+    FcPattern		*pat;
+    const char		*text;
+#if HAVE_GETOPT_LONG || HAVE_GETOPT
+    int			c;
+
+#if HAVE_GETOPT_LONG
+    while ((c = getopt_long (argc, argv, "vf:qVh", longopts, NULL)) != -1)
+#else
+    while ((c = getopt (argc, argv, "vf:qVh")) != -1)
+#endif
+    {
+	switch (c) {
+	case 'v':
+	    verbose = 1;
+	    break;
+	case 'f':
+	    format = (FcChar8 *) strdup (optarg);
+	    break;
+	case 'q':
+	    quiet = 1;
+	    break;
+	case 'V':
+	    fprintf (stderr, "fontconfig version %d.%d.%d\n",
+		     FC_MAJOR, FC_MINOR, FC_REVISION);
+	    exit (0);
+	case 'h':
+	    usage (argv[0], 0);
+	default:
+	    usage (argv[0], 1);
+	}
+    }
+    i = optind;
+#else
+    i = 1;
+#endif
+
+    if (!argv[i])
+	usage (argv[0], 1);
+
+    text = argv[i];
+    i++;
+
+    if (argv[i])
+    {
+	pat = FcNameParse ((FcChar8 *) argv[i]);
+	if (!pat)
+	{
+	    fputs ("Unable to parse the pattern\n", stderr);
+	    return 1;
+	}
+	while (argv[++i])
+	{
+	    if (!os)
+		os = FcObjectSetCreate ();
+	    FcObjectSetAdd (os, argv[i]);
+	}
+    }
+    else
+	pat = FcPatternCreate ();
+    if (quiet && !os)
+	os = FcObjectSetCreate ();
+    if (!verbose && !format && !os)
+	os = FcObjectSetBuild (FC_FAMILY, FC_STYLE, FC_FILE, (char *) 0);
+    FcObjectSetAdd (os, FC_CHARSET);
+    if (!format)
+        format = (const FcChar8 *) "%{=fclist}\n";
+    fs = FcFontList (0, pat, os);
+    if (os)
+	FcObjectSetDestroy (os);
+    if (pat)
+	FcPatternDestroy (pat);
+
+    if (!quiet && fs)
+    {
+	int	j;
+
+	for (j = 0; j < fs->nfont; j++)
+	{
+	    hb_font_t *font = hb_fc_font_create (fs->fonts[j]);
+	    hb_bool_t can_render = hb_fc_can_render (font, text);
+	    hb_font_destroy (font);
+
+	    if (!can_render)
+		continue;
+
+	    FcPatternDel (fs->fonts[j], FC_CHARSET);
+
+	    if (verbose)
+	    {
+		FcPatternPrint (fs->fonts[j]);
+	    }
+	    else
+	    {
+	        FcChar8 *s;
+
+		s = FcPatternFormat (fs->fonts[j], format);
+		if (s)
+		{
+		    printf ("%s", s);
+		    FcStrFree (s);
+		}
+	    }
+	}
+    }
+
+    if (fs) {
+	nfont = fs->nfont;
+	FcFontSetDestroy (fs);
+    }
+
+    FcFini ();
+
+    return quiet ? (nfont == 0 ? 1 : 0) : 0;
+}
diff --git a/util/hb-fc.cc b/util/hb-fc.cc
new file mode 100644
index 0000000..e99b1ae
--- /dev/null
+++ b/util/hb-fc.cc
@@ -0,0 +1,149 @@
+/*
+ * Copyright © 2014  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "hb-fc.h"
+
+static hb_bool_t
+hb_fc_get_glyph (hb_font_t *font /*HB_UNUSED*/,
+		 void *font_data,
+		 hb_codepoint_t unicode,
+		 hb_codepoint_t variation_selector,
+		 hb_codepoint_t *glyph,
+		 void *user_data /*HB_UNUSED*/)
+
+{
+  FcCharSet *cs = (FcCharSet *) font_data;
+
+  if (variation_selector)
+  {
+    /* Fontconfig doesn't cache cmap-14 info.  However:
+     * 1. If the font maps the variation_selector, assume it's
+     *    supported,
+     * 2. If the font doesn't map it, still say it's supported,
+     *    but return 0.  This way, the caller will see the zero
+     *    and reject.  If we return unsupported here, then the
+     *    variation selector will be hidden and ignored.
+     */
+    if (FcCharSetHasChar (cs, unicode) &&
+	FcCharSetHasChar (cs, variation_selector))
+    {
+      unsigned int var_num = 0;
+      if (variation_selector - 0xFE00u < 16)
+        var_num = variation_selector - 0xFE00 + 1;
+      else if (variation_selector - 0xE0100u < (256 - 16))
+        var_num = variation_selector - 0xE0100 + 17;
+      *glyph = (var_num << 21) | unicode;
+    }
+    else
+    {
+      *glyph = 0;
+    }
+    return true;
+  }
+
+  *glyph = FcCharSetHasChar (cs, unicode) ? unicode : 0;
+  return *glyph != 0;
+}
+
+static hb_font_funcs_t *
+_hb_fc_get_font_funcs (void)
+{
+  static const hb_font_funcs_t *fc_ffuncs;
+
+  const hb_font_funcs_t *ffuncs;
+
+  if (!(ffuncs = fc_ffuncs))
+  {
+    hb_font_funcs_t *newfuncs = hb_font_funcs_create ();
+
+    hb_font_funcs_set_glyph_func (newfuncs, hb_fc_get_glyph, NULL, NULL);
+
+    /* XXX MT-unsafe */
+    if (fc_ffuncs)
+      hb_font_funcs_destroy (newfuncs);
+    else
+      fc_ffuncs = ffuncs = newfuncs;
+  }
+
+  return const_cast<hb_font_funcs_t *> (fc_ffuncs);
+}
+
+
+hb_font_t *
+hb_fc_font_create (FcPattern *fcfont)
+{
+  static hb_face_t *face;
+  hb_font_t *font;
+
+  FcCharSet *cs;
+  if (FcResultMatch != FcPatternGetCharSet (fcfont, FC_CHARSET, 0, &cs))
+    return hb_font_get_empty ();
+
+  if (!face) /* XXX MT-unsafe */
+    face = hb_face_create (hb_blob_get_empty (), 0);
+
+  font = hb_font_create (face);
+
+  hb_font_set_funcs (font,
+		     _hb_fc_get_font_funcs (),
+		     FcCharSetCopy (cs),
+		     (hb_destroy_func_t) FcCharSetDestroy);
+
+  return font;
+}
+
+hb_bool_t
+hb_fc_can_render (hb_font_t *font, const char *text)
+{
+  static const char *ot[] = {"ot", NULL};
+
+  hb_buffer_t *buffer = hb_buffer_create ();
+  hb_buffer_add_utf8 (buffer, text, -1, 0, -1);
+
+  /* XXX Do we need this?  I think Arabic and Hangul shapers are the
+   * only one that make any use of this.  The Hangul case is not really
+   * needed, and for Arabic we'll miss a very narrow set of fonts.
+   * Might be better to force generic shaper perhaps. */
+  hb_buffer_guess_segment_properties (buffer);
+
+  if (!hb_shape_full (font, buffer, NULL, 0, ot))
+    abort (); /* hb-ot shaper not enabled? */
+
+  unsigned int len;
+  hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, &len);
+  for (unsigned int i = 0; i < len; i++)
+   {
+    if (!info[i].codepoint)
+     {
+      return false;
+     }
+   }
+
+  return true;
+}
diff --git a/util/hb-fc.h b/util/hb-fc.h
new file mode 100644
index 0000000..bb2f78a
--- /dev/null
+++ b/util/hb-fc.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright © 2014  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_FC_H
+#define HB_FC_H
+
+#include "hb.h"
+
+#include <fontconfig/fontconfig.h>
+
+HB_BEGIN_DECLS
+
+
+hb_font_t *
+hb_fc_font_create (FcPattern *font);
+
+hb_bool_t
+hb_fc_can_render (hb_font_t *font, const char *text);
+
+
+HB_END_DECLS
+
+#endif /* HB_FC_H */
commit eb0bf3ae6688b7e98a706df2ad2714c071d77e22
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Aug 6 15:36:41 2014 -0400

    Relax inert checks
    
    Previously, when creating an object from inert inputs (eg:
    "hb_font_create(hb_face_get_empty())") we returned the inert
    empty object.  This is not helpful as there are legitimate
    usecases to do that.
    
    We now never return the inert object unless allocation failed.
    
    Tests are revised to reflect.

diff --git a/src/hb-face.cc b/src/hb-face.cc
index 9348af7..f38f047 100644
--- a/src/hb-face.cc
+++ b/src/hb-face.cc
@@ -165,8 +165,8 @@ hb_face_create (hb_blob_t    *blob,
 {
   hb_face_t *face;
 
-  if (unlikely (!blob || !hb_blob_get_length (blob)))
-    return hb_face_get_empty ();
+  if (unlikely (!blob))
+    blob = hb_blob_get_empty ();
 
   hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (OT::Sanitizer<OT::OpenTypeFontFile>::sanitize (hb_blob_reference (blob)), index);
 
diff --git a/src/hb-font.cc b/src/hb-font.cc
index d42db59..3df41bd 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -854,8 +854,6 @@ hb_font_create (hb_face_t *face)
 
   if (unlikely (!face))
     face = hb_face_get_empty ();
-  if (unlikely (hb_object_is_inert (face)))
-    return hb_font_get_empty ();
   if (!(font = hb_object_create<hb_font_t> ()))
     return hb_font_get_empty ();
 
@@ -880,7 +878,7 @@ hb_font_t *
 hb_font_create_sub_font (hb_font_t *parent)
 {
   if (unlikely (!parent))
-    return hb_font_get_empty ();
+    parent = hb_font_get_empty ();
 
   hb_font_t *font = hb_font_create (parent->face);
 
diff --git a/src/hb-shape-plan.cc b/src/hb-shape-plan.cc
index 2166173..4ccf90e 100644
--- a/src/hb-shape-plan.cc
+++ b/src/hb-shape-plan.cc
@@ -126,7 +126,7 @@ hb_shape_plan_create (hb_face_t                     *face,
 
   if (unlikely (!face))
     face = hb_face_get_empty ();
-  if (unlikely (!props || hb_object_is_inert (face)))
+  if (unlikely (!props))
     return hb_shape_plan_get_empty ();
   if (num_user_features && !(features = (hb_feature_t *) malloc (num_user_features * sizeof (hb_feature_t))))
     return hb_shape_plan_get_empty ();
@@ -294,7 +294,6 @@ hb_shape_plan_execute (hb_shape_plan_t    *shape_plan,
 		  shape_plan->shaper_func);
 
   if (unlikely (hb_object_is_inert (shape_plan) ||
-		hb_object_is_inert (font) ||
 		hb_object_is_inert (buffer)))
     return false;
 
@@ -453,6 +452,10 @@ retry:
 
   hb_shape_plan_t *shape_plan = hb_shape_plan_create (face, props, user_features, num_user_features, shaper_list);
 
+  /* Don't add to the cache if face is inert. */
+  if (unlikely (hb_object_is_inert (face)))
+    return shape_plan;
+
   /* Don't add the plan to the cache if there were user features with non-global ranges */
 
   if (hb_non_global_user_features_present (user_features, num_user_features))
diff --git a/test/api/test-font.c b/test/api/test-font.c
index 6b6a503..2fc0631 100644
--- a/test/api/test-font.c
+++ b/test/api/test-font.c
@@ -36,8 +36,8 @@ static void
 test_face_empty (void)
 {
   g_assert (hb_face_get_empty ());
-  g_assert (hb_face_get_empty () == hb_face_create (hb_blob_get_empty (), 0));
-  g_assert (hb_face_get_empty () == hb_face_create (NULL, 0));
+  g_assert (hb_face_get_empty () != hb_face_create (hb_blob_get_empty (), 0));
+  g_assert (hb_face_get_empty () != hb_face_create (NULL, 0));
 
   g_assert (hb_face_reference_table (hb_face_get_empty (), HB_TAG ('h','e','a','d')) == hb_blob_get_empty ());
 
@@ -348,9 +348,9 @@ static void
 test_font_empty (void)
 {
   g_assert (hb_font_get_empty ());
-  g_assert (hb_font_get_empty () == hb_font_create (hb_face_get_empty ()));
-  g_assert (hb_font_get_empty () == hb_font_create (NULL));
-  g_assert (hb_font_get_empty () == hb_font_create_sub_font (NULL));
+  g_assert (hb_font_get_empty () != hb_font_create (hb_face_get_empty ()));
+  g_assert (hb_font_get_empty () != hb_font_create (NULL));
+  g_assert (hb_font_get_empty () != hb_font_create_sub_font (NULL));
   g_assert (hb_font_is_immutable (hb_font_get_empty ()));
 
   g_assert (hb_font_get_face (hb_font_get_empty ()) == hb_face_get_empty ());
diff --git a/test/api/test-object.c b/test/api/test-object.c
index 3afe6ae..4ea6f7c 100644
--- a/test/api/test-object.c
+++ b/test/api/test-object.c
@@ -36,7 +36,7 @@ create_blob (void)
   return hb_blob_create (data, sizeof (data), HB_MEMORY_MODE_READONLY, NULL, NULL);
 }
 static void *
-create_blob_inert (void)
+create_blob_from_inert (void)
 {
   return hb_blob_create (NULL, 0, HB_MEMORY_MODE_DUPLICATE, NULL, NULL);
 }
@@ -47,7 +47,7 @@ create_buffer (void)
   return hb_buffer_create ();
 }
 static void *
-create_buffer_inert (void)
+create_buffer_from_inert (void)
 {
   return NULL;
 }
@@ -58,7 +58,7 @@ create_set (void)
   return hb_set_create ();
 }
 static void *
-create_set_inert (void)
+create_set_from_inert (void)
 {
   return NULL;
 }
@@ -72,7 +72,7 @@ create_face (void)
   return face;
 }
 static void *
-create_face_inert (void)
+create_face_from_inert (void)
 {
   return hb_face_create (hb_blob_get_empty (), 0);
 }
@@ -86,7 +86,7 @@ create_font (void)
   return font;
 }
 static void *
-create_font_inert (void)
+create_font_from_inert (void)
 {
   return hb_font_create (hb_face_get_empty ());
 }
@@ -97,7 +97,7 @@ create_font_funcs (void)
   return hb_font_funcs_create ();
 }
 static void *
-create_font_funcs_inert (void)
+create_font_funcs_from_inert (void)
 {
   return NULL;
 }
@@ -108,9 +108,9 @@ create_unicode_funcs (void)
   return hb_unicode_funcs_create (NULL);
 }
 static void *
-create_unicode_funcs_inert (void)
+create_unicode_funcs_from_inert (void)
 {
-  return hb_unicode_funcs_get_default ();
+  return hb_unicode_funcs_create (hb_unicode_funcs_get_empty ());
 }
 
 
@@ -125,7 +125,7 @@ typedef hb_bool_t (*is_immutable_func_t)   (void *obj);
 
 typedef struct {
   create_func_t          create;
-  create_func_t          create_inert;
+  create_func_t          create_from_inert;
   create_func_t          get_empty;
   reference_func_t       reference;
   destroy_func_t         destroy;
@@ -139,7 +139,7 @@ typedef struct {
 #define OBJECT_WITHOUT_IMMUTABILITY(name) \
   { \
     (create_func_t)         create_##name, \
-    (create_func_t)         create_##name##_inert, \
+    (create_func_t)         create_##name##_from_inert, \
     (create_func_t)         hb_##name##_get_empty, \
     (reference_func_t)      hb_##name##_reference, \
     (destroy_func_t)        hb_##name##_destroy, \
@@ -152,7 +152,7 @@ typedef struct {
 #define OBJECT_WITH_IMMUTABILITY(name) \
   { \
     (create_func_t)         create_##name, \
-    (create_func_t)         create_##name##_inert, \
+    (create_func_t)         create_##name##_from_inert, \
     (create_func_t)         hb_##name##_get_empty, \
     (reference_func_t)      hb_##name##_reference, \
     (destroy_func_t)        hb_##name##_destroy, \
@@ -340,8 +340,8 @@ test_object (void)
     {
       data_t data[2] = {{MAGIC0, FALSE}, {MAGIC1, FALSE}};
 
-      g_test_message ("->create_inert()");
-      obj = o->create_inert ();
+      g_test_message ("->create_from_inert()");
+      obj = o->create_from_inert ();
       if (!obj)
 	continue;
       if (obj == o->get_empty ())
@@ -351,10 +351,10 @@ test_object (void)
       o->destroy (obj);
 
       if (o->is_immutable)
-	g_assert (o->is_immutable (obj));
+	g_assert (!o->is_immutable (obj));
 
-      g_assert (!o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE));
-      g_assert (!o->get_user_data (obj, &key[0]));
+      g_assert (o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE));
+      g_assert (o->get_user_data (obj, &key[0]));
 
       o->destroy (obj);
       o->destroy (obj);
@@ -362,7 +362,7 @@ test_object (void)
       o->destroy (obj);
       o->destroy (obj);
 
-      g_assert (!data[0].freed);
+      g_assert (data[0].freed);
     }
   }
 }


More information about the HarfBuzz mailing list