Use `Control_Type' to handle different segment directions.
[ttfautohint.git] / lib / tasfnt.c
blobea2d25ed3d7c3ef436df8cbd69d8aef214ef8d04
1 /* tasfnt.c */
3 /*
4 * Copyright (C) 2011-2014 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 TA_Err_Invalid_Font_Type;
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->name_idx = MISSING;
47 sfnt->post_idx = MISSING;
48 sfnt->OS2_idx = MISSING;
49 sfnt->GPOS_idx = MISSING;
51 for (i = 0; i < sfnt->num_table_infos; i++)
53 SFNT_Table_Info* table_info = &sfnt->table_infos[i];
54 FT_ULong tag;
55 FT_ULong len;
56 FT_Byte* buf;
58 FT_ULong buf_len;
59 FT_ULong j;
62 *table_info = MISSING;
64 error = FT_Sfnt_Table_Info(sfnt->face, i, &tag, &len);
65 if (error)
67 if (error == FT_Err_Table_Missing)
68 continue;
69 else
70 return error;
73 /* ignore zero-length tables */
74 else if (!len)
75 continue;
77 /* ignore tables which we are going to create by ourselves, */
78 /* or which would become invalid otherwise */
79 else if (tag == TTAG_fpgm
80 || tag == TTAG_prep
81 || tag == TTAG_cvt
82 || tag == TTAG_hdmx
83 || tag == TTAG_VDMX
84 || tag == TTAG_LTSH
85 || tag == TTAG_gasp)
86 continue;
88 else if (tag == TTAG_DSIG)
90 font->have_DSIG = 1;
91 continue;
94 /* make the allocated buffer length a multiple of 4 */
95 buf_len = (len + 3) & ~3;
96 buf = (FT_Byte*)malloc(buf_len);
97 if (!buf)
98 return FT_Err_Out_Of_Memory;
100 /* pad end of buffer with zeros */
101 buf[buf_len - 1] = 0x00;
102 buf[buf_len - 2] = 0x00;
103 buf[buf_len - 3] = 0x00;
105 /* load table */
106 error = FT_Load_Sfnt_Table(sfnt->face, tag, 0, buf, &len);
107 if (error)
108 goto Err;
110 /* check whether we already have this table */
111 for (j = 0; j < font->num_tables; j++)
113 SFNT_Table* table = &font->tables[j];
116 if (table->tag == tag
117 && table->len == len
118 && !memcmp(table->buf, buf, len))
119 break;
122 if (tag == TTAG_head)
123 sfnt->head_idx = j;
124 else if (tag == TTAG_glyf)
125 sfnt->glyf_idx = j;
126 else if (tag == TTAG_hmtx)
127 sfnt->hmtx_idx = j;
128 else if (tag == TTAG_loca)
129 sfnt->loca_idx = j;
130 else if (tag == TTAG_maxp)
132 sfnt->maxp_idx = j;
134 sfnt->max_components = buf[MAXP_MAX_COMPONENTS_OFFSET] << 8;
135 sfnt->max_components += buf[MAXP_MAX_COMPONENTS_OFFSET + 1];
137 else if (tag == TTAG_name)
138 sfnt->name_idx = j;
139 else if (tag == TTAG_post)
140 sfnt->post_idx = j;
141 else if (tag == TTAG_OS2)
142 sfnt->OS2_idx = j;
143 else if (tag == TTAG_GPOS)
144 sfnt->GPOS_idx = j;
146 if (j == font->num_tables)
148 /* add element to table array if it is missing or different; */
149 /* in case of success, `buf' gets linked and is eventually */
150 /* freed in `TA_font_unload' */
151 error = TA_font_add_table(font, table_info, tag, len, buf);
152 if (error)
153 goto Err;
155 else
157 /* reuse existing SFNT table */
158 free(buf);
159 *table_info = j;
161 continue;
163 Err:
164 free(buf);
165 return error;
168 /* no (non-empty) `glyf', `loca', `head', or `maxp' table; */
169 /* this can't be a valid TTF with outlines */
170 if (sfnt->glyf_idx == MISSING
171 || sfnt->loca_idx == MISSING
172 || sfnt->head_idx == MISSING
173 || sfnt->maxp_idx == MISSING)
174 return TA_Err_Invalid_Font_Type;
176 return TA_Err_Ok;
179 /* end of tasfnt.c */