Function renaming.
[ttfautohint.git] / src / ttfautohint.c
blobfe0456459e4b9541c4ffd227d5ef621956b70a63
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 /* composite glyph flags */
41 #define ARGS_ARE_WORDS 0x0001
42 #define ARGS_ARE_XY_VALUES 0x0002
43 #define WE_HAVE_A_SCALE 0x0008
44 #define MORE_COMPONENTS 0x0020
45 #define WE_HAVE_AN_XY_SCALE 0x0040
46 #define WE_HAVE_A_2X2 0x0080
47 #define WE_HAVE_INSTR 0x0100
50 /* a single glyph */
51 typedef struct GLYPH_
53 FT_ULong len;
54 FT_Byte* buf;
55 } GLYPH;
57 /* a representation of the data in the `glyf' table */
58 typedef struct glyf_Data_
60 FT_UShort num_glyphs;
61 GLYPH* glyphs;
62 } glyf_Data;
64 /* an SFNT table */
65 typedef struct SFNT_Table_ {
66 FT_ULong tag;
67 FT_ULong len;
68 FT_Byte* buf; /* the table data */
69 FT_ULong offset; /* from beginning of file */
70 FT_ULong checksum;
71 void* data;
72 } SFNT_Table;
74 /* we use indices into the SFNT table array to */
75 /* represent table info records in a TTF header */
76 typedef FT_ULong SFNT_Table_Info;
78 /* this structure is used to model a TTF or a subfont within a TTC */
79 typedef struct SFNT_ {
80 FT_Face face;
82 SFNT_Table_Info* table_infos;
83 FT_ULong num_table_infos;
85 FT_ULong glyf_idx; /* this subfont's `glyf' SFNT table index */
86 FT_ULong loca_idx; /* this subfont's `loca' SFNT table index */
87 FT_Byte loca_format; /* `indexToLocFormat' from `head' table */
88 } SFNT;
90 /* our font object */
91 typedef struct FONT_ {
92 FT_Library lib;
94 FT_Byte* in_buf;
95 size_t in_len;
97 FT_Byte* out_buf;
98 size_t out_len;
100 SFNT* sfnts;
101 FT_Long num_sfnts;
103 SFNT_Table* tables;
104 FT_ULong num_tables;
105 } FONT;
108 static FT_Error
109 TA_font_read(FONT* font,
110 FILE* in)
112 fseek(in, 0, SEEK_END);
113 font->in_len = ftell(in);
114 fseek(in, 0, SEEK_SET);
116 /* a valid TTF can never be that small */
117 if (font->in_len < 100)
118 return FT_Err_Invalid_Argument;
120 font->in_buf = (FT_Byte*)malloc(font->in_len);
121 if (!font->in_buf)
122 return FT_Err_Out_Of_Memory;
124 if (fread(font->in_buf, 1, font->in_len, in) != font->in_len)
125 return FT_Err_Invalid_Stream_Read;
127 return TA_Err_Ok;
131 static FT_Error
132 TA_font_init(FONT* font)
134 FT_Error error;
135 FT_Face f;
138 error = FT_Init_FreeType(&font->lib);
139 if (error)
140 return error;
142 /* get number of faces (i.e. subfonts) */
143 error = FT_New_Memory_Face(font->lib, font->in_buf, font->in_len, -1, &f);
144 if (error)
145 return error;
146 font->num_sfnts = f->num_faces;
147 FT_Done_Face(f);
149 /* it is a TTC if we have more than a single subfont */
150 font->sfnts = (SFNT*)calloc(1, font->num_sfnts * sizeof (SFNT));
151 if (!font->sfnts)
152 return FT_Err_Out_Of_Memory;
154 return TA_Err_Ok;
158 static FT_Error
159 TA_sfnt_add_table_info(SFNT* sfnt)
161 SFNT_Table_Info* table_infos_new;
164 sfnt->num_table_infos++;
165 table_infos_new =
166 (SFNT_Table_Info*)realloc(sfnt->table_infos, sfnt->num_table_infos
167 * sizeof (SFNT_Table_Info));
168 if (!table_infos_new)
170 sfnt->num_table_infos--;
171 return FT_Err_Out_Of_Memory;
173 else
174 sfnt->table_infos = table_infos_new;
176 sfnt->table_infos[sfnt->num_table_infos - 1] = MISSING;
178 return TA_Err_Ok;
182 static FT_ULong
183 TA_table_compute_checksum(FT_Byte* buf,
184 FT_ULong len)
186 FT_Byte* end_buf = buf + len;
187 FT_ULong checksum = 0;
190 while (buf < end_buf)
192 checksum += *(buf++) << 24;
193 checksum += *(buf++) << 16;
194 checksum += *(buf++) << 8;
195 checksum += *(buf++);
198 return checksum;
202 static FT_Error
203 TA_font_add_table(FONT* font,
204 SFNT_Table_Info* table_info,
205 FT_ULong tag,
206 FT_ULong len,
207 FT_Byte* buf)
209 SFNT_Table* tables_new;
210 SFNT_Table* table_last;
213 font->num_tables++;
214 tables_new = (SFNT_Table*)realloc(font->tables,
215 font->num_tables * sizeof (SFNT_Table));
216 if (!tables_new)
218 font->num_tables--;
219 return FT_Err_Out_Of_Memory;
221 else
222 font->tables = tables_new;
224 table_last = &font->tables[font->num_tables - 1];
226 table_last->tag = tag;
227 table_last->len = len;
228 table_last->buf = buf;
229 table_last->checksum = TA_table_compute_checksum(buf, len);
230 table_last->offset = 0; /* set in `TA_font_compute_table_offsets' */
231 table_last->data = NULL;
233 /* link table and table info */
234 *table_info = font->num_tables - 1;
236 return TA_Err_Ok;
240 static void
241 TA_sfnt_sort_table_info(SFNT* sfnt,
242 FONT* font)
244 /* Looking into an arbitrary TTF (with a `DSIG' table), tags */
245 /* starting with an uppercase letter are sorted before lowercase */
246 /* letters. In other words, the alphabetical ordering (as */
247 /* mandated by signing a font) is a simple numeric comparison of */
248 /* the 32bit tag values. */
250 SFNT_Table* tables = font->tables;
252 SFNT_Table_Info* table_infos = sfnt->table_infos;
253 FT_ULong num_table_infos = sfnt->num_table_infos;
255 FT_ULong i;
256 FT_ULong j;
259 for (i = 1; i < num_table_infos; i++)
261 for (j = i; j > 0; j--)
263 SFNT_Table_Info swap;
264 FT_ULong tag1;
265 FT_ULong tag2;
268 tag1 = (table_infos[j] == MISSING)
270 : tables[table_infos[j]].tag;
271 tag2 = (table_infos[j - 1] == MISSING)
273 : tables[table_infos[j - 1]].tag;
275 if (tag1 > tag2)
276 break;
278 swap = table_infos[j];
279 table_infos[j] = table_infos[j - 1];
280 table_infos[j - 1] = swap;
286 static FT_Error
287 TA_sfnt_split_into_SFNT_tables(SFNT* sfnt,
288 FONT* font)
290 FT_Error error;
291 FT_ULong i;
294 /* basic check whether font is a TTF or TTC */
295 if (!FT_IS_SFNT(sfnt->face))
296 return FT_Err_Invalid_Argument;
298 error = FT_Sfnt_Table_Info(sfnt->face, 0, NULL, &sfnt->num_table_infos);
299 if (error)
300 return error;
302 sfnt->table_infos = (SFNT_Table_Info*)malloc(sfnt->num_table_infos
303 * sizeof (SFNT_Table_Info));
304 if (!sfnt->table_infos)
305 return FT_Err_Out_Of_Memory;
307 /* collect SFNT tables and search for `glyf' and `loca' table */
308 sfnt->glyf_idx = MISSING;
309 sfnt->loca_idx = MISSING;
310 for (i = 0; i < sfnt->num_table_infos; i++)
312 SFNT_Table_Info* table_info = &sfnt->table_infos[i];
313 FT_ULong tag;
314 FT_ULong len;
315 FT_Byte* buf;
317 FT_ULong buf_len;
318 FT_ULong j;
321 *table_info = MISSING;
323 error = FT_Sfnt_Table_Info(sfnt->face, i, &tag, &len);
324 if (error)
326 /* this ignores both missing and zero-length tables */
327 if (error == FT_Err_Table_Missing)
328 continue;
329 else
330 return error;
333 /* ignore tables which we are going to create by ourselves */
334 else if (tag == TTAG_fpgm
335 || tag == TTAG_prep
336 || tag == TTAG_cvt
337 || tag == TTAG_DSIG)
338 continue;
340 /* make the allocated buffer length a multiple of 4 */
341 buf_len = (len + 3) & -3;
342 buf = (FT_Byte*)malloc(buf_len);
343 if (!buf)
344 return FT_Err_Out_Of_Memory;
346 /* pad end of buffer with zeros */
347 buf[buf_len - 1] = 0x00;
348 buf[buf_len - 2] = 0x00;
349 buf[buf_len - 3] = 0x00;
351 /* load table */
352 error = FT_Load_Sfnt_Table(sfnt->face, tag, 0, buf, &len);
353 if (error)
354 goto Err;
356 /* check whether we already have this table */
357 for (j = 0; j < font->num_tables; j++)
359 SFNT_Table* table = &font->tables[j];
362 if (table->tag == tag
363 && table->len == len
364 && !memcmp(table->buf, buf, len))
365 break;
368 if (tag == TTAG_head)
369 sfnt->loca_format = buf[51];
370 else if (tag == TTAG_glyf)
371 sfnt->glyf_idx = j;
372 else if (tag == TTAG_loca)
373 sfnt->loca_idx = j;
375 if (j == font->num_tables)
377 /* add element to table array if it is missing or different; */
378 /* in case of success, `buf' gets linked and is eventually */
379 /* freed in `TA_font_unload' */
380 error = TA_font_add_table(font, table_info, tag, len, buf);
381 if (error)
382 goto Err;
384 else
386 /* reuse existing SFNT table */
387 free(buf);
388 *table_info = j;
390 continue;
392 Err:
393 free(buf);
394 return error;
397 /* no (non-empty) `glyf' or `loca' table; */
398 /* this can't be a valid TTF with outlines */
399 if (sfnt->glyf_idx == MISSING || sfnt->loca_idx == MISSING)
400 return FT_Err_Invalid_Argument;
402 return TA_Err_Ok;
406 static FT_Error
407 TA_sfnt_split_glyf_table(SFNT* sfnt,
408 FONT* font)
410 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
411 SFNT_Table* loca_table = &font->tables[sfnt->loca_idx];
412 glyf_Data* data;
414 FT_ULong offset;
415 FT_ULong offset_next;
417 FT_Byte* p;
418 FT_UShort i;
421 /* in case of success, all allocated arrays are */
422 /* linked and eventually freed in `TA_font_unload' */
424 /* nothing to do if table has already been processed */
425 if (glyf_table->data)
426 return TA_Err_Ok;
428 data = (glyf_Data*)calloc(1, sizeof (glyf_Data));
429 if (!data)
430 return FT_Err_Out_Of_Memory;
432 glyf_table->data = data;
434 data->num_glyphs = sfnt->loca_format ? loca_table->len / 4 - 1
435 : loca_table->len / 2 - 1;
436 data->glyphs = (GLYPH*)calloc(1, data->num_glyphs * sizeof (GLYPH));
437 if (!data->glyphs)
438 return FT_Err_Out_Of_Memory;
440 p = loca_table->buf;
442 if (sfnt->loca_format)
444 offset_next = *(p++) << 24;
445 offset_next += *(p++) << 16;
446 offset_next += *(p++) << 8;
447 offset_next += *(p++);
449 else
451 offset_next = *(p++) << 8;
452 offset_next += *(p++);
453 offset_next <<= 1;
456 /* loop over `loca' and `glyf' data */
457 for (i = 0; i < data->num_glyphs; i++)
459 GLYPH* glyph = &data->glyphs[i];
461 FT_ULong len;
464 offset = offset_next;
466 if (sfnt->loca_format)
468 offset_next = *(p++) << 24;
469 offset_next += *(p++) << 16;
470 offset_next += *(p++) << 8;
471 offset_next += *(p++);
473 else
475 offset_next = *(p++) << 8;
476 offset_next += *(p++);
477 offset_next <<= 1;
480 if (offset_next < offset
481 || offset_next > glyf_table->len)
482 return FT_Err_Invalid_Table;
484 len = offset_next - offset;
485 if (!len)
486 continue; /* empty glyph */
487 else
489 FT_Byte* bufp;
490 FT_Byte* endp;
491 FT_Short num_contours;
494 /* check header size */
495 if (len < 10)
496 return FT_Err_Invalid_Table;
498 bufp = glyf_table->buf + offset;
499 endp = bufp + len;
501 num_contours = (FT_Short)((bufp[0] << 8) + bufp[1]);
503 if (num_contours < 0)
505 /* composite glyph */
507 FT_UShort flags;
508 FT_ULong flags_offset;
511 /* skip header */
512 bufp += 10;
514 /* walk over component records */
517 if (bufp + 4 > endp)
518 return FT_Err_Invalid_Table;
520 flags_offset = bufp - (glyf_table->buf + offset);
522 flags = *(bufp++) << 8;
523 flags += *(bufp++);
525 /* skip glyph component index */
526 bufp += 2;
528 /* skip scaling and offset arguments */
529 if (flags & ARGS_ARE_WORDS)
530 bufp += 4;
531 else
532 bufp += 2;
534 if (flags & WE_HAVE_A_SCALE)
535 bufp += 2;
536 else if (flags & WE_HAVE_AN_XY_SCALE)
537 bufp += 4;
538 else if (flags & WE_HAVE_A_2X2)
539 bufp += 8;
540 } while (flags & MORE_COMPONENTS);
542 if (flags & WE_HAVE_INSTR)
544 FT_UShort num_ins;
547 if (bufp + 2 > endp)
548 return FT_Err_Invalid_Table;
550 num_ins = *(bufp++) << 8;
551 num_ins += *(bufp++);
553 if (bufp + num_ins > endp)
554 return FT_Err_Invalid_Table;
556 /* adjust glyph record length */
557 glyph->len = len - (num_ins + 2);
558 glyph->buf = (FT_Byte*)malloc(glyph->len);
559 if (!glyph->buf)
560 return FT_Err_Out_Of_Memory;
562 /* now copy everything but the instructions */
563 memcpy(glyph->buf, glyf_table->buf + offset, glyph->len);
564 /* unset instruction flag */
565 glyph->buf[flags_offset] &= ~(WE_HAVE_INSTR >> 8);
567 else
569 glyph->len = len;
570 glyph->buf = (FT_Byte*)malloc(glyph->len);
571 if (!glyph->buf)
572 return FT_Err_Out_Of_Memory;
574 /* copy record */
575 memcpy(glyph->buf, glyf_table->buf, glyph->len);
578 else
580 /* simple glyph */
582 FT_ULong ins_offset;
583 FT_UShort num_ins;
586 ins_offset = 10 + num_contours * 2;
588 bufp += ins_offset;
590 if (bufp + 2 > endp)
591 return FT_Err_Invalid_Table;
593 /* get number of instructions */
594 num_ins = *(bufp++) << 8;
595 num_ins += *(bufp++);
597 bufp += num_ins;
599 if (bufp > endp)
600 return FT_Err_Invalid_Table;
602 /* adjust glyph record length */
603 glyph->len = len - num_ins;
604 glyph->buf = (FT_Byte*)malloc(glyph->len);
605 if (!glyph->buf)
606 return FT_Err_Out_Of_Memory;
608 /* now copy everything but the instructions */
609 memcpy(glyph->buf, glyf_table->buf + offset, ins_offset);
610 glyph->buf[ins_offset] = 0; /* no instructions */
611 glyph->buf[ins_offset + 1] = 0;
612 memcpy(glyph->buf + ins_offset + 2, bufp, endp - bufp);
617 return TA_Err_Ok;
621 /* we build a dummy `DSIG' table only */
623 static FT_Error
624 TA_table_build_DSIG(FT_Byte** DSIG)
626 FT_Byte* buf;
629 buf = (FT_Byte*)malloc(DSIG_LEN);
630 if (!buf)
631 return FT_Err_Out_Of_Memory;
633 /* version */
634 buf[0] = 0x00;
635 buf[1] = 0x00;
636 buf[2] = 0x00;
637 buf[3] = 0x01;
639 /* zero signatures */
640 buf[4] = 0x00;
641 buf[5] = 0x00;
643 /* permission flags */
644 buf[6] = 0x00;
645 buf[7] = 0x00;
647 *DSIG = buf;
649 return TA_Err_Ok;
653 static void
654 TA_font_compute_table_offsets(FONT* font,
655 FT_ULong start)
657 FT_ULong i;
658 FT_ULong offset = start;
661 for (i = 0; i < font->num_tables; i++)
663 SFNT_Table* table = &font->tables[i];
666 table->offset = offset;
668 /* table offsets must be multiples of 4; */
669 /* this also fits the actual buffer lengths */
670 offset += (table->len + 3) & ~3;
675 /* If `do_complete' is 0, only return `header_len'. */
677 static FT_Error
678 TA_sfnt_build_TTF_header(SFNT* sfnt,
679 FONT* font,
680 FT_Byte** header_buf,
681 FT_ULong* header_len,
682 FT_Int do_complete)
684 SFNT_Table* tables = font->tables;
686 SFNT_Table_Info* table_infos = sfnt->table_infos;
687 FT_ULong num_table_infos = sfnt->num_table_infos;
689 FT_Byte* buf;
690 FT_ULong len;
692 FT_Byte* table_record;
694 FT_Byte* head_buf = NULL; /* pointer to `head' table */
695 FT_ULong head_checksum; /* checksum in `head' table */
697 FT_ULong num_tables_in_header;
698 FT_ULong i;
701 num_tables_in_header = 0;
702 for (i = 0; i < num_table_infos; i++)
704 /* ignore empty tables */
705 if (table_infos[i] != MISSING)
706 num_tables_in_header++;
709 len = 12 + 16 * num_tables_in_header;
710 if (!do_complete)
712 *header_len = len;
713 return TA_Err_Ok;
715 buf = (FT_Byte*)malloc(len);
716 if (!buf)
717 return FT_Err_Out_Of_Memory;
719 /* SFNT version */
720 buf[0] = 0x00;
721 buf[1] = 0x01;
722 buf[2] = 0x00;
723 buf[3] = 0x00;
725 /* number of tables */
726 buf[4] = HIGH(num_tables_in_header);
727 buf[5] = LOW(num_tables_in_header);
729 /* auxiliary data */
731 FT_ULong search_range, entry_selector, range_shift;
732 FT_ULong i, j;
735 for (i = 1, j = 2; j <= num_tables_in_header; i++, j <<= 1)
738 entry_selector = i - 1;
739 search_range = 0x10 << entry_selector;
740 range_shift = (num_tables_in_header << 4) - search_range;
742 buf[6] = HIGH(search_range);
743 buf[7] = LOW(search_range);
744 buf[8] = HIGH(entry_selector);
745 buf[9] = LOW(entry_selector);
746 buf[10] = HIGH(range_shift);
747 buf[11] = LOW(range_shift);
750 /* location of the first table info record */
751 table_record = &buf[12];
753 head_checksum = 0;
755 /* loop over all tables */
756 for (i = 0; i < num_table_infos; i++)
758 SFNT_Table_Info table_info = table_infos[i];
759 SFNT_Table* table;
762 /* ignore empty slots */
763 if (table_info == MISSING)
764 continue;
766 table = &tables[table_info];
768 if (table->tag == TTAG_head)
770 /* we always reach this IF clause since FreeType would */
771 /* have aborted already if the `head' table were missing */
773 head_buf = table->buf;
775 /* reset checksum in `head' table for recalculation */
776 head_buf[8] = 0x00;
777 head_buf[9] = 0x00;
778 head_buf[10] = 0x00;
779 head_buf[11] = 0x00;
782 head_checksum += table->checksum;
784 table_record[0] = BYTE1(table->tag);
785 table_record[1] = BYTE2(table->tag);
786 table_record[2] = BYTE3(table->tag);
787 table_record[3] = BYTE4(table->tag);
789 table_record[4] = BYTE1(table->checksum);
790 table_record[5] = BYTE2(table->checksum);
791 table_record[6] = BYTE3(table->checksum);
792 table_record[7] = BYTE4(table->checksum);
794 table_record[8] = BYTE1(table->offset);
795 table_record[9] = BYTE2(table->offset);
796 table_record[10] = BYTE3(table->offset);
797 table_record[11] = BYTE4(table->offset);
799 table_record[12] = BYTE1(table->len);
800 table_record[13] = BYTE2(table->len);
801 table_record[14] = BYTE3(table->len);
802 table_record[15] = BYTE4(table->len);
804 table_record += 16;
807 /* the font header is complete; compute `head' checksum */
808 head_checksum += TA_table_compute_checksum(buf, len);
809 head_checksum = 0xB1B0AFBAUL - head_checksum;
811 /* store checksum in `head' table; */
812 head_buf[8] = BYTE1(head_checksum);
813 head_buf[9] = BYTE2(head_checksum);
814 head_buf[10] = BYTE3(head_checksum);
815 head_buf[11] = BYTE4(head_checksum);
817 *header_buf = buf;
818 *header_len = len;
820 return TA_Err_Ok;
824 static FT_Error
825 TA_font_build_TTF(FONT* font)
827 SFNT* sfnt = &font->sfnts[0];
829 SFNT_Table* tables;
830 FT_ULong num_tables;
832 FT_ULong SFNT_offset;
834 FT_Byte* DSIG_buf;
836 FT_Byte* header_buf;
837 FT_ULong header_len;
839 FT_ULong i;
840 FT_Error error;
843 /* add a dummy `DSIG' table */
845 error = TA_sfnt_add_table_info(sfnt);
846 if (error)
847 return error;
849 error = TA_table_build_DSIG(&DSIG_buf);
850 if (error)
851 return error;
853 /* in case of success, `DSIG_buf' gets linked */
854 /* and is eventually freed in `TA_font_unload' */
855 error = TA_font_add_table(font,
856 &sfnt->table_infos[sfnt->num_table_infos - 1],
857 TTAG_DSIG, DSIG_LEN, DSIG_buf);
858 if (error)
860 free(DSIG_buf);
861 return error;
864 TA_sfnt_sort_table_info(sfnt, font);
866 /* the first SFNT table immediately follows the header */
867 (void)TA_sfnt_build_TTF_header(sfnt, font, NULL, &SFNT_offset, 0);
868 TA_font_compute_table_offsets(font, SFNT_offset);
870 error = TA_sfnt_build_TTF_header(sfnt, font,
871 &header_buf, &header_len, 1);
872 if (error)
873 return error;
875 /* build font */
877 tables = font->tables;
878 num_tables = font->num_tables;
880 font->out_len = tables[num_tables - 1].offset
881 + ((tables[num_tables - 1].len + 3) & ~3);
882 font->out_buf = (FT_Byte*)malloc(font->out_len);
883 if (!font->out_buf)
885 error = FT_Err_Out_Of_Memory;
886 goto Err;
889 memcpy(font->out_buf, header_buf, header_len);
891 for (i = 0; i < num_tables; i++)
893 SFNT_Table* table = &tables[i];
896 /* buffer length is a multiple of 4 */
897 memcpy(font->out_buf + table->offset,
898 table->buf, (table->len + 3) & ~3);
901 error = TA_Err_Ok;
903 Err:
904 free(header_buf);
906 return error;
910 static FT_Error
911 TA_font_build_TTC_header(FONT* font,
912 FT_Byte** header_buf,
913 FT_ULong* header_len)
915 SFNT* sfnts = font->sfnts;
916 FT_Long num_sfnts = font->num_sfnts;
918 SFNT_Table* tables = font->tables;
919 FT_ULong num_tables = font->num_tables;
921 FT_ULong TTF_offset;
922 FT_ULong DSIG_offset;
924 FT_Byte* buf;
925 FT_ULong len;
927 FT_Long i;
928 FT_Byte* p;
931 len = 24 + 4 * num_sfnts;
932 buf = (FT_Byte*)malloc(len);
933 if (!buf)
934 return FT_Err_Out_Of_Memory;
936 p = buf;
938 /* TTC ID string */
939 *(p++) = 't';
940 *(p++) = 't';
941 *(p++) = 'c';
942 *(p++) = 'f';
944 /* TTC header version */
945 *(p++) = 0x00;
946 *(p++) = 0x02;
947 *(p++) = 0x00;
948 *(p++) = 0x00;
950 /* number of subfonts */
951 *(p++) = BYTE1(num_sfnts);
952 *(p++) = BYTE2(num_sfnts);
953 *(p++) = BYTE3(num_sfnts);
954 *(p++) = BYTE4(num_sfnts);
956 /* the first TTF subfont header immediately follows the TTC header */
957 TTF_offset = len;
959 /* loop over all subfonts */
960 for (i = 0; i < num_sfnts; i++)
962 SFNT* sfnt = &sfnts[i];
963 FT_ULong l;
966 TA_sfnt_sort_table_info(sfnt, font);
967 /* only get header length */
968 (void)TA_sfnt_build_TTF_header(sfnt, font, NULL, &l, 0);
970 *(p++) = BYTE1(TTF_offset);
971 *(p++) = BYTE2(TTF_offset);
972 *(p++) = BYTE3(TTF_offset);
973 *(p++) = BYTE4(TTF_offset);
975 TTF_offset += l;
978 /* the first SFNT table immediately follows the subfont TTF headers */
979 TA_font_compute_table_offsets(font, TTF_offset);
981 /* DSIG tag */
982 *(p++) = 'D';
983 *(p++) = 'S';
984 *(p++) = 'I';
985 *(p++) = 'G';
987 /* DSIG length */
988 *(p++) = 0x00;
989 *(p++) = 0x00;
990 *(p++) = 0x00;
991 *(p++) = 0x08;
993 /* DSIG offset; in a TTC this is always the last SFNT table */
994 DSIG_offset = tables[num_tables - 1].offset;
996 *(p++) = BYTE1(DSIG_offset);
997 *(p++) = BYTE2(DSIG_offset);
998 *(p++) = BYTE3(DSIG_offset);
999 *(p++) = BYTE4(DSIG_offset);
1001 *header_buf = buf;
1002 *header_len = len;
1004 return TA_Err_Ok;
1008 static FT_Error
1009 TA_font_build_TTC(FONT* font)
1011 SFNT* sfnts = font->sfnts;
1012 FT_Long num_sfnts = font->num_sfnts;
1014 SFNT_Table* tables;
1015 FT_ULong num_tables;
1017 FT_Byte* DSIG_buf;
1018 SFNT_Table_Info dummy;
1020 FT_Byte* TTC_header_buf;
1021 FT_ULong TTC_header_len;
1023 FT_Byte** TTF_header_bufs;
1024 FT_ULong* TTF_header_lens;
1026 FT_ULong offset;
1027 FT_Long i;
1028 FT_ULong j;
1029 FT_Error error;
1032 /* add a dummy `DSIG' table */
1034 error = TA_table_build_DSIG(&DSIG_buf);
1035 if (error)
1036 return error;
1038 /* in case of success, `DSIG_buf' gets linked */
1039 /* and is eventually freed in `TA_font_unload' */
1040 error = TA_font_add_table(font, &dummy, TTAG_DSIG, DSIG_LEN, DSIG_buf);
1041 if (error)
1043 free(DSIG_buf);
1044 return error;
1047 /* this also computes the SFNT table offsets */
1048 error = TA_font_build_TTC_header(font,
1049 &TTC_header_buf, &TTC_header_len);
1050 if (error)
1051 return error;
1053 TTF_header_bufs = (FT_Byte**)calloc(1, num_sfnts * sizeof (FT_Byte*));
1054 if (!TTF_header_bufs)
1055 goto Err;
1057 TTF_header_lens = (FT_ULong*)malloc(num_sfnts * sizeof (FT_ULong));
1058 if (!TTF_header_lens)
1059 goto Err;
1061 for (i = 0; i < num_sfnts; i++)
1063 error = TA_sfnt_build_TTF_header(&sfnts[i], font,
1064 &TTF_header_bufs[i],
1065 &TTF_header_lens[i], 1);
1066 if (error)
1067 goto Err;
1070 /* build font */
1072 tables = font->tables;
1073 num_tables = font->num_tables;
1075 font->out_len = tables[num_tables - 1].offset
1076 + ((tables[num_tables - 1].len + 3) & ~3);
1077 font->out_buf = (FT_Byte*)malloc(font->out_len);
1078 if (!font->out_buf)
1080 error = FT_Err_Out_Of_Memory;
1081 goto Err;
1084 memcpy(font->out_buf, TTC_header_buf, TTC_header_len);
1086 offset = TTC_header_len;
1088 for (i = 0; i < num_sfnts; i++)
1090 memcpy(font->out_buf + offset,
1091 TTF_header_bufs[i], TTF_header_lens[i]);
1093 offset += TTF_header_lens[i];
1096 for (j = 0; j < num_tables; j++)
1098 SFNT_Table* table = &tables[j];
1101 /* buffer length is a multiple of 4 */
1102 memcpy(font->out_buf + table->offset,
1103 table->buf, (table->len + 3) & ~3);
1106 error = TA_Err_Ok;
1108 Err:
1109 free(TTC_header_buf);
1110 if (TTF_header_bufs)
1112 for (i = 0; i < font->num_sfnts; i++)
1113 free(TTF_header_bufs[i]);
1114 free(TTF_header_bufs);
1116 free(TTF_header_lens);
1118 return error;
1122 static FT_Error
1123 TA_font_write(FONT* font,
1124 FILE* out)
1126 if (fwrite(font->out_buf, 1, font->out_len, out) != font->out_len)
1127 return TA_Err_Invalid_Stream_Write;
1129 return TA_Err_Ok;
1133 static void
1134 TA_font_unload(FONT* font)
1136 /* in case of error it is expected that unallocated pointers */
1137 /* are NULL (and counters are zero) */
1139 if (!font)
1140 return;
1142 if (font->tables)
1144 FT_ULong i;
1147 for (i = 0; i < font->num_tables; i++)
1149 free(font->tables[i].buf);
1150 if (font->tables[i].data)
1152 if (font->tables[i].tag == TTAG_glyf)
1154 glyf_Data* data = (glyf_Data*)font->tables[i].data;
1155 FT_UShort j;
1158 for (j = 0; j < data->num_glyphs; j++)
1159 free(data->glyphs[j].buf);
1160 free(data->glyphs);
1161 free(data);
1165 free(font->tables);
1168 if (font->sfnts)
1170 FT_Long i;
1173 for (i = 0; i < font->num_sfnts; i++)
1175 FT_Done_Face(font->sfnts[i].face);
1176 free(font->sfnts[i].table_infos);
1178 free(font->sfnts);
1181 FT_Done_FreeType(font->lib);
1182 free(font->in_buf);
1183 free(font->out_buf);
1184 free(font);
1188 TA_Error
1189 TTF_autohint(FILE* in,
1190 FILE* out)
1192 FONT* font;
1193 FT_Error error;
1194 FT_Long i;
1197 font = (FONT*)calloc(1, sizeof (FONT));
1198 if (!font)
1199 return FT_Err_Out_Of_Memory;
1201 error = TA_font_read(font, in);
1202 if (error)
1203 goto Err;
1205 error = TA_font_init(font);
1206 if (error)
1207 goto Err;
1209 /* loop over subfonts */
1210 for (i = 0; i < font->num_sfnts; i++)
1212 SFNT* sfnt = &font->sfnts[i];
1215 error = FT_New_Memory_Face(font->lib, font->in_buf, font->in_len,
1216 i, &sfnt->face);
1217 if (error)
1218 goto Err;
1220 error = TA_sfnt_split_into_SFNT_tables(sfnt, font);
1221 if (error)
1222 goto Err;
1224 error = TA_sfnt_split_glyf_table(sfnt, font);
1225 if (error)
1226 goto Err;
1229 /* remove `glyf' table */
1230 /* remove `loca' table */
1232 /* compute global hints */
1233 /* build `fpgm' table */
1234 /* build `prep' table */
1235 /* build `cvt ' table */
1237 /* handle all glyphs in a loop */
1238 /* hint the glyph */
1239 /* build bytecode */
1241 /* build `glyf' table */
1242 /* build `loca' table */
1244 if (font->num_sfnts == 1)
1245 error = TA_font_build_TTF(font);
1246 else
1247 error = TA_font_build_TTC(font);
1248 if (error)
1249 goto Err;
1251 error = TA_font_write(font, out);
1252 if (error)
1253 goto Err;
1255 error = TA_Err_Ok;
1257 Err:
1258 TA_font_unload(font);
1260 return error;
1263 /* end of ttfautohint.c */