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