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

Behdad Esfahbod behdad at kemper.freedesktop.org
Fri Oct 12 20:06:51 UTC 2018


 docs/harfbuzz-sections.txt |    2 
 src/Makefile.sources       |    1 
 src/hb-common.h            |    8 ++
 src/hb-deprecated.h        |   10 +--
 src/hb-font.cc             |    4 -
 src/hb-graphite2.h         |    2 
 src/hb-machinery.hh        |    6 +-
 src/hb-ot-layout-common.hh |   16 +++++
 src/hb-ot-layout.cc        |  135 +++++++++++++++++++++++++++++++++++++++++++++
 src/hb-ot-layout.h         |   21 ++++++-
 src/hb-ot-name.h           |   54 ++++++++++++++++++
 src/hb-ot-tag.cc           |    4 -
 src/hb-ot.h                |    1 
 test/api/CMakeLists.txt    |    2 
 test/api/Makefile.am       |    1 
 test/api/fonts/cv01.otf    |binary
 test/api/test-ot-nameid.c  |  100 +++++++++++++++++++++++++++++++++
 17 files changed, 350 insertions(+), 17 deletions(-)

New commits:
commit c0a6814b49e376984a0cae9d385a6f6ba8c73579
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Oct 12 16:05:56 2018 -0400

    Touch up new API
    
    New API:
    +hb_ot_layout_feature_get_name_ids()
    +hb_ot_layout_feature_get_characters()

diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index 4c751e64..1e547a7a 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -1121,7 +1121,6 @@ hb_ot_layout_get_size_params (hb_face_t    *face,
  * @face: #hb_face_t to work upon
  * @table_tag:
  * @feature_index:
- * @feature_tag: ssXX and cvXX tag
  * @label_id: (out) (allow-none): The ‘name’ table name ID that specifies a string
  *            for a user-interface label for this feature. (May be NULL.)
  * @tooltip_id: (out) (allow-none): The ‘name’ table name ID that specifies a string
@@ -1134,7 +1133,10 @@ hb_ot_layout_get_size_params (hb_face_t    *face,
  *                  strings for user-interface labels for the feature
  *                  parameters. (Must be zero if numParameters is zero.)
  *
- * Return value: true if could find any feature with the tag, false otherwise
+ * Fetches name indices from feature parameters for "Stylistic Set" ('ssXX') or
+ * "Character Variant" ('cvXX') features.
+ *
+ * Return value: true if data found, false otherwise
  *
  * Since: REPLACEME
  **/
@@ -1142,16 +1144,15 @@ hb_bool_t
 hb_ot_layout_feature_get_name_ids (hb_face_t      *face,
 				   hb_tag_t        table_tag,
 				   unsigned int    feature_index,
-				   hb_tag_t        feature_tag,
 				   hb_name_id_t   *label_id,             /* OUT.  May be NULL */
 				   hb_name_id_t   *tooltip_id,           /* OUT.  May be NULL */
 				   hb_name_id_t   *sample_id,            /* OUT.  May be NULL */
 				   unsigned int   *num_named_parameters, /* OUT.  May be NULL */
 				   hb_name_id_t   *first_param_id        /* OUT.  May be NULL */)
 {
-  static_assert ((OT::FeatureVariations::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_VARIATIONS_INDEX), "");
   const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
 
+  hb_tag_t feature_tag = g.get_feature_tag (feature_index);
   const OT::Feature &f = g.get_feature (feature_index);
 
   const OT::FeatureParams &feature_params = f.get_feature_params ();
@@ -1195,7 +1196,6 @@ hb_ot_layout_feature_get_name_ids (hb_face_t      *face,
 /**
  * hb_ot_layout_feature_get_characters::
  * @face: #hb_face_t to work upon
- * @feature_tag: cvXX tag
  * @table_tag:
  * @feature_index:
  * @start_offset: In case the resulting char_count was equal to its input value, there
@@ -1208,6 +1208,9 @@ hb_ot_layout_feature_get_name_ids (hb_face_t      *face,
  * @characters: (out) (allow-none): A buffer pointer. The Unicode Scalar Value
  *              of the characters for which this feature provides glyph variants.
  *
+ * Fetches characters listed by designer under feature parameters for "Character
+ * Variant" ("cvXX") features.
+ *
  * Return value: Number of total sample characters in the cvXX feature.
  *
  * Since: REPLACEME
@@ -1216,14 +1219,13 @@ unsigned int
 hb_ot_layout_feature_get_characters (hb_face_t      *face,
 				     hb_tag_t        table_tag,
 				     unsigned int    feature_index,
-				     hb_tag_t        feature_tag,
 				     unsigned int    start_offset,
 				     unsigned int   *char_count, /* IN/OUT.  May be NULL */
 				     hb_codepoint_t *characters  /* OUT.     May be NULL */)
 {
-  static_assert ((OT::FeatureVariations::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_VARIATIONS_INDEX), "");
   const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
 
+  hb_tag_t feature_tag = g.get_feature_tag (feature_index);
   const OT::Feature &f = g.get_feature (feature_index);
 
   const OT::FeatureParams &feature_params = f.get_feature_params ();
diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h
index 001d77b2..a2e5b515 100644
--- a/src/hb-ot-layout.h
+++ b/src/hb-ot-layout.h
@@ -335,7 +335,6 @@ HB_EXTERN hb_bool_t
 hb_ot_layout_feature_get_name_ids (hb_face_t      *face,
 				   hb_tag_t        table_tag,
 				   unsigned int    feature_index,
-				   hb_tag_t        feature_tag,
 				   hb_name_id_t   *label_id             /* OUT.  May be NULL */,
 				   hb_name_id_t   *tooltip_id           /* OUT.  May be NULL */,
 				   hb_name_id_t   *sample_id            /* OUT.  May be NULL */,
@@ -347,7 +346,6 @@ HB_EXTERN unsigned int
 hb_ot_layout_feature_get_characters (hb_face_t      *face,
 				     hb_tag_t        table_tag,
 				     unsigned int    feature_index,
-				     hb_tag_t        feature_tag,
 				     unsigned int    start_offset,
 				     unsigned int   *char_count    /* IN/OUT.  May be NULL */,
 				     hb_codepoint_t *characters    /* OUT.     May be NULL */);
diff --git a/test/api/test-ot-nameid.c b/test/api/test-ot-nameid.c
index 1389129f..1205190d 100644
--- a/test/api/test-ot-nameid.c
+++ b/test/api/test-ot-nameid.c
@@ -53,10 +53,14 @@ main (int argc, char **argv)
   font = hb_font_create (face);
 
   hb_tag_t cv01 = HB_TAG ('c','v','0','1');
-  unsigned int feature_index = 0;
-  // FIXME: See why below doesn't work
-  // if (!hb_ot_layout_language_find_feature (face, HB_OT_TAG_GSUB, 0, 0, cv01, &feature_index))
-  //   g_error ("Failed to find feature index");
+  unsigned int feature_index;
+  if (!hb_ot_layout_language_find_feature (face,
+					   HB_OT_TAG_GSUB,
+					   0,
+					   HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX,
+					   cv01,
+					   &feature_index))
+     g_error ("Failed to find feature index");
 
   hb_name_id_t label_id;
   hb_name_id_t tooltip_id;
@@ -64,7 +68,7 @@ main (int argc, char **argv)
   unsigned int num_named_parameters;
   hb_name_id_t first_param_id;
   if (!hb_ot_layout_feature_get_name_ids (face, HB_OT_TAG_GSUB, feature_index,
-					  cv01, &label_id, &tooltip_id, &sample_id,
+					  &label_id, &tooltip_id, &sample_id,
 					  &num_named_parameters, &first_param_id))
     g_error ("Failed to get name ids");
 
@@ -79,7 +83,7 @@ main (int argc, char **argv)
 
   unsigned int all_chars;
   all_chars = hb_ot_layout_feature_get_characters (face, HB_OT_TAG_GSUB, feature_index,
-						   cv01, 0, &char_count, characters);
+						   0, &char_count, characters);
 
   g_assert (all_chars == 2);
   g_assert (char_count == 2);
commit 477bc9aafeaf89708d13a436869126351e2d9b50
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Oct 12 15:52:31 2018 -0400

    Add hb-ot-name.h
    
    Actual name-fetching API to come later.
    
    New API:
    hb_name_id_t
    HB_NAME_ID_INVALID

diff --git a/src/Makefile.sources b/src/Makefile.sources
index db0a4138..59cde6bd 100644
--- a/src/Makefile.sources
+++ b/src/Makefile.sources
@@ -173,6 +173,7 @@ HB_OT_headers = \
 	hb-ot-font.h \
 	hb-ot-layout.h \
 	hb-ot-math.h \
+	hb-ot-name.h \
 	hb-ot-shape.h \
 	hb-ot-tag.h \
 	hb-ot-var.h \
diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh
index bf0a9c1e..4ebebb15 100644
--- a/src/hb-ot-layout-common.hh
+++ b/src/hb-ot-layout-common.hh
@@ -400,7 +400,7 @@ struct FeatureParamsSize
 				 * same subfamily value. If this value is
 				 * zero, the remaining fields in the array
 				 * will be ignored. */
-  HBUINT16	subfamilyNameID;/* If the preceding value is non-zero, this
+  NameID	subfamilyNameID;/* If the preceding value is non-zero, this
 				 * value must be set in the range 256 - 32767
 				 * (inclusive). It records the value of a
 				 * field in the name table, which must
diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h
index 0be85cb2..001d77b2 100644
--- a/src/hb-ot-layout.h
+++ b/src/hb-ot-layout.h
@@ -34,6 +34,7 @@
 #include "hb.h"
 
 #include "hb-ot-tag.h"
+#include "hb-ot-name.h"
 
 HB_BEGIN_DECLS
 
@@ -326,19 +327,10 @@ HB_EXTERN hb_bool_t
 hb_ot_layout_get_size_params (hb_face_t    *face,
 			      unsigned int *design_size,       /* OUT.  May be NULL */
 			      unsigned int *subfamily_id,      /* OUT.  May be NULL */
-			      unsigned int *subfamily_name_id, /* OUT.  May be NULL */
+			      hb_name_id_t *subfamily_name_id, /* OUT.  May be NULL */
 			      unsigned int *range_start,       /* OUT.  May be NULL */
 			      unsigned int *range_end          /* OUT.  May be NULL */);
 
-/**
- * hb_name_id_t:
- *
- * Since: REPLACEME
- */
-typedef unsigned int hb_name_id_t;
-
-#define HB_NAME_ID_INVALID 0xFFFF
-
 HB_EXTERN hb_bool_t
 hb_ot_layout_feature_get_name_ids (hb_face_t      *face,
 				   hb_tag_t        table_tag,
diff --git a/src/hb-ot-name.h b/src/hb-ot-name.h
new file mode 100644
index 00000000..0694b396
--- /dev/null
+++ b/src/hb-ot-name.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright © 2018  Ebrahim Byagowi.
+ *
+ *  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.
+ */
+
+#ifndef HB_OT_H_IN
+#error "Include <hb-ot.h> instead."
+#endif
+
+#ifndef HB_OT_NAME_H
+#define HB_OT_NAME_H
+
+#include "hb.h"
+
+HB_BEGIN_DECLS
+
+
+/**
+ * hb_name_id_t:
+ *
+ * Since: REPLACEME
+ */
+typedef unsigned int hb_name_id_t;
+
+/**
+ * HB_NAME_ID_INVALID
+ *
+ * Since: REPLACEME
+ **/
+#define HB_NAME_ID_INVALID 0xFFFF
+
+
+HB_END_DECLS
+
+#endif /* HB_OT_NAME_H */
diff --git a/src/hb-ot.h b/src/hb-ot.h
index 2120a3ef..4b6e3cf7 100644
--- a/src/hb-ot.h
+++ b/src/hb-ot.h
@@ -33,6 +33,7 @@
 #include "hb-ot-font.h"
 #include "hb-ot-layout.h"
 #include "hb-ot-math.h"
+#include "hb-ot-name.h"
 #include "hb-ot-tag.h"
 #include "hb-ot-shape.h"
 #include "hb-ot-var.h"
commit dc49bd8d813571fe16d9e5342e4a3926ff947bd6
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date:   Fri Oct 12 03:00:59 2018 +0330

    Add two APIs for getting stylistic set labels
    
    * hb_ot_layout_feature_get_characters
    * hb_ot_layout_feature_get_name_ids
    
    However HarfBuzz currently doesn't expose an API for retrieving the actual
    information associated with NameId from the `name` table and that should be
    done separately.

diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt
index 9472af4f..fccfcb0e 100644
--- a/docs/harfbuzz-sections.txt
+++ b/docs/harfbuzz-sections.txt
@@ -479,7 +479,9 @@ HB_OT_TAG_GSUB
 HB_OT_TAG_JSTF
 hb_ot_layout_collect_lookups
 hb_ot_layout_collect_features
+hb_ot_layout_feature_get_characters
 hb_ot_layout_feature_get_lookups
+hb_ot_layout_feature_get_name_ids
 hb_ot_layout_feature_with_variations_get_lookups
 hb_ot_layout_get_attach_points
 hb_ot_layout_get_glyph_class
diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh
index e5e996d4..bf0a9c1e 100644
--- a/src/hb-ot-layout-common.hh
+++ b/src/hb-ot-layout-common.hh
@@ -521,6 +521,20 @@ struct FeatureParams
     return Null(FeatureParamsSize);
   }
 
+  inline const FeatureParamsStylisticSet& get_stylistic_set_params (hb_tag_t tag) const
+  {
+    if ((tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */
+      return u.stylisticSet;
+    return Null(FeatureParamsStylisticSet);
+  }
+
+  inline const FeatureParamsCharacterVariants& get_character_variants_params (hb_tag_t tag) const
+  {
+    if ((tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */
+      return u.characterVariants;
+    return Null(FeatureParamsCharacterVariants);
+  }
+
   private:
   union {
   FeatureParamsSize			size;
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index aa36954d..4c751e64 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -1116,6 +1116,139 @@ hb_ot_layout_get_size_params (hb_face_t    *face,
   return false;
 }
 
+/**
+ * hb_ot_layout_feature_get_name_ids:
+ * @face: #hb_face_t to work upon
+ * @table_tag:
+ * @feature_index:
+ * @feature_tag: ssXX and cvXX tag
+ * @label_id: (out) (allow-none): The ‘name’ table name ID that specifies a string
+ *            for a user-interface label for this feature. (May be NULL.)
+ * @tooltip_id: (out) (allow-none): The ‘name’ table name ID that specifies a string
+ *              that an application can use for tooltip text for this
+ *              feature. (May be NULL.)
+ * @sample_id: (out) (allow-none): The ‘name’ table name ID that specifies sample text
+ *             that illustrates the effect of this feature. (May be NULL.)
+ * @num_named_parameters: (out) (allow-none):  Number of named parameters. (May be zero.)
+ * @first_param_id: (out) (allow-none): The first ‘name’ table name ID used to specify
+ *                  strings for user-interface labels for the feature
+ *                  parameters. (Must be zero if numParameters is zero.)
+ *
+ * Return value: true if could find any feature with the tag, false otherwise
+ *
+ * Since: REPLACEME
+ **/
+hb_bool_t
+hb_ot_layout_feature_get_name_ids (hb_face_t      *face,
+				   hb_tag_t        table_tag,
+				   unsigned int    feature_index,
+				   hb_tag_t        feature_tag,
+				   hb_name_id_t   *label_id,             /* OUT.  May be NULL */
+				   hb_name_id_t   *tooltip_id,           /* OUT.  May be NULL */
+				   hb_name_id_t   *sample_id,            /* OUT.  May be NULL */
+				   unsigned int   *num_named_parameters, /* OUT.  May be NULL */
+				   hb_name_id_t   *first_param_id        /* OUT.  May be NULL */)
+{
+  static_assert ((OT::FeatureVariations::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_VARIATIONS_INDEX), "");
+  const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+
+  const OT::Feature &f = g.get_feature (feature_index);
+
+  const OT::FeatureParams &feature_params = f.get_feature_params ();
+  if (&feature_params != &Null (OT::FeatureParams))
+  {
+    const OT::FeatureParamsStylisticSet& ss_params =
+      feature_params.get_stylistic_set_params (feature_tag);
+    if (&ss_params != &Null (OT::FeatureParamsStylisticSet)) /* ssXX */
+    {
+#define PARAM(a, A) if (a) *a = A
+      PARAM(label_id, ss_params.uiNameID);
+      // ssXX features don't have the rest
+      PARAM(tooltip_id, HB_NAME_ID_INVALID);
+      PARAM(sample_id, HB_NAME_ID_INVALID);
+      PARAM(num_named_parameters, 0);
+      PARAM(first_param_id, HB_NAME_ID_INVALID);
+      return true;
+    }
+    const OT::FeatureParamsCharacterVariants& cv_params =
+      feature_params.get_character_variants_params (feature_tag);
+    if (&cv_params != &Null (OT::FeatureParamsCharacterVariants)) /* cvXX */
+    {
+      PARAM(label_id, cv_params.featUILableNameID);
+      PARAM(tooltip_id, cv_params.featUITooltipTextNameID);
+      PARAM(sample_id, cv_params.sampleTextNameID);
+      PARAM(num_named_parameters, cv_params.numNamedParameters);
+      PARAM(first_param_id, cv_params.firstParamUILabelNameID);
+      return true;
+    }
+  }
+
+  PARAM(label_id, HB_NAME_ID_INVALID);
+  PARAM(tooltip_id, HB_NAME_ID_INVALID);
+  PARAM(sample_id, HB_NAME_ID_INVALID);
+  PARAM(num_named_parameters, 0);
+  PARAM(first_param_id, HB_NAME_ID_INVALID);
+#undef PARAM
+  return false;
+}
+
+/**
+ * hb_ot_layout_feature_get_characters::
+ * @face: #hb_face_t to work upon
+ * @feature_tag: cvXX tag
+ * @table_tag:
+ * @feature_index:
+ * @start_offset: In case the resulting char_count was equal to its input value, there
+ *                is a chance there were more characters on the tag so this API can be
+ *                called with an offset till resulting char_count gets to a number
+ *                lower than input buffer (or consider using just a bigger buffer for
+ *                one shot copying).
+ * @char_count: (in/out) (allow-none): The count of characters for which this feature
+ *              provides glyph variants. (May be zero.)
+ * @characters: (out) (allow-none): A buffer pointer. The Unicode Scalar Value
+ *              of the characters for which this feature provides glyph variants.
+ *
+ * Return value: Number of total sample characters in the cvXX feature.
+ *
+ * Since: REPLACEME
+ **/
+unsigned int
+hb_ot_layout_feature_get_characters (hb_face_t      *face,
+				     hb_tag_t        table_tag,
+				     unsigned int    feature_index,
+				     hb_tag_t        feature_tag,
+				     unsigned int    start_offset,
+				     unsigned int   *char_count, /* IN/OUT.  May be NULL */
+				     hb_codepoint_t *characters  /* OUT.     May be NULL */)
+{
+  static_assert ((OT::FeatureVariations::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_VARIATIONS_INDEX), "");
+  const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+
+  const OT::Feature &f = g.get_feature (feature_index);
+
+  const OT::FeatureParams &feature_params = f.get_feature_params ();
+
+  const OT::FeatureParamsCharacterVariants& cv_params =
+    feature_params.get_character_variants_params(feature_tag);
+  if (&cv_params != &Null (OT::FeatureParamsCharacterVariants))
+  {
+    unsigned int len = 0;
+    if (char_count && characters && start_offset < cv_params.characters.len)
+    {
+      len = MIN (cv_params.characters.len - start_offset, *char_count);
+      for (unsigned int i = 0; i < len; ++i)
+        characters[i] = cv_params.characters[start_offset + i];
+    }
+#define PARAM(a, A) if (a) *a = A
+    PARAM(char_count, len);
+    return cv_params.characters.len;
+  }
+  PARAM(char_count, 0);
+  PARAM(characters, 0);
+#undef PARAM
+  return 0;
+}
+
 
 /*
  * Parts of different types are implemented here such that they have direct
diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h
index eb0df893..0be85cb2 100644
--- a/src/hb-ot-layout.h
+++ b/src/hb-ot-layout.h
@@ -330,6 +330,35 @@ hb_ot_layout_get_size_params (hb_face_t    *face,
 			      unsigned int *range_start,       /* OUT.  May be NULL */
 			      unsigned int *range_end          /* OUT.  May be NULL */);
 
+/**
+ * hb_name_id_t:
+ *
+ * Since: REPLACEME
+ */
+typedef unsigned int hb_name_id_t;
+
+#define HB_NAME_ID_INVALID 0xFFFF
+
+HB_EXTERN hb_bool_t
+hb_ot_layout_feature_get_name_ids (hb_face_t      *face,
+				   hb_tag_t        table_tag,
+				   unsigned int    feature_index,
+				   hb_tag_t        feature_tag,
+				   hb_name_id_t   *label_id             /* OUT.  May be NULL */,
+				   hb_name_id_t   *tooltip_id           /* OUT.  May be NULL */,
+				   hb_name_id_t   *sample_id            /* OUT.  May be NULL */,
+				   unsigned int   *num_named_parameters /* OUT.  May be NULL */,
+				   hb_name_id_t   *first_param_id       /* OUT.  May be NULL */);
+
+
+HB_EXTERN unsigned int
+hb_ot_layout_feature_get_characters (hb_face_t      *face,
+				     hb_tag_t        table_tag,
+				     unsigned int    feature_index,
+				     hb_tag_t        feature_tag,
+				     unsigned int    start_offset,
+				     unsigned int   *char_count    /* IN/OUT.  May be NULL */,
+				     hb_codepoint_t *characters    /* OUT.     May be NULL */);
 
 /*
  * BASE
diff --git a/test/api/CMakeLists.txt b/test/api/CMakeLists.txt
index b540eb50..77cb3577 100644
--- a/test/api/CMakeLists.txt
+++ b/test/api/CMakeLists.txt
@@ -3,6 +3,8 @@ if (HB_HAVE_GLIB)
   extract_make_variable (TEST_PROGS ${MAKEFILEAM})
 
   list (APPEND TEST_PROGS
+    test-ot-color
+    test-ot-nameid
     test-ot-tag
     test-c
     test-cplusplus
diff --git a/test/api/Makefile.am b/test/api/Makefile.am
index 3ff7f5a8..0e3f9a40 100644
--- a/test/api/Makefile.am
+++ b/test/api/Makefile.am
@@ -71,6 +71,7 @@ endif
 
 TEST_PROGS += \
 	test-ot-color \
+	test-ot-nameid \
 	test-ot-tag \
 	$(NULL)
 
diff --git a/test/api/fonts/cv01.otf b/test/api/fonts/cv01.otf
new file mode 100644
index 00000000..01dbf01f
Binary files /dev/null and b/test/api/fonts/cv01.otf differ
diff --git a/test/api/test-ot-nameid.c b/test/api/test-ot-nameid.c
new file mode 100644
index 00000000..1389129f
--- /dev/null
+++ b/test/api/test-ot-nameid.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright © 2018  Ebrahim Byagowi
+ *
+ *  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.
+ *
+ */
+
+#include <hb.h>
+#include <hb-ot.h>
+#include <glib.h>
+
+static const char *font_path = "fonts/cv01.otf";
+
+int
+main (int argc, char **argv)
+{
+  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
+
+  hb_blob_t *blob;
+  hb_face_t *face;
+  hb_font_t *font;
+
+  char *path = argc > 1 && *argv[1] ? argv[1] : (char *) default_path;
+  blob = hb_blob_create_from_file (path);
+  if (hb_blob_get_length (blob) == 0)
+    g_error ("Font not found.");
+
+  face = hb_face_create (blob, 0);
+  font = hb_font_create (face);
+
+  hb_tag_t cv01 = HB_TAG ('c','v','0','1');
+  unsigned int feature_index = 0;
+  // FIXME: See why below doesn't work
+  // if (!hb_ot_layout_language_find_feature (face, HB_OT_TAG_GSUB, 0, 0, cv01, &feature_index))
+  //   g_error ("Failed to find feature index");
+
+  hb_name_id_t label_id;
+  hb_name_id_t tooltip_id;
+  hb_name_id_t sample_id;
+  unsigned int num_named_parameters;
+  hb_name_id_t first_param_id;
+  if (!hb_ot_layout_feature_get_name_ids (face, HB_OT_TAG_GSUB, feature_index,
+					  cv01, &label_id, &tooltip_id, &sample_id,
+					  &num_named_parameters, &first_param_id))
+    g_error ("Failed to get name ids");
+
+  g_assert (label_id == 256);
+  g_assert (tooltip_id == 257);
+  g_assert (sample_id == 258);
+  g_assert (num_named_parameters == 2);
+  g_assert (first_param_id == 259);
+
+  hb_codepoint_t characters[100];
+  unsigned int char_count = 100;
+
+  unsigned int all_chars;
+  all_chars = hb_ot_layout_feature_get_characters (face, HB_OT_TAG_GSUB, feature_index,
+						   cv01, 0, &char_count, characters);
+
+  g_assert (all_chars == 2);
+  g_assert (char_count == 2);
+  g_assert (characters[0] == 10);
+  g_assert (characters[1] == 24030);
+
+  hb_font_destroy (font);
+  hb_face_destroy (face);
+  hb_blob_destroy (blob);
+
+  g_free (default_path);
+
+  return 0;
+}
commit e9f9c0d81c73d8b6d87700aadb5b886bd289769a
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Oct 11 21:37:45 2018 -0400

    [sanitize] Reorder condition to silence bogus gcc warning
    
    Was givin a dozen of:
    
    ../../src/hb-machinery.hh: In member function ‘bool AAT::ankr::sanitize(hb_sanitize_context_t*) const’:
    ../../src/hb-machinery.hh:307:23: warning: missed loop optimization, the loop counter may overflow [-Wunsafe-loop-optimizations]
         bool ok = --this->max_ops > 0 &&
                   ~~~~~~~~~~~~~~~~~~~~~~
            this->start <= p &&
            ~~~~~~~~~~~~~~~~~~~
            p <= this->end &&
            ~~~~~~~~~~~~~~~^~
            (unsigned int) (this->end - p) >= len;
            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    I believe those are bogus, but this silences them and does not introduce
    logic issues I believe.

diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh
index 56914bea..a6ff6e7b 100644
--- a/src/hb-machinery.hh
+++ b/src/hb-machinery.hh
@@ -302,10 +302,10 @@ struct hb_sanitize_context_t :
   inline bool check_range (const void *base, unsigned int len) const
   {
     const char *p = (const char *) base;
-    bool ok = this->max_ops-- > 0 &&
-	      this->start <= p &&
+    bool ok = this->start <= p &&
 	      p <= this->end &&
-	      (unsigned int) (this->end - p) >= len;
+	      (unsigned int) (this->end - p) >= len &&
+	      this->max_ops-- > 0;
 
     DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0,
        "check_range [%p..%p] (%d bytes) in [%p..%p] -> %s",
commit 1a6b5ac6c300ed2ccdcd8eadde433120f6e07f2a
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Oct 11 21:22:49 2018 -0400

    Add HB_DEPRECATED_FOR and mark relevant symbols

diff --git a/src/hb-common.h b/src/hb-common.h
index 4f91a176..c601b1f6 100644
--- a/src/hb-common.h
+++ b/src/hb-common.h
@@ -71,6 +71,14 @@ typedef unsigned __int64 uint64_t;
 #define HB_DEPRECATED
 #endif
 
+#if    __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
+#define HB_DEPRECATED_FOR(f) __attribute__((__deprecated__("Use '" #f "' instead")))
+#elif defined(_MSC_FULL_VER) && (_MSC_FULL_VER > 140050320)
+#define HB_DEPRECATED_FOR(f) __declspec(deprecated("is deprecated. Use '" #f "' instead"))
+#else
+#define HB_DEPRECATED_FOR(f) HB_DEPRECATED
+#endif
+
 
 HB_BEGIN_DECLS
 
diff --git a/src/hb-deprecated.h b/src/hb-deprecated.h
index 46590731..52ee49e2 100644
--- a/src/hb-deprecated.h
+++ b/src/hb-deprecated.h
@@ -50,7 +50,7 @@ typedef hb_bool_t (*hb_font_get_glyph_func_t) (hb_font_t *font, void *font_data,
 					       hb_codepoint_t *glyph,
 					       void *user_data);
 
-HB_EXTERN HB_DEPRECATED void
+HB_EXTERN HB_DEPRECATED_FOR(hb_font_funcs_set_nominal_glyph_func or hb_font_funcs_set_variation_glyph_func) void
 hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
 			      hb_font_get_glyph_func_t func,
 			      void *user_data, hb_destroy_func_t destroy);
@@ -212,26 +212,26 @@ hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
 					 hb_position_t *x, hb_position_t *y);
 
 /* Like hb_ot_layout_table_find_script, but takes zero-terminated array of scripts to test */
-HB_EXTERN HB_DEPRECATED hb_bool_t
+HB_EXTERN HB_DEPRECATED_FOR (hb_ot_layout_table_select_script) hb_bool_t
 hb_ot_layout_table_choose_script (hb_face_t      *face,
 				  hb_tag_t        table_tag,
 				  const hb_tag_t *script_tags,
 				  unsigned int   *script_index,
 				  hb_tag_t       *chosen_script);
 
-HB_EXTERN HB_DEPRECATED hb_bool_t
+HB_EXTERN HB_DEPRECATED_FOR (hb_ot_layout_script_select_language) hb_bool_t
 hb_ot_layout_script_find_language (hb_face_t    *face,
 				   hb_tag_t      table_tag,
 				   unsigned int  script_index,
 				   hb_tag_t      language_tag,
 				   unsigned int *language_index);
 
-HB_EXTERN HB_DEPRECATED void
+HB_EXTERN HB_DEPRECATED_FOR (hb_ot_tags_from_script_and_language) void
 hb_ot_tags_from_script (hb_script_t  script,
 			hb_tag_t    *script_tag_1,
 			hb_tag_t    *script_tag_2);
 
-HB_EXTERN HB_DEPRECATED hb_tag_t
+HB_EXTERN HB_DEPRECATED_FOR (hb_ot_tags_from_script_and_language) hb_tag_t
 hb_ot_tag_from_language (hb_language_t language);
 
 
diff --git a/src/hb-graphite2.h b/src/hb-graphite2.h
index acf1dfa8..1720191b 100644
--- a/src/hb-graphite2.h
+++ b/src/hb-graphite2.h
@@ -41,7 +41,7 @@ hb_graphite2_face_get_gr_face (hb_face_t *face);
 
 #ifndef HB_DISABLE_DEPRECATED
 
-HB_EXTERN HB_DEPRECATED gr_font *
+HB_EXTERN HB_DEPRECATED_FOR (hb_graphite2_face_get_gr_face) gr_font *
 hb_graphite2_font_get_gr_font (hb_font_t *font);
 
 #endif
commit c9413d7bb575093411b39ac21974795b6ad91454
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Oct 11 21:19:39 2018 -0400

    [graphite] Add HB_DEPRECATED annotation

diff --git a/src/hb-graphite2.h b/src/hb-graphite2.h
index 05c55deb..acf1dfa8 100644
--- a/src/hb-graphite2.h
+++ b/src/hb-graphite2.h
@@ -41,7 +41,7 @@ hb_graphite2_face_get_gr_face (hb_face_t *face);
 
 #ifndef HB_DISABLE_DEPRECATED
 
-HB_EXTERN gr_font *
+HB_EXTERN HB_DEPRECATED gr_font *
 hb_graphite2_font_get_gr_font (hb_font_t *font);
 
 #endif
commit 68c86af187ff645a1305ac3b64832f3bb2350519
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Oct 11 21:18:20 2018 -0400

    Always compile deprecated symbols
    
    We haven't been keeping this updated.  So, while we don't expose the
    symbols in the headers if HB_DISABLE_DEPRECATED is defined, we still
    always build them.

diff --git a/src/hb-font.cc b/src/hb-font.cc
index fd0e097a..c9656cee 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -1910,8 +1910,6 @@ hb_font_get_var_coords_normalized (hb_font_t *font,
 }
 
 
-#ifndef HB_DISABLE_DEPRECATED
-
 /*
  * Deprecated get_glyph_func():
  */
@@ -2034,5 +2032,3 @@ hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
 					  trampoline,
 					  trampoline_destroy);
 }
-
-#endif /* HB_DISABLE_DEPRECATED */
commit c55100000bc20d7c8319cfc54294215a923ffc25
Author: David Corbett <corbett.dav at husky.neu.edu>
Date:   Thu Oct 11 22:08:14 2018 -0400

    Add missing colons to GObject annotations

diff --git a/src/hb-ot-tag.cc b/src/hb-ot-tag.cc
index b7c7c4ad..df372e33 100644
--- a/src/hb-ot-tag.cc
+++ b/src/hb-ot-tag.cc
@@ -441,8 +441,8 @@ hb_ot_tag_to_language (hb_tag_t tag)
  * hb_ot_tags_to_script_and_language:
  * @script_tag: a script tag
  * @language_tag: a language tag
- * @script (allow-none): the #hb_script_t corresponding to @script_tag (OUT).
- * @language (allow-none): the #hb_language_t corresponding to @script_tag and
+ * @script: (allow-none): the #hb_script_t corresponding to @script_tag (OUT).
+ * @language: (allow-none): the #hb_language_t corresponding to @script_tag and
  * @language_tag (OUT).
  *
  * Converts a script tag and a language tag to an #hb_script_t and an


More information about the HarfBuzz mailing list