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.
19 /* If `do_complete' is 0, only return `header_len'. */
22 TA_sfnt_build_TTF_header(SFNT
* sfnt
,
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
;
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
;
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
;
59 buf
= (FT_Byte
*)malloc(len
);
61 return FT_Err_Out_Of_Memory
;
69 /* number of tables */
70 buf
[4] = HIGH(num_tables_in_header
);
71 buf
[5] = LOW(num_tables_in_header
);
75 FT_ULong search_range
, entry_selector
, range_shift
;
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];
99 /* loop over all tables */
100 for (i
= 0; i
< num_table_infos
; i
++)
102 SFNT_Table_Info table_info
= table_infos
[i
];
106 /* ignore empty slots */
107 if (table_info
== MISSING
)
110 table
= &tables
[table_info
];
112 if (table
->tag
== TTAG_head
)
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 */
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
);
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
);
194 TA_font_build_TTF(FONT
* font
)
196 SFNT
* sfnt
= &font
->sfnts
[0];
201 FT_ULong SFNT_offset
;
210 /* add our information table */
218 error
= TA_sfnt_add_table_info(sfnt
);
222 error
= TA_table_build_TTFA(&TTFA_buf
, &TTFA_len
, font
);
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
);
238 /* replace an existing `DSIG' table with a dummy */
245 error
= TA_sfnt_add_table_info(sfnt
);
249 error
= TA_table_build_DSIG(&DSIG_buf
);
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
);
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);
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
);
289 error
= FT_Err_Out_Of_Memory
;
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);