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
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
57 /* a representation of the data in the `glyf' table */
58 typedef struct glyf_Data_
65 typedef struct SFNT_Table_
{
68 FT_Byte
* buf
; /* the table data */
69 FT_ULong offset
; /* from beginning of file */
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_
{
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 */
91 typedef struct FONT_
{
109 TA_font_read(FONT
* font
,
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
);
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
;
132 TA_font_init(FONT
* font
)
138 error
= FT_Init_FreeType(&font
->lib
);
142 /* get number of faces (i.e. subfonts) */
143 error
= FT_New_Memory_Face(font
->lib
, font
->in_buf
, font
->in_len
, -1, &f
);
146 font
->num_sfnts
= f
->num_faces
;
149 /* it is a TTC if we have more than a single subfont */
150 font
->sfnts
= (SFNT
*)calloc(1, font
->num_sfnts
* sizeof (SFNT
));
152 return FT_Err_Out_Of_Memory
;
159 TA_sfnt_add_table_info(SFNT
* sfnt
)
161 SFNT_Table_Info
* table_infos_new
;
164 sfnt
->num_table_infos
++;
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
;
174 sfnt
->table_infos
= table_infos_new
;
176 sfnt
->table_infos
[sfnt
->num_table_infos
- 1] = MISSING
;
183 TA_table_compute_checksum(FT_Byte
* buf
,
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
++);
203 TA_font_add_table(FONT
* font
,
204 SFNT_Table_Info
* table_info
,
209 SFNT_Table
* tables_new
;
210 SFNT_Table
* table_last
;
214 tables_new
= (SFNT_Table
*)realloc(font
->tables
,
215 font
->num_tables
* sizeof (SFNT_Table
));
219 return FT_Err_Out_Of_Memory
;
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;
241 TA_sfnt_sort_table_info(SFNT
* sfnt
,
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
;
259 for (i
= 1; i
< num_table_infos
; i
++)
261 for (j
= i
; j
> 0; j
--)
263 SFNT_Table_Info swap
;
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
;
278 swap
= table_infos
[j
];
279 table_infos
[j
] = table_infos
[j
- 1];
280 table_infos
[j
- 1] = swap
;
287 TA_sfnt_split_into_SFNT_tables(SFNT
* sfnt
,
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
);
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
];
321 *table_info
= MISSING
;
323 error
= FT_Sfnt_Table_Info(sfnt
->face
, i
, &tag
, &len
);
326 /* this ignores both missing and zero-length tables */
327 if (error
== FT_Err_Table_Missing
)
333 /* ignore tables which we are going to create by ourselves */
334 else if (tag
== TTAG_fpgm
340 /* make the allocated buffer length a multiple of 4 */
341 buf_len
= (len
+ 3) & -3;
342 buf
= (FT_Byte
*)malloc(buf_len
);
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;
352 error
= FT_Load_Sfnt_Table(sfnt
->face
, tag
, 0, buf
, &len
);
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
364 && !memcmp(table
->buf
, buf
, len
))
368 if (tag
== TTAG_head
)
369 sfnt
->loca_format
= buf
[51];
370 else if (tag
== TTAG_glyf
)
372 else if (tag
== TTAG_loca
)
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
);
386 /* reuse existing SFNT table */
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
;
407 TA_sfnt_split_glyf_table(SFNT
* sfnt
,
410 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
411 SFNT_Table
* loca_table
= &font
->tables
[sfnt
->loca_idx
];
415 FT_ULong offset_next
;
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
)
428 data
= (glyf_Data
*)calloc(1, sizeof (glyf_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
));
438 return FT_Err_Out_Of_Memory
;
442 if (sfnt
->loca_format
)
444 offset_next
= *(p
++) << 24;
445 offset_next
+= *(p
++) << 16;
446 offset_next
+= *(p
++) << 8;
447 offset_next
+= *(p
++);
451 offset_next
= *(p
++) << 8;
452 offset_next
+= *(p
++);
456 /* loop over `loca' and `glyf' data */
457 for (i
= 0; i
< data
->num_glyphs
; i
++)
459 GLYPH
* glyph
= &data
->glyphs
[i
];
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
++);
475 offset_next
= *(p
++) << 8;
476 offset_next
+= *(p
++);
480 if (offset_next
< offset
481 || offset_next
> glyf_table
->len
)
482 return FT_Err_Invalid_Table
;
484 len
= offset_next
- offset
;
486 continue; /* empty glyph */
491 FT_Short num_contours
;
494 /* check header size */
496 return FT_Err_Invalid_Table
;
498 bufp
= glyf_table
->buf
+ offset
;
501 num_contours
= (FT_Short
)((bufp
[0] << 8) + bufp
[1]);
503 if (num_contours
< 0)
505 /* composite glyph */
508 FT_ULong flags_offset
;
514 /* walk over component records */
518 return FT_Err_Invalid_Table
;
520 flags_offset
= bufp
- (glyf_table
->buf
+ offset
);
522 flags
= *(bufp
++) << 8;
525 /* skip glyph component index */
528 /* skip scaling and offset arguments */
529 if (flags
& ARGS_ARE_WORDS
)
534 if (flags
& WE_HAVE_A_SCALE
)
536 else if (flags
& WE_HAVE_AN_XY_SCALE
)
538 else if (flags
& WE_HAVE_A_2X2
)
540 } while (flags
& MORE_COMPONENTS
);
542 if (flags
& WE_HAVE_INSTR
)
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
);
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);
570 glyph
->buf
= (FT_Byte
*)malloc(glyph
->len
);
572 return FT_Err_Out_Of_Memory
;
575 memcpy(glyph
->buf
, glyf_table
->buf
, glyph
->len
);
586 ins_offset
= 10 + num_contours
* 2;
591 return FT_Err_Invalid_Table
;
593 /* get number of instructions */
594 num_ins
= *(bufp
++) << 8;
595 num_ins
+= *(bufp
++);
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
);
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
);
621 /* we build a dummy `DSIG' table only */
624 TA_table_build_DSIG(FT_Byte
** DSIG
)
629 buf
= (FT_Byte
*)malloc(DSIG_LEN
);
631 return FT_Err_Out_Of_Memory
;
639 /* zero signatures */
643 /* permission flags */
654 TA_font_compute_table_offsets(FONT
* font
,
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'. */
678 TA_sfnt_build_TTF_header(SFNT
* sfnt
,
680 FT_Byte
** header_buf
,
681 FT_ULong
* header_len
,
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
;
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
;
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
;
715 buf
= (FT_Byte
*)malloc(len
);
717 return FT_Err_Out_Of_Memory
;
725 /* number of tables */
726 buf
[4] = HIGH(num_tables_in_header
);
727 buf
[5] = LOW(num_tables_in_header
);
731 FT_ULong search_range
, entry_selector
, range_shift
;
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];
755 /* loop over all tables */
756 for (i
= 0; i
< num_table_infos
; i
++)
758 SFNT_Table_Info table_info
= table_infos
[i
];
762 /* ignore empty slots */
763 if (table_info
== MISSING
)
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 */
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
);
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
);
825 TA_font_build_TTF(FONT
* font
)
827 SFNT
* sfnt
= &font
->sfnts
[0];
832 FT_ULong SFNT_offset
;
843 /* add a dummy `DSIG' table */
845 error
= TA_sfnt_add_table_info(sfnt
);
849 error
= TA_table_build_DSIG(&DSIG_buf
);
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
);
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);
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
);
885 error
= FT_Err_Out_Of_Memory
;
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);
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
;
922 FT_ULong DSIG_offset
;
931 len
= 24 + 4 * num_sfnts
;
932 buf
= (FT_Byte
*)malloc(len
);
934 return FT_Err_Out_Of_Memory
;
944 /* TTC header version */
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 */
959 /* loop over all subfonts */
960 for (i
= 0; i
< num_sfnts
; i
++)
962 SFNT
* sfnt
= &sfnts
[i
];
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
);
978 /* the first SFNT table immediately follows the subfont TTF headers */
979 TA_font_compute_table_offsets(font
, TTF_offset
);
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
);
1009 TA_font_build_TTC(FONT
* font
)
1011 SFNT
* sfnts
= font
->sfnts
;
1012 FT_Long num_sfnts
= font
->num_sfnts
;
1015 FT_ULong num_tables
;
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
;
1032 /* add a dummy `DSIG' table */
1034 error
= TA_table_build_DSIG(&DSIG_buf
);
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
);
1047 /* this also computes the SFNT table offsets */
1048 error
= TA_font_build_TTC_header(font
,
1049 &TTC_header_buf
, &TTC_header_len
);
1053 TTF_header_bufs
= (FT_Byte
**)calloc(1, num_sfnts
* sizeof (FT_Byte
*));
1054 if (!TTF_header_bufs
)
1057 TTF_header_lens
= (FT_ULong
*)malloc(num_sfnts
* sizeof (FT_ULong
));
1058 if (!TTF_header_lens
)
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);
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
);
1080 error
= FT_Err_Out_Of_Memory
;
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);
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
);
1123 TA_font_write(FONT
* font
,
1126 if (fwrite(font
->out_buf
, 1, font
->out_len
, out
) != font
->out_len
)
1127 return TA_Err_Invalid_Stream_Write
;
1134 TA_font_unload(FONT
* font
)
1136 /* in case of error it is expected that unallocated pointers */
1137 /* are NULL (and counters are zero) */
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
;
1158 for (j
= 0; j
< data
->num_glyphs
; j
++)
1159 free(data
->glyphs
[j
].buf
);
1173 for (i
= 0; i
< font
->num_sfnts
; i
++)
1175 FT_Done_Face(font
->sfnts
[i
].face
);
1176 free(font
->sfnts
[i
].table_infos
);
1181 FT_Done_FreeType(font
->lib
);
1183 free(font
->out_buf
);
1189 TTF_autohint(FILE* in
,
1197 font
= (FONT
*)calloc(1, sizeof (FONT
));
1199 return FT_Err_Out_Of_Memory
;
1201 error
= TA_font_read(font
, in
);
1205 error
= TA_font_init(font
);
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
,
1220 error
= TA_sfnt_split_into_SFNT_tables(sfnt
, font
);
1224 error
= TA_sfnt_split_glyf_table(sfnt
, font
);
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
);
1247 error
= TA_font_build_TTC(font
);
1251 error
= TA_font_write(font
, out
);
1258 TA_font_unload(font
);
1263 /* end of ttfautohint.c */