3 /* written 2011 by Werner Lemberg <wl@gnu.org> */
5 /* This file needs FreeType 2.4.5 or newer. */
13 #include FT_FREETYPE_H
14 #include FT_TRUETYPE_TABLES_H
15 #include FT_TRUETYPE_TAGS_H
17 #include "ttfautohint.h"
20 /* these macros convert 16bit and 32bit numbers into single bytes */
21 /* using the byte order needed within SFNT files */
23 #define HIGH(x) (FT_Byte)(((x) & 0xFF00) >> 8)
24 #define LOW(x) ((x) & 0x00FF)
26 #define BYTE1(x) (FT_Byte)(((x) & 0xFF000000UL) >> 24);
27 #define BYTE2(x) (FT_Byte)(((x) & 0x00FF0000UL) >> 16);
28 #define BYTE3(x) (FT_Byte)(((x) & 0x0000FF00UL) >> 8);
29 #define BYTE4(x) ((x) & 0x000000FFUL);
32 /* this structure represents both the data contained in the SFNT */
33 /* table records and the actual SFNT table data */
34 typedef struct SFNT_Table_
{
38 FT_ULong offset
; /* used while building output font only */
41 /* this structure is used to model a TTF or a subfont within a TTC */
42 typedef struct SFNT_
{
44 SFNT_Table
* table_infos
;
45 FT_ULong num_table_infos
;
49 typedef struct FONT_
{
67 TA_font_read(FILE* in
,
70 fseek(in
, 0, SEEK_END
);
71 font
->in_len
= ftell(in
);
72 fseek(in
, 0, SEEK_SET
);
74 /* a valid TTF can never be that small */
75 if (font
->in_len
< 100)
76 return FT_Err_Invalid_Argument
;
78 font
->in_buf
= (FT_Byte
*)malloc(font
->in_len
* sizeof (FT_Byte
));
80 return FT_Err_Out_Of_Memory
;
82 if (fread(font
->in_buf
, 1, font
->in_len
, in
) != font
->in_len
)
83 return FT_Err_Invalid_Stream_Read
;
90 TA_font_init(FONT
* font
)
96 error
= FT_Init_FreeType(&font
->lib
);
100 /* get number of faces (i.e. subfonts) */
101 error
= FT_New_Memory_Face(font
->lib
, font
->in_buf
, font
->in_len
, -1, &f
);
104 font
->num_sfnts
= f
->num_faces
;
107 /* it is a TTC if we have more than a single subfont */
108 font
->sfnts
= (SFNT
*)calloc(1, font
->num_sfnts
* sizeof (SFNT
));
110 return FT_Err_Out_Of_Memory
;
117 TA_sfnt_collect_table_info(SFNT
* sfnt
)
124 /* check that font is TTF or TTC */
125 if (!FT_IS_SFNT(sfnt
->face
))
126 return FT_Err_Invalid_Argument
;
128 error
= FT_Sfnt_Table_Info(sfnt
->face
, 0, NULL
, &sfnt
->num_table_infos
);
133 (SFNT_Table
*)calloc(1, sfnt
->num_table_infos
* sizeof (SFNT_Table
));
134 if (!sfnt
->table_infos
)
135 return FT_Err_Out_Of_Memory
;
137 /* collect SFNT table information and search for `glyf' table */
138 glyf_idx
= sfnt
->num_table_infos
;
139 for (i
= 0; i
< sfnt
->num_table_infos
; i
++)
144 error
= FT_Sfnt_Table_Info(sfnt
->face
, i
, &tag
, &len
);
145 if (error
&& error
!= FT_Err_Table_Missing
)
150 if (tag
== TTAG_glyf
)
153 /* ignore tables which we are going to create by ourselves */
154 if (!(tag
== TTAG_fpgm
157 || tag
== TTAG_DSIG
))
159 sfnt
->table_infos
[i
].tag
= tag
;
160 sfnt
->table_infos
[i
].len
= len
;
165 /* no (non-empty) `glyf' table; this can't be a TTF with outlines */
166 if (glyf_idx
== sfnt
->num_table_infos
)
167 return FT_Err_Invalid_Argument
;
174 TA_font_add_table(FONT
* font
,
175 SFNT_Table
* table_info
,
178 SFNT_Table
* tables_new
;
179 SFNT_Table
* table_last
;
183 tables_new
= (SFNT_Table
*)realloc(font
->tables
,
184 font
->num_tables
* sizeof (SFNT_Table
));
186 return FT_Err_Out_Of_Memory
;
188 font
->tables
= tables_new
;
190 table_last
= &font
->tables
[font
->num_tables
- 1];
192 table_last
->tag
= table_info
->tag
;
193 table_last
->len
= table_info
->len
;
194 table_last
->buf
= buf
;
196 /* link buffer pointer */
197 table_info
->buf
= table_last
->buf
;
204 TA_font_split_into_SFNT_tables(SFNT
* sfnt
,
211 for (i
= 0; i
< sfnt
->num_table_infos
; i
++)
213 SFNT_Table
* table_info
= &sfnt
->table_infos
[i
];
216 /* we ignore empty tables */
224 /* make the allocated buffer length a multiple of 4; */
225 /* this simplifies writing the tables back */
226 len
= (table_info
->len
+ 3) & ~3;
228 buf
= (FT_Byte
*)malloc(len
* sizeof (FT_Byte
));
230 return FT_Err_Out_Of_Memory
;
232 /* pad buffer with zeros */
238 error
= FT_Load_Sfnt_Table(sfnt
->face
, table_info
->tag
, 0,
239 buf
, &table_info
->len
);
243 /* check whether we already have this table */
244 for (j
= 0; j
< font
->num_tables
; j
++)
246 SFNT_Table
* table
= &font
->tables
[j
];
249 if (table
->tag
== table_info
->tag
250 && table
->len
== table_info
->len
251 && !memcmp(table
->buf
, buf
, table
->len
))
255 if (j
== font
->num_tables
)
257 /* add element to table array if it is missing or different */
258 error
= TA_font_add_table(font
, table_info
, buf
);
265 table_info
->buf
= font
->tables
[j
].buf
;
280 TA_table_compute_checksum(FT_Byte
* buf
,
283 FT_Byte
* end_buf
= buf
+ len
;
284 FT_ULong checksum
= 0;
287 while (buf
< end_buf
)
289 checksum
+= *(buf
++) << 24;
290 checksum
+= *(buf
++) << 16;
291 checksum
+= *(buf
++) << 8;
292 checksum
+= *(buf
++);
300 TA_font_build_TTF(FONT
* font
)
302 SFNT
* sfnt
= &font
->sfnts
[0];
303 SFNT_Table
* table_infos
= sfnt
->table_infos
;
304 FT_ULong num_table_infos
= sfnt
->num_table_infos
;
306 FT_ULong num_tables_in_header
;
311 FT_Byte
* head_buf
= NULL
;
312 FT_ULong head_checksum
; /* checksum in `head' table */
314 FT_Byte
* table_record
;
315 FT_ULong table_offset
;
321 num_tables_in_header
= 0;
323 for (i
= 0; i
< num_table_infos
; i
++)
325 /* ignore empty tables */
326 if (table_infos
[i
].len
)
327 num_tables_in_header
++;
330 if (num_tables_in_header
> 0xFFFF)
331 return FT_Err_Array_Too_Large
;
333 /* construct TTF header */
335 header_len
= 12 + 16 * num_tables_in_header
;
336 header_buf
= (FT_Byte
*)malloc(header_len
* sizeof (FT_Byte
));
338 return FT_Err_Out_Of_Memory
;
341 header_buf
[0] = 0x00;
342 header_buf
[1] = 0x01;
343 header_buf
[2] = 0x00;
344 header_buf
[3] = 0x00;
346 /* number of tables */
347 header_buf
[4] = HIGH(num_tables_in_header
);
348 header_buf
[5] = LOW(num_tables_in_header
);
352 FT_ULong search_range
, entry_selector
, range_shift
;
356 for (i
= 1, j
= 2; j
<= num_tables_in_header
; i
++, j
<<= 1)
359 entry_selector
= i
- 1;
360 search_range
= 0x10 << entry_selector
;
361 range_shift
= (num_tables_in_header
<< 4) - search_range
;
363 header_buf
[6] = HIGH(search_range
);
364 header_buf
[7] = LOW(search_range
);
365 header_buf
[8] = HIGH(entry_selector
);
366 header_buf
[9] = LOW(entry_selector
);
367 header_buf
[10] = HIGH(range_shift
);
368 header_buf
[11] = LOW(range_shift
);
371 /* location of the first table record */
372 table_record
= &header_buf
[12];
373 /* the first table immediately follows the header */
374 table_offset
= header_len
;
378 /* loop over all tables */
379 for (i
= 0; i
< num_table_infos
; i
++)
381 SFNT_Table
*table_info
= &table_infos
[i
];
382 FT_ULong table_checksum
;
385 /* ignore empty tables */
386 if (!table_info
->len
)
389 table_info
->offset
= table_offset
;
391 if (table_info
->tag
== TTAG_head
)
393 /* we always reach this IF clause since FreeType would */
394 /* have aborted already if the `head' table were missing */
396 head_buf
= table_info
->buf
;
398 /* reset checksum in `head' table for recalculation */
405 table_checksum
= TA_table_compute_checksum(table_info
->buf
,
407 head_checksum
+= table_checksum
;
409 table_record
[0] = BYTE1(table_info
->tag
);
410 table_record
[1] = BYTE2(table_info
->tag
);
411 table_record
[2] = BYTE3(table_info
->tag
);
412 table_record
[3] = BYTE4(table_info
->tag
);
414 table_record
[4] = BYTE1(table_checksum
);
415 table_record
[5] = BYTE2(table_checksum
);
416 table_record
[6] = BYTE3(table_checksum
);
417 table_record
[7] = BYTE4(table_checksum
);
419 table_record
[8] = BYTE1(table_offset
);
420 table_record
[9] = BYTE2(table_offset
);
421 table_record
[10] = BYTE3(table_offset
);
422 table_record
[11] = BYTE4(table_offset
);
424 table_record
[12] = BYTE1(table_info
->len
);
425 table_record
[13] = BYTE2(table_info
->len
);
426 table_record
[14] = BYTE3(table_info
->len
);
427 table_record
[15] = BYTE4(table_info
->len
);
430 /* table offsets must be a multiple of 4; */
431 /* this also fits the actual buffer length */
432 table_offset
+= (table_info
->len
+ 3) & ~3;
435 /* the font header is complete; compute `head' checksum */
436 head_checksum
+= TA_table_compute_checksum(header_buf
, header_len
);
437 head_checksum
= 0xB1B0AFBAUL
- head_checksum
;
439 /* store checksum in `head' table; */
440 head_buf
[8] = BYTE1(head_checksum
);
441 head_buf
[9] = BYTE2(head_checksum
);
442 head_buf
[10] = BYTE3(head_checksum
);
443 head_buf
[11] = BYTE4(head_checksum
);
446 font
->out_len
= table_offset
;
447 font
->out_buf
= (FT_Byte
*)malloc(font
->out_len
* sizeof (FT_Byte
));
450 error
= FT_Err_Out_Of_Memory
;
454 memcpy(font
->out_buf
, header_buf
, header_len
);
456 for (i
= 0; i
< num_table_infos
; i
++)
458 SFNT_Table
*table_info
= &table_infos
[i
];
461 if (!table_info
->len
)
464 /* buffer length is a multiple of 4 */
465 memcpy(font
->out_buf
+ table_info
->offset
,
466 table_info
->buf
, (table_info
->len
+ 3) & ~3);
479 TA_font_build_TTC(FONT
* font
)
486 TA_font_write(FILE* out
,
489 if (fwrite(font
->out_buf
, 1, font
->out_len
, out
) != font
->out_len
)
490 return TA_Err_Invalid_Stream_Write
;
497 TA_font_unload(FONT
* font
)
499 /* in case of error it is expected that unallocated pointers */
500 /* are NULL (and counters are zero) */
510 for (i
= 0; i
< font
->num_tables
; i
++)
511 free(font
->tables
[i
].buf
);
520 for (i
= 0; i
< font
->num_sfnts
; i
++)
522 FT_Done_Face(font
->sfnts
[i
].face
);
523 free(font
->sfnts
[i
].table_infos
);
528 FT_Done_FreeType(font
->lib
);
536 TTF_autohint(FILE* in
,
544 font
= (FONT
*)calloc(1, sizeof (FONT
));
546 return FT_Err_Out_Of_Memory
;
548 error
= TA_font_read(in
, font
);
552 error
= TA_font_init(font
);
556 /* loop over subfonts */
557 for (i
= 0; i
< font
->num_sfnts
; i
++)
559 SFNT
* sfnt
= &font
->sfnts
[i
];
562 error
= FT_New_Memory_Face(font
->lib
, font
->in_buf
, font
->in_len
,
567 error
= TA_sfnt_collect_table_info(sfnt
);
571 error
= TA_font_split_into_SFNT_tables(sfnt
, font
);
577 /* compute global hints */
578 /* construct `fpgm' table */
579 /* construct `prep' table */
580 /* construct `cvt ' table */
582 /* split `glyf' table */
583 /* handle all glyphs in a loop */
586 /* construct bytecode */
588 /* construct `glyf' table */
590 /* build font from SFNT tables */
591 if (font
->num_sfnts
== 1)
592 error
= TA_font_build_TTF(font
);
594 error
= TA_font_build_TTC(font
);
598 /* write font from memory */
599 error
= TA_font_write(out
, font
);
606 TA_font_unload(font
);
611 /* end of ttfautohint.c */