3 // Copyright (C) 2011-2016 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
39 # include <QApplication>
42 # include <ft2build.h>
43 # include FT_FREETYPE_H
44 # include FT_TRUETYPE_TABLES_H // for option `-T'
48 #include <ttfautohint.h>
49 #include <numberset.h>
54 # define SET_BINARY(f) do { \
55 if (!isatty(fileno(f))) \
56 setmode(fileno(f), O_BINARY); \
61 # define SET_BINARY(f) do {} while (0)
68 typedef struct Tag_Names_
71 const char* description
;
75 // the available script tags and its descriptions are directly extracted
76 // from `ttfautohint-scripts.h'
78 #define SCRIPT(s, S, d, h, H, ss) \
81 const Tag_Names script_names
[] =
83 #include <ttfautohint-scripts.h>
88 // the available feature tags and its descriptions are directly extracted
89 // from `ttfautohint-coverages.h'
91 #define COVERAGE(n, N, d, t, t1, t2, t3, t4) \
94 const Tag_Names feature_names
[] =
96 #include <ttfautohint-coverages.h>
104 typedef struct Progress_Data_
113 progress(long curr_idx
,
119 Progress_Data
* data
= (Progress_Data
*)user
;
121 if (num_sfnts
> 1 && curr_sfnt
!= data
->last_sfnt
)
123 fprintf(stderr
, "subfont %ld of %ld\n", curr_sfnt
+ 1, num_sfnts
);
124 data
->last_sfnt
= curr_sfnt
;
125 data
->last_percent
= 0;
131 fprintf(stderr
, " %ld glyphs\n"
136 // print progress approx. every 10%
137 int curr_percent
= curr_idx
* 100 / num_glyphs
;
138 int curr_diff
= curr_percent
- data
->last_percent
;
142 fprintf(stderr
, " %d%%", curr_percent
);
143 data
->last_percent
= curr_percent
- curr_percent
% 10;
146 if (curr_idx
+ 1 == num_glyphs
)
147 fprintf(stderr
, "\n");
153 typedef struct Error_Data_
155 const char* control_name
;
161 const char* error_string
,
162 unsigned int errlinenum
,
167 Error_Data
* data
= static_cast<Error_Data
*>(user
);
172 // We replace some terse error strings with more user-friendly versions.
173 if (error
== TA_Err_Invalid_FreeType_Version
)
175 "FreeType version 2.4.5 or higher is needed.\n"
176 "Perhaps using a wrong FreeType DLL?\n");
177 else if (error
== TA_Err_Invalid_Font_Type
)
179 "This font is not a valid font"
180 " in SFNT format with TrueType outlines.\n"
181 "In particular, CFF outlines are not supported.\n");
182 else if (error
== TA_Err_Already_Processed
)
184 "This font has already been processed with ttfautohint.\n");
185 else if (error
== TA_Err_Missing_Legal_Permission
)
187 "Bit 1 in the `fsType' field of the `OS/2' table is set:\n"
188 "This font must not be modified"
189 " without permission of the legal owner.\n"
190 "Use command line option `-i' to continue"
191 " if you have such a permission.\n");
192 else if (error
== TA_Err_Missing_Unicode_CMap
)
194 "No Unicode character map.\n");
195 else if (error
== TA_Err_Missing_Symbol_CMap
)
197 "No symbol character map.\n");
198 else if (error
== TA_Err_Missing_Glyph
)
200 "No glyph for a standard character"
201 " to derive standard width and height.\n"
202 "Please check the documentation for a list of"
203 " script-specific standard characters,\n"
204 "or use option `--symbol'.\n");
208 fprintf(stderr
, "An error with code 0x%02x occurred"
209 " while autohinting fonts\n",
211 else if (error
>= 0x100 && error
< 0x200)
213 fprintf(stderr
, "An error with code 0x%03x occurred"
214 " while parsing the argument of option `-X'",
216 fprintf(stderr
, errline
? ":\n" : ".\n");
219 fprintf(stderr
, " %s\n", errline
);
220 if (errpos
&& errline
)
221 fprintf(stderr
, " %*s\n", int(errpos
- errline
+ 1), "^");
223 else if (error
>= 0x200 && error
< 0x300)
225 fprintf(stderr
, "%s:", data
->control_name
);
227 fprintf(stderr
, "%d:", errlinenum
);
228 if (errpos
&& errline
)
229 fprintf(stderr
, "%d:", int(errpos
- errline
+ 1));
231 fprintf(stderr
, " %s", error_string
);
232 fprintf(stderr
, " (0x%02X)\n", error
);
234 fprintf(stderr
, " %s\n", errline
);
235 if (errpos
&& errline
)
236 fprintf(stderr
, " %*s\n", int(errpos
- errline
+ 1), "^");
246 #ifdef CONSOLE_OUTPUT
255 FILE* handle
= is_error
? stderr
: stdout
;
259 "Usage: ttfautohintGUI [OPTION]...\n"
260 "A GUI application to replace hints in a TrueType font.\n"
262 "Usage: ttfautohint [OPTION]... [IN-FILE [OUT-FILE]]\n"
263 "Replace hints in TrueType font IN-FILE and write output to OUT-FILE.\n"
264 "If OUT-FILE is missing, standard output is used instead;\n"
265 "if IN-FILE is missing also, standard input and output are used.\n"
268 "The new hints are based on FreeType's auto-hinter.\n"
270 "This program is a simple front-end to the `ttfautohint' library.\n"
274 "Long options can be given with one or two dashes,\n"
275 "and with and without equal sign between option and argument.\n"
276 "This means that the following forms are acceptable:\n"
277 "`-foo=bar', `--foo=bar', `-foo bar', `--foo bar'.\n"
279 "Mandatory arguments to long options are mandatory for short options too.\n"
281 "Options not related to Qt or X11 set default values.\n"
289 " --debug print debugging information\n"
291 " -c, --composites hint glyph composites also\n"
292 " -d, --dehint remove all hints\n"
293 " -D, --default-script=S set default OpenType script (default: latn)\n"
294 " -f, --fallback-script=S set fallback script (default: none)\n"
295 " -F, --family-suffix=S append suffix to the family name string(s)\n"
296 " in the `name' table\n"
297 " -G, --hinting-limit=N switch off hinting above this PPEM value\n"
298 " (default: %d); value 0 means no limit\n"
299 " -h, --help display this help and exit\n"
300 " -H, --fallback-stem-width=N\n"
301 " set fallback stem width\n"
302 " (default: 50 font units at 2048 UPEM)\n"
304 " --help-all show Qt and X11 specific options also\n"
306 " -i, --ignore-restrictions override font license restrictions\n"
307 " -I, --detailed-info add detailed ttfautohint info\n"
308 " to the version string(s) in the `name' table\n"
309 " -l, --hinting-range-min=N the minimum PPEM value for hint sets\n"
312 " -m, --control-file=FILE get control instructions from FILE\n"
314 " -n, --no-info don't add ttfautohint info\n"
315 " to the version string(s) in the `name' table\n"
316 " -p, --adjust-subglyphs handle subglyph adjustments in exotic fonts\n",
317 TA_HINTING_LIMIT
, TA_HINTING_RANGE_MIN
);
319 " -r, --hinting-range-max=N the maximum PPEM value for hint sets\n"
321 " -s, --symbol input is symbol font\n"
322 " -S, --fallback-scaling use fallback scaling, not hinting\n"
323 " -t, --ttfa-table add TTFA information table\n"
325 " -T, --ttfa-info display TTFA table in IN-FILE and exit\n"
327 " -v, --verbose show progress information\n"
328 " -V, --version print version information and exit\n"
329 " -w, --strong-stem-width=S use strong stem width routine for modes S,\n"
330 " where S is a string of up to three letters\n"
331 " with possible values `g' for grayscale,\n"
332 " `G' for GDI ClearType, and `D' for\n"
333 " DirectWrite ClearType (default: G)\n"
334 " -W, --windows-compatibility\n"
335 " add blue zones for `usWinAscent' and\n"
336 " `usWinDescent' to avoid clipping\n"
337 " -x, --increase-x-height=N increase x height for sizes in the range\n"
338 " 6<=PPEM<=N; value 0 switches off this feature\n"
340 " -X, --x-height-snapping-exceptions=STRING\n"
341 " specify a comma-separated list of\n"
342 " x-height snapping exceptions, for example\n"
343 " \"-9, 13-17, 19\" (default: \"\")\n"
345 TA_HINTING_RANGE_MAX
, TA_INCREASE_X_HEIGHT
);
352 " --graphicssystem=SYSTEM\n"
353 " select a different graphics system backend\n"
354 " instead of the default one\n"
355 " (possible values: `raster', `opengl')\n"
356 " --reverse set layout direction to right-to-left\n");
358 " --session=ID restore the application for the given ID\n"
359 " --style=STYLE set application GUI style\n"
360 " (possible values: motif, windows, platinum)\n"
361 " --stylesheet=SHEET apply the given Qt stylesheet\n"
362 " to the application widgets\n"
367 " --background=COLOR set the default background color\n"
368 " and an application palette\n"
369 " (light and dark shades are calculated)\n"
370 " --bg=COLOR same as --background\n"
371 " --btn=COLOR set the default button color\n"
372 " --button=COLOR same as --btn\n"
373 " --cmap use a private color map on an 8-bit display\n"
374 " --display=NAME use the given X-server display\n");
376 " --fg=COLOR set the default foreground color\n"
377 " --fn=FONTNAME set the application font\n"
378 " --font=FONTNAME same as --fn\n"
379 " --foreground=COLOR same as --fg\n"
380 " --geometry=GEOMETRY set the client geometry of first window\n"
381 " --im=SERVER set the X Input Method (XIM) server\n"
382 " --inputstyle=STYLE set X Input Method input style\n"
383 " (possible values: onthespot, overthespot,\n"
384 " offthespot, root)\n");
386 " --name=NAME set the application name\n"
387 " --ncols=COUNT limit the number of colors allocated\n"
388 " in the color cube on an 8-bit display,\n"
389 " if the application is using the\n"
390 " QApplication::ManyColor color specification\n"
391 " --title=TITLE set the application title (caption)\n"
392 " --visual=VISUAL force the application\n"
393 " to use the given visual on an 8-bit display\n"
394 " (only possible value: TrueColor)\n"
400 "The program accepts both TTF and TTC files as input.\n"
401 "Use option -i only if you have a legal permission to modify the font.\n"
402 "The used PPEM value for option -p is FUnits per em, normally 2048.\n"
403 "With option -s, use default values for standard stem width and height,\n"
404 "otherwise they are derived from script-specific characters\n"
405 "resembling the shape of character `o'.\n"
408 "A hint set contains the optimal hinting for a certain PPEM value;\n"
409 "the larger the hint set range (as given by options -l and -r),\n"
410 "the more hint sets get computed, usually increasing the output font size.\n"
411 "The `gasp' table of the output file always enables grayscale hinting\n"
412 "for all sizes (limited by option -G, which is handled in the bytecode).\n"
413 "Increasing the value of -G does not increase the output font size.\n"
416 "Options -f and -D take a four-letter string that identifies a script.\n"
417 "Option -f sets the script used as a fallback for glyphs that can't be\n"
418 "associated with a known script. By default, such glyphs are hinted;\n"
419 "if option -S is set, they are scaled only instead. Option -D sets the\n"
420 "default script for handling OpenType features.\n"
422 "Possible four-letter string values are\n"
424 const Tag_Names
* sn
= script_names
;
427 fprintf(handle
, " %s (%s)",
428 sn
->tag
, sn
->description
);
431 fprintf(handle
, ",\n");
434 fprintf(handle
, ".\n");
441 "A control instructions file contains entries of the form\n"
443 " [<font idx>] <script> <feature> @ <glyph ids>\n"
445 " [<font idx>] <glyph id> l|r <points> [(<left offset>,<right offset>)]\n"
447 " [<font idx>] <glyph id> n <points>\n"
449 " [<font idx>] <glyph id> t|p <points> [x <shift>] [y <shift>] @ <ppems>\n"
451 "<font idx> is the current subfont, <glyph id> is a glyph name or index,\n"
452 "<glyph ids> is a set of <glyph id>s, <shift> is a real number in px,\n"
453 "<points> and <ppems> are integer ranges as with option `-X'.\n"
455 "<script> and <feature> are four-letter tags that define a style\n"
456 "the <glyph ids> are assigned to; possible values for <script> are the same\n"
457 "as with option -D, possible values for <feature> are\n"
459 const Tag_Names
* fn
= feature_names
;
462 fprintf(handle
, " %s (%s)",
463 fn
->tag
, fn
->description
);
466 fprintf(handle
, ",\n");
469 fprintf(handle
, ".\n");
475 "`l' (`r') creates one-point segments with direction left (right).\n"
476 "<left offset> and <right offset> specify offsets (in font units)\n"
477 "relative to the corresponding points to give the segments a length.\n"
478 "`n' removes points from horizontal segments, making them `weak' points.\n"
479 "`t' (`p') applies delta exceptions to the given points before (after) IUP.\n"
481 "`#' starts a line comment, which gets ignored.\n"
482 "Empty lines are ignored, too.\n"
484 "Key letters `l', `r', `n', `p', `t', `x', and `y' have the verbose aliases\n"
485 "`left', `right', `nodir', `point', `touch', `xshift', and `yshift'.\n"
489 "A command-line version of this program is called `ttfautohint'.\n"
491 "A GUI version of this program is called `ttfautohintGUI'.\n"
494 "Report bugs to: freetype-devel@nongnu.org\n"
496 "ttfautohint home page: <http://www.freetype.org/ttfautohint>\n");
510 "ttfautohintGUI " VERSION
"\n"
512 "ttfautohint " VERSION
"\n"
514 "Copyright (C) 2011-2016 Werner Lemberg <wl@gnu.org>.\n"
515 "License: FreeType License (FTL) or GNU GPLv2.\n"
516 "This is free software: you are free to change and redistribute it.\n"
517 "There is NO WARRANTY, to the extent permitted by law.\n");
521 #endif // CONSOLE_OUTPUT
526 typedef const struct FT_error_
532 static FT_error FT_errors
[] =
534 #undef __FTERRORS_H__
535 #define FT_ERRORDEF(e, v, s) { e, s },
536 #define FT_ERROR_START_LIST {
537 #define FT_ERROR_END_LIST { 0, NULL } };
542 FT_get_error_message(FT_Error error
)
544 FT_error
* e
= FT_errors
;
546 while (e
->err_code
|| e
->err_msg
)
548 if (e
->err_code
== error
)
557 #define BUF_SIZE 0x10000
559 #define TTAG_TTFA FT_MAKE_TAG('T', 'T', 'F', 'A')
562 display_TTFA(FILE* in
)
564 FT_Byte buf
[BUF_SIZE
];
572 in_buf
= (FT_Byte
*)malloc(BUF_SIZE
);
575 fprintf(stderr
, "Can't allocate enough memory.\n");
579 while ((read_bytes
= fread(buf
, 1, BUF_SIZE
, in
)) > 0)
581 FT_Byte
* in_buf_new
= (FT_Byte
*)realloc(in_buf
, in_len
+ read_bytes
);
584 fprintf(stderr
, "Can't reallocate enough memory.\n");
590 memcpy(in_buf
+ in_len
, buf
, read_bytes
);
592 in_len
+= read_bytes
;
597 fprintf(stderr
, "Stream error while handling input font.\n");
605 error
= FT_Init_FreeType(&library
);
608 fprintf(stderr
, "Can't initialize FreeType library:\n"
609 "%s\n", FT_get_error_message(error
));
613 // in a TTC, a `TTFA' table is part of the first subfont,
614 // thus we can simply pass 0 as the face index
615 error
= FT_New_Memory_Face(library
, in_buf
, (FT_Long
)in_len
, 0, &face
);
618 fprintf(stderr
, "Can't open input font:\n"
619 "%s\n", FT_get_error_message(error
));
624 FT_ULong ttfa_len
= 0;
626 error
= FT_Load_Sfnt_Table(face
, TTAG_TTFA
, 0, NULL
, &ttfa_len
);
629 fprintf(stderr
, "No `TTFA' table in font.\n");
633 ttfa_buf
= (FT_Byte
*)malloc(ttfa_len
);
636 fprintf(stderr
, "Can't allocate enough memory.\n");
640 error
= FT_Load_Sfnt_Table(face
, TTAG_TTFA
, 0, ttfa_buf
, &ttfa_len
);
643 fprintf(stderr
, "Error loading `TTFA' table:\n"
644 "%s\n", FT_get_error_message(error
));
648 fprintf(stdout
, "%s", ttfa_buf
);
652 FT_Done_FreeType(library
);
668 int hinting_range_min
= 0;
669 int hinting_range_max
= 0;
670 int hinting_limit
= 0;
671 int increase_x_height
= 0;
672 int fallback_stem_width
= 0;
674 bool have_hinting_range_min
= false;
675 bool have_hinting_range_max
= false;
676 bool have_hinting_limit
= false;
677 bool have_increase_x_height
= false;
678 bool have_fallback_stem_width
= false;
680 bool gray_strong_stem_width
= false;
681 bool gdi_cleartype_strong_stem_width
= true;
682 bool dw_cleartype_strong_stem_width
= false;
684 bool ignore_restrictions
= false;
685 bool windows_compatibility
= false;
686 bool adjust_subglyphs
= false;
687 bool hint_composites
= false;
688 bool no_info
= false;
689 bool detailed_info
= false;
690 bool TTFA_info
= false;
692 bool show_TTFA_info
= false;
695 bool fallback_scaling
= false;
697 const char* default_script
= NULL
;
698 bool have_default_script
= false;
699 const char* fallback_script
= NULL
;
700 bool have_fallback_script
= false;
701 const char* x_height_snapping_exceptions_string
= NULL
;
702 bool have_x_height_snapping_exceptions_string
= false;
703 const char* family_suffix
= NULL
;
704 bool have_family_suffix
= false;
711 TA_Progress_Func progress_func
= NULL
;
712 TA_Error_Func err_func
= err
;
713 TA_Info_Func info_func
= info
;
714 TA_Info_Post_Func info_post_func
= info_post
;
716 const char* control_name
= NULL
;
719 // For real numbers (both parsing and displaying) we only use `.' as the
720 // decimal separator; similarly, we don't want localized formats like a
721 // thousands separator for any number.
722 setlocale(LC_NUMERIC
, "C");
724 // make GNU, Qt, and X11 command line options look the same;
725 // we allow `--foo=bar', `--foo bar', `-foo=bar', `-foo bar',
726 // and short options specific to ttfautohint
728 // set up a new argument string
729 vector
<string
> new_arg_string
;
730 new_arg_string
.push_back(argv
[0]);
734 // use pseudo short options for long-only options
737 PASS_THROUGH
= CHAR_MAX
+ 1,
742 static struct option long_options
[] =
744 {"help", no_argument
, NULL
, 'h'},
746 {"help-all", no_argument
, NULL
, HELP_ALL_OPTION
},
749 // ttfautohint options
750 {"adjust-subglyphs", no_argument
, NULL
, 'p'},
751 {"composites", no_argument
, NULL
, 'c'},
753 {"control-file", required_argument
, NULL
, 'm'},
754 {"debug", no_argument
, NULL
, DEBUG_OPTION
},
756 {"default-script", required_argument
, NULL
, 'D'},
757 {"dehint", no_argument
, NULL
, 'd'},
758 {"detailed-info", no_argument
, NULL
, 'I'},
759 {"fallback-scaling", no_argument
, NULL
, 'S'},
760 {"fallback-script", required_argument
, NULL
, 'f'},
761 {"fallback-stem-width", required_argument
, NULL
, 'H'},
762 {"family-suffix", required_argument
, NULL
, 'F'},
763 {"hinting-limit", required_argument
, NULL
, 'G'},
764 {"hinting-range-max", required_argument
, NULL
, 'r'},
765 {"hinting-range-min", required_argument
, NULL
, 'l'},
766 {"ignore-restrictions", no_argument
, NULL
, 'i'},
767 {"increase-x-height", required_argument
, NULL
, 'x'},
768 {"no-info", no_argument
, NULL
, 'n'},
769 {"pre-hinting", no_argument
, NULL
, 'p'},
770 {"strong-stem-width", required_argument
, NULL
, 'w'},
771 {"symbol", no_argument
, NULL
, 's'},
772 {"ttfa-table", no_argument
, NULL
, 't'},
774 {"ttfa-info", no_argument
, NULL
, 'T'},
776 {"verbose", no_argument
, NULL
, 'v'},
777 {"version", no_argument
, NULL
, 'V'},
778 {"windows-compatibility", no_argument
, NULL
, 'W'},
779 {"x-height-snapping-exceptions", required_argument
, NULL
, 'X'},
782 {"graphicssystem", required_argument
, NULL
, PASS_THROUGH
},
783 {"reverse", no_argument
, NULL
, PASS_THROUGH
},
784 {"session", required_argument
, NULL
, PASS_THROUGH
},
785 {"style", required_argument
, NULL
, PASS_THROUGH
},
786 {"stylesheet", required_argument
, NULL
, PASS_THROUGH
},
789 {"background", required_argument
, NULL
, PASS_THROUGH
},
790 {"bg", required_argument
, NULL
, PASS_THROUGH
},
791 {"btn", required_argument
, NULL
, PASS_THROUGH
},
792 {"button", required_argument
, NULL
, PASS_THROUGH
},
793 {"cmap", no_argument
, NULL
, PASS_THROUGH
},
794 {"display", required_argument
, NULL
, PASS_THROUGH
},
795 {"fg", required_argument
, NULL
, PASS_THROUGH
},
796 {"fn", required_argument
, NULL
, PASS_THROUGH
},
797 {"font", required_argument
, NULL
, PASS_THROUGH
},
798 {"foreground", required_argument
, NULL
, PASS_THROUGH
},
799 {"geometry", required_argument
, NULL
, PASS_THROUGH
},
800 {"im", required_argument
, NULL
, PASS_THROUGH
},
801 {"inputstyle", required_argument
, NULL
, PASS_THROUGH
},
802 {"name", required_argument
, NULL
, PASS_THROUGH
},
803 {"ncols", required_argument
, NULL
, PASS_THROUGH
},
804 {"title", required_argument
, NULL
, PASS_THROUGH
},
805 {"visual", required_argument
, NULL
, PASS_THROUGH
},
811 int c
= getopt_long_only(argc
, argv
,
813 "cdD:f:F:G:hH:iIl:npr:sStvVw:Wx:X:",
815 "cdD:f:F:G:hH:iIl:m:npr:sStTvVw:Wx:X:",
817 long_options
, &option_index
);
824 hint_composites
= true;
832 default_script
= optarg
;
833 have_default_script
= true;
837 fallback_script
= optarg
;
838 have_fallback_script
= true;
842 family_suffix
= optarg
;
843 have_family_suffix
= true;
847 hinting_limit
= atoi(optarg
);
848 have_hinting_limit
= true;
852 #ifdef CONSOLE_OUTPUT
853 show_help(false, false);
858 fallback_stem_width
= atoi(optarg
);
859 have_fallback_stem_width
= true;
863 ignore_restrictions
= true;
867 detailed_info
= true;
872 hinting_range_min
= atoi(optarg
);
873 have_hinting_range_min
= true;
878 control_name
= optarg
;
884 detailed_info
= false;
888 adjust_subglyphs
= true;
892 hinting_range_max
= atoi(optarg
);
893 have_hinting_range_max
= true;
901 fallback_scaling
= true;
910 show_TTFA_info
= true;
914 progress_func
= progress
;
919 #ifdef CONSOLE_OUTPUT
925 gray_strong_stem_width
= strchr(optarg
, 'g') ? true : false;
926 gdi_cleartype_strong_stem_width
= strchr(optarg
, 'G') ? true : false;
927 dw_cleartype_strong_stem_width
= strchr(optarg
, 'D') ? true : false;
931 windows_compatibility
= true;
935 increase_x_height
= atoi(optarg
);
936 have_increase_x_height
= true;
940 x_height_snapping_exceptions_string
= optarg
;
941 have_x_height_snapping_exceptions_string
= true;
951 case HELP_ALL_OPTION
:
952 #ifdef CONSOLE_OUTPUT
953 show_help(true, false);
960 // append argument with proper syntax for Qt
963 arg
+= long_options
[option_index
].name
;
965 new_arg_string
.push_back(arg
);
967 new_arg_string
.push_back(optarg
);
978 // -d makes ttfautohint ignore all other hinting options
979 have_default_script
= false;
980 have_fallback_script
= false;
981 have_fallback_stem_width
= false;
982 have_hinting_range_max
= false;
983 have_hinting_range_min
= false;
984 have_hinting_limit
= false;
985 have_increase_x_height
= false;
986 have_x_height_snapping_exceptions_string
= false;
992 // -T makes ttfautohint ignore even more options
993 have_default_script
= false;
994 have_fallback_script
= false;
995 have_fallback_stem_width
= false;
996 have_hinting_range_max
= false;
997 have_hinting_range_min
= false;
998 have_hinting_limit
= false;
999 have_increase_x_height
= false;
1000 have_x_height_snapping_exceptions_string
= false;
1001 have_family_suffix
= false;
1006 if (!have_default_script
)
1007 default_script
= "latn";
1008 if (!have_fallback_script
)
1009 fallback_script
= "none";
1010 if (!have_hinting_range_min
)
1011 hinting_range_min
= TA_HINTING_RANGE_MIN
;
1012 if (!have_hinting_range_max
)
1013 hinting_range_max
= TA_HINTING_RANGE_MAX
;
1014 if (!have_hinting_limit
)
1015 hinting_limit
= TA_HINTING_LIMIT
;
1016 if (!have_increase_x_height
)
1017 increase_x_height
= TA_INCREASE_X_HEIGHT
;
1018 if (!have_x_height_snapping_exceptions_string
)
1019 x_height_snapping_exceptions_string
= "";
1020 if (!have_fallback_stem_width
)
1021 fallback_stem_width
= 0; /* redundant, but avoids a compiler warning */
1022 if (!have_family_suffix
)
1027 if (!isatty(fileno(stderr
)) && !debug
)
1028 setvbuf(stderr
, (char*)NULL
, _IONBF
, BUFSIZ
);
1030 if (hinting_range_min
< 2)
1032 fprintf(stderr
, "The hinting range minimum must be at least 2\n");
1035 if (hinting_range_max
< hinting_range_min
)
1037 fprintf(stderr
, "The hinting range maximum must not be smaller"
1038 " than the minimum (%d)\n",
1042 if (hinting_limit
!= 0 && hinting_limit
< hinting_range_max
)
1044 fprintf(stderr
, "A non-zero hinting limit must not be smaller"
1045 " than the hinting range maximum (%d)\n",
1049 if (increase_x_height
!= 0 && increase_x_height
< 6)
1051 fprintf(stderr
, "A non-zero x height increase limit"
1052 " must be larger than or equal to 6\n");
1055 if (have_fallback_stem_width
&& fallback_stem_width
<= 0)
1057 fprintf(stderr
, "The fallback stem width"
1058 " must be a positive integer\n");
1062 if (have_default_script
)
1064 const Tag_Names
* sn
;
1066 for (sn
= script_names
; sn
->tag
; sn
++)
1067 if (!strcmp(default_script
, sn
->tag
))
1071 fprintf(stderr
, "Unknown script tag `%s'\n", default_script
);
1076 if (have_fallback_script
)
1078 const Tag_Names
* sn
;
1080 for (sn
= script_names
; sn
->tag
; sn
++)
1081 if (!strcmp(fallback_script
, sn
->tag
))
1085 fprintf(stderr
, "Unknown script tag `%s'\n", fallback_script
);
1091 && have_fallback_stem_width
1092 && fallback_scaling
)
1094 "Warning: Setting a fallback stem width for a symbol font\n"
1095 " with fallback scaling only has no effect\n");
1097 if (const char* pos
= check_family_suffix(family_suffix
))
1100 "Invalid character in family suffix:\n"
1104 int(pos
- family_suffix
+ 1), "^");
1108 int num_args
= argc
- optind
;
1111 show_help(false, true);
1116 in
= fopen(argv
[optind
], "rb");
1120 "The following error occurred while opening font `%s':\n"
1123 argv
[optind
], strerror(errno
));
1129 if (isatty(fileno(stdin
)))
1130 show_help(false, true);
1136 display_TTFA(in
); // this function doesn't return
1142 if (!strcmp(argv
[optind
], argv
[optind
+ 1]))
1144 fprintf(stderr
, "Input and output file names must not be identical\n");
1148 out
= fopen(argv
[optind
+ 1], "wb");
1152 "The following error occurred while opening font `%s':\n"
1155 argv
[optind
+ 1], strerror(errno
));
1161 if (isatty(fileno(stdout
)))
1162 show_help(false, true);
1166 FILE* control
= NULL
;
1169 control
= fopen(control_name
, "r");
1173 "The following error occurred while open control file `%s':\n"
1176 control_name
, strerror(errno
));
1183 Progress_Data progress_data
= {-1, 1, 0};
1184 Error_Data error_data
= {control_name
};
1185 Info_Data info_data
;
1187 if (!*family_suffix
)
1188 info_post_func
= NULL
;
1190 info_data
.no_info
= no_info
;
1191 info_data
.detailed_info
= detailed_info
;
1192 info_data
.info_string
= NULL
; // must be deallocated after use
1193 info_data
.info_string_wide
= NULL
; // must be deallocated after use
1194 info_data
.info_string_len
= 0;
1195 info_data
.info_string_wide_len
= 0;
1197 info_data
.control_name
= control_name
;
1199 info_data
.hinting_range_min
= hinting_range_min
;
1200 info_data
.hinting_range_max
= hinting_range_max
;
1201 info_data
.hinting_limit
= hinting_limit
;
1203 info_data
.gray_strong_stem_width
= gray_strong_stem_width
;
1204 info_data
.gdi_cleartype_strong_stem_width
= gdi_cleartype_strong_stem_width
;
1205 info_data
.dw_cleartype_strong_stem_width
= dw_cleartype_strong_stem_width
;
1207 info_data
.windows_compatibility
= windows_compatibility
;
1208 info_data
.adjust_subglyphs
= adjust_subglyphs
;
1209 info_data
.hint_composites
= hint_composites
;
1210 info_data
.increase_x_height
= increase_x_height
;
1211 info_data
.x_height_snapping_exceptions_string
= x_height_snapping_exceptions_string
;
1212 info_data
.family_suffix
= family_suffix
;
1213 info_data
.family_data_head
= NULL
;
1214 info_data
.fallback_stem_width
= fallback_stem_width
;
1215 info_data
.symbol
= symbol
;
1216 info_data
.fallback_scaling
= fallback_scaling
;
1217 info_data
.TTFA_info
= TTFA_info
;
1219 strncpy(info_data
.default_script
,
1221 sizeof (info_data
.default_script
));
1222 strncpy(info_data
.fallback_script
,
1224 sizeof (info_data
.fallback_script
));
1226 info_data
.dehint
= dehint
;
1230 int ret
= build_version_string(&info_data
);
1232 fprintf(stderr
, "Warning: Can't allocate memory"
1233 " for ttfautohint options string in `name' table\n");
1235 fprintf(stderr
, "Warning: ttfautohint options string"
1236 " in `name' table too long\n");
1245 TTF_autohint("in-file, out-file, control-file,"
1246 "hinting-range-min, hinting-range-max, hinting-limit,"
1247 "gray-strong-stem-width, gdi-cleartype-strong-stem-width,"
1248 "dw-cleartype-strong-stem-width,"
1249 "progress-callback, progress-callback-data,"
1250 "error-callback, error-callback-data,"
1251 "info-callback, info-post-callback, info-callback-data,"
1252 "ignore-restrictions, windows-compatibility,"
1253 "adjust-subglyphs, hint-composites,"
1254 "increase-x-height, x-height-snapping-exceptions,"
1255 "fallback-stem-width, default-script,"
1256 "fallback-script, fallback-scaling,"
1257 "symbol, dehint, debug, TTFA-info",
1259 hinting_range_min
, hinting_range_max
, hinting_limit
,
1260 gray_strong_stem_width
, gdi_cleartype_strong_stem_width
,
1261 dw_cleartype_strong_stem_width
,
1262 progress_func
, &progress_data
,
1263 err_func
, &error_data
,
1264 info_func
, info_post_func
, &info_data
,
1265 ignore_restrictions
, windows_compatibility
,
1266 adjust_subglyphs
, hint_composites
,
1267 increase_x_height
, x_height_snapping_exceptions_string
,
1268 fallback_stem_width
, default_script
,
1269 fallback_script
, fallback_scaling
,
1270 symbol
, dehint
, debug
, TTFA_info
);
1274 free(info_data
.info_string
);
1275 free(info_data
.info_string_wide
);
1285 exit(error
? EXIT_FAILURE
: EXIT_SUCCESS
);
1287 return 0; // never reached
1291 int new_argc
= (int)new_arg_string
.size();
1292 char** new_argv
= new char*[new_argc
];
1294 // construct new argc and argv variables from collected data
1295 for (int i
= 0; i
< new_argc
; i
++)
1296 new_argv
[i
] = const_cast<char*>(new_arg_string
[i
].data());
1298 QApplication
app(new_argc
, new_argv
);
1299 app
.setApplicationName("TTFautohint");
1300 app
.setApplicationVersion(VERSION
);
1301 app
.setOrganizationName("FreeType");
1302 app
.setOrganizationDomain("freetype.org");
1304 bool alternative_layout
= false;
1306 // Display the window off the screen -- to get proper window dimensions
1307 // including the frame, the window manager must have a chance to
1310 // We don't want to change the default window positioning algorithm of
1311 // the platform's window manager, so we create the main GUI window
1314 // The original idea, however, was to simply move the off-screen window
1315 // back to the screen with
1317 // gui.move(100, 100);
1318 // gui.setAttribute(Qt::WA_Moved, false);
1321 // (unsetting the `WA_Moved' attribute makes the window manager handle
1322 // the previous call to `move' as a position suggestion instead of a
1323 // request). Unfortuntely, there seems to be a bug in Qt 4.8.4 which
1324 // prevents any effect of unsetting `WA_Moved' if `show' has already
1327 Main_GUI
dummy(alternative_layout
,
1328 hinting_range_min
, hinting_range_max
, hinting_limit
,
1329 gray_strong_stem_width
, gdi_cleartype_strong_stem_width
,
1330 dw_cleartype_strong_stem_width
, increase_x_height
,
1331 x_height_snapping_exceptions_string
, fallback_stem_width
,
1332 ignore_restrictions
, windows_compatibility
, adjust_subglyphs
,
1333 hint_composites
, no_info
, detailed_info
,
1334 default_script
, fallback_script
, fallback_scaling
,
1335 family_suffix
, symbol
, dehint
, TTFA_info
);
1337 dummy
.move(-50000, -50000);
1340 // if the vertical size of our window is too large,
1341 // select a horizontal layout
1342 QRect
screen(QApplication::desktop()->availableGeometry());
1343 if (dummy
.frameGeometry().height() > screen
.height())
1344 alternative_layout
= true;
1347 Main_GUI
gui(alternative_layout
,
1348 hinting_range_min
, hinting_range_max
, hinting_limit
,
1349 gray_strong_stem_width
, gdi_cleartype_strong_stem_width
,
1350 dw_cleartype_strong_stem_width
, increase_x_height
,
1351 x_height_snapping_exceptions_string
, fallback_stem_width
,
1352 ignore_restrictions
, windows_compatibility
, adjust_subglyphs
,
1353 hint_composites
, no_info
, detailed_info
,
1354 default_script
, fallback_script
, fallback_scaling
,
1355 family_suffix
, symbol
, dehint
, TTFA_info
);