src/Makefile.am | 2 src/Makefile.sources | 3 src/hb-common.cc | 334 ++++++++++++++++++++++++++++++++++++++++++++ src/hb-common.h | 31 ++++ src/hb-font.cc | 4 src/hb-ft.cc | 2 src/hb-ot-layout-private.hh | 6 src/hb-ot-layout.cc | 4 src/hb-ot-math.cc | 7 src/hb-ot-var-fvar-table.hh | 208 +++++++++++++++++++++++++++ src/hb-ot-var.cc | 100 +++++++++++++ src/hb-ot-var.h | 96 ++++++++++++ src/hb-ot.h | 1 src/hb-shape.cc | 248 -------------------------------- src/hb-shape.h | 16 -- test/api/test-ot-math.c | 32 +++- 16 files changed, 812 insertions(+), 282 deletions(-)
New commits: commit b3c0714b4bbb726b2b3e5e0416ac84cb5c6eb34e Author: Behdad Esfahbod <beh...@behdad.org> Date: Fri Jan 20 20:30:03 2017 -0800 [var] Add hb_var_coord_t and parsing routines diff --git a/src/hb-common.cc b/src/hb-common.cc index 04d9fb0..25c979c 100644 --- a/src/hb-common.cc +++ b/src/hb-common.cc @@ -607,7 +607,8 @@ hb_version_atleast (unsigned int major, } -/* hb_feature_t */ + +/* hb_feature_t and hb_var_coord_t */ static bool parse_space (const char **pp, const char *end) @@ -654,6 +655,28 @@ parse_uint (const char **pp, const char *end, unsigned int *pv) } static bool +parse_float (const char **pp, const char *end, float *pv) +{ + char buf[32]; + unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp)); + strncpy (buf, *pp, len); + buf[len] = '\0'; + + char *p = buf; + char *pend = p; + float v; + + errno = 0; + v = strtof (p, &pend); + if (errno || p == pend) + return false; + + *pv = v; + *pp += pend - p; + return true; +} + +static bool parse_bool (const char **pp, const char *end, unsigned int *pv) { parse_space (pp, end); @@ -673,6 +696,8 @@ parse_bool (const char **pp, const char *end, unsigned int *pv) return true; } +/* hb_feature_t */ + static bool parse_feature_value_prefix (const char **pp, const char *end, hb_feature_t *feature) { @@ -687,7 +712,7 @@ parse_feature_value_prefix (const char **pp, const char *end, hb_feature_t *feat } static bool -parse_feature_tag (const char **pp, const char *end, hb_feature_t *feature) +parse_tag (const char **pp, const char *end, hb_tag_t *tag) { parse_space (pp, end); @@ -706,7 +731,7 @@ parse_feature_tag (const char **pp, const char *end, hb_feature_t *feature) if (p == *pp || *pp - p > 4) return false; - feature->tag = hb_tag_from_string (p, *pp - p); + *tag = hb_tag_from_string (p, *pp - p); if (quote) { @@ -759,12 +784,11 @@ parse_feature_value_postfix (const char **pp, const char *end, hb_feature_t *fea return !had_equal || had_value; } - static bool parse_one_feature (const char **pp, const char *end, hb_feature_t *feature) { return parse_feature_value_prefix (pp, end, feature) && - parse_feature_tag (pp, end, feature) && + parse_tag (pp, end, &feature->tag) && parse_feature_indices (pp, end, feature) && parse_feature_value_postfix (pp, end, feature) && parse_space (pp, end) && @@ -855,3 +879,63 @@ hb_feature_to_string (hb_feature_t *feature, memcpy (buf, s, len); buf[len] = '\0'; } + +/* hb_var_coord_t */ + +static bool +parse_var_coord_value (const char **pp, const char *end, hb_var_coord_t *var_coord) +{ + parse_char (pp, end, '='); /* Optional. */ + return parse_float (pp, end, &var_coord->value); +} + +static bool +parse_one_var_coord (const char **pp, const char *end, hb_var_coord_t *var_coord) +{ + return parse_tag (pp, end, &var_coord->tag) && + parse_var_coord_value (pp, end, var_coord) && + parse_space (pp, end) && + *pp == end; +} + +hb_bool_t +hb_var_coord_from_string (const char *str, int len, + hb_var_coord_t *var_coord) +{ + hb_var_coord_t coord; + + if (len < 0) + len = strlen (str); + + if (likely (parse_one_var_coord (&str, str + len, &coord))) + { + if (var_coord) + *var_coord = coord; + return true; + } + + if (var_coord) + memset (var_coord, 0, sizeof (*var_coord)); + return false; +} + +void +hb_var_coord_to_string (hb_var_coord_t *var_coord, + char *buf, unsigned int size) +{ + if (unlikely (!size)) return; + + char s[128]; + unsigned int len = 0; + hb_tag_to_string (var_coord->tag, s + len); + len += 4; + while (len && s[len - 1] == ' ') + len--; + s[len++] = '='; + len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%g", var_coord->value)); + + assert (len < ARRAY_LENGTH (s)); + len = MIN (len, size - 1); + memcpy (buf, s, len); + buf[len] = '\0'; +} diff --git a/src/hb-common.h b/src/hb-common.h index dd72a9d..e483fb8 100644 --- a/src/hb-common.h +++ b/src/hb-common.h @@ -362,7 +362,7 @@ typedef struct hb_user_data_key_t { typedef void (*hb_destroy_func_t) (void *user_data); -/* Font features. */ +/* Font features and variations. */ typedef struct hb_feature_t { hb_tag_t tag; @@ -379,6 +379,19 @@ HB_EXTERN void hb_feature_to_string (hb_feature_t *feature, char *buf, unsigned int size); +typedef struct hb_var_coord_t { + hb_tag_t tag; + float value; +} hb_var_coord_t; + +HB_EXTERN hb_bool_t +hb_var_coord_from_string (const char *str, int len, + hb_var_coord_t *var_coord); + +HB_EXTERN void +hb_var_coord_to_string (hb_var_coord_t *var_coord, + char *buf, unsigned int size); + HB_END_DECLS commit 72364103bc9d910d19f23a3764d045af79d076d5 Author: Behdad Esfahbod <beh...@behdad.org> Date: Fri Jan 20 20:16:53 2017 -0800 Move code around diff --git a/src/hb-common.cc b/src/hb-common.cc index 3564e43..04d9fb0 100644 --- a/src/hb-common.cc +++ b/src/hb-common.cc @@ -605,3 +605,253 @@ hb_version_atleast (unsigned int major, { return HB_VERSION_ATLEAST (major, minor, micro); } + + +/* hb_feature_t */ + +static bool +parse_space (const char **pp, const char *end) +{ + while (*pp < end && ISSPACE (**pp)) + (*pp)++; + return true; +} + +static bool +parse_char (const char **pp, const char *end, char c) +{ + parse_space (pp, end); + + if (*pp == end || **pp != c) + return false; + + (*pp)++; + return true; +} + +static bool +parse_uint (const char **pp, const char *end, unsigned int *pv) +{ + char buf[32]; + unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp)); + strncpy (buf, *pp, len); + buf[len] = '\0'; + + char *p = buf; + char *pend = p; + unsigned int v; + + /* Intentionally use strtol instead of strtoul, such that + * -1 turns into "big number"... */ + errno = 0; + v = strtol (p, &pend, 0); + if (errno || p == pend) + return false; + + *pv = v; + *pp += pend - p; + return true; +} + +static bool +parse_bool (const char **pp, const char *end, unsigned int *pv) +{ + parse_space (pp, end); + + const char *p = *pp; + while (*pp < end && ISALPHA(**pp)) + (*pp)++; + + /* CSS allows on/off as aliases 1/0. */ + if (*pp - p == 2 || 0 == strncmp (p, "on", 2)) + *pv = 1; + else if (*pp - p == 3 || 0 == strncmp (p, "off", 2)) + *pv = 0; + else + return false; + + return true; +} + +static bool +parse_feature_value_prefix (const char **pp, const char *end, hb_feature_t *feature) +{ + if (parse_char (pp, end, '-')) + feature->value = 0; + else { + parse_char (pp, end, '+'); + feature->value = 1; + } + + return true; +} + +static bool +parse_feature_tag (const char **pp, const char *end, hb_feature_t *feature) +{ + parse_space (pp, end); + + char quote = 0; + + if (*pp < end && (**pp == '\'' || **pp == '"')) + { + quote = **pp; + (*pp)++; + } + + const char *p = *pp; + while (*pp < end && ISALNUM(**pp)) + (*pp)++; + + if (p == *pp || *pp - p > 4) + return false; + + feature->tag = hb_tag_from_string (p, *pp - p); + + if (quote) + { + /* CSS expects exactly four bytes. And we only allow quotations for + * CSS compatibility. So, enforce the length. */ + if (*pp - p != 4) + return false; + if (*pp == end || **pp != quote) + return false; + (*pp)++; + } + + return true; +} + +static bool +parse_feature_indices (const char **pp, const char *end, hb_feature_t *feature) +{ + parse_space (pp, end); + + bool has_start; + + feature->start = 0; + feature->end = (unsigned int) -1; + + if (!parse_char (pp, end, '[')) + return true; + + has_start = parse_uint (pp, end, &feature->start); + + if (parse_char (pp, end, ':')) { + parse_uint (pp, end, &feature->end); + } else { + if (has_start) + feature->end = feature->start + 1; + } + + return parse_char (pp, end, ']'); +} + +static bool +parse_feature_value_postfix (const char **pp, const char *end, hb_feature_t *feature) +{ + bool had_equal = parse_char (pp, end, '='); + bool had_value = parse_uint (pp, end, &feature->value) || + parse_bool (pp, end, &feature->value); + /* CSS doesn't use equal-sign between tag and value. + * If there was an equal-sign, then there *must* be a value. + * A value without an eqaul-sign is ok, but not required. */ + return !had_equal || had_value; +} + + +static bool +parse_one_feature (const char **pp, const char *end, hb_feature_t *feature) +{ + return parse_feature_value_prefix (pp, end, feature) && + parse_feature_tag (pp, end, feature) && + parse_feature_indices (pp, end, feature) && + parse_feature_value_postfix (pp, end, feature) && + parse_space (pp, end) && + *pp == end; +} + +/** + * hb_feature_from_string: + * @str: (array length=len) (element-type uint8_t): a string to parse + * @len: length of @str, or -1 if string is %NULL terminated + * @feature: (out): the #hb_feature_t to initialize with the parsed values + * + * Parses a string into a #hb_feature_t. + * + * TODO: document the syntax here. + * + * Return value: + * %true if @str is successfully parsed, %false otherwise. + * + * Since: 0.9.5 + **/ +hb_bool_t +hb_feature_from_string (const char *str, int len, + hb_feature_t *feature) +{ + hb_feature_t feat; + + if (len < 0) + len = strlen (str); + + if (likely (parse_one_feature (&str, str + len, &feat))) + { + if (feature) + *feature = feat; + return true; + } + + if (feature) + memset (feature, 0, sizeof (*feature)); + return false; +} + +/** + * hb_feature_to_string: + * @feature: an #hb_feature_t to convert + * @buf: (array length=size) (out): output string + * @size: the allocated size of @buf + * + * Converts a #hb_feature_t into a %NULL-terminated string in the format + * understood by hb_feature_from_string(). The client in responsible for + * allocating big enough size for @buf, 128 bytes is more than enough. + * + * Since: 0.9.5 + **/ +void +hb_feature_to_string (hb_feature_t *feature, + char *buf, unsigned int size) +{ + if (unlikely (!size)) return; + + char s[128]; + unsigned int len = 0; + if (feature->value == 0) + s[len++] = '-'; + hb_tag_to_string (feature->tag, s + len); + len += 4; + while (len && s[len - 1] == ' ') + len--; + if (feature->start != 0 || feature->end != (unsigned int) -1) + { + s[len++] = '['; + if (feature->start) + len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->start)); + if (feature->end != feature->start + 1) { + s[len++] = ':'; + if (feature->end != (unsigned int) -1) + len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->end)); + } + s[len++] = ']'; + } + if (feature->value > 1) + { + s[len++] = '='; + len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->value)); + } + assert (len < ARRAY_LENGTH (s)); + len = MIN (len, size - 1); + memcpy (buf, s, len); + buf[len] = '\0'; +} diff --git a/src/hb-common.h b/src/hb-common.h index 2cbee76..dd72a9d 100644 --- a/src/hb-common.h +++ b/src/hb-common.h @@ -362,6 +362,24 @@ typedef struct hb_user_data_key_t { typedef void (*hb_destroy_func_t) (void *user_data); +/* Font features. */ + +typedef struct hb_feature_t { + hb_tag_t tag; + uint32_t value; + unsigned int start; + unsigned int end; +} hb_feature_t; + +HB_EXTERN hb_bool_t +hb_feature_from_string (const char *str, int len, + hb_feature_t *feature); + +HB_EXTERN void +hb_feature_to_string (hb_feature_t *feature, + char *buf, unsigned int size); + + HB_END_DECLS #endif /* HB_COMMON_H */ diff --git a/src/hb-shape.cc b/src/hb-shape.cc index 706f144..f57cad9 100644 --- a/src/hb-shape.cc +++ b/src/hb-shape.cc @@ -45,254 +45,6 @@ * contains the output glyphs and their positions. **/ -static bool -parse_space (const char **pp, const char *end) -{ - while (*pp < end && ISSPACE (**pp)) - (*pp)++; - return true; -} - -static bool -parse_char (const char **pp, const char *end, char c) -{ - parse_space (pp, end); - - if (*pp == end || **pp != c) - return false; - - (*pp)++; - return true; -} - -static bool -parse_uint (const char **pp, const char *end, unsigned int *pv) -{ - char buf[32]; - unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp)); - strncpy (buf, *pp, len); - buf[len] = '\0'; - - char *p = buf; - char *pend = p; - unsigned int v; - - /* Intentionally use strtol instead of strtoul, such that - * -1 turns into "big number"... */ - errno = 0; - v = strtol (p, &pend, 0); - if (errno || p == pend) - return false; - - *pv = v; - *pp += pend - p; - return true; -} - -static bool -parse_bool (const char **pp, const char *end, unsigned int *pv) -{ - parse_space (pp, end); - - const char *p = *pp; - while (*pp < end && ISALPHA(**pp)) - (*pp)++; - - /* CSS allows on/off as aliases 1/0. */ - if (*pp - p == 2 || 0 == strncmp (p, "on", 2)) - *pv = 1; - else if (*pp - p == 3 || 0 == strncmp (p, "off", 2)) - *pv = 0; - else - return false; - - return true; -} - -static bool -parse_feature_value_prefix (const char **pp, const char *end, hb_feature_t *feature) -{ - if (parse_char (pp, end, '-')) - feature->value = 0; - else { - parse_char (pp, end, '+'); - feature->value = 1; - } - - return true; -} - -static bool -parse_feature_tag (const char **pp, const char *end, hb_feature_t *feature) -{ - parse_space (pp, end); - - char quote = 0; - - if (*pp < end && (**pp == '\'' || **pp == '"')) - { - quote = **pp; - (*pp)++; - } - - const char *p = *pp; - while (*pp < end && ISALNUM(**pp)) - (*pp)++; - - if (p == *pp || *pp - p > 4) - return false; - - feature->tag = hb_tag_from_string (p, *pp - p); - - if (quote) - { - /* CSS expects exactly four bytes. And we only allow quotations for - * CSS compatibility. So, enforce the length. */ - if (*pp - p != 4) - return false; - if (*pp == end || **pp != quote) - return false; - (*pp)++; - } - - return true; -} - -static bool -parse_feature_indices (const char **pp, const char *end, hb_feature_t *feature) -{ - parse_space (pp, end); - - bool has_start; - - feature->start = 0; - feature->end = (unsigned int) -1; - - if (!parse_char (pp, end, '[')) - return true; - - has_start = parse_uint (pp, end, &feature->start); - - if (parse_char (pp, end, ':')) { - parse_uint (pp, end, &feature->end); - } else { - if (has_start) - feature->end = feature->start + 1; - } - - return parse_char (pp, end, ']'); -} - -static bool -parse_feature_value_postfix (const char **pp, const char *end, hb_feature_t *feature) -{ - bool had_equal = parse_char (pp, end, '='); - bool had_value = parse_uint (pp, end, &feature->value) || - parse_bool (pp, end, &feature->value); - /* CSS doesn't use equal-sign between tag and value. - * If there was an equal-sign, then there *must* be a value. - * A value without an eqaul-sign is ok, but not required. */ - return !had_equal || had_value; -} - - -static bool -parse_one_feature (const char **pp, const char *end, hb_feature_t *feature) -{ - return parse_feature_value_prefix (pp, end, feature) && - parse_feature_tag (pp, end, feature) && - parse_feature_indices (pp, end, feature) && - parse_feature_value_postfix (pp, end, feature) && - parse_space (pp, end) && - *pp == end; -} - -/** - * hb_feature_from_string: - * @str: (array length=len) (element-type uint8_t): a string to parse - * @len: length of @str, or -1 if string is %NULL terminated - * @feature: (out): the #hb_feature_t to initialize with the parsed values - * - * Parses a string into a #hb_feature_t. - * - * TODO: document the syntax here. - * - * Return value: - * %true if @str is successfully parsed, %false otherwise. - * - * Since: 0.9.5 - **/ -hb_bool_t -hb_feature_from_string (const char *str, int len, - hb_feature_t *feature) -{ - hb_feature_t feat; - - if (len < 0) - len = strlen (str); - - if (likely (parse_one_feature (&str, str + len, &feat))) - { - if (feature) - *feature = feat; - return true; - } - - if (feature) - memset (feature, 0, sizeof (*feature)); - return false; -} - -/** - * hb_feature_to_string: - * @feature: an #hb_feature_t to convert - * @buf: (array length=size) (out): output string - * @size: the allocated size of @buf - * - * Converts a #hb_feature_t into a %NULL-terminated string in the format - * understood by hb_feature_from_string(). The client in responsible for - * allocating big enough size for @buf, 128 bytes is more than enough. - * - * Since: 0.9.5 - **/ -void -hb_feature_to_string (hb_feature_t *feature, - char *buf, unsigned int size) -{ - if (unlikely (!size)) return; - - char s[128]; - unsigned int len = 0; - if (feature->value == 0) - s[len++] = '-'; - hb_tag_to_string (feature->tag, s + len); - len += 4; - while (len && s[len - 1] == ' ') - len--; - if (feature->start != 0 || feature->end != (unsigned int) -1) - { - s[len++] = '['; - if (feature->start) - len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->start)); - if (feature->end != feature->start + 1) { - s[len++] = ':'; - if (feature->end != (unsigned int) -1) - len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->end)); - } - s[len++] = ']'; - } - if (feature->value > 1) - { - s[len++] = '='; - len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->value)); - } - assert (len < ARRAY_LENGTH (s)); - len = MIN (len, size - 1); - memcpy (buf, s, len); - buf[len] = '\0'; -} - - static const char **static_shaper_list; #ifdef HB_USE_ATEXIT diff --git a/src/hb-shape.h b/src/hb-shape.h index 53bb845..39507ff 100644 --- a/src/hb-shape.h +++ b/src/hb-shape.h @@ -40,22 +40,6 @@ HB_BEGIN_DECLS -typedef struct hb_feature_t { - hb_tag_t tag; - uint32_t value; - unsigned int start; - unsigned int end; -} hb_feature_t; - -HB_EXTERN hb_bool_t -hb_feature_from_string (const char *str, int len, - hb_feature_t *feature); - -HB_EXTERN void -hb_feature_to_string (hb_feature_t *feature, - char *buf, unsigned int size); - - HB_EXTERN void hb_shape (hb_font_t *font, hb_buffer_t *buffer, commit 785982bf830723552270db5649abcb9f9f0b46b1 Author: Behdad Esfahbod <beh...@behdad.org> Date: Fri Jan 20 19:57:27 2017 -0800 [var] Flesh out some more diff --git a/src/Makefile.am b/src/Makefile.am index 8cfe4ac..d7420a0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -299,6 +299,8 @@ test_buffer_serialize_SOURCES = test-buffer-serialize.cc test_buffer_serialize_CPPFLAGS = $(HBCFLAGS) test_buffer_serialize_LDADD = libharfbuzz.la $(HBLIBS) +check: harfbuzz.def # For check-defs.sh + dist_check_SCRIPTS = \ check-c-linkage-decls.sh \ check-defs.sh \ diff --git a/src/hb-ot-var-fvar-table.hh b/src/hb-ot-var-fvar-table.hh index 39015b3..cb88de8 100644 --- a/src/hb-ot-var-fvar-table.hh +++ b/src/hb-ot-var-fvar-table.hh @@ -99,15 +99,49 @@ struct fvar axisCount * axisSize + instanceCount * instanceSize)); } - inline const AxisRecord * get_axes (void) const - { return &StructAtOffset<AxisRecord> (this, things); } - - inline const InstanceRecord * get_instances (void) const - { return &StructAtOffset<InstanceRecord> (get_axes () + axisCount, 0); } - inline unsigned int get_axis_count (void) const { return axisCount; } + inline bool get_axis (unsigned int index, hb_ot_var_axis_t *info) const + { + if (unlikely (index >= axisCount)) + return false; + + if (info) + { + const AxisRecord &axis = get_axes ()[index]; + info->tag = axis.axisTag; + info->name_id = axis.axisNameID; + info->default_value = axis.defaultValue / 65536.; + /* Ensure order, to simplify client math. */ + info->min_value = MIN<float> (info->default_value, axis.minValue / 65536.); + info->max_value = MAX<float> (info->default_value, axis.maxValue / 65536.); + } + + return true; + } + + inline unsigned int get_axis_infos (unsigned int start_offset, + unsigned int *axes_count /* IN/OUT */, + hb_ot_var_axis_t *axes_array /* OUT */) const + { + if (axes_count) + { + unsigned int count = axisCount; + start_offset = MIN (start_offset, count); + + count -= start_offset; + axes_array += start_offset; + + count = MIN (count, *axes_count); + *axes_count = count; + + for (unsigned int i = 0; i < count; i++) + get_axis (start_offset + i, axes_array + i); + } + return axisCount; + } + inline bool find_axis (hb_tag_t tag, unsigned int *index, hb_ot_var_axis_t *info) const { const AxisRecord *axes = get_axes (); @@ -117,27 +151,17 @@ struct fvar { if (index) *index = i; - if (info) - { - const AxisRecord &axis = axes[i]; - info->tag = axis.axisTag; - info->name_id = axis.axisNameID; - info->default_value = axis.defaultValue / 65536.; - /* Ensure order, to simplify client math. */ - info->min_value = MIN<float> (info->default_value, axis.minValue / 65536.); - info->max_value = MAX<float> (info->default_value, axis.maxValue / 65536.); - } - return true; + return get_axis (i, info); } if (index) *index = HB_OT_VAR_NO_AXIS_INDEX; return false; } - inline int normalize_axis_value (hb_tag_t tag, float v, unsigned int *axis_index) const + inline int normalize_axis_value (unsigned int axis_index, float v) const { hb_ot_var_axis_t axis; - if (!find_axis (tag, axis_index, &axis)) + if (!get_axis (axis_index, &axis)) return 0; v = MAX (MIN (v, axis.max_value), axis.min_value); /* Clamp. */ @@ -152,6 +176,13 @@ struct fvar } protected: + inline const AxisRecord * get_axes (void) const + { return &StructAtOffset<AxisRecord> (this, things); } + + inline const InstanceRecord * get_instances (void) const + { return &StructAtOffset<InstanceRecord> (get_axes () + axisCount, 0); } + + protected: FixedVersion<>version; /* Version of the fvar table * initially set to 0x00010000u */ Offset<> things; /* Offset in bytes from the beginning of the table diff --git a/src/hb-ot-var.cc b/src/hb-ot-var.cc index c9dcb1f..d1e9725 100644 --- a/src/hb-ot-var.cc +++ b/src/hb-ot-var.cc @@ -43,7 +43,7 @@ _get_fvar (hb_face_t *face) } /* - * OT::fvar + * fvar/avar */ /** @@ -51,6 +51,7 @@ _get_fvar (hb_face_t *face) * @face: #hb_face_t to test * * This function allows to verify the presence of OpenType variation data on the face. + * Alternatively, use hb_ot_var_get_axis_count(). * * Return value: true if face has a `fvar' table and false otherwise * @@ -61,3 +62,39 @@ hb_ot_var_has_data (hb_face_t *face) { return &_get_fvar (face) != &OT::Null(OT::fvar); } + +unsigned int +hb_ot_var_get_axis_count (hb_face_t *face) +{ + const OT::fvar &fvar = _get_fvar (face); + return fvar.get_axis_count (); +} + +unsigned int +hb_ot_var_get_axes (hb_face_t *face, + unsigned int start_offset, + unsigned int *axes_count /* IN/OUT */, + hb_ot_var_axis_t *axes_array /* OUT */) +{ + const OT::fvar &fvar = _get_fvar (face); + return fvar.get_axis_infos (start_offset, axes_count, axes_array); +} + +HB_EXTERN hb_bool_t +hb_ot_var_find_axis (hb_face_t *face, + hb_tag_t axis_tag, + unsigned int *axis_index, + hb_ot_var_axis_t *axis_info) +{ + const OT::fvar &fvar = _get_fvar (face); + return fvar.find_axis (axis_tag, axis_index, axis_info); +} + +HB_EXTERN int +hb_ot_var_normalize_axis_value (hb_face_t *face, + unsigned int axis_index, + float v) +{ + const OT::fvar &fvar = _get_fvar (face); + return fvar.normalize_axis_value (axis_index, v); +} diff --git a/src/hb-ot-var.h b/src/hb-ot-var.h index fd7a5aa..4023b29 100644 --- a/src/hb-ot-var.h +++ b/src/hb-ot-var.h @@ -62,7 +62,14 @@ hb_ot_var_has_data (hb_face_t *face); #define HB_OT_VAR_NO_AXIS_INDEX 0xFFFFFFFFu -#if 0 +HB_EXTERN unsigned int +hb_ot_var_get_axis_count (hb_face_t *face); + +HB_EXTERN unsigned int +hb_ot_var_get_axes (hb_face_t *face, + unsigned int start_offset, + unsigned int *axes_count /* IN/OUT */, + hb_ot_var_axis_t *axes_array /* OUT */); HB_EXTERN hb_bool_t hb_ot_var_find_axis (hb_face_t *face, @@ -70,13 +77,13 @@ hb_ot_var_find_axis (hb_face_t *face, unsigned int *axis_index, hb_ot_var_axis_t *axis_info); -HB_EXTERN unsigned int -Xhb_ot_var_get_axes (hb_face_t *face, - unsigned int start_offset, - unsigned int *axes_count /* IN/OUT */, - hb_ot_var_axis_t *axes_array /* OUT */); -/* TODO Add "find_axis", etc API? Are they needed at all? */ +HB_EXTERN int +hb_ot_var_normalize_axis_value (hb_face_t *face, + unsigned int axis_index, + float v); + +#if 0 HB_EXTERN unsigned int Xhb_ot_var_get_named_instances (hb_face_t *face, ... ); commit 422c0c36c80145a2d993f80d5c7d3265e3d8357a Author: Behdad Esfahbod <beh...@behdad.org> Date: Fri Jan 20 19:14:54 2017 -0800 [var] Flesh out a bit diff --git a/src/hb-ot-var-fvar-table.hh b/src/hb-ot-var-fvar-table.hh index 8461741..39015b3 100644 --- a/src/hb-ot-var-fvar-table.hh +++ b/src/hb-ot-var-fvar-table.hh @@ -63,7 +63,7 @@ struct AxisRecord return_trace (c->check_struct (this)); } - protected: + public: Tag axisTag; /* Tag identifying the design variation for the axis. */ Fixed minValue; /* The minimum coordinate value for the axis. */ Fixed defaultValue; /* The default coordinate value for the axis. */ @@ -89,23 +89,67 @@ struct fvar { TRACE_SANITIZE (this); return_trace (version.sanitize (c) && - likely (version.major == 1) /*&& - mathConstants.sanitize (c, this) && - mathGlyphInfo.sanitize (c, this) && - mathVariants.sanitize (c, this)*/); + likely (version.major == 1) && + c->check_struct (this) && + instanceSize >= axisCount * 4 + 4 && + axisSize <= 1024 && /* Arbitrary, just to simplify overflow checks. */ + instanceSize <= 1024 && /* Arbitrary, just to simplify overflow checks. */ + c->check_range (this, things) && + c->check_range (&StructAtOffset<char> (this, things), + axisCount * axisSize + instanceCount * instanceSize)); } -#if 0 - inline hb_position_t get_constant (hb_ot_math_constant_t constant, - hb_font_t *font) const - { return (this+mathConstants).get_value (constant, font); } + inline const AxisRecord * get_axes (void) const + { return &StructAtOffset<AxisRecord> (this, things); } + + inline const InstanceRecord * get_instances (void) const + { return &StructAtOffset<InstanceRecord> (get_axes () + axisCount, 0); } + + inline unsigned int get_axis_count (void) const + { return axisCount; } - inline const MathGlyphInfo &get_math_glyph_info (void) const - { return this+mathGlyphInfo; } + inline bool find_axis (hb_tag_t tag, unsigned int *index, hb_ot_var_axis_t *info) const + { + const AxisRecord *axes = get_axes (); + unsigned int count = get_axis_count (); + for (unsigned int i = 0; i < count; i++) + if (axes[i].axisTag == tag) + { + if (index) + *index = i; + if (info) + { + const AxisRecord &axis = axes[i]; + info->tag = axis.axisTag; + info->name_id = axis.axisNameID; + info->default_value = axis.defaultValue / 65536.; + /* Ensure order, to simplify client math. */ + info->min_value = MIN<float> (info->default_value, axis.minValue / 65536.); + info->max_value = MAX<float> (info->default_value, axis.maxValue / 65536.); + } + return true; + } + if (index) + *index = HB_OT_VAR_NO_AXIS_INDEX; + return false; + } - inline const MathVariants &get_math_variants (void) const - { return this+mathVariants; } -#endif + inline int normalize_axis_value (hb_tag_t tag, float v, unsigned int *axis_index) const + { + hb_ot_var_axis_t axis; + if (!find_axis (tag, axis_index, &axis)) + return 0; + + v = MAX (MIN (v, axis.max_value), axis.min_value); /* Clamp. */ + + if (v == axis.default_value) + return 0; + else if (v < axis.default_value) + v = (v - axis.default_value) / (axis.default_value - axis.min_value); + else + v = (v - axis.default_value) / (axis.max_value - axis.default_value); + return (int) (v * 16384. + (v >= 0. ? .5 : -.5)); + } protected: FixedVersion<>version; /* Version of the fvar table diff --git a/src/hb-ot-var.h b/src/hb-ot-var.h index 9d73bed..fd7a5aa 100644 --- a/src/hb-ot-var.h +++ b/src/hb-ot-var.h @@ -53,15 +53,23 @@ typedef struct hb_ot_var_axis_t { hb_tag_t tag; unsigned int name_id; float min_value; - float def_value; + float default_value; float max_value; } hb_ot_var_axis_t; HB_EXTERN hb_bool_t hb_ot_var_has_data (hb_face_t *face); +#define HB_OT_VAR_NO_AXIS_INDEX 0xFFFFFFFFu + #if 0 +HB_EXTERN hb_bool_t +hb_ot_var_find_axis (hb_face_t *face, + hb_tag_t axis_tag, + unsigned int *axis_index, + hb_ot_var_axis_t *axis_info); + HB_EXTERN unsigned int Xhb_ot_var_get_axes (hb_face_t *face, unsigned int start_offset, commit b8376b10904e1772b8d34d852d1100ca7e2185e2 Author: Behdad Esfahbod <beh...@behdad.org> Date: Fri Jan 20 18:19:28 2017 -0800 Minor diff --git a/src/hb-ft.cc b/src/hb-ft.cc index f127066..d5f8d52 100644 --- a/src/hb-ft.cc +++ b/src/hb-ft.cc @@ -625,7 +625,7 @@ hb_ft_font_create (FT_Face ft_face, int hbCoords[mm_var->num_axis]; if (!FT_Get_Var_Blend_Coordinates (ft_face, mm_var->num_axis, coords)) { - for (int i = 0; i < mm_var->num_axis; ++i) + for (unsigned int i = 0; i < mm_var->num_axis; ++i) hbCoords[i] = coords[i] >> 2; hb_font_set_var_coords_normalized (font, hbCoords, mm_var->num_axis); commit f2e73d37e77ccea8b948d1ecf5f11e7a699386dc Author: Behdad Esfahbod <beh...@behdad.org> Date: Fri Jan 20 17:42:18 2017 -0800 [var] Remove over-optimization diff --git a/src/hb-font.cc b/src/hb-font.cc index 2935c4b..b91a35b 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -1552,10 +1552,6 @@ hb_font_set_var_coords_normalized (hb_font_t *font, if (font->immutable) return; - /* Skip tail zero entries. */ - while (coords_length && !coords[coords_length - 1]) - coords_length--; - int *copy = coords_length ? (int *) calloc (coords_length, sizeof (coords[0])) : NULL; if (unlikely (coords_length && !copy)) return; commit 469926cc45760cb681d44e5757b18b9bdd736189 Author: Behdad Esfahbod <beh...@behdad.org> Date: Fri Jan 20 17:40:46 2017 -0800 [var] Change double to float in API diff --git a/src/hb-ot-var.h b/src/hb-ot-var.h index 679feb9..9d73bed 100644 --- a/src/hb-ot-var.h +++ b/src/hb-ot-var.h @@ -52,9 +52,9 @@ HB_BEGIN_DECLS typedef struct hb_ot_var_axis_t { hb_tag_t tag; unsigned int name_id; - double min_value; - double def_value; - double max_value; + float min_value; + float def_value; + float max_value; } hb_ot_var_axis_t; HB_EXTERN hb_bool_t commit 55d42fd667b9c34a1109bb850bf2ea7322c01040 Author: Behdad Esfahbod <beh...@behdad.org> Date: Thu Jan 19 19:35:48 2017 -0800 Start adding hb-ot-var.h and implementation Supports enumerating variation axes, normalizing values, etc. diff --git a/src/Makefile.sources b/src/Makefile.sources index b75ec0c..279bc46 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -108,6 +108,8 @@ HB_OT_sources = \ hb-ot-shape-fallback-private.hh \ hb-ot-shape-fallback.cc \ hb-ot-shape-private.hh \ + hb-ot-var.cc \ + hb-ot-var-fvar-table.hh \ $(NULL) HB_OT_headers = \ @@ -117,6 +119,7 @@ HB_OT_headers = \ hb-ot-math.h \ hb-ot-shape.h \ hb-ot-tag.h \ + hb-ot-var.h \ $(NULL) # Optional Sources and Headers with external deps diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh index 1c398e9..8c348be 100644 --- a/src/hb-ot-layout-private.hh +++ b/src/hb-ot-layout-private.hh @@ -126,6 +126,8 @@ namespace OT { struct GSUB; struct GPOS; struct MATH; + struct fvar; + struct avar; } struct hb_ot_layout_lookup_accelerator_t @@ -158,7 +160,11 @@ struct hb_ot_layout_t const struct OT::GDEF *gdef; const struct OT::GSUB *gsub; const struct OT::GPOS *gpos; + + /* TODO Move the following out of this struct. */ OT::hb_lazy_table_loader_t<struct OT::MATH> math; + OT::hb_lazy_table_loader_t<struct OT::fvar> fvar; + OT::hb_lazy_table_loader_t<struct OT::avar> avar; unsigned int gsub_lookup_count; unsigned int gpos_lookup_count; diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index d165402..d8d6284 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -61,6 +61,8 @@ _hb_ot_layout_create (hb_face_t *face) layout->gpos = OT::Sanitizer<OT::GPOS>::lock_instance (layout->gpos_blob); layout->math.init (face); + layout->fvar.init (face); + layout->avar.init (face); { /* @@ -181,6 +183,8 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout) hb_blob_destroy (layout->gpos_blob); layout->math.fini (); + layout->fvar.fini (); + layout->avar.fini (); free (layout); } diff --git a/src/hb-ot-var-fvar-table.hh b/src/hb-ot-var-fvar-table.hh new file mode 100644 index 0000000..8461741 --- /dev/null +++ b/src/hb-ot-var-fvar-table.hh @@ -0,0 +1,133 @@ +/* + * Copyright © 2017 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_OT_VAR_FVAR_TABLE_HH +#define HB_OT_VAR_FVAR_TABLE_HH + +#include "hb-open-type-private.hh" +#include "hb-ot-var.h" + +namespace OT { + + +struct InstanceRecord +{ + inline bool sanitize (hb_sanitize_context_t *c, unsigned int axis_count) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + c->check_array (coordinates, coordinates[0].static_size, axis_count)); + } + + protected: + USHORT subfamilyNameID;/* The name ID for entries in the 'name' table + * that provide subfamily names for this instance. */ + USHORT reserved; /* Reserved for future use â set to 0. */ + Fixed coordinates[VAR];/* The coordinates array for this instance. */ + //USHORT postScriptNameIDX;/*Optional. The name ID for entries in the 'name' + // * table that provide PostScript names for this + // * instance. */ + + public: + DEFINE_SIZE_ARRAY (4, coordinates); +}; + +struct AxisRecord +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + protected: + Tag axisTag; /* Tag identifying the design variation for the axis. */ + Fixed minValue; /* The minimum coordinate value for the axis. */ + Fixed defaultValue; /* The default coordinate value for the axis. */ + Fixed maxValue; /* The maximum coordinate value for the axis. */ + USHORT reserved; /* Reserved for future use â set to 0. */ + USHORT axisNameID; /* The name ID for entries in the 'name' table that + * provide a display name for this axis. */ + + public: + DEFINE_SIZE_STATIC (20); +}; + + +/* + * fvar â Font Variations Table + */ + +struct fvar +{ + static const hb_tag_t tableTag = HB_OT_TAG_fvar; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (version.sanitize (c) && + likely (version.major == 1) /*&& + mathConstants.sanitize (c, this) && + mathGlyphInfo.sanitize (c, this) && + mathVariants.sanitize (c, this)*/); + } + +#if 0 + inline hb_position_t get_constant (hb_ot_math_constant_t constant, + hb_font_t *font) const + { return (this+mathConstants).get_value (constant, font); } + + inline const MathGlyphInfo &get_math_glyph_info (void) const + { return this+mathGlyphInfo; } + + inline const MathVariants &get_math_variants (void) const + { return this+mathVariants; } +#endif + + protected: + FixedVersion<>version; /* Version of the fvar table + * initially set to 0x00010000u */ + Offset<> things; /* Offset in bytes from the beginning of the table + * to the start of the AxisRecord array. */ + USHORT reserved; /* This field is permanently reserved. Set to 2. */ + USHORT axisCount; /* The number of variation axes in the font (the + * number of records in the axes array). */ + USHORT axisSize; /* The size in bytes of each VariationAxisRecord â + * set to 20 (0x0014) for this version. */ + USHORT instanceCount; /* The number of named instances defined in the font + * (the number of records in the instances array). */ + USHORT instanceSize; /* The size in bytes of each InstanceRecord â set + * to either axisCount * sizeof(Fixed) + 4, or to + * axisCount * sizeof(Fixed) + 6. */ + + public: + DEFINE_SIZE_STATIC (16); +}; + +} /* namespace OT */ + + +#endif /* HB_OT_VAR_FVAR_TABLE_HH */ diff --git a/src/hb-ot-var.cc b/src/hb-ot-var.cc new file mode 100644 index 0000000..c9dcb1f --- /dev/null +++ b/src/hb-ot-var.cc @@ -0,0 +1,63 @@ +/* + * Copyright © 2017 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 "hb-open-type-private.hh" + +#include "hb-ot-layout-private.hh" +#include "hb-ot-var-fvar-table.hh" +#include "hb-ot-var.h" + +HB_SHAPER_DATA_ENSURE_DECLARE(ot, face) + +static inline const OT::fvar& +_get_fvar (hb_face_t *face) +{ + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::fvar); + + hb_ot_layout_t * layout = hb_ot_layout_from_face (face); + + return *(layout->fvar.get ()); +} + +/* + * OT::fvar + */ + +/** + * hb_ot_var_has_data: + * @face: #hb_face_t to test + * + * This function allows to verify the presence of OpenType variation data on the face. + * + * Return value: true if face has a `fvar' table and false otherwise + * + * Since: 1.4.2 + **/ +hb_bool_t +hb_ot_var_has_data (hb_face_t *face) +{ + return &_get_fvar (face) != &OT::Null(OT::fvar); +} diff --git a/src/hb-ot-var.h b/src/hb-ot-var.h new file mode 100644 index 0000000..679feb9 --- /dev/null +++ b/src/hb-ot-var.h @@ -0,0 +1,81 @@ +/* + * Copyright © 2017 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. + * + * Red Hat Author(s): Behdad Esfahbod + */ + +#ifndef HB_OT_H_IN +#error "Include <hb-ot.h> instead." +#endif + +#ifndef HB_OT_VAR_H +#define HB_OT_VAR_H + +#include "hb.h" + +HB_BEGIN_DECLS + + +#define HB_OT_TAG_fvar HB_TAG('f','v','a','r') +#define HB_OT_TAG_avar HB_TAG('a','v','a','r') + + +/* + * fvar / avar + */ + +/** + * hb_ot_var_axis_t: + * + * Since: 1.4.2 + */ +typedef struct hb_ot_var_axis_t { + hb_tag_t tag; + unsigned int name_id; + double min_value; + double def_value; + double max_value; +} hb_ot_var_axis_t; + +HB_EXTERN hb_bool_t +hb_ot_var_has_data (hb_face_t *face); + +#if 0 + +HB_EXTERN unsigned int +Xhb_ot_var_get_axes (hb_face_t *face, + unsigned int start_offset, + unsigned int *axes_count /* IN/OUT */, + hb_ot_var_axis_t *axes_array /* OUT */); + +/* TODO Add "find_axis", etc API? Are they needed at all? */ + +HB_EXTERN unsigned int +Xhb_ot_var_get_named_instances (hb_face_t *face, ... ); + +#endif + + +HB_END_DECLS + +#endif /* HB_OT_VAR_H */ diff --git a/src/hb-ot.h b/src/hb-ot.h index 113e37b..2120a3e 100644 --- a/src/hb-ot.h +++ b/src/hb-ot.h @@ -35,6 +35,7 @@ #include "hb-ot-math.h" #include "hb-ot-tag.h" #include "hb-ot-shape.h" +#include "hb-ot-var.h" HB_BEGIN_DECLS commit 272b5115325b785e92ff5500d4bfc3a67490b6f8 Author: Behdad Esfahbod <beh...@behdad.org> Date: Thu Jan 19 19:33:07 2017 -0800 Minor diff --git a/src/hb-ot-math.cc b/src/hb-ot-math.cc index 40414eb..ec8df2c 100644 --- a/src/hb-ot-math.cc +++ b/src/hb-ot-math.cc @@ -49,10 +49,9 @@ _get_math (hb_face_t *face) * @face: #hb_face_t to test * * This function allows to verify the presence of an OpenType MATH table on the - * face. If so, such a table will be loaded into memory and sanitized. You can - * then safely call other functions for math layout and shaping. + * face. * - * Return value: #TRUE if face has a MATH table and #FALSE otherwise + * Return value: true if face has a MATH table, false otherwise * * Since: 1.3.3 **/ @@ -124,7 +123,7 @@ hb_ot_math_get_glyph_top_accent_attachment (hb_font_t *font, * @font: a #hb_font_t to test * @glyph: a glyph index to test * - * Return value: #TRUE if the glyph is an extended shape and #FALSE otherwise + * Return value: true if the glyph is an extended shape, false otherwise * * Since: 1.3.3 **/ commit a8a5e81a52f56f5f8bf975dc4d9f79bede5d895b Author: Behdad Esfahbod <beh...@behdad.org> Date: Thu Jan 19 16:55:04 2017 -0800 [test-ot-math] Add test with nil face/font diff --git a/test/api/test-ot-math.c b/test/api/test-ot-math.c index b9fcb65..0ca5566 100644 --- a/test/api/test-ot-math.c +++ b/test/api/test-ot-math.c @@ -97,6 +97,14 @@ test_has_data (void) g_assert(hb_ot_math_has_data (hb_face)); // MATH table available closeFont(); + hb_face = hb_face_get_empty (); + hb_font = hb_font_create (hb_face); + g_assert(!hb_ot_math_has_data (hb_face)); // MATH table not available + + hb_font = hb_font_get_empty (); + hb_face = hb_font_get_face (hb_font); + g_assert(!hb_ot_math_has_data (hb_face)); // MATH table not available + cleanupFreeType(); } commit 331d07bd40a3d9ff30db5cdf85fdc4f10f0fcb99 Author: Behdad Esfahbod <beh...@behdad.org> Date: Thu Jan 19 16:51:36 2017 -0800 Minor diff --git a/test/api/test-ot-math.c b/test/api/test-ot-math.c index e7a6fc8..b9fcb65 100644 --- a/test/api/test-ot-math.c +++ b/test/api/test-ot-math.c @@ -79,6 +79,9 @@ closeFont (void) hb_face_destroy (hb_face); hb_font_destroy (hb_font); FT_Done_Face (ft_face); + hb_face = NULL; + hb_font = NULL; + ft_face = NULL; } static void commit b5ecf1bfa459a755e36bc4c7f545c7f803b7d016 Author: Behdad Esfahbod <beh...@behdad.org> Date: Thu Jan 19 16:50:29 2017 -0800 Fix warnings diff --git a/test/api/test-ot-math.c b/test/api/test-ot-math.c index cfac109..e7a6fc8 100644 --- a/test/api/test-ot-math.c +++ b/test/api/test-ot-math.c @@ -401,6 +401,11 @@ static void test_get_glyph_variants (void) { hb_codepoint_t glyph; + hb_ot_math_glyph_variant_t variants[20]; + unsigned variantsSize = sizeof (variants) / sizeof (variants[0]); + unsigned int count; + unsigned int offset = 0; + initFreeType(); openFont("fonts/MathTestFontEmpty.otf"); @@ -464,10 +469,6 @@ test_get_glyph_variants (void) NULL), ==, 0); g_assert(hb_font_get_glyph_from_name (hb_font, "arrowleft", -1, &glyph)); - hb_ot_math_glyph_variant_t variants[20]; - unsigned variantsSize = sizeof (variants) / sizeof (variants[0]); - unsigned int count; - unsigned int offset = 0; do { count = variantsSize; hb_ot_math_get_glyph_variants (hb_font, @@ -524,6 +525,11 @@ static void test_get_glyph_assembly (void) { hb_codepoint_t glyph; + hb_ot_math_glyph_part_t parts[20]; + unsigned partsSize = sizeof (parts) / sizeof (parts[0]); + unsigned int count; + unsigned int offset = 0; + initFreeType(); openFont("fonts/MathTestFontEmpty.otf"); @@ -591,10 +597,6 @@ test_get_glyph_assembly (void) NULL), ==, 0); g_assert(hb_font_get_glyph_from_name (hb_font, "arrowright", -1, &glyph)); - hb_ot_math_glyph_part_t parts[20]; - unsigned partsSize = sizeof (parts) / sizeof (parts[0]); - unsigned int count; - unsigned int offset = 0; do { count = partsSize; hb_ot_math_get_glyph_assembly (hb_font, commit 2f2ceee1853649d1b2ad4315a38cd9c07659932a Author: Behdad Esfahbod <beh...@behdad.org> Date: Thu Jan 19 16:48:01 2017 -0800 Minor diff --git a/test/api/test-ot-math.c b/test/api/test-ot-math.c index 049656a..cfac109 100644 --- a/test/api/test-ot-math.c +++ b/test/api/test-ot-math.c @@ -70,12 +70,13 @@ openFont(const char* fontFile) if ((ft_error = FT_Set_Char_Size (ft_face, 2000, 1000, 0, 0))) abort(); hb_font = hb_ft_font_create (ft_face, NULL); - hb_face = hb_ft_face_create_cached(ft_face); + hb_face = hb_face_reference (hb_font_get_face (hb_font)); } static inline void closeFont (void) { + hb_face_destroy (hb_face); hb_font_destroy (hb_font); FT_Done_Face (ft_face); }
_______________________________________________ HarfBuzz mailing list HarfBuzz@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/harfbuzz