4 * Copyright (C) 2011-2014 by Werner Lemberg.
6 * This file is part of the ttfautohint library, and may only be used,
7 * modified, and distributed under the terms given in `COPYING'. By
8 * continuing to use, modify, or distribute this file you indicate that you
9 * have read `COPYING' and understand and accept it fully.
11 * The file `COPYING' mentioned in the previous paragraph is distributed
12 * with the ttfautohint library.
16 /* This file needs FreeType 2.4.5 or newer. */
26 #define DUMP_COLUMN "33"
28 #define COMPARE(str) \
29 (len == (sizeof (str) - 1) \
30 && !strncmp(start, str, sizeof (str) - 1))
31 #define DUMPVAL(str, arg) \
32 fprintf(stderr, "%" DUMP_COLUMN "s = %ld\n", \
35 #define DUMPSTR(str, arg) \
36 fprintf(stderr, "%" DUMP_COLUMN "s = %s\n", \
39 #define DUMPSTRX(arg) \
40 fprintf(stderr, "%" DUMP_COLUMN "s %s\n", \
46 TA_sfnt_set_properties(SFNT
* sfnt
,
49 TA_FaceGlobals globals
= (TA_FaceGlobals
)sfnt
->face
->autohint
.data
;
52 globals
->increase_x_height
= font
->increase_x_height
;
57 TTF_autohint(const char* options
,
66 const char* error_string
= NULL
;
67 unsigned int errlinenum
= 0;
72 FILE* out_file
= NULL
;
74 const char* in_buf
= NULL
;
76 char** out_bufp
= NULL
;
77 size_t* out_lenp
= NULL
;
79 const unsigned char** error_stringp
= NULL
;
81 FT_Long hinting_range_min
= -1;
82 FT_Long hinting_range_max
= -1;
83 FT_Long hinting_limit
= -1;
84 FT_Long increase_x_height
= -1;
86 const char* x_height_snapping_exceptions_string
= NULL
;
87 number_range
* x_height_snapping_exceptions
= NULL
;
89 FT_Long fallback_stem_width
= 0;
91 FT_Bool gray_strong_stem_width
= 0;
92 FT_Bool gdi_cleartype_strong_stem_width
= 1;
93 FT_Bool dw_cleartype_strong_stem_width
= 0;
95 TA_Progress_Func progress
= NULL
;
96 void* progress_data
= NULL
;
97 TA_Error_Func err
= NULL
;
98 void* err_data
= NULL
;
99 TA_Info_Func info
= NULL
;
100 void* info_data
= NULL
;
102 FT_Bool windows_compatibility
= 0;
103 FT_Bool ignore_restrictions
= 0;
104 FT_Bool adjust_subglyphs
= 0;
105 FT_Bool hint_composites
= 0;
108 const char* fallback_script_string
= NULL
;
109 const char* default_script_string
= NULL
;
110 TA_Style fallback_style
= TA_STYLE_NONE_DFLT
;
111 TA_Script default_script
= TA_SCRIPT_LATN
;
119 #define SCRIPT(s, S, d, h, sc1, sc2, sc3) #s,
121 const char* script_names
[] =
124 #include <ttfautohint-scripts.h>
129 if (!options
|| !*options
)
131 error
= FT_Err_Invalid_Argument
;
136 va_start(ap
, options
);
149 while (*op
&& *op
!= ',')
152 /* remove leading whitespace */
153 while (isspace(*start
))
156 /* check for empty option */
162 /* the `COMPARE' macro uses `len' and `start' */
164 /* handle options -- don't forget to update parameter dump below! */
165 if (COMPARE("adjust-subglyphs"))
166 adjust_subglyphs
= (FT_Bool
)va_arg(ap
, FT_Int
);
167 else if (COMPARE("debug"))
168 debug
= (FT_Bool
)va_arg(ap
, FT_Int
);
169 else if (COMPARE("default-script"))
170 default_script_string
= va_arg(ap
, const char*);
171 else if (COMPARE("dehint"))
172 dehint
= (FT_Bool
)va_arg(ap
, FT_Int
);
173 else if (COMPARE("dw-cleartype-strong-stem-width"))
174 dw_cleartype_strong_stem_width
= (FT_Bool
)va_arg(ap
, FT_Int
);
175 else if (COMPARE("error-callback"))
176 err
= va_arg(ap
, TA_Error_Func
);
177 else if (COMPARE("error-callback-data"))
178 err_data
= va_arg(ap
, void*);
179 else if (COMPARE("error-string"))
180 error_stringp
= va_arg(ap
, const unsigned char**);
181 else if (COMPARE("fallback-script"))
182 fallback_script_string
= va_arg(ap
, const char*);
183 else if (COMPARE("fallback-stem-width"))
184 fallback_stem_width
= (FT_Long
)va_arg(ap
, FT_UInt
);
185 else if (COMPARE("gdi-cleartype-strong-stem-width"))
186 gdi_cleartype_strong_stem_width
= (FT_Bool
)va_arg(ap
, FT_Int
);
187 else if (COMPARE("gray-strong-stem-width"))
188 gray_strong_stem_width
= (FT_Bool
)va_arg(ap
, FT_Int
);
189 else if (COMPARE("hinting-limit"))
190 hinting_limit
= (FT_Long
)va_arg(ap
, FT_UInt
);
191 else if (COMPARE("hinting-range-max"))
192 hinting_range_max
= (FT_Long
)va_arg(ap
, FT_UInt
);
193 else if (COMPARE("hinting-range-min"))
194 hinting_range_min
= (FT_Long
)va_arg(ap
, FT_UInt
);
195 else if (COMPARE("hint-composites"))
196 hint_composites
= (FT_Bool
)va_arg(ap
, FT_Int
);
197 else if (COMPARE("ignore-restrictions"))
198 ignore_restrictions
= (FT_Bool
)va_arg(ap
, FT_Int
);
199 else if (COMPARE("in-buffer"))
202 in_buf
= va_arg(ap
, const char*);
204 else if (COMPARE("in-buffer-len"))
207 in_len
= va_arg(ap
, size_t);
209 else if (COMPARE("in-file"))
211 in_file
= va_arg(ap
, FILE*);
215 else if (COMPARE("increase-x-height"))
216 increase_x_height
= (FT_Long
)va_arg(ap
, FT_UInt
);
217 else if (COMPARE("info-callback"))
218 info
= va_arg(ap
, TA_Info_Func
);
219 else if (COMPARE("info-callback-data"))
220 info_data
= va_arg(ap
, void*);
221 else if (COMPARE("out-buffer"))
224 out_bufp
= va_arg(ap
, char**);
226 else if (COMPARE("out-buffer-len"))
229 out_lenp
= va_arg(ap
, size_t*);
231 else if (COMPARE("out-file"))
233 out_file
= va_arg(ap
, FILE*);
237 else if (COMPARE("pre-hinting"))
238 adjust_subglyphs
= (FT_Bool
)va_arg(ap
, FT_Int
);
239 else if (COMPARE("progress-callback"))
240 progress
= va_arg(ap
, TA_Progress_Func
);
241 else if (COMPARE("progress-callback-data"))
242 progress_data
= va_arg(ap
, void*);
243 else if (COMPARE("symbol"))
244 symbol
= (FT_Bool
)va_arg(ap
, FT_Int
);
245 else if (COMPARE("windows-compatibility"))
246 windows_compatibility
= (FT_Bool
)va_arg(ap
, FT_Int
);
247 else if (COMPARE("x-height-snapping-exceptions"))
248 x_height_snapping_exceptions_string
= va_arg(ap
, const char*);
251 error
= TA_Err_Unknown_Argument
;
266 || (in_buf
&& in_len
)))
268 error
= FT_Err_Invalid_Argument
;
273 || (out_bufp
&& out_lenp
)))
275 error
= FT_Err_Invalid_Argument
;
279 font
= (FONT
*)calloc(1, sizeof (FONT
));
282 error
= FT_Err_Out_Of_Memory
;
289 if (hinting_range_min
>= 0 && hinting_range_min
< 2)
291 error
= FT_Err_Invalid_Argument
;
294 if (hinting_range_min
< 0)
295 hinting_range_min
= TA_HINTING_RANGE_MIN
;
297 if (hinting_range_max
>= 0 && hinting_range_max
< hinting_range_min
)
299 error
= FT_Err_Invalid_Argument
;
302 if (hinting_range_max
< 0)
303 hinting_range_max
= TA_HINTING_RANGE_MAX
;
305 /* value 0 is valid */
306 if (hinting_limit
> 0 && hinting_limit
< hinting_range_max
)
308 error
= FT_Err_Invalid_Argument
;
311 if (hinting_limit
< 0)
312 hinting_limit
= TA_HINTING_LIMIT
;
314 if (increase_x_height
> 0
315 && increase_x_height
< TA_PROP_INCREASE_X_HEIGHT_MIN
)
317 error
= FT_Err_Invalid_Argument
;
320 if (increase_x_height
< 0)
321 increase_x_height
= TA_INCREASE_X_HEIGHT
;
323 if (fallback_script_string
)
328 for (i
= 0; i
< TA_STYLE_MAX
; i
++)
330 TA_StyleClass style_class
= ta_style_classes
[i
];
333 if (style_class
->coverage
== TA_COVERAGE_DEFAULT
334 && !strcmp(script_names
[style_class
->script
],
335 fallback_script_string
))
338 if (i
== TA_STYLE_MAX
)
340 error
= FT_Err_Invalid_Argument
;
344 fallback_style
= (TA_Style
)i
;
347 if (default_script_string
)
352 for (i
= 0; i
< TA_SCRIPT_MAX
; i
++)
354 if (!strcmp(script_names
[i
], default_script_string
))
357 if (i
== TA_SCRIPT_MAX
)
359 error
= FT_Err_Invalid_Argument
;
363 default_script
= (TA_Script
)i
;
366 if (x_height_snapping_exceptions_string
)
368 const char* s
= number_set_parse(x_height_snapping_exceptions_string
,
369 &x_height_snapping_exceptions
,
370 TA_PROP_INCREASE_X_HEIGHT_MIN
,
374 /* we map numberset.h's error codes to values starting with 0x100 */
375 error
= 0x100 - (FT_Error
)x_height_snapping_exceptions
;
377 errline
= (char*)x_height_snapping_exceptions_string
;
384 font
->hinting_range_min
= (FT_UInt
)hinting_range_min
;
385 font
->hinting_range_max
= (FT_UInt
)hinting_range_max
;
386 font
->hinting_limit
= (FT_UInt
)hinting_limit
;
387 font
->increase_x_height
= increase_x_height
;
388 font
->x_height_snapping_exceptions
= x_height_snapping_exceptions
;
389 font
->fallback_stem_width
= (FT_UInt
)fallback_stem_width
;
391 font
->gray_strong_stem_width
= gray_strong_stem_width
;
392 font
->gdi_cleartype_strong_stem_width
= gdi_cleartype_strong_stem_width
;
393 font
->dw_cleartype_strong_stem_width
= dw_cleartype_strong_stem_width
;
395 font
->windows_compatibility
= windows_compatibility
;
396 font
->ignore_restrictions
= ignore_restrictions
;
397 font
->adjust_subglyphs
= adjust_subglyphs
;
398 font
->hint_composites
= hint_composites
;
399 font
->fallback_style
= fallback_style
;
400 font
->default_script
= default_script
;
401 font
->symbol
= symbol
;
404 font
->progress
= progress
;
405 font
->progress_data
= progress_data
;
407 font
->info_data
= info_data
;
410 font
->dehint
= dehint
;
412 font
->gasp_idx
= MISSING
;
414 /* dump parameters */
417 fprintf(stderr
, "TTF_autohint parameters\n"
418 "=======================\n"
429 DUMPSTR("default-script",
430 script_names
[font
->default_script
]);
431 DUMPVAL("dw-cleartype-strong-stem-width",
432 font
->dw_cleartype_strong_stem_width
);
433 DUMPSTR("fallback-script",
434 script_names
[ta_style_classes
[font
->fallback_style
]->script
]);
435 DUMPVAL("fallback-stem-width",
436 font
->fallback_stem_width
);
437 DUMPVAL("gdi-cleartype-strong-stem-width",
438 font
->gdi_cleartype_strong_stem_width
);
439 DUMPVAL("gray-strong-stem-width",
440 font
->gray_strong_stem_width
);
441 DUMPVAL("hinting-limit",
442 font
->hinting_limit
);
443 DUMPVAL("hinting-range-max",
444 font
->hinting_range_max
);
445 DUMPVAL("hinting-range-min",
446 font
->hinting_range_min
);
447 DUMPVAL("hint-composites",
448 font
->hint_composites
);
449 DUMPVAL("ignore-restrictions",
450 font
->ignore_restrictions
);
451 DUMPVAL("increase-x-height",
452 font
->increase_x_height
);
453 DUMPVAL("adjust-subglyphs",
454 font
->adjust_subglyphs
);
457 DUMPVAL("windows-compatibility",
458 font
->windows_compatibility
);
460 s
= number_set_show(font
->x_height_snapping_exceptions
,
461 TA_PROP_INCREASE_X_HEIGHT_MIN
, 0x7FFF);
462 DUMPSTR("x-height-snapping-exceptions", s
);
466 fprintf(stderr
, "\n");
469 /* now start with processing the data */
473 error
= TA_font_file_read(font
, in_file
);
479 /* a valid TTF can never be that small */
482 error
= TA_Err_Invalid_Font_Type
;
485 font
->in_buf
= (FT_Byte
*)in_buf
;
486 font
->in_len
= in_len
;
489 error
= TA_font_init(font
);
496 _ta_debug_global
= 1;
499 /* we do some loops over all subfonts */
500 for (i
= 0; i
< font
->num_sfnts
; i
++)
502 SFNT
* sfnt
= &font
->sfnts
[i
];
506 error
= FT_New_Memory_Face(font
->lib
, font
->in_buf
, font
->in_len
,
509 /* assure that the font hasn't been already processed by ttfautohint; */
510 /* another, more thorough check is done in TA_glyph_parse_simple */
511 idx
= FT_Get_Name_Index(sfnt
->face
, (FT_String
*)TTFAUTOHINT_GLYPH
);
514 error
= TA_Err_Already_Processed
;
521 error
= TA_sfnt_split_into_SFNT_tables(sfnt
, font
);
525 /* check permission */
526 if (sfnt
->OS2_idx
!= MISSING
)
528 SFNT_Table
* OS2_table
= &font
->tables
[sfnt
->OS2_idx
];
531 /* check lower byte of the `fsType' field */
532 if (OS2_table
->buf
[OS2_FSTYPE_OFFSET
+ 1] == 0x02
533 && !font
->ignore_restrictions
)
535 error
= TA_Err_Missing_Legal_Permission
;
542 error
= TA_sfnt_split_glyf_table(sfnt
, font
);
548 if (font
->adjust_subglyphs
)
549 error
= TA_sfnt_create_glyf_data(sfnt
, font
);
551 error
= TA_sfnt_split_glyf_table(sfnt
, font
);
555 /* this call creates a `globals' object... */
556 error
= TA_sfnt_handle_coverage(sfnt
, font
);
560 /* ... so that we now can initialize its properties */
561 TA_sfnt_set_properties(sfnt
, font
);
567 for (i
= 0; i
< font
->num_sfnts
; i
++)
569 SFNT
* sfnt
= &font
->sfnts
[i
];
572 TA_sfnt_adjust_coverage(sfnt
, font
);
577 /* this code is here for completeness -- */
578 /* right now, `glyf' tables get hinted only once, */
579 /* and referring subfonts simply reuse it, */
580 /* but this might change in the future */
584 for (i
= 0; i
< font
->num_sfnts
; i
++)
586 SFNT
* sfnt
= &font
->sfnts
[i
];
589 TA_sfnt_copy_master_coverage(sfnt
, font
);
594 /* loop again over subfonts */
595 for (i
= 0; i
< font
->num_sfnts
; i
++)
597 SFNT
* sfnt
= &font
->sfnts
[i
];
600 error
= ta_loader_init(font
);
604 error
= TA_sfnt_build_gasp_table(sfnt
, font
);
609 error
= TA_sfnt_build_cvt_table(sfnt
, font
);
612 error
= TA_sfnt_build_fpgm_table(sfnt
, font
);
615 error
= TA_sfnt_build_prep_table(sfnt
, font
);
619 error
= TA_sfnt_build_glyf_table(sfnt
, font
);
622 error
= TA_sfnt_build_loca_table(sfnt
, font
);
627 ta_loader_done(font
);
630 for (i
= 0; i
< font
->num_sfnts
; i
++)
632 SFNT
* sfnt
= &font
->sfnts
[i
];
635 error
= TA_sfnt_update_maxp_table(sfnt
, font
);
641 /* we add one glyph for composites */
642 if (sfnt
->max_components
643 && !font
->adjust_subglyphs
644 && font
->hint_composites
)
646 error
= TA_sfnt_update_hmtx_table(sfnt
, font
);
649 error
= TA_sfnt_update_post_table(sfnt
, font
);
652 error
= TA_sfnt_update_GPOS_table(sfnt
, font
);
660 /* add info about ttfautohint to the version string */
661 error
= TA_sfnt_update_name_table(sfnt
, font
);
667 if (font
->num_sfnts
== 1)
668 error
= TA_font_build_TTF(font
);
670 error
= TA_font_build_TTC(font
);
676 error
= TA_font_file_write(font
, out_file
);
682 *out_bufp
= (char*)font
->out_buf
;
683 *out_lenp
= font
->out_len
;
689 TA_font_unload(font
, in_buf
, out_bufp
);
692 error_string
= TA_get_error_message(error
);
695 *error_stringp
= (const unsigned char*)error_string
;
708 /* end of ttfautohint.c */