xref: /aosp_15_r20/external/harfbuzz_ng/util/shape-format.hh (revision 2d1272b857b1f7575e6e246373e1cb218663db8a)
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
parse_verbose(const char * name G_GNUC_UNUSED,const char * arg G_GNUC_UNUSED,gpointer data G_GNUC_UNUSED,GError ** error G_GNUC_UNUSED)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
parse_ned(const char * name G_GNUC_UNUSED,const char * arg G_GNUC_UNUSED,gpointer data G_GNUC_UNUSED,GError ** error G_GNUC_UNUSED)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
serialize(hb_buffer_t * buffer,hb_font_t * font,hb_buffer_serialize_format_t output_format,hb_buffer_serialize_flags_t flags,GString * gs)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
serialize_line_no(unsigned int line_no,GString * gs)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
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)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
serialize_message(unsigned int line_no,const char * type,const char * msg,GString * gs)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
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)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
add_options(option_parser_t * parser)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
215