Use `Control_Type' to handle different segment directions.
[ttfautohint.git] / lib / tattf.c
blobd9d2b14523b76778a5211dd982ad633c283c8daf
1 /* tattf.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 /* 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 i, j;
79 for (i = 1, j = 2; j <= num_tables_in_header; i++, j <<= 1)
82 entry_selector = i - 1;
83 search_range = 0x10 << 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 modification time */
130 TA_get_current_time(&date_high, &date_low);
132 head_buf[28] = BYTE1(date_high);
133 head_buf[29] = BYTE2(date_high);
134 head_buf[30] = BYTE3(date_high);
135 head_buf[31] = BYTE4(date_high);
137 head_buf[32] = BYTE1(date_low);
138 head_buf[33] = BYTE2(date_low);
139 head_buf[34] = BYTE3(date_low);
140 head_buf[35] = BYTE4(date_low);
142 table->checksum = TA_table_compute_checksum(table->buf, table->len);
145 head_checksum += table->checksum;
147 table_record[0] = BYTE1(table->tag);
148 table_record[1] = BYTE2(table->tag);
149 table_record[2] = BYTE3(table->tag);
150 table_record[3] = BYTE4(table->tag);
152 table_record[4] = BYTE1(table->checksum);
153 table_record[5] = BYTE2(table->checksum);
154 table_record[6] = BYTE3(table->checksum);
155 table_record[7] = BYTE4(table->checksum);
157 table_record[8] = BYTE1(table->offset);
158 table_record[9] = BYTE2(table->offset);
159 table_record[10] = BYTE3(table->offset);
160 table_record[11] = BYTE4(table->offset);
162 table_record[12] = BYTE1(table->len);
163 table_record[13] = BYTE2(table->len);
164 table_record[14] = BYTE3(table->len);
165 table_record[15] = BYTE4(table->len);
167 table_record += 16;
170 /* the font header is complete; compute `head' checksum */
171 head_checksum += TA_table_compute_checksum(buf, len);
172 head_checksum = 0xB1B0AFBAUL - head_checksum;
174 /* store checksum in `head' table; */
175 head_buf[8] = BYTE1(head_checksum);
176 head_buf[9] = BYTE2(head_checksum);
177 head_buf[10] = BYTE3(head_checksum);
178 head_buf[11] = BYTE4(head_checksum);
180 *header_buf = buf;
181 *header_len = len;
183 return TA_Err_Ok;
187 FT_Error
188 TA_font_build_TTF(FONT* font)
190 SFNT* sfnt = &font->sfnts[0];
192 SFNT_Table* tables;
193 FT_ULong num_tables;
195 FT_ULong SFNT_offset;
197 FT_Byte* header_buf;
198 FT_ULong header_len;
200 FT_ULong i;
201 FT_Error error;
204 /* add our information table */
206 if (font->TTFA_info)
208 FT_Byte* TTFA_buf;
209 FT_ULong TTFA_len;
212 error = TA_sfnt_add_table_info(sfnt);
213 if (error)
214 return error;
216 error = TA_table_build_TTFA(&TTFA_buf, &TTFA_len, font);
217 if (error)
218 return error;
220 /* in case of success, `TTFA_buf' gets linked */
221 /* and is eventually freed in `TA_font_unload' */
222 error = TA_font_add_table(font,
223 &sfnt->table_infos[sfnt->num_table_infos - 1],
224 TTAG_TTFA, TTFA_len, TTFA_buf);
225 if (error)
227 free(TTFA_buf);
228 return error;
232 /* replace an existing `DSIG' table with a dummy */
234 if (font->have_DSIG)
236 FT_Byte* DSIG_buf;
239 error = TA_sfnt_add_table_info(sfnt);
240 if (error)
241 return error;
243 error = TA_table_build_DSIG(&DSIG_buf);
244 if (error)
245 return error;
247 /* in case of success, `DSIG_buf' gets linked */
248 /* and is eventually freed in `TA_font_unload' */
249 error = TA_font_add_table(font,
250 &sfnt->table_infos[sfnt->num_table_infos - 1],
251 TTAG_DSIG, DSIG_LEN, DSIG_buf);
252 if (error)
254 free(DSIG_buf);
255 return error;
259 TA_sfnt_sort_table_info(sfnt, font);
261 /* the first SFNT table immediately follows the header */
262 (void)TA_sfnt_build_TTF_header(sfnt, font, NULL, &SFNT_offset, 0);
263 TA_font_compute_table_offsets(font, SFNT_offset);
265 error = TA_sfnt_build_TTF_header(sfnt, font,
266 &header_buf, &header_len, 1);
267 if (error)
268 return error;
270 /* build font */
272 tables = font->tables;
273 num_tables = font->num_tables;
275 /* get font length from last SFNT table array element */
276 font->out_len = tables[num_tables - 1].offset
277 + ((tables[num_tables - 1].len + 3) & ~3);
278 font->out_buf = (FT_Byte*)malloc(font->out_len);
279 if (!font->out_buf)
281 error = FT_Err_Out_Of_Memory;
282 goto Err;
285 memcpy(font->out_buf, header_buf, header_len);
287 for (i = 0; i < num_tables; i++)
289 SFNT_Table* table = &tables[i];
292 /* buffer length is a multiple of 4 */
293 memcpy(font->out_buf + table->offset,
294 table->buf, (table->len + 3) & ~3);
297 error = TA_Err_Ok;
299 Err:
300 free(header_buf);
302 return error;
305 /* end of tattf.c */