Store `glyf' index in `SFNT' structure.
[ttfautohint.git] / src / ttfautohint.c
blobdac401d0982024a8d33b6074fdf8ce7c1021d7cc
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 <stdlib.h>
11 #include <string.h>
13 #include <ft2build.h>
14 #include FT_FREETYPE_H
15 #include FT_TRUETYPE_TABLES_H
16 #include FT_TRUETYPE_TAGS_H
18 #include "ttfautohint.h"
21 /* these macros convert 16bit and 32bit numbers into single bytes */
22 /* using the byte order needed within SFNT files */
24 #define HIGH(x) (FT_Byte)(((x) & 0xFF00) >> 8)
25 #define LOW(x) ((x) & 0x00FF)
27 #define BYTE1(x) (FT_Byte)(((x) & 0xFF000000UL) >> 24);
28 #define BYTE2(x) (FT_Byte)(((x) & 0x00FF0000UL) >> 16);
29 #define BYTE3(x) (FT_Byte)(((x) & 0x0000FF00UL) >> 8);
30 #define BYTE4(x) ((x) & 0x000000FFUL);
33 /* the length of a dummy `DSIG' table */
34 #define DSIG_LEN 8
36 /* an empty slot in the table info array */
37 #define MISSING (FT_ULong)~0
40 /* an SFNT table */
41 typedef struct SFNT_Table_ {
42 FT_ULong tag;
43 FT_ULong len;
44 FT_Byte* buf; /* the table data */
45 FT_ULong offset; /* from beginning of file */
46 FT_ULong checksum;
47 } SFNT_Table;
49 /* we use indices into the SFNT table array to */
50 /* represent table info records in a TTF header */
51 typedef FT_ULong SFNT_Table_Info;
53 /* this structure is used to model a TTF or a subfont within a TTC */
54 typedef struct SFNT_ {
55 FT_Face face;
56 SFNT_Table_Info* table_infos;
57 FT_ULong num_table_infos;
58 FT_ULong glyf_idx; /* this subfont's `glyf' SFNT table index */
59 } SFNT;
61 /* our font object */
62 typedef struct FONT_ {
63 FT_Library lib;
65 FT_Byte* in_buf;
66 size_t in_len;
68 FT_Byte* out_buf;
69 size_t out_len;
71 SFNT* sfnts;
72 FT_Long num_sfnts;
74 SFNT_Table* tables;
75 FT_ULong num_tables;
76 } FONT;
79 static FT_Error
80 TA_font_read(FONT* font,
81 FILE* in)
83 fseek(in, 0, SEEK_END);
84 font->in_len = ftell(in);
85 fseek(in, 0, SEEK_SET);
87 /* a valid TTF can never be that small */
88 if (font->in_len < 100)
89 return FT_Err_Invalid_Argument;
91 font->in_buf = (FT_Byte*)malloc(font->in_len);
92 if (!font->in_buf)
93 return FT_Err_Out_Of_Memory;
95 if (fread(font->in_buf, 1, font->in_len, in) != font->in_len)
96 return FT_Err_Invalid_Stream_Read;
98 return TA_Err_Ok;
102 static FT_Error
103 TA_font_init(FONT* font)
105 FT_Error error;
106 FT_Face f;
109 error = FT_Init_FreeType(&font->lib);
110 if (error)
111 return error;
113 /* get number of faces (i.e. subfonts) */
114 error = FT_New_Memory_Face(font->lib, font->in_buf, font->in_len, -1, &f);
115 if (error)
116 return error;
117 font->num_sfnts = f->num_faces;
118 FT_Done_Face(f);
120 /* it is a TTC if we have more than a single subfont */
121 font->sfnts = (SFNT*)calloc(1, font->num_sfnts * sizeof (SFNT));
122 if (!font->sfnts)
123 return FT_Err_Out_Of_Memory;
125 return TA_Err_Ok;
129 static FT_Error
130 TA_sfnt_add_table_info(SFNT* sfnt)
132 SFNT_Table_Info* table_infos_new;
135 sfnt->num_table_infos++;
136 table_infos_new =
137 (SFNT_Table_Info*)realloc(sfnt->table_infos, sfnt->num_table_infos
138 * sizeof (SFNT_Table_Info));
139 if (!table_infos_new)
141 sfnt->num_table_infos--;
142 return FT_Err_Out_Of_Memory;
144 else
145 sfnt->table_infos = table_infos_new;
147 sfnt->table_infos[sfnt->num_table_infos - 1] = MISSING;
149 return TA_Err_Ok;
153 static FT_ULong
154 TA_table_compute_checksum(FT_Byte* buf,
155 FT_ULong len)
157 FT_Byte* end_buf = buf + len;
158 FT_ULong checksum = 0;
161 while (buf < end_buf)
163 checksum += *(buf++) << 24;
164 checksum += *(buf++) << 16;
165 checksum += *(buf++) << 8;
166 checksum += *(buf++);
169 return checksum;
173 static FT_Error
174 TA_font_add_table(FONT* font,
175 SFNT_Table_Info* table_info,
176 FT_ULong tag,
177 FT_ULong len,
178 FT_Byte* buf)
180 SFNT_Table* tables_new;
181 SFNT_Table* table_last;
184 font->num_tables++;
185 tables_new = (SFNT_Table*)realloc(font->tables,
186 font->num_tables * sizeof (SFNT_Table));
187 if (!tables_new)
189 font->num_tables--;
190 return FT_Err_Out_Of_Memory;
192 else
193 font->tables = tables_new;
195 table_last = &font->tables[font->num_tables - 1];
197 table_last->tag = tag;
198 table_last->len = len;
199 table_last->buf = buf;
200 table_last->checksum = TA_table_compute_checksum(buf, len);
202 /* link table and table info */
203 *table_info = font->num_tables - 1;
205 return TA_Err_Ok;
209 static void
210 TA_sfnt_sort_table_info(SFNT* sfnt,
211 FONT* font)
213 /* Looking into an arbitrary TTF (with a `DSIG' table), tags */
214 /* starting with an uppercase letter are sorted before lowercase */
215 /* letters. In other words, the alphabetical ordering (as */
216 /* mandated by signing a font) is a simple numeric comparison of */
217 /* the 32bit tag values. */
219 SFNT_Table* tables = font->tables;
221 SFNT_Table_Info* table_infos = sfnt->table_infos;
222 FT_ULong num_table_infos = sfnt->num_table_infos;
224 FT_ULong i;
225 FT_ULong j;
228 for (i = 1; i < num_table_infos; i++)
230 for (j = i; j > 0; j--)
232 SFNT_Table_Info swap;
233 FT_ULong tag1;
234 FT_ULong tag2;
237 tag1 = (table_infos[j] == MISSING)
239 : tables[table_infos[j]].tag;
240 tag2 = (table_infos[j - 1] == MISSING)
242 : tables[table_infos[j - 1]].tag;
244 if (tag1 > tag2)
245 break;
247 swap = table_infos[j];
248 table_infos[j] = table_infos[j - 1];
249 table_infos[j - 1] = swap;
255 static FT_Error
256 TA_sfnt_split_into_SFNT_tables(SFNT* sfnt,
257 FONT* font)
259 FT_Error error;
260 FT_ULong i;
263 /* basic check whether font is a TTF or TTC */
264 if (!FT_IS_SFNT(sfnt->face))
265 return FT_Err_Invalid_Argument;
267 error = FT_Sfnt_Table_Info(sfnt->face, 0, NULL, &sfnt->num_table_infos);
268 if (error)
269 return error;
271 sfnt->table_infos = (SFNT_Table_Info*)malloc(sfnt->num_table_infos
272 * sizeof (SFNT_Table_Info));
273 if (!sfnt->table_infos)
274 return FT_Err_Out_Of_Memory;
276 /* collect SFNT tables and search for `glyf' table */
277 sfnt->glyf_idx = MISSING;
278 for (i = 0; i < sfnt->num_table_infos; i++)
280 SFNT_Table_Info* table_info = &sfnt->table_infos[i];
281 FT_ULong tag;
282 FT_ULong len;
283 FT_Byte* buf;
285 FT_ULong buf_len;
286 FT_ULong j;
289 *table_info = MISSING;
291 error = FT_Sfnt_Table_Info(sfnt->face, i, &tag, &len);
292 if (error)
294 /* this ignores both missing and zero-length tables */
295 if (error == FT_Err_Table_Missing)
296 continue;
297 else
298 return error;
301 /* ignore tables which we are going to create by ourselves */
302 else if (tag == TTAG_fpgm
303 || tag == TTAG_prep
304 || tag == TTAG_cvt
305 || tag == TTAG_DSIG)
306 continue;
308 /* make the allocated buffer length a multiple of 4 */
309 buf_len = (len + 3) & -3;
310 buf = (FT_Byte*)malloc(buf_len);
311 if (!buf)
312 return FT_Err_Out_Of_Memory;
314 /* pad end of buffer with zeros */
315 buf[buf_len - 1] = 0x00;
316 buf[buf_len - 2] = 0x00;
317 buf[buf_len - 3] = 0x00;
319 /* load table */
320 error = FT_Load_Sfnt_Table(sfnt->face, tag, 0, buf, &len);
321 if (error)
322 goto Err;
324 /* check whether we already have this table */
325 for (j = 0; j < font->num_tables; j++)
327 SFNT_Table* table = &font->tables[j];
330 if (table->tag == tag
331 && table->len == len
332 && !memcmp(table->buf, buf, len))
333 break;
336 if (tag == TTAG_glyf)
337 sfnt->glyf_idx = j;
339 if (j == font->num_tables)
341 /* add element to table array if it is missing or different; */
342 /* in case of success, `buf' gets linked and is eventually */
343 /* freed in `TA_font_unload' */
344 error = TA_font_add_table(font, table_info, tag, len, buf);
345 if (error)
346 goto Err;
348 else
350 /* reuse existing SFNT table */
351 free(buf);
352 *table_info = j;
354 continue;
356 Err:
357 free(buf);
358 return error;
361 /* no (non-empty) `glyf' table; this can't be a TTF with outlines */
362 if (sfnt->glyf_idx == MISSING)
363 return FT_Err_Invalid_Argument;
365 return TA_Err_Ok;
369 /* we build a dummy `DSIG' table only */
371 static FT_Error
372 TA_table_construct_DSIG(FT_Byte** DSIG)
374 FT_Byte* buf;
377 buf = (FT_Byte*)malloc(DSIG_LEN);
378 if (!buf)
379 return FT_Err_Out_Of_Memory;
381 /* version */
382 buf[0] = 0x00;
383 buf[1] = 0x00;
384 buf[2] = 0x00;
385 buf[3] = 0x01;
387 /* zero signatures */
388 buf[4] = 0x00;
389 buf[5] = 0x00;
391 /* permission flags */
392 buf[6] = 0x00;
393 buf[7] = 0x00;
395 *DSIG = buf;
397 return TA_Err_Ok;
401 static void
402 TA_font_compute_table_offsets(FONT* font,
403 FT_ULong start)
405 FT_ULong i;
406 FT_ULong offset = start;
409 for (i = 0; i < font->num_tables; i++)
411 SFNT_Table* table = &font->tables[i];
414 table->offset = offset;
416 /* table offsets must be multiples of 4; */
417 /* this also fits the actual buffer lengths */
418 offset += (table->len + 3) & ~3;
423 /* If `do_complete' is 0, only return `header_len'. */
425 static FT_Error
426 TA_sfnt_construct_TTF_header(SFNT* sfnt,
427 FONT* font,
428 FT_Byte** header_buf,
429 FT_ULong* header_len,
430 FT_Int do_complete)
432 SFNT_Table* tables = font->tables;
434 SFNT_Table_Info* table_infos = sfnt->table_infos;
435 FT_ULong num_table_infos = sfnt->num_table_infos;
437 FT_Byte* buf;
438 FT_ULong len;
440 FT_Byte* table_record;
442 FT_Byte* head_buf = NULL; /* pointer to `head' table */
443 FT_ULong head_checksum; /* checksum in `head' table */
445 FT_ULong num_tables_in_header;
446 FT_ULong i;
449 num_tables_in_header = 0;
450 for (i = 0; i < num_table_infos; i++)
452 /* ignore empty tables */
453 if (table_infos[i] != MISSING)
454 num_tables_in_header++;
457 len = 12 + 16 * num_tables_in_header;
458 if (!do_complete)
460 *header_len = len;
461 return TA_Err_Ok;
463 buf = (FT_Byte*)malloc(len);
464 if (!buf)
465 return FT_Err_Out_Of_Memory;
467 /* SFNT version */
468 buf[0] = 0x00;
469 buf[1] = 0x01;
470 buf[2] = 0x00;
471 buf[3] = 0x00;
473 /* number of tables */
474 buf[4] = HIGH(num_tables_in_header);
475 buf[5] = LOW(num_tables_in_header);
477 /* auxiliary data */
479 FT_ULong search_range, entry_selector, range_shift;
480 FT_ULong i, j;
483 for (i = 1, j = 2; j <= num_tables_in_header; i++, j <<= 1)
486 entry_selector = i - 1;
487 search_range = 0x10 << entry_selector;
488 range_shift = (num_tables_in_header << 4) - search_range;
490 buf[6] = HIGH(search_range);
491 buf[7] = LOW(search_range);
492 buf[8] = HIGH(entry_selector);
493 buf[9] = LOW(entry_selector);
494 buf[10] = HIGH(range_shift);
495 buf[11] = LOW(range_shift);
498 /* location of the first table info record */
499 table_record = &buf[12];
501 head_checksum = 0;
503 /* loop over all tables */
504 for (i = 0; i < num_table_infos; i++)
506 SFNT_Table_Info table_info = table_infos[i];
507 SFNT_Table* table;
510 /* ignore empty slots */
511 if (table_info == MISSING)
512 continue;
514 table = &tables[table_info];
516 if (table->tag == TTAG_head)
518 /* we always reach this IF clause since FreeType would */
519 /* have aborted already if the `head' table were missing */
521 head_buf = table->buf;
523 /* reset checksum in `head' table for recalculation */
524 head_buf[8] = 0x00;
525 head_buf[9] = 0x00;
526 head_buf[10] = 0x00;
527 head_buf[11] = 0x00;
530 head_checksum += table->checksum;
532 table_record[0] = BYTE1(table->tag);
533 table_record[1] = BYTE2(table->tag);
534 table_record[2] = BYTE3(table->tag);
535 table_record[3] = BYTE4(table->tag);
537 table_record[4] = BYTE1(table->checksum);
538 table_record[5] = BYTE2(table->checksum);
539 table_record[6] = BYTE3(table->checksum);
540 table_record[7] = BYTE4(table->checksum);
542 table_record[8] = BYTE1(table->offset);
543 table_record[9] = BYTE2(table->offset);
544 table_record[10] = BYTE3(table->offset);
545 table_record[11] = BYTE4(table->offset);
547 table_record[12] = BYTE1(table->len);
548 table_record[13] = BYTE2(table->len);
549 table_record[14] = BYTE3(table->len);
550 table_record[15] = BYTE4(table->len);
552 table_record += 16;
555 /* the font header is complete; compute `head' checksum */
556 head_checksum += TA_table_compute_checksum(buf, len);
557 head_checksum = 0xB1B0AFBAUL - head_checksum;
559 /* store checksum in `head' table; */
560 head_buf[8] = BYTE1(head_checksum);
561 head_buf[9] = BYTE2(head_checksum);
562 head_buf[10] = BYTE3(head_checksum);
563 head_buf[11] = BYTE4(head_checksum);
565 *header_buf = buf;
566 *header_len = len;
568 return TA_Err_Ok;
572 static FT_Error
573 TA_font_build_TTF(FONT* font)
575 SFNT* sfnt = &font->sfnts[0];
577 SFNT_Table* tables;
578 FT_ULong num_tables;
580 FT_ULong SFNT_offset;
582 FT_Byte* DSIG_buf;
584 FT_Byte* header_buf;
585 FT_ULong header_len;
587 FT_ULong i;
588 FT_Error error;
591 /* add a dummy `DSIG' table */
593 error = TA_sfnt_add_table_info(sfnt);
594 if (error)
595 return error;
597 error = TA_table_construct_DSIG(&DSIG_buf);
598 if (error)
599 return error;
601 /* in case of success, `DSIG_buf' gets linked */
602 /* and is eventually freed in `TA_font_unload' */
603 error = TA_font_add_table(font,
604 &sfnt->table_infos[sfnt->num_table_infos - 1],
605 TTAG_DSIG, DSIG_LEN, DSIG_buf);
606 if (error)
608 free(DSIG_buf);
609 return error;
612 TA_sfnt_sort_table_info(sfnt, font);
614 /* the first SFNT table immediately follows the header */
615 (void)TA_sfnt_construct_TTF_header(sfnt, font, NULL, &SFNT_offset, 0);
616 TA_font_compute_table_offsets(font, SFNT_offset);
618 error = TA_sfnt_construct_TTF_header(sfnt, font,
619 &header_buf, &header_len, 1);
620 if (error)
621 return error;
623 /* build font */
625 tables = font->tables;
626 num_tables = font->num_tables;
628 font->out_len = tables[num_tables - 1].offset
629 + ((tables[num_tables - 1].len + 3) & ~3);
630 font->out_buf = (FT_Byte*)malloc(font->out_len);
631 if (!font->out_buf)
633 error = FT_Err_Out_Of_Memory;
634 goto Err;
637 memcpy(font->out_buf, header_buf, header_len);
639 for (i = 0; i < num_tables; i++)
641 SFNT_Table* table = &tables[i];
644 /* buffer length is a multiple of 4 */
645 memcpy(font->out_buf + table->offset,
646 table->buf, (table->len + 3) & ~3);
649 error = TA_Err_Ok;
651 Err:
652 free(header_buf);
654 return error;
658 static FT_Error
659 TA_font_construct_TTC_header(FONT* font,
660 FT_Byte** header_buf,
661 FT_ULong* header_len)
663 SFNT* sfnts = font->sfnts;
664 FT_Long num_sfnts = font->num_sfnts;
666 SFNT_Table* tables = font->tables;
667 FT_ULong num_tables = font->num_tables;
669 FT_ULong TTF_offset;
670 FT_ULong DSIG_offset;
672 FT_Byte* buf;
673 FT_ULong len;
675 FT_Long i;
676 FT_Byte* p;
679 len = 24 + 4 * num_sfnts;
680 buf = (FT_Byte*)malloc(len);
681 if (!buf)
682 return FT_Err_Out_Of_Memory;
684 p = buf;
686 /* TTC ID string */
687 *(p++) = 't';
688 *(p++) = 't';
689 *(p++) = 'c';
690 *(p++) = 'f';
692 /* TTC header version */
693 *(p++) = 0x00;
694 *(p++) = 0x02;
695 *(p++) = 0x00;
696 *(p++) = 0x00;
698 /* number of subfonts */
699 *(p++) = BYTE1(num_sfnts);
700 *(p++) = BYTE2(num_sfnts);
701 *(p++) = BYTE3(num_sfnts);
702 *(p++) = BYTE4(num_sfnts);
704 /* the first TTF subfont header immediately follows the TTC header */
705 TTF_offset = len;
707 /* loop over all subfonts */
708 for (i = 0; i < num_sfnts; i++)
710 SFNT* sfnt = &sfnts[i];
711 FT_ULong l;
714 TA_sfnt_sort_table_info(sfnt, font);
715 /* only get header length */
716 (void)TA_sfnt_construct_TTF_header(sfnt, font, NULL, &l, 0);
718 *(p++) = BYTE1(TTF_offset);
719 *(p++) = BYTE2(TTF_offset);
720 *(p++) = BYTE3(TTF_offset);
721 *(p++) = BYTE4(TTF_offset);
723 TTF_offset += l;
726 /* the first SFNT table immediately follows the subfont TTF headers */
727 TA_font_compute_table_offsets(font, TTF_offset);
729 /* DSIG tag */
730 *(p++) = 'D';
731 *(p++) = 'S';
732 *(p++) = 'I';
733 *(p++) = 'G';
735 /* DSIG length */
736 *(p++) = 0x00;
737 *(p++) = 0x00;
738 *(p++) = 0x00;
739 *(p++) = 0x08;
741 /* DSIG offset; in a TTC this is always the last SFNT table */
742 DSIG_offset = tables[num_tables - 1].offset;
744 *(p++) = BYTE1(DSIG_offset);
745 *(p++) = BYTE2(DSIG_offset);
746 *(p++) = BYTE3(DSIG_offset);
747 *(p++) = BYTE4(DSIG_offset);
749 *header_buf = buf;
750 *header_len = len;
752 return TA_Err_Ok;
756 static FT_Error
757 TA_font_build_TTC(FONT* font)
759 SFNT* sfnts = font->sfnts;
760 FT_Long num_sfnts = font->num_sfnts;
762 SFNT_Table* tables;
763 FT_ULong num_tables;
765 FT_Byte* DSIG_buf;
766 SFNT_Table_Info dummy;
768 FT_Byte* TTC_header_buf;
769 FT_ULong TTC_header_len;
771 FT_Byte** TTF_header_bufs;
772 FT_ULong* TTF_header_lens;
774 FT_ULong offset;
775 FT_Long i;
776 FT_ULong j;
777 FT_Error error;
780 /* add a dummy `DSIG' table */
782 error = TA_table_construct_DSIG(&DSIG_buf);
783 if (error)
784 return error;
786 /* in case of success, `DSIG_buf' gets linked */
787 /* and is eventually freed in `TA_font_unload' */
788 error = TA_font_add_table(font, &dummy, TTAG_DSIG, DSIG_LEN, DSIG_buf);
789 if (error)
791 free(DSIG_buf);
792 return error;
795 /* this also computes the SFNT table offsets */
796 error = TA_font_construct_TTC_header(font,
797 &TTC_header_buf, &TTC_header_len);
798 if (error)
799 return error;
801 TTF_header_bufs = (FT_Byte**)calloc(1, num_sfnts * sizeof (FT_Byte*));
802 if (!TTF_header_bufs)
803 goto Err;
805 TTF_header_lens = (FT_ULong*)malloc(num_sfnts * sizeof (FT_ULong));
806 if (!TTF_header_lens)
807 goto Err;
809 for (i = 0; i < num_sfnts; i++)
811 error = TA_sfnt_construct_TTF_header(&sfnts[i], font,
812 &TTF_header_bufs[i],
813 &TTF_header_lens[i], 1);
814 if (error)
815 goto Err;
818 /* build font */
820 tables = font->tables;
821 num_tables = font->num_tables;
823 font->out_len = tables[num_tables - 1].offset
824 + ((tables[num_tables - 1].len + 3) & ~3);
825 font->out_buf = (FT_Byte*)malloc(font->out_len);
826 if (!font->out_buf)
828 error = FT_Err_Out_Of_Memory;
829 goto Err;
832 memcpy(font->out_buf, TTC_header_buf, TTC_header_len);
834 offset = TTC_header_len;
836 for (i = 0; i < num_sfnts; i++)
838 memcpy(font->out_buf + offset,
839 TTF_header_bufs[i], TTF_header_lens[i]);
841 offset += TTF_header_lens[i];
844 for (j = 0; j < num_tables; j++)
846 SFNT_Table* table = &tables[j];
849 /* buffer length is a multiple of 4 */
850 memcpy(font->out_buf + table->offset,
851 table->buf, (table->len + 3) & ~3);
854 error = TA_Err_Ok;
856 Err:
857 free(TTC_header_buf);
858 if (TTF_header_bufs)
860 for (i = 0; i < font->num_sfnts; i++)
861 free(TTF_header_bufs[i]);
862 free(TTF_header_bufs);
864 free(TTF_header_lens);
866 return error;
870 static FT_Error
871 TA_font_write(FONT* font,
872 FILE* out)
874 if (fwrite(font->out_buf, 1, font->out_len, out) != font->out_len)
875 return TA_Err_Invalid_Stream_Write;
877 return TA_Err_Ok;
881 static void
882 TA_font_unload(FONT* font)
884 /* in case of error it is expected that unallocated pointers */
885 /* are NULL (and counters are zero) */
887 if (!font)
888 return;
890 if (font->tables)
892 FT_ULong i;
895 for (i = 0; i < font->num_tables; i++)
896 free(font->tables[i].buf);
897 free(font->tables);
900 if (font->sfnts)
902 FT_Long i;
905 for (i = 0; i < font->num_sfnts; i++)
907 FT_Done_Face(font->sfnts[i].face);
908 free(font->sfnts[i].table_infos);
910 free(font->sfnts);
913 FT_Done_FreeType(font->lib);
914 free(font->in_buf);
915 free(font->out_buf);
916 free(font);
920 TA_Error
921 TTF_autohint(FILE* in,
922 FILE* out)
924 FONT* font;
925 FT_Error error;
926 FT_Long i;
929 font = (FONT*)calloc(1, sizeof (FONT));
930 if (!font)
931 return FT_Err_Out_Of_Memory;
933 error = TA_font_read(font, in);
934 if (error)
935 goto Err;
937 error = TA_font_init(font);
938 if (error)
939 goto Err;
941 /* loop over subfonts */
942 for (i = 0; i < font->num_sfnts; i++)
944 SFNT* sfnt = &font->sfnts[i];
947 error = FT_New_Memory_Face(font->lib, font->in_buf, font->in_len,
948 i, &sfnt->face);
949 if (error)
950 goto Err;
952 error = TA_sfnt_split_into_SFNT_tables(sfnt, font);
953 if (error)
954 goto Err;
957 /* compute global hints */
958 /* construct `fpgm' table */
959 /* construct `prep' table */
960 /* construct `cvt ' table */
962 /* split `glyf' table */
963 /* handle all glyphs in a loop */
964 /* strip bytecode */
965 /* hint the glyph */
966 /* construct bytecode */
968 /* construct `glyf' table */
970 if (font->num_sfnts == 1)
971 error = TA_font_build_TTF(font);
972 else
973 error = TA_font_build_TTC(font);
974 if (error)
975 goto Err;
977 error = TA_font_write(font, out);
978 if (error)
979 goto Err;
981 error = TA_Err_Ok;
983 Err:
984 TA_font_unload(font);
986 return error;
989 /* end of ttfautohint.c */