Typos.
[ttfautohint.git] / frontend / main.cpp
blob1658e05849dc3d6b90aa38cb2e3178aaa253ee3c
1 // main.cpp
3 // Copyright (C) 2011-2014 by Werner Lemberg.
4 //
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.
9 //
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'.
16 #ifdef BUILD_GUI
17 # ifndef _WIN32
18 # define CONSOLE_OUTPUT
19 # endif
20 #else
21 # define CONSOLE_OUTPUT
22 #endif
24 #include <config.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <errno.h>
29 #include <string.h>
30 #include <getopt.h>
31 #include <limits.h>
32 #include <unistd.h>
33 #include <locale.h>
35 #include <vector>
36 #include <string>
38 #if BUILD_GUI
39 # include <QApplication>
40 # include "maingui.h"
41 #else
42 # include "info.h"
43 #endif
45 #include <ttfautohint.h>
46 #include <numberset.h>
49 #ifdef _WIN32
50 # include <fcntl.h>
51 # define SET_BINARY(f) do { \
52 if (!isatty(fileno(f))) \
53 setmode(fileno(f), O_BINARY); \
54 } while (0)
55 #endif
57 #ifndef SET_BINARY
58 # define SET_BINARY(f) do {} while (0)
59 #endif
62 using namespace std;
65 // the available script tags and its descriptions are directly extracted
66 // from `ttfautohint-scripts.h'
67 typedef struct Script_Names_
69 const char* tag;
70 const char* description;
71 } Script_Names;
73 #undef SCRIPT
74 #define SCRIPT(s, S, d, h, sc1, sc2, sc3) \
75 {#s, d},
77 const Script_Names script_names[] =
79 #include <ttfautohint-scripts.h>
80 {NULL, NULL}
84 #ifndef BUILD_GUI
85 extern "C" {
87 typedef struct Progress_Data_
89 long last_sfnt;
90 bool begin;
91 int last_percent;
92 } Progress_Data;
95 int
96 progress(long curr_idx,
97 long num_glyphs,
98 long curr_sfnt,
99 long num_sfnts,
100 void* user)
102 Progress_Data* data = (Progress_Data*)user;
104 if (num_sfnts > 1 && curr_sfnt != data->last_sfnt)
106 fprintf(stderr, "subfont %ld of %ld\n", curr_sfnt + 1, num_sfnts);
107 data->last_sfnt = curr_sfnt;
108 data->last_percent = 0;
109 data->begin = true;
112 if (data->begin)
114 fprintf(stderr, " %ld glyphs\n"
115 " ", num_glyphs);
116 data->begin = false;
119 // print progress approx. every 10%
120 int curr_percent = curr_idx * 100 / num_glyphs;
121 int curr_diff = curr_percent - data->last_percent;
123 if (curr_diff >= 10)
125 fprintf(stderr, " %d%%", curr_percent);
126 data->last_percent = curr_percent - curr_percent % 10;
129 if (curr_idx + 1 == num_glyphs)
130 fprintf(stderr, "\n");
132 return 0;
136 typedef struct Error_Data_
138 const char* control_name;
139 } Error_Data;
142 void
143 err(TA_Error error,
144 const char* error_string,
145 unsigned int errlinenum,
146 const char* errline,
147 const char* errpos,
148 void* user)
150 Error_Data* data = static_cast<Error_Data*>(user);
152 if (!error)
153 return;
155 // We replace some terse error strings with more user-friendly versions.
156 if (error == TA_Err_Invalid_FreeType_Version)
157 fprintf(stderr,
158 "FreeType version 2.4.5 or higher is needed.\n"
159 "Perhaps using a wrong FreeType DLL?\n");
160 else if (error == TA_Err_Invalid_Font_Type)
161 fprintf(stderr,
162 "This font is not a valid font"
163 " in SFNT format with TrueType outlines.\n"
164 "In particular, CFF outlines are not supported.\n");
165 else if (error == TA_Err_Already_Processed)
166 fprintf(stderr,
167 "This font has already been processed with ttfautohint.\n");
168 else if (error == TA_Err_Missing_Legal_Permission)
169 fprintf(stderr,
170 "Bit 1 in the `fsType' field of the `OS/2' table is set:\n"
171 "This font must not be modified"
172 " without permission of the legal owner.\n"
173 "Use command line option `-i' to continue"
174 " if you have such a permission.\n");
175 else if (error == TA_Err_Missing_Unicode_CMap)
176 fprintf(stderr,
177 "No Unicode character map.\n");
178 else if (error == TA_Err_Missing_Symbol_CMap)
179 fprintf(stderr,
180 "No symbol character map.\n");
181 else if (error == TA_Err_Missing_Glyph)
182 fprintf(stderr,
183 "No glyph for a standard character"
184 " to derive standard width and height.\n"
185 "Please check the documentation for a list of"
186 " script-specific standard characters,\n"
187 "or use option `--symbol'.\n");
188 else
190 if (error < 0x100)
191 fprintf(stderr, "An error with code 0x%02x occurred"
192 " while autohinting fonts",
193 error);
194 else if (error >= 0x100 && error < 0x200)
196 fprintf(stderr, "An error with code 0x%03x occurred"
197 " while parsing the argument of option `-X'",
198 error);
199 fprintf(stderr, errline ? ":\n" : ".\n");
201 if (errline)
202 fprintf(stderr, " %s\n", errline);
203 if (errpos && errline)
204 fprintf(stderr, " %*s\n", int(errpos - errline + 1), "^");
206 else if (error >= 0x200 && error < 0x300)
208 fprintf(stderr, "%s:", data->control_name);
209 if (errlinenum)
210 fprintf(stderr, "%d:", errlinenum);
211 if (errpos && errline)
212 fprintf(stderr, "%d:", int(errpos - errline + 1));
213 if (error_string)
214 fprintf(stderr, " %s", error_string);
215 fprintf(stderr, " (0x%02X)\n", error);
216 if (errline)
217 fprintf(stderr, " %s\n", errline);
218 if (errpos && errline)
219 fprintf(stderr, " %*s\n", int(errpos - errline + 1), "^");
225 } // extern "C"
226 #endif // !BUILD_GUI
229 #ifdef CONSOLE_OUTPUT
230 static void
231 show_help(bool
232 #ifdef BUILD_GUI
234 #endif
236 bool is_error)
238 FILE* handle = is_error ? stderr : stdout;
240 fprintf(handle,
241 #ifdef BUILD_GUI
242 "Usage: ttfautohintGUI [OPTION]...\n"
243 "A GUI application to replace hints in a TrueType font.\n"
244 #else
245 "Usage: ttfautohint [OPTION]... [IN-FILE [OUT-FILE]]\n"
246 "Replace hints in TrueType font IN-FILE and write output to OUT-FILE.\n"
247 "If OUT-FILE is missing, standard output is used instead;\n"
248 "if IN-FILE is missing also, standard input and output are used.\n"
249 #endif
250 "\n"
251 "The new hints are based on FreeType's auto-hinter.\n"
252 "\n"
253 "This program is a simple front-end to the `ttfautohint' library.\n"
254 "\n");
256 fprintf(handle,
257 "Long options can be given with one or two dashes,\n"
258 "and with and without equal sign between option and argument.\n"
259 "This means that the following forms are acceptable:\n"
260 "`-foo=bar', `--foo=bar', `-foo bar', `--foo bar'.\n"
261 "\n"
262 "Mandatory arguments to long options are mandatory for short options too.\n"
263 #ifdef BUILD_GUI
264 "Options not related to Qt or X11 set default values.\n"
265 #endif
266 "\n"
269 fprintf(handle,
270 "Options:\n"
271 #ifndef BUILD_GUI
272 " --debug print debugging information\n"
273 #endif
274 " -c, --composites hint glyph composites also\n"
275 " -d, --dehint remove all hints\n"
276 " -D, --default-script=S set default OpenType script (default: latn)\n"
277 " -f, --fallback-script=S set fallback script (default: none)\n"
278 " -G, --hinting-limit=N switch off hinting above this PPEM value\n"
279 " (default: %d); value 0 means no limit\n"
280 " -h, --help display this help and exit\n"
281 " -H, --fallback-stem-width=N\n"
282 " set fallback stem width\n"
283 " (default: 50 font units at 2048 UPEM)\n"
284 #ifdef BUILD_GUI
285 " --help-all show Qt and X11 specific options also\n"
286 #endif
287 " -i, --ignore-restrictions override font license restrictions\n"
288 " -l, --hinting-range-min=N the minimum PPEM value for hint sets\n"
289 " (default: %d)\n"
290 #ifndef BUILD_GUI
291 " -m, --control-file=FILE get control instructions from FILE\n"
292 #endif
293 " -n, --no-info don't add ttfautohint info\n"
294 " to the version string(s) in the `name' table\n"
295 " -p, --adjust-subglyphs handle subglyph adjustments in exotic fonts\n",
296 TA_HINTING_LIMIT, TA_HINTING_RANGE_MIN);
297 fprintf(handle,
298 " -r, --hinting-range-max=N the maximum PPEM value for hint sets\n"
299 " (default: %d)\n"
300 " -s, --symbol input is symbol font\n"
301 " -t, --ttfa-table add TTFA information table\n"
302 " -v, --verbose show progress information\n"
303 " -V, --version print version information and exit\n"
304 " -w, --strong-stem-width=S use strong stem width routine for modes S,\n"
305 " where S is a string of up to three letters\n"
306 " with possible values `g' for grayscale,\n"
307 " `G' for GDI ClearType, and `D' for\n"
308 " DirectWrite ClearType (default: G)\n"
309 " -W, --windows-compatibility\n"
310 " add blue zones for `usWinAscent' and\n"
311 " `usWinDescent' to avoid clipping\n"
312 " -x, --increase-x-height=N increase x height for sizes in the range\n"
313 " 6<=PPEM<=N; value 0 switches off this feature\n"
314 " (default: %d)\n"
315 " -X, --x-height-snapping-exceptions=STRING\n"
316 " specify a comma-separated list of\n"
317 " x-height snapping exceptions, for example\n"
318 " \"-9, 13-17, 19\" (default: \"\")\n"
319 "\n",
320 TA_HINTING_RANGE_MAX, TA_INCREASE_X_HEIGHT);
322 #ifdef BUILD_GUI
323 if (all)
325 fprintf(handle,
326 "Qt Options:\n"
327 " --graphicssystem=SYSTEM\n"
328 " select a different graphics system backend\n"
329 " instead of the default one\n"
330 " (possible values: `raster', `opengl')\n"
331 " --reverse set layout direction to right-to-left\n");
332 fprintf(handle,
333 " --session=ID restore the application for the given ID\n"
334 " --style=STYLE set application GUI style\n"
335 " (possible values: motif, windows, platinum)\n"
336 " --stylesheet=SHEET apply the given Qt stylesheet\n"
337 " to the application widgets\n"
338 "\n");
340 fprintf(handle,
341 "X11 options:\n"
342 " --background=COLOR set the default background color\n"
343 " and an application palette\n"
344 " (light and dark shades are calculated)\n"
345 " --bg=COLOR same as --background\n"
346 " --btn=COLOR set the default button color\n"
347 " --button=COLOR same as --btn\n"
348 " --cmap use a private color map on an 8-bit display\n"
349 " --display=NAME use the given X-server display\n");
350 fprintf(handle,
351 " --fg=COLOR set the default foreground color\n"
352 " --fn=FONTNAME set the application font\n"
353 " --font=FONTNAME same as --fn\n"
354 " --foreground=COLOR same as --fg\n"
355 " --geometry=GEOMETRY set the client geometry of first window\n"
356 " --im=SERVER set the X Input Method (XIM) server\n"
357 " --inputstyle=STYLE set X Input Method input style\n"
358 " (possible values: onthespot, overthespot,\n"
359 " offthespot, root)\n");
360 fprintf(handle,
361 " --name=NAME set the application name\n"
362 " --ncols=COUNT limit the number of colors allocated\n"
363 " in the color cube on an 8-bit display,\n"
364 " if the application is using the\n"
365 " QApplication::ManyColor color specification\n"
366 " --title=TITLE set the application title (caption)\n"
367 " --visual=VISUAL force the application\n"
368 " to use the given visual on an 8-bit display\n"
369 " (only possible value: TrueColor)\n"
370 "\n");
372 #endif // BUILD_GUI
374 fprintf(handle,
375 "The program accepts both TTF and TTC files as input.\n"
376 "Use option -i only if you have a legal permission to modify the font.\n"
377 "The used PPEM value for option -p is FUnits per em, normally 2048.\n"
378 "With option -s, use default values for standard stem width and height,\n"
379 "otherwise they are derived from script-specific characters\n"
380 "resembling the shape of character `o'.\n"
381 "\n");
382 fprintf(handle,
383 "A hint set contains the optimal hinting for a certain PPEM value;\n"
384 "the larger the hint set range (as given by options -l and -r),\n"
385 "the more hint sets get computed, usually increasing the output font size.\n"
386 "The `gasp' table of the output file always enables grayscale hinting\n"
387 "for all sizes (limited by option -G, which is handled in the bytecode).\n"
388 "Increasing the value of -G does not increase the output font size.\n"
389 "\n");
390 fprintf(handle,
391 "Options -f and -D take a four-letter string that identifies a script.\n"
392 "Option -f sets the script used as a fallback for glyphs that have\n"
393 "character codes outside of known script ranges. Option -D sets the\n"
394 "default script for handling OpenType features. Possible values are\n"
395 "\n");
396 const Script_Names* sn = script_names;
397 for(;;)
399 fprintf(handle, " %s (%s)",
400 sn->tag, sn->description);
401 sn++;
402 if (sn->tag)
403 fprintf(handle, ",\n");
404 else
406 fprintf(handle, ".\n");
407 break;
410 fprintf(handle,
411 #ifndef BUILD_GUI
412 "\n"
413 "A control instructions file contains entries of the form\n"
414 "\n"
415 " [<subfont idx>] <glyph id> l|r <points> [(<left offset>,<right offset>)]\n"
416 "or\n"
417 " [<subfont idx>] <glyph id> n <points>\n"
418 "or\n"
419 " [<subfont idx>] <glyph id> p <points> [x <shift>] [y <shift>] @ <ppems>\n"
420 "\n"
421 "`l' (`r') creates one-point segments with direction left (right).\n"
422 "<left offset> and <right offset> specify offsets (in font units)\n"
423 "relative to the corresponding points to give the segments a length.\n"
424 "`n' removes points from horizontal segments, making them `weak' points.\n"
425 "`p' applies delta exceptions to the specified points.\n"
426 "\n"
427 "<glyph id> is a glyph name or index, <shift> is a real number in px,\n"
428 "<points> and <ppems> are integer ranges as with option `-X'.\n"
429 "`#' starts a line comment, which gets ignored.\n"
430 "Empty lines are ignored, too.\n"
431 "\n"
432 "Key letters `l', `r', `n', `p', `x', and `y' have the verbose aliases\n"
433 "`left', `right', `nodir', `point', `xshift', and `yshift', respectively.\n"
434 #endif
435 "\n"
436 #ifdef BUILD_GUI
437 "A command-line version of this program is called `ttfautohint'.\n"
438 #else
439 "A GUI version of this program is called `ttfautohintGUI'.\n"
440 #endif
441 "\n"
442 "Report bugs to: freetype-devel@nongnu.org\n"
443 "ttfautohint home page: <http://www.freetype.org/ttfautohint>\n");
445 if (is_error)
446 exit(EXIT_FAILURE);
447 else
448 exit(EXIT_SUCCESS);
452 static void
453 show_version()
455 fprintf(stdout,
456 #ifdef BUILD_GUI
457 "ttfautohintGUI " VERSION "\n"
458 #else
459 "ttfautohint " VERSION "\n"
460 #endif
461 "Copyright (C) 2011-2014 Werner Lemberg <wl@gnu.org>.\n"
462 "License: FreeType License (FTL) or GNU GPLv2.\n"
463 "This is free software: you are free to change and redistribute it.\n"
464 "There is NO WARRANTY, to the extent permitted by law.\n");
466 exit(EXIT_SUCCESS);
468 #endif // CONSOLE_OUTPUT
472 main(int argc,
473 char** argv)
475 int hinting_range_min = 0;
476 int hinting_range_max = 0;
477 int hinting_limit = 0;
478 int increase_x_height = 0;
479 int fallback_stem_width = 0;
481 bool have_hinting_range_min = false;
482 bool have_hinting_range_max = false;
483 bool have_hinting_limit = false;
484 bool have_increase_x_height = false;
485 bool have_fallback_stem_width = false;
487 bool gray_strong_stem_width = false;
488 bool gdi_cleartype_strong_stem_width = true;
489 bool dw_cleartype_strong_stem_width = false;
491 bool ignore_restrictions = false;
492 bool windows_compatibility = false;
493 bool adjust_subglyphs = false;
494 bool hint_composites = false;
495 bool no_info = false;
496 bool TTFA_info = false;
497 bool symbol = false;
499 const char* default_script = NULL;
500 bool have_default_script = false;
501 const char* fallback_script = NULL;
502 bool have_fallback_script = false;
503 const char* x_height_snapping_exceptions_string = NULL;
504 bool have_x_height_snapping_exceptions_string = false;
506 bool dehint = false;
508 #ifndef BUILD_GUI
509 bool debug = false;
511 TA_Progress_Func progress_func = NULL;
512 TA_Error_Func err_func = err;
513 TA_Info_Func info_func = info;
515 const char* control_name = NULL;
516 #endif
518 // For real numbers (both parsing and displaying) we only use `.' as the
519 // decimal separator; similarly, we don't want localized formats like a
520 // thousands separator for any number.
521 setlocale(LC_NUMERIC, "C");
523 // make GNU, Qt, and X11 command line options look the same;
524 // we allow `--foo=bar', `--foo bar', `-foo=bar', `-foo bar',
525 // and short options specific to ttfautohint
527 // set up a new argument string
528 vector<string> new_arg_string;
529 new_arg_string.push_back(argv[0]);
531 while (1)
533 // use pseudo short options for long-only options
534 enum
536 PASS_THROUGH = CHAR_MAX + 1,
537 HELP_ALL_OPTION,
538 DEBUG_OPTION
541 static struct option long_options[] =
543 {"help", no_argument, NULL, 'h'},
544 #ifdef BUILD_GUI
545 {"help-all", no_argument, NULL, HELP_ALL_OPTION},
546 #endif
548 // ttfautohint options
549 {"adjust-subglyphs", no_argument, NULL, 'p'},
550 {"composites", no_argument, NULL, 'c'},
551 #ifndef BUILD_GUI
552 {"control-file", required_argument, NULL, 'm'},
553 {"debug", no_argument, NULL, DEBUG_OPTION},
554 #endif
555 {"default-script", required_argument, NULL, 'D'},
556 {"dehint", no_argument, NULL, 'd'},
557 {"fallback-script", required_argument, NULL, 'f'},
558 {"fallback-stem-width", required_argument, NULL, 'H'},
559 {"hinting-limit", required_argument, NULL, 'G'},
560 {"hinting-range-max", required_argument, NULL, 'r'},
561 {"hinting-range-min", required_argument, NULL, 'l'},
562 {"ignore-restrictions", no_argument, NULL, 'i'},
563 {"increase-x-height", required_argument, NULL, 'x'},
564 {"no-info", no_argument, NULL, 'n'},
565 {"pre-hinting", no_argument, NULL, 'p'},
566 {"strong-stem-width", required_argument, NULL, 'w'},
567 {"symbol", no_argument, NULL, 's'},
568 {"ttfa-table", no_argument, NULL, 't'},
569 {"verbose", no_argument, NULL, 'v'},
570 {"version", no_argument, NULL, 'V'},
571 {"windows-compatibility", no_argument, NULL, 'W'},
572 {"x-height-snapping-exceptions", required_argument, NULL, 'X'},
574 // Qt options
575 {"graphicssystem", required_argument, NULL, PASS_THROUGH},
576 {"reverse", no_argument, NULL, PASS_THROUGH},
577 {"session", required_argument, NULL, PASS_THROUGH},
578 {"style", required_argument, NULL, PASS_THROUGH},
579 {"stylesheet", required_argument, NULL, PASS_THROUGH},
581 // X11 options
582 {"background", required_argument, NULL, PASS_THROUGH},
583 {"bg", required_argument, NULL, PASS_THROUGH},
584 {"btn", required_argument, NULL, PASS_THROUGH},
585 {"button", required_argument, NULL, PASS_THROUGH},
586 {"cmap", no_argument, NULL, PASS_THROUGH},
587 {"display", required_argument, NULL, PASS_THROUGH},
588 {"fg", required_argument, NULL, PASS_THROUGH},
589 {"fn", required_argument, NULL, PASS_THROUGH},
590 {"font", required_argument, NULL, PASS_THROUGH},
591 {"foreground", required_argument, NULL, PASS_THROUGH},
592 {"geometry", required_argument, NULL, PASS_THROUGH},
593 {"im", required_argument, NULL, PASS_THROUGH},
594 {"inputstyle", required_argument, NULL, PASS_THROUGH},
595 {"name", required_argument, NULL, PASS_THROUGH},
596 {"ncols", required_argument, NULL, PASS_THROUGH},
597 {"title", required_argument, NULL, PASS_THROUGH},
598 {"visual", required_argument, NULL, PASS_THROUGH},
600 {NULL, 0, NULL, 0}
603 int option_index;
604 int c = getopt_long_only(argc, argv,
605 #ifdef BUILD_GUI
606 "cdD:f:G:hH:il:npr:stVvw:Wx:X:",
607 #else
608 "cdD:f:G:hH:il:m:npr:stVvw:Wx:X:",
609 #endif
610 long_options, &option_index);
611 if (c == -1)
612 break;
614 switch (c)
616 case 'c':
617 hint_composites = true;
618 break;
620 case 'd':
621 dehint = true;
622 break;
624 case 'D':
625 default_script = optarg;
626 have_default_script = true;
627 break;
629 case 'f':
630 fallback_script = optarg;
631 have_fallback_script = true;
632 break;
634 case 'G':
635 hinting_limit = atoi(optarg);
636 have_hinting_limit = true;
637 break;
639 case 'h':
640 #ifdef CONSOLE_OUTPUT
641 show_help(false, false);
642 #endif
643 break;
645 case 'H':
646 fallback_stem_width = atoi(optarg);
647 have_fallback_stem_width = true;
648 break;
650 case 'i':
651 ignore_restrictions = true;
652 break;
654 case 'l':
655 hinting_range_min = atoi(optarg);
656 have_hinting_range_min = true;
657 break;
659 #ifndef BUILD_GUI
660 case 'm':
661 control_name = optarg;
662 break;
663 #endif
665 case 'n':
666 no_info = true;
667 break;
669 case 'p':
670 adjust_subglyphs = true;
671 break;
673 case 'r':
674 hinting_range_max = atoi(optarg);
675 have_hinting_range_max = true;
676 break;
678 case 's':
679 symbol = true;
680 break;
682 case 't':
683 TTFA_info = true;
684 break;
686 case 'v':
687 #ifndef BUILD_GUI
688 progress_func = progress;
689 #endif
690 break;
692 case 'V':
693 #ifdef CONSOLE_OUTPUT
694 show_version();
695 #endif
696 break;
698 case 'w':
699 gray_strong_stem_width = strchr(optarg, 'g') ? true : false;
700 gdi_cleartype_strong_stem_width = strchr(optarg, 'G') ? true : false;
701 dw_cleartype_strong_stem_width = strchr(optarg, 'D') ? true : false;
702 break;
704 case 'W':
705 windows_compatibility = true;
706 break;
708 case 'x':
709 increase_x_height = atoi(optarg);
710 have_increase_x_height = true;
711 break;
713 case 'X':
714 x_height_snapping_exceptions_string = optarg;
715 have_x_height_snapping_exceptions_string = true;
716 break;
718 #ifndef BUILD_GUI
719 case DEBUG_OPTION:
720 debug = true;
721 break;
722 #endif
724 #ifdef BUILD_GUI
725 case HELP_ALL_OPTION:
726 #ifdef CONSOLE_OUTPUT
727 show_help(true, false);
728 #endif
729 break;
730 #endif
732 case PASS_THROUGH:
734 // append argument with proper syntax for Qt
735 string arg;
736 arg += '-';
737 arg += long_options[option_index].name;
739 new_arg_string.push_back(arg);
740 if (optarg)
741 new_arg_string.push_back(optarg);
742 break;
745 default:
746 exit(EXIT_FAILURE);
750 if (dehint)
752 // -d makes ttfautohint ignore all other hinting options
753 have_default_script = false;
754 have_fallback_script = false;
755 have_fallback_stem_width = false;
756 have_hinting_range_max = false;
757 have_hinting_range_min = false;
758 have_hinting_limit = false;
759 have_increase_x_height = false;
760 have_x_height_snapping_exceptions_string = false;
763 if (!have_default_script)
764 default_script = "latn";
765 if (!have_fallback_script)
766 fallback_script = "none";
767 if (!have_hinting_range_min)
768 hinting_range_min = TA_HINTING_RANGE_MIN;
769 if (!have_hinting_range_max)
770 hinting_range_max = TA_HINTING_RANGE_MAX;
771 if (!have_hinting_limit)
772 hinting_limit = TA_HINTING_LIMIT;
773 if (!have_increase_x_height)
774 increase_x_height = TA_INCREASE_X_HEIGHT;
775 if (!have_x_height_snapping_exceptions_string)
776 x_height_snapping_exceptions_string = "";
777 if (!have_fallback_stem_width)
778 fallback_stem_width = 0; /* redundant, but avoids a compiler warning */
780 #ifndef BUILD_GUI
782 if (!isatty(fileno(stderr)) && !debug)
783 setvbuf(stderr, (char*)NULL, _IONBF, BUFSIZ);
785 if (hinting_range_min < 2)
787 fprintf(stderr, "The hinting range minimum must be at least 2\n");
788 exit(EXIT_FAILURE);
790 if (hinting_range_max < hinting_range_min)
792 fprintf(stderr, "The hinting range maximum must not be smaller"
793 " than the minimum (%d)\n",
794 hinting_range_min);
795 exit(EXIT_FAILURE);
797 if (hinting_limit != 0 && hinting_limit < hinting_range_max)
799 fprintf(stderr, "A non-zero hinting limit must not be smaller"
800 " than the hinting range maximum (%d)\n",
801 hinting_range_max);
802 exit(EXIT_FAILURE);
804 if (increase_x_height != 0 && increase_x_height < 6)
806 fprintf(stderr, "A non-zero x height increase limit"
807 " must be larger than or equal to 6\n");
808 exit(EXIT_FAILURE);
810 if (have_fallback_stem_width && fallback_stem_width <= 0)
812 fprintf(stderr, "The fallback stem width"
813 " must be a positive integer\n");
814 exit(EXIT_FAILURE);
817 if (have_default_script)
819 const Script_Names* sn;
821 for (sn = script_names; sn->tag; sn++)
822 if (!strcmp(default_script, sn->tag))
823 break;
824 if (!sn->tag)
826 fprintf(stderr, "Unknown script tag `%s'\n", default_script);
827 exit(EXIT_FAILURE);
831 if (have_fallback_script)
833 const Script_Names* sn;
835 for (sn = script_names; sn->tag; sn++)
836 if (!strcmp(fallback_script, sn->tag))
837 break;
838 if (!sn->tag)
840 fprintf(stderr, "Unknown script tag `%s'\n", fallback_script);
841 exit(EXIT_FAILURE);
845 if (symbol
846 && have_fallback_stem_width
847 && !strcmp(fallback_script, "none"))
848 fprintf(stderr,
849 "Warning: Setting a fallback stem width for a symbol font\n"
850 " without setting a fallback script has no effect\n");
852 int num_args = argc - optind;
854 if (num_args > 2)
855 show_help(false, true);
857 FILE* in;
858 if (num_args > 0)
860 in = fopen(argv[optind], "rb");
861 if (!in)
863 fprintf(stderr,
864 "The following error occurred while opening font `%s':\n"
865 "\n"
866 " %s\n",
867 argv[optind], strerror(errno));
868 exit(EXIT_FAILURE);
871 else
873 if (isatty(fileno(stdin)))
874 show_help(false, true);
875 in = stdin;
878 FILE* out;
879 if (num_args > 1)
881 if (!strcmp(argv[optind], argv[optind + 1]))
883 fprintf(stderr, "Input and output file names must not be identical\n");
884 exit(EXIT_FAILURE);
887 out = fopen(argv[optind + 1], "wb");
888 if (!out)
890 fprintf(stderr,
891 "The following error occurred while opening font `%s':\n"
892 "\n"
893 " %s\n",
894 argv[optind + 1], strerror(errno));
895 exit(EXIT_FAILURE);
898 else
900 if (isatty(fileno(stdout)))
901 show_help(false, true);
902 out = stdout;
905 FILE* control = NULL;
906 if (control_name)
908 control = fopen(control_name, "r");
909 if (!control)
911 fprintf(stderr,
912 "The following error occurred while open control file `%s':\n"
913 "\n"
914 " %s\n",
915 control_name, strerror(errno));
916 exit(EXIT_FAILURE);
919 else
920 control = NULL;
922 Progress_Data progress_data = {-1, 1, 0};
923 Error_Data error_data = {control_name};
924 Info_Data info_data;
926 if (no_info)
927 info_func = NULL;
928 else
930 info_data.data = NULL; // must be deallocated after use
931 info_data.data_wide = NULL; // must be deallocated after use
932 info_data.data_len = 0;
933 info_data.data_wide_len = 0;
935 info_data.control_name = control_name;
937 info_data.hinting_range_min = hinting_range_min;
938 info_data.hinting_range_max = hinting_range_max;
939 info_data.hinting_limit = hinting_limit;
941 info_data.gray_strong_stem_width = gray_strong_stem_width;
942 info_data.gdi_cleartype_strong_stem_width = gdi_cleartype_strong_stem_width;
943 info_data.dw_cleartype_strong_stem_width = dw_cleartype_strong_stem_width;
945 info_data.windows_compatibility = windows_compatibility;
946 info_data.adjust_subglyphs = adjust_subglyphs;
947 info_data.hint_composites = hint_composites;
948 info_data.increase_x_height = increase_x_height;
949 info_data.x_height_snapping_exceptions_string = x_height_snapping_exceptions_string;
950 info_data.fallback_stem_width = fallback_stem_width;
951 info_data.symbol = symbol;
952 info_data.TTFA_info = TTFA_info;
954 strncpy(info_data.default_script,
955 default_script,
956 sizeof (info_data.default_script));
957 strncpy(info_data.fallback_script,
958 fallback_script,
959 sizeof (info_data.fallback_script));
961 info_data.dehint = dehint;
963 int ret = build_version_string(&info_data);
964 if (ret == 1)
965 fprintf(stderr, "Warning: Can't allocate memory"
966 " for ttfautohint options string in `name' table\n");
967 else if (ret == 2)
968 fprintf(stderr, "Warning: ttfautohint options string"
969 " in `name' table too long\n");
972 if (in == stdin)
973 SET_BINARY(stdin);
974 if (out == stdout)
975 SET_BINARY(stdout);
977 TA_Error error =
978 TTF_autohint("in-file, out-file, control-file,"
979 "hinting-range-min, hinting-range-max, hinting-limit,"
980 "gray-strong-stem-width, gdi-cleartype-strong-stem-width,"
981 "dw-cleartype-strong-stem-width,"
982 "progress-callback, progress-callback-data,"
983 "error-callback, error-callback-data,"
984 "info-callback, info-callback-data,"
985 "ignore-restrictions, windows-compatibility,"
986 "adjust-subglyphs, hint-composites,"
987 "increase-x-height, x-height-snapping-exceptions,"
988 "fallback-stem-width, default-script, fallback-script,"
989 "symbol, dehint, debug, TTFA-info",
990 in, out, control,
991 hinting_range_min, hinting_range_max, hinting_limit,
992 gray_strong_stem_width, gdi_cleartype_strong_stem_width,
993 dw_cleartype_strong_stem_width,
994 progress_func, &progress_data,
995 err_func, &error_data,
996 info_func, &info_data,
997 ignore_restrictions, windows_compatibility,
998 adjust_subglyphs, hint_composites,
999 increase_x_height, x_height_snapping_exceptions_string,
1000 fallback_stem_width, default_script, fallback_script,
1001 symbol, dehint, debug, TTFA_info);
1003 if (!no_info)
1005 free(info_data.data);
1006 free(info_data.data_wide);
1009 if (in != stdin)
1010 fclose(in);
1011 if (out != stdout)
1012 fclose(out);
1013 if (control)
1014 fclose(control);
1016 exit(error ? EXIT_FAILURE : EXIT_SUCCESS);
1018 return 0; // never reached
1020 #else // BUILD_GUI
1022 int new_argc = new_arg_string.size();
1023 char** new_argv = new char*[new_argc];
1025 // construct new argc and argv variables from collected data
1026 for (int i = 0; i < new_argc; i++)
1027 new_argv[i] = const_cast<char*>(new_arg_string[i].data());
1029 QApplication app(new_argc, new_argv);
1030 app.setApplicationName("TTFautohint");
1031 app.setApplicationVersion(VERSION);
1032 app.setOrganizationName("FreeType");
1033 app.setOrganizationDomain("freetype.org");
1035 bool alternative_layout = false;
1037 // Display the window off the screen -- to get proper window dimensions
1038 // including the frame, the window manager must have a chance to
1039 // decorate it.
1041 // We don't want to change the default window positioning algorithm of
1042 // the platform's window manager, so we create the main GUI window
1043 // twice.
1045 // The original idea, however, was to simply move the off-screen window
1046 // back to the screen with
1048 // gui.move(100, 100);
1049 // gui.setAttribute(Qt::WA_Moved, false);
1050 // gui.show();
1052 // (unsetting the `WA_Moved' attribute makes the window manager handle
1053 // the previous call to `move' as a position suggestion instead of a
1054 // request). Unfortuntely, there seems to be a bug in Qt 4.8.4 which
1055 // prevents any effect of unsetting `WA_Moved' if `show' has already
1056 // been called.
1058 Main_GUI dummy(alternative_layout,
1059 hinting_range_min, hinting_range_max, hinting_limit,
1060 gray_strong_stem_width, gdi_cleartype_strong_stem_width,
1061 dw_cleartype_strong_stem_width, increase_x_height,
1062 x_height_snapping_exceptions_string, fallback_stem_width,
1063 ignore_restrictions, windows_compatibility, adjust_subglyphs,
1064 hint_composites, no_info, default_script, fallback_script,
1065 symbol, dehint, TTFA_info);
1067 dummy.move(-50000, -50000);
1068 dummy.show();
1070 // if the vertical size of our window is too large,
1071 // select a horizontal layout
1072 QRect screen(QApplication::desktop()->availableGeometry());
1073 if (dummy.frameGeometry().height() > screen.width())
1074 alternative_layout = true;
1077 Main_GUI gui(alternative_layout,
1078 hinting_range_min, hinting_range_max, hinting_limit,
1079 gray_strong_stem_width, gdi_cleartype_strong_stem_width,
1080 dw_cleartype_strong_stem_width, increase_x_height,
1081 x_height_snapping_exceptions_string, fallback_stem_width,
1082 ignore_restrictions, windows_compatibility, adjust_subglyphs,
1083 hint_composites, no_info, default_script, fallback_script,
1084 symbol, dehint, TTFA_info);
1085 gui.show();
1087 return app.exec();
1089 #endif // BUILD_GUI
1092 // end of main.cpp