[util/hb-subset] Pre-parse font-face so we can use it during main parsing

This commit is contained in:
Behdad Esfahbod 2021-08-12 11:38:28 -06:00
parent c45d2a9c9d
commit 11b0b68853
3 changed files with 69 additions and 8 deletions

View File

@ -36,6 +36,9 @@ struct face_options_t
g_free (font_file); g_free (font_file);
} }
void set_face (hb_face_t *face_)
{ face = face_; }
void add_options (option_parser_t *parser); void add_options (option_parser_t *parser);
void post_parse (GError **error); void post_parse (GError **error);

View File

@ -46,8 +46,37 @@ struct subset_main_t : option_parser_t, face_options_t, output_options_t<false>
hb_subset_input_destroy (input); hb_subset_input_destroy (input);
} }
void parse_face (int argc, const char * const *argv)
{
option_parser_t parser;
face_options_t face_opts;
face_opts.add_options (&parser);
GOptionEntry entries[] =
{
{G_OPTION_REMAINING, 0, G_OPTION_FLAG_IN_MAIN,
G_OPTION_ARG_CALLBACK, (gpointer) &collect_face, nullptr, "[FONT-FILE] [TEXT]"},
{nullptr}
};
parser.add_main_group (entries, &face_opts);
g_option_context_set_ignore_unknown_options (parser.context, true);
g_option_context_set_help_enabled (parser.context, false);
char **args = (char **) g_memdup (argv, argc * sizeof (*argv));
parser.parse (&argc, &args, true);
g_free (args);
set_face (face_opts.face);
}
void parse (int argc, char **argv) void parse (int argc, char **argv)
{ {
/* Do a preliminary parse to load font-face, such that we can use it
* during main option parsing. */
parse_face (argc, argv);
add_options (); add_options ();
option_parser_t::parse (&argc, &argv); option_parser_t::parse (&argc, &argv);
} }
@ -103,6 +132,11 @@ struct subset_main_t : option_parser_t, face_options_t, output_options_t<false>
protected: protected:
static gboolean static gboolean
collect_face (const char *name,
const char *arg,
gpointer data,
GError **error);
static gboolean
collect_rest (const char *name, collect_rest (const char *name,
const char *arg, const char *arg,
gpointer data, gpointer data,
@ -565,6 +599,23 @@ parse_file_for (const char *name,
return true; return true;
} }
gboolean
subset_main_t::collect_face (const char *name,
const char *arg,
gpointer data,
GError **error)
{
face_options_t *thiz = (face_options_t *) data;
if (!thiz->font_file)
{
thiz->font_file = g_strdup (arg);
return true;
}
return true;
}
gboolean gboolean
subset_main_t::collect_rest (const char *name, subset_main_t::collect_rest (const char *name,
const char *arg, const char *arg,

View File

@ -126,7 +126,8 @@ struct option_parser_t
GOptionGroup *group = g_option_group_new (nullptr, nullptr, nullptr, GOptionGroup *group = g_option_group_new (nullptr, nullptr, nullptr,
static_cast<gpointer>(closure), nullptr); static_cast<gpointer>(closure), nullptr);
g_option_group_add_entries (group, entries); g_option_group_add_entries (group, entries);
g_option_group_set_parse_hooks (group, nullptr, post_parse<Type>); /* https://gitlab.gnome.org/GNOME/glib/-/issues/2460 */
//g_option_group_set_parse_hooks (group, nullptr, post_parse<Type>);
g_option_context_set_main_group (context, group); g_option_context_set_main_group (context, group);
} }
@ -143,10 +144,10 @@ struct option_parser_t
g_ptr_array_add (to_free, p); g_ptr_array_add (to_free, p);
} }
void parse (int *argc, char ***argv); bool parse (int *argc, char ***argv, bool ignore_error = false);
protected:
GOptionContext *context; GOptionContext *context;
protected:
GPtrArray *to_free; GPtrArray *to_free;
}; };
@ -195,8 +196,8 @@ option_parser_t::add_options ()
g_option_context_add_main_entries (context, entries, nullptr); g_option_context_add_main_entries (context, entries, nullptr);
} }
inline void inline bool
option_parser_t::parse (int *argc, char ***argv) option_parser_t::parse (int *argc, char ***argv, bool ignore_error)
{ {
setlocale (LC_ALL, ""); setlocale (LC_ALL, "");
@ -205,12 +206,18 @@ option_parser_t::parse (int *argc, char ***argv)
{ {
if (parse_error) if (parse_error)
{ {
if (!ignore_error)
fail (true, "%s", parse_error->message); fail (true, "%s", parse_error->message);
//g_error_free (parse_error); g_error_free (parse_error);
} }
else else
{
if (!ignore_error)
fail (true, "Option parse error"); fail (true, "Option parse error");
} }
return false;
}
return true;
} }