blob: e8747a6b21430ebfae9f063193f72bba81b75ca6 [file] [log] [blame]
Behdad Esfahbod3bb300e2011-08-11 11:54:31 +02001/*
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#include "common.hh"
28
29#ifndef OPTIONS_HH
30#define OPTIONS_HH
31
32
Behdad Esfahbodb9b10ad2011-09-13 13:30:39 -040033extern bool debug;
34
35struct option_group_t
36{
37 virtual void add_options (struct option_parser_t *parser) = 0;
38
39 virtual void pre_parse (GError **error G_GNUC_UNUSED) {};
40 virtual void post_parse (GError **error G_GNUC_UNUSED) {};
41};
42
43
44struct option_parser_t
45{
46 option_parser_t (const char *usage) {
47 memset (this, 0, sizeof (*this));
48 usage_str = usage;
49 context = g_option_context_new (usage);
50
51 add_main_options ();
52 }
53 ~option_parser_t (void) {
54 g_option_context_free (context);
55 }
56
57 void add_main_options (void);
58
59 void add_group (GOptionEntry *entries,
60 const gchar *name,
61 const gchar *description,
62 const gchar *help_description,
63 option_group_t *option_group);
64
65 void parse (int *argc, char ***argv);
66
67 G_GNUC_NORETURN void usage (void) {
68 g_printerr ("Usage: %s [OPTION...] %s\n", g_get_prgname (), usage_str);
69 exit (1);
70 }
71
72 const char *usage_str;
73 GOptionContext *context;
74};
75
76
Behdad Esfahbod109cb382011-09-08 16:00:04 -040077#define DEFAULT_MARGIN 18
78#define DEFAULT_FORE "#000000"
79#define DEFAULT_BACK "#FFFFFF"
Behdad Esfahbod11e51992011-09-19 09:58:55 -040080#define DEFAULT_FONT_SIZE 36
Behdad Esfahbod109cb382011-09-08 16:00:04 -040081
Behdad Esfahbodb9b10ad2011-09-13 13:30:39 -040082struct view_options_t : option_group_t
Behdad Esfahbod3bb300e2011-08-11 11:54:31 +020083{
Behdad Esfahbodb9b10ad2011-09-13 13:30:39 -040084 view_options_t (option_parser_t *parser) {
85 annotate = false;
Behdad Esfahbod109cb382011-09-08 16:00:04 -040086 fore = DEFAULT_FORE;
87 back = DEFAULT_BACK;
Behdad Esfahbodb9b10ad2011-09-13 13:30:39 -040088 line_space = 0;
Behdad Esfahbod109cb382011-09-08 16:00:04 -040089 margin.t = margin.r = margin.b = margin.l = DEFAULT_MARGIN;
Behdad Esfahbod11e51992011-09-19 09:58:55 -040090 font_size = DEFAULT_FONT_SIZE;
Behdad Esfahbodb9b10ad2011-09-13 13:30:39 -040091
92 add_options (parser);
Behdad Esfahbod3bb300e2011-08-11 11:54:31 +020093 }
94
Behdad Esfahbodb9b10ad2011-09-13 13:30:39 -040095 void add_options (option_parser_t *parser);
Behdad Esfahbodbc4b07b2011-09-08 17:08:32 -040096
Behdad Esfahbodb9b10ad2011-09-13 13:30:39 -040097 bool annotate;
Behdad Esfahbod3bb300e2011-08-11 11:54:31 +020098 const char *fore;
99 const char *back;
100 double line_space;
101 struct margin_t {
102 double t, r, b, l;
103 } margin;
Behdad Esfahbod11e51992011-09-19 09:58:55 -0400104 double font_size;
Behdad Esfahbodb9b10ad2011-09-13 13:30:39 -0400105};
Behdad Esfahbod3bb300e2011-08-11 11:54:31 +0200106
Behdad Esfahbod109cb382011-09-08 16:00:04 -0400107
Behdad Esfahbodb9b10ad2011-09-13 13:30:39 -0400108struct shape_options_t : option_group_t
Behdad Esfahbod3bb300e2011-08-11 11:54:31 +0200109{
Behdad Esfahbodb9b10ad2011-09-13 13:30:39 -0400110 shape_options_t (option_parser_t *parser) {
111 direction = language = script = NULL;
112 features = NULL;
113 num_features = 0;
114 shapers = NULL;
115
116 add_options (parser);
Behdad Esfahbod3bb300e2011-08-11 11:54:31 +0200117 }
Behdad Esfahbod90e312c2011-09-08 16:42:37 -0400118 ~shape_options_t (void) {
119 free (features);
120 g_free (shapers);
121 }
Behdad Esfahbod3bb300e2011-08-11 11:54:31 +0200122
Behdad Esfahbodb9b10ad2011-09-13 13:30:39 -0400123 void add_options (option_parser_t *parser);
Behdad Esfahbodbc4b07b2011-09-08 17:08:32 -0400124
Behdad Esfahbod4f4b1142011-09-08 16:49:02 -0400125 void setup_buffer (hb_buffer_t *buffer) {
Behdad Esfahbod516857e2011-09-08 16:50:24 -0400126 hb_buffer_set_direction (buffer, hb_direction_from_string (direction, -1));
127 hb_buffer_set_script (buffer, hb_script_from_string (script, -1));
128 hb_buffer_set_language (buffer, hb_language_from_string (language, -1));
Behdad Esfahbod4f4b1142011-09-08 16:49:02 -0400129 }
130
Behdad Esfahbodb9b10ad2011-09-13 13:30:39 -0400131 bool shape (const char *text, int text_len,
132 hb_font_t *font, hb_buffer_t *buffer) {
133 hb_buffer_reset (buffer);
134 hb_buffer_add_utf8 (buffer, text, text_len, 0, text_len);
Behdad Esfahbod4f4b1142011-09-08 16:49:02 -0400135 setup_buffer (buffer);
136 return hb_shape_full (font, buffer, features, num_features, NULL, shapers);
137 }
138
Behdad Esfahbod3bb300e2011-08-11 11:54:31 +0200139 const char *direction;
140 const char *language;
141 const char *script;
142 hb_feature_t *features;
143 unsigned int num_features;
144 char **shapers;
Behdad Esfahbodb9b10ad2011-09-13 13:30:39 -0400145};
Behdad Esfahbod3bb300e2011-08-11 11:54:31 +0200146
Behdad Esfahbod109cb382011-09-08 16:00:04 -0400147
Behdad Esfahbodb9b10ad2011-09-13 13:30:39 -0400148struct font_options_t : option_group_t
Behdad Esfahbod3bb300e2011-08-11 11:54:31 +0200149{
Behdad Esfahbodb9b10ad2011-09-13 13:30:39 -0400150 font_options_t (option_parser_t *parser) {
151 font_file = NULL;
152 face_index = 0;
Behdad Esfahbodb9b10ad2011-09-13 13:30:39 -0400153
154 font = NULL;
155
156 add_options (parser);
157 }
158 ~font_options_t (void) {
159 hb_font_destroy (font);
Behdad Esfahbod3bb300e2011-08-11 11:54:31 +0200160 }
161
Behdad Esfahbodb9b10ad2011-09-13 13:30:39 -0400162 void add_options (option_parser_t *parser);
163
164 hb_font_t *get_font (void) const;
Behdad Esfahbodbc4b07b2011-09-08 17:08:32 -0400165
Behdad Esfahbod3bb300e2011-08-11 11:54:31 +0200166 const char *font_file;
167 int face_index;
Behdad Esfahbodb9b10ad2011-09-13 13:30:39 -0400168
169 private:
170 mutable hb_font_t *font;
171};
Behdad Esfahbod3bb300e2011-08-11 11:54:31 +0200172
173
Behdad Esfahbodb9b10ad2011-09-13 13:30:39 -0400174struct text_options_t : option_group_t
175{
176 text_options_t (option_parser_t *parser) {
177 text = NULL;
178 text_file = NULL;
Behdad Esfahbod3bb300e2011-08-11 11:54:31 +0200179
Behdad Esfahbod55aeb042011-09-16 02:08:36 -0400180 fp = NULL;
181 gs = NULL;
Behdad Esfahbodb9b10ad2011-09-13 13:30:39 -0400182 text_len = (unsigned int) -1;
183
184 add_options (parser);
185 }
186 ~text_options_t (void) {
Behdad Esfahbod55aeb042011-09-16 02:08:36 -0400187 if (gs)
188 g_string_free (gs, TRUE);
189 if (fp)
190 fclose (fp);
Behdad Esfahbodb9b10ad2011-09-13 13:30:39 -0400191 }
192
193 void add_options (option_parser_t *parser);
194
195 void post_parse (GError **error G_GNUC_UNUSED) {
196 if (text && text_file)
197 g_set_error (error,
198 G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
199 "Only one of text and text-file must be set");
200
201 };
202
203 const char *get_line (unsigned int *len);
204
205 const char *text;
206 const char *text_file;
207
208 private:
Behdad Esfahbod55aeb042011-09-16 02:08:36 -0400209 FILE *fp;
210 GString *gs;
211 unsigned int text_len;
Behdad Esfahbodb9b10ad2011-09-13 13:30:39 -0400212};
213
Behdad Esfahbodb9b10ad2011-09-13 13:30:39 -0400214struct output_options_t : option_group_t
215{
216 output_options_t (option_parser_t *parser) {
217 output_file = NULL;
218 output_format = NULL;
219
Behdad Esfahbodf7e2ef72011-09-15 17:52:00 -0400220 fp = NULL;
221
Behdad Esfahbodb9b10ad2011-09-13 13:30:39 -0400222 add_options (parser);
223 }
Behdad Esfahbodf7e2ef72011-09-15 17:52:00 -0400224 ~output_options_t (void) {
Behdad Esfahbod55aeb042011-09-16 02:08:36 -0400225 if (fp)
Behdad Esfahbodf7e2ef72011-09-15 17:52:00 -0400226 fclose (fp);
227 }
Behdad Esfahbodb9b10ad2011-09-13 13:30:39 -0400228
229 void add_options (option_parser_t *parser);
230
231 void post_parse (GError **error G_GNUC_UNUSED)
232 {
233 if (output_file && !output_format) {
234 output_format = strrchr (output_file, '.');
235 if (output_format)
236 output_format++; /* skip the dot */
237 }
238
Behdad Esfahbodf7e2ef72011-09-15 17:52:00 -0400239 if (output_file && 0 == strcmp (output_file, "-"))
240 output_file = NULL; /* STDOUT */
241 }
242
Behdad Esfahboda75c1b12011-09-16 01:16:41 -0400243 FILE *get_file_handle (void);
Behdad Esfahbodb9b10ad2011-09-13 13:30:39 -0400244
245 virtual void init (const font_options_t *font_opts) = 0;
246 virtual void consume_line (hb_buffer_t *buffer,
247 const char *text,
248 unsigned int text_len) = 0;
249 virtual void finish (const font_options_t *font_opts) = 0;
250
Behdad Esfahbodf7e2ef72011-09-15 17:52:00 -0400251 protected:
Behdad Esfahbodb9b10ad2011-09-13 13:30:39 -0400252 const char *output_file;
253 const char *output_format;
Behdad Esfahbodf7e2ef72011-09-15 17:52:00 -0400254
255 mutable FILE *fp;
Behdad Esfahbodb9b10ad2011-09-13 13:30:39 -0400256};
Behdad Esfahbod3bb300e2011-08-11 11:54:31 +0200257
258
259#endif