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. */
18 #define _POSIX_SOURCE /* to access `strtok_r' with glibc */
28 #define DUMP_COLUMN "33"
30 #define COMPARE(str) \
31 (len == (sizeof (str) - 1) \
32 && !strncmp(start, str, sizeof (str) - 1))
33 #define DUMPVAL(str, arg) \
34 fprintf(stderr, "%" DUMP_COLUMN "s = %ld\n", \
37 #define DUMPSTR(str, arg) \
38 fprintf(stderr, "%" DUMP_COLUMN "s = %s\n", \
41 #define DUMPSTRX(arg) \
42 fprintf(stderr, "%" DUMP_COLUMN "s %s\n", \
48 TA_sfnt_set_properties(SFNT
* sfnt
,
51 TA_FaceGlobals globals
= (TA_FaceGlobals
)sfnt
->face
->autohint
.data
;
54 globals
->increase_x_height
= font
->increase_x_height
;
59 TTF_autohint(const char* options
,
68 const char* error_string
= NULL
;
69 unsigned int errlinenum
= 0;
72 FT_Bool free_errline
= 0;
75 FILE* out_file
= NULL
;
76 FILE* deltas_file
= NULL
;
78 const char* in_buf
= NULL
;
80 char** out_bufp
= NULL
;
81 size_t* out_lenp
= NULL
;
82 const char* deltas_buf
= NULL
;
83 size_t deltas_len
= 0;
85 const unsigned char** error_stringp
= NULL
;
89 FT_Long hinting_range_min
= -1;
90 FT_Long hinting_range_max
= -1;
91 FT_Long hinting_limit
= -1;
92 FT_Long increase_x_height
= -1;
94 const char* x_height_snapping_exceptions_string
= NULL
;
95 number_range
* x_height_snapping_exceptions
= NULL
;
97 FT_Long fallback_stem_width
= 0;
99 FT_Bool gray_strong_stem_width
= 0;
100 FT_Bool gdi_cleartype_strong_stem_width
= 1;
101 FT_Bool dw_cleartype_strong_stem_width
= 0;
103 TA_Progress_Func progress
= NULL
;
104 void* progress_data
= NULL
;
105 TA_Error_Func err
= NULL
;
106 void* err_data
= NULL
;
107 TA_Info_Func info
= NULL
;
108 void* info_data
= NULL
;
110 FT_Bool windows_compatibility
= 0;
111 FT_Bool ignore_restrictions
= 0;
112 FT_Bool adjust_subglyphs
= 0;
113 FT_Bool hint_composites
= 0;
116 const char* fallback_script_string
= NULL
;
117 const char* default_script_string
= NULL
;
118 TA_Style fallback_style
= TA_STYLE_NONE_DFLT
;
119 TA_Script default_script
= TA_SCRIPT_LATN
;
127 #define SCRIPT(s, S, d, h, sc1, sc2, sc3) #s,
129 const char* script_names
[] =
132 #include <ttfautohint-scripts.h>
137 if (!options
|| !*options
)
139 error
= FT_Err_Invalid_Argument
;
144 va_start(ap
, options
);
157 while (*op
&& *op
!= ',')
160 /* remove leading whitespace */
161 while (isspace(*start
))
164 /* check for empty option */
170 /* the `COMPARE' macro uses `len' and `start' */
172 /* handle options -- don't forget to update parameter dump below! */
173 if (COMPARE("adjust-subglyphs"))
174 adjust_subglyphs
= (FT_Bool
)va_arg(ap
, FT_Int
);
175 else if (COMPARE("debug"))
176 debug
= (FT_Bool
)va_arg(ap
, FT_Int
);
177 else if (COMPARE("default-script"))
178 default_script_string
= va_arg(ap
, const char*);
179 else if (COMPARE("dehint"))
180 dehint
= (FT_Bool
)va_arg(ap
, FT_Int
);
181 else if (COMPARE("deltas-buffer"))
184 deltas_buf
= va_arg(ap
, const char*);
186 else if (COMPARE("deltas-buffer-len"))
189 deltas_len
= va_arg(ap
, size_t);
191 else if (COMPARE("deltas-file"))
193 deltas_file
= va_arg(ap
, FILE*);
197 else if (COMPARE("dw-cleartype-strong-stem-width"))
198 dw_cleartype_strong_stem_width
= (FT_Bool
)va_arg(ap
, FT_Int
);
199 else if (COMPARE("error-callback"))
200 err
= va_arg(ap
, TA_Error_Func
);
201 else if (COMPARE("error-callback-data"))
202 err_data
= va_arg(ap
, void*);
203 else if (COMPARE("error-string"))
204 error_stringp
= va_arg(ap
, const unsigned char**);
205 else if (COMPARE("fallback-script"))
206 fallback_script_string
= va_arg(ap
, const char*);
207 else if (COMPARE("fallback-stem-width"))
208 fallback_stem_width
= (FT_Long
)va_arg(ap
, FT_UInt
);
209 else if (COMPARE("gdi-cleartype-strong-stem-width"))
210 gdi_cleartype_strong_stem_width
= (FT_Bool
)va_arg(ap
, FT_Int
);
211 else if (COMPARE("gray-strong-stem-width"))
212 gray_strong_stem_width
= (FT_Bool
)va_arg(ap
, FT_Int
);
213 else if (COMPARE("hinting-limit"))
214 hinting_limit
= (FT_Long
)va_arg(ap
, FT_UInt
);
215 else if (COMPARE("hinting-range-max"))
216 hinting_range_max
= (FT_Long
)va_arg(ap
, FT_UInt
);
217 else if (COMPARE("hinting-range-min"))
218 hinting_range_min
= (FT_Long
)va_arg(ap
, FT_UInt
);
219 else if (COMPARE("hint-composites"))
220 hint_composites
= (FT_Bool
)va_arg(ap
, FT_Int
);
221 else if (COMPARE("ignore-restrictions"))
222 ignore_restrictions
= (FT_Bool
)va_arg(ap
, FT_Int
);
223 else if (COMPARE("in-buffer"))
226 in_buf
= va_arg(ap
, const char*);
228 else if (COMPARE("in-buffer-len"))
231 in_len
= va_arg(ap
, size_t);
233 else if (COMPARE("in-file"))
235 in_file
= va_arg(ap
, FILE*);
239 else if (COMPARE("increase-x-height"))
240 increase_x_height
= (FT_Long
)va_arg(ap
, FT_UInt
);
241 else if (COMPARE("info-callback"))
242 info
= va_arg(ap
, TA_Info_Func
);
243 else if (COMPARE("info-callback-data"))
244 info_data
= va_arg(ap
, void*);
245 else if (COMPARE("out-buffer"))
248 out_bufp
= va_arg(ap
, char**);
250 else if (COMPARE("out-buffer-len"))
253 out_lenp
= va_arg(ap
, size_t*);
255 else if (COMPARE("out-file"))
257 out_file
= va_arg(ap
, FILE*);
261 else if (COMPARE("pre-hinting"))
262 adjust_subglyphs
= (FT_Bool
)va_arg(ap
, FT_Int
);
263 else if (COMPARE("progress-callback"))
264 progress
= va_arg(ap
, TA_Progress_Func
);
265 else if (COMPARE("progress-callback-data"))
266 progress_data
= va_arg(ap
, void*);
267 else if (COMPARE("symbol"))
268 symbol
= (FT_Bool
)va_arg(ap
, FT_Int
);
269 else if (COMPARE("windows-compatibility"))
270 windows_compatibility
= (FT_Bool
)va_arg(ap
, FT_Int
);
271 else if (COMPARE("x-height-snapping-exceptions"))
272 x_height_snapping_exceptions_string
= va_arg(ap
, const char*);
275 error
= TA_Err_Unknown_Argument
;
290 || (in_buf
&& in_len
)))
292 error
= FT_Err_Invalid_Argument
;
297 || (out_bufp
&& out_lenp
)))
299 error
= FT_Err_Invalid_Argument
;
303 font
= (FONT
*)calloc(1, sizeof (FONT
));
306 error
= FT_Err_Out_Of_Memory
;
313 if (hinting_range_min
>= 0 && hinting_range_min
< 2)
315 error
= FT_Err_Invalid_Argument
;
318 if (hinting_range_min
< 0)
319 hinting_range_min
= TA_HINTING_RANGE_MIN
;
321 if (hinting_range_max
>= 0 && hinting_range_max
< hinting_range_min
)
323 error
= FT_Err_Invalid_Argument
;
326 if (hinting_range_max
< 0)
327 hinting_range_max
= TA_HINTING_RANGE_MAX
;
329 /* value 0 is valid */
330 if (hinting_limit
> 0 && hinting_limit
< hinting_range_max
)
332 error
= FT_Err_Invalid_Argument
;
335 if (hinting_limit
< 0)
336 hinting_limit
= TA_HINTING_LIMIT
;
338 if (increase_x_height
> 0
339 && increase_x_height
< TA_PROP_INCREASE_X_HEIGHT_MIN
)
341 error
= FT_Err_Invalid_Argument
;
344 if (increase_x_height
< 0)
345 increase_x_height
= TA_INCREASE_X_HEIGHT
;
347 if (fallback_script_string
)
352 for (i
= 0; i
< TA_STYLE_MAX
; i
++)
354 TA_StyleClass style_class
= ta_style_classes
[i
];
357 if (style_class
->coverage
== TA_COVERAGE_DEFAULT
358 && !strcmp(script_names
[style_class
->script
],
359 fallback_script_string
))
362 if (i
== TA_STYLE_MAX
)
364 error
= FT_Err_Invalid_Argument
;
368 fallback_style
= (TA_Style
)i
;
371 if (default_script_string
)
376 for (i
= 0; i
< TA_SCRIPT_MAX
; i
++)
378 if (!strcmp(script_names
[i
], default_script_string
))
381 if (i
== TA_SCRIPT_MAX
)
383 error
= FT_Err_Invalid_Argument
;
387 default_script
= (TA_Script
)i
;
390 if (x_height_snapping_exceptions_string
)
392 const char* s
= number_set_parse(x_height_snapping_exceptions_string
,
393 &x_height_snapping_exceptions
,
394 TA_PROP_INCREASE_X_HEIGHT_MIN
,
398 /* we map numberset.h's error codes to values starting with 0x100 */
399 error
= 0x100 - (FT_Error
)x_height_snapping_exceptions
;
401 errline
= (char*)x_height_snapping_exceptions_string
;
408 font
->hinting_range_min
= (FT_UInt
)hinting_range_min
;
409 font
->hinting_range_max
= (FT_UInt
)hinting_range_max
;
410 font
->hinting_limit
= (FT_UInt
)hinting_limit
;
411 font
->increase_x_height
= increase_x_height
;
412 font
->x_height_snapping_exceptions
= x_height_snapping_exceptions
;
413 font
->fallback_stem_width
= (FT_UInt
)fallback_stem_width
;
415 font
->gray_strong_stem_width
= gray_strong_stem_width
;
416 font
->gdi_cleartype_strong_stem_width
= gdi_cleartype_strong_stem_width
;
417 font
->dw_cleartype_strong_stem_width
= dw_cleartype_strong_stem_width
;
419 font
->windows_compatibility
= windows_compatibility
;
420 font
->ignore_restrictions
= ignore_restrictions
;
421 font
->adjust_subglyphs
= adjust_subglyphs
;
422 font
->hint_composites
= hint_composites
;
423 font
->fallback_style
= fallback_style
;
424 font
->default_script
= default_script
;
425 font
->symbol
= symbol
;
428 font
->progress
= progress
;
429 font
->progress_data
= progress_data
;
431 font
->info_data
= info_data
;
434 font
->dehint
= dehint
;
436 font
->gasp_idx
= MISSING
;
438 /* start with processing the data */
442 error
= TA_font_file_read(font
, in_file
);
448 /* a valid TTF can never be that small */
451 error
= TA_Err_Invalid_Font_Type
;
454 font
->in_buf
= (FT_Byte
*)in_buf
;
455 font
->in_len
= in_len
;
460 error
= TA_deltas_file_read(font
, deltas_file
);
466 font
->deltas_buf
= (char*)deltas_buf
;
467 font
->deltas_len
= deltas_len
;
470 error
= TA_font_init(font
);
477 _ta_debug_global
= 1;
480 /* we do some loops over all subfonts -- */
481 /* to process options early, just start with loading all of them */
482 for (i
= 0; i
< font
->num_sfnts
; i
++)
484 SFNT
* sfnt
= &font
->sfnts
[i
];
488 error
= FT_New_Memory_Face(font
->lib
, font
->in_buf
, font
->in_len
,
491 /* assure that the font hasn't been already processed by ttfautohint; */
492 /* another, more thorough check is done in TA_glyph_parse_simple */
493 idx
= FT_Get_Name_Index(sfnt
->face
, (FT_String
*)TTFAUTOHINT_GLYPH
);
496 error
= TA_Err_Already_Processed
;
504 /* process delta exceptions data */
505 error
= TA_deltas_parse(font
, &deltas
, &errlinenum
, &errline
, &errpos
);
512 /* now we are able to dump all parameters */
515 fprintf(stderr
, "TTF_autohint parameters\n"
516 "=======================\n"
527 DUMPSTR("default-script",
528 script_names
[font
->default_script
]);
529 DUMPVAL("dw-cleartype-strong-stem-width",
530 font
->dw_cleartype_strong_stem_width
);
531 DUMPSTR("fallback-script",
532 script_names
[ta_style_classes
[font
->fallback_style
]->script
]);
533 DUMPVAL("fallback-stem-width",
534 font
->fallback_stem_width
);
535 DUMPVAL("gdi-cleartype-strong-stem-width",
536 font
->gdi_cleartype_strong_stem_width
);
537 DUMPVAL("gray-strong-stem-width",
538 font
->gray_strong_stem_width
);
539 DUMPVAL("hinting-limit",
540 font
->hinting_limit
);
541 DUMPVAL("hinting-range-max",
542 font
->hinting_range_max
);
543 DUMPVAL("hinting-range-min",
544 font
->hinting_range_min
);
545 DUMPVAL("hint-composites",
546 font
->hint_composites
);
547 DUMPVAL("ignore-restrictions",
548 font
->ignore_restrictions
);
549 DUMPVAL("increase-x-height",
550 font
->increase_x_height
);
551 DUMPVAL("adjust-subglyphs",
552 font
->adjust_subglyphs
);
555 DUMPVAL("windows-compatibility",
556 font
->windows_compatibility
);
558 s
= number_set_show(font
->x_height_snapping_exceptions
,
559 TA_PROP_INCREASE_X_HEIGHT_MIN
, 0x7FFF);
562 DUMPSTR("x-height-snapping-exceptions", s
);
567 error
= FT_Err_Out_Of_Memory
;
571 s
= TA_deltas_show(font
, deltas
);
578 /* show delta exceptions data line by line */
579 token
= strtok_r(s
, "\n", &saveptr
);
580 DUMPSTR("delta exceptions", token
);
584 token
= strtok_r(NULL
, "\n", &saveptr
);
595 error
= FT_Err_Out_Of_Memory
;
600 fprintf(stderr
, "\n");
603 error
= TA_deltas_build_tree(font
, deltas
);
607 /* loop again over subfonts and continue processing */
608 for (i
= 0; i
< font
->num_sfnts
; i
++)
610 SFNT
* sfnt
= &font
->sfnts
[i
];
613 error
= TA_sfnt_split_into_SFNT_tables(sfnt
, font
);
617 /* check permission */
618 if (sfnt
->OS2_idx
!= MISSING
)
620 SFNT_Table
* OS2_table
= &font
->tables
[sfnt
->OS2_idx
];
623 /* check lower byte of the `fsType' field */
624 if (OS2_table
->buf
[OS2_FSTYPE_OFFSET
+ 1] == 0x02
625 && !font
->ignore_restrictions
)
627 error
= TA_Err_Missing_Legal_Permission
;
634 error
= TA_sfnt_split_glyf_table(sfnt
, font
);
640 if (font
->adjust_subglyphs
)
641 error
= TA_sfnt_create_glyf_data(sfnt
, font
);
643 error
= TA_sfnt_split_glyf_table(sfnt
, font
);
647 /* this call creates a `globals' object... */
648 error
= TA_sfnt_handle_coverage(sfnt
, font
);
652 /* ... so that we now can initialize its properties */
653 TA_sfnt_set_properties(sfnt
, font
);
659 for (i
= 0; i
< font
->num_sfnts
; i
++)
661 SFNT
* sfnt
= &font
->sfnts
[i
];
664 TA_sfnt_adjust_coverage(sfnt
, font
);
669 /* this code is here for completeness -- */
670 /* right now, `glyf' tables get hinted only once, */
671 /* and referring subfonts simply reuse it, */
672 /* but this might change in the future */
676 for (i
= 0; i
< font
->num_sfnts
; i
++)
678 SFNT
* sfnt
= &font
->sfnts
[i
];
681 TA_sfnt_copy_master_coverage(sfnt
, font
);
686 /* loop again over subfonts */
687 for (i
= 0; i
< font
->num_sfnts
; i
++)
689 SFNT
* sfnt
= &font
->sfnts
[i
];
692 error
= ta_loader_init(font
);
696 error
= TA_sfnt_build_gasp_table(sfnt
, font
);
701 error
= TA_sfnt_build_cvt_table(sfnt
, font
);
704 error
= TA_sfnt_build_fpgm_table(sfnt
, font
);
707 error
= TA_sfnt_build_prep_table(sfnt
, font
);
711 error
= TA_sfnt_build_glyf_table(sfnt
, font
);
714 error
= TA_sfnt_build_loca_table(sfnt
, font
);
719 ta_loader_done(font
);
722 for (i
= 0; i
< font
->num_sfnts
; i
++)
724 SFNT
* sfnt
= &font
->sfnts
[i
];
727 error
= TA_sfnt_update_maxp_table(sfnt
, font
);
733 /* we add one glyph for composites */
734 if (sfnt
->max_components
735 && !font
->adjust_subglyphs
736 && font
->hint_composites
)
738 error
= TA_sfnt_update_hmtx_table(sfnt
, font
);
741 error
= TA_sfnt_update_post_table(sfnt
, font
);
744 error
= TA_sfnt_update_GPOS_table(sfnt
, font
);
752 /* add info about ttfautohint to the version string */
753 error
= TA_sfnt_update_name_table(sfnt
, font
);
759 if (font
->num_sfnts
== 1)
760 error
= TA_font_build_TTF(font
);
762 error
= TA_font_build_TTC(font
);
768 error
= TA_font_file_write(font
, out_file
);
774 *out_bufp
= (char*)font
->out_buf
;
775 *out_lenp
= font
->out_len
;
781 TA_deltas_free(deltas
);
782 TA_deltas_free_tree(font
);
783 TA_font_unload(font
, in_buf
, out_bufp
, deltas_buf
);
786 error_string
= TA_get_error_message(error
);
789 *error_stringp
= (const unsigned char*)error_string
;
805 /* end of ttfautohint.c */