Minor.
[ttfautohint.git] / lib / tattc.c
blob8cab7014622281a499162cb9da71d9a8da6d4d55
1 /* tattc.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 static FT_Error
20 TA_font_build_TTC_header(FONT* font,
21 FT_Byte** header_buf,
22 FT_ULong* header_len)
24 SFNT* sfnts = font->sfnts;
25 FT_Long num_sfnts = font->num_sfnts;
27 SFNT_Table* tables = font->tables;
28 FT_ULong num_tables = font->num_tables;
30 FT_ULong TTF_offset;
31 FT_ULong DSIG_offset;
33 FT_Byte* buf;
34 FT_ULong len;
36 FT_Long i;
37 FT_Byte* p;
40 len = (font->have_DSIG ? 24 : 12) + 4 * num_sfnts;
41 buf = (FT_Byte*)malloc(len);
42 if (!buf)
43 return FT_Err_Out_Of_Memory;
45 p = buf;
47 /* TTC ID string */
48 *(p++) = 't';
49 *(p++) = 't';
50 *(p++) = 'c';
51 *(p++) = 'f';
53 /* TTC header version */
54 *(p++) = 0x00;
55 *(p++) = font->have_DSIG ? 0x02 : 0x01;
56 *(p++) = 0x00;
57 *(p++) = 0x00;
59 /* number of subfonts */
60 *(p++) = BYTE1(num_sfnts);
61 *(p++) = BYTE2(num_sfnts);
62 *(p++) = BYTE3(num_sfnts);
63 *(p++) = BYTE4(num_sfnts);
65 /* the first TTF subfont header immediately follows the TTC header */
66 TTF_offset = len;
68 /* loop over all subfonts */
69 for (i = 0; i < num_sfnts; i++)
71 SFNT* sfnt = &sfnts[i];
72 FT_ULong l;
75 TA_sfnt_sort_table_info(sfnt, font);
76 /* only get header length */
77 (void)TA_sfnt_build_TTF_header(sfnt, font, NULL, &l, 0);
79 *(p++) = BYTE1(TTF_offset);
80 *(p++) = BYTE2(TTF_offset);
81 *(p++) = BYTE3(TTF_offset);
82 *(p++) = BYTE4(TTF_offset);
84 TTF_offset += l;
87 /* the first SFNT table immediately follows the subfont TTF headers */
88 TA_font_compute_table_offsets(font, TTF_offset);
90 if (font->have_DSIG)
92 /* DSIG tag */
93 *(p++) = 'D';
94 *(p++) = 'S';
95 *(p++) = 'I';
96 *(p++) = 'G';
98 /* DSIG length */
99 *(p++) = 0x00;
100 *(p++) = 0x00;
101 *(p++) = 0x00;
102 *(p++) = 0x08;
104 /* DSIG offset; in a TTC this is always the last SFNT table */
105 DSIG_offset = tables[num_tables - 1].offset;
107 *(p++) = BYTE1(DSIG_offset);
108 *(p++) = BYTE2(DSIG_offset);
109 *(p++) = BYTE3(DSIG_offset);
110 *(p++) = BYTE4(DSIG_offset);
113 *header_buf = buf;
114 *header_len = len;
116 return TA_Err_Ok;
120 FT_Error
121 TA_font_build_TTC(FONT* font)
123 SFNT* sfnts = font->sfnts;
124 FT_Long num_sfnts = font->num_sfnts;
126 SFNT_Table* tables;
127 FT_ULong num_tables;
129 FT_Byte* DSIG_buf;
130 SFNT_Table_Info dummy;
132 FT_Byte* TTC_header_buf;
133 FT_ULong TTC_header_len;
135 FT_Byte** TTF_header_bufs = NULL;
136 FT_ULong* TTF_header_lens = NULL;
138 FT_ULong offset;
139 FT_Long i;
140 FT_ULong j;
141 FT_Error error;
144 /* replace an existing `DSIG' table with a dummy */
146 if (font->have_DSIG)
148 error = TA_table_build_DSIG(&DSIG_buf);
149 if (error)
150 return error;
152 /* in case of success, `DSIG_buf' gets linked */
153 /* and is eventually freed in `TA_font_unload' */
154 error = TA_font_add_table(font, &dummy, TTAG_DSIG, DSIG_LEN, DSIG_buf);
155 if (error)
157 free(DSIG_buf);
158 return error;
162 /* this also computes the SFNT table offsets */
163 error = TA_font_build_TTC_header(font,
164 &TTC_header_buf, &TTC_header_len);
165 if (error)
166 return error;
168 TTF_header_bufs = (FT_Byte**)calloc(1, num_sfnts * sizeof (FT_Byte*));
169 if (!TTF_header_bufs)
170 goto Err;
172 TTF_header_lens = (FT_ULong*)malloc(num_sfnts * sizeof (FT_ULong));
173 if (!TTF_header_lens)
174 goto Err;
176 for (i = 0; i < num_sfnts; i++)
178 error = TA_sfnt_build_TTF_header(&sfnts[i], font,
179 &TTF_header_bufs[i],
180 &TTF_header_lens[i], 1);
181 if (error)
182 goto Err;
185 /* build font */
187 tables = font->tables;
188 num_tables = font->num_tables;
190 /* get font length from last SFNT table array element */
191 font->out_len = tables[num_tables - 1].offset
192 + ((tables[num_tables - 1].len + 3) & ~3);
193 font->out_buf = (FT_Byte*)malloc(font->out_len);
194 if (!font->out_buf)
196 error = FT_Err_Out_Of_Memory;
197 goto Err;
200 memcpy(font->out_buf, TTC_header_buf, TTC_header_len);
202 offset = TTC_header_len;
204 for (i = 0; i < num_sfnts; i++)
206 memcpy(font->out_buf + offset,
207 TTF_header_bufs[i], TTF_header_lens[i]);
209 offset += TTF_header_lens[i];
212 for (j = 0; j < num_tables; j++)
214 SFNT_Table* table = &tables[j];
217 /* buffer length is a multiple of 4 */
218 memcpy(font->out_buf + table->offset,
219 table->buf, (table->len + 3) & ~3);
222 error = TA_Err_Ok;
224 Err:
225 free(TTC_header_buf);
226 if (TTF_header_bufs)
228 for (i = 0; i < font->num_sfnts; i++)
229 free(TTF_header_bufs[i]);
230 free(TTF_header_bufs);
232 free(TTF_header_lens);
234 return error;
238 /* end of tattc.c */