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>
43 #include <ttfautohint.h>
51 typedef struct Progress_Data_
60 progress(long curr_idx
,
66 Progress_Data
* data
= (Progress_Data
*)user
;
68 if (num_sfnts
> 1 && curr_sfnt
!= data
->last_sfnt
)
70 fprintf(stderr
, "subfont %ld of %ld\n", curr_sfnt
+ 1, num_sfnts
);
71 data
->last_sfnt
= curr_sfnt
;
77 fprintf(stderr
, " %ld glyphs\n"
82 // print progress approx. every 10%
83 int curr_percent
= curr_idx
* 100 / num_glyphs
;
84 int curr_diff
= curr_percent
- data
->last_percent
;
88 fprintf(stderr
, " %d%%", curr_percent
);
89 data
->last_percent
= curr_percent
- curr_percent
% 10;
92 if (curr_idx
+ 1 == num_glyphs
)
93 fprintf(stderr
, "\n");
102 #ifdef CONSOLE_OUTPUT
111 FILE* handle
= is_error
? stderr
: stdout
;
115 "Usage: ttfautohintGUI [OPTION]...\n"
116 "A GUI application to replace hints in a TrueType font.\n"
118 "Usage: ttfautohint [OPTION]... IN-FILE OUT-FILE\n"
119 "Replace hints in TrueType font IN-FILE and write output to OUT-FILE.\n"
121 "The new hints are based on FreeType's autohinter.\n"
123 "This program is a simple front-end to the `ttfautohint' library.\n"
127 "Long options can be given with one or two dashes,\n"
128 "and with and without equal sign between option and argument.\n"
129 "This means that the following forms are acceptable:\n"
130 "`-foo=bar', `--foo=bar', `-foo bar', `--foo bar'.\n"
132 "Mandatory arguments to long options are mandatory for short options too.\n"
134 "Options not related to Qt or X11 set default values.\n"
141 " -f, --latin-fallback set fallback script to latin\n"
142 " -G, --hinting-limit=N switch off hinting above this PPEM value\n"
143 " (default: %d); value 0 means no limit\n"
144 " -h, --help display this help and exit\n"
146 " --help-all show Qt and X11 specific options also\n"
148 " -i, --ignore-permissions override font license restrictions\n"
149 " -l, --hinting-range-min=N the minimum PPEM value for hint sets\n"
151 " -n --no-info don't add ttfautohint info\n"
152 " to the version string(s) in the `name' table\n"
153 " -p, --pre-hinting apply original hints in advance\n",
154 TA_HINTING_LIMIT
, TA_HINTING_RANGE_MIN
);
156 " -r, --hinting-range-max=N the maximum PPEM value for hint sets\n"
158 " -s, --symbol input is symbol font\n"
159 " -v, --verbose show progress information\n"
160 " -V, --version print version information and exit\n"
161 " -x, --increase-x-height increase x height for small sizes\n"
162 " -X, --x-height-snapping-exceptions=STRING\n"
163 " specify a comma-separated list of\n"
164 " x-height snapping exceptions\n"
166 TA_HINTING_RANGE_MAX
);
173 " --graphicssystem=SYSTEM\n"
174 " select a different graphics system backend\n"
175 " instead of the default one\n"
176 " (possible values: `raster', `opengl')\n"
177 " --reverse set layout direction to right-to-left\n");
179 " --session=ID restore the application for the given ID\n"
180 " --style=STYLE set application GUI style\n"
181 " (possible values: motif, windows, platinum)\n"
182 " --stylesheet=SHEET apply the given Qt stylesheet\n"
183 " to the application widgets\n"
188 " --background=COLOR set the default background color\n"
189 " and an application palette\n"
190 " (light and dark shades are calculated)\n"
191 " --bg=COLOR same as --background\n"
192 " --btn=COLOR set the default button color\n"
193 " --button=COLOR same as --btn\n"
194 " --cmap use a private color map on an 8-bit display\n"
195 " --display=NAME use the given X-server display\n");
197 " --fg=COLOR set the default foreground color\n"
198 " --fn=FONTNAME set the application font\n"
199 " --font=FONTNAME same as --fn\n"
200 " --foreground=COLOR same as --fg\n"
201 " --geometry=GEOMETRY set the client geometry of first window\n"
202 " --im=SERVER set the X Input Method (XIM) server\n"
203 " --inputstyle=STYLE set X Input Method input style\n"
204 " (possible values: onthespot, overthespot,\n"
205 " offthespot, root)\n");
207 " --name=NAME set the application name\n"
208 " --ncols=COUNT limit the number of colors allocated\n"
209 " in the color cube on an 8-bit display,\n"
210 " if the application is using the\n"
211 " QApplication::ManyColor color specification\n"
212 " --title=TITLE set the application title (caption)\n"
213 " --visual=VISUAL force the application\n"
214 " to use the given visual on an 8-bit display\n"
215 " (only possible value: TrueColor)\n"
221 "The program accepts both TTF and TTC files as input.\n"
222 "Use option -i only if you have a legal permission to modify the font.\n"
223 "If option -f is not set, glyphs not in the latin range stay unhinted.\n"
224 "The used PPEM value for option -p is FUnits per em, normally 2048.\n"
225 "With option -s, use default values for standard stem width and height,\n"
226 "otherwise they are derived from latin character `o'.\n"
229 "A hint set contains the optimal hinting for a certain PPEM value;\n"
230 "the larger the hint set range, the more hint sets get computed,\n"
231 "usually increasing the output font size. Note, however,\n"
232 "that the `gasp' table of the output file enables grayscale hinting\n"
233 "for all sizes (limited by option -G which is handled in the bytecode).\n"
237 "A command-line version of this program is called `ttfautohint'.\n"
239 "A GUI version of this program is called `ttfautohintGUI'.\n"
242 "Report bugs to: freetype-devel@nongnu.org\n"
243 "ttfautohint home page: <http://www.freetype.org/ttfautohint>\n");
257 "ttfautohintGUI " VERSION
"\n"
259 "ttfautohint " VERSION
"\n"
261 "Copyright (C) 2011-2012 Werner Lemberg <wl@gnu.org>.\n"
262 "License: FreeType License (FTL) or GNU GPLv2.\n"
263 "This is free software: you are free to change and redistribute it.\n"
264 "There is NO WARRANTY, to the extent permitted by law.\n");
268 #endif // CONSOLE_OUTPUT
275 int hinting_range_min
= 0;
276 int hinting_range_max
= 0;
277 int hinting_limit
= 0;
278 bool have_hinting_range_min
= false;
279 bool have_hinting_range_max
= false;
280 bool have_hinting_limit
= false;
282 bool ignore_permissions
= false;
283 bool pre_hinting
= false;
284 bool increase_x_height
= false;
285 bool no_info
= false;
286 int latin_fallback
= 0; // leave it as int; this probably gets extended
290 TA_Progress_Func progress_func
= NULL
;
291 TA_Info_Func info_func
= info
;
294 // make GNU, Qt, and X11 command line options look the same;
295 // we allow `--foo=bar', `--foo bar', `-foo=bar', `-foo bar',
296 // and short options specific to ttfautohint
298 // set up a new argument string
299 vector
<string
> new_arg_string
;
300 new_arg_string
.push_back(argv
[0]);
304 // use pseudo short options for long-only options
307 PASS_THROUGH
= CHAR_MAX
+ 1,
311 static struct option long_options
[] =
313 {"help", no_argument
, NULL
, 'h'},
315 {"help-all", no_argument
, NULL
, HELP_ALL_OPTION
},
318 // ttfautohint options
319 {"hinting-limit", required_argument
, NULL
, 'G'},
320 {"hinting-range-max", required_argument
, NULL
, 'r'},
321 {"hinting-range-min", required_argument
, NULL
, 'l'},
322 {"ignore-permissions", no_argument
, NULL
, 'i'},
323 {"increase-x-height", no_argument
, NULL
, 'x'},
324 {"latin-fallback", no_argument
, NULL
, 'f'},
325 {"no-info", no_argument
, NULL
, 'n'},
326 {"pre-hinting", no_argument
, NULL
, 'p'},
327 {"symbol", no_argument
, NULL
, 's'},
328 {"verbose", no_argument
, NULL
, 'v'},
329 {"version", no_argument
, NULL
, 'V'},
330 {"x-height-snapping-exceptions", required_argument
, NULL
, 'X'},
333 {"graphicssystem", required_argument
, NULL
, PASS_THROUGH
},
334 {"reverse", no_argument
, NULL
, PASS_THROUGH
},
335 {"session", required_argument
, NULL
, PASS_THROUGH
},
336 {"style", required_argument
, NULL
, PASS_THROUGH
},
337 {"stylesheet", required_argument
, NULL
, PASS_THROUGH
},
340 {"background", required_argument
, NULL
, PASS_THROUGH
},
341 {"bg", required_argument
, NULL
, PASS_THROUGH
},
342 {"btn", required_argument
, NULL
, PASS_THROUGH
},
343 {"button", required_argument
, NULL
, PASS_THROUGH
},
344 {"cmap", no_argument
, NULL
, PASS_THROUGH
},
345 {"display", required_argument
, NULL
, PASS_THROUGH
},
346 {"fg", required_argument
, NULL
, PASS_THROUGH
},
347 {"fn", required_argument
, NULL
, PASS_THROUGH
},
348 {"font", required_argument
, NULL
, PASS_THROUGH
},
349 {"foreground", required_argument
, NULL
, PASS_THROUGH
},
350 {"geometry", required_argument
, NULL
, PASS_THROUGH
},
351 {"im", required_argument
, NULL
, PASS_THROUGH
},
352 {"inputstyle", required_argument
, NULL
, PASS_THROUGH
},
353 {"name", required_argument
, NULL
, PASS_THROUGH
},
354 {"ncols", required_argument
, NULL
, PASS_THROUGH
},
355 {"title", required_argument
, NULL
, PASS_THROUGH
},
356 {"visual", required_argument
, NULL
, PASS_THROUGH
},
362 int c
= getopt_long_only(argc
, argv
, "fG:hil:npr:stVvxX:",
363 long_options
, &option_index
);
374 hinting_limit
= atoi(optarg
);
375 have_hinting_limit
= true;
379 #ifdef CONSOLE_OUTPUT
380 show_help(false, false);
385 ignore_permissions
= true;
389 hinting_range_min
= atoi(optarg
);
390 have_hinting_range_min
= true;
402 hinting_range_max
= atoi(optarg
);
403 have_hinting_range_max
= true;
412 progress_func
= progress
;
417 #ifdef CONSOLE_OUTPUT
423 increase_x_height
= true;
427 #ifdef CONSOLE_OUTPUT
428 fprintf(stderr
, "Option `-x' not implemented yet\n");
432 case HELP_ALL_OPTION
:
433 #ifdef CONSOLE_OUTPUT
434 show_help(true, false);
440 // append argument with proper syntax for Qt
443 arg
+= long_options
[option_index
].name
;
445 new_arg_string
.push_back(arg
);
447 new_arg_string
.push_back(optarg
);
456 if (!have_hinting_range_min
)
457 hinting_range_min
= TA_HINTING_RANGE_MIN
;
458 if (!have_hinting_range_max
)
459 hinting_range_max
= TA_HINTING_RANGE_MAX
;
460 if (!have_hinting_limit
)
461 hinting_limit
= TA_HINTING_LIMIT
;
465 if (hinting_range_min
< 2)
467 fprintf(stderr
, "The hinting range minimum must be at least 2\n");
470 if (hinting_range_max
< hinting_range_min
)
472 fprintf(stderr
, "The hinting range maximum must not be smaller"
473 " than the minimum (%d)\n",
477 if (hinting_limit
!= 0 && hinting_limit
< hinting_range_max
)
479 fprintf(stderr
, "A non-zero hinting limit must not be smaller"
480 " than the hinting range maximum (%d)\n",
485 // on the console we need in and out file arguments
486 if (argc
- optind
!= 2)
487 show_help(false, true);
489 FILE* in
= fopen(argv
[optind
], "rb");
492 fprintf(stderr
, "The following error occurred while opening font `%s':\n"
495 argv
[optind
], strerror(errno
));
499 FILE* out
= fopen(argv
[optind
+ 1], "wb");
502 fprintf(stderr
, "The following error occurred while opening font `%s':\n"
505 argv
[optind
+ 1], strerror(errno
));
509 unsigned char version_data
[128];
510 unsigned char version_data_wide
[256];
512 const unsigned char* error_string
;
513 Progress_Data progress_data
= {-1, 1, 0};
520 info_data
.data
= version_data
;
521 info_data
.data_wide
= version_data_wide
;
523 info_data
.hinting_range_min
= hinting_range_min
;
524 info_data
.hinting_range_max
= hinting_range_max
;
525 info_data
.hinting_limit
= hinting_limit
;
527 info_data
.pre_hinting
= pre_hinting
;
528 info_data
.increase_x_height
= increase_x_height
;
529 info_data
.latin_fallback
= latin_fallback
;
530 info_data
.symbol
= symbol
;
532 build_version_string(&info_data
);
536 TTF_autohint("in-file, out-file,"
537 "hinting-range-min, hinting-range-max, hinting-limit,"
539 "progress-callback, progress-callback-data,"
540 "info-callback, info-callback-data,"
541 "ignore-permissions, pre-hinting, increase-x-height,"
542 "fallback-script, symbol",
544 hinting_range_min
, hinting_range_max
, hinting_limit
,
546 progress_func
, &progress_data
,
547 info_func
, &info_data
,
548 ignore_permissions
, pre_hinting
, increase_x_height
,
549 latin_fallback
, symbol
);
553 if (error
== TA_Err_Invalid_FreeType_Version
)
555 "FreeType version 2.4.5 or higher is needed.\n"
556 "Perhaps using a wrong FreeType DLL?\n");
557 else if (error
== TA_Err_Already_Processed
)
559 "This font has already been processed with ttfautohint.\n");
560 else if (error
== TA_Err_Missing_Legal_Permission
)
562 "Bit 1 in the `fsType' field of the `OS/2' table is set:\n"
563 "This font must not be modified"
564 " without permission of the legal owner.\n"
565 "Use command line option `-i' to continue"
566 " if you have such a permission.\n");
567 else if (error
== TA_Err_Missing_Unicode_CMap
)
569 "No Unicode character map.\n");
570 else if (error
== TA_Err_Missing_Glyph
)
572 "No glyph for the key character"
573 " to derive standard width and height.\n"
574 "For the latin script, this key character is `o' (U+006F).\n");
577 "Error code `0x%02x' while autohinting font:\n"
578 " %s\n", error
, error_string
);
587 return 0; // never reached
591 int new_argc
= new_arg_string
.size();
592 char** new_argv
= new char*[new_argc
];
594 // construct new argc and argv variables from collected data
595 for (int i
= 0; i
< new_argc
; i
++)
596 new_argv
[i
] = const_cast<char*>(new_arg_string
[i
].data());
598 QApplication
app(new_argc
, new_argv
);
599 app
.setApplicationName("TTFautohint");
600 app
.setApplicationVersion(VERSION
);
601 app
.setOrganizationName("FreeType");
602 app
.setOrganizationDomain("freetype.org");
604 Main_GUI
gui(hinting_range_min
, hinting_range_max
, hinting_limit
,
605 ignore_permissions
, pre_hinting
, increase_x_height
,
606 no_info
, latin_fallback
, symbol
);