4 * Copyright (C) 2011 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 COMPARE(str) (len == (sizeof (str) - 1) \
27 && !strncmp(start, str, sizeof (str) - 1))
31 TTF_autohint(const char* options
,
41 FILE* out_file
= NULL
;
43 const char* in_buf
= NULL
;
45 char** out_bufp
= NULL
;
46 size_t* out_lenp
= NULL
;
48 const unsigned char** error_stringp
= NULL
;
50 FT_Long hinting_range_min
= -1;
51 FT_Long hinting_range_max
= -1;
53 TA_Progress_Func progress
;
56 FT_Bool ignore_permissions
= 0;
57 FT_UInt fallback_script
= 0;
62 if (!options
|| !*options
)
64 error
= FT_Err_Invalid_Argument
;
69 va_start(ap
, options
);
82 while (*op
&& *op
!= ',')
85 /* remove leading whitespace */
86 while (isspace(*start
))
89 /* check for empty option */
95 /* the `COMPARE' macro uses `len' and `start' */
98 if (COMPARE("error-string"))
99 error_stringp
= va_arg(ap
, const unsigned char**);
100 else if (COMPARE("fallback-script"))
101 fallback_script
= va_arg(ap
, FT_UInt
);
102 else if (COMPARE("hinting-range-max"))
103 hinting_range_max
= (FT_Long
)va_arg(ap
, FT_UInt
);
104 else if (COMPARE("hinting-range-min"))
105 hinting_range_min
= (FT_Long
)va_arg(ap
, FT_UInt
);
106 else if (COMPARE("ignore-permissions"))
107 ignore_permissions
= (FT_Bool
)va_arg(ap
, FT_Int
);
108 else if (COMPARE("in-buffer"))
111 in_buf
= va_arg(ap
, const char*);
113 else if (COMPARE("in-buffer-len"))
116 in_len
= va_arg(ap
, size_t);
118 else if (COMPARE("in-file"))
120 in_file
= va_arg(ap
, FILE*);
124 else if (COMPARE("out-buffer"))
127 out_bufp
= va_arg(ap
, char**);
129 else if (COMPARE("out-buffer-len"))
132 out_lenp
= va_arg(ap
, size_t*);
134 else if (COMPARE("out-file"))
136 out_file
= va_arg(ap
, FILE*);
140 else if (COMPARE("progress-callback"))
141 progress
= va_arg(ap
, TA_Progress_Func
);
142 else if (COMPARE("progress-callback-data"))
143 progress_data
= va_arg(ap
, void*);
147 x-height-snapping-exceptions
161 || (in_buf
&& in_len
)))
163 error
= FT_Err_Invalid_Argument
;
168 || (out_bufp
&& out_lenp
)))
170 error
= FT_Err_Invalid_Argument
;
174 font
= (FONT
*)calloc(1, sizeof (FONT
));
177 error
= FT_Err_Out_Of_Memory
;
181 if (hinting_range_min
>= 0 && hinting_range_min
< 2)
183 error
= FT_Err_Invalid_Argument
;
186 if (hinting_range_min
< 0)
187 hinting_range_min
= 8;
189 if (hinting_range_max
>= 0 && hinting_range_max
< hinting_range_min
)
191 error
= FT_Err_Invalid_Argument
;
194 if (hinting_range_max
< 0)
195 hinting_range_max
= 1000;
197 font
->hinting_range_min
= (FT_UInt
)hinting_range_min
;
198 font
->hinting_range_max
= (FT_UInt
)hinting_range_max
;
200 font
->progress
= progress
;
201 font
->progress_data
= progress_data
;
203 font
->ignore_permissions
= ignore_permissions
;
204 /* restrict value to two bits */
205 font
->fallback_script
= fallback_script
& 3;
207 /* now start with processing the data */
211 error
= TA_font_file_read(font
, in_file
);
217 /* a valid TTF can never be that small */
220 error
= FT_Err_Invalid_Argument
;
223 font
->in_buf
= (FT_Byte
*)in_buf
;
224 font
->in_len
= in_len
;
227 error
= TA_font_init(font
);
231 /* loop over subfonts */
232 for (i
= 0; i
< font
->num_sfnts
; i
++)
234 SFNT
* sfnt
= &font
->sfnts
[i
];
237 error
= FT_New_Memory_Face(font
->lib
, font
->in_buf
, font
->in_len
,
242 error
= TA_sfnt_split_into_SFNT_tables(sfnt
, font
);
246 error
= TA_sfnt_split_glyf_table(sfnt
, font
);
250 /* check permission */
251 if (sfnt
->OS2_idx
!= MISSING
)
253 SFNT_Table
* OS2_table
= &font
->tables
[sfnt
->OS2_idx
];
256 /* check lower byte of the `fsType' field */
257 if (OS2_table
->buf
[OS2_FSTYPE_OFFSET
+ 1] == 0x02
258 && !font
->ignore_permissions
)
260 error
= TA_Err_Missing_Legal_Permission
;
266 /* build `gasp' table */
267 error
= TA_sfnt_build_gasp_table(&font
->sfnts
[0], font
);
271 /* XXX handle subfonts for bytecode tables */
273 /* build `cvt ' table */
274 error
= TA_sfnt_build_cvt_table(&font
->sfnts
[0], font
);
278 /* build `fpgm' table */
279 error
= TA_sfnt_build_fpgm_table(&font
->sfnts
[0], font
);
283 /* build `prep' table */
284 error
= TA_sfnt_build_prep_table(&font
->sfnts
[0], font
);
288 /* hint the glyphs and build bytecode */
289 error
= TA_sfnt_build_glyf_hints(&font
->sfnts
[0], font
);
293 /* loop again over subfonts */
294 for (i
= 0; i
< font
->num_sfnts
; i
++)
296 SFNT
* sfnt
= &font
->sfnts
[i
];
299 error
= TA_sfnt_build_glyf_table(sfnt
, font
);
302 error
= TA_sfnt_build_loca_table(sfnt
, font
);
305 error
= TA_sfnt_update_maxp_table(sfnt
, font
);
310 if (font
->num_sfnts
== 1)
311 error
= TA_font_build_TTF(font
);
313 error
= TA_font_build_TTC(font
);
319 error
= TA_font_file_write(font
, out_file
);
325 *out_bufp
= (char*)font
->out_buf
;
326 *out_lenp
= font
->out_len
;
332 TA_font_unload(font
, in_buf
, out_bufp
);
336 *error_stringp
= (const unsigned char*)TA_get_error_message(error
);
341 /* end of ttfautohint.c */