3 /* written 2011 by Werner Lemberg <wl@gnu.org> */
5 /* This file needs FreeType 2.4.5 or newer. */
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 */
36 /* an empty slot in the table info array */
37 #define MISSING (FT_ULong)~0
41 typedef struct SFNT_Table_
{
44 FT_Byte
* buf
; /* the table data */
45 FT_ULong offset
; /* from beginning of file */
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_
{
56 SFNT_Table_Info
* table_infos
;
57 FT_ULong num_table_infos
;
58 FT_ULong glyf_idx
; /* this subfont's `glyf' SFNT table index */
62 typedef struct FONT_
{
80 TA_font_read(FONT
* font
,
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
);
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
;
103 TA_font_init(FONT
* font
)
109 error
= FT_Init_FreeType(&font
->lib
);
113 /* get number of faces (i.e. subfonts) */
114 error
= FT_New_Memory_Face(font
->lib
, font
->in_buf
, font
->in_len
, -1, &f
);
117 font
->num_sfnts
= f
->num_faces
;
120 /* it is a TTC if we have more than a single subfont */
121 font
->sfnts
= (SFNT
*)calloc(1, font
->num_sfnts
* sizeof (SFNT
));
123 return FT_Err_Out_Of_Memory
;
130 TA_sfnt_add_table_info(SFNT
* sfnt
)
132 SFNT_Table_Info
* table_infos_new
;
135 sfnt
->num_table_infos
++;
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
;
145 sfnt
->table_infos
= table_infos_new
;
147 sfnt
->table_infos
[sfnt
->num_table_infos
- 1] = MISSING
;
154 TA_table_compute_checksum(FT_Byte
* buf
,
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
++);
174 TA_font_add_table(FONT
* font
,
175 SFNT_Table_Info
* table_info
,
180 SFNT_Table
* tables_new
;
181 SFNT_Table
* table_last
;
185 tables_new
= (SFNT_Table
*)realloc(font
->tables
,
186 font
->num_tables
* sizeof (SFNT_Table
));
190 return FT_Err_Out_Of_Memory
;
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;
210 TA_sfnt_sort_table_info(SFNT
* sfnt
,
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
;
228 for (i
= 1; i
< num_table_infos
; i
++)
230 for (j
= i
; j
> 0; j
--)
232 SFNT_Table_Info swap
;
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
;
247 swap
= table_infos
[j
];
248 table_infos
[j
] = table_infos
[j
- 1];
249 table_infos
[j
- 1] = swap
;
256 TA_sfnt_split_into_SFNT_tables(SFNT
* sfnt
,
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
);
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
];
289 *table_info
= MISSING
;
291 error
= FT_Sfnt_Table_Info(sfnt
->face
, i
, &tag
, &len
);
294 /* this ignores both missing and zero-length tables */
295 if (error
== FT_Err_Table_Missing
)
301 /* ignore tables which we are going to create by ourselves */
302 else if (tag
== TTAG_fpgm
308 /* make the allocated buffer length a multiple of 4 */
309 buf_len
= (len
+ 3) & -3;
310 buf
= (FT_Byte
*)malloc(buf_len
);
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;
320 error
= FT_Load_Sfnt_Table(sfnt
->face
, tag
, 0, buf
, &len
);
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
332 && !memcmp(table
->buf
, buf
, len
))
336 if (tag
== TTAG_glyf
)
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
);
350 /* reuse existing SFNT table */
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
;
369 /* we build a dummy `DSIG' table only */
372 TA_table_construct_DSIG(FT_Byte
** DSIG
)
377 buf
= (FT_Byte
*)malloc(DSIG_LEN
);
379 return FT_Err_Out_Of_Memory
;
387 /* zero signatures */
391 /* permission flags */
402 TA_font_compute_table_offsets(FONT
* font
,
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'. */
426 TA_sfnt_construct_TTF_header(SFNT
* sfnt
,
428 FT_Byte
** header_buf
,
429 FT_ULong
* header_len
,
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
;
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
;
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
;
463 buf
= (FT_Byte
*)malloc(len
);
465 return FT_Err_Out_Of_Memory
;
473 /* number of tables */
474 buf
[4] = HIGH(num_tables_in_header
);
475 buf
[5] = LOW(num_tables_in_header
);
479 FT_ULong search_range
, entry_selector
, range_shift
;
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];
503 /* loop over all tables */
504 for (i
= 0; i
< num_table_infos
; i
++)
506 SFNT_Table_Info table_info
= table_infos
[i
];
510 /* ignore empty slots */
511 if (table_info
== MISSING
)
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 */
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
);
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
);
573 TA_font_build_TTF(FONT
* font
)
575 SFNT
* sfnt
= &font
->sfnts
[0];
580 FT_ULong SFNT_offset
;
591 /* add a dummy `DSIG' table */
593 error
= TA_sfnt_add_table_info(sfnt
);
597 error
= TA_table_construct_DSIG(&DSIG_buf
);
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
);
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);
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
);
633 error
= FT_Err_Out_Of_Memory
;
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);
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
;
670 FT_ULong DSIG_offset
;
679 len
= 24 + 4 * num_sfnts
;
680 buf
= (FT_Byte
*)malloc(len
);
682 return FT_Err_Out_Of_Memory
;
692 /* TTC header version */
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 */
707 /* loop over all subfonts */
708 for (i
= 0; i
< num_sfnts
; i
++)
710 SFNT
* sfnt
= &sfnts
[i
];
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
);
726 /* the first SFNT table immediately follows the subfont TTF headers */
727 TA_font_compute_table_offsets(font
, TTF_offset
);
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
);
757 TA_font_build_TTC(FONT
* font
)
759 SFNT
* sfnts
= font
->sfnts
;
760 FT_Long num_sfnts
= font
->num_sfnts
;
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
;
780 /* add a dummy `DSIG' table */
782 error
= TA_table_construct_DSIG(&DSIG_buf
);
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
);
795 /* this also computes the SFNT table offsets */
796 error
= TA_font_construct_TTC_header(font
,
797 &TTC_header_buf
, &TTC_header_len
);
801 TTF_header_bufs
= (FT_Byte
**)calloc(1, num_sfnts
* sizeof (FT_Byte
*));
802 if (!TTF_header_bufs
)
805 TTF_header_lens
= (FT_ULong
*)malloc(num_sfnts
* sizeof (FT_ULong
));
806 if (!TTF_header_lens
)
809 for (i
= 0; i
< num_sfnts
; i
++)
811 error
= TA_sfnt_construct_TTF_header(&sfnts
[i
], font
,
813 &TTF_header_lens
[i
], 1);
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
);
828 error
= FT_Err_Out_Of_Memory
;
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);
857 free(TTC_header_buf
);
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
);
871 TA_font_write(FONT
* font
,
874 if (fwrite(font
->out_buf
, 1, font
->out_len
, out
) != font
->out_len
)
875 return TA_Err_Invalid_Stream_Write
;
882 TA_font_unload(FONT
* font
)
884 /* in case of error it is expected that unallocated pointers */
885 /* are NULL (and counters are zero) */
895 for (i
= 0; i
< font
->num_tables
; i
++)
896 free(font
->tables
[i
].buf
);
905 for (i
= 0; i
< font
->num_sfnts
; i
++)
907 FT_Done_Face(font
->sfnts
[i
].face
);
908 free(font
->sfnts
[i
].table_infos
);
913 FT_Done_FreeType(font
->lib
);
921 TTF_autohint(FILE* in
,
929 font
= (FONT
*)calloc(1, sizeof (FONT
));
931 return FT_Err_Out_Of_Memory
;
933 error
= TA_font_read(font
, in
);
937 error
= TA_font_init(font
);
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
,
952 error
= TA_sfnt_split_into_SFNT_tables(sfnt
, font
);
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 */
966 /* construct bytecode */
968 /* construct `glyf' table */
970 if (font
->num_sfnts
== 1)
971 error
= TA_font_build_TTF(font
);
973 error
= TA_font_build_TTC(font
);
977 error
= TA_font_write(font
, out
);
984 TA_font_unload(font
);
989 /* end of ttfautohint.c */