3 // Copyright (C) 2011-2012 by Werner Lemberg.
5 // This file is part of the ttfautohint library, and may only be used,
6 // modified, and distributed under the terms given in `COPYING'. By
7 // continuing to use, modify, or distribute this file you indicate that you
8 // have read `COPYING' and understand and accept it fully.
10 // The file `COPYING' mentioned in the previous paragraph is distributed
11 // with the ttfautohint library.
14 // This program is a wrapper for `TTF_autohint'.
18 # define CONSOLE_OUTPUT
21 # define CONSOLE_OUTPUT
37 # include <QApplication>
41 #include <ttfautohint.h>
47 typedef struct Progress_Data_
56 progress(long curr_idx
,
62 Progress_Data
* data
= (Progress_Data
*)user
;
64 if (num_sfnts
> 1 && curr_sfnt
!= data
->last_sfnt
)
66 fprintf(stderr
, "subfont %ld of %ld\n", curr_sfnt
+ 1, num_sfnts
);
67 data
->last_sfnt
= curr_sfnt
;
73 fprintf(stderr
, " %ld glyphs\n"
78 // print progress approx. every 10%
79 int curr_percent
= curr_idx
* 100 / num_glyphs
;
80 int curr_diff
= curr_percent
- data
->last_percent
;
84 fprintf(stderr
, " %d%%", curr_percent
);
85 data
->last_percent
= curr_percent
- curr_percent
% 10;
88 if (curr_idx
+ 1 == num_glyphs
)
89 fprintf(stderr
, "\n");
93 #endif /* !BUILD_GUI */
101 FILE* handle
= is_error
? stderr
: stdout
;
104 "Usage: ttfautohint [OPTION]... IN-FILE OUT-FILE\n"
105 " or: ttfautohintGUI [OPTION]...\n"
106 "Replace hints in TrueType font IN-FILE and write output to OUT-FILE.\n"
107 "The new hints are based on FreeType's autohinter.\n"
109 "These programs (for console and GUI, respectively)\n"
110 "are simple front-ends to the `ttfautohint' library.\n"
114 "Long options can be given with one or two dashes,\n"
115 "and with and without equal sign between option and argument.\n"
116 "This means that the following forms are acceptable:\n"
117 "`-foo=bar', `--foo=bar', `-foo bar', `--foo bar'.\n"
122 " -f, --latin-fallback set fallback script to latin\n"
123 " -G, --hinting-limit=N switch off hinting above this PPEM value\n"
125 " -h, --help display this help and exit\n"
126 " --help-all show Qt and X11 specific options also\n"
127 " -i, --ignore-permissions override font license restrictions\n"
128 " -l, --hinting-range-min=N the minimum PPEM value for hint sets\n"
130 " -p, --pre-hinting apply original hints in advance\n",
131 TA_HINTING_LIMIT
, TA_HINTING_RANGE_MIN
);
133 " -r, --hinting-range-max=N the maximum PPEM value for hint sets\n"
135 " -v, --verbose show progress information\n"
136 " -V, --version print version information and exit\n"
137 " -x, --increase-x-height increase x height for small sizes\n"
138 " -X, --x-height-snapping-exceptions=STRING\n"
139 " specify a comma-separated list of\n"
140 " x-height snapping exceptions\n"
142 TA_HINTING_RANGE_MAX
);
148 " --graphicssystem=SYSTEM\n"
149 " select a different graphics system backend\n"
150 " instead of the default one\n"
151 " (possible values: `raster', `opengl')\n"
152 " --reverse set layout direction to right-to-left\n");
154 " --session=ID restore the application for the given ID\n"
155 " --style=STYLE set application GUI style\n"
156 " (possible values: motif, windows, platinum)\n"
157 " --stylesheet=SHEET apply the given Qt stylesheet\n"
158 " to the application widgets\n"
163 " --background=COLOR set the default background color\n"
164 " and an application palette\n"
165 " (light and dark shades are calculated)\n"
166 " --bg=COLOR same as --background\n"
167 " --btn=COLOR set the default button color\n"
168 " --button=COLOR same as --btn\n"
169 " --cmap use a private color map on an 8-bit display\n"
170 " --display=NAME use the given X-server display\n");
172 " --fg=COLOR set the default foreground color\n"
173 " --fn=FONTNAME set the application font\n"
174 " --font=FONTNAME same as --fn\n"
175 " --foreground=COLOR same as --fg\n"
176 " --geometry=GEOMETRY set the client geometry of first window\n"
177 " --im=SERVER set the X Input Method (XIM) server\n"
178 " --inputstyle=STYLE set X Input Method input style\n"
179 " (possible values: onthespot, overthespot,\n"
180 " offthespot, root)\n");
182 " --name=NAME set the application name\n"
183 " --ncols=COUNT limit the number of colors allocated\n"
184 " in the color cube on an 8-bit display,\n"
185 " if the application is using the\n"
186 " QApplication::ManyColor color specification\n"
187 " --title=TITLE set the application title (caption)\n"
188 " --visual=VISUAL force the application\n"
189 " to use the given visual on an 8-bit display\n"
190 " (only possible value: TrueColor)\n"
195 "The programs accept both TTF and TTC files as input.\n"
196 "Use option -i only if you have a legal permission to modify the font.\n"
197 "If option -f is not set, glyphs not in the latin range stay unhinted.\n"
198 "The used PPEM value for option -p is FUnits per em, normally 2048.\n"
201 "A hint set contains the optimal hinting for a certain PPEM value;\n"
202 "the larger the hint set range, the more hint sets get computed,\n"
203 "usually increasing the output font size. Note, however,\n"
204 "that the `gasp' table of the output file enables grayscale hinting\n"
205 "for all sizes (limited by option -G which is handled in the bytecode).\n"
208 "If run in GUI mode, options not related to Qt or X11 set default values.\n"
209 "Additionally, there is no output to the console.\n"
211 "GUI support might be disabled at compile time.\n"
213 "Report bugs to: freetype-devel@nongnu.org\n"
214 "FreeType home page: <http://www.freetype.org>\n");
227 "ttfautohint " VERSION
"\n"
228 "Copyright (C) 2011-2012 Werner Lemberg <wl@gnu.org>.\n"
229 "License: FreeType License (FTL) or GNU GPLv2.\n"
230 "This is free software: you are free to change and redistribute it.\n"
231 "There is NO WARRANTY, to the extent permitted by law.\n");
235 #endif /* CONSOLE_OUTPUT */
242 int hinting_range_min
= 0;
243 int hinting_range_max
= 0;
244 int hinting_limit
= 0;
245 bool have_hinting_range_min
= false;
246 bool have_hinting_range_max
= false;
247 bool have_hinting_limit
= false;
249 bool ignore_permissions
= false;
250 bool pre_hinting
= false;
251 bool increase_x_height
= false;
252 int latin_fallback
= 0; // leave it as int; this probably gets extended
255 TA_Progress_Func progress_func
= NULL
;
258 // make GNU, Qt, and X11 command line options look the same;
259 // we allow `--foo=bar', `--foo bar', `-foo=bar', `-foo bar',
260 // and short options specific to ttfautohint
262 // set up a new argument string
263 vector
<string
> new_arg_string
;
264 new_arg_string
.push_back(argv
[0]);
268 // use pseudo short options for long-only options
271 PASS_THROUGH
= CHAR_MAX
+ 1,
275 static struct option long_options
[] =
277 {"help", no_argument
, NULL
, 'h'},
278 {"help-all", no_argument
, NULL
, HELP_ALL_OPTION
},
280 // ttfautohint options
281 {"hinting-range-max", required_argument
, NULL
, 'r'},
282 {"hinting-range-min", required_argument
, NULL
, 'l'},
283 {"hinting-limit", required_argument
, NULL
, 'G'},
284 {"ignore-permissions", no_argument
, NULL
, 'i'},
285 {"latin-fallback", no_argument
, NULL
, 'f'},
286 {"pre-hinting", no_argument
, NULL
, 'p'},
287 {"verbose", no_argument
, NULL
, 'v'},
288 {"version", no_argument
, NULL
, 'V'},
289 {"increase-x-height", no_argument
, NULL
, 'x'},
290 {"x-height-snapping-exceptions", required_argument
, NULL
, 'X'},
293 {"graphicssystem", required_argument
, NULL
, PASS_THROUGH
},
294 {"reverse", no_argument
, NULL
, PASS_THROUGH
},
295 {"session", required_argument
, NULL
, PASS_THROUGH
},
296 {"style", required_argument
, NULL
, PASS_THROUGH
},
297 {"stylesheet", required_argument
, NULL
, PASS_THROUGH
},
300 {"background", required_argument
, NULL
, PASS_THROUGH
},
301 {"bg", required_argument
, NULL
, PASS_THROUGH
},
302 {"btn", required_argument
, NULL
, PASS_THROUGH
},
303 {"button", required_argument
, NULL
, PASS_THROUGH
},
304 {"cmap", no_argument
, NULL
, PASS_THROUGH
},
305 {"display", required_argument
, NULL
, PASS_THROUGH
},
306 {"fg", required_argument
, NULL
, PASS_THROUGH
},
307 {"fn", required_argument
, NULL
, PASS_THROUGH
},
308 {"font", required_argument
, NULL
, PASS_THROUGH
},
309 {"foreground", required_argument
, NULL
, PASS_THROUGH
},
310 {"geometry", required_argument
, NULL
, PASS_THROUGH
},
311 {"im", required_argument
, NULL
, PASS_THROUGH
},
312 {"inputstyle", required_argument
, NULL
, PASS_THROUGH
},
313 {"name", required_argument
, NULL
, PASS_THROUGH
},
314 {"ncols", required_argument
, NULL
, PASS_THROUGH
},
315 {"title", required_argument
, NULL
, PASS_THROUGH
},
316 {"visual", required_argument
, NULL
, PASS_THROUGH
},
322 int c
= getopt_long_only(argc
, argv
, "fG:hil:r:ptVvxX:",
323 long_options
, &option_index
);
334 hinting_limit
= atoi(optarg
);
335 have_hinting_limit
= true;
339 #ifdef CONSOLE_OUTPUT
340 show_help(false, false);
345 ignore_permissions
= true;
349 hinting_range_min
= atoi(optarg
);
350 have_hinting_range_min
= true;
354 hinting_range_max
= atoi(optarg
);
355 have_hinting_range_max
= true;
364 progress_func
= progress
;
369 #ifdef CONSOLE_OUTPUT
375 increase_x_height
= true;
379 #ifdef CONSOLE_OUTPUT
380 fprintf(stderr
, "Option `-x' not implemented yet\n");
384 case HELP_ALL_OPTION
:
385 #ifdef CONSOLE_OUTPUT
386 show_help(true, false);
392 // append argument with proper syntax for Qt
395 arg
+= long_options
[option_index
].name
;
397 new_arg_string
.push_back(arg
);
399 new_arg_string
.push_back(optarg
);
408 if (!have_hinting_range_min
)
409 hinting_range_min
= TA_HINTING_RANGE_MIN
;
410 if (!have_hinting_range_max
)
411 hinting_range_max
= TA_HINTING_RANGE_MAX
;
412 if (!have_hinting_limit
)
413 hinting_limit
= TA_HINTING_LIMIT
;
417 if (hinting_range_min
< 2)
419 fprintf(stderr
, "The hinting range minimum must be at least 2\n");
422 if (hinting_range_max
< hinting_range_min
)
424 fprintf(stderr
, "The hinting range maximum must not be smaller"
425 " than the minimum (%d)\n",
429 if (hinting_limit
!= 0 && hinting_limit
< hinting_range_max
)
431 fprintf(stderr
, "A non-zero hinting limit must not be smaller"
432 " than the hinting range maximum (%d)\n",
437 // on the console we need in and out file arguments
438 if (argc
- optind
!= 2)
439 show_help(false, true);
441 FILE* in
= fopen(argv
[optind
], "rb");
444 fprintf(stderr
, "The following error occurred while opening font `%s':\n"
447 argv
[optind
], strerror(errno
));
451 FILE* out
= fopen(argv
[optind
+ 1], "wb");
454 fprintf(stderr
, "The following error occurred while opening font `%s':\n"
457 argv
[optind
+ 1], strerror(errno
));
461 const unsigned char* error_string
;
462 Progress_Data progress_data
= {-1, 1, 0};
465 TTF_autohint("in-file, out-file,"
466 "hinting-range-min, hinting-range-max, hinting-limit,"
468 "progress-callback, progress-callback-data,"
469 "ignore-permissions, pre-hinting, increase-x-height,"
472 hinting_range_min
, hinting_range_max
, hinting_limit
,
474 progress_func
, &progress_data
,
475 ignore_permissions
, pre_hinting
, increase_x_height
,
480 if (error
== TA_Err_Invalid_FreeType_Version
)
482 "FreeType version 2.4.5 or higher is needed.\n"
483 "Perhaps using a wrong FreeType DLL?\n");
484 else if (error
== TA_Err_Already_Processed
)
486 "This font has already been processed with ttfautohint.\n");
487 else if (error
== TA_Err_Missing_Legal_Permission
)
489 "Bit 1 in the `fsType' field of the `OS/2' table is set:\n"
490 "This font must not be modified"
491 " without permission of the legal owner.\n"
492 "Use command line option `-i' to continue"
493 " if you have such a permission.\n");
494 else if (error
== TA_Err_Missing_Unicode_CMap
)
496 "No Unicode character map.\n");
497 else if (error
== TA_Err_Missing_Glyph
)
499 "No glyph for the key character"
500 " to derive standard width and height.\n"
501 "For the latin script, this key character is `o' (U+006F).\n");
504 "Error code `0x%02x' while autohinting font:\n"
505 " %s\n", error
, error_string
);
514 return 0; // never reached
516 #else /* BUILD_GUI */
518 int new_argc
= new_arg_string
.size();
519 char** new_argv
= new char*[new_argc
];
521 // construct new argc and argv variables from collected data
522 for (int i
= 0; i
< new_argc
; i
++)
523 new_argv
[i
] = const_cast<char*>(new_arg_string
[i
].data());
525 QApplication
app(new_argc
, new_argv
);
526 app
.setApplicationName("TTFautohint");
527 app
.setApplicationVersion(VERSION
);
528 app
.setOrganizationName("FreeType");
529 app
.setOrganizationDomain("freetype.org");
531 Main_GUI
gui(hinting_range_min
, hinting_range_max
, hinting_limit
,
532 ignore_permissions
, pre_hinting
, increase_x_height
,
538 #endif /* BUILD_GUI */