Fix OTS warning about `maxp.maxSizeOfInstructions`.
[ttfautohint.git] / lib / tasfnt.c
blobaa647ca33c0ce6a2ac16851ae782b0152d2bebd5
1 /* tasfnt.c */
3 /*
4 * Copyright (C) 2011-2022 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, (FT_UInt)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_cvt
80 || tag == TTAG_fpgm
81 || tag == TTAG_gasp
82 || tag == TTAG_hdmx
83 || tag == TTAG_LTSH
84 || tag == TTAG_prep
85 || tag == TTAG_TTFA
86 || tag == TTAG_VDMX)
87 continue;
89 else if (tag == TTAG_DSIG)
91 font->have_DSIG = 1;
92 continue;
95 /* make the allocated buffer length a multiple of 4 */
96 buf_len = (len + 3) & ~3U;
97 buf = (FT_Byte*)malloc(buf_len);
98 if (!buf)
99 return FT_Err_Out_Of_Memory;
101 /* pad end of buffer with zeros */
102 buf[buf_len - 1] = 0x00;
103 buf[buf_len - 2] = 0x00;
104 buf[buf_len - 3] = 0x00;
106 /* load table */
107 error = FT_Load_Sfnt_Table(sfnt->face, tag, 0, buf, &len);
108 if (error)
109 goto Err;
111 /* check whether we already have this table */
112 for (j = 0; j < font->num_tables; j++)
114 SFNT_Table* table = &font->tables[j];
117 if (table->tag == tag
118 && table->len == len
119 && !memcmp(table->buf, buf, len))
120 break;
123 if (tag == TTAG_head)
124 sfnt->head_idx = j;
125 else if (tag == TTAG_glyf)
126 sfnt->glyf_idx = j;
127 else if (tag == TTAG_hmtx)
128 sfnt->hmtx_idx = j;
129 else if (tag == TTAG_loca)
130 sfnt->loca_idx = j;
131 else if (tag == TTAG_maxp)
133 sfnt->maxp_idx = j;
135 sfnt->max_components = (FT_UShort)(buf[MAXP_MAX_COMPONENTS_OFFSET] << 8
136 | buf[MAXP_MAX_COMPONENTS_OFFSET + 1]);
138 else if (tag == TTAG_name)
139 sfnt->name_idx = j;
140 else if (tag == TTAG_post)
141 sfnt->post_idx = j;
142 else if (tag == TTAG_OS2)
143 sfnt->OS2_idx = j;
144 else if (tag == TTAG_GPOS)
145 sfnt->GPOS_idx = j;
147 if (j == font->num_tables)
149 /* add element to table array if it is missing or different; */
150 /* in case of success, `buf' gets linked and is eventually */
151 /* freed in `TA_font_unload' */
152 error = TA_font_add_table(font, table_info, tag, len, buf);
153 if (error)
154 goto Err;
156 else
158 /* reuse existing SFNT table */
159 free(buf);
160 *table_info = j;
162 continue;
164 Err:
165 free(buf);
166 return error;
169 /* no (non-empty) `glyf', `loca', `head', or `maxp' table; */
170 /* this can't be a valid TTF with outlines */
171 if (sfnt->glyf_idx == MISSING
172 || sfnt->loca_idx == MISSING
173 || sfnt->head_idx == MISSING
174 || sfnt->maxp_idx == MISSING)
175 return TA_Err_Invalid_Font_Type;
177 return TA_Err_Ok;
180 /* end of tasfnt.c */