4 * Copyright (C) 2011-2012 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
= 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];
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 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
);
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
);
188 TA_font_build_TTF(FONT
* font
)
190 SFNT
* sfnt
= &font
->sfnts
[0];
195 FT_ULong SFNT_offset
;
206 /* replace an existing `DSIG' table with a dummy */
210 error
= TA_sfnt_add_table_info(sfnt
);
214 error
= TA_table_build_DSIG(&DSIG_buf
);
218 /* in case of success, `DSIG_buf' gets linked */
219 /* and is eventually freed in `TA_font_unload' */
220 error
= TA_font_add_table(font
,
221 &sfnt
->table_infos
[sfnt
->num_table_infos
- 1],
222 TTAG_DSIG
, DSIG_LEN
, DSIG_buf
);
230 TA_sfnt_sort_table_info(sfnt
, font
);
232 /* the first SFNT table immediately follows the header */
233 (void)TA_sfnt_build_TTF_header(sfnt
, font
, NULL
, &SFNT_offset
, 0);
234 TA_font_compute_table_offsets(font
, SFNT_offset
);
236 error
= TA_sfnt_build_TTF_header(sfnt
, font
,
237 &header_buf
, &header_len
, 1);
243 tables
= font
->tables
;
244 num_tables
= font
->num_tables
;
246 /* get font length from last SFNT table array element */
247 font
->out_len
= tables
[num_tables
- 1].offset
248 + ((tables
[num_tables
- 1].len
+ 3) & ~3);
249 font
->out_buf
= (FT_Byte
*)malloc(font
->out_len
);
252 error
= FT_Err_Out_Of_Memory
;
256 memcpy(font
->out_buf
, header_buf
, header_len
);
258 for (i
= 0; i
< num_tables
; i
++)
260 SFNT_Table
* table
= &tables
[i
];
263 /* buffer length is a multiple of 4 */
264 memcpy(font
->out_buf
+ table
->offset
,
265 table
->buf
, (table
->len
+ 3) & ~3);