Handle options `progress-callback' and `progress-callback-data'.
[ttfautohint.git] / src / ttfautohint.c
blob516f2a0169ee9c1c8bad4656323ae61e1bcef277
1 /* ttfautohint.c */
3 /* written 2011 by Werner Lemberg <wl@gnu.org> */
5 /* This file needs FreeType 2.4.5 or newer. */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <ctype.h>
12 #include "ta.h"
15 static FT_Error
16 TA_font_file_read(FONT* font,
17 FILE* in_file)
19 fseek(in_file, 0, SEEK_END);
20 font->in_len = ftell(in_file);
21 fseek(in_file, 0, SEEK_SET);
23 /* a valid TTF can never be that small */
24 if (font->in_len < 100)
25 return FT_Err_Invalid_Argument;
27 font->in_buf = (FT_Byte*)malloc(font->in_len);
28 if (!font->in_buf)
29 return FT_Err_Out_Of_Memory;
31 if (fread(font->in_buf, 1, font->in_len, in_file) != font->in_len)
32 return FT_Err_Invalid_Stream_Read;
34 return TA_Err_Ok;
38 static FT_Error
39 TA_font_init(FONT* font)
41 FT_Error error;
42 FT_Face f;
45 error = FT_Init_FreeType(&font->lib);
46 if (error)
47 return error;
49 /* get number of faces (i.e. subfonts) */
50 error = FT_New_Memory_Face(font->lib, font->in_buf, font->in_len, -1, &f);
51 if (error)
52 return error;
53 font->num_sfnts = f->num_faces;
54 FT_Done_Face(f);
56 /* it is a TTC if we have more than a single subfont */
57 font->sfnts = (SFNT*)calloc(1, font->num_sfnts * sizeof (SFNT));
58 if (!font->sfnts)
59 return FT_Err_Out_Of_Memory;
61 return TA_Err_Ok;
65 static FT_Error
66 TA_sfnt_split_into_SFNT_tables(SFNT* sfnt,
67 FONT* font)
69 FT_Error error;
70 FT_ULong i;
73 /* basic check whether font is a TTF or TTC */
74 if (!FT_IS_SFNT(sfnt->face))
75 return FT_Err_Invalid_Argument;
77 error = FT_Sfnt_Table_Info(sfnt->face, 0, NULL, &sfnt->num_table_infos);
78 if (error)
79 return error;
81 sfnt->table_infos = (SFNT_Table_Info*)malloc(sfnt->num_table_infos
82 * sizeof (SFNT_Table_Info));
83 if (!sfnt->table_infos)
84 return FT_Err_Out_Of_Memory;
86 /* collect SFNT tables and search for `glyf' and `loca' table */
87 sfnt->glyf_idx = MISSING;
88 sfnt->loca_idx = MISSING;
89 sfnt->head_idx = MISSING;
90 sfnt->maxp_idx = MISSING;
92 for (i = 0; i < sfnt->num_table_infos; i++)
94 SFNT_Table_Info* table_info = &sfnt->table_infos[i];
95 FT_ULong tag;
96 FT_ULong len;
97 FT_Byte* buf;
99 FT_ULong buf_len;
100 FT_ULong j;
103 *table_info = MISSING;
105 error = FT_Sfnt_Table_Info(sfnt->face, i, &tag, &len);
106 if (error)
108 /* this ignores both missing and zero-length tables */
109 if (error == FT_Err_Table_Missing)
110 continue;
111 else
112 return error;
115 /* ignore tables which we are going to create by ourselves, */
116 /* or which would become invalid otherwise */
117 else if (tag == TTAG_fpgm
118 || tag == TTAG_prep
119 || tag == TTAG_cvt
120 || tag == TTAG_DSIG
121 || tag == TTAG_hdmx
122 || tag == TTAG_VDMX
123 || tag == TTAG_LTSH
124 || tag == TTAG_gasp)
125 continue;
127 /* make the allocated buffer length a multiple of 4 */
128 buf_len = (len + 3) & -3;
129 buf = (FT_Byte*)malloc(buf_len);
130 if (!buf)
131 return FT_Err_Out_Of_Memory;
133 /* pad end of buffer with zeros */
134 buf[buf_len - 1] = 0x00;
135 buf[buf_len - 2] = 0x00;
136 buf[buf_len - 3] = 0x00;
138 /* load table */
139 error = FT_Load_Sfnt_Table(sfnt->face, tag, 0, buf, &len);
140 if (error)
141 goto Err;
143 /* check whether we already have this table */
144 for (j = 0; j < font->num_tables; j++)
146 SFNT_Table* table = &font->tables[j];
149 if (table->tag == tag
150 && table->len == len
151 && !memcmp(table->buf, buf, len))
152 break;
155 if (tag == TTAG_head)
156 sfnt->head_idx = j;
157 else if (tag == TTAG_glyf)
158 sfnt->glyf_idx = j;
159 else if (tag == TTAG_loca)
160 sfnt->loca_idx = j;
161 else if (tag == TTAG_maxp)
162 sfnt->maxp_idx = j;
164 if (j == font->num_tables)
166 /* add element to table array if it is missing or different; */
167 /* in case of success, `buf' gets linked and is eventually */
168 /* freed in `TA_font_unload' */
169 error = TA_font_add_table(font, table_info, tag, len, buf);
170 if (error)
171 goto Err;
173 else
175 /* reuse existing SFNT table */
176 free(buf);
177 *table_info = j;
179 continue;
181 Err:
182 free(buf);
183 return error;
186 /* no (non-empty) `glyf', `loca', `head', or `maxp' table; */
187 /* this can't be a valid TTF with outlines */
188 if (sfnt->glyf_idx == MISSING
189 || sfnt->loca_idx == MISSING
190 || sfnt->head_idx == MISSING
191 || sfnt->maxp_idx == MISSING)
192 return FT_Err_Invalid_Argument;
194 return TA_Err_Ok;
198 static FT_Error
199 TA_glyph_parse_composite(GLYPH* glyph,
200 FT_Byte* buf,
201 FT_ULong len)
203 FT_ULong flags_offset; /* after the loop, this is the offset */
204 /* to the last element in the flags array */
205 FT_UShort flags;
207 FT_Byte* p;
208 FT_Byte* endp;
211 p = buf;
212 endp = buf + len;
214 /* skip header */
215 p += 10;
217 /* walk over component records */
220 if (p + 4 > endp)
221 return FT_Err_Invalid_Table;
223 flags_offset = p - buf;
225 flags = *(p++) << 8;
226 flags += *(p++);
228 /* skip glyph component index */
229 p += 2;
231 /* skip scaling and offset arguments */
232 if (flags & ARGS_ARE_WORDS)
233 p += 4;
234 else
235 p += 2;
237 if (flags & WE_HAVE_A_SCALE)
238 p += 2;
239 else if (flags & WE_HAVE_AN_XY_SCALE)
240 p += 4;
241 else if (flags & WE_HAVE_A_2X2)
242 p += 8;
243 } while (flags & MORE_COMPONENTS);
245 glyph->flags_offset = flags_offset;
247 /* adjust glyph record length */
248 len = p - buf;
250 glyph->len1 = len;
251 /* glyph->len2 = 0; */
252 glyph->buf = (FT_Byte*)malloc(len);
253 if (!glyph->buf)
254 return FT_Err_Out_Of_Memory;
256 /* copy record without instructions (if any) */
257 memcpy(glyph->buf, buf, len);
258 glyph->buf[flags_offset] &= ~(WE_HAVE_INSTR >> 8);
260 return TA_Err_Ok;
264 static FT_Error
265 TA_glyph_parse_simple(GLYPH* glyph,
266 FT_Byte* buf,
267 FT_UShort num_contours,
268 FT_ULong len)
270 FT_ULong ins_offset;
271 FT_Byte* flags_start;
273 FT_UShort num_ins;
274 FT_UShort num_pts;
276 FT_ULong flags_size; /* size of the flags array */
277 FT_ULong xy_size; /* size of x and y coordinate arrays together */
279 FT_Byte* p;
280 FT_Byte* endp;
282 FT_UShort i;
285 p = buf;
286 endp = buf + len;
288 ins_offset = 10 + num_contours * 2;
290 p += ins_offset;
292 if (p + 2 > endp)
293 return FT_Err_Invalid_Table;
295 /* get number of instructions */
296 num_ins = *(p++) << 8;
297 num_ins += *(p++);
299 p += num_ins;
301 if (p > endp)
302 return FT_Err_Invalid_Table;
304 /* get number of points from last outline point */
305 num_pts = buf[ins_offset - 2] << 8;
306 num_pts += buf[ins_offset - 1];
307 num_pts++;
309 flags_start = p;
310 xy_size = 0;
311 i = 0;
313 while (i < num_pts)
315 FT_Byte flags;
316 FT_Byte x_short;
317 FT_Byte y_short;
318 FT_Byte have_x;
319 FT_Byte have_y;
320 FT_Byte count;
323 if (p + 1 > endp)
324 return FT_Err_Invalid_Table;
326 flags = *(p++);
328 x_short = (flags & X_SHORT_VECTOR) ? 1 : 2;
329 y_short = (flags & Y_SHORT_VECTOR) ? 1 : 2;
331 have_x = ((flags & SAME_X) && !(flags & X_SHORT_VECTOR)) ? 0 : 1;
332 have_y = ((flags & SAME_Y) && !(flags & Y_SHORT_VECTOR)) ? 0 : 1;
334 count = 1;
336 if (flags & REPEAT)
338 if (p + 1 > endp)
339 return FT_Err_Invalid_Table;
341 count += *(p++);
343 if (i + count > num_pts)
344 return FT_Err_Invalid_Table;
347 xy_size += count * x_short * have_x;
348 xy_size += count * y_short * have_y;
350 i += count;
353 if (p + xy_size > endp)
354 return FT_Err_Invalid_Table;
356 flags_size = p - flags_start;
358 /* store the data before and after the bytecode instructions */
359 /* in the same array */
360 glyph->len1 = ins_offset;
361 glyph->len2 = flags_size + xy_size;
362 glyph->buf = (FT_Byte*)malloc(glyph->len1 + glyph->len2);
363 if (!glyph->buf)
364 return FT_Err_Out_Of_Memory;
366 /* now copy everything but the instructions */
367 memcpy(glyph->buf, buf, glyph->len1);
368 memcpy(glyph->buf + glyph->len1, flags_start, glyph->len2);
370 return TA_Err_Ok;
374 static FT_Error
375 TA_sfnt_split_glyf_table(SFNT* sfnt,
376 FONT* font)
378 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
379 SFNT_Table* loca_table = &font->tables[sfnt->loca_idx];
380 SFNT_Table* head_table = &font->tables[sfnt->head_idx];
382 glyf_Data* data;
383 FT_Byte loca_format;
385 FT_ULong offset;
386 FT_ULong offset_next;
388 FT_Byte* p;
389 FT_UShort i;
392 /* in case of success, all allocated arrays are */
393 /* linked and eventually freed in `TA_font_unload' */
395 /* nothing to do if table has already been split */
396 if (glyf_table->data)
397 return TA_Err_Ok;
399 data = (glyf_Data*)calloc(1, sizeof (glyf_Data));
400 if (!data)
401 return FT_Err_Out_Of_Memory;
403 glyf_table->data = data;
405 loca_format = head_table->buf[LOCA_FORMAT_OFFSET];
407 data->num_glyphs = loca_format ? loca_table->len / 4 - 1
408 : loca_table->len / 2 - 1;
409 data->glyphs = (GLYPH*)calloc(1, data->num_glyphs * sizeof (GLYPH));
410 if (!data->glyphs)
411 return FT_Err_Out_Of_Memory;
413 p = loca_table->buf;
415 if (loca_format)
417 offset_next = *(p++) << 24;
418 offset_next += *(p++) << 16;
419 offset_next += *(p++) << 8;
420 offset_next += *(p++);
422 else
424 offset_next = *(p++) << 8;
425 offset_next += *(p++);
426 offset_next <<= 1;
429 /* loop over `loca' and `glyf' data */
430 for (i = 0; i < data->num_glyphs; i++)
432 GLYPH* glyph = &data->glyphs[i];
433 FT_ULong len;
436 offset = offset_next;
438 if (loca_format)
440 offset_next = *(p++) << 24;
441 offset_next += *(p++) << 16;
442 offset_next += *(p++) << 8;
443 offset_next += *(p++);
445 else
447 offset_next = *(p++) << 8;
448 offset_next += *(p++);
449 offset_next <<= 1;
452 if (offset_next < offset
453 || offset_next > glyf_table->len)
454 return FT_Err_Invalid_Table;
456 len = offset_next - offset;
457 if (!len)
458 continue; /* empty glyph */
459 else
461 FT_Byte* buf;
462 FT_Short num_contours;
463 FT_Error error;
466 /* check header size */
467 if (len < 10)
468 return FT_Err_Invalid_Table;
470 buf = glyf_table->buf + offset;
471 num_contours = (FT_Short)((buf[0] << 8) + buf[1]);
473 /* We must parse the rest of the glyph record to get the exact */
474 /* record length. Since the `loca' table rounds record lengths */
475 /* up to multiples of 4 (or 2 for older fonts), and we must round */
476 /* up again after stripping off the instructions, it would be */
477 /* possible otherwise to have more than 4 bytes of padding which */
478 /* is more or less invalid. */
480 if (num_contours < 0)
482 error = TA_glyph_parse_composite(glyph, buf, len);
483 if (error)
484 return error;
486 else
488 error = TA_glyph_parse_simple(glyph, buf, num_contours, len);
489 if (error)
490 return error;
495 return TA_Err_Ok;
499 static FT_Error
500 TA_sfnt_build_glyf_table(SFNT* sfnt,
501 FONT* font)
503 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
504 glyf_Data* data = (glyf_Data*)glyf_table->data;
506 GLYPH* glyph;
508 FT_ULong len;
509 FT_Byte* buf_new;
510 FT_Byte* p;
511 FT_UShort i;
514 if (glyf_table->processed)
515 return TA_Err_Ok;
517 /* get table size */
518 len = 0;
519 glyph = data->glyphs;
520 for (i = 0; i < data->num_glyphs; i++, glyph++)
522 /* glyph records should have offsets which are multiples of 4 */
523 len = (len + 3) & ~3;
524 len += glyph->len1 + glyph->len2 + glyph->ins_len;
525 /* add two bytes for the instructionLength field */
526 if (glyph->len2 || glyph->ins_len)
527 len += 2;
530 glyf_table->len = len;
531 buf_new = (FT_Byte*)realloc(glyf_table->buf, (len + 3) & ~3);
532 if (!buf_new)
533 return FT_Err_Out_Of_Memory;
534 else
535 glyf_table->buf = buf_new;
537 p = glyf_table->buf;
538 glyph = data->glyphs;
539 for (i = 0; i < data->num_glyphs; i++, glyph++)
541 len = glyph->len1 + glyph->len2 + glyph->ins_len;
542 if (glyph->len2 || glyph->ins_len)
543 len += 2;
545 if (len)
547 /* copy glyph data and insert new instructions */
548 memcpy(p, glyph->buf, glyph->len1);
550 if (glyph->len2)
552 /* simple glyph */
553 p += glyph->len1;
554 *(p++) = HIGH(glyph->ins_len);
555 *(p++) = LOW(glyph->ins_len);
556 memcpy(p, glyph->ins_buf, glyph->ins_len);
557 p += glyph->ins_len;
558 memcpy(p, glyph->buf + glyph->len1, glyph->len2);
559 p += glyph->len2;
561 else
563 /* composite glyph */
564 if (glyph->ins_len)
566 *(p + glyph->flags_offset) |= (WE_HAVE_INSTR >> 8);
567 p += glyph->len1;
568 *(p++) = HIGH(glyph->ins_len);
569 *(p++) = LOW(glyph->ins_len);
570 memcpy(p, glyph->ins_buf, glyph->ins_len);
571 p += glyph->ins_len;
573 else
574 p += glyph->len1;
577 /* pad with zero bytes to have an offset which is a multiple of 4; */
578 /* this works even for the last glyph record since the `glyf' */
579 /* table length is a multiple of 4 also */
580 switch (len % 4)
582 case 1:
583 *(p++) = 0;
584 case 2:
585 *(p++) = 0;
586 case 3:
587 *(p++) = 0;
588 default:
589 break;
594 glyf_table->checksum = TA_table_compute_checksum(glyf_table->buf,
595 glyf_table->len);
596 glyf_table->processed = 1;
598 return TA_Err_Ok;
602 static FT_Error
603 TA_sfnt_build_loca_table(SFNT* sfnt,
604 FONT* font)
606 SFNT_Table* loca_table = &font->tables[sfnt->loca_idx];
607 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
608 SFNT_Table* head_table = &font->tables[sfnt->head_idx];
610 glyf_Data* data = (glyf_Data*)glyf_table->data;
611 GLYPH* glyph;
613 FT_ULong offset;
614 FT_Byte loca_format;
615 FT_Byte* buf_new;
616 FT_Byte* p;
617 FT_UShort i;
620 if (loca_table->processed)
621 return TA_Err_Ok;
623 /* get largest offset */
624 offset = 0;
625 glyph = data->glyphs;
627 for (i = 0; i < data->num_glyphs; i++, glyph++)
629 /* glyph records should have offsets which are multiples of 4 */
630 offset = (offset + 3) & ~3;
631 offset += glyph->len1 + glyph->len2 + glyph->ins_len;
632 /* add two bytes for the instructionLength field */
633 if (glyph->len2 || glyph->ins_len)
634 offset += 2;
637 if (offset > 0xFFFF * 2)
638 loca_format = 1;
639 else
640 loca_format = 0;
642 /* fill table */
643 if (loca_format)
645 loca_table->len = (data->num_glyphs + 1) * 4;
646 buf_new = (FT_Byte*)realloc(loca_table->buf, loca_table->len);
647 if (!buf_new)
648 return FT_Err_Out_Of_Memory;
649 else
650 loca_table->buf = buf_new;
652 p = loca_table->buf;
653 offset = 0;
654 glyph = data->glyphs;
656 for (i = 0; i < data->num_glyphs; i++, glyph++)
658 offset = (offset + 3) & ~3;
660 *(p++) = BYTE1(offset);
661 *(p++) = BYTE2(offset);
662 *(p++) = BYTE3(offset);
663 *(p++) = BYTE4(offset);
665 offset += glyph->len1 + glyph->len2 + glyph->ins_len;
666 if (glyph->len2 || glyph->ins_len)
667 offset += 2;
670 /* last element holds the size of the `glyf' table */
671 *(p++) = BYTE1(offset);
672 *(p++) = BYTE2(offset);
673 *(p++) = BYTE3(offset);
674 *(p++) = BYTE4(offset);
676 else
678 loca_table->len = (data->num_glyphs + 1) * 2;
679 buf_new = (FT_Byte*)realloc(loca_table->buf,
680 (loca_table->len + 3) & ~3);
681 if (!buf_new)
682 return FT_Err_Out_Of_Memory;
683 else
684 loca_table->buf = buf_new;
686 p = loca_table->buf;
687 offset = 0;
688 glyph = data->glyphs;
690 for (i = 0; i < data->num_glyphs; i++, glyph++)
692 offset = (offset + 1) & ~1;
694 *(p++) = HIGH(offset);
695 *(p++) = LOW(offset);
697 offset += (glyph->len1 + glyph->len2 + glyph->ins_len + 1) >> 1;
698 if (glyph->len2 || glyph->ins_len)
699 offset += 1;
702 /* last element holds the size of the `glyf' table */
703 *(p++) = HIGH(offset);
704 *(p++) = LOW(offset);
706 /* pad `loca' table to make its length a multiple of 4 */
707 if (loca_table->len % 4 == 2)
709 *(p++) = 0;
710 *(p++) = 0;
714 loca_table->checksum = TA_table_compute_checksum(loca_table->buf,
715 loca_table->len);
716 loca_table->processed = 1;
718 head_table->buf[LOCA_FORMAT_OFFSET] = loca_format;
720 return TA_Err_Ok;
724 static FT_Error
725 TA_sfnt_update_maxp_table(SFNT* sfnt,
726 FONT* font)
728 SFNT_Table* maxp_table = &font->tables[sfnt->maxp_idx];
729 FT_Byte* buf = maxp_table->buf;
732 if (maxp_table->processed)
733 return TA_Err_Ok;
735 if (maxp_table->len != MAXP_LEN)
736 return FT_Err_Invalid_Table;
738 buf[MAXP_MAX_ZONES_OFFSET] = 0;
739 buf[MAXP_MAX_ZONES_OFFSET + 1] = 2;
740 buf[MAXP_MAX_TWILIGHT_POINTS_OFFSET] = HIGH(sfnt->max_twilight_points);
741 buf[MAXP_MAX_TWILIGHT_POINTS_OFFSET + 1] = LOW(sfnt->max_twilight_points);
742 buf[MAXP_MAX_STORAGE_OFFSET] = HIGH(sfnt->max_storage);
743 buf[MAXP_MAX_STORAGE_OFFSET + 1] = LOW(sfnt->max_storage);
744 buf[MAXP_MAX_FUNCTION_DEFS_OFFSET] = 0;
745 buf[MAXP_MAX_FUNCTION_DEFS_OFFSET + 1] = NUM_FDEFS;
746 buf[MAXP_MAX_INSTRUCTION_DEFS_OFFSET] = 0;
747 buf[MAXP_MAX_INSTRUCTION_DEFS_OFFSET + 1] = 0;
748 buf[MAXP_MAX_STACK_ELEMENTS_OFFSET] = HIGH(sfnt->max_stack_elements);
749 buf[MAXP_MAX_STACK_ELEMENTS_OFFSET + 1] = LOW(sfnt->max_stack_elements);
750 buf[MAXP_MAX_INSTRUCTIONS_OFFSET] = HIGH(sfnt->max_instructions);
751 buf[MAXP_MAX_INSTRUCTIONS_OFFSET + 1] = LOW(sfnt->max_instructions);
753 maxp_table->checksum = TA_table_compute_checksum(maxp_table->buf,
754 maxp_table->len);
755 maxp_table->processed = 1;
757 return TA_Err_Ok;
761 /* we build a dummy `DSIG' table only */
763 static FT_Error
764 TA_table_build_DSIG(FT_Byte** DSIG)
766 FT_Byte* buf;
769 buf = (FT_Byte*)malloc(DSIG_LEN);
770 if (!buf)
771 return FT_Err_Out_Of_Memory;
773 /* version */
774 buf[0] = 0x00;
775 buf[1] = 0x00;
776 buf[2] = 0x00;
777 buf[3] = 0x01;
779 /* zero signatures */
780 buf[4] = 0x00;
781 buf[5] = 0x00;
783 /* permission flags */
784 buf[6] = 0x00;
785 buf[7] = 0x00;
787 *DSIG = buf;
789 return TA_Err_Ok;
793 static FT_Error
794 TA_table_build_gasp(FT_Byte** gasp)
796 FT_Byte* buf;
799 buf = (FT_Byte*)malloc(GASP_LEN);
800 if (!buf)
801 return FT_Err_Out_Of_Memory;
803 /* version */
804 buf[0] = 0x00;
805 buf[1] = 0x01;
807 /* one range */
808 buf[2] = 0x00;
809 buf[3] = 0x01;
811 /* entry valid for all sizes */
812 buf[4] = 0xFF;
813 buf[5] = 0xFF;
814 buf[6] = 0x00;
815 buf[7] = 0x0F; /* always use grayscale rendering with grid-fitting, */
816 /* symmetric grid-fitting and symmetric smoothing */
818 *gasp = buf;
820 return TA_Err_Ok;
824 static FT_Error
825 TA_sfnt_build_gasp_table(SFNT* sfnt,
826 FONT* font)
828 FT_Error error;
830 FT_Byte* gasp_buf;
833 error = TA_sfnt_add_table_info(sfnt);
834 if (error)
835 return error;
837 error = TA_table_build_gasp(&gasp_buf);
838 if (error)
839 return error;
841 /* in case of success, `gasp_buf' gets linked */
842 /* and is eventually freed in `TA_font_unload' */
843 error = TA_font_add_table(font,
844 &sfnt->table_infos[sfnt->num_table_infos - 1],
845 TTAG_gasp, GASP_LEN, gasp_buf);
846 if (error)
848 free(gasp_buf);
849 return error;
852 return FT_Err_Ok;
856 static void
857 TA_font_compute_table_offsets(FONT* font,
858 FT_ULong start)
860 FT_ULong i;
861 FT_ULong offset = start;
864 for (i = 0; i < font->num_tables; i++)
866 SFNT_Table* table = &font->tables[i];
869 table->offset = offset;
871 /* table offsets must be multiples of 4; */
872 /* this also fits the actual buffer lengths */
873 offset += (table->len + 3) & ~3;
878 /* If `do_complete' is 0, only return `header_len'. */
880 static FT_Error
881 TA_sfnt_build_TTF_header(SFNT* sfnt,
882 FONT* font,
883 FT_Byte** header_buf,
884 FT_ULong* header_len,
885 FT_Int do_complete)
887 SFNT_Table* tables = font->tables;
889 SFNT_Table_Info* table_infos = sfnt->table_infos;
890 FT_ULong num_table_infos = sfnt->num_table_infos;
892 FT_Byte* buf;
893 FT_ULong len;
895 FT_Byte* table_record;
897 FT_Byte* head_buf = NULL; /* pointer to `head' table */
898 FT_ULong head_checksum; /* checksum in `head' table */
900 FT_ULong num_tables_in_header;
901 FT_ULong i;
904 num_tables_in_header = 0;
905 for (i = 0; i < num_table_infos; i++)
907 /* ignore empty tables */
908 if (table_infos[i] != MISSING)
909 num_tables_in_header++;
912 len = 12 + 16 * num_tables_in_header;
913 if (!do_complete)
915 *header_len = len;
916 return TA_Err_Ok;
918 buf = (FT_Byte*)malloc(len);
919 if (!buf)
920 return FT_Err_Out_Of_Memory;
922 /* SFNT version */
923 buf[0] = 0x00;
924 buf[1] = 0x01;
925 buf[2] = 0x00;
926 buf[3] = 0x00;
928 /* number of tables */
929 buf[4] = HIGH(num_tables_in_header);
930 buf[5] = LOW(num_tables_in_header);
932 /* auxiliary data */
934 FT_ULong search_range, entry_selector, range_shift;
935 FT_ULong i, j;
938 for (i = 1, j = 2; j <= num_tables_in_header; i++, j <<= 1)
941 entry_selector = i - 1;
942 search_range = 0x10 << entry_selector;
943 range_shift = (num_tables_in_header << 4) - search_range;
945 buf[6] = HIGH(search_range);
946 buf[7] = LOW(search_range);
947 buf[8] = HIGH(entry_selector);
948 buf[9] = LOW(entry_selector);
949 buf[10] = HIGH(range_shift);
950 buf[11] = LOW(range_shift);
953 /* location of the first table info record */
954 table_record = &buf[12];
956 head_checksum = 0;
958 /* loop over all tables */
959 for (i = 0; i < num_table_infos; i++)
961 SFNT_Table_Info table_info = table_infos[i];
962 SFNT_Table* table;
965 /* ignore empty slots */
966 if (table_info == MISSING)
967 continue;
969 table = &tables[table_info];
971 if (table->tag == TTAG_head)
973 /* we always reach this IF clause since FreeType would */
974 /* have aborted already if the `head' table were missing */
976 head_buf = table->buf;
978 /* reset checksum in `head' table for recalculation */
979 head_buf[8] = 0x00;
980 head_buf[9] = 0x00;
981 head_buf[10] = 0x00;
982 head_buf[11] = 0x00;
985 head_checksum += table->checksum;
987 table_record[0] = BYTE1(table->tag);
988 table_record[1] = BYTE2(table->tag);
989 table_record[2] = BYTE3(table->tag);
990 table_record[3] = BYTE4(table->tag);
992 table_record[4] = BYTE1(table->checksum);
993 table_record[5] = BYTE2(table->checksum);
994 table_record[6] = BYTE3(table->checksum);
995 table_record[7] = BYTE4(table->checksum);
997 table_record[8] = BYTE1(table->offset);
998 table_record[9] = BYTE2(table->offset);
999 table_record[10] = BYTE3(table->offset);
1000 table_record[11] = BYTE4(table->offset);
1002 table_record[12] = BYTE1(table->len);
1003 table_record[13] = BYTE2(table->len);
1004 table_record[14] = BYTE3(table->len);
1005 table_record[15] = BYTE4(table->len);
1007 table_record += 16;
1010 /* the font header is complete; compute `head' checksum */
1011 head_checksum += TA_table_compute_checksum(buf, len);
1012 head_checksum = 0xB1B0AFBAUL - head_checksum;
1014 /* store checksum in `head' table; */
1015 head_buf[8] = BYTE1(head_checksum);
1016 head_buf[9] = BYTE2(head_checksum);
1017 head_buf[10] = BYTE3(head_checksum);
1018 head_buf[11] = BYTE4(head_checksum);
1020 *header_buf = buf;
1021 *header_len = len;
1023 return TA_Err_Ok;
1027 static FT_Error
1028 TA_font_build_TTF(FONT* font)
1030 SFNT* sfnt = &font->sfnts[0];
1032 SFNT_Table* tables;
1033 FT_ULong num_tables;
1035 FT_ULong SFNT_offset;
1037 FT_Byte* DSIG_buf;
1039 FT_Byte* header_buf;
1040 FT_ULong header_len;
1042 FT_ULong i;
1043 FT_Error error;
1046 /* add a dummy `DSIG' table */
1048 error = TA_sfnt_add_table_info(sfnt);
1049 if (error)
1050 return error;
1052 error = TA_table_build_DSIG(&DSIG_buf);
1053 if (error)
1054 return error;
1056 /* in case of success, `DSIG_buf' gets linked */
1057 /* and is eventually freed in `TA_font_unload' */
1058 error = TA_font_add_table(font,
1059 &sfnt->table_infos[sfnt->num_table_infos - 1],
1060 TTAG_DSIG, DSIG_LEN, DSIG_buf);
1061 if (error)
1063 free(DSIG_buf);
1064 return error;
1067 TA_sfnt_sort_table_info(sfnt, font);
1069 /* the first SFNT table immediately follows the header */
1070 (void)TA_sfnt_build_TTF_header(sfnt, font, NULL, &SFNT_offset, 0);
1071 TA_font_compute_table_offsets(font, SFNT_offset);
1073 error = TA_sfnt_build_TTF_header(sfnt, font,
1074 &header_buf, &header_len, 1);
1075 if (error)
1076 return error;
1078 /* build font */
1080 tables = font->tables;
1081 num_tables = font->num_tables;
1083 /* get font length from last SFNT table array element */
1084 font->out_len = tables[num_tables - 1].offset
1085 + ((tables[num_tables - 1].len + 3) & ~3);
1086 font->out_buf = (FT_Byte*)malloc(font->out_len);
1087 if (!font->out_buf)
1089 error = FT_Err_Out_Of_Memory;
1090 goto Err;
1093 memcpy(font->out_buf, header_buf, header_len);
1095 for (i = 0; i < num_tables; i++)
1097 SFNT_Table* table = &tables[i];
1100 /* buffer length is a multiple of 4 */
1101 memcpy(font->out_buf + table->offset,
1102 table->buf, (table->len + 3) & ~3);
1105 error = TA_Err_Ok;
1107 Err:
1108 free(header_buf);
1110 return error;
1114 static FT_Error
1115 TA_font_build_TTC_header(FONT* font,
1116 FT_Byte** header_buf,
1117 FT_ULong* header_len)
1119 SFNT* sfnts = font->sfnts;
1120 FT_Long num_sfnts = font->num_sfnts;
1122 SFNT_Table* tables = font->tables;
1123 FT_ULong num_tables = font->num_tables;
1125 FT_ULong TTF_offset;
1126 FT_ULong DSIG_offset;
1128 FT_Byte* buf;
1129 FT_ULong len;
1131 FT_Long i;
1132 FT_Byte* p;
1135 len = 24 + 4 * num_sfnts;
1136 buf = (FT_Byte*)malloc(len);
1137 if (!buf)
1138 return FT_Err_Out_Of_Memory;
1140 p = buf;
1142 /* TTC ID string */
1143 *(p++) = 't';
1144 *(p++) = 't';
1145 *(p++) = 'c';
1146 *(p++) = 'f';
1148 /* TTC header version */
1149 *(p++) = 0x00;
1150 *(p++) = 0x02;
1151 *(p++) = 0x00;
1152 *(p++) = 0x00;
1154 /* number of subfonts */
1155 *(p++) = BYTE1(num_sfnts);
1156 *(p++) = BYTE2(num_sfnts);
1157 *(p++) = BYTE3(num_sfnts);
1158 *(p++) = BYTE4(num_sfnts);
1160 /* the first TTF subfont header immediately follows the TTC header */
1161 TTF_offset = len;
1163 /* loop over all subfonts */
1164 for (i = 0; i < num_sfnts; i++)
1166 SFNT* sfnt = &sfnts[i];
1167 FT_ULong l;
1170 TA_sfnt_sort_table_info(sfnt, font);
1171 /* only get header length */
1172 (void)TA_sfnt_build_TTF_header(sfnt, font, NULL, &l, 0);
1174 *(p++) = BYTE1(TTF_offset);
1175 *(p++) = BYTE2(TTF_offset);
1176 *(p++) = BYTE3(TTF_offset);
1177 *(p++) = BYTE4(TTF_offset);
1179 TTF_offset += l;
1182 /* the first SFNT table immediately follows the subfont TTF headers */
1183 TA_font_compute_table_offsets(font, TTF_offset);
1185 /* DSIG tag */
1186 *(p++) = 'D';
1187 *(p++) = 'S';
1188 *(p++) = 'I';
1189 *(p++) = 'G';
1191 /* DSIG length */
1192 *(p++) = 0x00;
1193 *(p++) = 0x00;
1194 *(p++) = 0x00;
1195 *(p++) = 0x08;
1197 /* DSIG offset; in a TTC this is always the last SFNT table */
1198 DSIG_offset = tables[num_tables - 1].offset;
1200 *(p++) = BYTE1(DSIG_offset);
1201 *(p++) = BYTE2(DSIG_offset);
1202 *(p++) = BYTE3(DSIG_offset);
1203 *(p++) = BYTE4(DSIG_offset);
1205 *header_buf = buf;
1206 *header_len = len;
1208 return TA_Err_Ok;
1212 static FT_Error
1213 TA_font_build_TTC(FONT* font)
1215 SFNT* sfnts = font->sfnts;
1216 FT_Long num_sfnts = font->num_sfnts;
1218 SFNT_Table* tables;
1219 FT_ULong num_tables;
1221 FT_Byte* DSIG_buf;
1222 SFNT_Table_Info dummy;
1224 FT_Byte* TTC_header_buf;
1225 FT_ULong TTC_header_len;
1227 FT_Byte** TTF_header_bufs = NULL;
1228 FT_ULong* TTF_header_lens = NULL;
1230 FT_ULong offset;
1231 FT_Long i;
1232 FT_ULong j;
1233 FT_Error error;
1236 /* add a dummy `DSIG' table */
1238 error = TA_table_build_DSIG(&DSIG_buf);
1239 if (error)
1240 return error;
1242 /* in case of success, `DSIG_buf' gets linked */
1243 /* and is eventually freed in `TA_font_unload' */
1244 error = TA_font_add_table(font, &dummy, TTAG_DSIG, DSIG_LEN, DSIG_buf);
1245 if (error)
1247 free(DSIG_buf);
1248 return error;
1251 /* this also computes the SFNT table offsets */
1252 error = TA_font_build_TTC_header(font,
1253 &TTC_header_buf, &TTC_header_len);
1254 if (error)
1255 return error;
1257 TTF_header_bufs = (FT_Byte**)calloc(1, num_sfnts * sizeof (FT_Byte*));
1258 if (!TTF_header_bufs)
1259 goto Err;
1261 TTF_header_lens = (FT_ULong*)malloc(num_sfnts * sizeof (FT_ULong));
1262 if (!TTF_header_lens)
1263 goto Err;
1265 for (i = 0; i < num_sfnts; i++)
1267 error = TA_sfnt_build_TTF_header(&sfnts[i], font,
1268 &TTF_header_bufs[i],
1269 &TTF_header_lens[i], 1);
1270 if (error)
1271 goto Err;
1274 /* build font */
1276 tables = font->tables;
1277 num_tables = font->num_tables;
1279 /* get font length from last SFNT table array element */
1280 font->out_len = tables[num_tables - 1].offset
1281 + ((tables[num_tables - 1].len + 3) & ~3);
1282 font->out_buf = (FT_Byte*)malloc(font->out_len);
1283 if (!font->out_buf)
1285 error = FT_Err_Out_Of_Memory;
1286 goto Err;
1289 memcpy(font->out_buf, TTC_header_buf, TTC_header_len);
1291 offset = TTC_header_len;
1293 for (i = 0; i < num_sfnts; i++)
1295 memcpy(font->out_buf + offset,
1296 TTF_header_bufs[i], TTF_header_lens[i]);
1298 offset += TTF_header_lens[i];
1301 for (j = 0; j < num_tables; j++)
1303 SFNT_Table* table = &tables[j];
1306 /* buffer length is a multiple of 4 */
1307 memcpy(font->out_buf + table->offset,
1308 table->buf, (table->len + 3) & ~3);
1311 error = TA_Err_Ok;
1313 Err:
1314 free(TTC_header_buf);
1315 if (TTF_header_bufs)
1317 for (i = 0; i < font->num_sfnts; i++)
1318 free(TTF_header_bufs[i]);
1319 free(TTF_header_bufs);
1321 free(TTF_header_lens);
1323 return error;
1327 static FT_Error
1328 TA_font_file_write(FONT* font,
1329 FILE* out_file)
1331 if (fwrite(font->out_buf, 1, font->out_len, out_file) != font->out_len)
1332 return TA_Err_Invalid_Stream_Write;
1334 return TA_Err_Ok;
1338 static void
1339 TA_font_unload(FONT* font,
1340 const char *in_buf,
1341 char** out_bufp)
1343 /* in case of error it is expected that unallocated pointers */
1344 /* are NULL (and counters are zero) */
1346 if (!font)
1347 return;
1349 if (font->loader)
1350 ta_loader_done(font->loader);
1352 if (font->tables)
1354 FT_ULong i;
1357 for (i = 0; i < font->num_tables; i++)
1359 free(font->tables[i].buf);
1360 if (font->tables[i].data)
1362 if (font->tables[i].tag == TTAG_glyf)
1364 glyf_Data* data = (glyf_Data*)font->tables[i].data;
1365 FT_UShort j;
1368 for (j = 0; j < data->num_glyphs; j++)
1370 free(data->glyphs[j].buf);
1371 free(data->glyphs[j].ins_buf);
1373 free(data->glyphs);
1374 free(data);
1378 free(font->tables);
1381 if (font->sfnts)
1383 FT_Long i;
1386 for (i = 0; i < font->num_sfnts; i++)
1388 FT_Done_Face(font->sfnts[i].face);
1389 free(font->sfnts[i].table_infos);
1391 free(font->sfnts);
1394 FT_Done_FreeType(font->lib);
1395 if (!in_buf)
1396 free(font->in_buf);
1397 if (!out_bufp)
1398 free(font->out_buf);
1399 free(font);
1403 #define COMPARE(str) (len == (sizeof (str) - 1) \
1404 && !strncmp(start, str, sizeof (str) - 1))
1407 TA_Error
1408 TTF_autohint(const char* options,
1409 ...)
1411 va_list ap;
1413 FONT* font;
1414 FT_Error error;
1415 FT_Long i;
1417 FILE* in_file = NULL;
1418 FILE* out_file = NULL;
1420 const char* in_buf = NULL;
1421 size_t in_len = 0;
1422 char** out_bufp = NULL;
1423 size_t* out_lenp = NULL;
1425 FT_Long hinting_range_min = -1;
1426 FT_Long hinting_range_max = -1;
1428 TA_Progress_Func progress;
1429 void* progress_data;
1431 const char *op;
1434 if (!options || !*options)
1435 return FT_Err_Invalid_Argument;
1437 /* XXX */
1438 va_start(ap, options);
1440 op = options;
1442 for(;;)
1444 const char* start;
1445 size_t len;
1448 start = op;
1450 /* search comma */
1451 while (*op && *op != ',')
1452 op++;
1454 /* remove leading whitespace */
1455 while (isspace(*start))
1456 start++;
1458 /* check for empty option */
1459 if (start == op)
1460 goto End;
1462 len = op - start;
1464 /* the `COMPARE' macro uses `len' and `start' */
1466 /* handle option */
1467 if (COMPARE("in-file"))
1469 in_file = va_arg(ap, FILE*);
1470 in_buf = NULL;
1471 in_len = 0;
1473 else if (COMPARE("in-buffer"))
1475 in_file = NULL;
1476 in_buf = va_arg(ap, const char*);
1478 else if (COMPARE("in-buffer-len"))
1480 in_file = NULL;
1481 in_len = va_arg(ap, size_t);
1483 else if (COMPARE("out-file"))
1485 out_file = va_arg(ap, FILE*);
1486 out_bufp = NULL;
1487 out_lenp = NULL;
1489 else if (COMPARE("out-buffer"))
1491 out_file = NULL;
1492 out_bufp = va_arg(ap, char**);
1494 else if (COMPARE("out-buffer-len"))
1496 out_file = NULL;
1497 out_lenp = va_arg(ap, size_t*);
1499 else if (COMPARE("hinting-range-min"))
1500 hinting_range_min = (FT_Long)va_arg(ap, FT_UInt);
1501 else if (COMPARE("hinting-range-max"))
1502 hinting_range_max = (FT_Long)va_arg(ap, FT_UInt);
1503 else if (COMPARE("progress-callback"))
1504 progress = (TA_Progress_Func)va_arg(ap, void*);
1505 else if (COMPARE("progress-callback-data"))
1506 progress_data = va_arg(ap, void*);
1509 pre-hinting
1510 x-height-snapping-exceptions
1511 ignore-permissions
1512 latin-fallback
1515 End:
1516 if (!*op)
1517 break;
1518 op++;
1521 va_end(ap);
1523 /* check options */
1525 if (!(in_file
1526 || (in_buf && in_len)))
1527 return FT_Err_Invalid_Argument;
1529 if (!(out_file
1530 || (out_bufp && out_lenp)))
1531 return FT_Err_Invalid_Argument;
1533 font = (FONT*)calloc(1, sizeof (FONT));
1534 if (!font)
1535 return FT_Err_Out_Of_Memory;
1537 if (hinting_range_min >= 0 && hinting_range_min < 2)
1538 return FT_Err_Invalid_Argument;
1539 if (hinting_range_min < 0)
1540 hinting_range_min = 8;
1542 if (hinting_range_max >= 0 && hinting_range_max < hinting_range_min)
1543 return FT_Err_Invalid_Argument;
1544 if (hinting_range_max < 0)
1545 hinting_range_max = 1000;
1547 font->hinting_range_min = (FT_UInt)hinting_range_min;
1548 font->hinting_range_max = (FT_UInt)hinting_range_max;
1550 font->progress = progress;
1551 font->progress_data = progress_data;
1553 /* now start with processing the data */
1555 if (in_file)
1557 error = TA_font_file_read(font, in_file);
1558 if (error)
1559 goto Err;
1561 else
1563 /* a valid TTF can never be that small */
1564 if (in_len < 100)
1565 return FT_Err_Invalid_Argument;
1566 font->in_buf = (FT_Byte*)in_buf;
1567 font->in_len = in_len;
1570 error = TA_font_init(font);
1571 if (error)
1572 goto Err;
1574 /* loop over subfonts */
1575 for (i = 0; i < font->num_sfnts; i++)
1577 SFNT* sfnt = &font->sfnts[i];
1580 error = FT_New_Memory_Face(font->lib, font->in_buf, font->in_len,
1581 i, &sfnt->face);
1582 if (error)
1583 goto Err;
1585 error = TA_sfnt_split_into_SFNT_tables(sfnt, font);
1586 if (error)
1587 goto Err;
1589 error = TA_sfnt_split_glyf_table(sfnt, font);
1590 if (error)
1591 goto Err;
1594 /* build `gasp' table */
1595 error = TA_sfnt_build_gasp_table(&font->sfnts[0], font);
1596 if (error)
1597 goto Err;
1599 /* XXX handle subfonts for bytecode tables */
1601 /* build `cvt ' table */
1602 error = TA_sfnt_build_cvt_table(&font->sfnts[0], font);
1603 if (error)
1604 goto Err;
1606 /* build `fpgm' table */
1607 error = TA_sfnt_build_fpgm_table(&font->sfnts[0], font);
1608 if (error)
1609 goto Err;
1611 /* build `prep' table */
1612 error = TA_sfnt_build_prep_table(&font->sfnts[0], font);
1613 if (error)
1614 goto Err;
1616 /* hint the glyphs and build bytecode */
1617 error = TA_sfnt_build_glyf_hints(&font->sfnts[0], font);
1618 if (error)
1619 goto Err;
1621 /* loop again over subfonts */
1622 for (i = 0; i < font->num_sfnts; i++)
1624 SFNT* sfnt = &font->sfnts[i];
1627 error = TA_sfnt_build_glyf_table(sfnt, font);
1628 if (error)
1629 goto Err;
1630 error = TA_sfnt_build_loca_table(sfnt, font);
1631 if (error)
1632 goto Err;
1633 error = TA_sfnt_update_maxp_table(sfnt, font);
1634 if (error)
1635 goto Err;
1638 if (font->num_sfnts == 1)
1639 error = TA_font_build_TTF(font);
1640 else
1641 error = TA_font_build_TTC(font);
1642 if (error)
1643 goto Err;
1645 if (out_file)
1647 error = TA_font_file_write(font, out_file);
1648 if (error)
1649 goto Err;
1651 else
1653 *out_bufp = (char*)font->out_buf;
1654 *out_lenp = font->out_len;
1657 error = TA_Err_Ok;
1659 Err:
1660 TA_font_unload(font, in_buf, out_bufp);
1662 return error;
1665 /* end of ttfautohint.c */