options.hh revision 088c1e27c0fc0cdef999cf1f567e4d5eb2cfb2e4
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 OPTIONS_HH
28#define OPTIONS_HH
29
30
31#ifdef HAVE_CONFIG_H
32#include "config.h"
33#endif
34
35#include <stdlib.h>
36#include <stddef.h>
37#include <string.h>
38#include <stdio.h>
39#include <math.h>
40#include <locale.h>
41#include <errno.h>
42#include <fcntl.h>
43#ifdef HAVE_IO_H
44#include <io.h> /* for _setmode() under Windows */
45#endif
46
47#include <hb.h>
48#include <glib.h>
49#include <glib/gprintf.h>
50
51void fail (hb_bool_t suggest_help, const char *format, ...) G_GNUC_NORETURN;
52
53
54extern hb_bool_t debug;
55
56struct option_group_t
57{
58  virtual void add_options (struct option_parser_t *parser) = 0;
59
60  virtual void pre_parse (GError **error G_GNUC_UNUSED) {};
61  virtual void post_parse (GError **error G_GNUC_UNUSED) {};
62};
63
64
65struct option_parser_t
66{
67  option_parser_t (const char *usage) {
68    memset (this, 0, sizeof (*this));
69    usage_str = usage;
70    context = g_option_context_new (usage);
71
72    add_main_options ();
73  }
74  ~option_parser_t (void) {
75    g_option_context_free (context);
76  }
77
78  void add_main_options (void);
79
80  void add_group (GOptionEntry   *entries,
81		  const gchar    *name,
82		  const gchar    *description,
83		  const gchar    *help_description,
84		  option_group_t *option_group);
85
86  void parse (int *argc, char ***argv);
87
88  G_GNUC_NORETURN void usage (void) {
89    g_printerr ("Usage: %s [OPTION...] %s\n", g_get_prgname (), usage_str);
90    exit (1);
91  }
92
93  const char *usage_str;
94  GOptionContext *context;
95};
96
97
98#define DEFAULT_MARGIN 18
99#define DEFAULT_FORE "#000000"
100#define DEFAULT_BACK "#FFFFFF"
101#define DEFAULT_FONT_SIZE 36
102
103struct view_options_t : option_group_t
104{
105  view_options_t (option_parser_t *parser) {
106    annotate = false;
107    fore = DEFAULT_FORE;
108    back = DEFAULT_BACK;
109    line_space = 0;
110    margin.t = margin.r = margin.b = margin.l = DEFAULT_MARGIN;
111    font_size = DEFAULT_FONT_SIZE;
112
113    add_options (parser);
114  }
115
116  void add_options (option_parser_t *parser);
117
118  hb_bool_t annotate;
119  const char *fore;
120  const char *back;
121  double line_space;
122  struct margin_t {
123    double t, r, b, l;
124  } margin;
125  double font_size;
126};
127
128
129struct shape_options_t : option_group_t
130{
131  shape_options_t (option_parser_t *parser) {
132    direction = language = script = NULL;
133    features = NULL;
134    num_features = 0;
135    shapers = NULL;
136
137    add_options (parser);
138  }
139  ~shape_options_t (void) {
140    free (features);
141    g_free (shapers);
142  }
143
144  void add_options (option_parser_t *parser);
145
146  void setup_buffer (hb_buffer_t *buffer) {
147    hb_buffer_set_direction (buffer, hb_direction_from_string (direction, -1));
148    hb_buffer_set_script (buffer, hb_script_from_string (script, -1));
149    hb_buffer_set_language (buffer, hb_language_from_string (language, -1));
150  }
151
152  hb_bool_t shape (const char *text, int text_len,
153		   hb_font_t *font, hb_buffer_t *buffer) {
154    hb_buffer_reset (buffer);
155    hb_buffer_add_utf8 (buffer, text, text_len, 0, text_len);
156    setup_buffer (buffer);
157    return hb_shape_full (font, buffer, features, num_features, NULL, shapers);
158  }
159
160  const char *direction;
161  const char *language;
162  const char *script;
163  hb_feature_t *features;
164  unsigned int num_features;
165  char **shapers;
166};
167
168
169struct font_options_t : option_group_t
170{
171  font_options_t (option_parser_t *parser) {
172    font_file = NULL;
173    face_index = 0;
174
175    font = NULL;
176
177    add_options (parser);
178  }
179  ~font_options_t (void) {
180    hb_font_destroy (font);
181  }
182
183  void add_options (option_parser_t *parser);
184
185  hb_font_t *get_font (void) const;
186
187  const char *font_file;
188  int face_index;
189
190  private:
191  mutable hb_font_t *font;
192};
193
194
195struct text_options_t : option_group_t
196{
197  text_options_t (option_parser_t *parser) {
198    text = NULL;
199    text_file = NULL;
200
201    fp = NULL;
202    gs = NULL;
203    text_len = (unsigned int) -1;
204
205    add_options (parser);
206  }
207  ~text_options_t (void) {
208    if (gs)
209      g_string_free (gs, TRUE);
210    if (fp)
211      fclose (fp);
212  }
213
214  void add_options (option_parser_t *parser);
215
216  void post_parse (GError **error G_GNUC_UNUSED) {
217    if (text && text_file)
218      g_set_error (error,
219		   G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
220		   "Only one of text and text-file must be set");
221
222  };
223
224  const char *get_line (unsigned int *len);
225
226  const char *text;
227  const char *text_file;
228
229  private:
230  FILE *fp;
231  GString *gs;
232  unsigned int text_len;
233};
234
235struct output_options_t : option_group_t
236{
237  output_options_t (option_parser_t *parser) {
238    output_file = NULL;
239    output_format = NULL;
240
241    fp = NULL;
242
243    add_options (parser);
244  }
245  ~output_options_t (void) {
246    if (fp)
247      fclose (fp);
248  }
249
250  void add_options (option_parser_t *parser);
251
252  void post_parse (GError **error G_GNUC_UNUSED)
253  {
254    if (output_file && !output_format) {
255      output_format = strrchr (output_file, '.');
256      if (output_format)
257	  output_format++; /* skip the dot */
258    }
259
260    if (output_file && 0 == strcmp (output_file, "-"))
261      output_file = NULL; /* STDOUT */
262  }
263
264  FILE *get_file_handle (void);
265
266  virtual void init (const font_options_t *font_opts) = 0;
267  virtual void consume_line (hb_buffer_t  *buffer,
268			     const char   *text,
269			     unsigned int  text_len) = 0;
270  virtual void finish (const font_options_t *font_opts) = 0;
271
272  const char *output_file;
273  const char *output_format;
274
275  protected:
276
277  mutable FILE *fp;
278};
279
280struct format_options_t : option_group_t
281{
282  format_options_t (option_parser_t *parser) {
283    show_glyph_names = true;
284    show_positions = true;
285    show_clusters = true;
286
287    add_options (parser);
288  }
289  ~format_options_t (void) {
290  }
291
292  void add_options (option_parser_t *parser);
293
294  void serialize (hb_buffer_t *buffer,
295		  hb_font_t   *font,
296		  GString     *gs);
297
298  protected:
299  hb_bool_t show_glyph_names;
300  hb_bool_t show_positions;
301  hb_bool_t show_clusters;
302};
303
304
305#endif
306