[var] Add hb_var_coord_t and parsing routines

pull/407/head
Behdad Esfahbod 8 years ago
parent 72364103bc
commit b3c0714b4b
  1. 94
      src/hb-common.cc
  2. 15
      src/hb-common.h

@ -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)
@ -653,6 +654,28 @@ parse_uint (const char **pp, const char *end, unsigned int *pv)
return true;
}
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)
{
@ -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';
}

@ -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

Loading…
Cancel
Save