Add code to build a `gasp' table.
[ttfautohint.git] / src / ttfautohint.c
blob9e1f6b643637cc7a6fa43060bb269d6f5f438d80
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>
11 #include "ta.h"
14 static FT_Error
15 TA_font_read(FONT* font,
16 FILE* in)
18 fseek(in, 0, SEEK_END);
19 font->in_len = ftell(in);
20 fseek(in, 0, SEEK_SET);
22 /* a valid TTF can never be that small */
23 if (font->in_len < 100)
24 return FT_Err_Invalid_Argument;
26 font->in_buf = (FT_Byte*)malloc(font->in_len);
27 if (!font->in_buf)
28 return FT_Err_Out_Of_Memory;
30 if (fread(font->in_buf, 1, font->in_len, in) != font->in_len)
31 return FT_Err_Invalid_Stream_Read;
33 return TA_Err_Ok;
37 static FT_Error
38 TA_font_init(FONT* font)
40 FT_Error error;
41 FT_Face f;
44 error = FT_Init_FreeType(&font->lib);
45 if (error)
46 return error;
48 /* get number of faces (i.e. subfonts) */
49 error = FT_New_Memory_Face(font->lib, font->in_buf, font->in_len, -1, &f);
50 if (error)
51 return error;
52 font->num_sfnts = f->num_faces;
53 FT_Done_Face(f);
55 /* it is a TTC if we have more than a single subfont */
56 font->sfnts = (SFNT*)calloc(1, font->num_sfnts * sizeof (SFNT));
57 if (!font->sfnts)
58 return FT_Err_Out_Of_Memory;
60 return TA_Err_Ok;
64 static FT_Error
65 TA_sfnt_split_into_SFNT_tables(SFNT* sfnt,
66 FONT* font)
68 FT_Error error;
69 FT_ULong i;
72 /* basic check whether font is a TTF or TTC */
73 if (!FT_IS_SFNT(sfnt->face))
74 return FT_Err_Invalid_Argument;
76 error = FT_Sfnt_Table_Info(sfnt->face, 0, NULL, &sfnt->num_table_infos);
77 if (error)
78 return error;
80 sfnt->table_infos = (SFNT_Table_Info*)malloc(sfnt->num_table_infos
81 * sizeof (SFNT_Table_Info));
82 if (!sfnt->table_infos)
83 return FT_Err_Out_Of_Memory;
85 /* collect SFNT tables and search for `glyf' and `loca' table */
86 sfnt->glyf_idx = MISSING;
87 sfnt->loca_idx = MISSING;
88 sfnt->head_idx = MISSING;
89 sfnt->maxp_idx = MISSING;
91 for (i = 0; i < sfnt->num_table_infos; i++)
93 SFNT_Table_Info* table_info = &sfnt->table_infos[i];
94 FT_ULong tag;
95 FT_ULong len;
96 FT_Byte* buf;
98 FT_ULong buf_len;
99 FT_ULong j;
102 *table_info = MISSING;
104 error = FT_Sfnt_Table_Info(sfnt->face, i, &tag, &len);
105 if (error)
107 /* this ignores both missing and zero-length tables */
108 if (error == FT_Err_Table_Missing)
109 continue;
110 else
111 return error;
114 /* ignore tables which we are going to create by ourselves, */
115 /* or which would become invalid otherwise */
116 else if (tag == TTAG_fpgm
117 || tag == TTAG_prep
118 || tag == TTAG_cvt
119 || tag == TTAG_DSIG
120 || tag == TTAG_hdmx
121 || tag == TTAG_VDMX
122 || tag == TTAG_LTSH
123 || tag == TTAG_gasp)
124 continue;
126 /* make the allocated buffer length a multiple of 4 */
127 buf_len = (len + 3) & -3;
128 buf = (FT_Byte*)malloc(buf_len);
129 if (!buf)
130 return FT_Err_Out_Of_Memory;
132 /* pad end of buffer with zeros */
133 buf[buf_len - 1] = 0x00;
134 buf[buf_len - 2] = 0x00;
135 buf[buf_len - 3] = 0x00;
137 /* load table */
138 error = FT_Load_Sfnt_Table(sfnt->face, tag, 0, buf, &len);
139 if (error)
140 goto Err;
142 /* check whether we already have this table */
143 for (j = 0; j < font->num_tables; j++)
145 SFNT_Table* table = &font->tables[j];
148 if (table->tag == tag
149 && table->len == len
150 && !memcmp(table->buf, buf, len))
151 break;
154 if (tag == TTAG_head)
155 sfnt->head_idx = j;
156 else if (tag == TTAG_glyf)
157 sfnt->glyf_idx = j;
158 else if (tag == TTAG_loca)
159 sfnt->loca_idx = j;
160 else if (tag == TTAG_maxp)
161 sfnt->maxp_idx = j;
163 if (j == font->num_tables)
165 /* add element to table array if it is missing or different; */
166 /* in case of success, `buf' gets linked and is eventually */
167 /* freed in `TA_font_unload' */
168 error = TA_font_add_table(font, table_info, tag, len, buf);
169 if (error)
170 goto Err;
172 else
174 /* reuse existing SFNT table */
175 free(buf);
176 *table_info = j;
178 continue;
180 Err:
181 free(buf);
182 return error;
185 /* no (non-empty) `glyf', `loca', `head', or `maxp' table; */
186 /* this can't be a valid TTF with outlines */
187 if (sfnt->glyf_idx == MISSING
188 || sfnt->loca_idx == MISSING
189 || sfnt->head_idx == MISSING
190 || sfnt->maxp_idx == MISSING)
191 return FT_Err_Invalid_Argument;
193 return TA_Err_Ok;
197 static FT_Error
198 TA_glyph_parse_composite(GLYPH* glyph,
199 FT_Byte* buf,
200 FT_ULong len)
202 FT_ULong flags_offset; /* after the loop, this is the offset */
203 /* to the last element in the flags array */
204 FT_UShort flags;
206 FT_Byte* p;
207 FT_Byte* endp;
210 p = buf;
211 endp = buf + len;
213 /* skip header */
214 p += 10;
216 /* walk over component records */
219 if (p + 4 > endp)
220 return FT_Err_Invalid_Table;
222 flags_offset = p - buf;
224 flags = *(p++) << 8;
225 flags += *(p++);
227 /* skip glyph component index */
228 p += 2;
230 /* skip scaling and offset arguments */
231 if (flags & ARGS_ARE_WORDS)
232 p += 4;
233 else
234 p += 2;
236 if (flags & WE_HAVE_A_SCALE)
237 p += 2;
238 else if (flags & WE_HAVE_AN_XY_SCALE)
239 p += 4;
240 else if (flags & WE_HAVE_A_2X2)
241 p += 8;
242 } while (flags & MORE_COMPONENTS);
244 glyph->flags_offset = flags_offset;
246 /* adjust glyph record length */
247 len = p - buf;
249 glyph->len1 = len;
250 /* glyph->len2 = 0; */
251 glyph->buf = (FT_Byte*)malloc(len);
252 if (!glyph->buf)
253 return FT_Err_Out_Of_Memory;
255 /* copy record without instructions (if any) */
256 memcpy(glyph->buf, buf, len);
257 glyph->buf[flags_offset] &= ~(WE_HAVE_INSTR >> 8);
259 return TA_Err_Ok;
263 static FT_Error
264 TA_glyph_parse_simple(GLYPH* glyph,
265 FT_Byte* buf,
266 FT_UShort num_contours,
267 FT_ULong len)
269 FT_ULong ins_offset;
270 FT_Byte* flags_start;
272 FT_UShort num_ins;
273 FT_UShort num_pts;
275 FT_ULong flags_size; /* size of the flags array */
276 FT_ULong xy_size; /* size of x and y coordinate arrays together */
278 FT_Byte* p;
279 FT_Byte* endp;
281 FT_UShort i;
284 p = buf;
285 endp = buf + len;
287 ins_offset = 10 + num_contours * 2;
289 p += ins_offset;
291 if (p + 2 > endp)
292 return FT_Err_Invalid_Table;
294 /* get number of instructions */
295 num_ins = *(p++) << 8;
296 num_ins += *(p++);
298 p += num_ins;
300 if (p > endp)
301 return FT_Err_Invalid_Table;
303 /* get number of points from last outline point */
304 num_pts = buf[ins_offset - 2] << 8;
305 num_pts += buf[ins_offset - 1];
306 num_pts++;
308 flags_start = p;
309 xy_size = 0;
310 i = 0;
312 while (i < num_pts)
314 FT_Byte flags;
315 FT_Byte x_short;
316 FT_Byte y_short;
317 FT_Byte have_x;
318 FT_Byte have_y;
319 FT_Byte count;
322 if (p + 1 > endp)
323 return FT_Err_Invalid_Table;
325 flags = *(p++);
327 x_short = (flags & X_SHORT_VECTOR) ? 1 : 2;
328 y_short = (flags & Y_SHORT_VECTOR) ? 1 : 2;
330 have_x = ((flags & SAME_X) && !(flags & X_SHORT_VECTOR)) ? 0 : 1;
331 have_y = ((flags & SAME_Y) && !(flags & Y_SHORT_VECTOR)) ? 0 : 1;
333 count = 1;
335 if (flags & REPEAT)
337 if (p + 1 > endp)
338 return FT_Err_Invalid_Table;
340 count += *(p++);
342 if (i + count > num_pts)
343 return FT_Err_Invalid_Table;
346 xy_size += count * x_short * have_x;
347 xy_size += count * y_short * have_y;
349 i += count;
352 if (p + xy_size > endp)
353 return FT_Err_Invalid_Table;
355 flags_size = p - flags_start;
357 /* store the data before and after the bytecode instructions */
358 /* in the same array */
359 glyph->len1 = ins_offset;
360 glyph->len2 = flags_size + xy_size;
361 glyph->buf = (FT_Byte*)malloc(glyph->len1 + glyph->len2);
362 if (!glyph->buf)
363 return FT_Err_Out_Of_Memory;
365 /* now copy everything but the instructions */
366 memcpy(glyph->buf, buf, glyph->len1);
367 memcpy(glyph->buf + glyph->len1, flags_start, glyph->len2);
369 return TA_Err_Ok;
373 static FT_Error
374 TA_sfnt_split_glyf_table(SFNT* sfnt,
375 FONT* font)
377 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
378 SFNT_Table* loca_table = &font->tables[sfnt->loca_idx];
379 SFNT_Table* head_table = &font->tables[sfnt->head_idx];
381 glyf_Data* data;
382 FT_Byte loca_format;
384 FT_ULong offset;
385 FT_ULong offset_next;
387 FT_Byte* p;
388 FT_UShort i;
391 /* in case of success, all allocated arrays are */
392 /* linked and eventually freed in `TA_font_unload' */
394 /* nothing to do if table has already been split */
395 if (glyf_table->data)
396 return TA_Err_Ok;
398 data = (glyf_Data*)calloc(1, sizeof (glyf_Data));
399 if (!data)
400 return FT_Err_Out_Of_Memory;
402 glyf_table->data = data;
404 loca_format = head_table->buf[LOCA_FORMAT_OFFSET];
406 data->num_glyphs = loca_format ? loca_table->len / 4 - 1
407 : loca_table->len / 2 - 1;
408 data->glyphs = (GLYPH*)calloc(1, data->num_glyphs * sizeof (GLYPH));
409 if (!data->glyphs)
410 return FT_Err_Out_Of_Memory;
412 p = loca_table->buf;
414 if (loca_format)
416 offset_next = *(p++) << 24;
417 offset_next += *(p++) << 16;
418 offset_next += *(p++) << 8;
419 offset_next += *(p++);
421 else
423 offset_next = *(p++) << 8;
424 offset_next += *(p++);
425 offset_next <<= 1;
428 /* loop over `loca' and `glyf' data */
429 for (i = 0; i < data->num_glyphs; i++)
431 GLYPH* glyph = &data->glyphs[i];
432 FT_ULong len;
435 offset = offset_next;
437 if (loca_format)
439 offset_next = *(p++) << 24;
440 offset_next += *(p++) << 16;
441 offset_next += *(p++) << 8;
442 offset_next += *(p++);
444 else
446 offset_next = *(p++) << 8;
447 offset_next += *(p++);
448 offset_next <<= 1;
451 if (offset_next < offset
452 || offset_next > glyf_table->len)
453 return FT_Err_Invalid_Table;
455 len = offset_next - offset;
456 if (!len)
457 continue; /* empty glyph */
458 else
460 FT_Byte* buf;
461 FT_Short num_contours;
462 FT_Error error;
465 /* check header size */
466 if (len < 10)
467 return FT_Err_Invalid_Table;
469 buf = glyf_table->buf + offset;
470 num_contours = (FT_Short)((buf[0] << 8) + buf[1]);
472 /* We must parse the rest of the glyph record to get the exact */
473 /* record length. Since the `loca' table rounds record lengths */
474 /* up to multiples of 4 (or 2 for older fonts), and we must round */
475 /* up again after stripping off the instructions, it would be */
476 /* possible otherwise to have more than 4 bytes of padding which */
477 /* is more or less invalid. */
479 if (num_contours < 0)
481 error = TA_glyph_parse_composite(glyph, buf, len);
482 if (error)
483 return error;
485 else
487 error = TA_glyph_parse_simple(glyph, buf, num_contours, len);
488 if (error)
489 return error;
494 return TA_Err_Ok;
498 static FT_Error
499 TA_sfnt_build_glyf_table(SFNT* sfnt,
500 FONT* font)
502 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
503 glyf_Data* data = (glyf_Data*)glyf_table->data;
505 GLYPH* glyph;
507 FT_ULong len;
508 FT_Byte* buf_new;
509 FT_Byte* p;
510 FT_UShort i;
513 if (glyf_table->processed)
514 return TA_Err_Ok;
516 /* get table size */
517 len = 0;
518 glyph = data->glyphs;
519 for (i = 0; i < data->num_glyphs; i++, glyph++)
521 /* glyph records should have offsets which are multiples of 4 */
522 len = (len + 3) & ~3;
523 len += glyph->len1 + glyph->len2 + glyph->ins_len;
524 /* add two bytes for the instructionLength field */
525 if (glyph->len2 || glyph->ins_len)
526 len += 2;
529 glyf_table->len = len;
530 buf_new = (FT_Byte*)realloc(glyf_table->buf, (len + 3) & ~3);
531 if (!buf_new)
532 return FT_Err_Out_Of_Memory;
533 else
534 glyf_table->buf = buf_new;
536 p = glyf_table->buf;
537 glyph = data->glyphs;
538 for (i = 0; i < data->num_glyphs; i++, glyph++)
540 len = glyph->len1 + glyph->len2 + glyph->ins_len;
541 if (glyph->len2 || glyph->ins_len)
542 len += 2;
544 if (len)
546 /* copy glyph data and insert new instructions */
547 memcpy(p, glyph->buf, glyph->len1);
549 if (glyph->len2)
551 /* simple glyph */
552 p += glyph->len1;
553 *(p++) = HIGH(glyph->ins_len);
554 *(p++) = LOW(glyph->ins_len);
555 memcpy(p, glyph->ins_buf, glyph->ins_len);
556 p += glyph->ins_len;
557 memcpy(p, glyph->buf + glyph->len1, glyph->len2);
558 p += glyph->len2;
560 else
562 /* composite glyph */
563 if (glyph->ins_len)
565 *(p + glyph->flags_offset) |= (WE_HAVE_INSTR >> 8);
566 p += glyph->len1;
567 *(p++) = HIGH(glyph->ins_len);
568 *(p++) = LOW(glyph->ins_len);
569 memcpy(p, glyph->ins_buf, glyph->ins_len);
570 p += glyph->ins_len;
572 else
573 p += glyph->len1;
576 /* pad with zero bytes to have an offset which is a multiple of 4; */
577 /* this works even for the last glyph record since the `glyf' */
578 /* table length is a multiple of 4 also */
579 switch (len % 4)
581 case 1:
582 *(p++) = 0;
583 case 2:
584 *(p++) = 0;
585 case 3:
586 *(p++) = 0;
587 default:
588 break;
593 glyf_table->checksum = TA_table_compute_checksum(glyf_table->buf,
594 glyf_table->len);
595 glyf_table->processed = 1;
597 return TA_Err_Ok;
601 static FT_Error
602 TA_sfnt_build_loca_table(SFNT* sfnt,
603 FONT* font)
605 SFNT_Table* loca_table = &font->tables[sfnt->loca_idx];
606 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
607 SFNT_Table* head_table = &font->tables[sfnt->head_idx];
609 glyf_Data* data = (glyf_Data*)glyf_table->data;
610 GLYPH* glyph;
612 FT_ULong offset;
613 FT_Byte loca_format;
614 FT_Byte* buf_new;
615 FT_Byte* p;
616 FT_UShort i;
619 if (loca_table->processed)
620 return TA_Err_Ok;
622 /* get largest offset */
623 offset = 0;
624 glyph = data->glyphs;
626 for (i = 0; i < data->num_glyphs; i++, glyph++)
628 /* glyph records should have offsets which are multiples of 4 */
629 offset = (offset + 3) & ~3;
630 offset += glyph->len1 + glyph->len2 + glyph->ins_len;
631 /* add two bytes for the instructionLength field */
632 if (glyph->len2 || glyph->ins_len)
633 offset += 2;
636 if (offset > 0xFFFF * 2)
637 loca_format = 1;
638 else
639 loca_format = 0;
641 /* fill table */
642 if (loca_format)
644 loca_table->len = (data->num_glyphs + 1) * 4;
645 buf_new = (FT_Byte*)realloc(loca_table->buf, loca_table->len);
646 if (!buf_new)
647 return FT_Err_Out_Of_Memory;
648 else
649 loca_table->buf = buf_new;
651 p = loca_table->buf;
652 offset = 0;
653 glyph = data->glyphs;
655 for (i = 0; i < data->num_glyphs; i++, glyph++)
657 offset = (offset + 3) & ~3;
659 *(p++) = BYTE1(offset);
660 *(p++) = BYTE2(offset);
661 *(p++) = BYTE3(offset);
662 *(p++) = BYTE4(offset);
664 offset += glyph->len1 + glyph->len2 + glyph->ins_len;
665 if (glyph->len2 || glyph->ins_len)
666 offset += 2;
669 /* last element holds the size of the `glyf' table */
670 *(p++) = BYTE1(offset);
671 *(p++) = BYTE2(offset);
672 *(p++) = BYTE3(offset);
673 *(p++) = BYTE4(offset);
675 else
677 loca_table->len = (data->num_glyphs + 1) * 2;
678 buf_new = (FT_Byte*)realloc(loca_table->buf,
679 (loca_table->len + 3) & ~3);
680 if (!buf_new)
681 return FT_Err_Out_Of_Memory;
682 else
683 loca_table->buf = buf_new;
685 p = loca_table->buf;
686 offset = 0;
687 glyph = data->glyphs;
689 for (i = 0; i < data->num_glyphs; i++, glyph++)
691 offset = (offset + 1) & ~1;
693 *(p++) = HIGH(offset);
694 *(p++) = LOW(offset);
696 offset += (glyph->len1 + glyph->len2 + glyph->ins_len + 1) >> 1;
697 if (glyph->len2 || glyph->ins_len)
698 offset += 1;
701 /* last element holds the size of the `glyf' table */
702 *(p++) = HIGH(offset);
703 *(p++) = LOW(offset);
705 /* pad `loca' table to make its length a multiple of 4 */
706 if (loca_table->len % 4 == 2)
708 *(p++) = 0;
709 *(p++) = 0;
713 loca_table->checksum = TA_table_compute_checksum(loca_table->buf,
714 loca_table->len);
715 loca_table->processed = 1;
717 head_table->buf[LOCA_FORMAT_OFFSET] = loca_format;
719 return TA_Err_Ok;
723 static FT_Error
724 TA_sfnt_update_maxp_table(SFNT* sfnt,
725 FONT* font)
727 SFNT_Table* maxp_table = &font->tables[sfnt->maxp_idx];
728 FT_Byte* buf = maxp_table->buf;
731 if (maxp_table->processed)
732 return TA_Err_Ok;
734 if (maxp_table->len != MAXP_LEN)
735 return FT_Err_Invalid_Table;
737 buf[MAXP_MAX_ZONES_OFFSET] = 0;
738 buf[MAXP_MAX_ZONES_OFFSET + 1] = 2;
739 buf[MAXP_MAX_TWILIGHT_POINTS_OFFSET] = 0;
740 buf[MAXP_MAX_TWILIGHT_POINTS_OFFSET + 1] = 0;
741 buf[MAXP_MAX_STORAGE_OFFSET] = 0;
742 buf[MAXP_MAX_STORAGE_OFFSET + 1] = 0;
743 buf[MAXP_MAX_FUNCTION_DEFS_OFFSET] = 0;
744 buf[MAXP_MAX_FUNCTION_DEFS_OFFSET + 1] = NUM_FDEFS;
745 buf[MAXP_MAX_INSTRUCTION_DEFS_OFFSET] = 0;
746 buf[MAXP_MAX_INSTRUCTION_DEFS_OFFSET + 1] = 0;
747 buf[MAXP_MAX_STACK_ELEMENTS_OFFSET] = 0;
748 buf[MAXP_MAX_STACK_ELEMENTS_OFFSET + 1] = 0;
749 buf[MAXP_MAX_INSTRUCTIONS_OFFSET] = 0;
750 buf[MAXP_MAX_INSTRUCTIONS_OFFSET + 1] = 0;
752 maxp_table->checksum = TA_table_compute_checksum(maxp_table->buf,
753 maxp_table->len);
754 maxp_table->processed = 1;
756 return TA_Err_Ok;
760 /* we build a dummy `DSIG' table only */
762 static FT_Error
763 TA_table_build_DSIG(FT_Byte** DSIG)
765 FT_Byte* buf;
768 buf = (FT_Byte*)malloc(DSIG_LEN);
769 if (!buf)
770 return FT_Err_Out_Of_Memory;
772 /* version */
773 buf[0] = 0x00;
774 buf[1] = 0x00;
775 buf[2] = 0x00;
776 buf[3] = 0x01;
778 /* zero signatures */
779 buf[4] = 0x00;
780 buf[5] = 0x00;
782 /* permission flags */
783 buf[6] = 0x00;
784 buf[7] = 0x00;
786 *DSIG = buf;
788 return TA_Err_Ok;
792 static FT_Error
793 TA_table_build_gasp(FT_Byte** gasp)
795 FT_Byte* buf;
798 buf = (FT_Byte*)malloc(GASP_LEN);
799 if (!buf)
800 return FT_Err_Out_Of_Memory;
802 /* version */
803 buf[0] = 0x00;
804 buf[1] = 0x01;
806 /* one range */
807 buf[2] = 0x00;
808 buf[3] = 0x01;
810 /* entry valid for all sizes */
811 buf[4] = 0xFF;
812 buf[5] = 0xFF;
813 buf[6] = 0x00;
814 buf[7] = 0x0F; /* always use grayscale rendering with grid-fitting, */
815 /* symmetric grid-fitting and symmetric smoothing */
817 *gasp = buf;
819 return TA_Err_Ok;
823 static FT_Error
824 TA_sfnt_build_gasp_table(SFNT* sfnt,
825 FONT* font)
827 FT_Error error;
829 FT_Byte* gasp_buf;
832 error = TA_sfnt_add_table_info(sfnt);
833 if (error)
834 return error;
836 error = TA_table_build_gasp(&gasp_buf);
837 if (error)
838 return error;
840 /* in case of success, `gasp_buf' gets linked */
841 /* and is eventually freed in `TA_font_unload' */
842 error = TA_font_add_table(font,
843 &sfnt->table_infos[sfnt->num_table_infos - 1],
844 TTAG_gasp, GASP_LEN, gasp_buf);
845 if (error)
847 free(gasp_buf);
848 return error;
853 static void
854 TA_font_compute_table_offsets(FONT* font,
855 FT_ULong start)
857 FT_ULong i;
858 FT_ULong offset = start;
861 for (i = 0; i < font->num_tables; i++)
863 SFNT_Table* table = &font->tables[i];
866 table->offset = offset;
868 /* table offsets must be multiples of 4; */
869 /* this also fits the actual buffer lengths */
870 offset += (table->len + 3) & ~3;
875 /* If `do_complete' is 0, only return `header_len'. */
877 static FT_Error
878 TA_sfnt_build_TTF_header(SFNT* sfnt,
879 FONT* font,
880 FT_Byte** header_buf,
881 FT_ULong* header_len,
882 FT_Int do_complete)
884 SFNT_Table* tables = font->tables;
886 SFNT_Table_Info* table_infos = sfnt->table_infos;
887 FT_ULong num_table_infos = sfnt->num_table_infos;
889 FT_Byte* buf;
890 FT_ULong len;
892 FT_Byte* table_record;
894 FT_Byte* head_buf = NULL; /* pointer to `head' table */
895 FT_ULong head_checksum; /* checksum in `head' table */
897 FT_ULong num_tables_in_header;
898 FT_ULong i;
901 num_tables_in_header = 0;
902 for (i = 0; i < num_table_infos; i++)
904 /* ignore empty tables */
905 if (table_infos[i] != MISSING)
906 num_tables_in_header++;
909 len = 12 + 16 * num_tables_in_header;
910 if (!do_complete)
912 *header_len = len;
913 return TA_Err_Ok;
915 buf = (FT_Byte*)malloc(len);
916 if (!buf)
917 return FT_Err_Out_Of_Memory;
919 /* SFNT version */
920 buf[0] = 0x00;
921 buf[1] = 0x01;
922 buf[2] = 0x00;
923 buf[3] = 0x00;
925 /* number of tables */
926 buf[4] = HIGH(num_tables_in_header);
927 buf[5] = LOW(num_tables_in_header);
929 /* auxiliary data */
931 FT_ULong search_range, entry_selector, range_shift;
932 FT_ULong i, j;
935 for (i = 1, j = 2; j <= num_tables_in_header; i++, j <<= 1)
938 entry_selector = i - 1;
939 search_range = 0x10 << entry_selector;
940 range_shift = (num_tables_in_header << 4) - search_range;
942 buf[6] = HIGH(search_range);
943 buf[7] = LOW(search_range);
944 buf[8] = HIGH(entry_selector);
945 buf[9] = LOW(entry_selector);
946 buf[10] = HIGH(range_shift);
947 buf[11] = LOW(range_shift);
950 /* location of the first table info record */
951 table_record = &buf[12];
953 head_checksum = 0;
955 /* loop over all tables */
956 for (i = 0; i < num_table_infos; i++)
958 SFNT_Table_Info table_info = table_infos[i];
959 SFNT_Table* table;
962 /* ignore empty slots */
963 if (table_info == MISSING)
964 continue;
966 table = &tables[table_info];
968 if (table->tag == TTAG_head)
970 /* we always reach this IF clause since FreeType would */
971 /* have aborted already if the `head' table were missing */
973 head_buf = table->buf;
975 /* reset checksum in `head' table for recalculation */
976 head_buf[8] = 0x00;
977 head_buf[9] = 0x00;
978 head_buf[10] = 0x00;
979 head_buf[11] = 0x00;
982 head_checksum += table->checksum;
984 table_record[0] = BYTE1(table->tag);
985 table_record[1] = BYTE2(table->tag);
986 table_record[2] = BYTE3(table->tag);
987 table_record[3] = BYTE4(table->tag);
989 table_record[4] = BYTE1(table->checksum);
990 table_record[5] = BYTE2(table->checksum);
991 table_record[6] = BYTE3(table->checksum);
992 table_record[7] = BYTE4(table->checksum);
994 table_record[8] = BYTE1(table->offset);
995 table_record[9] = BYTE2(table->offset);
996 table_record[10] = BYTE3(table->offset);
997 table_record[11] = BYTE4(table->offset);
999 table_record[12] = BYTE1(table->len);
1000 table_record[13] = BYTE2(table->len);
1001 table_record[14] = BYTE3(table->len);
1002 table_record[15] = BYTE4(table->len);
1004 table_record += 16;
1007 /* the font header is complete; compute `head' checksum */
1008 head_checksum += TA_table_compute_checksum(buf, len);
1009 head_checksum = 0xB1B0AFBAUL - head_checksum;
1011 /* store checksum in `head' table; */
1012 head_buf[8] = BYTE1(head_checksum);
1013 head_buf[9] = BYTE2(head_checksum);
1014 head_buf[10] = BYTE3(head_checksum);
1015 head_buf[11] = BYTE4(head_checksum);
1017 *header_buf = buf;
1018 *header_len = len;
1020 return TA_Err_Ok;
1024 static FT_Error
1025 TA_font_build_TTF(FONT* font)
1027 SFNT* sfnt = &font->sfnts[0];
1029 SFNT_Table* tables;
1030 FT_ULong num_tables;
1032 FT_ULong SFNT_offset;
1034 FT_Byte* DSIG_buf;
1036 FT_Byte* header_buf;
1037 FT_ULong header_len;
1039 FT_ULong i;
1040 FT_Error error;
1043 /* add a dummy `DSIG' table */
1045 error = TA_sfnt_add_table_info(sfnt);
1046 if (error)
1047 return error;
1049 error = TA_table_build_DSIG(&DSIG_buf);
1050 if (error)
1051 return error;
1053 /* in case of success, `DSIG_buf' gets linked */
1054 /* and is eventually freed in `TA_font_unload' */
1055 error = TA_font_add_table(font,
1056 &sfnt->table_infos[sfnt->num_table_infos - 1],
1057 TTAG_DSIG, DSIG_LEN, DSIG_buf);
1058 if (error)
1060 free(DSIG_buf);
1061 return error;
1064 TA_sfnt_sort_table_info(sfnt, font);
1066 /* the first SFNT table immediately follows the header */
1067 (void)TA_sfnt_build_TTF_header(sfnt, font, NULL, &SFNT_offset, 0);
1068 TA_font_compute_table_offsets(font, SFNT_offset);
1070 error = TA_sfnt_build_TTF_header(sfnt, font,
1071 &header_buf, &header_len, 1);
1072 if (error)
1073 return error;
1075 /* build font */
1077 tables = font->tables;
1078 num_tables = font->num_tables;
1080 /* get font length from last SFNT table array element */
1081 font->out_len = tables[num_tables - 1].offset
1082 + ((tables[num_tables - 1].len + 3) & ~3);
1083 font->out_buf = (FT_Byte*)malloc(font->out_len);
1084 if (!font->out_buf)
1086 error = FT_Err_Out_Of_Memory;
1087 goto Err;
1090 memcpy(font->out_buf, header_buf, header_len);
1092 for (i = 0; i < num_tables; i++)
1094 SFNT_Table* table = &tables[i];
1097 /* buffer length is a multiple of 4 */
1098 memcpy(font->out_buf + table->offset,
1099 table->buf, (table->len + 3) & ~3);
1102 error = TA_Err_Ok;
1104 Err:
1105 free(header_buf);
1107 return error;
1111 static FT_Error
1112 TA_font_build_TTC_header(FONT* font,
1113 FT_Byte** header_buf,
1114 FT_ULong* header_len)
1116 SFNT* sfnts = font->sfnts;
1117 FT_Long num_sfnts = font->num_sfnts;
1119 SFNT_Table* tables = font->tables;
1120 FT_ULong num_tables = font->num_tables;
1122 FT_ULong TTF_offset;
1123 FT_ULong DSIG_offset;
1125 FT_Byte* buf;
1126 FT_ULong len;
1128 FT_Long i;
1129 FT_Byte* p;
1132 len = 24 + 4 * num_sfnts;
1133 buf = (FT_Byte*)malloc(len);
1134 if (!buf)
1135 return FT_Err_Out_Of_Memory;
1137 p = buf;
1139 /* TTC ID string */
1140 *(p++) = 't';
1141 *(p++) = 't';
1142 *(p++) = 'c';
1143 *(p++) = 'f';
1145 /* TTC header version */
1146 *(p++) = 0x00;
1147 *(p++) = 0x02;
1148 *(p++) = 0x00;
1149 *(p++) = 0x00;
1151 /* number of subfonts */
1152 *(p++) = BYTE1(num_sfnts);
1153 *(p++) = BYTE2(num_sfnts);
1154 *(p++) = BYTE3(num_sfnts);
1155 *(p++) = BYTE4(num_sfnts);
1157 /* the first TTF subfont header immediately follows the TTC header */
1158 TTF_offset = len;
1160 /* loop over all subfonts */
1161 for (i = 0; i < num_sfnts; i++)
1163 SFNT* sfnt = &sfnts[i];
1164 FT_ULong l;
1167 TA_sfnt_sort_table_info(sfnt, font);
1168 /* only get header length */
1169 (void)TA_sfnt_build_TTF_header(sfnt, font, NULL, &l, 0);
1171 *(p++) = BYTE1(TTF_offset);
1172 *(p++) = BYTE2(TTF_offset);
1173 *(p++) = BYTE3(TTF_offset);
1174 *(p++) = BYTE4(TTF_offset);
1176 TTF_offset += l;
1179 /* the first SFNT table immediately follows the subfont TTF headers */
1180 TA_font_compute_table_offsets(font, TTF_offset);
1182 /* DSIG tag */
1183 *(p++) = 'D';
1184 *(p++) = 'S';
1185 *(p++) = 'I';
1186 *(p++) = 'G';
1188 /* DSIG length */
1189 *(p++) = 0x00;
1190 *(p++) = 0x00;
1191 *(p++) = 0x00;
1192 *(p++) = 0x08;
1194 /* DSIG offset; in a TTC this is always the last SFNT table */
1195 DSIG_offset = tables[num_tables - 1].offset;
1197 *(p++) = BYTE1(DSIG_offset);
1198 *(p++) = BYTE2(DSIG_offset);
1199 *(p++) = BYTE3(DSIG_offset);
1200 *(p++) = BYTE4(DSIG_offset);
1202 *header_buf = buf;
1203 *header_len = len;
1205 return TA_Err_Ok;
1209 static FT_Error
1210 TA_font_build_TTC(FONT* font)
1212 SFNT* sfnts = font->sfnts;
1213 FT_Long num_sfnts = font->num_sfnts;
1215 SFNT_Table* tables;
1216 FT_ULong num_tables;
1218 FT_Byte* DSIG_buf;
1219 SFNT_Table_Info dummy;
1221 FT_Byte* TTC_header_buf;
1222 FT_ULong TTC_header_len;
1224 FT_Byte** TTF_header_bufs;
1225 FT_ULong* TTF_header_lens;
1227 FT_ULong offset;
1228 FT_Long i;
1229 FT_ULong j;
1230 FT_Error error;
1233 /* add a dummy `DSIG' table */
1235 error = TA_table_build_DSIG(&DSIG_buf);
1236 if (error)
1237 return error;
1239 /* in case of success, `DSIG_buf' gets linked */
1240 /* and is eventually freed in `TA_font_unload' */
1241 error = TA_font_add_table(font, &dummy, TTAG_DSIG, DSIG_LEN, DSIG_buf);
1242 if (error)
1244 free(DSIG_buf);
1245 return error;
1248 /* this also computes the SFNT table offsets */
1249 error = TA_font_build_TTC_header(font,
1250 &TTC_header_buf, &TTC_header_len);
1251 if (error)
1252 return error;
1254 TTF_header_bufs = (FT_Byte**)calloc(1, num_sfnts * sizeof (FT_Byte*));
1255 if (!TTF_header_bufs)
1256 goto Err;
1258 TTF_header_lens = (FT_ULong*)malloc(num_sfnts * sizeof (FT_ULong));
1259 if (!TTF_header_lens)
1260 goto Err;
1262 for (i = 0; i < num_sfnts; i++)
1264 error = TA_sfnt_build_TTF_header(&sfnts[i], font,
1265 &TTF_header_bufs[i],
1266 &TTF_header_lens[i], 1);
1267 if (error)
1268 goto Err;
1271 /* build font */
1273 tables = font->tables;
1274 num_tables = font->num_tables;
1276 /* get font length from last SFNT table array element */
1277 font->out_len = tables[num_tables - 1].offset
1278 + ((tables[num_tables - 1].len + 3) & ~3);
1279 font->out_buf = (FT_Byte*)malloc(font->out_len);
1280 if (!font->out_buf)
1282 error = FT_Err_Out_Of_Memory;
1283 goto Err;
1286 memcpy(font->out_buf, TTC_header_buf, TTC_header_len);
1288 offset = TTC_header_len;
1290 for (i = 0; i < num_sfnts; i++)
1292 memcpy(font->out_buf + offset,
1293 TTF_header_bufs[i], TTF_header_lens[i]);
1295 offset += TTF_header_lens[i];
1298 for (j = 0; j < num_tables; j++)
1300 SFNT_Table* table = &tables[j];
1303 /* buffer length is a multiple of 4 */
1304 memcpy(font->out_buf + table->offset,
1305 table->buf, (table->len + 3) & ~3);
1308 error = TA_Err_Ok;
1310 Err:
1311 free(TTC_header_buf);
1312 if (TTF_header_bufs)
1314 for (i = 0; i < font->num_sfnts; i++)
1315 free(TTF_header_bufs[i]);
1316 free(TTF_header_bufs);
1318 free(TTF_header_lens);
1320 return error;
1324 static FT_Error
1325 TA_font_write(FONT* font,
1326 FILE* out)
1328 if (fwrite(font->out_buf, 1, font->out_len, out) != font->out_len)
1329 return TA_Err_Invalid_Stream_Write;
1331 return TA_Err_Ok;
1335 static void
1336 TA_font_unload(FONT* font)
1338 /* in case of error it is expected that unallocated pointers */
1339 /* are NULL (and counters are zero) */
1341 if (!font)
1342 return;
1344 if (font->loader)
1345 ta_loader_done(font->loader);
1347 if (font->tables)
1349 FT_ULong i;
1352 for (i = 0; i < font->num_tables; i++)
1354 free(font->tables[i].buf);
1355 if (font->tables[i].data)
1357 if (font->tables[i].tag == TTAG_glyf)
1359 glyf_Data* data = (glyf_Data*)font->tables[i].data;
1360 FT_UShort j;
1363 for (j = 0; j < data->num_glyphs; j++)
1364 free(data->glyphs[j].buf);
1365 free(data->glyphs);
1366 free(data);
1370 free(font->tables);
1373 if (font->sfnts)
1375 FT_Long i;
1378 for (i = 0; i < font->num_sfnts; i++)
1380 FT_Done_Face(font->sfnts[i].face);
1381 free(font->sfnts[i].table_infos);
1383 free(font->sfnts);
1386 FT_Done_FreeType(font->lib);
1387 free(font->in_buf);
1388 free(font->out_buf);
1389 free(font);
1393 TA_Error
1394 TTF_autohint(FILE* in,
1395 FILE* out)
1397 FONT* font;
1398 FT_Error error;
1399 FT_Long i;
1402 font = (FONT*)calloc(1, sizeof (FONT));
1403 if (!font)
1404 return FT_Err_Out_Of_Memory;
1406 error = TA_font_read(font, in);
1407 if (error)
1408 goto Err;
1410 error = TA_font_init(font);
1411 if (error)
1412 goto Err;
1414 /* loop over subfonts */
1415 for (i = 0; i < font->num_sfnts; i++)
1417 SFNT* sfnt = &font->sfnts[i];
1420 error = FT_New_Memory_Face(font->lib, font->in_buf, font->in_len,
1421 i, &sfnt->face);
1422 if (error)
1423 goto Err;
1425 error = TA_sfnt_split_into_SFNT_tables(sfnt, font);
1426 if (error)
1427 goto Err;
1429 error = TA_sfnt_split_glyf_table(sfnt, font);
1430 if (error)
1431 goto Err;
1434 /* build `gasp' table */
1435 error = TA_sfnt_build_gasp_table(&font->sfnts[0], font);
1436 if (error)
1437 goto Err;
1439 /* XXX handle subfonts for bytecode tables? */
1441 /* build `cvt ' table */
1442 error = TA_sfnt_build_cvt_table(&font->sfnts[0], font);
1443 if (error)
1444 goto Err;
1446 /* build `fpgm' table */
1447 error = TA_sfnt_build_fpgm_table(&font->sfnts[0], font);
1448 if (error)
1449 goto Err;
1451 /* build `prep' table */
1452 error = TA_sfnt_build_prep_table(&font->sfnts[0], font);
1453 if (error)
1454 goto Err;
1456 /* handle all glyphs in a loop */
1457 /* hint the glyph */
1458 /* build bytecode */
1460 /* adjust `maxp' table */
1462 /* loop again over subfonts */
1463 for (i = 0; i < font->num_sfnts; i++)
1465 SFNT* sfnt = &font->sfnts[i];
1468 error = TA_sfnt_build_glyf_table(sfnt, font);
1469 if (error)
1470 goto Err;
1471 error = TA_sfnt_build_loca_table(sfnt, font);
1472 if (error)
1473 goto Err;
1474 error = TA_sfnt_update_maxp_table(sfnt, font);
1475 if (error)
1476 goto Err;
1479 if (font->num_sfnts == 1)
1480 error = TA_font_build_TTF(font);
1481 else
1482 error = TA_font_build_TTC(font);
1483 if (error)
1484 goto Err;
1486 error = TA_font_write(font, out);
1487 if (error)
1488 goto Err;
1490 error = TA_Err_Ok;
1492 Err:
1493 TA_font_unload(font);
1495 return error;
1498 /* end of ttfautohint.c */