| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- /*
- * Copyright © 2023 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): Garret Rieger
- */
- #ifndef HELPER_SUBSET_HH
- #define HELPER_SUBSET_HH
- #include "glib.h"
- #include <errno.h>
- #include <math.h>
- #include <stdbool.h>
- #include "hb-subset.h"
- #ifndef HB_NO_VAR
- // Parses an axis position string and sets min, default, and max to
- // the requested values. If a value should be set to it's default value
- // then it will be set to NaN.
- static gboolean
- parse_axis_position(const char* s,
- float* min,
- float* def,
- float* max,
- gboolean* drop,
- GError **error)
- {
- const char* part = strpbrk(s, ":");
- *drop = false;
- if (!part) {
- // Single value.
- if (strcmp (s, "drop") == 0)
- {
- *min = NAN;
- *def = NAN;
- *max = NAN;
- *drop = true;
- return true;
- }
- 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;
- }
- *min = axis_value;
- *def = axis_value;
- *max = axis_value;
- return true;
- }
- float values[3];
- int count = 0;
- for (int i = 0; i < 3; i++) {
- errno = 0;
- count++;
- if (!*s || part == s) {
- values[i] = NAN;
- if (part == NULL) break;
- s = part + 1;
- part = strpbrk(s, ":");
- continue;
- }
- char *pend;
- values[i] = strtof (s, &pend);
- if (errno || s == pend || (part && pend != part))
- {
- g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
- "Failed parsing axis value at: '%s'", s);
- return false;
- }
- if (part == NULL) break;
- s = pend + 1;
- part = strpbrk(s, ":");
- }
- if (count == 2) {
- *min = values[0];
- *def = NAN;
- *max = values[1];
- return true;
- } else if (count == 3) {
- *min = values[0];
- *def = values[1];
- *max = values[2];
- return true;
- }
- g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
- "Failed parsing axis value at: '%s'", s);
- return false;
- }
- static gboolean
- parse_instancing_spec (const char *arg,
- hb_face_t* face,
- hb_subset_input_t* input,
- GError **error)
- {
- char* s;
- while ((s = strtok((char *) arg, "=")))
- {
- arg = NULL;
- unsigned len = strlen (s);
- if (len > 4) //Axis tags are 4 bytes.
- {
- g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
- "Failed parsing axis tag at: '%s'", s);
- return false;
- }
- /* support *=drop */
- if (0 == strcmp (s, "*"))
- {
- s = strtok(NULL, ", ");
- if (0 != strcmp (s, "drop"))
- {
- g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
- "Failed parsing axis position at: '%s'", s);
- return false;
- }
- if (!hb_subset_input_pin_all_axes_to_default (input, face))
- {
- g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
- "Failed pinning all axes to default.");
- return false;
- }
- continue;
- }
- hb_tag_t axis_tag = hb_tag_from_string (s, len);
- s = strtok(NULL, ", ");
- if (!s)
- {
- g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
- "Value not specified for axis: %c%c%c%c", HB_UNTAG (axis_tag));
- return false;
- }
- gboolean drop;
- float min, def, max;
- if (!parse_axis_position(s, &min, &def, &max, &drop, error))
- return false;
- if (drop)
- {
- if (!hb_subset_input_pin_axis_to_default (input,
- 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;
- }
- continue;
- }
- if (min == def && def == max) {
- if (!hb_subset_input_pin_axis_location (input,
- face, axis_tag,
- def))
- {
- 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;
- }
- continue;
- }
- if (!hb_subset_input_set_axis_range (input,
- face, axis_tag,
- min, max, def))
- {
- 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;
- }
- continue;
- g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
- "Partial instancing is not supported.");
- return false;
- }
- return true;
- }
- #endif
- #endif
|