4 * Copyright (C) 2011-2016 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. */
27 #define COMPARE(str) \
28 (len == (sizeof (str) - 1) \
29 && !strncmp(start, str, sizeof (str) - 1))
33 TA_sfnt_set_properties(SFNT
* sfnt
,
36 TA_FaceGlobals globals
= (TA_FaceGlobals
)sfnt
->face
->autohint
.data
;
39 globals
->increase_x_height
= font
->increase_x_height
;
44 TTF_autohint(const char* options
,
53 char* error_string
= NULL
;
54 unsigned int errlinenum
= 0;
57 FT_Bool free_errline
= 0;
58 FT_Bool free_error_string
= 0;
61 FILE* out_file
= NULL
;
62 FILE* control_file
= NULL
;
64 const char* in_buf
= NULL
;
66 char** out_bufp
= NULL
;
67 size_t* out_lenp
= NULL
;
68 const char* control_buf
= NULL
;
69 size_t control_len
= 0;
71 const unsigned char** error_stringp
= NULL
;
73 FT_Long hinting_range_min
= -1;
74 FT_Long hinting_range_max
= -1;
75 FT_Long hinting_limit
= -1;
76 FT_Long increase_x_height
= -1;
78 const char* x_height_snapping_exceptions_string
= NULL
;
79 number_range
* x_height_snapping_exceptions
= NULL
;
81 FT_Long fallback_stem_width
= 0;
83 FT_Bool gray_strong_stem_width
= 0;
84 FT_Bool gdi_cleartype_strong_stem_width
= 1;
85 FT_Bool dw_cleartype_strong_stem_width
= 0;
87 TA_Progress_Func progress
= NULL
;
88 void* progress_data
= NULL
;
89 TA_Error_Func err
= NULL
;
90 void* err_data
= NULL
;
91 TA_Info_Func info
= NULL
;
92 TA_Info_Post_Func info_post
= NULL
;
93 void* info_data
= NULL
;
95 FT_Bool windows_compatibility
= 0;
96 FT_Bool ignore_restrictions
= 0;
97 FT_Bool adjust_subglyphs
= 0;
98 FT_Bool hint_composites
= 0;
100 FT_Bool fallback_scaling
= 0;
102 const char* fallback_script_string
= NULL
;
103 const char* default_script_string
= NULL
;
105 TA_Style fallback_style
= TA_STYLE_NONE_DFLT
;
106 TA_Script default_script
= TA_SCRIPT_LATN
;
110 FT_Bool TTFA_info
= 0;
111 unsigned long long epoch
= ULLONG_MAX
;
115 if (!options
|| !*options
)
117 error
= FT_Err_Invalid_Argument
;
122 va_start(ap
, options
);
135 while (*op
&& *op
!= ',')
138 /* remove leading whitespace */
139 while (isspace(*start
))
142 /* check for empty option */
146 len
= (size_t)(op
- start
);
148 /* the `COMPARE' macro uses `len' and `start' */
150 /* handle options -- don't forget to update parameter dump below! */
151 if (COMPARE("adjust-subglyphs"))
152 adjust_subglyphs
= (FT_Bool
)va_arg(ap
, FT_Int
);
153 else if (COMPARE("debug"))
154 debug
= (FT_Bool
)va_arg(ap
, FT_Int
);
155 else if (COMPARE("default-script"))
156 default_script_string
= va_arg(ap
, const char*);
157 else if (COMPARE("dehint"))
158 dehint
= (FT_Bool
)va_arg(ap
, FT_Int
);
159 else if (COMPARE("control-buffer"))
162 control_buf
= va_arg(ap
, const char*);
164 else if (COMPARE("control-buffer-len"))
167 control_len
= va_arg(ap
, size_t);
169 else if (COMPARE("control-file"))
171 control_file
= va_arg(ap
, FILE*);
175 else if (COMPARE("dw-cleartype-strong-stem-width"))
176 dw_cleartype_strong_stem_width
= (FT_Bool
)va_arg(ap
, FT_Int
);
177 else if (COMPARE("epoch"))
178 epoch
= (unsigned long long)va_arg(ap
, unsigned long long);
179 else if (COMPARE("error-callback"))
180 err
= va_arg(ap
, TA_Error_Func
);
181 else if (COMPARE("error-callback-data"))
182 err_data
= va_arg(ap
, void*);
183 else if (COMPARE("error-string"))
184 error_stringp
= va_arg(ap
, const unsigned char**);
185 else if (COMPARE("fallback-scaling"))
186 fallback_scaling
= (FT_Bool
)va_arg(ap
, FT_Int
);
187 else if (COMPARE("fallback-script"))
188 fallback_script_string
= va_arg(ap
, const char*);
189 else if (COMPARE("fallback-stem-width"))
190 fallback_stem_width
= (FT_Long
)va_arg(ap
, FT_UInt
);
191 else if (COMPARE("gdi-cleartype-strong-stem-width"))
192 gdi_cleartype_strong_stem_width
= (FT_Bool
)va_arg(ap
, FT_Int
);
193 else if (COMPARE("gray-strong-stem-width"))
194 gray_strong_stem_width
= (FT_Bool
)va_arg(ap
, FT_Int
);
195 else if (COMPARE("hinting-limit"))
196 hinting_limit
= (FT_Long
)va_arg(ap
, FT_UInt
);
197 else if (COMPARE("hinting-range-max"))
198 hinting_range_max
= (FT_Long
)va_arg(ap
, FT_UInt
);
199 else if (COMPARE("hinting-range-min"))
200 hinting_range_min
= (FT_Long
)va_arg(ap
, FT_UInt
);
201 else if (COMPARE("hint-composites"))
202 hint_composites
= (FT_Bool
)va_arg(ap
, FT_Int
);
203 else if (COMPARE("ignore-restrictions"))
204 ignore_restrictions
= (FT_Bool
)va_arg(ap
, FT_Int
);
205 else if (COMPARE("in-buffer"))
208 in_buf
= va_arg(ap
, const char*);
210 else if (COMPARE("in-buffer-len"))
213 in_len
= va_arg(ap
, size_t);
215 else if (COMPARE("in-file"))
217 in_file
= va_arg(ap
, FILE*);
221 else if (COMPARE("increase-x-height"))
222 increase_x_height
= (FT_Long
)va_arg(ap
, FT_UInt
);
223 else if (COMPARE("info-callback"))
224 info
= va_arg(ap
, TA_Info_Func
);
225 else if (COMPARE("info-callback-data"))
226 info_data
= va_arg(ap
, void*);
227 else if (COMPARE("info-post-callback"))
228 info_post
= va_arg(ap
, TA_Info_Post_Func
);
229 else if (COMPARE("out-buffer"))
232 out_bufp
= va_arg(ap
, char**);
234 else if (COMPARE("out-buffer-len"))
237 out_lenp
= va_arg(ap
, size_t*);
239 else if (COMPARE("out-file"))
241 out_file
= va_arg(ap
, FILE*);
245 else if (COMPARE("pre-hinting"))
246 adjust_subglyphs
= (FT_Bool
)va_arg(ap
, FT_Int
);
247 else if (COMPARE("progress-callback"))
248 progress
= va_arg(ap
, TA_Progress_Func
);
249 else if (COMPARE("progress-callback-data"))
250 progress_data
= va_arg(ap
, void*);
251 else if (COMPARE("symbol"))
252 symbol
= (FT_Bool
)va_arg(ap
, FT_Int
);
253 else if (COMPARE("TTFA-info"))
254 TTFA_info
= (FT_Bool
)va_arg(ap
, FT_Int
);
255 else if (COMPARE("windows-compatibility"))
256 windows_compatibility
= (FT_Bool
)va_arg(ap
, FT_Int
);
257 else if (COMPARE("x-height-snapping-exceptions"))
258 x_height_snapping_exceptions_string
= va_arg(ap
, const char*);
261 error
= TA_Err_Unknown_Argument
;
276 || (in_buf
&& in_len
)))
278 error
= FT_Err_Invalid_Argument
;
283 || (out_bufp
&& out_lenp
)))
285 error
= FT_Err_Invalid_Argument
;
289 font
= (FONT
*)calloc(1, sizeof (FONT
));
292 error
= FT_Err_Out_Of_Memory
;
299 if (hinting_range_min
>= 0 && hinting_range_min
< 2)
301 error
= FT_Err_Invalid_Argument
;
304 if (hinting_range_min
< 0)
305 hinting_range_min
= TA_HINTING_RANGE_MIN
;
307 if (hinting_range_max
>= 0 && hinting_range_max
< hinting_range_min
)
309 error
= FT_Err_Invalid_Argument
;
312 if (hinting_range_max
< 0)
313 hinting_range_max
= TA_HINTING_RANGE_MAX
;
315 /* value 0 is valid */
316 if (hinting_limit
> 0 && hinting_limit
< hinting_range_max
)
318 error
= FT_Err_Invalid_Argument
;
321 if (hinting_limit
< 0)
322 hinting_limit
= TA_HINTING_LIMIT
;
324 if (increase_x_height
> 0
325 && increase_x_height
< TA_PROP_INCREASE_X_HEIGHT_MIN
)
327 error
= FT_Err_Invalid_Argument
;
330 if (increase_x_height
< 0)
331 increase_x_height
= TA_INCREASE_X_HEIGHT
;
333 if (fallback_script_string
)
335 for (i
= 0; i
< TA_STYLE_MAX
; i
++)
337 TA_StyleClass style_class
= ta_style_classes
[i
];
340 if (style_class
->coverage
== TA_COVERAGE_DEFAULT
341 && !strcmp(script_names
[style_class
->script
],
342 fallback_script_string
))
345 if (i
== TA_STYLE_MAX
)
347 error
= FT_Err_Invalid_Argument
;
351 fallback_style
= (TA_Style
)i
;
354 if (default_script_string
)
356 for (i
= 0; i
< TA_SCRIPT_MAX
; i
++)
358 if (!strcmp(script_names
[i
], default_script_string
))
361 if (i
== TA_SCRIPT_MAX
)
363 error
= FT_Err_Invalid_Argument
;
367 default_script
= (TA_Script
)i
;
370 if (x_height_snapping_exceptions_string
)
372 const char* s
= number_set_parse(x_height_snapping_exceptions_string
,
373 &x_height_snapping_exceptions
,
374 TA_PROP_INCREASE_X_HEIGHT_MIN
,
378 /* we map numberset.h's error codes to values starting with 0x100 */
379 error
= 0x100 - (FT_Error
)(uintptr_t)x_height_snapping_exceptions
;
381 errline
= (char*)x_height_snapping_exceptions_string
;
388 font
->hinting_range_min
= (FT_UInt
)hinting_range_min
;
389 font
->hinting_range_max
= (FT_UInt
)hinting_range_max
;
390 font
->hinting_limit
= (FT_UInt
)hinting_limit
;
391 font
->increase_x_height
= (FT_UInt
)increase_x_height
;
392 font
->x_height_snapping_exceptions
= x_height_snapping_exceptions
;
393 font
->fallback_stem_width
= (FT_UInt
)fallback_stem_width
;
395 font
->gray_strong_stem_width
= gray_strong_stem_width
;
396 font
->gdi_cleartype_strong_stem_width
= gdi_cleartype_strong_stem_width
;
397 font
->dw_cleartype_strong_stem_width
= dw_cleartype_strong_stem_width
;
399 font
->windows_compatibility
= windows_compatibility
;
400 font
->ignore_restrictions
= ignore_restrictions
;
401 font
->adjust_subglyphs
= adjust_subglyphs
;
402 font
->hint_composites
= hint_composites
;
403 font
->fallback_style
= fallback_style
;
404 font
->fallback_scaling
= fallback_scaling
;
405 font
->default_script
= default_script
;
406 font
->symbol
= symbol
;
409 font
->progress
= progress
;
410 font
->progress_data
= progress_data
;
412 font
->info_post
= info_post
;
413 font
->info_data
= info_data
;
416 font
->dehint
= dehint
;
417 font
->TTFA_info
= TTFA_info
;
420 font
->gasp_idx
= MISSING
;
422 /* start with processing the data */
426 error
= TA_font_file_read(font
, in_file
);
432 /* a valid TTF can never be that small */
435 error
= TA_Err_Invalid_Font_Type
;
438 font
->in_buf
= (FT_Byte
*)in_buf
;
439 font
->in_len
= in_len
;
444 error
= TA_control_file_read(font
, control_file
);
448 else if (control_buf
)
450 font
->control_buf
= (char*)control_buf
;
451 font
->control_len
= control_len
;
454 error
= TA_font_init(font
);
461 _ta_debug_global
= 1;
464 /* we do some loops over all subfonts -- */
465 /* to process options early, just start with loading all of them */
466 for (i
= 0; i
< font
->num_sfnts
; i
++)
468 SFNT
* sfnt
= &font
->sfnts
[i
];
472 error
= FT_New_Memory_Face(font
->lib
,
474 (FT_Long
)font
->in_len
,
478 /* assure that the font hasn't been already processed by ttfautohint; */
479 /* another, more thorough check is done in TA_glyph_parse_simple */
480 idx
= FT_Get_Name_Index(sfnt
->face
, (FT_String
*)TTFAUTOHINT_GLYPH
);
483 error
= TA_Err_Already_Processed
;
491 /* process control instructions */
492 error
= TA_control_parse_buffer(font
,
494 &errlinenum
, &errline
, &errpos
);
498 free_error_string
= 1;
502 /* now we are able to dump all parameters */
508 s
= TA_font_dump_parameters(font
, 1);
511 error
= FT_Err_Out_Of_Memory
;
515 fprintf(stderr
, "%s", s
);
519 error
= TA_control_build_tree(font
);
523 /* loop again over subfonts and continue processing */
524 for (i
= 0; i
< font
->num_sfnts
; i
++)
526 SFNT
* sfnt
= &font
->sfnts
[i
];
529 error
= TA_sfnt_split_into_SFNT_tables(sfnt
, font
);
533 /* check permission */
534 if (sfnt
->OS2_idx
!= MISSING
)
536 SFNT_Table
* OS2_table
= &font
->tables
[sfnt
->OS2_idx
];
539 /* check lower byte of the `fsType' field */
540 if (OS2_table
->buf
[OS2_FSTYPE_OFFSET
+ 1] == 0x02
541 && !font
->ignore_restrictions
)
543 error
= TA_Err_Missing_Legal_Permission
;
550 error
= TA_sfnt_split_glyf_table(sfnt
, font
);
556 if (font
->adjust_subglyphs
)
557 error
= TA_sfnt_create_glyf_data(sfnt
, font
);
559 error
= TA_sfnt_split_glyf_table(sfnt
, font
);
563 /* this call creates a `globals' object... */
564 error
= TA_sfnt_handle_coverage(sfnt
, font
);
568 /* ... so that we now can initialize its properties */
569 TA_sfnt_set_properties(sfnt
, font
);
575 for (i
= 0; i
< font
->num_sfnts
; i
++)
577 SFNT
* sfnt
= &font
->sfnts
[i
];
580 TA_sfnt_adjust_coverage(sfnt
, font
);
585 /* this code is here for completeness -- */
586 /* right now, `glyf' tables get hinted only once, */
587 /* and referring subfonts simply reuse it, */
588 /* but this might change in the future */
592 for (i
= 0; i
< font
->num_sfnts
; i
++)
594 SFNT
* sfnt
= &font
->sfnts
[i
];
597 TA_sfnt_copy_master_coverage(sfnt
, font
);
604 for (i
= 0; i
< font
->num_sfnts
; i
++)
606 SFNT
* sfnt
= &font
->sfnts
[i
];
609 TA_control_apply_coverage(sfnt
, font
);
613 /* loop again over subfonts */
614 for (i
= 0; i
< font
->num_sfnts
; i
++)
616 SFNT
* sfnt
= &font
->sfnts
[i
];
619 error
= ta_loader_init(font
);
623 error
= TA_sfnt_build_gasp_table(sfnt
, font
);
628 error
= TA_sfnt_build_cvt_table(sfnt
, font
);
631 error
= TA_sfnt_build_fpgm_table(sfnt
, font
);
634 error
= TA_sfnt_build_prep_table(sfnt
, font
);
638 error
= TA_sfnt_build_glyf_table(sfnt
, font
);
641 error
= TA_sfnt_build_loca_table(sfnt
, font
);
646 ta_loader_done(font
);
649 for (i
= 0; i
< font
->num_sfnts
; i
++)
651 SFNT
* sfnt
= &font
->sfnts
[i
];
654 error
= TA_sfnt_update_maxp_table(sfnt
, font
);
660 /* we add one glyph for composites */
661 if (sfnt
->max_components
662 && !font
->adjust_subglyphs
663 && font
->hint_composites
)
665 error
= TA_sfnt_update_hmtx_table(sfnt
, font
);
668 error
= TA_sfnt_update_post_table(sfnt
, font
);
671 error
= TA_sfnt_update_GPOS_table(sfnt
, font
);
679 /* add info about ttfautohint to the version string */
680 error
= TA_sfnt_update_name_table(sfnt
, font
);
686 if (font
->num_sfnts
== 1)
687 error
= TA_font_build_TTF(font
);
689 error
= TA_font_build_TTC(font
);
695 error
= TA_font_file_write(font
, out_file
);
701 *out_bufp
= (char*)font
->out_buf
;
702 *out_lenp
= font
->out_len
;
708 TA_control_free(font
->control
);
709 TA_control_free_tree(font
);
710 TA_font_unload(font
, in_buf
, out_bufp
, control_buf
);
714 error_string
= (char*)TA_get_error_message(error
);
716 /* this must be a static value */
718 *error_stringp
= (const unsigned char*)TA_get_error_message(error
);
730 if (free_error_string
)
736 /* end of ttfautohint.c */