options.hh revision 1172dc736280566426eb6dade1a886b2a0ca9aa4
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>
4352e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod#ifdef HAVE_UNISTD_H
4452e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod#include <unistd.h> /* for isatty() */
4552e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod#endif
468b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod#ifdef HAVE_IO_H
478b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod#include <io.h> /* for _setmode() under Windows */
488b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod#endif
498b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod
508b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod#include <hb.h>
51c87b317f0eb118e67134e8e419a6d65e0fa40d30Behdad Esfahbod#ifdef HAVE_OT
52c87b317f0eb118e67134e8e419a6d65e0fa40d30Behdad Esfahbod#include <hb-ot.h>
53c87b317f0eb118e67134e8e419a6d65e0fa40d30Behdad Esfahbod#endif
548b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod#include <glib.h>
558b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod#include <glib/gprintf.h>
568b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod
5769b84a8f6c789726815261c2e86692de7a65d6e8Behdad Esfahbod#undef MIN
5869b84a8f6c789726815261c2e86692de7a65d6e8Behdad Esfahbodtemplate <typename Type> static inline Type MIN (const Type &a, const Type &b) { return a < b ? a : b; }
5969b84a8f6c789726815261c2e86692de7a65d6e8Behdad Esfahbod
6069b84a8f6c789726815261c2e86692de7a65d6e8Behdad Esfahbod#undef MAX
6169b84a8f6c789726815261c2e86692de7a65d6e8Behdad Esfahbodtemplate <typename Type> static inline Type MAX (const Type &a, const Type &b) { return a > b ? a : b; }
6269b84a8f6c789726815261c2e86692de7a65d6e8Behdad Esfahbod
6369b84a8f6c789726815261c2e86692de7a65d6e8Behdad Esfahbod
648b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbodvoid fail (hb_bool_t suggest_help, const char *format, ...) G_GNUC_NORETURN;
658b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod
668b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod
67088c1e27c0fc0cdef999cf1f567e4d5eb2cfb2e4Behdad Esfahbodextern hb_bool_t debug;
68b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
69b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodstruct option_group_t
70b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod{
71b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  virtual void add_options (struct option_parser_t *parser) = 0;
72b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
73b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  virtual void pre_parse (GError **error G_GNUC_UNUSED) {};
74b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  virtual void post_parse (GError **error G_GNUC_UNUSED) {};
75b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod};
76b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
77b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
78b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodstruct option_parser_t
79b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod{
80b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  option_parser_t (const char *usage) {
81b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    memset (this, 0, sizeof (*this));
82b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    usage_str = usage;
83b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    context = g_option_context_new (usage);
84b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
85b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    add_main_options ();
86b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  }
87b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  ~option_parser_t (void) {
88b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    g_option_context_free (context);
89b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  }
90b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
91b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  void add_main_options (void);
92b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
93b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  void add_group (GOptionEntry   *entries,
94b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod		  const gchar    *name,
95b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod		  const gchar    *description,
96b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod		  const gchar    *help_description,
97b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod		  option_group_t *option_group);
98b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
99b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  void parse (int *argc, char ***argv);
100b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
101b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  G_GNUC_NORETURN void usage (void) {
102b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    g_printerr ("Usage: %s [OPTION...] %s\n", g_get_prgname (), usage_str);
103b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    exit (1);
104b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  }
105b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
106b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  const char *usage_str;
107b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  GOptionContext *context;
108b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod};
109b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
110b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
111912c5ff80a255edb8145b9db69e2ed828f8eab5cBehdad Esfahbod#define DEFAULT_MARGIN 16
112109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod#define DEFAULT_FORE "#000000"
113109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod#define DEFAULT_BACK "#FFFFFF"
1142097951110e33fe091ed9515ae77e2683c46c889Behdad Esfahbod#define DEFAULT_FONT_SIZE 256
115109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod
116b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodstruct view_options_t : option_group_t
1173bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod{
118b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  view_options_t (option_parser_t *parser) {
119b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    annotate = false;
120109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod    fore = DEFAULT_FORE;
121109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod    back = DEFAULT_BACK;
122b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    line_space = 0;
123109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod    margin.t = margin.r = margin.b = margin.l = DEFAULT_MARGIN;
12411e51993ab562d4c7460eb7c43d0e97404e628e7Behdad Esfahbod    font_size = DEFAULT_FONT_SIZE;
125b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
126b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    add_options (parser);
1273bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod  }
1283bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod
129b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  void add_options (option_parser_t *parser);
130bc4b07b05ea9e39eb9f966eb2c3e1c737efa77ffBehdad Esfahbod
131088c1e27c0fc0cdef999cf1f567e4d5eb2cfb2e4Behdad Esfahbod  hb_bool_t annotate;
1323bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod  const char *fore;
1333bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod  const char *back;
1343bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod  double line_space;
1353bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod  struct margin_t {
1363bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod    double t, r, b, l;
1373bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod  } margin;
13811e51993ab562d4c7460eb7c43d0e97404e628e7Behdad Esfahbod  double font_size;
139b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod};
1403bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod
141109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod
142b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodstruct shape_options_t : option_group_t
1433bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod{
144ae62166519291057316a9d15cea3f1570fcb5eafBehdad Esfahbod  shape_options_t (option_parser_t *parser)
145ae62166519291057316a9d15cea3f1570fcb5eafBehdad Esfahbod  {
146b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    direction = language = script = NULL;
147407f80d62589774f845ef1a6a0a7d841b09d57c6Behdad Esfahbod    bot = eot = preserve_default_ignorables = false;
148b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    features = NULL;
149b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    num_features = 0;
150b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    shapers = NULL;
15195cefdf96efe43a44133aa8a186155cf4e63e2b7Behdad Esfahbod    utf8_clusters = false;
15239b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod    normalize_glyphs = false;
153b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
154b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    add_options (parser);
1553bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod  }
156ae62166519291057316a9d15cea3f1570fcb5eafBehdad Esfahbod  ~shape_options_t (void)
157ae62166519291057316a9d15cea3f1570fcb5eafBehdad Esfahbod  {
15890e312cb85df7a6dc350cb62138ab950790e3d15Behdad Esfahbod    free (features);
159ade7459ea7c75b4f33f7cfa43dd5bdfa0c18d6d5Behdad Esfahbod    g_strfreev (shapers);
16090e312cb85df7a6dc350cb62138ab950790e3d15Behdad Esfahbod  }
1613bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod
162b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  void add_options (option_parser_t *parser);
163bc4b07b05ea9e39eb9f966eb2c3e1c737efa77ffBehdad Esfahbod
164ae62166519291057316a9d15cea3f1570fcb5eafBehdad Esfahbod  void setup_buffer (hb_buffer_t *buffer)
165ae62166519291057316a9d15cea3f1570fcb5eafBehdad Esfahbod  {
166516857eb51bbb79ff4adf44e3fefbf460f9ee8f8Behdad Esfahbod    hb_buffer_set_direction (buffer, hb_direction_from_string (direction, -1));
167516857eb51bbb79ff4adf44e3fefbf460f9ee8f8Behdad Esfahbod    hb_buffer_set_script (buffer, hb_script_from_string (script, -1));
168516857eb51bbb79ff4adf44e3fefbf460f9ee8f8Behdad Esfahbod    hb_buffer_set_language (buffer, hb_language_from_string (language, -1));
169407f80d62589774f845ef1a6a0a7d841b09d57c6Behdad Esfahbod    hb_buffer_set_flags (buffer, (hb_buffer_flags_t) (HB_BUFFER_FLAGS_DEFAULT |
170407f80d62589774f845ef1a6a0a7d841b09d57c6Behdad Esfahbod			 (bot ? HB_BUFFER_FLAG_BOT : 0) |
171407f80d62589774f845ef1a6a0a7d841b09d57c6Behdad Esfahbod			 (eot ? HB_BUFFER_FLAG_EOT : 0) |
172407f80d62589774f845ef1a6a0a7d841b09d57c6Behdad Esfahbod			 (preserve_default_ignorables ? HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES : 0)));
1734f4b114a5592c2f5d128ee795f159b438ad97829Behdad Esfahbod  }
1744f4b114a5592c2f5d128ee795f159b438ad97829Behdad Esfahbod
175321f73c16efa0730c96e001d65268f4927a0f735Behdad Esfahbod  void populate_buffer (hb_buffer_t *buffer, const char *text, int text_len,
176321f73c16efa0730c96e001d65268f4927a0f735Behdad Esfahbod			const char *text_before, const char *text_after)
177ae62166519291057316a9d15cea3f1570fcb5eafBehdad Esfahbod  {
1781172dc736280566426eb6dade1a886b2a0ca9aa4Behdad Esfahbod    hb_buffer_clear_contents (buffer);
179321f73c16efa0730c96e001d65268f4927a0f735Behdad Esfahbod    if (text_before) {
180321f73c16efa0730c96e001d65268f4927a0f735Behdad Esfahbod      unsigned int len = strlen (text_before);
181321f73c16efa0730c96e001d65268f4927a0f735Behdad Esfahbod      hb_buffer_add_utf8 (buffer, text_before, len, len, 0);
182321f73c16efa0730c96e001d65268f4927a0f735Behdad Esfahbod    }
183b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    hb_buffer_add_utf8 (buffer, text, text_len, 0, text_len);
184321f73c16efa0730c96e001d65268f4927a0f735Behdad Esfahbod    if (text_after) {
185321f73c16efa0730c96e001d65268f4927a0f735Behdad Esfahbod      hb_buffer_add_utf8 (buffer, text_after, -1, 0, 0);
186321f73c16efa0730c96e001d65268f4927a0f735Behdad Esfahbod    }
187d5300241680844f5625f32792f7dd7181ed05f9bBehdad Esfahbod
18895cefdf96efe43a44133aa8a186155cf4e63e2b7Behdad Esfahbod    if (!utf8_clusters) {
18995cefdf96efe43a44133aa8a186155cf4e63e2b7Behdad Esfahbod      /* Reset cluster values to refer to Unicode character index
19095cefdf96efe43a44133aa8a186155cf4e63e2b7Behdad Esfahbod       * instead of UTF-8 index. */
19195cefdf96efe43a44133aa8a186155cf4e63e2b7Behdad Esfahbod      unsigned int num_glyphs = hb_buffer_get_length (buffer);
19295cefdf96efe43a44133aa8a186155cf4e63e2b7Behdad Esfahbod      hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, NULL);
19395cefdf96efe43a44133aa8a186155cf4e63e2b7Behdad Esfahbod      for (unsigned int i = 0; i < num_glyphs; i++)
19495cefdf96efe43a44133aa8a186155cf4e63e2b7Behdad Esfahbod      {
19595cefdf96efe43a44133aa8a186155cf4e63e2b7Behdad Esfahbod	info->cluster = i;
19695cefdf96efe43a44133aa8a186155cf4e63e2b7Behdad Esfahbod	info++;
19795cefdf96efe43a44133aa8a186155cf4e63e2b7Behdad Esfahbod      }
198d5300241680844f5625f32792f7dd7181ed05f9bBehdad Esfahbod    }
199d5300241680844f5625f32792f7dd7181ed05f9bBehdad Esfahbod
2004f4b114a5592c2f5d128ee795f159b438ad97829Behdad Esfahbod    setup_buffer (buffer);
201ae62166519291057316a9d15cea3f1570fcb5eafBehdad Esfahbod  }
202ae62166519291057316a9d15cea3f1570fcb5eafBehdad Esfahbod
203ae62166519291057316a9d15cea3f1570fcb5eafBehdad Esfahbod  hb_bool_t shape (hb_font_t *font, hb_buffer_t *buffer)
204ae62166519291057316a9d15cea3f1570fcb5eafBehdad Esfahbod  {
20539b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod    hb_bool_t res = hb_shape_full (font, buffer, features, num_features, shapers);
20639b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod    if (normalize_glyphs)
20739b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod      hb_buffer_normalize_glyphs (buffer);
20839b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod    return res;
2094f4b114a5592c2f5d128ee795f159b438ad97829Behdad Esfahbod  }
2104f4b114a5592c2f5d128ee795f159b438ad97829Behdad Esfahbod
211c87b317f0eb118e67134e8e419a6d65e0fa40d30Behdad Esfahbod  void shape_closure (const char *text, int text_len,
212c87b317f0eb118e67134e8e419a6d65e0fa40d30Behdad Esfahbod		      hb_font_t *font, hb_buffer_t *buffer,
213ae62166519291057316a9d15cea3f1570fcb5eafBehdad Esfahbod		      hb_set_t *glyphs)
214ae62166519291057316a9d15cea3f1570fcb5eafBehdad Esfahbod  {
215c87b317f0eb118e67134e8e419a6d65e0fa40d30Behdad Esfahbod    hb_buffer_reset (buffer);
216c87b317f0eb118e67134e8e419a6d65e0fa40d30Behdad Esfahbod    hb_buffer_add_utf8 (buffer, text, text_len, 0, text_len);
217c87b317f0eb118e67134e8e419a6d65e0fa40d30Behdad Esfahbod    setup_buffer (buffer);
218c87b317f0eb118e67134e8e419a6d65e0fa40d30Behdad Esfahbod    hb_ot_shape_glyphs_closure (font, buffer, features, num_features, glyphs);
219c87b317f0eb118e67134e8e419a6d65e0fa40d30Behdad Esfahbod  }
220c87b317f0eb118e67134e8e419a6d65e0fa40d30Behdad Esfahbod
221407f80d62589774f845ef1a6a0a7d841b09d57c6Behdad Esfahbod  /* Buffer properties */
2223bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod  const char *direction;
2233bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod  const char *language;
2243bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod  const char *script;
225407f80d62589774f845ef1a6a0a7d841b09d57c6Behdad Esfahbod
226407f80d62589774f845ef1a6a0a7d841b09d57c6Behdad Esfahbod  /* Buffer flags */
227407f80d62589774f845ef1a6a0a7d841b09d57c6Behdad Esfahbod  hb_bool_t bot;
228407f80d62589774f845ef1a6a0a7d841b09d57c6Behdad Esfahbod  hb_bool_t eot;
229407f80d62589774f845ef1a6a0a7d841b09d57c6Behdad Esfahbod  hb_bool_t preserve_default_ignorables;
230407f80d62589774f845ef1a6a0a7d841b09d57c6Behdad Esfahbod
2313bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod  hb_feature_t *features;
2323bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod  unsigned int num_features;
2333bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod  char **shapers;
23495cefdf96efe43a44133aa8a186155cf4e63e2b7Behdad Esfahbod  hb_bool_t utf8_clusters;
23539b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod  hb_bool_t normalize_glyphs;
236b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod};
2373bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod
238109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod
239b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodstruct font_options_t : option_group_t
2403bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod{
241b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  font_options_t (option_parser_t *parser) {
242b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    font_file = NULL;
243b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    face_index = 0;
244b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
245b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    font = NULL;
246b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
247b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    add_options (parser);
248b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  }
249b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  ~font_options_t (void) {
250b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    hb_font_destroy (font);
2513bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod  }
2523bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod
253b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  void add_options (option_parser_t *parser);
254b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
255b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  hb_font_t *get_font (void) const;
256bc4b07b05ea9e39eb9f966eb2c3e1c737efa77ffBehdad Esfahbod
2573bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod  const char *font_file;
2583bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod  int face_index;
2593bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod
260b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  private:
261b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  mutable hb_font_t *font;
262b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod};
263b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
264b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
265b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodstruct text_options_t : option_group_t
266b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod{
267b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  text_options_t (option_parser_t *parser) {
268321f73c16efa0730c96e001d65268f4927a0f735Behdad Esfahbod    text_before = NULL;
269321f73c16efa0730c96e001d65268f4927a0f735Behdad Esfahbod    text_after = NULL;
270321f73c16efa0730c96e001d65268f4927a0f735Behdad Esfahbod
271b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    text = NULL;
272b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    text_file = NULL;
273b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
27455aeb0490454cc1ba93a42f307ed1230f59dee4bBehdad Esfahbod    fp = NULL;
27555aeb0490454cc1ba93a42f307ed1230f59dee4bBehdad Esfahbod    gs = NULL;
276b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    text_len = (unsigned int) -1;
277b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
278b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    add_options (parser);
279b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  }
280b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  ~text_options_t (void) {
28155aeb0490454cc1ba93a42f307ed1230f59dee4bBehdad Esfahbod    if (gs)
2820594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod      g_string_free (gs, true);
28355aeb0490454cc1ba93a42f307ed1230f59dee4bBehdad Esfahbod    if (fp)
28455aeb0490454cc1ba93a42f307ed1230f59dee4bBehdad Esfahbod      fclose (fp);
285b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  }
286b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
287b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  void add_options (option_parser_t *parser);
288b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
289b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  void post_parse (GError **error G_GNUC_UNUSED) {
290b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    if (text && text_file)
291b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod      g_set_error (error,
292b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod		   G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
29330874b4819a99cc84fa39e794266685e1b8735d2Behdad Esfahbod		   "Only one of text and text-file can be set");
294b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
295b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  };
296b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
297b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  const char *get_line (unsigned int *len);
298b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
299321f73c16efa0730c96e001d65268f4927a0f735Behdad Esfahbod  const char *text_before;
300321f73c16efa0730c96e001d65268f4927a0f735Behdad Esfahbod  const char *text_after;
301321f73c16efa0730c96e001d65268f4927a0f735Behdad Esfahbod
302b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  const char *text;
303b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  const char *text_file;
304b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
305b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  private:
30655aeb0490454cc1ba93a42f307ed1230f59dee4bBehdad Esfahbod  FILE *fp;
30755aeb0490454cc1ba93a42f307ed1230f59dee4bBehdad Esfahbod  GString *gs;
30855aeb0490454cc1ba93a42f307ed1230f59dee4bBehdad Esfahbod  unsigned int text_len;
309b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod};
310b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
311b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodstruct output_options_t : option_group_t
312b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod{
3139815a88111072aa51e78e258c5f660993b47d4dfBehdad Esfahbod  output_options_t (option_parser_t *parser,
3149815a88111072aa51e78e258c5f660993b47d4dfBehdad Esfahbod		    const char *supported_formats_ = NULL) {
315b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    output_file = NULL;
316b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    output_format = NULL;
3179815a88111072aa51e78e258c5f660993b47d4dfBehdad Esfahbod    supported_formats = supported_formats_;
3186bad092aa87bc3e6bbf0b9faf07693e6ebbe55f2Behdad Esfahbod    explicit_output_format = false;
319b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
320f7e2ef74f856ee13d6fd6cf3f1e04bc162203bc2Behdad Esfahbod    fp = NULL;
321f7e2ef74f856ee13d6fd6cf3f1e04bc162203bc2Behdad Esfahbod
322b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    add_options (parser);
323b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  }
324f7e2ef74f856ee13d6fd6cf3f1e04bc162203bc2Behdad Esfahbod  ~output_options_t (void) {
32555aeb0490454cc1ba93a42f307ed1230f59dee4bBehdad Esfahbod    if (fp)
326f7e2ef74f856ee13d6fd6cf3f1e04bc162203bc2Behdad Esfahbod      fclose (fp);
327f7e2ef74f856ee13d6fd6cf3f1e04bc162203bc2Behdad Esfahbod  }
328b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
329b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  void add_options (option_parser_t *parser);
330b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
331b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  void post_parse (GError **error G_GNUC_UNUSED)
332b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  {
3336bad092aa87bc3e6bbf0b9faf07693e6ebbe55f2Behdad Esfahbod    if (output_format)
3346bad092aa87bc3e6bbf0b9faf07693e6ebbe55f2Behdad Esfahbod      explicit_output_format = true;
3356bad092aa87bc3e6bbf0b9faf07693e6ebbe55f2Behdad Esfahbod
336b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    if (output_file && !output_format) {
337b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod      output_format = strrchr (output_file, '.');
338b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod      if (output_format)
339b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod	  output_format++; /* skip the dot */
340b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod    }
341b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod
342f7e2ef74f856ee13d6fd6cf3f1e04bc162203bc2Behdad Esfahbod    if (output_file && 0 == strcmp (output_file, "-"))
343f7e2ef74f856ee13d6fd6cf3f1e04bc162203bc2Behdad Esfahbod      output_file = NULL; /* STDOUT */
344f7e2ef74f856ee13d6fd6cf3f1e04bc162203bc2Behdad Esfahbod  }
345f7e2ef74f856ee13d6fd6cf3f1e04bc162203bc2Behdad Esfahbod
346a75c1b125159f6cfb6b652a9ec40803f7c7e3f71Behdad Esfahbod  FILE *get_file_handle (void);
3473bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod
348b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  const char *output_file;
349b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod  const char *output_format;
3509815a88111072aa51e78e258c5f660993b47d4dfBehdad Esfahbod  const char *supported_formats;
3516bad092aa87bc3e6bbf0b9faf07693e6ebbe55f2Behdad Esfahbod  bool explicit_output_format;
352f7e2ef74f856ee13d6fd6cf3f1e04bc162203bc2Behdad Esfahbod
353f7e2ef74f856ee13d6fd6cf3f1e04bc162203bc2Behdad Esfahbod  mutable FILE *fp;
354b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod};
3553bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod
3568b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbodstruct format_options_t : option_group_t
3578b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod{
3588b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod  format_options_t (option_parser_t *parser) {
3598b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod    show_glyph_names = true;
3608b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod    show_positions = true;
3618b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod    show_clusters = true;
362cc4d9810d6318ca2e4de3b8d62f03b51cc21ee05Behdad Esfahbod    show_text = false;
363cc4d9810d6318ca2e4de3b8d62f03b51cc21ee05Behdad Esfahbod    show_unicode = false;
364cdc673d97c5ffedb386865a81f54a5cedcbad27cBehdad Esfahbod    show_line_num = false;
3658b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod
3668b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod    add_options (parser);
3678b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod  }
3688b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod
3698b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod  void add_options (option_parser_t *parser);
3708b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod
371cdc673d97c5ffedb386865a81f54a5cedcbad27cBehdad Esfahbod  void serialize_unicode (hb_buffer_t  *buffer,
372cdc673d97c5ffedb386865a81f54a5cedcbad27cBehdad Esfahbod			  GString      *gs);
373cdc673d97c5ffedb386865a81f54a5cedcbad27cBehdad Esfahbod  void serialize_glyphs (hb_buffer_t  *buffer,
374cdc673d97c5ffedb386865a81f54a5cedcbad27cBehdad Esfahbod			 hb_font_t    *font,
375f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod			 hb_buffer_serialize_format_t format,
376f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod			 hb_buffer_serialize_flags_t flags,
377cdc673d97c5ffedb386865a81f54a5cedcbad27cBehdad Esfahbod			 GString      *gs);
378cdc673d97c5ffedb386865a81f54a5cedcbad27cBehdad Esfahbod  void serialize_line_no (unsigned int  line_no,
379cdc673d97c5ffedb386865a81f54a5cedcbad27cBehdad Esfahbod			  GString      *gs);
3805db0683a822f70c914468430cda6487cee740ae3Behdad Esfahbod  void serialize_buffer_of_text (hb_buffer_t  *buffer,
3815db0683a822f70c914468430cda6487cee740ae3Behdad Esfahbod				 unsigned int  line_no,
3825db0683a822f70c914468430cda6487cee740ae3Behdad Esfahbod				 const char   *text,
3835db0683a822f70c914468430cda6487cee740ae3Behdad Esfahbod				 unsigned int  text_len,
3845db0683a822f70c914468430cda6487cee740ae3Behdad Esfahbod				 hb_font_t    *font,
3855db0683a822f70c914468430cda6487cee740ae3Behdad Esfahbod				 GString      *gs);
3865db0683a822f70c914468430cda6487cee740ae3Behdad Esfahbod  void serialize_message (unsigned int  line_no,
3875db0683a822f70c914468430cda6487cee740ae3Behdad Esfahbod			  const char   *msg,
3885db0683a822f70c914468430cda6487cee740ae3Behdad Esfahbod			  GString      *gs);
3895db0683a822f70c914468430cda6487cee740ae3Behdad Esfahbod  void serialize_buffer_of_glyphs (hb_buffer_t  *buffer,
3905db0683a822f70c914468430cda6487cee740ae3Behdad Esfahbod				   unsigned int  line_no,
3915db0683a822f70c914468430cda6487cee740ae3Behdad Esfahbod				   const char   *text,
3925db0683a822f70c914468430cda6487cee740ae3Behdad Esfahbod				   unsigned int  text_len,
3935db0683a822f70c914468430cda6487cee740ae3Behdad Esfahbod				   hb_font_t    *font,
394f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod				   hb_buffer_serialize_format_t output_format,
395f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod				   hb_buffer_serialize_flags_t format_flags,
3965db0683a822f70c914468430cda6487cee740ae3Behdad Esfahbod				   GString      *gs);
397cdc673d97c5ffedb386865a81f54a5cedcbad27cBehdad Esfahbod
3988b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod
399088c1e27c0fc0cdef999cf1f567e4d5eb2cfb2e4Behdad Esfahbod  hb_bool_t show_glyph_names;
400088c1e27c0fc0cdef999cf1f567e4d5eb2cfb2e4Behdad Esfahbod  hb_bool_t show_positions;
401088c1e27c0fc0cdef999cf1f567e4d5eb2cfb2e4Behdad Esfahbod  hb_bool_t show_clusters;
402cc4d9810d6318ca2e4de3b8d62f03b51cc21ee05Behdad Esfahbod  hb_bool_t show_text;
403cc4d9810d6318ca2e4de3b8d62f03b51cc21ee05Behdad Esfahbod  hb_bool_t show_unicode;
404cdc673d97c5ffedb386865a81f54a5cedcbad27cBehdad Esfahbod  hb_bool_t show_line_num;
4058b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod};
4068b8b19056decaf09e4e0ccd9412ee1aeb30f4de7Behdad Esfahbod
4073bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod
4083bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod#endif
409