Version 0.6.1.
[ttfautohint.git] / src / tasfnt.c
blobf6ca94c632749d5c6d5e40a7a79f707e9d4809e1
1 /* tasfnt.c */
3 /*
4 * Copyright (C) 2011-2012 by Werner Lemberg.
6 * This file is part of the ttfautohint library, and may only be used,
7 * modified, and distributed under the terms given in `COPYING'. By
8 * continuing to use, modify, or distribute this file you indicate that you
9 * have read `COPYING' and understand and accept it fully.
11 * The file `COPYING' mentioned in the previous paragraph is distributed
12 * with the ttfautohint library.
16 #include "ta.h"
19 FT_Error
20 TA_sfnt_split_into_SFNT_tables(SFNT* sfnt,
21 FONT* font)
23 FT_Error error;
24 FT_ULong i;
27 /* basic check whether font is a TTF or TTC */
28 if (!FT_IS_SFNT(sfnt->face))
29 return FT_Err_Invalid_Argument;
31 error = FT_Sfnt_Table_Info(sfnt->face, 0, NULL, &sfnt->num_table_infos);
32 if (error)
33 return error;
35 sfnt->table_infos = (SFNT_Table_Info*)malloc(sfnt->num_table_infos
36 * sizeof (SFNT_Table_Info));
37 if (!sfnt->table_infos)
38 return FT_Err_Out_Of_Memory;
40 /* collect SFNT tables and trace some of them */
41 sfnt->glyf_idx = MISSING;
42 sfnt->loca_idx = MISSING;
43 sfnt->head_idx = MISSING;
44 sfnt->hmtx_idx = MISSING;
45 sfnt->maxp_idx = MISSING;
46 sfnt->post_idx = MISSING;
47 sfnt->OS2_idx = MISSING;
48 sfnt->GPOS_idx = MISSING;
50 for (i = 0; i < sfnt->num_table_infos; i++)
52 SFNT_Table_Info* table_info = &sfnt->table_infos[i];
53 FT_ULong tag;
54 FT_ULong len;
55 FT_Byte* buf;
57 FT_ULong buf_len;
58 FT_ULong j;
61 *table_info = MISSING;
63 error = FT_Sfnt_Table_Info(sfnt->face, i, &tag, &len);
64 if (error)
66 /* this ignores both missing and zero-length tables */
67 if (error == FT_Err_Table_Missing)
68 continue;
69 else
70 return error;
73 /* ignore tables which we are going to create by ourselves, */
74 /* or which would become invalid otherwise */
75 else if (tag == TTAG_fpgm
76 || tag == TTAG_prep
77 || tag == TTAG_cvt
78 || tag == TTAG_hdmx
79 || tag == TTAG_VDMX
80 || tag == TTAG_LTSH
81 || tag == TTAG_gasp)
82 continue;
84 else if (tag == TTAG_DSIG)
86 font->have_DSIG = 1;
87 continue;
90 /* make the allocated buffer length a multiple of 4 */
91 buf_len = (len + 3) & ~3;
92 buf = (FT_Byte*)malloc(buf_len);
93 if (!buf)
94 return FT_Err_Out_Of_Memory;
96 /* pad end of buffer with zeros */
97 buf[buf_len - 1] = 0x00;
98 buf[buf_len - 2] = 0x00;
99 buf[buf_len - 3] = 0x00;
101 /* load table */
102 error = FT_Load_Sfnt_Table(sfnt->face, tag, 0, buf, &len);
103 if (error)
104 goto Err;
106 /* check whether we already have this table */
107 for (j = 0; j < font->num_tables; j++)
109 SFNT_Table* table = &font->tables[j];
112 if (table->tag == tag
113 && table->len == len
114 && !memcmp(table->buf, buf, len))
115 break;
118 if (tag == TTAG_head)
119 sfnt->head_idx = j;
120 else if (tag == TTAG_glyf)
121 sfnt->glyf_idx = j;
122 else if (tag == TTAG_hmtx)
123 sfnt->hmtx_idx = j;
124 else if (tag == TTAG_loca)
125 sfnt->loca_idx = j;
126 else if (tag == TTAG_maxp)
128 sfnt->maxp_idx = j;
130 sfnt->max_components = buf[MAXP_MAX_COMPONENTS_OFFSET] << 8;
131 sfnt->max_components += buf[MAXP_MAX_COMPONENTS_OFFSET + 1];
133 else if (tag == TTAG_post)
134 sfnt->post_idx = j;
135 else if (tag == TTAG_OS2)
136 sfnt->OS2_idx = j;
137 else if (tag == TTAG_GPOS)
138 sfnt->GPOS_idx = j;
140 if (j == font->num_tables)
142 /* add element to table array if it is missing or different; */
143 /* in case of success, `buf' gets linked and is eventually */
144 /* freed in `TA_font_unload' */
145 error = TA_font_add_table(font, table_info, tag, len, buf);
146 if (error)
147 goto Err;
149 else
151 /* reuse existing SFNT table */
152 free(buf);
153 *table_info = j;
155 continue;
157 Err:
158 free(buf);
159 return error;
162 /* no (non-empty) `glyf', `loca', `head', or `maxp' table; */
163 /* this can't be a valid TTF with outlines */
164 if (sfnt->glyf_idx == MISSING
165 || sfnt->loca_idx == MISSING
166 || sfnt->head_idx == MISSING
167 || sfnt->maxp_idx == MISSING)
168 return FT_Err_Invalid_Argument;
170 return TA_Err_Ok;
173 /* end of tasfnt.c */