|  | /* | 
|  | * Copyright © 2011  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): Behdad Esfahbod | 
|  | */ | 
|  |  | 
|  | #ifndef SHAPE_FORMAT_OPTIONS_HH | 
|  | #define SHAPE_FORMAT_OPTIONS_HH | 
|  |  | 
|  | #include "options.hh" | 
|  |  | 
|  |  | 
|  | struct shape_format_options_t | 
|  | { | 
|  | void add_options (option_parser_t *parser); | 
|  |  | 
|  | void serialize (hb_buffer_t  *buffer, | 
|  | hb_font_t    *font, | 
|  | hb_buffer_serialize_format_t format, | 
|  | hb_buffer_serialize_flags_t flags, | 
|  | GString      *gs); | 
|  | void serialize_line_no (unsigned int  line_no, | 
|  | GString      *gs); | 
|  | void serialize_buffer_of_text (hb_buffer_t  *buffer, | 
|  | unsigned int  line_no, | 
|  | const char   *text, | 
|  | unsigned int  text_len, | 
|  | hb_font_t    *font, | 
|  | GString      *gs); | 
|  | void serialize_message (unsigned int  line_no, | 
|  | const char   *type, | 
|  | const char   *msg, | 
|  | GString      *gs); | 
|  | void serialize_buffer_of_glyphs (hb_buffer_t  *buffer, | 
|  | unsigned int  line_no, | 
|  | const char   *text, | 
|  | unsigned int  text_len, | 
|  | hb_font_t    *font, | 
|  | hb_buffer_serialize_format_t output_format, | 
|  | hb_buffer_serialize_flags_t format_flags, | 
|  | GString      *gs); | 
|  |  | 
|  |  | 
|  | hb_bool_t show_glyph_names = true; | 
|  | hb_bool_t show_positions = true; | 
|  | hb_bool_t show_advances = true; | 
|  | hb_bool_t show_clusters = true; | 
|  | hb_bool_t show_text = false; | 
|  | hb_bool_t show_unicode = false; | 
|  | hb_bool_t show_line_num = false; | 
|  | hb_bool_t show_extents = false; | 
|  | hb_bool_t show_flags = false; | 
|  | hb_bool_t trace = false; | 
|  | }; | 
|  |  | 
|  |  | 
|  | static gboolean | 
|  | parse_verbose (const char *name G_GNUC_UNUSED, | 
|  | const char *arg G_GNUC_UNUSED, | 
|  | gpointer    data G_GNUC_UNUSED, | 
|  | GError    **error G_GNUC_UNUSED) | 
|  | { | 
|  | shape_format_options_t *format_opts = (shape_format_options_t *) data; | 
|  | format_opts->show_text = format_opts->show_unicode = format_opts->show_line_num = true; | 
|  | return true; | 
|  | } | 
|  |  | 
|  | static gboolean | 
|  | parse_ned (const char *name G_GNUC_UNUSED, | 
|  | const char *arg G_GNUC_UNUSED, | 
|  | gpointer    data G_GNUC_UNUSED, | 
|  | GError    **error G_GNUC_UNUSED) | 
|  | { | 
|  | shape_format_options_t *format_opts = (shape_format_options_t *) data; | 
|  | format_opts->show_clusters = format_opts->show_advances = false; | 
|  | return true; | 
|  | } | 
|  |  | 
|  | inline void | 
|  | shape_format_options_t::serialize (hb_buffer_t *buffer, | 
|  | hb_font_t   *font, | 
|  | hb_buffer_serialize_format_t output_format, | 
|  | hb_buffer_serialize_flags_t flags, | 
|  | GString     *gs) | 
|  | { | 
|  | unsigned int num_glyphs = hb_buffer_get_length (buffer); | 
|  | unsigned int start = 0; | 
|  |  | 
|  | while (start < num_glyphs) | 
|  | { | 
|  | char buf[32768]; | 
|  | unsigned int consumed; | 
|  | start += hb_buffer_serialize (buffer, start, num_glyphs, | 
|  | buf, sizeof (buf), &consumed, | 
|  | font, output_format, flags); | 
|  | if (!consumed) | 
|  | break; | 
|  | g_string_append (gs, buf); | 
|  | } | 
|  | } | 
|  |  | 
|  | inline void | 
|  | shape_format_options_t::serialize_line_no (unsigned int  line_no, | 
|  | GString      *gs) | 
|  | { | 
|  | if (show_line_num) | 
|  | g_string_append_printf (gs, "%d: ", line_no); | 
|  | } | 
|  | inline void | 
|  | shape_format_options_t::serialize_buffer_of_text (hb_buffer_t  *buffer, | 
|  | unsigned int  line_no, | 
|  | const char   *text, | 
|  | unsigned int  text_len, | 
|  | hb_font_t    *font, | 
|  | GString      *gs) | 
|  | { | 
|  | if (show_text) | 
|  | { | 
|  | serialize_line_no (line_no, gs); | 
|  | g_string_append_c (gs, '('); | 
|  | g_string_append_len (gs, text, text_len); | 
|  | g_string_append_c (gs, ')'); | 
|  | g_string_append_c (gs, '\n'); | 
|  | } | 
|  |  | 
|  | if (show_unicode) | 
|  | { | 
|  | serialize_line_no (line_no, gs); | 
|  | serialize (buffer, font, HB_BUFFER_SERIALIZE_FORMAT_TEXT, HB_BUFFER_SERIALIZE_FLAG_DEFAULT, gs); | 
|  | g_string_append_c (gs, '\n'); | 
|  | } | 
|  | } | 
|  | inline void | 
|  | shape_format_options_t::serialize_message (unsigned int  line_no, | 
|  | const char   *type, | 
|  | const char   *msg, | 
|  | GString      *gs) | 
|  | { | 
|  | serialize_line_no (line_no, gs); | 
|  | g_string_append_printf (gs, "%s: %s", type, msg); | 
|  | g_string_append_c (gs, '\n'); | 
|  | } | 
|  | inline void | 
|  | shape_format_options_t::serialize_buffer_of_glyphs (hb_buffer_t  *buffer, | 
|  | unsigned int  line_no, | 
|  | const char   *text, | 
|  | unsigned int  text_len, | 
|  | hb_font_t    *font, | 
|  | hb_buffer_serialize_format_t output_format, | 
|  | hb_buffer_serialize_flags_t format_flags, | 
|  | GString      *gs) | 
|  | { | 
|  | serialize_line_no (line_no, gs); | 
|  | serialize (buffer, font, output_format, format_flags, gs); | 
|  | g_string_append_c (gs, '\n'); | 
|  | } | 
|  |  | 
|  |  | 
|  | void | 
|  | shape_format_options_t::add_options (option_parser_t *parser) | 
|  | { | 
|  | GOptionEntry entries[] = | 
|  | { | 
|  | {"show-text",	0, 0, G_OPTION_ARG_NONE,	&this->show_text,		"Prefix each line of output with its corresponding input text",		nullptr}, | 
|  | {"show-unicode",	0, 0, G_OPTION_ARG_NONE,	&this->show_unicode,		"Prefix each line of output with its corresponding input codepoint(s)",	nullptr}, | 
|  | {"show-line-num",	0, 0, G_OPTION_ARG_NONE,	&this->show_line_num,		"Prefix each line of output with its corresponding input line number",	nullptr}, | 
|  | {"verbose",	      'v', G_OPTION_FLAG_NO_ARG, | 
|  | G_OPTION_ARG_CALLBACK,	(gpointer) &parse_verbose,	"Prefix each line of output with all of the above",			nullptr}, | 
|  | {"no-glyph-names",	0, G_OPTION_FLAG_REVERSE, | 
|  | G_OPTION_ARG_NONE,	&this->show_glyph_names,	"Output glyph indices instead of names",				nullptr}, | 
|  | {"no-positions",	0, G_OPTION_FLAG_REVERSE, | 
|  | G_OPTION_ARG_NONE,	&this->show_positions,		"Do not output glyph positions",					nullptr}, | 
|  | {"no-advances",	0, G_OPTION_FLAG_REVERSE, | 
|  | G_OPTION_ARG_NONE,	&this->show_advances,		"Do not output glyph advances",						nullptr}, | 
|  | {"no-clusters",	0, G_OPTION_FLAG_REVERSE, | 
|  | G_OPTION_ARG_NONE,	&this->show_clusters,		"Do not output cluster indices",					nullptr}, | 
|  | {"show-extents",	0, 0, G_OPTION_ARG_NONE,	&this->show_extents,		"Output glyph extents",							nullptr}, | 
|  | {"show-flags",	0, 0, G_OPTION_ARG_NONE,	&this->show_flags,		"Output glyph flags",							nullptr}, | 
|  | {"ned",	      'v', G_OPTION_FLAG_NO_ARG, | 
|  | G_OPTION_ARG_CALLBACK,	(gpointer) &parse_ned,		"No Extra Data; Do not output clusters or advances",			nullptr}, | 
|  | {"trace",	      'V', 0, G_OPTION_ARG_NONE,	&this->trace,			"Output interim shaping results",					nullptr}, | 
|  | {nullptr} | 
|  | }; | 
|  | parser->add_group (entries, | 
|  | "output-syntax", | 
|  | "Output syntax:\n" | 
|  | "    text: [<glyph name or index>=<glyph cluster index within input>@<horizontal displacement>,<vertical displacement>+<horizontal advance>,<vertical advance>|...]\n" | 
|  | "    json: [{\"g\": <glyph name or index>, \"ax\": <horizontal advance>, \"ay\": <vertical advance>, \"dx\": <horizontal displacement>, \"dy\": <vertical displacement>, \"cl\": <glyph cluster index within input>}, ...]\n" | 
|  | "\nOutput syntax options:", | 
|  | "Options for the syntax of the output", | 
|  | this); | 
|  | } | 
|  |  | 
|  | #endif |