diff options
Diffstat (limited to 'util/hb-subset.cc')
-rw-r--r-- | util/hb-subset.cc | 84 |
1 files changed, 69 insertions, 15 deletions
diff --git a/util/hb-subset.cc b/util/hb-subset.cc index 599c7dc4e..bd3df8f57 100644 --- a/util/hb-subset.cc +++ b/util/hb-subset.cc @@ -707,34 +707,88 @@ parse_instance (const char *name, return false; } - if (strcmp (s, "drop") == 0) +#ifdef HB_EXPERIMENTAL_API + char *pp = s; + pp = strpbrk (pp, ":"); + if (pp) // partial instancing { - if (!hb_subset_input_pin_axis_to_default (subset_main->input, subset_main->face, axis_tag)) + errno = 0; + char *pend; + float min_val = strtof (s, &pend); + if (errno || s == pend || pend != pp) { g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, - "Cannot pin axis: '%c%c%c%c', not present in fvar", HB_UNTAG (axis_tag)); + "Failed parsing axis value at: '%s'", s); return false; } - } - else - { - errno = 0; - char *p; - float axis_value = strtof (s, &p); - if (errno || s == p) + pp++; + float max_val = strtof (pp, &pend); + /* we need to specify 2 values or 3 values for partial instancing: + * at least new min and max values, new default is optional */ + if (errno || pp == pend || (*pend != ':' && *pend != '\0')) { g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Failed parsing axis value at: '%s'", s); return false; } - - if (!hb_subset_input_pin_axis_location (subset_main->input, subset_main->face, axis_tag, axis_value)) + /* 3 values are specified */ + float *def_val_p = nullptr; + float def_val; + if (*pend == ':') { - g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, - "Cannot pin axis: '%c%c%c%c', not present in fvar", HB_UNTAG (axis_tag)); - return false; + def_val = max_val; + def_val_p = &def_val; + pp = pend + 1; + max_val = strtof (pp, &pend); + if (errno || pp == pend || *pend != '\0') + { + g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, + "Failed parsing axis value at: '%s'", s); + return false; + } } + if (!hb_subset_input_set_axis_range (subset_main->input, subset_main->face, axis_tag, min_val, max_val, def_val_p)) + { + g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, + "Error: axis: '%c%c%c%c', not present in fvar or invalid range with min:%.6f max:%.6f", + HB_UNTAG (axis_tag), min_val, max_val); + return false; + } } + else + { +#endif + if (strcmp (s, "drop") == 0) + { + if (!hb_subset_input_pin_axis_to_default (subset_main->input, subset_main->face, axis_tag)) + { + g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, + "Cannot pin axis: '%c%c%c%c', not present in fvar", HB_UNTAG (axis_tag)); + return false; + } + } + else + { + errno = 0; + char *p; + float axis_value = strtof (s, &p); + if (errno || s == p) + { + g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, + "Failed parsing axis value at: '%s'", s); + return false; + } + + if (!hb_subset_input_pin_axis_location (subset_main->input, subset_main->face, axis_tag, axis_value)) + { + g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, + "Cannot pin axis: '%c%c%c%c', not present in fvar", HB_UNTAG (axis_tag)); + return false; + } + } +#ifdef HB_EXPERIMENTAL_API + } +#endif s = strtok(nullptr, "="); } |