Fix OTS warning about `maxp.maxSizeOfInstructions`.
[ttfautohint.git] / lib / tattf.c
blob16e95d98e31384e294fa29741e6a08dc28a7202c
1 /* tattf.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 /* If `do_complete' is 0, only return `header_len'. */
21 FT_Error
22 TA_sfnt_build_TTF_header(SFNT* sfnt,
23 FONT* font,
24 FT_Byte** header_buf,
25 FT_ULong* header_len,
26 FT_Int do_complete)
28 SFNT_Table* tables = font->tables;
30 SFNT_Table_Info* table_infos = sfnt->table_infos;
31 FT_ULong num_table_infos = sfnt->num_table_infos;
33 FT_Byte* buf;
34 FT_ULong len;
36 FT_Byte* table_record;
38 FT_Byte* head_buf = NULL; /* pointer to `head' table */
39 FT_ULong head_checksum; /* checksum in `head' table */
41 FT_ULong num_tables_in_header;
42 FT_ULong i;
45 num_tables_in_header = 0;
46 for (i = 0; i < num_table_infos; i++)
48 /* ignore empty tables */
49 if (table_infos[i] != MISSING)
50 num_tables_in_header++;
53 len = 12 + 16 * num_tables_in_header;
54 if (!do_complete)
56 *header_len = len;
57 return TA_Err_Ok;
59 buf = (FT_Byte*)malloc(len);
60 if (!buf)
61 return FT_Err_Out_Of_Memory;
63 /* SFNT version */
64 buf[0] = 0x00;
65 buf[1] = 0x01;
66 buf[2] = 0x00;
67 buf[3] = 0x00;
69 /* number of tables */
70 buf[4] = HIGH(num_tables_in_header);
71 buf[5] = LOW(num_tables_in_header);
73 /* auxiliary data */
75 FT_ULong search_range, entry_selector, range_shift;
76 FT_ULong j;
79 for (i = 1, j = 2; j <= num_tables_in_header; i++, j <<= 1)
82 entry_selector = i - 1;
83 search_range = 0x10U << entry_selector;
84 range_shift = (num_tables_in_header << 4) - search_range;
86 buf[6] = HIGH(search_range);
87 buf[7] = LOW(search_range);
88 buf[8] = HIGH(entry_selector);
89 buf[9] = LOW(entry_selector);
90 buf[10] = HIGH(range_shift);
91 buf[11] = LOW(range_shift);
94 /* location of the first table info record */
95 table_record = &buf[12];
97 head_checksum = 0;
99 /* loop over all tables */
100 for (i = 0; i < num_table_infos; i++)
102 SFNT_Table_Info table_info = table_infos[i];
103 SFNT_Table* table;
106 /* ignore empty slots */
107 if (table_info == MISSING)
108 continue;
110 table = &tables[table_info];
112 if (table->tag == TTAG_head)
114 FT_ULong date_high;
115 FT_ULong date_low;
118 /* we always reach this IF clause since FreeType would */
119 /* have aborted already if the `head' table were missing */
121 head_buf = table->buf;
123 /* reset checksum in `head' table for recalculation */
124 head_buf[8] = 0x00;
125 head_buf[9] = 0x00;
126 head_buf[10] = 0x00;
127 head_buf[11] = 0x00;
129 /* update flags; we have to */
130 /* set bit 2 (`instructions may depend on point size') and to */
131 /* clear bit 4 (`instructions may alter advance width') */
132 head_buf[17] |= 0x04U;
133 head_buf[17] &= ~0x10U;
135 /* update modification time */
136 TA_get_current_time(font, &date_high, &date_low);
138 head_buf[28] = BYTE1(date_high);
139 head_buf[29] = BYTE2(date_high);
140 head_buf[30] = BYTE3(date_high);
141 head_buf[31] = BYTE4(date_high);
143 head_buf[32] = BYTE1(date_low);
144 head_buf[33] = BYTE2(date_low);
145 head_buf[34] = BYTE3(date_low);
146 head_buf[35] = BYTE4(date_low);
148 table->checksum = TA_table_compute_checksum(table->buf, table->len);
151 head_checksum += table->checksum;
153 table_record[0] = BYTE1(table->tag);
154 table_record[1] = BYTE2(table->tag);
155 table_record[2] = BYTE3(table->tag);
156 table_record[3] = BYTE4(table->tag);
158 table_record[4] = BYTE1(table->checksum);
159 table_record[5] = BYTE2(table->checksum);
160 table_record[6] = BYTE3(table->checksum);
161 table_record[7] = BYTE4(table->checksum);
163 table_record[8] = BYTE1(table->offset);
164 table_record[9] = BYTE2(table->offset);
165 table_record[10] = BYTE3(table->offset);
166 table_record[11] = BYTE4(table->offset);
168 table_record[12] = BYTE1(table->len);
169 table_record[13] = BYTE2(table->len);
170 table_record[14] = BYTE3(table->len);
171 table_record[15] = BYTE4(table->len);
173 table_record += 16;
176 /* the font header is complete; compute `head' checksum */
177 head_checksum += TA_table_compute_checksum(buf, len);
178 head_checksum = 0xB1B0AFBAUL - head_checksum;
180 /* store checksum in `head' table; */
181 head_buf[8] = BYTE1(head_checksum);
182 head_buf[9] = BYTE2(head_checksum);
183 head_buf[10] = BYTE3(head_checksum);
184 head_buf[11] = BYTE4(head_checksum);
186 *header_buf = buf;
187 *header_len = len;
189 return TA_Err_Ok;
193 FT_Error
194 TA_font_build_TTF(FONT* font)
196 SFNT* sfnt = &font->sfnts[0];
198 SFNT_Table* tables;
199 FT_ULong num_tables;
201 FT_ULong SFNT_offset;
203 FT_Byte* header_buf;
204 FT_ULong header_len;
206 FT_ULong i;
207 FT_Error error;
210 /* add our information table */
212 if (font->TTFA_info)
214 FT_Byte* TTFA_buf;
215 FT_ULong TTFA_len;
218 error = TA_sfnt_add_table_info(sfnt);
219 if (error)
220 return error;
222 error = TA_table_build_TTFA(&TTFA_buf, &TTFA_len, font);
223 if (error)
224 return error;
226 /* in case of success, `TTFA_buf' gets linked */
227 /* and is eventually freed in `TA_font_unload' */
228 error = TA_font_add_table(font,
229 &sfnt->table_infos[sfnt->num_table_infos - 1],
230 TTAG_TTFA, TTFA_len, TTFA_buf);
231 if (error)
233 free(TTFA_buf);
234 return error;
238 /* replace an existing `DSIG' table with a dummy */
240 if (font->have_DSIG)
242 FT_Byte* DSIG_buf;
245 error = TA_sfnt_add_table_info(sfnt);
246 if (error)
247 return error;
249 error = TA_table_build_DSIG(&DSIG_buf);
250 if (error)
251 return error;
253 /* in case of success, `DSIG_buf' gets linked */
254 /* and is eventually freed in `TA_font_unload' */
255 error = TA_font_add_table(font,
256 &sfnt->table_infos[sfnt->num_table_infos - 1],
257 TTAG_DSIG, DSIG_LEN, DSIG_buf);
258 if (error)
260 free(DSIG_buf);
261 return error;
265 TA_sfnt_sort_table_info(sfnt, font);
267 /* the first SFNT table immediately follows the header */
268 (void)TA_sfnt_build_TTF_header(sfnt, font, NULL, &SFNT_offset, 0);
269 TA_font_compute_table_offsets(font, SFNT_offset);
271 error = TA_sfnt_build_TTF_header(sfnt, font,
272 &header_buf, &header_len, 1);
273 if (error)
274 return error;
276 /* build font */
278 tables = font->tables;
279 num_tables = font->num_tables;
281 /* get font length from last SFNT table array element */
282 font->out_len = tables[num_tables - 1].offset
283 + ((tables[num_tables - 1].len + 3) & ~3U);
284 /* if `out-buffer' is set, this buffer gets returned to the user, */
285 /* thus we use the customized allocator function */
286 font->out_buf = (FT_Byte*)font->allocate(font->out_len);
287 if (!font->out_buf)
289 error = FT_Err_Out_Of_Memory;
290 goto Err;
293 memcpy(font->out_buf, header_buf, header_len);
295 for (i = 0; i < num_tables; i++)
297 SFNT_Table* table = &tables[i];
300 /* buffer length is a multiple of 4 */
301 memcpy(font->out_buf + table->offset,
302 table->buf, (table->len + 3) & ~3U);
305 error = TA_Err_Ok;
307 Err:
308 free(header_buf);
310 return error;
313 /* end of tattf.c */