Typo.
[ttfautohint.git] / src / ttfautohint.c
blob9ae3497fe58ff59b9578c223dfcea54464726c02
1 /* ttfautohint.c */
3 /*
4 * Copyright (C) 2011 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 /* This file needs FreeType 2.4.5 or newer. */
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <ctype.h>
23 #include "ta.h"
26 static FT_Error
27 TA_font_file_read(FONT* font,
28 FILE* in_file)
30 fseek(in_file, 0, SEEK_END);
31 font->in_len = ftell(in_file);
32 fseek(in_file, 0, SEEK_SET);
34 /* a valid TTF can never be that small */
35 if (font->in_len < 100)
36 return FT_Err_Invalid_Argument;
38 font->in_buf = (FT_Byte*)malloc(font->in_len);
39 if (!font->in_buf)
40 return FT_Err_Out_Of_Memory;
42 if (fread(font->in_buf, 1, font->in_len, in_file) != font->in_len)
43 return FT_Err_Invalid_Stream_Read;
45 return TA_Err_Ok;
49 static FT_Error
50 TA_font_init(FONT* font)
52 FT_Error error;
53 FT_Face f;
54 FT_Int major, minor, patch;
57 error = FT_Init_FreeType(&font->lib);
58 if (error)
59 return error;
61 /* assure correct FreeType version to avoid using the wrong DLL */
62 FT_Library_Version(font->lib, &major, &minor, &patch);
63 if (((major*1000 + minor)*1000 + patch) < 2004005)
64 return TA_Err_Invalid_FreeType_Version;
66 /* get number of faces (i.e. subfonts) */
67 error = FT_New_Memory_Face(font->lib, font->in_buf, font->in_len, -1, &f);
68 if (error)
69 return error;
70 font->num_sfnts = f->num_faces;
71 FT_Done_Face(f);
73 /* it is a TTC if we have more than a single subfont */
74 font->sfnts = (SFNT*)calloc(1, font->num_sfnts * sizeof (SFNT));
75 if (!font->sfnts)
76 return FT_Err_Out_Of_Memory;
78 return TA_Err_Ok;
82 static FT_Error
83 TA_sfnt_split_into_SFNT_tables(SFNT* sfnt,
84 FONT* font)
86 FT_Error error;
87 FT_ULong i;
90 /* basic check whether font is a TTF or TTC */
91 if (!FT_IS_SFNT(sfnt->face))
92 return FT_Err_Invalid_Argument;
94 error = FT_Sfnt_Table_Info(sfnt->face, 0, NULL, &sfnt->num_table_infos);
95 if (error)
96 return error;
98 sfnt->table_infos = (SFNT_Table_Info*)malloc(sfnt->num_table_infos
99 * sizeof (SFNT_Table_Info));
100 if (!sfnt->table_infos)
101 return FT_Err_Out_Of_Memory;
103 /* collect SFNT tables and search for `glyf' and `loca' table */
104 sfnt->glyf_idx = MISSING;
105 sfnt->loca_idx = MISSING;
106 sfnt->head_idx = MISSING;
107 sfnt->maxp_idx = MISSING;
108 sfnt->OS2_idx = MISSING;
110 for (i = 0; i < sfnt->num_table_infos; i++)
112 SFNT_Table_Info* table_info = &sfnt->table_infos[i];
113 FT_ULong tag;
114 FT_ULong len;
115 FT_Byte* buf;
117 FT_ULong buf_len;
118 FT_ULong j;
121 *table_info = MISSING;
123 error = FT_Sfnt_Table_Info(sfnt->face, i, &tag, &len);
124 if (error)
126 /* this ignores both missing and zero-length tables */
127 if (error == FT_Err_Table_Missing)
128 continue;
129 else
130 return error;
133 /* ignore tables which we are going to create by ourselves, */
134 /* or which would become invalid otherwise */
135 else if (tag == TTAG_fpgm
136 || tag == TTAG_prep
137 || tag == TTAG_cvt
138 || tag == TTAG_DSIG
139 || tag == TTAG_hdmx
140 || tag == TTAG_VDMX
141 || tag == TTAG_LTSH
142 || tag == TTAG_gasp)
143 continue;
145 /* make the allocated buffer length a multiple of 4 */
146 buf_len = (len + 3) & ~3;
147 buf = (FT_Byte*)malloc(buf_len);
148 if (!buf)
149 return FT_Err_Out_Of_Memory;
151 /* pad end of buffer with zeros */
152 buf[buf_len - 1] = 0x00;
153 buf[buf_len - 2] = 0x00;
154 buf[buf_len - 3] = 0x00;
156 /* load table */
157 error = FT_Load_Sfnt_Table(sfnt->face, tag, 0, buf, &len);
158 if (error)
159 goto Err;
161 /* check whether we already have this table */
162 for (j = 0; j < font->num_tables; j++)
164 SFNT_Table* table = &font->tables[j];
167 if (table->tag == tag
168 && table->len == len
169 && !memcmp(table->buf, buf, len))
170 break;
173 if (tag == TTAG_head)
174 sfnt->head_idx = j;
175 else if (tag == TTAG_glyf)
176 sfnt->glyf_idx = j;
177 else if (tag == TTAG_loca)
178 sfnt->loca_idx = j;
179 else if (tag == TTAG_maxp)
180 sfnt->maxp_idx = j;
181 else if (tag == TTAG_OS2)
182 sfnt->OS2_idx = j;
184 if (j == font->num_tables)
186 /* add element to table array if it is missing or different; */
187 /* in case of success, `buf' gets linked and is eventually */
188 /* freed in `TA_font_unload' */
189 error = TA_font_add_table(font, table_info, tag, len, buf);
190 if (error)
191 goto Err;
193 else
195 /* reuse existing SFNT table */
196 free(buf);
197 *table_info = j;
199 continue;
201 Err:
202 free(buf);
203 return error;
206 /* no (non-empty) `glyf', `loca', `head', or `maxp' table; */
207 /* this can't be a valid TTF with outlines */
208 if (sfnt->glyf_idx == MISSING
209 || sfnt->loca_idx == MISSING
210 || sfnt->head_idx == MISSING
211 || sfnt->maxp_idx == MISSING)
212 return FT_Err_Invalid_Argument;
214 return TA_Err_Ok;
218 static FT_Error
219 TA_glyph_parse_composite(GLYPH* glyph,
220 FT_Byte* buf,
221 FT_ULong len)
223 FT_ULong flags_offset; /* after the loop, this is the offset */
224 /* to the last element in the flags array */
225 FT_UShort flags;
227 FT_Byte* p;
228 FT_Byte* endp;
231 p = buf;
232 endp = buf + len;
234 /* skip header */
235 p += 10;
237 /* walk over component records */
240 if (p + 4 > endp)
241 return FT_Err_Invalid_Table;
243 flags_offset = p - buf;
245 flags = *(p++) << 8;
246 flags += *(p++);
248 /* skip glyph component index */
249 p += 2;
251 /* skip scaling and offset arguments */
252 if (flags & ARGS_ARE_WORDS)
253 p += 4;
254 else
255 p += 2;
257 if (flags & WE_HAVE_A_SCALE)
258 p += 2;
259 else if (flags & WE_HAVE_AN_XY_SCALE)
260 p += 4;
261 else if (flags & WE_HAVE_A_2X2)
262 p += 8;
263 } while (flags & MORE_COMPONENTS);
265 glyph->flags_offset = flags_offset;
267 /* adjust glyph record length */
268 len = p - buf;
270 glyph->len1 = len;
271 /* glyph->len2 = 0; */
272 glyph->buf = (FT_Byte*)malloc(len);
273 if (!glyph->buf)
274 return FT_Err_Out_Of_Memory;
276 /* copy record without instructions (if any) */
277 memcpy(glyph->buf, buf, len);
278 glyph->buf[flags_offset] &= ~(WE_HAVE_INSTR >> 8);
280 return TA_Err_Ok;
284 static FT_Error
285 TA_glyph_parse_simple(GLYPH* glyph,
286 FT_Byte* buf,
287 FT_UShort num_contours,
288 FT_ULong len)
290 FT_ULong ins_offset;
291 FT_Byte* flags_start;
293 FT_UShort num_ins;
294 FT_UShort num_pts;
296 FT_ULong flags_size; /* size of the flags array */
297 FT_ULong xy_size; /* size of x and y coordinate arrays together */
299 FT_Byte* p;
300 FT_Byte* endp;
302 FT_UShort i;
305 p = buf;
306 endp = buf + len;
308 ins_offset = 10 + num_contours * 2;
310 p += ins_offset;
312 if (p + 2 > endp)
313 return FT_Err_Invalid_Table;
315 /* get number of instructions */
316 num_ins = *(p++) << 8;
317 num_ins += *(p++);
319 p += num_ins;
321 if (p > endp)
322 return FT_Err_Invalid_Table;
324 /* get number of points from last outline point */
325 num_pts = buf[ins_offset - 2] << 8;
326 num_pts += buf[ins_offset - 1];
327 num_pts++;
329 flags_start = p;
330 xy_size = 0;
331 i = 0;
333 while (i < num_pts)
335 FT_Byte flags;
336 FT_Byte x_short;
337 FT_Byte y_short;
338 FT_Byte have_x;
339 FT_Byte have_y;
340 FT_Byte count;
343 if (p + 1 > endp)
344 return FT_Err_Invalid_Table;
346 flags = *(p++);
348 x_short = (flags & X_SHORT_VECTOR) ? 1 : 2;
349 y_short = (flags & Y_SHORT_VECTOR) ? 1 : 2;
351 have_x = ((flags & SAME_X) && !(flags & X_SHORT_VECTOR)) ? 0 : 1;
352 have_y = ((flags & SAME_Y) && !(flags & Y_SHORT_VECTOR)) ? 0 : 1;
354 count = 1;
356 if (flags & REPEAT)
358 if (p + 1 > endp)
359 return FT_Err_Invalid_Table;
361 count += *(p++);
363 if (i + count > num_pts)
364 return FT_Err_Invalid_Table;
367 xy_size += count * x_short * have_x;
368 xy_size += count * y_short * have_y;
370 i += count;
373 if (p + xy_size > endp)
374 return FT_Err_Invalid_Table;
376 flags_size = p - flags_start;
378 /* store the data before and after the bytecode instructions */
379 /* in the same array */
380 glyph->len1 = ins_offset;
381 glyph->len2 = flags_size + xy_size;
382 glyph->buf = (FT_Byte*)malloc(glyph->len1 + glyph->len2);
383 if (!glyph->buf)
384 return FT_Err_Out_Of_Memory;
386 /* now copy everything but the instructions */
387 memcpy(glyph->buf, buf, glyph->len1);
388 memcpy(glyph->buf + glyph->len1, flags_start, glyph->len2);
390 return TA_Err_Ok;
394 static FT_Error
395 TA_sfnt_split_glyf_table(SFNT* sfnt,
396 FONT* font)
398 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
399 SFNT_Table* loca_table = &font->tables[sfnt->loca_idx];
400 SFNT_Table* head_table = &font->tables[sfnt->head_idx];
402 glyf_Data* data;
403 FT_Byte loca_format;
405 FT_ULong offset;
406 FT_ULong offset_next;
408 FT_Byte* p;
409 FT_UShort i;
412 /* in case of success, all allocated arrays are */
413 /* linked and eventually freed in `TA_font_unload' */
415 /* nothing to do if table has already been split */
416 if (glyf_table->data)
417 return TA_Err_Ok;
419 data = (glyf_Data*)calloc(1, sizeof (glyf_Data));
420 if (!data)
421 return FT_Err_Out_Of_Memory;
423 glyf_table->data = data;
425 loca_format = head_table->buf[LOCA_FORMAT_OFFSET];
427 data->num_glyphs = loca_format ? loca_table->len / 4 - 1
428 : loca_table->len / 2 - 1;
429 data->glyphs = (GLYPH*)calloc(1, data->num_glyphs * sizeof (GLYPH));
430 if (!data->glyphs)
431 return FT_Err_Out_Of_Memory;
433 p = loca_table->buf;
435 if (loca_format)
437 offset_next = *(p++) << 24;
438 offset_next += *(p++) << 16;
439 offset_next += *(p++) << 8;
440 offset_next += *(p++);
442 else
444 offset_next = *(p++) << 8;
445 offset_next += *(p++);
446 offset_next <<= 1;
449 /* loop over `loca' and `glyf' data */
450 for (i = 0; i < data->num_glyphs; i++)
452 GLYPH* glyph = &data->glyphs[i];
453 FT_ULong len;
456 offset = offset_next;
458 if (loca_format)
460 offset_next = *(p++) << 24;
461 offset_next += *(p++) << 16;
462 offset_next += *(p++) << 8;
463 offset_next += *(p++);
465 else
467 offset_next = *(p++) << 8;
468 offset_next += *(p++);
469 offset_next <<= 1;
472 if (offset_next < offset
473 || offset_next > glyf_table->len)
474 return FT_Err_Invalid_Table;
476 len = offset_next - offset;
477 if (!len)
478 continue; /* empty glyph */
479 else
481 FT_Byte* buf;
482 FT_Short num_contours;
483 FT_Error error;
486 /* check header size */
487 if (len < 10)
488 return FT_Err_Invalid_Table;
490 buf = glyf_table->buf + offset;
491 num_contours = (FT_Short)((buf[0] << 8) + buf[1]);
493 /* We must parse the rest of the glyph record to get the exact */
494 /* record length. Since the `loca' table rounds record lengths */
495 /* up to multiples of 4 (or 2 for older fonts), and we must round */
496 /* up again after stripping off the instructions, it would be */
497 /* possible otherwise to have more than 4 bytes of padding which */
498 /* is more or less invalid. */
500 if (num_contours < 0)
502 error = TA_glyph_parse_composite(glyph, buf, len);
503 if (error)
504 return error;
506 else
508 error = TA_glyph_parse_simple(glyph, buf, num_contours, len);
509 if (error)
510 return error;
515 return TA_Err_Ok;
519 static FT_Error
520 TA_sfnt_build_glyf_table(SFNT* sfnt,
521 FONT* font)
523 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
524 glyf_Data* data = (glyf_Data*)glyf_table->data;
526 GLYPH* glyph;
528 FT_ULong len;
529 FT_Byte* buf_new;
530 FT_Byte* p;
531 FT_UShort i;
534 if (glyf_table->processed)
535 return TA_Err_Ok;
537 /* get table size */
538 len = 0;
539 glyph = data->glyphs;
540 for (i = 0; i < data->num_glyphs; i++, glyph++)
542 /* glyph records should have offsets which are multiples of 4 */
543 len = (len + 3) & ~3;
544 len += glyph->len1 + glyph->len2 + glyph->ins_len;
545 /* add two bytes for the instructionLength field */
546 if (glyph->len2 || glyph->ins_len)
547 len += 2;
550 /* to make the short format of the `loca' table always work, */
551 /* assure an even length of the `glyf' table */
552 glyf_table->len = (len + 1) & ~1;
554 buf_new = (FT_Byte*)realloc(glyf_table->buf, (len + 3) & ~3);
555 if (!buf_new)
556 return FT_Err_Out_Of_Memory;
557 else
558 glyf_table->buf = buf_new;
560 p = glyf_table->buf;
561 glyph = data->glyphs;
562 for (i = 0; i < data->num_glyphs; i++, glyph++)
564 len = glyph->len1 + glyph->len2 + glyph->ins_len;
565 if (glyph->len2 || glyph->ins_len)
566 len += 2;
568 if (len)
570 /* copy glyph data and insert new instructions */
571 memcpy(p, glyph->buf, glyph->len1);
573 if (glyph->len2)
575 /* simple glyph */
576 p += glyph->len1;
577 *(p++) = HIGH(glyph->ins_len);
578 *(p++) = LOW(glyph->ins_len);
579 memcpy(p, glyph->ins_buf, glyph->ins_len);
580 p += glyph->ins_len;
581 memcpy(p, glyph->buf + glyph->len1, glyph->len2);
582 p += glyph->len2;
584 else
586 /* composite glyph */
587 if (glyph->ins_len)
589 *(p + glyph->flags_offset) |= (WE_HAVE_INSTR >> 8);
590 p += glyph->len1;
591 *(p++) = HIGH(glyph->ins_len);
592 *(p++) = LOW(glyph->ins_len);
593 memcpy(p, glyph->ins_buf, glyph->ins_len);
594 p += glyph->ins_len;
596 else
597 p += glyph->len1;
600 /* pad with zero bytes to have an offset which is a multiple of 4; */
601 /* this works even for the last glyph record since the `glyf' */
602 /* table length is a multiple of 4 also */
603 switch (len % 4)
605 case 1:
606 *(p++) = 0;
607 case 2:
608 *(p++) = 0;
609 case 3:
610 *(p++) = 0;
611 default:
612 break;
617 glyf_table->checksum = TA_table_compute_checksum(glyf_table->buf,
618 glyf_table->len);
619 glyf_table->processed = 1;
621 return TA_Err_Ok;
625 static FT_Error
626 TA_sfnt_build_loca_table(SFNT* sfnt,
627 FONT* font)
629 SFNT_Table* loca_table = &font->tables[sfnt->loca_idx];
630 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
631 SFNT_Table* head_table = &font->tables[sfnt->head_idx];
633 glyf_Data* data = (glyf_Data*)glyf_table->data;
634 GLYPH* glyph;
636 FT_ULong offset;
637 FT_Byte loca_format;
638 FT_Byte* buf_new;
639 FT_Byte* p;
640 FT_UShort i;
643 if (loca_table->processed)
644 return TA_Err_Ok;
646 /* get largest offset */
647 offset = 0;
648 glyph = data->glyphs;
650 for (i = 0; i < data->num_glyphs; i++, glyph++)
652 /* glyph records should have offsets which are multiples of 4 */
653 offset = (offset + 3) & ~3;
654 offset += glyph->len1 + glyph->len2 + glyph->ins_len;
655 /* add two bytes for the instructionLength field */
656 if (glyph->len2 || glyph->ins_len)
657 offset += 2;
660 if (offset > 0xFFFF * 2)
661 loca_format = 1;
662 else
663 loca_format = 0;
665 /* fill table */
666 if (loca_format)
668 loca_table->len = (data->num_glyphs + 1) * 4;
669 buf_new = (FT_Byte*)realloc(loca_table->buf, loca_table->len);
670 if (!buf_new)
671 return FT_Err_Out_Of_Memory;
672 else
673 loca_table->buf = buf_new;
675 p = loca_table->buf;
676 offset = 0;
677 glyph = data->glyphs;
679 for (i = 0; i < data->num_glyphs; i++, glyph++)
681 offset = (offset + 3) & ~3;
683 *(p++) = BYTE1(offset);
684 *(p++) = BYTE2(offset);
685 *(p++) = BYTE3(offset);
686 *(p++) = BYTE4(offset);
688 offset += glyph->len1 + glyph->len2 + glyph->ins_len;
689 if (glyph->len2 || glyph->ins_len)
690 offset += 2;
693 /* last element holds the size of the `glyf' table */
694 *(p++) = BYTE1(offset);
695 *(p++) = BYTE2(offset);
696 *(p++) = BYTE3(offset);
697 *(p++) = BYTE4(offset);
699 else
701 loca_table->len = (data->num_glyphs + 1) * 2;
702 buf_new = (FT_Byte*)realloc(loca_table->buf,
703 (loca_table->len + 3) & ~3);
704 if (!buf_new)
705 return FT_Err_Out_Of_Memory;
706 else
707 loca_table->buf = buf_new;
709 p = loca_table->buf;
710 offset = 0;
711 glyph = data->glyphs;
713 for (i = 0; i < data->num_glyphs; i++, glyph++)
715 offset = (offset + 1) & ~1;
717 *(p++) = HIGH(offset);
718 *(p++) = LOW(offset);
720 offset += (glyph->len1 + glyph->len2 + glyph->ins_len + 1) >> 1;
721 if (glyph->len2 || glyph->ins_len)
722 offset += 1;
725 /* last element holds the size of the `glyf' table */
726 *(p++) = HIGH(offset);
727 *(p++) = LOW(offset);
729 /* pad `loca' table to make its length a multiple of 4 */
730 if (loca_table->len % 4 == 2)
732 *(p++) = 0;
733 *(p++) = 0;
737 loca_table->checksum = TA_table_compute_checksum(loca_table->buf,
738 loca_table->len);
739 loca_table->processed = 1;
741 head_table->buf[LOCA_FORMAT_OFFSET] = loca_format;
743 return TA_Err_Ok;
747 static FT_Error
748 TA_sfnt_update_maxp_table(SFNT* sfnt,
749 FONT* font)
751 SFNT_Table* maxp_table = &font->tables[sfnt->maxp_idx];
752 FT_Byte* buf = maxp_table->buf;
755 if (maxp_table->processed)
756 return TA_Err_Ok;
758 if (maxp_table->len != MAXP_LEN)
759 return FT_Err_Invalid_Table;
761 buf[MAXP_MAX_ZONES_OFFSET] = 0;
762 buf[MAXP_MAX_ZONES_OFFSET + 1] = 2;
763 buf[MAXP_MAX_TWILIGHT_POINTS_OFFSET] = HIGH(sfnt->max_twilight_points);
764 buf[MAXP_MAX_TWILIGHT_POINTS_OFFSET + 1] = LOW(sfnt->max_twilight_points);
765 buf[MAXP_MAX_STORAGE_OFFSET] = HIGH(sfnt->max_storage);
766 buf[MAXP_MAX_STORAGE_OFFSET + 1] = LOW(sfnt->max_storage);
767 buf[MAXP_MAX_FUNCTION_DEFS_OFFSET] = 0;
768 buf[MAXP_MAX_FUNCTION_DEFS_OFFSET + 1] = NUM_FDEFS;
769 buf[MAXP_MAX_INSTRUCTION_DEFS_OFFSET] = 0;
770 buf[MAXP_MAX_INSTRUCTION_DEFS_OFFSET + 1] = 0;
771 buf[MAXP_MAX_STACK_ELEMENTS_OFFSET] = HIGH(sfnt->max_stack_elements);
772 buf[MAXP_MAX_STACK_ELEMENTS_OFFSET + 1] = LOW(sfnt->max_stack_elements);
773 buf[MAXP_MAX_INSTRUCTIONS_OFFSET] = HIGH(sfnt->max_instructions);
774 buf[MAXP_MAX_INSTRUCTIONS_OFFSET + 1] = LOW(sfnt->max_instructions);
776 maxp_table->checksum = TA_table_compute_checksum(maxp_table->buf,
777 maxp_table->len);
778 maxp_table->processed = 1;
780 return TA_Err_Ok;
784 /* we build a dummy `DSIG' table only */
786 static FT_Error
787 TA_table_build_DSIG(FT_Byte** DSIG)
789 FT_Byte* buf;
792 buf = (FT_Byte*)malloc(DSIG_LEN);
793 if (!buf)
794 return FT_Err_Out_Of_Memory;
796 /* version */
797 buf[0] = 0x00;
798 buf[1] = 0x00;
799 buf[2] = 0x00;
800 buf[3] = 0x01;
802 /* zero signatures */
803 buf[4] = 0x00;
804 buf[5] = 0x00;
806 /* permission flags */
807 buf[6] = 0x00;
808 buf[7] = 0x00;
810 *DSIG = buf;
812 return TA_Err_Ok;
816 static FT_Error
817 TA_table_build_gasp(FT_Byte** gasp)
819 FT_Byte* buf;
822 buf = (FT_Byte*)malloc(GASP_LEN);
823 if (!buf)
824 return FT_Err_Out_Of_Memory;
826 /* version */
827 buf[0] = 0x00;
828 buf[1] = 0x01;
830 /* one range */
831 buf[2] = 0x00;
832 buf[3] = 0x01;
834 /* entry valid for all sizes */
835 buf[4] = 0xFF;
836 buf[5] = 0xFF;
837 buf[6] = 0x00;
838 buf[7] = 0x0F; /* always use grayscale rendering with grid-fitting, */
839 /* symmetric grid-fitting and symmetric smoothing */
841 *gasp = buf;
843 return TA_Err_Ok;
847 static FT_Error
848 TA_sfnt_build_gasp_table(SFNT* sfnt,
849 FONT* font)
851 FT_Error error;
853 FT_Byte* gasp_buf;
856 error = TA_sfnt_add_table_info(sfnt);
857 if (error)
858 return error;
860 error = TA_table_build_gasp(&gasp_buf);
861 if (error)
862 return error;
864 /* in case of success, `gasp_buf' gets linked */
865 /* and is eventually freed in `TA_font_unload' */
866 error = TA_font_add_table(font,
867 &sfnt->table_infos[sfnt->num_table_infos - 1],
868 TTAG_gasp, GASP_LEN, gasp_buf);
869 if (error)
871 free(gasp_buf);
872 return error;
875 return FT_Err_Ok;
879 static void
880 TA_font_compute_table_offsets(FONT* font,
881 FT_ULong start)
883 FT_ULong i;
884 FT_ULong offset = start;
887 for (i = 0; i < font->num_tables; i++)
889 SFNT_Table* table = &font->tables[i];
892 table->offset = offset;
894 /* table offsets must be multiples of 4; */
895 /* this also fits the actual buffer lengths */
896 offset += (table->len + 3) & ~3;
901 /* If `do_complete' is 0, only return `header_len'. */
903 static FT_Error
904 TA_sfnt_build_TTF_header(SFNT* sfnt,
905 FONT* font,
906 FT_Byte** header_buf,
907 FT_ULong* header_len,
908 FT_Int do_complete)
910 SFNT_Table* tables = font->tables;
912 SFNT_Table_Info* table_infos = sfnt->table_infos;
913 FT_ULong num_table_infos = sfnt->num_table_infos;
915 FT_Byte* buf;
916 FT_ULong len;
918 FT_Byte* table_record;
920 FT_Byte* head_buf = NULL; /* pointer to `head' table */
921 FT_ULong head_checksum; /* checksum in `head' table */
923 FT_ULong num_tables_in_header;
924 FT_ULong i;
927 num_tables_in_header = 0;
928 for (i = 0; i < num_table_infos; i++)
930 /* ignore empty tables */
931 if (table_infos[i] != MISSING)
932 num_tables_in_header++;
935 len = 12 + 16 * num_tables_in_header;
936 if (!do_complete)
938 *header_len = len;
939 return TA_Err_Ok;
941 buf = (FT_Byte*)malloc(len);
942 if (!buf)
943 return FT_Err_Out_Of_Memory;
945 /* SFNT version */
946 buf[0] = 0x00;
947 buf[1] = 0x01;
948 buf[2] = 0x00;
949 buf[3] = 0x00;
951 /* number of tables */
952 buf[4] = HIGH(num_tables_in_header);
953 buf[5] = LOW(num_tables_in_header);
955 /* auxiliary data */
957 FT_ULong search_range, entry_selector, range_shift;
958 FT_ULong i, j;
961 for (i = 1, j = 2; j <= num_tables_in_header; i++, j <<= 1)
964 entry_selector = i - 1;
965 search_range = 0x10 << entry_selector;
966 range_shift = (num_tables_in_header << 4) - search_range;
968 buf[6] = HIGH(search_range);
969 buf[7] = LOW(search_range);
970 buf[8] = HIGH(entry_selector);
971 buf[9] = LOW(entry_selector);
972 buf[10] = HIGH(range_shift);
973 buf[11] = LOW(range_shift);
976 /* location of the first table info record */
977 table_record = &buf[12];
979 head_checksum = 0;
981 /* loop over all tables */
982 for (i = 0; i < num_table_infos; i++)
984 SFNT_Table_Info table_info = table_infos[i];
985 SFNT_Table* table;
988 /* ignore empty slots */
989 if (table_info == MISSING)
990 continue;
992 table = &tables[table_info];
994 if (table->tag == TTAG_head)
996 /* we always reach this IF clause since FreeType would */
997 /* have aborted already if the `head' table were missing */
999 head_buf = table->buf;
1001 /* reset checksum in `head' table for recalculation */
1002 head_buf[8] = 0x00;
1003 head_buf[9] = 0x00;
1004 head_buf[10] = 0x00;
1005 head_buf[11] = 0x00;
1008 head_checksum += table->checksum;
1010 table_record[0] = BYTE1(table->tag);
1011 table_record[1] = BYTE2(table->tag);
1012 table_record[2] = BYTE3(table->tag);
1013 table_record[3] = BYTE4(table->tag);
1015 table_record[4] = BYTE1(table->checksum);
1016 table_record[5] = BYTE2(table->checksum);
1017 table_record[6] = BYTE3(table->checksum);
1018 table_record[7] = BYTE4(table->checksum);
1020 table_record[8] = BYTE1(table->offset);
1021 table_record[9] = BYTE2(table->offset);
1022 table_record[10] = BYTE3(table->offset);
1023 table_record[11] = BYTE4(table->offset);
1025 table_record[12] = BYTE1(table->len);
1026 table_record[13] = BYTE2(table->len);
1027 table_record[14] = BYTE3(table->len);
1028 table_record[15] = BYTE4(table->len);
1030 table_record += 16;
1033 /* the font header is complete; compute `head' checksum */
1034 head_checksum += TA_table_compute_checksum(buf, len);
1035 head_checksum = 0xB1B0AFBAUL - head_checksum;
1037 /* store checksum in `head' table; */
1038 head_buf[8] = BYTE1(head_checksum);
1039 head_buf[9] = BYTE2(head_checksum);
1040 head_buf[10] = BYTE3(head_checksum);
1041 head_buf[11] = BYTE4(head_checksum);
1043 *header_buf = buf;
1044 *header_len = len;
1046 return TA_Err_Ok;
1050 static FT_Error
1051 TA_font_build_TTF(FONT* font)
1053 SFNT* sfnt = &font->sfnts[0];
1055 SFNT_Table* tables;
1056 FT_ULong num_tables;
1058 FT_ULong SFNT_offset;
1060 FT_Byte* DSIG_buf;
1062 FT_Byte* header_buf;
1063 FT_ULong header_len;
1065 FT_ULong i;
1066 FT_Error error;
1069 /* add a dummy `DSIG' table */
1071 error = TA_sfnt_add_table_info(sfnt);
1072 if (error)
1073 return error;
1075 error = TA_table_build_DSIG(&DSIG_buf);
1076 if (error)
1077 return error;
1079 /* in case of success, `DSIG_buf' gets linked */
1080 /* and is eventually freed in `TA_font_unload' */
1081 error = TA_font_add_table(font,
1082 &sfnt->table_infos[sfnt->num_table_infos - 1],
1083 TTAG_DSIG, DSIG_LEN, DSIG_buf);
1084 if (error)
1086 free(DSIG_buf);
1087 return error;
1090 TA_sfnt_sort_table_info(sfnt, font);
1092 /* the first SFNT table immediately follows the header */
1093 (void)TA_sfnt_build_TTF_header(sfnt, font, NULL, &SFNT_offset, 0);
1094 TA_font_compute_table_offsets(font, SFNT_offset);
1096 error = TA_sfnt_build_TTF_header(sfnt, font,
1097 &header_buf, &header_len, 1);
1098 if (error)
1099 return error;
1101 /* build font */
1103 tables = font->tables;
1104 num_tables = font->num_tables;
1106 /* get font length from last SFNT table array element */
1107 font->out_len = tables[num_tables - 1].offset
1108 + ((tables[num_tables - 1].len + 3) & ~3);
1109 font->out_buf = (FT_Byte*)malloc(font->out_len);
1110 if (!font->out_buf)
1112 error = FT_Err_Out_Of_Memory;
1113 goto Err;
1116 memcpy(font->out_buf, header_buf, header_len);
1118 for (i = 0; i < num_tables; i++)
1120 SFNT_Table* table = &tables[i];
1123 /* buffer length is a multiple of 4 */
1124 memcpy(font->out_buf + table->offset,
1125 table->buf, (table->len + 3) & ~3);
1128 error = TA_Err_Ok;
1130 Err:
1131 free(header_buf);
1133 return error;
1137 static FT_Error
1138 TA_font_build_TTC_header(FONT* font,
1139 FT_Byte** header_buf,
1140 FT_ULong* header_len)
1142 SFNT* sfnts = font->sfnts;
1143 FT_Long num_sfnts = font->num_sfnts;
1145 SFNT_Table* tables = font->tables;
1146 FT_ULong num_tables = font->num_tables;
1148 FT_ULong TTF_offset;
1149 FT_ULong DSIG_offset;
1151 FT_Byte* buf;
1152 FT_ULong len;
1154 FT_Long i;
1155 FT_Byte* p;
1158 len = 24 + 4 * num_sfnts;
1159 buf = (FT_Byte*)malloc(len);
1160 if (!buf)
1161 return FT_Err_Out_Of_Memory;
1163 p = buf;
1165 /* TTC ID string */
1166 *(p++) = 't';
1167 *(p++) = 't';
1168 *(p++) = 'c';
1169 *(p++) = 'f';
1171 /* TTC header version */
1172 *(p++) = 0x00;
1173 *(p++) = 0x02;
1174 *(p++) = 0x00;
1175 *(p++) = 0x00;
1177 /* number of subfonts */
1178 *(p++) = BYTE1(num_sfnts);
1179 *(p++) = BYTE2(num_sfnts);
1180 *(p++) = BYTE3(num_sfnts);
1181 *(p++) = BYTE4(num_sfnts);
1183 /* the first TTF subfont header immediately follows the TTC header */
1184 TTF_offset = len;
1186 /* loop over all subfonts */
1187 for (i = 0; i < num_sfnts; i++)
1189 SFNT* sfnt = &sfnts[i];
1190 FT_ULong l;
1193 TA_sfnt_sort_table_info(sfnt, font);
1194 /* only get header length */
1195 (void)TA_sfnt_build_TTF_header(sfnt, font, NULL, &l, 0);
1197 *(p++) = BYTE1(TTF_offset);
1198 *(p++) = BYTE2(TTF_offset);
1199 *(p++) = BYTE3(TTF_offset);
1200 *(p++) = BYTE4(TTF_offset);
1202 TTF_offset += l;
1205 /* the first SFNT table immediately follows the subfont TTF headers */
1206 TA_font_compute_table_offsets(font, TTF_offset);
1208 /* DSIG tag */
1209 *(p++) = 'D';
1210 *(p++) = 'S';
1211 *(p++) = 'I';
1212 *(p++) = 'G';
1214 /* DSIG length */
1215 *(p++) = 0x00;
1216 *(p++) = 0x00;
1217 *(p++) = 0x00;
1218 *(p++) = 0x08;
1220 /* DSIG offset; in a TTC this is always the last SFNT table */
1221 DSIG_offset = tables[num_tables - 1].offset;
1223 *(p++) = BYTE1(DSIG_offset);
1224 *(p++) = BYTE2(DSIG_offset);
1225 *(p++) = BYTE3(DSIG_offset);
1226 *(p++) = BYTE4(DSIG_offset);
1228 *header_buf = buf;
1229 *header_len = len;
1231 return TA_Err_Ok;
1235 static FT_Error
1236 TA_font_build_TTC(FONT* font)
1238 SFNT* sfnts = font->sfnts;
1239 FT_Long num_sfnts = font->num_sfnts;
1241 SFNT_Table* tables;
1242 FT_ULong num_tables;
1244 FT_Byte* DSIG_buf;
1245 SFNT_Table_Info dummy;
1247 FT_Byte* TTC_header_buf;
1248 FT_ULong TTC_header_len;
1250 FT_Byte** TTF_header_bufs = NULL;
1251 FT_ULong* TTF_header_lens = NULL;
1253 FT_ULong offset;
1254 FT_Long i;
1255 FT_ULong j;
1256 FT_Error error;
1259 /* add a dummy `DSIG' table */
1261 error = TA_table_build_DSIG(&DSIG_buf);
1262 if (error)
1263 return error;
1265 /* in case of success, `DSIG_buf' gets linked */
1266 /* and is eventually freed in `TA_font_unload' */
1267 error = TA_font_add_table(font, &dummy, TTAG_DSIG, DSIG_LEN, DSIG_buf);
1268 if (error)
1270 free(DSIG_buf);
1271 return error;
1274 /* this also computes the SFNT table offsets */
1275 error = TA_font_build_TTC_header(font,
1276 &TTC_header_buf, &TTC_header_len);
1277 if (error)
1278 return error;
1280 TTF_header_bufs = (FT_Byte**)calloc(1, num_sfnts * sizeof (FT_Byte*));
1281 if (!TTF_header_bufs)
1282 goto Err;
1284 TTF_header_lens = (FT_ULong*)malloc(num_sfnts * sizeof (FT_ULong));
1285 if (!TTF_header_lens)
1286 goto Err;
1288 for (i = 0; i < num_sfnts; i++)
1290 error = TA_sfnt_build_TTF_header(&sfnts[i], font,
1291 &TTF_header_bufs[i],
1292 &TTF_header_lens[i], 1);
1293 if (error)
1294 goto Err;
1297 /* build font */
1299 tables = font->tables;
1300 num_tables = font->num_tables;
1302 /* get font length from last SFNT table array element */
1303 font->out_len = tables[num_tables - 1].offset
1304 + ((tables[num_tables - 1].len + 3) & ~3);
1305 font->out_buf = (FT_Byte*)malloc(font->out_len);
1306 if (!font->out_buf)
1308 error = FT_Err_Out_Of_Memory;
1309 goto Err;
1312 memcpy(font->out_buf, TTC_header_buf, TTC_header_len);
1314 offset = TTC_header_len;
1316 for (i = 0; i < num_sfnts; i++)
1318 memcpy(font->out_buf + offset,
1319 TTF_header_bufs[i], TTF_header_lens[i]);
1321 offset += TTF_header_lens[i];
1324 for (j = 0; j < num_tables; j++)
1326 SFNT_Table* table = &tables[j];
1329 /* buffer length is a multiple of 4 */
1330 memcpy(font->out_buf + table->offset,
1331 table->buf, (table->len + 3) & ~3);
1334 error = TA_Err_Ok;
1336 Err:
1337 free(TTC_header_buf);
1338 if (TTF_header_bufs)
1340 for (i = 0; i < font->num_sfnts; i++)
1341 free(TTF_header_bufs[i]);
1342 free(TTF_header_bufs);
1344 free(TTF_header_lens);
1346 return error;
1350 static FT_Error
1351 TA_font_file_write(FONT* font,
1352 FILE* out_file)
1354 if (fwrite(font->out_buf, 1, font->out_len, out_file) != font->out_len)
1355 return TA_Err_Invalid_Stream_Write;
1357 return TA_Err_Ok;
1361 static void
1362 TA_font_unload(FONT* font,
1363 const char *in_buf,
1364 char** out_bufp)
1366 /* in case of error it is expected that unallocated pointers */
1367 /* are NULL (and counters are zero) */
1369 if (!font)
1370 return;
1372 if (font->loader)
1373 ta_loader_done(font->loader);
1375 if (font->tables)
1377 FT_ULong i;
1380 for (i = 0; i < font->num_tables; i++)
1382 free(font->tables[i].buf);
1383 if (font->tables[i].data)
1385 if (font->tables[i].tag == TTAG_glyf)
1387 glyf_Data* data = (glyf_Data*)font->tables[i].data;
1388 FT_UShort j;
1391 for (j = 0; j < data->num_glyphs; j++)
1393 free(data->glyphs[j].buf);
1394 free(data->glyphs[j].ins_buf);
1396 free(data->glyphs);
1397 free(data);
1401 free(font->tables);
1404 if (font->sfnts)
1406 FT_Long i;
1409 for (i = 0; i < font->num_sfnts; i++)
1411 FT_Done_Face(font->sfnts[i].face);
1412 free(font->sfnts[i].table_infos);
1414 free(font->sfnts);
1417 FT_Done_FreeType(font->lib);
1418 if (!in_buf)
1419 free(font->in_buf);
1420 if (!out_bufp)
1421 free(font->out_buf);
1422 free(font);
1426 #define COMPARE(str) (len == (sizeof (str) - 1) \
1427 && !strncmp(start, str, sizeof (str) - 1))
1430 TA_Error
1431 TTF_autohint(const char* options,
1432 ...)
1434 va_list ap;
1436 FONT* font;
1437 FT_Error error;
1438 FT_Long i;
1440 FILE* in_file = NULL;
1441 FILE* out_file = NULL;
1443 const char* in_buf = NULL;
1444 size_t in_len = 0;
1445 char** out_bufp = NULL;
1446 size_t* out_lenp = NULL;
1448 FT_Long hinting_range_min = -1;
1449 FT_Long hinting_range_max = -1;
1451 TA_Progress_Func progress;
1452 void* progress_data;
1454 FT_Bool ignore_permissions = 0;
1455 FT_UInt fallback_script = 0;
1457 const char *op;
1460 if (!options || !*options)
1461 return FT_Err_Invalid_Argument;
1463 /* XXX */
1464 va_start(ap, options);
1466 op = options;
1468 for(;;)
1470 const char* start;
1471 size_t len;
1474 start = op;
1476 /* search comma */
1477 while (*op && *op != ',')
1478 op++;
1480 /* remove leading whitespace */
1481 while (isspace(*start))
1482 start++;
1484 /* check for empty option */
1485 if (start == op)
1486 goto End;
1488 len = op - start;
1490 /* the `COMPARE' macro uses `len' and `start' */
1492 /* handle option */
1493 if (COMPARE("in-file"))
1495 in_file = va_arg(ap, FILE*);
1496 in_buf = NULL;
1497 in_len = 0;
1499 else if (COMPARE("in-buffer"))
1501 in_file = NULL;
1502 in_buf = va_arg(ap, const char*);
1504 else if (COMPARE("in-buffer-len"))
1506 in_file = NULL;
1507 in_len = va_arg(ap, size_t);
1509 else if (COMPARE("out-file"))
1511 out_file = va_arg(ap, FILE*);
1512 out_bufp = NULL;
1513 out_lenp = NULL;
1515 else if (COMPARE("out-buffer"))
1517 out_file = NULL;
1518 out_bufp = va_arg(ap, char**);
1520 else if (COMPARE("out-buffer-len"))
1522 out_file = NULL;
1523 out_lenp = va_arg(ap, size_t*);
1525 else if (COMPARE("hinting-range-min"))
1526 hinting_range_min = (FT_Long)va_arg(ap, FT_UInt);
1527 else if (COMPARE("hinting-range-max"))
1528 hinting_range_max = (FT_Long)va_arg(ap, FT_UInt);
1529 else if (COMPARE("progress-callback"))
1530 progress = va_arg(ap, TA_Progress_Func);
1531 else if (COMPARE("progress-callback-data"))
1532 progress_data = va_arg(ap, void*);
1533 else if (COMPARE("ignore-permissions"))
1534 ignore_permissions = (FT_Bool)va_arg(ap, FT_Int);
1535 else if (COMPARE("fallback-script"))
1536 fallback_script = va_arg(ap, FT_UInt);
1539 pre-hinting
1540 x-height-snapping-exceptions
1543 End:
1544 if (!*op)
1545 break;
1546 op++;
1549 va_end(ap);
1551 /* check options */
1553 if (!(in_file
1554 || (in_buf && in_len)))
1555 return FT_Err_Invalid_Argument;
1557 if (!(out_file
1558 || (out_bufp && out_lenp)))
1559 return FT_Err_Invalid_Argument;
1561 font = (FONT*)calloc(1, sizeof (FONT));
1562 if (!font)
1563 return FT_Err_Out_Of_Memory;
1565 if (hinting_range_min >= 0 && hinting_range_min < 2)
1566 return FT_Err_Invalid_Argument;
1567 if (hinting_range_min < 0)
1568 hinting_range_min = 8;
1570 if (hinting_range_max >= 0 && hinting_range_max < hinting_range_min)
1571 return FT_Err_Invalid_Argument;
1572 if (hinting_range_max < 0)
1573 hinting_range_max = 1000;
1575 font->hinting_range_min = (FT_UInt)hinting_range_min;
1576 font->hinting_range_max = (FT_UInt)hinting_range_max;
1578 font->progress = progress;
1579 font->progress_data = progress_data;
1581 font->ignore_permissions = ignore_permissions;
1582 /* restrict value to two bits */
1583 font->fallback_script = fallback_script & 3;
1585 /* now start with processing the data */
1587 if (in_file)
1589 error = TA_font_file_read(font, in_file);
1590 if (error)
1591 goto Err;
1593 else
1595 /* a valid TTF can never be that small */
1596 if (in_len < 100)
1597 return FT_Err_Invalid_Argument;
1598 font->in_buf = (FT_Byte*)in_buf;
1599 font->in_len = in_len;
1602 error = TA_font_init(font);
1603 if (error)
1604 goto Err;
1606 /* loop over subfonts */
1607 for (i = 0; i < font->num_sfnts; i++)
1609 SFNT* sfnt = &font->sfnts[i];
1612 error = FT_New_Memory_Face(font->lib, font->in_buf, font->in_len,
1613 i, &sfnt->face);
1614 if (error)
1615 goto Err;
1617 error = TA_sfnt_split_into_SFNT_tables(sfnt, font);
1618 if (error)
1619 goto Err;
1621 error = TA_sfnt_split_glyf_table(sfnt, font);
1622 if (error)
1623 goto Err;
1625 /* check permission */
1626 if (sfnt->OS2_idx != MISSING)
1628 SFNT_Table* OS2_table = &font->tables[sfnt->OS2_idx];
1631 /* check lower byte of the `fsType' field */
1632 if (OS2_table->buf[OS2_FSTYPE_OFFSET + 1] == 0x02
1633 && !font->ignore_permissions)
1635 error = TA_Err_Missing_Legal_Permission;
1636 goto Err;
1641 /* build `gasp' table */
1642 error = TA_sfnt_build_gasp_table(&font->sfnts[0], font);
1643 if (error)
1644 goto Err;
1646 /* XXX handle subfonts for bytecode tables */
1648 /* build `cvt ' table */
1649 error = TA_sfnt_build_cvt_table(&font->sfnts[0], font);
1650 if (error)
1651 goto Err;
1653 /* build `fpgm' table */
1654 error = TA_sfnt_build_fpgm_table(&font->sfnts[0], font);
1655 if (error)
1656 goto Err;
1658 /* build `prep' table */
1659 error = TA_sfnt_build_prep_table(&font->sfnts[0], font);
1660 if (error)
1661 goto Err;
1663 /* hint the glyphs and build bytecode */
1664 error = TA_sfnt_build_glyf_hints(&font->sfnts[0], font);
1665 if (error)
1666 goto Err;
1668 /* loop again over subfonts */
1669 for (i = 0; i < font->num_sfnts; i++)
1671 SFNT* sfnt = &font->sfnts[i];
1674 error = TA_sfnt_build_glyf_table(sfnt, font);
1675 if (error)
1676 goto Err;
1677 error = TA_sfnt_build_loca_table(sfnt, font);
1678 if (error)
1679 goto Err;
1680 error = TA_sfnt_update_maxp_table(sfnt, font);
1681 if (error)
1682 goto Err;
1685 if (font->num_sfnts == 1)
1686 error = TA_font_build_TTF(font);
1687 else
1688 error = TA_font_build_TTC(font);
1689 if (error)
1690 goto Err;
1692 if (out_file)
1694 error = TA_font_file_write(font, out_file);
1695 if (error)
1696 goto Err;
1698 else
1700 *out_bufp = (char*)font->out_buf;
1701 *out_lenp = font->out_len;
1704 error = TA_Err_Ok;
1706 Err:
1707 TA_font_unload(font, in_buf, out_bufp);
1709 return error;
1712 /* end of ttfautohint.c */