options.cc revision 4451168e5d1ea26560899e9a9733b3a3f1853050
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#include "options.hh" 283bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 29b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod#if HAVE_FREETYPE 30b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod#include <hb-ft.h> 31b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod#endif 323bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 333bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 34b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodbool debug = FALSE; 35b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod 36b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodstatic gchar * 37b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodshapers_to_string (void) 38b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod{ 39b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod GString *shapers = g_string_new (NULL); 40b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod const char **shaper_list = hb_shape_list_shapers (); 41b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod 42b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod for (; *shaper_list; shaper_list++) { 43b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod g_string_append (shapers, *shaper_list); 44b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod g_string_append_c (shapers, ','); 45b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod } 46b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod g_string_truncate (shapers, MAX (0, (gint)shapers->len - 1)); 47b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod 48b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod return g_string_free (shapers, FALSE); 49b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod} 50b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod 51b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodstatic G_GNUC_NORETURN gboolean 52b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodshow_version (const char *name G_GNUC_UNUSED, 53b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod const char *arg G_GNUC_UNUSED, 54b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod gpointer data G_GNUC_UNUSED, 55b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod GError **error G_GNUC_UNUSED) 56b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod{ 57b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod g_printf ("%s (%s) %s\n", g_get_prgname (), PACKAGE_NAME, PACKAGE_VERSION); 58b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod 59b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod char *shapers = shapers_to_string (); 60b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod g_printf ("Available shapers: %s\n", shapers); 61b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod g_free (shapers); 62b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod if (strcmp (HB_VERSION_STRING, hb_version_string ())) 63b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod g_printf ("Linked HarfBuzz library has a different version: %s\n", hb_version_string ()); 64b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod 65b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod exit(0); 66b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod} 67b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod 68b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod 69b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodvoid 70b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodoption_parser_t::add_main_options (void) 71b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod{ 72b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod GOptionEntry entries[] = 73b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod { 74b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod {"version", 0, G_OPTION_FLAG_NO_ARG, 75b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod G_OPTION_ARG_CALLBACK, (gpointer) &show_version, "Show version numbers", NULL}, 76b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod {"debug", 0, 0, G_OPTION_ARG_NONE, &debug, "Free all resources before exit", NULL}, 77b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod {NULL} 78b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod }; 79b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod g_option_context_add_main_entries (context, entries, NULL); 80b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod} 81b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod 82b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodstatic gboolean 83b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodpre_parse (GOptionContext *context G_GNUC_UNUSED, 84b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod GOptionGroup *group G_GNUC_UNUSED, 85b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod gpointer data, 86b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod GError **error) 87b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod{ 88b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod option_group_t *option_group = (option_group_t *) data; 89b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod option_group->pre_parse (error); 90b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod return *error == NULL; 91b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod} 92b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod 93b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodstatic gboolean 94b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodpost_parse (GOptionContext *context G_GNUC_UNUSED, 95b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod GOptionGroup *group G_GNUC_UNUSED, 96b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod gpointer data, 97b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod GError **error) 98b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod{ 99b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod option_group_t *option_group = static_cast<option_group_t *>(data); 100b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod option_group->post_parse (error); 101b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod return *error == NULL; 102b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod} 103b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod 104b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodvoid 105b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodoption_parser_t::add_group (GOptionEntry *entries, 106b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod const gchar *name, 107b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod const gchar *description, 108b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod const gchar *help_description, 109b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod option_group_t *option_group) 110b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod{ 111b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod GOptionGroup *group = g_option_group_new (name, description, help_description, 112b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod static_cast<gpointer>(option_group), NULL); 113b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod g_option_group_add_entries (group, entries); 114b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod g_option_group_set_parse_hooks (group, pre_parse, post_parse); 115b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod g_option_context_add_group (context, group); 116b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod} 117b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod 118b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodvoid 119b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodoption_parser_t::parse (int *argc, char ***argv) 120b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod{ 121b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod GError *parse_error = NULL; 122b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod if (!g_option_context_parse (context, argc, argv, &parse_error)) 123b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod { 124b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod if (parse_error != NULL) 125b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod fail (TRUE, "%s", parse_error->message); 126b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod else 127b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod fail (TRUE, "Option parse error"); 128b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod } 129b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod} 1303bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1313bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1323bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodstatic gboolean 1333bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodparse_margin (const char *name G_GNUC_UNUSED, 1343bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod const char *arg, 135bc4b07b05ea9e39eb9f966eb2c3e1c737efa77ffBehdad Esfahbod gpointer data, 1363bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod GError **error G_GNUC_UNUSED) 1373bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod{ 138bc4b07b05ea9e39eb9f966eb2c3e1c737efa77ffBehdad Esfahbod view_options_t *view_opts = (view_options_t *) data; 1393bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod view_options_t::margin_t &m = view_opts->margin; 14097796453aab56873809a15b5e316cba8acea7449Behdad Esfahbod switch (sscanf (arg, "%lf %lf %lf %lf", &m.t, &m.r, &m.b, &m.l)) { 1413bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod case 1: m.r = m.t; 1423bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod case 2: m.b = m.t; 1433bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod case 3: m.l = m.r; 1443bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod case 4: return TRUE; 1453bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod default: 1463bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, 1473bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod "%s argument should be one to four space-separated numbers", 1483bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod name); 1493bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod return FALSE; 1503bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod } 1513bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod} 1523bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1533bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1543bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodstatic gboolean 1553bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodparse_shapers (const char *name G_GNUC_UNUSED, 1563bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod const char *arg, 157bc4b07b05ea9e39eb9f966eb2c3e1c737efa77ffBehdad Esfahbod gpointer data, 1583bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod GError **error G_GNUC_UNUSED) 1593bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod{ 160bc4b07b05ea9e39eb9f966eb2c3e1c737efa77ffBehdad Esfahbod shape_options_t *shape_opts = (shape_options_t *) data; 1613bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod shape_opts->shapers = g_strsplit (arg, ",", 0); 1623bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod return TRUE; 1633bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod} 1643bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1653bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1663bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodstatic void 1673bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodparse_space (char **pp) 1683bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod{ 1693bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod char c; 1703bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod#define ISSPACE(c) ((c)==' '||(c)=='\f'||(c)=='\n'||(c)=='\r'||(c)=='\t'||(c)=='\v') 1713bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod while (c = **pp, ISSPACE (c)) 1723bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod (*pp)++; 1733bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod#undef ISSPACE 1743bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod} 1753bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1763bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodstatic hb_bool_t 1773bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodparse_char (char **pp, char c) 1783bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod{ 1793bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod parse_space (pp); 1803bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1813bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod if (**pp != c) 1823bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod return FALSE; 1833bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1843bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod (*pp)++; 1853bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod return TRUE; 1863bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod} 1873bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1883bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodstatic hb_bool_t 1893bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodparse_uint (char **pp, unsigned int *pv) 1903bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod{ 1913bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod char *p = *pp; 1923bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod unsigned int v; 1933bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1943bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod v = strtol (p, pp, 0); 1953bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1963bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod if (p == *pp) 1973bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod return FALSE; 1983bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1993bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod *pv = v; 2003bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod return TRUE; 2013bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod} 2023bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2033bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2043bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodstatic hb_bool_t 2053bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodparse_feature_value_prefix (char **pp, hb_feature_t *feature) 2063bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod{ 2073bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod if (parse_char (pp, '-')) 2083bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod feature->value = 0; 2093bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod else { 2103bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod parse_char (pp, '+'); 2113bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod feature->value = 1; 2123bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod } 2133bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2143bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod return TRUE; 2153bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod} 2163bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2173bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodstatic hb_bool_t 2183bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodparse_feature_tag (char **pp, hb_feature_t *feature) 2193bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod{ 2203bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod char *p = *pp, c; 2213bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2223bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod parse_space (pp); 2233bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2243bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod#define ISALNUM(c) (('a' <= (c) && (c) <= 'z') || ('A' <= (c) && (c) <= 'Z') || ('0' <= (c) && (c) <= '9')) 2253bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod while (c = **pp, ISALNUM(c)) 2263bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod (*pp)++; 2273bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod#undef ISALNUM 2283bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2293bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod if (p == *pp) 2303bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod return FALSE; 2313bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2324c9fe88d30036340fe592bcbc375049b84602b8bBehdad Esfahbod feature->tag = hb_tag_from_string (p, *pp - p); 2333bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod return TRUE; 2343bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod} 2353bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2363bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodstatic hb_bool_t 2373bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodparse_feature_indices (char **pp, hb_feature_t *feature) 2383bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod{ 2393bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod hb_bool_t has_start; 2403bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2413bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod feature->start = 0; 2423bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod feature->end = (unsigned int) -1; 2433bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2443bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod if (!parse_char (pp, '[')) 2453bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod return TRUE; 2463bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2473bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod has_start = parse_uint (pp, &feature->start); 2483bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2493bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod if (parse_char (pp, ':')) { 2503bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod parse_uint (pp, &feature->end); 2513bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod } else { 2523bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod if (has_start) 2533bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod feature->end = feature->start + 1; 2543bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod } 2553bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2563bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod return parse_char (pp, ']'); 2573bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod} 2583bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2593bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodstatic hb_bool_t 2603bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodparse_feature_value_postfix (char **pp, hb_feature_t *feature) 2613bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod{ 2623bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod return !parse_char (pp, '=') || parse_uint (pp, &feature->value); 2633bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod} 2643bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2653bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2663bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodstatic hb_bool_t 2673bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodparse_one_feature (char **pp, hb_feature_t *feature) 2683bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod{ 2693bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod return parse_feature_value_prefix (pp, feature) && 2703bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod parse_feature_tag (pp, feature) && 2713bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod parse_feature_indices (pp, feature) && 2723bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod parse_feature_value_postfix (pp, feature) && 2733bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod (parse_char (pp, ',') || **pp == '\0'); 2743bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod} 2753bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2763bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodstatic void 2773bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodskip_one_feature (char **pp) 2783bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod{ 2793bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod char *e; 2803bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod e = strchr (*pp, ','); 2813bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod if (e) 2823bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod *pp = e + 1; 2833bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod else 2843bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod *pp = *pp + strlen (*pp); 2853bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod} 2863bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2873bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodstatic gboolean 2883bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodparse_features (const char *name G_GNUC_UNUSED, 2893bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod const char *arg, 290bc4b07b05ea9e39eb9f966eb2c3e1c737efa77ffBehdad Esfahbod gpointer data, 2913bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod GError **error G_GNUC_UNUSED) 2923bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod{ 293bc4b07b05ea9e39eb9f966eb2c3e1c737efa77ffBehdad Esfahbod shape_options_t *shape_opts = (shape_options_t *) data; 2943bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod char *s = (char *) arg; 2953bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod char *p; 2963bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2973bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod shape_opts->num_features = 0; 2983bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod shape_opts->features = NULL; 2993bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 3003bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod if (!*s) 3013bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod return TRUE; 3023bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 3033bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod /* count the features first, so we can allocate memory */ 3043bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod p = s; 3053bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod do { 3063bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod shape_opts->num_features++; 3073bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod p = strchr (p, ','); 3083bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod if (p) 3093bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod p++; 3103bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod } while (p); 3113bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 3123bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod shape_opts->features = (hb_feature_t *) calloc (shape_opts->num_features, sizeof (*shape_opts->features)); 3133bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 3143bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod /* now do the actual parsing */ 3153bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod p = s; 3163bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod shape_opts->num_features = 0; 3173bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod while (*p) { 3183bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod if (parse_one_feature (&p, &shape_opts->features[shape_opts->num_features])) 3193bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod shape_opts->num_features++; 3203bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod else 3213bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod skip_one_feature (&p); 3223bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod } 3233bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 3243bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod return TRUE; 3253bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod} 3263bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 3273bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 3283bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodvoid 329b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodview_options_t::add_options (option_parser_t *parser) 3303bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod{ 3313bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod GOptionEntry entries[] = 3323bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod { 333bc4b07b05ea9e39eb9f966eb2c3e1c737efa77ffBehdad Esfahbod {"annotate", 0, 0, G_OPTION_ARG_NONE, &this->annotate, "Annotate output rendering", NULL}, 334bc4b07b05ea9e39eb9f966eb2c3e1c737efa77ffBehdad Esfahbod {"background", 0, 0, G_OPTION_ARG_STRING, &this->back, "Set background color (default: "DEFAULT_BACK")", "red/#rrggbb/#rrggbbaa"}, 335bc4b07b05ea9e39eb9f966eb2c3e1c737efa77ffBehdad Esfahbod {"foreground", 0, 0, G_OPTION_ARG_STRING, &this->fore, "Set foreground color (default: "DEFAULT_FORE")", "red/#rrggbb/#rrggbbaa"}, 336bc4b07b05ea9e39eb9f966eb2c3e1c737efa77ffBehdad Esfahbod {"line-space", 0, 0, G_OPTION_ARG_DOUBLE, &this->line_space, "Set space between lines (default: 0)", "units"}, 337109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod {"margin", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_margin, "Margin around output (default: "G_STRINGIFY(DEFAULT_MARGIN)")","one to four numbers"}, 338109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod {NULL} 339109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod }; 340b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod parser->add_group (entries, 341b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod "view", 342b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod "View options:", 343b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod "Options controlling the output rendering", 344b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod this); 345109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod} 3463bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 347109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbodvoid 348b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodshape_options_t::add_options (option_parser_t *parser) 349109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod{ 350109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod GOptionEntry entries[] = 351109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod { 3523bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod {"shapers", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_shapers, "Comma-separated list of shapers", "list"}, 353bc4b07b05ea9e39eb9f966eb2c3e1c737efa77ffBehdad Esfahbod {"direction", 0, 0, G_OPTION_ARG_STRING, &this->direction, "Set text direction (default: auto)", "ltr/rtl/ttb/btt"}, 354bc4b07b05ea9e39eb9f966eb2c3e1c737efa77ffBehdad Esfahbod {"language", 0, 0, G_OPTION_ARG_STRING, &this->language, "Set text language (default: $LANG)", "langstr"}, 355bc4b07b05ea9e39eb9f966eb2c3e1c737efa77ffBehdad Esfahbod {"script", 0, 0, G_OPTION_ARG_STRING, &this->script, "Set text script (default: auto)", "ISO-15924 tag"}, 3563bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod {"features", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_features, "Font features to apply to text", "TODO"}, 357109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod {NULL} 358109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod }; 359b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod parser->add_group (entries, 360b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod "shape", 361b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod "Shape options:", 362b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod "Options controlling the shaping process", 363b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod this); 364109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod} 3653bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 366109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbodvoid 367b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodfont_options_t::add_options (option_parser_t *parser) 368109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod{ 369109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod GOptionEntry entries[] = 370109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod { 371b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod {"font-file", 0, 0, G_OPTION_ARG_STRING, &this->font_file, "Font file-name", "filename"}, 372b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod {"face-index", 0, 0, G_OPTION_ARG_INT, &this->face_index, "Face index (default: 0)", "index"}, 373bc4b07b05ea9e39eb9f966eb2c3e1c737efa77ffBehdad Esfahbod {"font-size", 0, 0, G_OPTION_ARG_DOUBLE, &this->font_size, "Font size (default: "G_STRINGIFY(DEFAULT_FONT_SIZE)")","size"}, 374109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod {NULL} 375109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod }; 376b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod parser->add_group (entries, 377b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod "font", 378b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod "Font options:", 379b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod "Options controlling the font", 380b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod this); 381109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod} 3823bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 383109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbodvoid 384b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodtext_options_t::add_options (option_parser_t *parser) 385109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod{ 386109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod GOptionEntry entries[] = 387109cb382898f491eed733dba4ef5ba12de94aaf6Behdad Esfahbod { 388b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod {"text", 0, 0, G_OPTION_ARG_STRING, &this->text, "Set input text", "string"}, 389b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod {"text-file", 0, 0, G_OPTION_ARG_STRING, &this->text_file, "Set input text file-name", "filename"}, 3903bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod {NULL} 3913bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod }; 392b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod parser->add_group (entries, 393b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod "text", 394b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod "Text options:", 395b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod "Options controlling the input text", 396b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod this); 397b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod} 398b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod 399b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodvoid 400b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodoutput_options_t::add_options (option_parser_t *parser) 401b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod{ 402b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod GOptionEntry entries[] = 403b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod { 404b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod {"output", 0, 0, G_OPTION_ARG_STRING, &this->output_file, "Set output file-name (default: stdout)","filename"}, 405b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod {"format", 0, 0, G_OPTION_ARG_STRING, &this->output_format, "Set output format", "format"}, 406b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod {NULL} 407b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod }; 408b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod parser->add_group (entries, 409b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod "output", 410b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod "Output options:", 411b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod "Options controlling the output", 412b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod this); 413b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod} 4143bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 4153bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 4163bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 417b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodhb_font_t * 418b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodfont_options_t::get_font (void) const 419b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod{ 420b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod if (font) 421b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod return font; 422b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod 423b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod hb_blob_t *blob = NULL; 424b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod 425b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod /* Create the blob */ 4263bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod { 4274451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod char *font_data; 4284451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod unsigned int len = 0; 429b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod hb_destroy_func_t destroy; 430b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod void *user_data; 431b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod hb_memory_mode_t mm; 432b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod 4334451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod /* This is a hell of a lot of code for just reading a file! */ 434b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod if (!font_file) 435b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod fail (TRUE, "No font file set"); 436b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod 4374451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod if (0 == strcmp (font_file, "-")) { 4384451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod /* read it */ 4394451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod GString *gs = g_string_new (NULL); 4404451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod char buf[BUFSIZ]; 4414451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod#if HAVE_IO_H 4424451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod _setmode (fileno (stdin), O_BINARY); 4434451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod#endif 4444451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod while (!feof (stdin)) { 4454451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod size_t ret = fread (buf, 1, sizeof (buf), stdin); 4464451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod if (ferror (stdin)) 4474451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod fail (FALSE, "Failed reading font from standard input: %s", 4484451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod strerror (errno)); 4494451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod g_string_append_len (gs, buf, ret); 4504451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod } 4514451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod len = gs->len; 4524451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod font_data = g_string_free (gs, FALSE); 4534451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod user_data = font_data; 4544451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod destroy = (hb_destroy_func_t) g_free; 4554451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod mm = HB_MEMORY_MODE_WRITABLE; 4564451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod } else { 4574451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod GMappedFile *mf = g_mapped_file_new (font_file, FALSE, NULL); 4584451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod if (mf) { 4594451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod font_data = g_mapped_file_get_contents (mf); 4604451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod len = g_mapped_file_get_length (mf); 4614451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod if (len) { 4624451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod destroy = (hb_destroy_func_t) g_mapped_file_unref; 4634451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod user_data = (void *) mf; 4644451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod mm = HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE; 4654451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod } else 4664451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod g_mapped_file_unref (mf); 4674451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod } 4684451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod if (!len) { 4694451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod /* GMappedFile is buggy, it doesn't fail if file isn't regular. 4704451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod * Try reading. 4714451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod * https://bugzilla.gnome.org/show_bug.cgi?id=659212 */ 4724451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod GError *error = NULL; 4734451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod gsize l; 4744451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod if (g_file_get_contents (font_file, &font_data, &l, &error)) { 4754451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod len = l; 4764451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod destroy = (hb_destroy_func_t) g_free; 4774451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod user_data = (void *) font_data; 4784451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod mm = HB_MEMORY_MODE_WRITABLE; 4794451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod } else { 4804451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod fail (FALSE, "Failed reading font file `%s': %s", 4814451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod g_filename_display_name (font_file), 4824451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod error->message); 4834451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod //g_error_free (error); 4844451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod } 4854451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod } 4864451168e5d1ea26560899e9a9733b3a3f1853050Behdad Esfahbod } 487b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod 488b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod blob = hb_blob_create (font_data, len, mm, user_data, destroy); 489b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod } 490b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod 491b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod /* Create the face */ 492b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod hb_face_t *face = hb_face_create (blob, face_index); 493b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod hb_blob_destroy (blob); 494b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod 495b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod 496b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod font = hb_font_create (face); 497b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod 498b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod unsigned int upem = hb_face_get_upem (face); 499b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod hb_font_set_scale (font, font_size * upem, font_size * upem); 500b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod hb_face_destroy (face); 501b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod 502b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod#if HAVE_FREETYPE 503b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod hb_ft_font_set_funcs (font); 504b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod#endif 505b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod 506b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod return font; 507b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod} 508b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod 509b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod 510b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodconst char * 511b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbodtext_options_t::get_line (unsigned int *len) 512b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod{ 513b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod if (!text) { 514b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod if (!text_file) 515b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod fail (TRUE, "At least one of text or text-file must be set"); 516b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod 517b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod GMappedFile *mf = g_mapped_file_new (text_file, FALSE, NULL); 518b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod if (!mf) 519639b5957d9c7b6d8bef6784e3467ccc055ddeea4Behdad Esfahbod fail (FALSE, "Failed opening text file `%s'", g_filename_display_name (text_file)); 520b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod text = g_mapped_file_get_contents (mf); 521b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod text_len = g_mapped_file_get_length (mf); 5223bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod } 5233bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 524b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod if (text_len == (unsigned int) -1) 525b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod text_len = strlen (text); 526b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod 527b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod if (!text_len) { 528b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod *len = 0; 529b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod return NULL; 530b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod } 531b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod 532b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod const char *ret = text; 533b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod const char *p = (const char *) memchr (text, '\n', text_len); 534b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod unsigned int ret_len; 535b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod if (!p) { 536b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod ret_len = text_len; 537b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod text += ret_len; 538b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod text_len = 0; 539b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod } else { 540b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod ret_len = p - ret; 541b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod text += ret_len + 1; 542b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod text_len -= ret_len + 1; 5433bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod } 5443bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 545b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod *len = ret_len; 546b9b10ad78b1f977494a3a42b58f8040fe16505a3Behdad Esfahbod return ret; 5473bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod} 548