Synchronize front-ends with recent library changes.
[ttfautohint.git] / frontend / main.cpp
blob8bbdd7340fd21c7ed8d0d5b9c92e19129b19b760
1 // main.cpp
3 // Copyright (C) 2011-2013 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>
34 #include <vector>
35 #include <string>
37 #if BUILD_GUI
38 # include <QApplication>
39 # include "maingui.h"
40 #else
41 # include "info.h"
42 #endif
44 #include <ttfautohint.h>
45 #include <numberset.h>
48 #ifdef _WIN32
49 # include <fcntl.h>
50 # define SET_BINARY(f) do { \
51 if (!isatty(fileno(f))) \
52 setmode(fileno(f), O_BINARY); \
53 } while (0)
54 #endif
56 #ifndef SET_BINARY
57 # define SET_BINARY(f) do {} while (0)
58 #endif
61 using namespace std;
64 // the available script tags and its descriptions are directly extracted
65 // from `ttfautohint-scripts.h'
66 typedef struct Script_Names_
68 const char* tag;
69 const char* description;
70 } Script_Names;
72 #undef SCRIPT
73 #define SCRIPT(s, S, d) \
74 {#s, d},
76 const Script_Names script_names[] =
78 #include <ttfautohint-scripts.h>
79 {NULL, NULL}
83 #ifndef BUILD_GUI
84 extern "C" {
86 typedef struct Progress_Data_
88 long last_sfnt;
89 bool begin;
90 int last_percent;
91 } Progress_Data;
94 int
95 progress(long curr_idx,
96 long num_glyphs,
97 long curr_sfnt,
98 long num_sfnts,
99 void* user)
101 Progress_Data* data = (Progress_Data*)user;
103 if (num_sfnts > 1 && curr_sfnt != data->last_sfnt)
105 fprintf(stderr, "subfont %ld of %ld\n", curr_sfnt + 1, num_sfnts);
106 data->last_sfnt = curr_sfnt;
107 data->last_percent = 0;
108 data->begin = true;
111 if (data->begin)
113 fprintf(stderr, " %ld glyphs\n"
114 " ", num_glyphs);
115 data->begin = false;
118 // print progress approx. every 10%
119 int curr_percent = curr_idx * 100 / num_glyphs;
120 int curr_diff = curr_percent - data->last_percent;
122 if (curr_diff >= 10)
124 fprintf(stderr, " %d%%", curr_percent);
125 data->last_percent = curr_percent - curr_percent % 10;
128 if (curr_idx + 1 == num_glyphs)
129 fprintf(stderr, "\n");
131 return 0;
134 } // extern "C"
135 #endif // !BUILD_GUI
138 #ifdef CONSOLE_OUTPUT
139 static void
140 show_help(bool
141 #ifdef BUILD_GUI
143 #endif
145 bool is_error)
147 FILE* handle = is_error ? stderr : stdout;
149 fprintf(handle,
150 #ifdef BUILD_GUI
151 "Usage: ttfautohintGUI [OPTION]...\n"
152 "A GUI application to replace hints in a TrueType font.\n"
153 #else
154 "Usage: ttfautohint [OPTION]... [IN-FILE [OUT-FILE]]\n"
155 "Replace hints in TrueType font IN-FILE and write output to OUT-FILE.\n"
156 "If OUT-FILE is missing, standard output is used instead;\n"
157 "if IN-FILE is missing also, standard input and output are used.\n"
158 #endif
159 "\n"
160 "The new hints are based on FreeType's auto-hinter.\n"
161 "\n"
162 "This program is a simple front-end to the `ttfautohint' library.\n"
163 "\n");
165 fprintf(handle,
166 "Long options can be given with one or two dashes,\n"
167 "and with and without equal sign between option and argument.\n"
168 "This means that the following forms are acceptable:\n"
169 "`-foo=bar', `--foo=bar', `-foo bar', `--foo bar'.\n"
170 "\n"
171 "Mandatory arguments to long options are mandatory for short options too.\n"
172 #ifdef BUILD_GUI
173 "Options not related to Qt or X11 set default values.\n"
174 #endif
175 "\n"
178 fprintf(handle,
179 "Options:\n"
180 #ifndef BUILD_GUI
181 " --debug print debugging information\n"
182 #endif
183 " -c, --composites hint glyph composites also\n"
184 " -d, --dehint remove all hints\n"
185 " -f, --fallback-script=S set fallback script (default: none)\n"
186 " -G, --hinting-limit=N switch off hinting above this PPEM value\n"
187 " (default: %d); value 0 means no limit\n"
188 " -h, --help display this help and exit\n"
189 #ifdef BUILD_GUI
190 " --help-all show Qt and X11 specific options also\n"
191 #endif
192 " -i, --ignore-restrictions override font license restrictions\n"
193 " -l, --hinting-range-min=N the minimum PPEM value for hint sets\n"
194 " (default: %d)\n"
195 " -n, --no-info don't add ttfautohint info\n"
196 " to the version string(s) in the `name' table\n"
197 " -p, --pre-hinting apply original hints in advance\n",
198 TA_HINTING_LIMIT, TA_HINTING_RANGE_MIN);
199 fprintf(handle,
200 " -r, --hinting-range-max=N the maximum PPEM value for hint sets\n"
201 " (default: %d)\n"
202 " -s, --symbol input is symbol font\n"
203 " -v, --verbose show progress information\n"
204 " -V, --version print version information and exit\n"
205 " -w, --strong-stem-width=S use strong stem width routine for modes S,\n"
206 " where S is a string of up to three letters\n"
207 " with possible values `g' for grayscale,\n"
208 " `G' for GDI ClearType, and `D' for\n"
209 " DirectWrite ClearType (default: G)\n"
210 " -W, --windows-compatibility\n"
211 " add blue zones for `usWinAscent' and\n"
212 " `usWinDescent' to avoid clipping\n"
213 " -x, --increase-x-height=N increase x height for sizes in the range\n"
214 " 6<=PPEM<=N; value 0 switches off this feature\n"
215 " (default: %d)\n"
216 " -X, --x-height-snapping-exceptions=STRING\n"
217 " specify a comma-separated list of\n"
218 " x-height snapping exceptions, for example\n"
219 " \"-9, 13-17, 19\" (default: \"\")\n"
220 "\n",
221 TA_HINTING_RANGE_MAX, TA_INCREASE_X_HEIGHT);
223 #ifdef BUILD_GUI
224 if (all)
226 fprintf(handle,
227 "Qt Options:\n"
228 " --graphicssystem=SYSTEM\n"
229 " select a different graphics system backend\n"
230 " instead of the default one\n"
231 " (possible values: `raster', `opengl')\n"
232 " --reverse set layout direction to right-to-left\n");
233 fprintf(handle,
234 " --session=ID restore the application for the given ID\n"
235 " --style=STYLE set application GUI style\n"
236 " (possible values: motif, windows, platinum)\n"
237 " --stylesheet=SHEET apply the given Qt stylesheet\n"
238 " to the application widgets\n"
239 "\n");
241 fprintf(handle,
242 "X11 options:\n"
243 " --background=COLOR set the default background color\n"
244 " and an application palette\n"
245 " (light and dark shades are calculated)\n"
246 " --bg=COLOR same as --background\n"
247 " --btn=COLOR set the default button color\n"
248 " --button=COLOR same as --btn\n"
249 " --cmap use a private color map on an 8-bit display\n"
250 " --display=NAME use the given X-server display\n");
251 fprintf(handle,
252 " --fg=COLOR set the default foreground color\n"
253 " --fn=FONTNAME set the application font\n"
254 " --font=FONTNAME same as --fn\n"
255 " --foreground=COLOR same as --fg\n"
256 " --geometry=GEOMETRY set the client geometry of first window\n"
257 " --im=SERVER set the X Input Method (XIM) server\n"
258 " --inputstyle=STYLE set X Input Method input style\n"
259 " (possible values: onthespot, overthespot,\n"
260 " offthespot, root)\n");
261 fprintf(handle,
262 " --name=NAME set the application name\n"
263 " --ncols=COUNT limit the number of colors allocated\n"
264 " in the color cube on an 8-bit display,\n"
265 " if the application is using the\n"
266 " QApplication::ManyColor color specification\n"
267 " --title=TITLE set the application title (caption)\n"
268 " --visual=VISUAL force the application\n"
269 " to use the given visual on an 8-bit display\n"
270 " (only possible value: TrueColor)\n"
271 "\n");
273 #endif // BUILD_GUI
275 fprintf(handle,
276 "The program accepts both TTF and TTC files as input.\n"
277 "Use option -i only if you have a legal permission to modify the font.\n"
278 "The used PPEM value for option -p is FUnits per em, normally 2048.\n"
279 "With option -s, use default values for standard stem width and height,\n"
280 "otherwise they are derived from script-specific characters\n"
281 "resembling the shape of character `o'.\n"
282 "\n");
283 fprintf(handle,
284 "A hint set contains the optimal hinting for a certain PPEM value;\n"
285 "the larger the hint set range, the more hint sets get computed,\n"
286 "usually increasing the output font size. Note, however,\n"
287 "that the `gasp' table of the output file enables grayscale hinting\n"
288 "for all sizes (limited by option -G, which is handled in the bytecode).\n"
289 "\n");
290 fprintf(handle,
291 "Option -f takes a four-letter string that identifies the script\n"
292 "to be used as a fallback for glyphs that have character codes\n"
293 "outside of known script ranges. Possible values are\n"
294 "\n");
295 const Script_Names* sn = script_names;
296 for(;;)
298 fprintf(handle, " %s (%s)",
299 sn->tag, sn->description);
300 sn++;
301 if (sn->tag)
302 fprintf(handle, ",\n");
303 else
305 fprintf(handle, ".\n");
306 break;
309 fprintf(handle,
310 "\n"
311 "If no option -f is given, or if its value is `none',\n"
312 "no fallback script is used.\n"
313 "\n");
314 fprintf(handle,
315 #ifdef BUILD_GUI
316 "A command-line version of this program is called `ttfautohint'.\n"
317 #else
318 "A GUI version of this program is called `ttfautohintGUI'.\n"
319 #endif
320 "\n"
321 "Report bugs to: freetype-devel@nongnu.org\n"
322 "ttfautohint home page: <http://www.freetype.org/ttfautohint>\n");
324 if (is_error)
325 exit(EXIT_FAILURE);
326 else
327 exit(EXIT_SUCCESS);
331 static void
332 show_version()
334 fprintf(stdout,
335 #ifdef BUILD_GUI
336 "ttfautohintGUI " VERSION "\n"
337 #else
338 "ttfautohint " VERSION "\n"
339 #endif
340 "Copyright (C) 2011-2013 Werner Lemberg <wl@gnu.org>.\n"
341 "License: FreeType License (FTL) or GNU GPLv2.\n"
342 "This is free software: you are free to change and redistribute it.\n"
343 "There is NO WARRANTY, to the extent permitted by law.\n");
345 exit(EXIT_SUCCESS);
347 #endif // CONSOLE_OUTPUT
351 main(int argc,
352 char** argv)
354 int hinting_range_min = 0;
355 int hinting_range_max = 0;
356 int hinting_limit = 0;
357 int increase_x_height = 0;
358 bool have_hinting_range_min = false;
359 bool have_hinting_range_max = false;
360 bool have_hinting_limit = false;
361 bool have_increase_x_height = false;
363 bool gray_strong_stem_width = false;
364 bool gdi_cleartype_strong_stem_width = true;
365 bool dw_cleartype_strong_stem_width = false;
367 bool ignore_restrictions = false;
368 bool windows_compatibility = false;
369 bool pre_hinting = false;
370 bool hint_composites = false;
371 bool no_info = false;
372 bool symbol = false;
374 const char* fallback_script = NULL;
375 bool have_fallback_script = false;
376 const char* x_height_snapping_exceptions_string = NULL;
377 bool have_x_height_snapping_exceptions_string = false;
379 bool dehint = false;
381 #ifndef BUILD_GUI
382 bool debug = false;
384 TA_Progress_Func progress_func = NULL;
385 TA_Info_Func info_func = info;
386 #endif
388 // make GNU, Qt, and X11 command line options look the same;
389 // we allow `--foo=bar', `--foo bar', `-foo=bar', `-foo bar',
390 // and short options specific to ttfautohint
392 // set up a new argument string
393 vector<string> new_arg_string;
394 new_arg_string.push_back(argv[0]);
396 while (1)
398 // use pseudo short options for long-only options
399 enum
401 PASS_THROUGH = CHAR_MAX + 1,
402 HELP_ALL_OPTION,
403 DEBUG_OPTION
406 static struct option long_options[] =
408 {"help", no_argument, NULL, 'h'},
409 #ifdef BUILD_GUI
410 {"help-all", no_argument, NULL, HELP_ALL_OPTION},
411 #endif
413 // ttfautohint options
414 {"composites", no_argument, NULL, 'c'},
415 #ifndef BUILD_GUI
416 {"debug", no_argument, NULL, DEBUG_OPTION},
417 #endif
418 {"dehint", no_argument, NULL, 'd'},
419 {"fallback-script", required_argument, NULL, 'f'},
420 {"hinting-limit", required_argument, NULL, 'G'},
421 {"hinting-range-max", required_argument, NULL, 'r'},
422 {"hinting-range-min", required_argument, NULL, 'l'},
423 {"ignore-restrictions", no_argument, NULL, 'i'},
424 {"increase-x-height", required_argument, NULL, 'x'},
425 {"no-info", no_argument, NULL, 'n'},
426 {"pre-hinting", no_argument, NULL, 'p'},
427 {"strong-stem-width", required_argument, NULL, 'w'},
428 {"symbol", no_argument, NULL, 's'},
429 {"verbose", no_argument, NULL, 'v'},
430 {"version", no_argument, NULL, 'V'},
431 {"windows-compatibility", no_argument, NULL, 'W'},
432 {"x-height-snapping-exceptions", required_argument, NULL, 'X'},
434 // Qt options
435 {"graphicssystem", required_argument, NULL, PASS_THROUGH},
436 {"reverse", no_argument, NULL, PASS_THROUGH},
437 {"session", required_argument, NULL, PASS_THROUGH},
438 {"style", required_argument, NULL, PASS_THROUGH},
439 {"stylesheet", required_argument, NULL, PASS_THROUGH},
441 // X11 options
442 {"background", required_argument, NULL, PASS_THROUGH},
443 {"bg", required_argument, NULL, PASS_THROUGH},
444 {"btn", required_argument, NULL, PASS_THROUGH},
445 {"button", required_argument, NULL, PASS_THROUGH},
446 {"cmap", no_argument, NULL, PASS_THROUGH},
447 {"display", required_argument, NULL, PASS_THROUGH},
448 {"fg", required_argument, NULL, PASS_THROUGH},
449 {"fn", required_argument, NULL, PASS_THROUGH},
450 {"font", required_argument, NULL, PASS_THROUGH},
451 {"foreground", required_argument, NULL, PASS_THROUGH},
452 {"geometry", required_argument, NULL, PASS_THROUGH},
453 {"im", required_argument, NULL, PASS_THROUGH},
454 {"inputstyle", required_argument, NULL, PASS_THROUGH},
455 {"name", required_argument, NULL, PASS_THROUGH},
456 {"ncols", required_argument, NULL, PASS_THROUGH},
457 {"title", required_argument, NULL, PASS_THROUGH},
458 {"visual", required_argument, NULL, PASS_THROUGH},
460 {NULL, 0, NULL, 0}
463 int option_index;
464 int c = getopt_long_only(argc, argv, "cdf:G:hil:npr:stVvw:Wx:X:",
465 long_options, &option_index);
466 if (c == -1)
467 break;
469 switch (c)
471 case 'c':
472 hint_composites = true;
473 break;
475 case 'd':
476 dehint = true;
477 break;
479 case 'f':
480 fallback_script = optarg;
481 have_fallback_script = true;
482 break;
484 case 'G':
485 hinting_limit = atoi(optarg);
486 have_hinting_limit = true;
487 break;
489 case 'h':
490 #ifdef CONSOLE_OUTPUT
491 show_help(false, false);
492 #endif
493 break;
495 case 'i':
496 ignore_restrictions = true;
497 break;
499 case 'l':
500 hinting_range_min = atoi(optarg);
501 have_hinting_range_min = true;
502 break;
504 case 'n':
505 no_info = true;
506 break;
508 case 'p':
509 pre_hinting = true;
510 break;
512 case 'r':
513 hinting_range_max = atoi(optarg);
514 have_hinting_range_max = true;
515 break;
517 case 's':
518 symbol = true;
519 break;
521 case 'v':
522 #ifndef BUILD_GUI
523 progress_func = progress;
524 #endif
525 break;
527 case 'V':
528 #ifdef CONSOLE_OUTPUT
529 show_version();
530 #endif
531 break;
533 case 'w':
534 gray_strong_stem_width = strchr(optarg, 'g') ? true : false;
535 gdi_cleartype_strong_stem_width = strchr(optarg, 'G') ? true : false;
536 dw_cleartype_strong_stem_width = strchr(optarg, 'D') ? true : false;
537 break;
539 case 'W':
540 windows_compatibility = true;
541 break;
543 case 'x':
544 increase_x_height = atoi(optarg);
545 have_increase_x_height = true;
546 break;
548 case 'X':
549 x_height_snapping_exceptions_string = optarg;
550 have_x_height_snapping_exceptions_string = true;
551 break;
553 #ifndef BUILD_GUI
554 case DEBUG_OPTION:
555 debug = true;
556 break;
557 #endif
559 #ifdef BUILD_GUI
560 case HELP_ALL_OPTION:
561 #ifdef CONSOLE_OUTPUT
562 show_help(true, false);
563 #endif
564 break;
565 #endif
567 case PASS_THROUGH:
569 // append argument with proper syntax for Qt
570 string arg;
571 arg += '-';
572 arg += long_options[option_index].name;
574 new_arg_string.push_back(arg);
575 if (optarg)
576 new_arg_string.push_back(optarg);
577 break;
580 default:
581 exit(EXIT_FAILURE);
585 if (dehint)
587 // -d makes ttfautohint ignore all other hinting options
588 have_fallback_script = false;
589 have_hinting_range_min = false;
590 have_hinting_range_max = false;
591 have_hinting_limit = false;
592 have_increase_x_height = false;
593 have_x_height_snapping_exceptions_string = false;
596 if (!have_fallback_script)
597 fallback_script = "none";
598 if (!have_hinting_range_min)
599 hinting_range_min = TA_HINTING_RANGE_MIN;
600 if (!have_hinting_range_max)
601 hinting_range_max = TA_HINTING_RANGE_MAX;
602 if (!have_hinting_limit)
603 hinting_limit = TA_HINTING_LIMIT;
604 if (!have_increase_x_height)
605 increase_x_height = TA_INCREASE_X_HEIGHT;
606 if (!have_x_height_snapping_exceptions_string)
607 x_height_snapping_exceptions_string = "";
609 #ifndef BUILD_GUI
611 if (!isatty(fileno(stderr)) && !debug)
612 setvbuf(stderr, (char*)NULL, _IONBF, BUFSIZ);
614 if (hinting_range_min < 2)
616 fprintf(stderr, "The hinting range minimum must be at least 2\n");
617 exit(EXIT_FAILURE);
619 if (hinting_range_max < hinting_range_min)
621 fprintf(stderr, "The hinting range maximum must not be smaller"
622 " than the minimum (%d)\n",
623 hinting_range_min);
624 exit(EXIT_FAILURE);
626 if (hinting_limit != 0 && hinting_limit < hinting_range_max)
628 fprintf(stderr, "A non-zero hinting limit must not be smaller"
629 " than the hinting range maximum (%d)\n",
630 hinting_range_max);
631 exit(EXIT_FAILURE);
633 if (increase_x_height != 0 && increase_x_height < 6)
635 fprintf(stderr, "A non-zero x height increase limit"
636 " must be larger than or equal to 6\n");
637 exit(EXIT_FAILURE);
640 number_range* x_height_snapping_exceptions = NULL;
642 if (have_x_height_snapping_exceptions_string)
644 const char* s;
647 s = number_set_parse(x_height_snapping_exceptions_string,
648 &x_height_snapping_exceptions,
649 6, 0x7FFF);
650 if (*s)
652 if (x_height_snapping_exceptions == NUMBERSET_ALLOCATION_ERROR)
653 fprintf(stderr, "Allocation error while scanning"
654 " x height snapping exceptions\n");
655 else {
656 if (x_height_snapping_exceptions == NUMBERSET_INVALID_CHARACTER)
657 fprintf(stderr, "Invalid character");
658 else if (x_height_snapping_exceptions == NUMBERSET_OVERFLOW)
659 fprintf(stderr, "Overflow");
660 else if (x_height_snapping_exceptions == NUMBERSET_INVALID_RANGE)
661 fprintf(stderr, "Invalid range");
662 else if (x_height_snapping_exceptions == NUMBERSET_OVERLAPPING_RANGES)
663 fprintf(stderr, "Overlapping ranges");
664 else if (x_height_snapping_exceptions == NUMBERSET_NOT_ASCENDING)
665 fprintf(stderr, "Values und ranges must be ascending");
666 fprintf(stderr, " in x height snapping exceptions:\n"
667 " \"%s\"\n"
668 " %*s\n",
669 x_height_snapping_exceptions_string,
670 s - x_height_snapping_exceptions_string + 1, "^");
672 exit(EXIT_FAILURE);
676 if (have_fallback_script)
678 const Script_Names* sn;
680 for (sn = script_names; sn->tag; sn++)
681 if (!strcmp(fallback_script, sn->tag))
682 break;
683 if (!sn->tag)
685 fprintf(stderr, "Unknown script tag `%s'\n", fallback_script);
686 exit(EXIT_FAILURE);
690 int num_args = argc - optind;
692 if (num_args > 2)
693 show_help(false, true);
695 FILE* in;
696 if (num_args > 0)
698 in = fopen(argv[optind], "rb");
699 if (!in)
701 fprintf(stderr, "The following error occurred while opening font `%s':\n"
702 "\n"
703 " %s\n",
704 argv[optind], strerror(errno));
705 exit(EXIT_FAILURE);
708 else
710 if (isatty(fileno(stdin)))
711 show_help(false, true);
712 in = stdin;
715 FILE* out;
716 if (num_args > 1)
718 if (!strcmp(argv[optind], argv[optind + 1]))
720 fprintf(stderr, "Input and output file names must not be identical\n");
721 exit(EXIT_FAILURE);
724 out = fopen(argv[optind + 1], "wb");
725 if (!out)
727 fprintf(stderr, "The following error occurred while opening font `%s':\n"
728 "\n"
729 " %s\n",
730 argv[optind + 1], strerror(errno));
731 exit(EXIT_FAILURE);
734 else
736 if (isatty(fileno(stdout)))
737 show_help(false, true);
738 out = stdout;
741 const unsigned char* error_string;
742 Progress_Data progress_data = {-1, 1, 0};
743 Info_Data info_data;
745 if (no_info)
746 info_func = NULL;
747 else
749 info_data.data = NULL; // must be deallocated after use
750 info_data.data_wide = NULL; // must be deallocated after use
751 info_data.data_len = 0;
752 info_data.data_wide_len = 0;
754 info_data.hinting_range_min = hinting_range_min;
755 info_data.hinting_range_max = hinting_range_max;
756 info_data.hinting_limit = hinting_limit;
758 info_data.gray_strong_stem_width = gray_strong_stem_width;
759 info_data.gdi_cleartype_strong_stem_width = gdi_cleartype_strong_stem_width;
760 info_data.dw_cleartype_strong_stem_width = dw_cleartype_strong_stem_width;
762 info_data.windows_compatibility = windows_compatibility;
763 info_data.pre_hinting = pre_hinting;
764 info_data.hint_composites = hint_composites;
765 info_data.increase_x_height = increase_x_height;
766 info_data.x_height_snapping_exceptions = x_height_snapping_exceptions;
767 info_data.symbol = symbol;
769 strncpy(info_data.fallback_script,
770 fallback_script,
771 sizeof (info_data.fallback_script));
773 info_data.dehint = dehint;
775 int ret = build_version_string(&info_data);
776 if (ret == 1)
777 fprintf(stderr, "Warning: Can't allocate memory"
778 " for ttfautohint options string in `name' table\n");
779 else if (ret == 2)
780 fprintf(stderr, "Warning: ttfautohint options string"
781 " in `name' table too long\n");
784 if (in == stdin)
785 SET_BINARY(stdin);
786 if (out == stdout)
787 SET_BINARY(stdout);
789 TA_Error error =
790 TTF_autohint("in-file, out-file,"
791 "hinting-range-min, hinting-range-max, hinting-limit,"
792 "gray-strong-stem-width, gdi-cleartype-strong-stem-width,"
793 "dw-cleartype-strong-stem-width,"
794 "error-string,"
795 "progress-callback, progress-callback-data,"
796 "info-callback, info-callback-data,"
797 "ignore-restrictions, windows-compatibility,"
798 "pre-hinting, hint-composites,"
799 "increase-x-height, x-height-snapping-exceptions,"
800 "fallback-script, symbol,"
801 "dehint, debug",
802 in, out,
803 hinting_range_min, hinting_range_max, hinting_limit,
804 gray_strong_stem_width, gdi_cleartype_strong_stem_width,
805 dw_cleartype_strong_stem_width,
806 &error_string,
807 progress_func, &progress_data,
808 info_func, &info_data,
809 ignore_restrictions, windows_compatibility,
810 pre_hinting, hint_composites,
811 increase_x_height, x_height_snapping_exceptions_string,
812 fallback_script, symbol,
813 dehint, debug);
815 if (!no_info)
817 free(info_data.data);
818 free(info_data.data_wide);
821 number_set_free(x_height_snapping_exceptions);
823 if (error)
825 if (error == TA_Err_Invalid_FreeType_Version)
826 fprintf(stderr,
827 "FreeType version 2.4.5 or higher is needed.\n"
828 "Perhaps using a wrong FreeType DLL?\n");
829 else if (error == TA_Err_Invalid_Font_Type)
830 fprintf(stderr,
831 "This font is not a valid font"
832 " in SFNT format with TrueType outlines.\n"
833 "In particular, CFF outlines are not supported.\n");
834 else if (error == TA_Err_Already_Processed)
835 fprintf(stderr,
836 "This font has already been processed with ttfautohint.\n");
837 else if (error == TA_Err_Missing_Legal_Permission)
838 fprintf(stderr,
839 "Bit 1 in the `fsType' field of the `OS/2' table is set:\n"
840 "This font must not be modified"
841 " without permission of the legal owner.\n"
842 "Use command line option `-i' to continue"
843 " if you have such a permission.\n");
844 else if (error == TA_Err_Missing_Unicode_CMap)
845 fprintf(stderr,
846 "No Unicode character map.\n");
847 else if (error == TA_Err_Missing_Symbol_CMap)
848 fprintf(stderr,
849 "No symbol character map.\n");
850 else if (error == TA_Err_Missing_Glyph)
851 fprintf(stderr,
852 "No glyph for the key character"
853 " to derive standard width and height.\n"
854 "For the latin script, this key character is `o' (U+006F).\n");
855 else
856 fprintf(stderr,
857 "Error code `0x%02x' while autohinting font:\n"
858 " %s\n", error, error_string);
859 exit(EXIT_FAILURE);
862 if (in != stdin)
863 fclose(in);
864 if (out != stdout)
865 fclose(out);
867 exit(EXIT_SUCCESS);
869 return 0; // never reached
871 #else // BUILD_GUI
873 int new_argc = new_arg_string.size();
874 char** new_argv = new char*[new_argc];
876 // construct new argc and argv variables from collected data
877 for (int i = 0; i < new_argc; i++)
878 new_argv[i] = const_cast<char*>(new_arg_string[i].data());
880 QApplication app(new_argc, new_argv);
881 app.setApplicationName("TTFautohint");
882 app.setApplicationVersion(VERSION);
883 app.setOrganizationName("FreeType");
884 app.setOrganizationDomain("freetype.org");
886 bool alternative_layout = false;
888 // Display the window off the screen -- to get proper window dimensions
889 // including the frame, the window manager must have a chance to
890 // decorate it.
892 // We don't want to change the default window positioning algorithm of
893 // the platform's window manager, so we create the main GUI window
894 // twice.
896 // The original idea, however, was to simply move the off-screen window
897 // back to the screen with
899 // gui.move(100, 100);
900 // gui.setAttribute(Qt::WA_Moved, false);
901 // gui.show();
903 // (unsetting the `WA_Moved' attribute makes the window manager handle
904 // the previous call to `move' as a position suggestion instead of a
905 // request). Unfortuntely, there seems to be a bug in Qt 4.8.4 which
906 // prevents any effect of unsetting `WA_Moved' if `show' has already
907 // been called.
909 Main_GUI dummy(alternative_layout,
910 hinting_range_min, hinting_range_max, hinting_limit,
911 gray_strong_stem_width, gdi_cleartype_strong_stem_width,
912 dw_cleartype_strong_stem_width, increase_x_height,
913 x_height_snapping_exceptions_string,
914 ignore_restrictions, windows_compatibility, pre_hinting,
915 hint_composites, no_info, fallback_script, symbol,
916 dehint);
918 dummy.move(-50000, -50000);
919 dummy.show();
921 // if the vertical size of our window is too large,
922 // select a horizontal layout
923 QRect screen(QApplication::desktop()->availableGeometry());
924 if (dummy.frameGeometry().height() > screen.width())
925 alternative_layout = true;
928 Main_GUI gui(alternative_layout,
929 hinting_range_min, hinting_range_max, hinting_limit,
930 gray_strong_stem_width, gdi_cleartype_strong_stem_width,
931 dw_cleartype_strong_stem_width, increase_x_height,
932 x_height_snapping_exceptions_string,
933 ignore_restrictions, windows_compatibility, pre_hinting,
934 hint_composites, no_info, fallback_script, symbol,
935 dehint);
936 gui.show();
938 return app.exec();
940 #endif // BUILD_GUI
943 // end of main.cpp