options.cc revision 97796453aab56873809a15b5e316cba8acea7449
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 293bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 303bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodview_options_t view_opts[1]; 313bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodshape_options_t shape_opts[1]; 323bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodfont_options_t font_opts[1]; 333bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 3497796453aab56873809a15b5e316cba8acea7449Behdad Esfahbodconst char *out_file = "/dev/stdout"; 3597796453aab56873809a15b5e316cba8acea7449Behdad Esfahbodhb_bool_t debug = FALSE; 363bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 373bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 383bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodstatic gboolean 393bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodparse_margin (const char *name G_GNUC_UNUSED, 403bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod const char *arg, 413bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod gpointer data G_GNUC_UNUSED, 423bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod GError **error G_GNUC_UNUSED) 433bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod{ 443bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod view_options_t::margin_t &m = view_opts->margin; 4597796453aab56873809a15b5e316cba8acea7449Behdad Esfahbod switch (sscanf (arg, "%lf %lf %lf %lf", &m.t, &m.r, &m.b, &m.l)) { 463bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod case 1: m.r = m.t; 473bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod case 2: m.b = m.t; 483bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod case 3: m.l = m.r; 493bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod case 4: return TRUE; 503bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod default: 513bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, 523bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod "%s argument should be one to four space-separated numbers", 533bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod name); 543bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod return FALSE; 553bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod } 563bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod} 573bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 583bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 593bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodstatic gboolean 603bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodparse_shapers (const char *name G_GNUC_UNUSED, 613bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod const char *arg, 623bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod gpointer data G_GNUC_UNUSED, 633bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod GError **error G_GNUC_UNUSED) 643bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod{ 653bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod shape_opts->shapers = g_strsplit (arg, ",", 0); 663bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod return TRUE; 673bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod} 683bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 693bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 703bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodstatic void 713bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodparse_space (char **pp) 723bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod{ 733bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod char c; 743bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod#define ISSPACE(c) ((c)==' '||(c)=='\f'||(c)=='\n'||(c)=='\r'||(c)=='\t'||(c)=='\v') 753bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod while (c = **pp, ISSPACE (c)) 763bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod (*pp)++; 773bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod#undef ISSPACE 783bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod} 793bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 803bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodstatic hb_bool_t 813bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodparse_char (char **pp, char c) 823bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod{ 833bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod parse_space (pp); 843bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 853bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod if (**pp != c) 863bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod return FALSE; 873bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 883bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod (*pp)++; 893bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod return TRUE; 903bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod} 913bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 923bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodstatic hb_bool_t 933bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodparse_uint (char **pp, unsigned int *pv) 943bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod{ 953bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod char *p = *pp; 963bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod unsigned int v; 973bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 983bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod v = strtol (p, pp, 0); 993bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1003bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod if (p == *pp) 1013bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod return FALSE; 1023bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1033bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod *pv = v; 1043bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod return TRUE; 1053bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod} 1063bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1073bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1083bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodstatic hb_bool_t 1093bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodparse_feature_value_prefix (char **pp, hb_feature_t *feature) 1103bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod{ 1113bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod if (parse_char (pp, '-')) 1123bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod feature->value = 0; 1133bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod else { 1143bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod parse_char (pp, '+'); 1153bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod feature->value = 1; 1163bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod } 1173bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1183bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod return TRUE; 1193bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod} 1203bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1213bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodstatic hb_bool_t 1223bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodparse_feature_tag (char **pp, hb_feature_t *feature) 1233bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod{ 1243bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod char *p = *pp, c; 1253bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1263bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod parse_space (pp); 1273bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1283bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod#define ISALNUM(c) (('a' <= (c) && (c) <= 'z') || ('A' <= (c) && (c) <= 'Z') || ('0' <= (c) && (c) <= '9')) 1293bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod while (c = **pp, ISALNUM(c)) 1303bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod (*pp)++; 1313bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod#undef ISALNUM 1323bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1333bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod if (p == *pp) 1343bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod return FALSE; 1353bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1363bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod **pp = '\0'; 1373bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod feature->tag = hb_tag_from_string (p); 1383bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod **pp = c; 1393bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1403bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod return TRUE; 1413bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod} 1423bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1433bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodstatic hb_bool_t 1443bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodparse_feature_indices (char **pp, hb_feature_t *feature) 1453bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod{ 1463bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod hb_bool_t has_start; 1473bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1483bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod feature->start = 0; 1493bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod feature->end = (unsigned int) -1; 1503bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1513bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod if (!parse_char (pp, '[')) 1523bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod return TRUE; 1533bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1543bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod has_start = parse_uint (pp, &feature->start); 1553bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1563bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod if (parse_char (pp, ':')) { 1573bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod parse_uint (pp, &feature->end); 1583bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod } else { 1593bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod if (has_start) 1603bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod feature->end = feature->start + 1; 1613bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod } 1623bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1633bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod return parse_char (pp, ']'); 1643bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod} 1653bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1663bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodstatic hb_bool_t 1673bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodparse_feature_value_postfix (char **pp, hb_feature_t *feature) 1683bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod{ 1693bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod return !parse_char (pp, '=') || parse_uint (pp, &feature->value); 1703bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod} 1713bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1723bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1733bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodstatic hb_bool_t 1743bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodparse_one_feature (char **pp, hb_feature_t *feature) 1753bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod{ 1763bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod return parse_feature_value_prefix (pp, feature) && 1773bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod parse_feature_tag (pp, feature) && 1783bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod parse_feature_indices (pp, feature) && 1793bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod parse_feature_value_postfix (pp, feature) && 1803bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod (parse_char (pp, ',') || **pp == '\0'); 1813bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod} 1823bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1833bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodstatic void 1843bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodskip_one_feature (char **pp) 1853bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod{ 1863bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod char *e; 1873bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod e = strchr (*pp, ','); 1883bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod if (e) 1893bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod *pp = e + 1; 1903bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod else 1913bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod *pp = *pp + strlen (*pp); 1923bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod} 1933bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 1943bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodstatic gboolean 1953bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodparse_features (const char *name G_GNUC_UNUSED, 1963bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod const char *arg, 1973bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod gpointer data G_GNUC_UNUSED, 1983bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod GError **error G_GNUC_UNUSED) 1993bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod{ 2003bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod char *s = (char *) arg; 2013bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod char *p; 2023bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2033bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod shape_opts->num_features = 0; 2043bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod shape_opts->features = NULL; 2053bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2063bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod if (!*s) 2073bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod return TRUE; 2083bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2093bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod /* count the features first, so we can allocate memory */ 2103bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod p = s; 2113bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod do { 2123bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod shape_opts->num_features++; 2133bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod p = strchr (p, ','); 2143bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod if (p) 2153bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod p++; 2163bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod } while (p); 2173bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2183bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod shape_opts->features = (hb_feature_t *) calloc (shape_opts->num_features, sizeof (*shape_opts->features)); 2193bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2203bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod /* now do the actual parsing */ 2213bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod p = s; 2223bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod shape_opts->num_features = 0; 2233bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod while (*p) { 2243bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod if (parse_one_feature (&p, &shape_opts->features[shape_opts->num_features])) 2253bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod shape_opts->num_features++; 2263bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod else 2273bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod skip_one_feature (&p); 2283bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod } 2293bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2303bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod return TRUE; 2313bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod} 2323bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2333bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2343bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodstatic gchar * 2353bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodshapers_to_string (void) 2363bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod{ 2373bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod GString *shapers = g_string_new (NULL); 2383bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod const char **shaper_list = hb_shape_list_shapers (); 2393bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2403bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod for (; *shaper_list; shaper_list++) { 2413bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod g_string_append (shapers, *shaper_list); 2423bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod g_string_append_c (shapers, ','); 2433bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod } 2443bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod g_string_truncate (shapers, MAX (0, (gint)shapers->len - 1)); 2453bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2463bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod return g_string_free (shapers, FALSE); 2473bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod} 2483bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2493bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodstatic G_GNUC_NORETURN gboolean 2503bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodshow_version (const char *name G_GNUC_UNUSED, 2513bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod const char *arg G_GNUC_UNUSED, 2523bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod gpointer data G_GNUC_UNUSED, 2533bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod GError **error G_GNUC_UNUSED) 2543bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod{ 2553bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod g_printf ("%s (%s) %s\n", g_get_prgname (), PACKAGE_NAME, PACKAGE_VERSION); 2563bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2573bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod char *shapers = shapers_to_string (); 2583bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod g_printf ("Available shapers: %s\n", shapers); 2593bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod g_free (shapers); 2603bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod if (strcmp (HB_VERSION_STRING, hb_version_string ())) 2613bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod g_printf ("Linked HarfBuzz library has a different version: %s\n", hb_version_string ()); 2623bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2633bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod exit(0); 2643bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod} 2653bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2663bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2673bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodvoid 2683bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbodparse_options (int argc, char *argv[]) 2693bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod{ 2703bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod GOptionEntry entries[] = 2713bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod { 2723bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod {"version", 0, G_OPTION_FLAG_NO_ARG, 27397796453aab56873809a15b5e316cba8acea7449Behdad Esfahbod G_OPTION_ARG_CALLBACK, (gpointer) &show_version, "Show version numbers", NULL}, 2743bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod {"debug", 0, 0, G_OPTION_ARG_NONE, &debug, "Free all resources before exit", NULL}, 2753bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod {"output", 0, 0, G_OPTION_ARG_STRING, &out_file, "Set output file name", "filename"}, 2763bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2773bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod {"annotate", 0, 0, G_OPTION_ARG_NONE, &view_opts->annotate, "Annotate output rendering", NULL}, 2783bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod {"background", 0, 0, G_OPTION_ARG_STRING, &view_opts->back, "Set background color", "red/#rrggbb/#rrggbbaa"}, 2793bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod {"foreground", 0, 0, G_OPTION_ARG_STRING, &view_opts->fore, "Set foreground color", "red/#rrggbb/#rrggbbaa"}, 2803bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod {"line-space", 0, 0, G_OPTION_ARG_DOUBLE, &view_opts->line_space, "Set space between lines (default: 0)", "units"}, 2813bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod {"margin", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_margin, "Margin around output", "one to four numbers"}, 2823bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2833bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod {"shapers", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_shapers, "Comma-separated list of shapers", "list"}, 2843bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod {"direction", 0, 0, G_OPTION_ARG_STRING, &shape_opts->direction, "Set text direction (default: auto)", "ltr/rtl/ttb/btt"}, 2853bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod {"language", 0, 0, G_OPTION_ARG_STRING, &shape_opts->language, "Set text language (default: $LANG)", "langstr"}, 2863bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod {"script", 0, 0, G_OPTION_ARG_STRING, &shape_opts->script, "Set text script (default: auto)", "ISO-15924 tag"}, 2873bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod {"features", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_features, "Font features to apply to text", "TODO"}, 2883bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2893bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod {"face-index", 0, 0, G_OPTION_ARG_INT, &font_opts->face_index, "Face index (default: 0)", "index"}, 2903bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod {"font-size", 0, 0, G_OPTION_ARG_DOUBLE, &font_opts->font_size, "Font size", "size"}, 2913bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2923bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod {NULL} 2933bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod }; 2943bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod GError *parse_error = NULL; 2953bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod GOptionContext *context; 2963bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2973bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod context = g_option_context_new ("- FONT-FILE TEXT"); 2983bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 2993bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod g_option_context_add_main_entries (context, entries, NULL); 3003bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 3013bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod if (!g_option_context_parse (context, &argc, &argv, &parse_error)) 3023bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod { 3033bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod if (parse_error != NULL) 3043bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod fail ("%s", parse_error->message); 3053bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod else 3063bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod fail ("Option parse error"); 3073bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod exit(1); 3083bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod } 3093bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod g_option_context_free(context); 3103bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 3113bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod if (argc != 3) { 3123bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod g_printerr ("Usage: %s [OPTION...] FONT-FILE TEXT\n", g_get_prgname ()); 3133bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod exit (1); 3143bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod } 3153bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod 3163bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod font_opts->font_file = argv[1]; 3173bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod shape_opts->text = argv[2]; 3183bb300ee78a40f9ded21ab19283863b733aeb677Behdad Esfahbod} 319