Nitpick.
[ttfautohint.git] / src / ttfautohint.c
bloba503ec389c049d716a2a6d5e57661b92cb8fd943
1 /* ttfautohint.c */
3 /* written 2011 by Werner Lemberg <wl@gnu.org> */
5 /* This file needs FreeType 2.4.5 or newer. */
8 #include <config.h>
9 #include <stdio.h>
10 #include <string.h>
12 #include <ft2build.h>
13 #include FT_FREETYPE_H
14 #include FT_TRUETYPE_TABLES_H
15 #include FT_TRUETYPE_TAGS_H
17 #include "ttfautohint.h"
20 /* these macros convert 16bit and 32bit numbers into single bytes */
21 /* using the byte order needed within SFNT files */
23 #define HIGH(x) (FT_Byte)(((x) & 0xFF00) >> 8)
24 #define LOW(x) ((x) & 0x00FF)
26 #define BYTE1(x) (FT_Byte)(((x) & 0xFF000000UL) >> 24);
27 #define BYTE2(x) (FT_Byte)(((x) & 0x00FF0000UL) >> 16);
28 #define BYTE3(x) (FT_Byte)(((x) & 0x0000FF00UL) >> 8);
29 #define BYTE4(x) ((x) & 0x000000FFUL);
32 /* this structure represents both the data contained in the SFNT */
33 /* table records and the actual SFNT table data */
34 typedef struct SFNT_Table_ {
35 FT_ULong tag;
36 FT_ULong len;
37 FT_Byte* buf;
38 FT_ULong offset; /* used while building output font only */
39 } SFNT_Table;
41 /* this structure is used to model a TTF or a subfont within a TTC */
42 typedef struct SFNT_ {
43 FT_Face face;
44 SFNT_Table* table_infos;
45 FT_ULong num_table_infos;
46 } SFNT;
48 /* our font object */
49 typedef struct FONT_ {
50 FT_Library lib;
52 FT_Byte* in_buf;
53 size_t in_len;
55 FT_Byte* out_buf;
56 size_t out_len;
58 SFNT* sfnts;
59 FT_Long num_sfnts;
61 SFNT_Table* tables;
62 FT_ULong num_tables;
63 } FONT;
66 static FT_Error
67 TA_font_read(FILE* in,
68 FONT* font)
70 fseek(in, 0, SEEK_END);
71 font->in_len = ftell(in);
72 fseek(in, 0, SEEK_SET);
74 /* a valid TTF can never be that small */
75 if (font->in_len < 100)
76 return FT_Err_Invalid_Argument;
78 font->in_buf = (FT_Byte*)malloc(font->in_len * sizeof (FT_Byte));
79 if (!font->in_buf)
80 return FT_Err_Out_Of_Memory;
82 if (fread(font->in_buf, 1, font->in_len, in) != font->in_len)
83 return FT_Err_Invalid_Stream_Read;
85 return TA_Err_Ok;
89 static FT_Error
90 TA_font_init(FONT* font)
92 FT_Error error;
93 FT_Face f;
96 error = FT_Init_FreeType(&font->lib);
97 if (error)
98 return error;
100 /* get number of faces (i.e. subfonts) */
101 error = FT_New_Memory_Face(font->lib, font->in_buf, font->in_len, -1, &f);
102 if (error)
103 return error;
104 font->num_sfnts = f->num_faces;
105 FT_Done_Face(f);
107 /* it is a TTC if we have more than a single subfont */
108 font->sfnts = (SFNT*)calloc(1, font->num_sfnts * sizeof (SFNT));
109 if (!font->sfnts)
110 return FT_Err_Out_Of_Memory;
112 return TA_Err_Ok;
116 static FT_Error
117 TA_sfnt_collect_table_info(SFNT* sfnt)
119 FT_Error error;
120 FT_ULong glyf_idx;
121 FT_ULong i;
124 /* check that font is TTF or TTC */
125 if (!FT_IS_SFNT(sfnt->face))
126 return FT_Err_Invalid_Argument;
128 error = FT_Sfnt_Table_Info(sfnt->face, 0, NULL, &sfnt->num_table_infos);
129 if (error)
130 return error;
132 sfnt->table_infos =
133 (SFNT_Table*)calloc(1, sfnt->num_table_infos * sizeof (SFNT_Table));
134 if (!sfnt->table_infos)
135 return FT_Err_Out_Of_Memory;
137 /* collect SFNT table information and search for `glyf' table */
138 glyf_idx = sfnt->num_table_infos;
139 for (i = 0; i < sfnt->num_table_infos; i++)
141 FT_ULong tag, len;
144 error = FT_Sfnt_Table_Info(sfnt->face, i, &tag, &len);
145 if (error && error != FT_Err_Table_Missing)
146 return error;
148 if (!error)
150 if (tag == TTAG_glyf)
151 glyf_idx = i;
153 /* ignore tables which we are going to create by ourselves */
154 if (!(tag == TTAG_fpgm
155 || tag == TTAG_prep
156 || tag == TTAG_cvt
157 || tag == TTAG_DSIG))
159 sfnt->table_infos[i].tag = tag;
160 sfnt->table_infos[i].len = len;
165 /* no (non-empty) `glyf' table; this can't be a TTF with outlines */
166 if (glyf_idx == sfnt->num_table_infos)
167 return FT_Err_Invalid_Argument;
169 return TA_Err_Ok;
173 static FT_Error
174 TA_font_add_table(FONT* font,
175 SFNT_Table* table_info,
176 FT_Byte* buf)
178 SFNT_Table* tables_new;
179 SFNT_Table* table_last;
182 font->num_tables++;
183 tables_new = (SFNT_Table*)realloc(font->tables,
184 font->num_tables * sizeof (SFNT_Table));
185 if (!tables_new)
186 return FT_Err_Out_Of_Memory;
187 else
188 font->tables = tables_new;
190 table_last = &font->tables[font->num_tables - 1];
192 table_last->tag = table_info->tag;
193 table_last->len = table_info->len;
194 table_last->buf = buf;
196 /* link buffer pointer */
197 table_info->buf = table_last->buf;
199 return TA_Err_Ok;
203 static FT_Error
204 TA_font_split_into_SFNT_tables(SFNT* sfnt,
205 FONT* font)
207 FT_Error error;
208 FT_ULong i;
211 for (i = 0; i < sfnt->num_table_infos; i++)
213 SFNT_Table* table_info = &sfnt->table_infos[i];
216 /* we ignore empty tables */
217 if (table_info->len)
219 FT_Byte* buf;
220 FT_ULong len;
221 FT_ULong j;
224 /* make the allocated buffer length a multiple of 4; */
225 /* this simplifies writing the tables back */
226 len = (table_info->len + 3) & ~3;
228 buf = (FT_Byte*)malloc(len * sizeof (FT_Byte));
229 if (!buf)
230 return FT_Err_Out_Of_Memory;
232 /* pad buffer with zeros */
233 buf[len - 1] = 0;
234 buf[len - 2] = 0;
235 buf[len - 3] = 0;
237 /* load table */
238 error = FT_Load_Sfnt_Table(sfnt->face, table_info->tag, 0,
239 buf, &table_info->len);
240 if (error)
241 goto Err;
243 /* check whether we already have this table */
244 for (j = 0; j < font->num_tables; j++)
246 SFNT_Table* table = &font->tables[j];
249 if (table->tag == table_info->tag
250 && table->len == table_info->len
251 && !memcmp(table->buf, buf, table->len))
252 break;
255 if (j == font->num_tables)
257 /* add element to table array if it is missing or different */
258 error = TA_font_add_table(font, table_info, buf);
259 if (error)
260 goto Err;
262 else
264 free(buf);
265 table_info->buf = font->tables[j].buf;
267 continue;
269 Err:
270 free(buf);
271 return error;
275 return TA_Err_Ok;
279 static FT_ULong
280 TA_table_compute_checksum(FT_Byte* buf,
281 FT_ULong len)
283 FT_Byte* end_buf = buf + len;
284 FT_ULong checksum = 0;
287 while (buf < end_buf)
289 checksum += *(buf++) << 24;
290 checksum += *(buf++) << 16;
291 checksum += *(buf++) << 8;
292 checksum += *(buf++);
295 return checksum;
299 static FT_Error
300 TA_font_build_TTF(FONT* font)
302 SFNT* sfnt = &font->sfnts[0];
303 SFNT_Table* table_infos = sfnt->table_infos;
304 FT_ULong num_table_infos = sfnt->num_table_infos;
306 FT_ULong num_tables_in_header;
308 FT_Byte* header_buf;
309 FT_ULong header_len;
311 FT_Byte* head_buf = NULL;
312 FT_ULong head_checksum; /* checksum in `head' table */
314 FT_Byte* table_record;
315 FT_ULong table_offset;
317 FT_ULong i;
318 FT_Error error;
321 num_tables_in_header = 0;
323 for (i = 0; i < num_table_infos; i++)
325 /* ignore empty tables */
326 if (table_infos[i].len)
327 num_tables_in_header++;
330 if (num_tables_in_header > 0xFFFF)
331 return FT_Err_Array_Too_Large;
333 /* construct TTF header */
335 header_len = 12 + 16 * num_tables_in_header;
336 header_buf = (FT_Byte*)malloc(header_len * sizeof (FT_Byte));
337 if (!header_buf)
338 return FT_Err_Out_Of_Memory;
340 /* SFNT version */
341 header_buf[0] = 0x00;
342 header_buf[1] = 0x01;
343 header_buf[2] = 0x00;
344 header_buf[3] = 0x00;
346 /* number of tables */
347 header_buf[4] = HIGH(num_tables_in_header);
348 header_buf[5] = LOW(num_tables_in_header);
350 /* auxiliary data */
352 FT_ULong search_range, entry_selector, range_shift;
353 FT_ULong i, j;
356 for (i = 1, j = 2; j <= num_tables_in_header; i++, j <<= 1)
359 entry_selector = i - 1;
360 search_range = 0x10 << entry_selector;
361 range_shift = (num_tables_in_header << 4) - search_range;
363 header_buf[6] = HIGH(search_range);
364 header_buf[7] = LOW(search_range);
365 header_buf[8] = HIGH(entry_selector);
366 header_buf[9] = LOW(entry_selector);
367 header_buf[10] = HIGH(range_shift);
368 header_buf[11] = LOW(range_shift);
371 /* location of the first table record */
372 table_record = &header_buf[12];
373 /* the first table immediately follows the header */
374 table_offset = header_len;
376 head_checksum = 0;
378 /* loop over all tables */
379 for (i = 0; i < num_table_infos; i++)
381 SFNT_Table *table_info = &table_infos[i];
382 FT_ULong table_checksum;
385 /* ignore empty tables */
386 if (!table_info->len)
387 continue;
389 table_info->offset = table_offset;
391 if (table_info->tag == TTAG_head)
393 /* we always reach this IF clause since FreeType would */
394 /* have aborted already if the `head' table were missing */
396 head_buf = table_info->buf;
398 /* reset checksum in `head' table for recalculation */
399 head_buf[8] = 0x00;
400 head_buf[9] = 0x00;
401 head_buf[10] = 0x00;
402 head_buf[11] = 0x00;
405 table_checksum = TA_table_compute_checksum(table_info->buf,
406 table_info->len);
407 head_checksum += table_checksum;
409 table_record[0] = BYTE1(table_info->tag);
410 table_record[1] = BYTE2(table_info->tag);
411 table_record[2] = BYTE3(table_info->tag);
412 table_record[3] = BYTE4(table_info->tag);
414 table_record[4] = BYTE1(table_checksum);
415 table_record[5] = BYTE2(table_checksum);
416 table_record[6] = BYTE3(table_checksum);
417 table_record[7] = BYTE4(table_checksum);
419 table_record[8] = BYTE1(table_offset);
420 table_record[9] = BYTE2(table_offset);
421 table_record[10] = BYTE3(table_offset);
422 table_record[11] = BYTE4(table_offset);
424 table_record[12] = BYTE1(table_info->len);
425 table_record[13] = BYTE2(table_info->len);
426 table_record[14] = BYTE3(table_info->len);
427 table_record[15] = BYTE4(table_info->len);
429 table_record += 16;
430 /* table offsets must be a multiple of 4; */
431 /* this also fits the actual buffer length */
432 table_offset += (table_info->len + 3) & ~3;
435 /* the font header is complete; compute `head' checksum */
436 head_checksum += TA_table_compute_checksum(header_buf, header_len);
437 head_checksum = 0xB1B0AFBAUL - head_checksum;
439 /* store checksum in `head' table; */
440 head_buf[8] = BYTE1(head_checksum);
441 head_buf[9] = BYTE2(head_checksum);
442 head_buf[10] = BYTE3(head_checksum);
443 head_buf[11] = BYTE4(head_checksum);
445 /* build font */
446 font->out_len = table_offset;
447 font->out_buf = (FT_Byte*)malloc(font->out_len * sizeof (FT_Byte));
448 if (!font->out_buf)
450 error = FT_Err_Out_Of_Memory;
451 goto Err;
454 memcpy(font->out_buf, header_buf, header_len);
456 for (i = 0; i < num_table_infos; i++)
458 SFNT_Table *table_info = &table_infos[i];
461 if (!table_info->len)
462 continue;
464 /* buffer length is a multiple of 4 */
465 memcpy(font->out_buf + table_info->offset,
466 table_info->buf, (table_info->len + 3) & ~3);
469 error = TA_Err_Ok;
471 Err:
472 free(header_buf);
474 return error;
478 static FT_Error
479 TA_font_build_TTC(FONT* font)
481 return TA_Err_Ok;
485 static FT_Error
486 TA_font_write(FILE* out,
487 FONT* font)
489 if (fwrite(font->out_buf, 1, font->out_len, out) != font->out_len)
490 return TA_Err_Invalid_Stream_Write;
492 return TA_Err_Ok;
496 static void
497 TA_font_unload(FONT* font)
499 /* in case of error it is expected that unallocated pointers */
500 /* are NULL (and counters are zero) */
502 if (!font)
503 return;
505 if (font->tables)
507 FT_ULong i;
510 for (i = 0; i < font->num_tables; i++)
511 free(font->tables[i].buf);
512 free(font->tables);
515 if (font->sfnts)
517 FT_Long i;
520 for (i = 0; i < font->num_sfnts; i++)
522 FT_Done_Face(font->sfnts[i].face);
523 free(font->sfnts[i].table_infos);
525 free(font->sfnts);
528 FT_Done_FreeType(font->lib);
529 free(font->in_buf);
530 free(font->out_buf);
531 free(font);
535 TA_Error
536 TTF_autohint(FILE* in,
537 FILE* out)
539 FONT* font;
540 FT_Error error;
541 FT_Long i;
544 font = (FONT*)calloc(1, sizeof (FONT));
545 if (!font)
546 return FT_Err_Out_Of_Memory;
548 error = TA_font_read(in, font);
549 if (error)
550 goto Err;
552 error = TA_font_init(font);
553 if (error)
554 goto Err;
556 /* loop over subfonts */
557 for (i = 0; i < font->num_sfnts; i++)
559 SFNT* sfnt = &font->sfnts[i];
562 error = FT_New_Memory_Face(font->lib, font->in_buf, font->in_len,
563 i, &sfnt->face);
564 if (error)
565 goto Err;
567 error = TA_sfnt_collect_table_info(sfnt);
568 if (error)
569 goto Err;
571 error = TA_font_split_into_SFNT_tables(sfnt, font);
572 if (error)
573 goto Err;
577 /* compute global hints */
578 /* construct `fpgm' table */
579 /* construct `prep' table */
580 /* construct `cvt ' table */
582 /* split `glyf' table */
583 /* handle all glyphs in a loop */
584 /* strip bytecode */
585 /* hint the glyph */
586 /* construct bytecode */
588 /* construct `glyf' table */
590 /* build font from SFNT tables */
591 if (font->num_sfnts == 1)
592 error = TA_font_build_TTF(font);
593 else
594 error = TA_font_build_TTC(font);
595 if (error)
596 goto Err;
598 /* write font from memory */
599 error = TA_font_write(out, font);
600 if (error)
601 goto Err;
603 error = TA_Err_Ok;
605 Err:
606 TA_font_unload(font);
608 return error;
611 /* end of ttfautohint.c */