options.hh revision d5300241680844f5625f32792f7dd7181ed05f9b
13bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod/*
23bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod * Copyright © 2011  Google, Inc.
33bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod *
43bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod *  This is part of HarfBuzz, a text shaping library.
53bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod *
63bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod * Permission is hereby granted, without written agreement and without
73bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod * license or royalty fees, to use, copy, modify, and distribute this
83bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod * software and its documentation for any purpose, provided that the
93bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod * above copyright notice and the following two paragraphs appear in
103bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod * all copies of this software.
113bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod *
123bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
133bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
143bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
153bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
163bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod * DAMAGE.
173bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod *
183bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
193bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
203bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
213bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
223bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
233bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod *
243bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod * Google Author(s): Behdad Esfahbod
253bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod */
263bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod
273bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod#ifndef OPTIONS_HH
283bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod#define OPTIONS_HH
293bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod
303bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod
318b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod#ifdef HAVE_CONFIG_H
328b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod#include "config.h"
338b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod#endif
348b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod
358b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod#include <stdlib.h>
368b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod#include <stddef.h>
378b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod#include <string.h>
388b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod#include <stdio.h>
398b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod#include <math.h>
408b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod#include <locale.h>
418b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod#include <errno.h>
428b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod#include <fcntl.h>
438b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod#ifdef HAVE_IO_H
448b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod#include <io.h> /* for _setmode() under Windows */
458b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod#endif
468b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod
478b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod#include <hb.h>
488b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod#include <glib.h>
498b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod#include <glib/gprintf.h>
508b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod
518b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbodvoid fail (hb_bool_t suggest_help, const char *format, ...) G_GNUC_NORETURN;
528b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod
538b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod
54088c1e27c0fc0cdef999cf1f567e4d5eb2cfb2e4Behdad Esfahbodextern hb_bool_t debug;
55b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
56b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodstruct option_group_t
57b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod{
58b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  virtual void add_options (struct option_parser_t *parser) = 0;
59b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
60b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  virtual void pre_parse (GError **error G_GNUC_UNUSED) {};
61b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  virtual void post_parse (GError **error G_GNUC_UNUSED) {};
62b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod};
63b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
64b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
65b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodstruct option_parser_t
66b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod{
67b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  option_parser_t (const char *usage) {
68b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    memset (this, 0, sizeof (*this));
69b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    usage_str = usage;
70b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    context = g_option_context_new (usage);
71b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
72b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    add_main_options ();
73b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  }
74b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  ~option_parser_t (void) {
75b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    g_option_context_free (context);
76b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  }
77b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
78b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  void add_main_options (void);
79b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
80b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  void add_group (GOptionEntry   *entries,
81b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod		  const gchar    *name,
82b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod		  const gchar    *description,
83b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod		  const gchar    *help_description,
84b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod		  option_group_t *option_group);
85b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
86b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  void parse (int *argc, char ***argv);
87b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
88b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  G_GNUC_NORETURN void usage (void) {
89b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    g_printerr ("Usage: %s [OPTION...] %s\n", g_get_prgname (), usage_str);
90b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    exit (1);
91b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  }
92b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
93b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  const char *usage_str;
94b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  GOptionContext *context;
95b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod};
96b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
97b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
98109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod#define DEFAULT_MARGIN 18
99109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod#define DEFAULT_FORE "#000000"
100109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod#define DEFAULT_BACK "#FFFFFF"
10111e51993ab562d4c7460eb7c43d0e97404e628e7Behdad Esfahbod#define DEFAULT_FONT_SIZE 36
102109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod
103b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodstruct view_options_t : option_group_t
1043bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod{
105b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  view_options_t (option_parser_t *parser) {
106b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    annotate = false;
107109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod    fore = DEFAULT_FORE;
108109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod    back = DEFAULT_BACK;
109b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    line_space = 0;
110109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod    margin.t = margin.r = margin.b = margin.l = DEFAULT_MARGIN;
11111e51993ab562d4c7460eb7c43d0e97404e628e7Behdad Esfahbod    font_size = DEFAULT_FONT_SIZE;
112b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
113b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    add_options (parser);
1143bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod  }
1153bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod
116b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  void add_options (option_parser_t *parser);
117bc4b07b05ea9e39eb9f966eb2c3e1c737efa77ffBehdad Esfahbod
118088c1e27c0fc0cdef999cf1f567e4d5eb2cfb2e4Behdad Esfahbod  hb_bool_t annotate;
1193bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod  const char *fore;
1203bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod  const char *back;
1213bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod  double line_space;
1223bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod  struct margin_t {
1233bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod    double t, r, b, l;
1243bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod  } margin;
12511e51993ab562d4c7460eb7c43d0e97404e628e7Behdad Esfahbod  double font_size;
126b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod};
1273bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod
128109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod
129b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodstruct shape_options_t : option_group_t
1303bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod{
131b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  shape_options_t (option_parser_t *parser) {
132b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    direction = language = script = NULL;
133b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    features = NULL;
134b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    num_features = 0;
135b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    shapers = NULL;
136b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
137b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    add_options (parser);
1383bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod  }
13990e312cb85df7a6dc350cb62138ab950790e3d15Behdad Esfahbod  ~shape_options_t (void) {
14090e312cb85df7a6dc350cb62138ab950790e3d15Behdad Esfahbod    free (features);
14190e312cb85df7a6dc350cb62138ab950790e3d15Behdad Esfahbod    g_free (shapers);
14290e312cb85df7a6dc350cb62138ab950790e3d15Behdad Esfahbod  }
1433bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod
144b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  void add_options (option_parser_t *parser);
145bc4b07b05ea9e39eb9f966eb2c3e1c737efa77ffBehdad Esfahbod
1464f4b114a5592c2f5d128ee795f159b438ad97829Behdad Esfahbod  void setup_buffer (hb_buffer_t *buffer) {
147516857eb51bbb79ff4adf44e3fefbf460f9ee8f8Behdad Esfahbod    hb_buffer_set_direction (buffer, hb_direction_from_string (direction, -1));
148516857eb51bbb79ff4adf44e3fefbf460f9ee8f8Behdad Esfahbod    hb_buffer_set_script (buffer, hb_script_from_string (script, -1));
149516857eb51bbb79ff4adf44e3fefbf460f9ee8f8Behdad Esfahbod    hb_buffer_set_language (buffer, hb_language_from_string (language, -1));
1504f4b114a5592c2f5d128ee795f159b438ad97829Behdad Esfahbod  }
1514f4b114a5592c2f5d128ee795f159b438ad97829Behdad Esfahbod
152088c1e27c0fc0cdef999cf1f567e4d5eb2cfb2e4Behdad Esfahbod  hb_bool_t shape (const char *text, int text_len,
153088c1e27c0fc0cdef999cf1f567e4d5eb2cfb2e4Behdad Esfahbod		   hb_font_t *font, hb_buffer_t *buffer) {
154b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    hb_buffer_reset (buffer);
155b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    hb_buffer_add_utf8 (buffer, text, text_len, 0, text_len);
156d5300241680844f5625f32792f7dd7181ed05f9bBehdad Esfahbod
157d5300241680844f5625f32792f7dd7181ed05f9bBehdad Esfahbod    /* Reset cluster values to refer to Unicode character index
158d5300241680844f5625f32792f7dd7181ed05f9bBehdad Esfahbod     * instead of UTF-8 index.
159d5300241680844f5625f32792f7dd7181ed05f9bBehdad Esfahbod     * TODO: Add an option for this. */
160d5300241680844f5625f32792f7dd7181ed05f9bBehdad Esfahbod    unsigned int num_glyphs = hb_buffer_get_length (buffer);
161d5300241680844f5625f32792f7dd7181ed05f9bBehdad Esfahbod    hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, NULL);
162d5300241680844f5625f32792f7dd7181ed05f9bBehdad Esfahbod    for (unsigned int i = 0; i < num_glyphs; i++)
163d5300241680844f5625f32792f7dd7181ed05f9bBehdad Esfahbod    {
164d5300241680844f5625f32792f7dd7181ed05f9bBehdad Esfahbod      info->cluster = i;
165d5300241680844f5625f32792f7dd7181ed05f9bBehdad Esfahbod      info++;
166d5300241680844f5625f32792f7dd7181ed05f9bBehdad Esfahbod    }
167d5300241680844f5625f32792f7dd7181ed05f9bBehdad Esfahbod
1684f4b114a5592c2f5d128ee795f159b438ad97829Behdad Esfahbod    setup_buffer (buffer);
1694f4b114a5592c2f5d128ee795f159b438ad97829Behdad Esfahbod    return hb_shape_full (font, buffer, features, num_features, NULL, shapers);
1704f4b114a5592c2f5d128ee795f159b438ad97829Behdad Esfahbod  }
1714f4b114a5592c2f5d128ee795f159b438ad97829Behdad Esfahbod
1723bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod  const char *direction;
1733bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod  const char *language;
1743bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod  const char *script;
1753bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod  hb_feature_t *features;
1763bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod  unsigned int num_features;
1773bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod  char **shapers;
178b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod};
1793bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod
180109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod
181b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodstruct font_options_t : option_group_t
1823bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod{
183b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  font_options_t (option_parser_t *parser) {
184b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    font_file = NULL;
185b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    face_index = 0;
186b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
187b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    font = NULL;
188b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
189b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    add_options (parser);
190b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  }
191b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  ~font_options_t (void) {
192b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    hb_font_destroy (font);
1933bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod  }
1943bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod
195b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  void add_options (option_parser_t *parser);
196b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
197b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  hb_font_t *get_font (void) const;
198bc4b07b05ea9e39eb9f966eb2c3e1c737efa77ffBehdad Esfahbod
1993bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod  const char *font_file;
2003bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod  int face_index;
2013bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod
202b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  private:
203b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  mutable hb_font_t *font;
204b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod};
205b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
206b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
207b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodstruct text_options_t : option_group_t
208b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod{
209b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  text_options_t (option_parser_t *parser) {
210b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    text = NULL;
211b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    text_file = NULL;
212b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
21355aeb0490454cc1ba93a42f307ed1230f59dee4bBehdad Esfahbod    fp = NULL;
21455aeb0490454cc1ba93a42f307ed1230f59dee4bBehdad Esfahbod    gs = NULL;
215b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    text_len = (unsigned int) -1;
216b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
217b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    add_options (parser);
218b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  }
219b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  ~text_options_t (void) {
22055aeb0490454cc1ba93a42f307ed1230f59dee4bBehdad Esfahbod    if (gs)
22155aeb0490454cc1ba93a42f307ed1230f59dee4bBehdad Esfahbod      g_string_free (gs, TRUE);
22255aeb0490454cc1ba93a42f307ed1230f59dee4bBehdad Esfahbod    if (fp)
22355aeb0490454cc1ba93a42f307ed1230f59dee4bBehdad Esfahbod      fclose (fp);
224b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  }
225b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
226b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  void add_options (option_parser_t *parser);
227b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
228b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  void post_parse (GError **error G_GNUC_UNUSED) {
229b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    if (text && text_file)
230b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod      g_set_error (error,
231b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod		   G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
232b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod		   "Only one of text and text-file must be set");
233b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
234b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  };
235b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
236b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  const char *get_line (unsigned int *len);
237b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
238b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  const char *text;
239b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  const char *text_file;
240b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
241b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  private:
24255aeb0490454cc1ba93a42f307ed1230f59dee4bBehdad Esfahbod  FILE *fp;
24355aeb0490454cc1ba93a42f307ed1230f59dee4bBehdad Esfahbod  GString *gs;
24455aeb0490454cc1ba93a42f307ed1230f59dee4bBehdad Esfahbod  unsigned int text_len;
245b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod};
246b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
247b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodstruct output_options_t : option_group_t
248b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod{
249b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  output_options_t (option_parser_t *parser) {
250b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    output_file = NULL;
251b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    output_format = NULL;
252b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
253f7e2ef74f856ee13d6fd6cf3f1e04bc162203bc2Behdad Esfahbod    fp = NULL;
254f7e2ef74f856ee13d6fd6cf3f1e04bc162203bc2Behdad Esfahbod
255b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    add_options (parser);
256b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  }
257f7e2ef74f856ee13d6fd6cf3f1e04bc162203bc2Behdad Esfahbod  ~output_options_t (void) {
25855aeb0490454cc1ba93a42f307ed1230f59dee4bBehdad Esfahbod    if (fp)
259f7e2ef74f856ee13d6fd6cf3f1e04bc162203bc2Behdad Esfahbod      fclose (fp);
260f7e2ef74f856ee13d6fd6cf3f1e04bc162203bc2Behdad Esfahbod  }
261b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
262b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  void add_options (option_parser_t *parser);
263b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
264b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  void post_parse (GError **error G_GNUC_UNUSED)
265b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  {
266b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    if (output_file && !output_format) {
267b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod      output_format = strrchr (output_file, '.');
268b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod      if (output_format)
269b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod	  output_format++; /* skip the dot */
270b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    }
271b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
272f7e2ef74f856ee13d6fd6cf3f1e04bc162203bc2Behdad Esfahbod    if (output_file && 0 == strcmp (output_file, "-"))
273f7e2ef74f856ee13d6fd6cf3f1e04bc162203bc2Behdad Esfahbod      output_file = NULL; /* STDOUT */
274f7e2ef74f856ee13d6fd6cf3f1e04bc162203bc2Behdad Esfahbod  }
275f7e2ef74f856ee13d6fd6cf3f1e04bc162203bc2Behdad Esfahbod
276a75c1b125159f6cfb6b652a9ec40803f7c7e3f71Behdad Esfahbod  FILE *get_file_handle (void);
2773bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod
278b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  virtual void init (const font_options_t *font_opts) = 0;
279b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  virtual void consume_line (hb_buffer_t  *buffer,
280b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod			     const char   *text,
281b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod			     unsigned int  text_len) = 0;
282b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  virtual void finish (const font_options_t *font_opts) = 0;
2833bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod
284b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  const char *output_file;
285b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  const char *output_format;
286f7e2ef74f856ee13d6fd6cf3f1e04bc162203bc2Behdad Esfahbod
2878b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod  protected:
2888b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod
289f7e2ef74f856ee13d6fd6cf3f1e04bc162203bc2Behdad Esfahbod  mutable FILE *fp;
290b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod};
2913bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod
2928b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbodstruct format_options_t : option_group_t
2938b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod{
2948b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod  format_options_t (option_parser_t *parser) {
2958b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod    show_glyph_names = true;
2968b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod    show_positions = true;
2978b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod    show_clusters = true;
298cc4d9810d6318ca2e4de3b8d62f03b51cc21ee05Behdad Esfahbod    show_text = false;
299cc4d9810d6318ca2e4de3b8d62f03b51cc21ee05Behdad Esfahbod    show_unicode = false;
300cdc673d97c5ffedb386865a81f54a5cedcbad27cBehdad Esfahbod    show_line_num = false;
301cdc673d97c5ffedb386865a81f54a5cedcbad27cBehdad Esfahbod    scratch = hb_buffer_create ();
3028b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod
3038b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod    add_options (parser);
3048b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod  }
3058b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod  ~format_options_t (void) {
306cdc673d97c5ffedb386865a81f54a5cedcbad27cBehdad Esfahbod    hb_buffer_destroy (scratch);
3078b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod  }
3088b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod
3098b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod  void add_options (option_parser_t *parser);
3108b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod
311cdc673d97c5ffedb386865a81f54a5cedcbad27cBehdad Esfahbod  void serialize_unicode (hb_buffer_t  *buffer,
312cdc673d97c5ffedb386865a81f54a5cedcbad27cBehdad Esfahbod			  GString      *gs);
313cdc673d97c5ffedb386865a81f54a5cedcbad27cBehdad Esfahbod  void serialize_glyphs (hb_buffer_t  *buffer,
314cdc673d97c5ffedb386865a81f54a5cedcbad27cBehdad Esfahbod			 hb_font_t    *font,
315cdc673d97c5ffedb386865a81f54a5cedcbad27cBehdad Esfahbod			 GString      *gs);
316cdc673d97c5ffedb386865a81f54a5cedcbad27cBehdad Esfahbod  void serialize_line_no (unsigned int  line_no,
317cdc673d97c5ffedb386865a81f54a5cedcbad27cBehdad Esfahbod			  GString      *gs);
318cdc673d97c5ffedb386865a81f54a5cedcbad27cBehdad Esfahbod  void serialize_line (hb_buffer_t  *buffer,
319cdc673d97c5ffedb386865a81f54a5cedcbad27cBehdad Esfahbod		       unsigned int  line_no,
320cdc673d97c5ffedb386865a81f54a5cedcbad27cBehdad Esfahbod		       const char   *text,
321cdc673d97c5ffedb386865a81f54a5cedcbad27cBehdad Esfahbod		       unsigned int  text_len,
322cdc673d97c5ffedb386865a81f54a5cedcbad27cBehdad Esfahbod		       hb_font_t    *font,
323cdc673d97c5ffedb386865a81f54a5cedcbad27cBehdad Esfahbod		       GString      *gs);
324cdc673d97c5ffedb386865a81f54a5cedcbad27cBehdad Esfahbod
3258b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod
3268b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod  protected:
327088c1e27c0fc0cdef999cf1f567e4d5eb2cfb2e4Behdad Esfahbod  hb_bool_t show_glyph_names;
328088c1e27c0fc0cdef999cf1f567e4d5eb2cfb2e4Behdad Esfahbod  hb_bool_t show_positions;
329088c1e27c0fc0cdef999cf1f567e4d5eb2cfb2e4Behdad Esfahbod  hb_bool_t show_clusters;
330cc4d9810d6318ca2e4de3b8d62f03b51cc21ee05Behdad Esfahbod  hb_bool_t show_text;
331cc4d9810d6318ca2e4de3b8d62f03b51cc21ee05Behdad Esfahbod  hb_bool_t show_unicode;
332cdc673d97c5ffedb386865a81f54a5cedcbad27cBehdad Esfahbod  hb_bool_t show_line_num;
333cdc673d97c5ffedb386865a81f54a5cedcbad27cBehdad Esfahbod  private:
334cdc673d97c5ffedb386865a81f54a5cedcbad27cBehdad Esfahbod  hb_buffer_t *scratch;
3358b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod};
3368b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod
3373bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod
3383bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod#endif
339