| /* |
| * Copyright © 2019 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 |
| */ |
| |
| #include "options.hh" |
| |
| #include "hb-subset-input.hh" |
| |
| static gboolean |
| parse_nameids (const char *name, |
| const char *arg, |
| gpointer data, |
| GError **error G_GNUC_UNUSED) |
| { |
| subset_options_t *subset_opts = (subset_options_t *) data; |
| hb_set_t *name_ids = subset_opts->input->name_ids; |
| |
| char last_name_char = name[strlen (name) - 1]; |
| |
| if (last_name_char != '+' && last_name_char != '-') |
| hb_set_clear (name_ids); |
| |
| if (0 == strcmp (arg, "*")) |
| { |
| if (last_name_char == '-') |
| hb_set_del_range (name_ids, 0, 0x7FFF); |
| else |
| hb_set_add_range (name_ids, 0, 0x7FFF); |
| return true; |
| } |
| |
| char *s = (char *) arg; |
| char *p; |
| |
| while (s && *s) |
| { |
| while (*s && strchr (", ", *s)) |
| s++; |
| if (!*s) |
| break; |
| |
| errno = 0; |
| hb_codepoint_t u = strtoul (s, &p, 10); |
| if (errno || s == p) |
| { |
| hb_set_destroy (name_ids); |
| g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, |
| "Failed parsing nameID values at: '%s'", s); |
| return false; |
| } |
| |
| if (last_name_char != '-') |
| { |
| hb_set_add (name_ids, u); |
| } else { |
| hb_set_del (name_ids, u); |
| } |
| |
| s = p; |
| } |
| |
| return true; |
| } |
| |
| static gboolean |
| parse_drop_tables (const char *name, |
| const char *arg, |
| gpointer data, |
| GError **error G_GNUC_UNUSED) |
| { |
| subset_options_t *subset_opts = (subset_options_t *) data; |
| hb_set_t *drop_tables = subset_opts->input->drop_tables; |
| |
| char last_name_char = name[strlen (name) - 1]; |
| |
| if (last_name_char != '+' && last_name_char != '-') |
| hb_set_clear (drop_tables); |
| |
| char *s = strtok((char *) arg, ", "); |
| while (s) |
| { |
| if (strlen (s) > 4) // Table tags are at most 4 bytes. |
| { |
| g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, |
| "Failed parsing table tag values at: '%s'", s); |
| return false; |
| } |
| |
| hb_tag_t tag = hb_tag_from_string (s, strlen (s)); |
| |
| if (last_name_char != '-') |
| hb_set_add (drop_tables, tag); |
| else |
| hb_set_del (drop_tables, tag); |
| |
| s = strtok(nullptr, ", "); |
| } |
| |
| return true; |
| } |
| |
| void |
| subset_options_t::add_options (option_parser_t *parser) |
| { |
| GOptionEntry entries[] = |
| { |
| {"no-hinting", 0, 0, G_OPTION_ARG_NONE, &this->input->drop_hints, "Whether to drop hints", nullptr}, |
| {"retain-gids", 0, 0, G_OPTION_ARG_NONE, &this->input->retain_gids, "If set don't renumber glyph ids in the subset.", nullptr}, |
| {"desubroutinize", 0, 0, G_OPTION_ARG_NONE, &this->input->desubroutinize, "Remove CFF/CFF2 use of subroutines", nullptr}, |
| {"name-IDs", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_nameids, "Subset specified nameids", "list of int numbers"}, |
| {"drop-tables", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_drop_tables, "Drop the specified tables.", "list of string table tags."}, |
| {"drop-tables+", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_drop_tables, "Drop the specified tables.", "list of string table tags."}, |
| {"drop-tables-", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_drop_tables, "Drop the specified tables.", "list of string table tags."}, |
| |
| {nullptr} |
| }; |
| parser->add_group (entries, |
| "subset", |
| "Subset options:", |
| "Options subsetting", |
| this); |
| } |