Imported Upstream version 8.2.2
[platform/upstream/harfbuzz.git] / util / shape-format.hh
1 /*
2  * Copyright © 2011  Google, Inc.
3  *
4  *  This is part of HarfBuzz, a text shaping library.
5  *
6  * Permission is hereby granted, without written agreement and without
7  * license or royalty fees, to use, copy, modify, and distribute this
8  * software and its documentation for any purpose, provided that the
9  * above copyright notice and the following two paragraphs appear in
10  * all copies of this software.
11  *
12  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16  * DAMAGE.
17  *
18  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
21  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23  *
24  * Google Author(s): Behdad Esfahbod
25  */
26
27 #ifndef SHAPE_FORMAT_OPTIONS_HH
28 #define SHAPE_FORMAT_OPTIONS_HH
29
30 #include "options.hh"
31
32
33 struct shape_format_options_t
34 {
35   void add_options (option_parser_t *parser);
36
37   void serialize (hb_buffer_t  *buffer,
38                          hb_font_t    *font,
39                          hb_buffer_serialize_format_t format,
40                          hb_buffer_serialize_flags_t flags,
41                          GString      *gs);
42   void serialize_line_no (unsigned int  line_no,
43                           GString      *gs);
44   void serialize_buffer_of_text (hb_buffer_t  *buffer,
45                                  unsigned int  line_no,
46                                  const char   *text,
47                                  unsigned int  text_len,
48                                  hb_font_t    *font,
49                                  GString      *gs);
50   void serialize_message (unsigned int  line_no,
51                           const char   *type,
52                           const char   *msg,
53                           GString      *gs);
54   void serialize_buffer_of_glyphs (hb_buffer_t  *buffer,
55                                    unsigned int  line_no,
56                                    const char   *text,
57                                    unsigned int  text_len,
58                                    hb_font_t    *font,
59                                    hb_buffer_serialize_format_t output_format,
60                                    hb_buffer_serialize_flags_t format_flags,
61                                    GString      *gs);
62
63
64   hb_bool_t show_glyph_names = true;
65   hb_bool_t show_positions = true;
66   hb_bool_t show_advances = true;
67   hb_bool_t show_clusters = true;
68   hb_bool_t show_text = false;
69   hb_bool_t show_unicode = false;
70   hb_bool_t show_line_num = false;
71   hb_bool_t show_extents = false;
72   hb_bool_t show_flags = false;
73   hb_bool_t trace = false;
74 };
75
76
77 static gboolean
78 parse_verbose (const char *name G_GNUC_UNUSED,
79                const char *arg G_GNUC_UNUSED,
80                gpointer    data G_GNUC_UNUSED,
81                GError    **error G_GNUC_UNUSED)
82 {
83   shape_format_options_t *format_opts = (shape_format_options_t *) data;
84   format_opts->show_text = format_opts->show_unicode = format_opts->show_line_num = true;
85   return true;
86 }
87
88 static gboolean
89 parse_ned (const char *name G_GNUC_UNUSED,
90            const char *arg G_GNUC_UNUSED,
91            gpointer    data G_GNUC_UNUSED,
92            GError    **error G_GNUC_UNUSED)
93 {
94   shape_format_options_t *format_opts = (shape_format_options_t *) data;
95   format_opts->show_clusters = format_opts->show_advances = false;
96   return true;
97 }
98
99 inline void
100 shape_format_options_t::serialize (hb_buffer_t *buffer,
101                                    hb_font_t   *font,
102                                    hb_buffer_serialize_format_t output_format,
103                                    hb_buffer_serialize_flags_t flags,
104                                    GString     *gs)
105 {
106   unsigned int num_glyphs = hb_buffer_get_length (buffer);
107   unsigned int start = 0;
108
109   while (start < num_glyphs)
110   {
111     char buf[32768];
112     unsigned int consumed;
113     start += hb_buffer_serialize (buffer, start, num_glyphs,
114                                   buf, sizeof (buf), &consumed,
115                                   font, output_format, flags);
116     if (!consumed)
117       break;
118     g_string_append (gs, buf);
119   }
120 }
121
122 inline void
123 shape_format_options_t::serialize_line_no (unsigned int  line_no,
124                                            GString      *gs)
125 {
126   if (show_line_num)
127     g_string_append_printf (gs, "%u: ", line_no);
128 }
129 inline void
130 shape_format_options_t::serialize_buffer_of_text (hb_buffer_t  *buffer,
131                                                   unsigned int  line_no,
132                                                   const char   *text,
133                                                   unsigned int  text_len,
134                                                   hb_font_t    *font,
135                                                   GString      *gs)
136 {
137   if (show_text)
138   {
139     serialize_line_no (line_no, gs);
140     g_string_append_c (gs, '(');
141     g_string_append_len (gs, text, text_len);
142     g_string_append_c (gs, ')');
143     g_string_append_c (gs, '\n');
144   }
145
146   if (show_unicode)
147   {
148     serialize_line_no (line_no, gs);
149     serialize (buffer, font, HB_BUFFER_SERIALIZE_FORMAT_TEXT, HB_BUFFER_SERIALIZE_FLAG_DEFAULT, gs);
150     g_string_append_c (gs, '\n');
151   }
152 }
153 inline void
154 shape_format_options_t::serialize_message (unsigned int  line_no,
155                                            const char   *type,
156                                            const char   *msg,
157                                            GString      *gs)
158 {
159   serialize_line_no (line_no, gs);
160   g_string_append_printf (gs, "%s: %s", type, msg);
161   g_string_append_c (gs, '\n');
162 }
163 inline void
164 shape_format_options_t::serialize_buffer_of_glyphs (hb_buffer_t  *buffer,
165                                                     unsigned int  line_no,
166                                                     const char   *text,
167                                                     unsigned int  text_len,
168                                                     hb_font_t    *font,
169                                                     hb_buffer_serialize_format_t output_format,
170                                                     hb_buffer_serialize_flags_t format_flags,
171                                                     GString      *gs)
172 {
173   serialize_line_no (line_no, gs);
174   serialize (buffer, font, output_format, format_flags, gs);
175   g_string_append_c (gs, '\n');
176 }
177
178
179 void
180 shape_format_options_t::add_options (option_parser_t *parser)
181 {
182   GOptionEntry entries[] =
183   {
184     {"show-text",       0, 0, G_OPTION_ARG_NONE,        &this->show_text,               "Prefix each line of output with its corresponding input text",         nullptr},
185     {"show-unicode",    0, 0, G_OPTION_ARG_NONE,        &this->show_unicode,            "Prefix each line of output with its corresponding input codepoint(s)", nullptr},
186     {"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},
187     {"verbose",       'v', G_OPTION_FLAG_NO_ARG,
188                               G_OPTION_ARG_CALLBACK,    (gpointer) &parse_verbose,      "Prefix each line of output with all of the above",                     nullptr},
189     {"no-glyph-names",  0, G_OPTION_FLAG_REVERSE,
190                               G_OPTION_ARG_NONE,        &this->show_glyph_names,        "Output glyph indices instead of names",                                nullptr},
191     {"no-positions",    0, G_OPTION_FLAG_REVERSE,
192                               G_OPTION_ARG_NONE,        &this->show_positions,          "Do not output glyph positions",                                        nullptr},
193     {"no-advances",     0, G_OPTION_FLAG_REVERSE,
194                               G_OPTION_ARG_NONE,        &this->show_advances,           "Do not output glyph advances",                                         nullptr},
195     {"no-clusters",     0, G_OPTION_FLAG_REVERSE,
196                               G_OPTION_ARG_NONE,        &this->show_clusters,           "Do not output cluster indices",                                        nullptr},
197     {"show-extents",    0, 0, G_OPTION_ARG_NONE,        &this->show_extents,            "Output glyph extents",                                                 nullptr},
198     {"show-flags",      0, 0, G_OPTION_ARG_NONE,        &this->show_flags,              "Output glyph flags",                                                   nullptr},
199     {"ned",           'v', G_OPTION_FLAG_NO_ARG,
200                               G_OPTION_ARG_CALLBACK,    (gpointer) &parse_ned,          "No Extra Data; Do not output clusters or advances",                    nullptr},
201     {"trace",         'V', 0, G_OPTION_ARG_NONE,        &this->trace,                   "Output interim shaping results",                                       nullptr},
202     {nullptr}
203   };
204   parser->add_group (entries,
205                      "output-syntax",
206                      "Output syntax:\n"
207          "    text: [<glyph name or index>=<glyph cluster index within input>@<horizontal displacement>,<vertical displacement>+<horizontal advance>,<vertical advance>|...]\n"
208          "    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"
209          "\nOutput syntax options:",
210                      "Options for the syntax of the output",
211                      this);
212 }
213
214 #endif