Add code to build `fpgm' table.
[ttfautohint.git] / src / ttfautohint.c
blob96a8a7e25c0c2b0e64e6452a2da336ca0cfe2362
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 continue;
125 /* make the allocated buffer length a multiple of 4 */
126 buf_len = (len + 3) & -3;
127 buf = (FT_Byte*)malloc(buf_len);
128 if (!buf)
129 return FT_Err_Out_Of_Memory;
131 /* pad end of buffer with zeros */
132 buf[buf_len - 1] = 0x00;
133 buf[buf_len - 2] = 0x00;
134 buf[buf_len - 3] = 0x00;
136 /* load table */
137 error = FT_Load_Sfnt_Table(sfnt->face, tag, 0, buf, &len);
138 if (error)
139 goto Err;
141 /* check whether we already have this table */
142 for (j = 0; j < font->num_tables; j++)
144 SFNT_Table* table = &font->tables[j];
147 if (table->tag == tag
148 && table->len == len
149 && !memcmp(table->buf, buf, len))
150 break;
153 if (tag == TTAG_head)
154 sfnt->head_idx = j;
155 else if (tag == TTAG_glyf)
156 sfnt->glyf_idx = j;
157 else if (tag == TTAG_loca)
158 sfnt->loca_idx = j;
159 else if (tag == TTAG_maxp)
160 sfnt->maxp_idx = j;
162 if (j == font->num_tables)
164 /* add element to table array if it is missing or different; */
165 /* in case of success, `buf' gets linked and is eventually */
166 /* freed in `TA_font_unload' */
167 error = TA_font_add_table(font, table_info, tag, len, buf);
168 if (error)
169 goto Err;
171 else
173 /* reuse existing SFNT table */
174 free(buf);
175 *table_info = j;
177 continue;
179 Err:
180 free(buf);
181 return error;
184 /* no (non-empty) `glyf', `loca', `head', or `maxp' table; */
185 /* this can't be a valid TTF with outlines */
186 if (sfnt->glyf_idx == MISSING
187 || sfnt->loca_idx == MISSING
188 || sfnt->head_idx == MISSING
189 || sfnt->maxp_idx == MISSING)
190 return FT_Err_Invalid_Argument;
192 return TA_Err_Ok;
196 static FT_Error
197 TA_glyph_parse_composite(GLYPH* glyph,
198 FT_Byte* buf,
199 FT_ULong len)
201 FT_ULong flags_offset; /* after the loop, this is the offset */
202 /* to the last element in the flags array */
203 FT_UShort flags;
205 FT_Byte* p;
206 FT_Byte* endp;
209 p = buf;
210 endp = buf + len;
212 /* skip header */
213 p += 10;
215 /* walk over component records */
218 if (p + 4 > endp)
219 return FT_Err_Invalid_Table;
221 flags_offset = p - buf;
223 flags = *(p++) << 8;
224 flags += *(p++);
226 /* skip glyph component index */
227 p += 2;
229 /* skip scaling and offset arguments */
230 if (flags & ARGS_ARE_WORDS)
231 p += 4;
232 else
233 p += 2;
235 if (flags & WE_HAVE_A_SCALE)
236 p += 2;
237 else if (flags & WE_HAVE_AN_XY_SCALE)
238 p += 4;
239 else if (flags & WE_HAVE_A_2X2)
240 p += 8;
241 } while (flags & MORE_COMPONENTS);
243 glyph->flags_offset = flags_offset;
245 /* adjust glyph record length */
246 len = p - buf;
248 glyph->len1 = len;
249 /* glyph->len2 = 0; */
250 glyph->buf = (FT_Byte*)malloc(len);
251 if (!glyph->buf)
252 return FT_Err_Out_Of_Memory;
254 /* copy record without instructions (if any) */
255 memcpy(glyph->buf, buf, len);
256 glyph->buf[flags_offset] &= ~(WE_HAVE_INSTR >> 8);
258 return TA_Err_Ok;
262 static FT_Error
263 TA_glyph_parse_simple(GLYPH* glyph,
264 FT_Byte* buf,
265 FT_UShort num_contours,
266 FT_ULong len)
268 FT_ULong ins_offset;
269 FT_Byte* flags_start;
271 FT_UShort num_ins;
272 FT_UShort num_pts;
274 FT_ULong flags_size; /* size of the flags array */
275 FT_ULong xy_size; /* size of x and y coordinate arrays together */
277 FT_Byte* p;
278 FT_Byte* endp;
280 FT_UShort i;
283 p = buf;
284 endp = buf + len;
286 ins_offset = 10 + num_contours * 2;
288 p += ins_offset;
290 if (p + 2 > endp)
291 return FT_Err_Invalid_Table;
293 /* get number of instructions */
294 num_ins = *(p++) << 8;
295 num_ins += *(p++);
297 p += num_ins;
299 if (p > endp)
300 return FT_Err_Invalid_Table;
302 /* get number of points from last outline point */
303 num_pts = buf[ins_offset - 2] << 8;
304 num_pts += buf[ins_offset - 1];
305 num_pts++;
307 flags_start = p;
308 xy_size = 0;
309 i = 0;
311 while (i < num_pts)
313 FT_Byte flags;
314 FT_Byte x_short;
315 FT_Byte y_short;
316 FT_Byte have_x;
317 FT_Byte have_y;
318 FT_Byte count;
321 if (p + 1 > endp)
322 return FT_Err_Invalid_Table;
324 flags = *(p++);
326 x_short = (flags & X_SHORT_VECTOR) ? 1 : 2;
327 y_short = (flags & Y_SHORT_VECTOR) ? 1 : 2;
329 have_x = ((flags & SAME_X) && !(flags & X_SHORT_VECTOR)) ? 0 : 1;
330 have_y = ((flags & SAME_Y) && !(flags & Y_SHORT_VECTOR)) ? 0 : 1;
332 count = 1;
334 if (flags & REPEAT)
336 if (p + 1 > endp)
337 return FT_Err_Invalid_Table;
339 count += *(p++);
341 if (i + count > num_pts)
342 return FT_Err_Invalid_Table;
345 xy_size += count * x_short * have_x;
346 xy_size += count * y_short * have_y;
348 i += count;
351 if (p + xy_size > endp)
352 return FT_Err_Invalid_Table;
354 flags_size = p - flags_start;
356 /* store the data before and after the bytecode instructions */
357 /* in the same array */
358 glyph->len1 = ins_offset;
359 glyph->len2 = flags_size + xy_size;
360 glyph->buf = (FT_Byte*)malloc(glyph->len1 + glyph->len2);
361 if (!glyph->buf)
362 return FT_Err_Out_Of_Memory;
364 /* now copy everything but the instructions */
365 memcpy(glyph->buf, buf, glyph->len1);
366 memcpy(glyph->buf + glyph->len1, flags_start, glyph->len2);
368 return TA_Err_Ok;
372 static FT_Error
373 TA_sfnt_split_glyf_table(SFNT* sfnt,
374 FONT* font)
376 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
377 SFNT_Table* loca_table = &font->tables[sfnt->loca_idx];
378 SFNT_Table* head_table = &font->tables[sfnt->head_idx];
380 glyf_Data* data;
381 FT_Byte loca_format;
383 FT_ULong offset;
384 FT_ULong offset_next;
386 FT_Byte* p;
387 FT_UShort i;
390 /* in case of success, all allocated arrays are */
391 /* linked and eventually freed in `TA_font_unload' */
393 /* nothing to do if table has already been split */
394 if (glyf_table->data)
395 return TA_Err_Ok;
397 data = (glyf_Data*)calloc(1, sizeof (glyf_Data));
398 if (!data)
399 return FT_Err_Out_Of_Memory;
401 glyf_table->data = data;
403 loca_format = head_table->buf[LOCA_FORMAT_OFFSET];
405 data->num_glyphs = loca_format ? loca_table->len / 4 - 1
406 : loca_table->len / 2 - 1;
407 data->glyphs = (GLYPH*)calloc(1, data->num_glyphs * sizeof (GLYPH));
408 if (!data->glyphs)
409 return FT_Err_Out_Of_Memory;
411 p = loca_table->buf;
413 if (loca_format)
415 offset_next = *(p++) << 24;
416 offset_next += *(p++) << 16;
417 offset_next += *(p++) << 8;
418 offset_next += *(p++);
420 else
422 offset_next = *(p++) << 8;
423 offset_next += *(p++);
424 offset_next <<= 1;
427 /* loop over `loca' and `glyf' data */
428 for (i = 0; i < data->num_glyphs; i++)
430 GLYPH* glyph = &data->glyphs[i];
431 FT_ULong len;
434 offset = offset_next;
436 if (loca_format)
438 offset_next = *(p++) << 24;
439 offset_next += *(p++) << 16;
440 offset_next += *(p++) << 8;
441 offset_next += *(p++);
443 else
445 offset_next = *(p++) << 8;
446 offset_next += *(p++);
447 offset_next <<= 1;
450 if (offset_next < offset
451 || offset_next > glyf_table->len)
452 return FT_Err_Invalid_Table;
454 len = offset_next - offset;
455 if (!len)
456 continue; /* empty glyph */
457 else
459 FT_Byte* buf;
460 FT_Short num_contours;
461 FT_Error error;
464 /* check header size */
465 if (len < 10)
466 return FT_Err_Invalid_Table;
468 buf = glyf_table->buf + offset;
469 num_contours = (FT_Short)((buf[0] << 8) + buf[1]);
471 /* We must parse the rest of the glyph record to get the exact */
472 /* record length. Since the `loca' table rounds record lengths */
473 /* up to multiples of 4 (or 2 for older fonts), and we must round */
474 /* up again after stripping off the instructions, it would be */
475 /* possible otherwise to have more than 4 bytes of padding which */
476 /* is more or less invalid. */
478 if (num_contours < 0)
480 error = TA_glyph_parse_composite(glyph, buf, len);
481 if (error)
482 return error;
484 else
486 error = TA_glyph_parse_simple(glyph, buf, num_contours, len);
487 if (error)
488 return error;
493 return TA_Err_Ok;
497 static FT_Error
498 TA_sfnt_build_glyf_table(SFNT* sfnt,
499 FONT* font)
501 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
502 glyf_Data* data = (glyf_Data*)glyf_table->data;
504 GLYPH* glyph;
506 FT_ULong len;
507 FT_Byte* buf_new;
508 FT_Byte* p;
509 FT_UShort i;
512 if (glyf_table->processed)
513 return TA_Err_Ok;
515 /* get table size */
516 len = 0;
517 glyph = data->glyphs;
518 for (i = 0; i < data->num_glyphs; i++, glyph++)
520 /* glyph records should have offsets which are multiples of 4 */
521 len = (len + 3) & ~3;
522 len += glyph->len1 + glyph->len2 + glyph->ins_len;
523 /* add two bytes for the instructionLength field */
524 if (glyph->len2 || glyph->ins_len)
525 len += 2;
528 glyf_table->len = len;
529 buf_new = (FT_Byte*)realloc(glyf_table->buf, (len + 3) & ~3);
530 if (!buf_new)
531 return FT_Err_Out_Of_Memory;
532 else
533 glyf_table->buf = buf_new;
535 p = glyf_table->buf;
536 glyph = data->glyphs;
537 for (i = 0; i < data->num_glyphs; i++, glyph++)
539 len = glyph->len1 + glyph->len2 + glyph->ins_len;
540 if (glyph->len2 || glyph->ins_len)
541 len += 2;
543 if (len)
545 /* copy glyph data and insert new instructions */
546 memcpy(p, glyph->buf, glyph->len1);
548 if (glyph->len2)
550 /* simple glyph */
551 p += glyph->len1;
552 *(p++) = HIGH(glyph->ins_len);
553 *(p++) = LOW(glyph->ins_len);
554 memcpy(p, glyph->ins_buf, glyph->ins_len);
555 p += glyph->ins_len;
556 memcpy(p, glyph->buf + glyph->len1, glyph->len2);
557 p += glyph->len2;
559 else
561 /* composite glyph */
562 if (glyph->ins_len)
564 *(p + glyph->flags_offset) |= (WE_HAVE_INSTR >> 8);
565 p += glyph->len1;
566 *(p++) = HIGH(glyph->ins_len);
567 *(p++) = LOW(glyph->ins_len);
568 memcpy(p, glyph->ins_buf, glyph->ins_len);
569 p += glyph->ins_len;
571 else
572 p += glyph->len1;
575 /* pad with zero bytes to have an offset which is a multiple of 4; */
576 /* this works even for the last glyph record since the `glyf' */
577 /* table length is a multiple of 4 also */
578 switch (len % 4)
580 case 1:
581 *(p++) = 0;
582 case 2:
583 *(p++) = 0;
584 case 3:
585 *(p++) = 0;
586 default:
587 break;
592 glyf_table->checksum = TA_table_compute_checksum(glyf_table->buf,
593 glyf_table->len);
594 glyf_table->processed = 1;
596 return TA_Err_Ok;
600 static FT_Error
601 TA_sfnt_build_loca_table(SFNT* sfnt,
602 FONT* font)
604 SFNT_Table* loca_table = &font->tables[sfnt->loca_idx];
605 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
606 SFNT_Table* head_table = &font->tables[sfnt->head_idx];
608 glyf_Data* data = (glyf_Data*)glyf_table->data;
609 GLYPH* glyph;
611 FT_ULong offset;
612 FT_Byte loca_format;
613 FT_Byte* buf_new;
614 FT_Byte* p;
615 FT_UShort i;
618 if (loca_table->processed)
619 return TA_Err_Ok;
621 /* get largest offset */
622 offset = 0;
623 glyph = data->glyphs;
625 for (i = 0; i < data->num_glyphs; i++, glyph++)
627 /* glyph records should have offsets which are multiples of 4 */
628 offset = (offset + 3) & ~3;
629 offset += glyph->len1 + glyph->len2 + glyph->ins_len;
630 /* add two bytes for the instructionLength field */
631 if (glyph->len2 || glyph->ins_len)
632 offset += 2;
635 if (offset > 0xFFFF * 2)
636 loca_format = 1;
637 else
638 loca_format = 0;
640 /* fill table */
641 if (loca_format)
643 loca_table->len = (data->num_glyphs + 1) * 4;
644 buf_new = (FT_Byte*)realloc(loca_table->buf, loca_table->len);
645 if (!buf_new)
646 return FT_Err_Out_Of_Memory;
647 else
648 loca_table->buf = buf_new;
650 p = loca_table->buf;
651 offset = 0;
652 glyph = data->glyphs;
654 for (i = 0; i < data->num_glyphs; i++, glyph++)
656 offset = (offset + 3) & ~3;
658 *(p++) = BYTE1(offset);
659 *(p++) = BYTE2(offset);
660 *(p++) = BYTE3(offset);
661 *(p++) = BYTE4(offset);
663 offset += glyph->len1 + glyph->len2 + glyph->ins_len;
664 if (glyph->len2 || glyph->ins_len)
665 offset += 2;
668 /* last element holds the size of the `glyf' table */
669 *(p++) = BYTE1(offset);
670 *(p++) = BYTE2(offset);
671 *(p++) = BYTE3(offset);
672 *(p++) = BYTE4(offset);
674 else
676 loca_table->len = (data->num_glyphs + 1) * 2;
677 buf_new = (FT_Byte*)realloc(loca_table->buf,
678 (loca_table->len + 3) & ~3);
679 if (!buf_new)
680 return FT_Err_Out_Of_Memory;
681 else
682 loca_table->buf = buf_new;
684 p = loca_table->buf;
685 offset = 0;
686 glyph = data->glyphs;
688 for (i = 0; i < data->num_glyphs; i++, glyph++)
690 offset = (offset + 1) & ~1;
692 *(p++) = HIGH(offset);
693 *(p++) = LOW(offset);
695 offset += (glyph->len1 + glyph->len2 + glyph->ins_len + 1) >> 1;
696 if (glyph->len2 || glyph->ins_len)
697 offset += 1;
700 /* last element holds the size of the `glyf' table */
701 *(p++) = HIGH(offset);
702 *(p++) = LOW(offset);
704 /* pad `loca' table to make its length a multiple of 4 */
705 if (loca_table->len % 4 == 2)
707 *(p++) = 0;
708 *(p++) = 0;
712 loca_table->checksum = TA_table_compute_checksum(loca_table->buf,
713 loca_table->len);
714 loca_table->processed = 1;
716 head_table->buf[LOCA_FORMAT_OFFSET] = loca_format;
718 return TA_Err_Ok;
722 static FT_Error
723 TA_sfnt_update_maxp_table(SFNT* sfnt,
724 FONT* font)
726 SFNT_Table* maxp_table = &font->tables[sfnt->maxp_idx];
727 FT_Byte* buf = maxp_table->buf;
730 if (maxp_table->processed)
731 return TA_Err_Ok;
733 if (maxp_table->len != MAXP_LEN)
734 return FT_Err_Invalid_Table;
736 buf[MAXP_MAX_ZONES_OFFSET] = 0;
737 buf[MAXP_MAX_ZONES_OFFSET + 1] = 1;
738 buf[MAXP_MAX_TWILIGHT_POINTS_OFFSET] = 0;
739 buf[MAXP_MAX_TWILIGHT_POINTS_OFFSET + 1] = 0;
740 buf[MAXP_MAX_STORAGE_OFFSET] = 0;
741 buf[MAXP_MAX_STORAGE_OFFSET + 1] = 0;
742 buf[MAXP_MAX_FUNCTION_DEFS_OFFSET] = 0;
743 buf[MAXP_MAX_FUNCTION_DEFS_OFFSET + 1] = 0;
744 buf[MAXP_MAX_INSTRUCTION_DEFS_OFFSET] = 0;
745 buf[MAXP_MAX_INSTRUCTION_DEFS_OFFSET + 1] = 0;
746 buf[MAXP_MAX_STACK_ELEMENTS_OFFSET] = 0;
747 buf[MAXP_MAX_STACK_ELEMENTS_OFFSET + 1] = 0;
748 buf[MAXP_MAX_INSTRUCTIONS_OFFSET] = 0;
749 buf[MAXP_MAX_INSTRUCTIONS_OFFSET + 1] = 0;
751 maxp_table->checksum = TA_table_compute_checksum(maxp_table->buf,
752 maxp_table->len);
753 maxp_table->processed = 1;
755 return TA_Err_Ok;
759 /* we build a dummy `DSIG' table only */
761 static FT_Error
762 TA_table_build_DSIG(FT_Byte** DSIG)
764 FT_Byte* buf;
767 buf = (FT_Byte*)malloc(DSIG_LEN);
768 if (!buf)
769 return FT_Err_Out_Of_Memory;
771 /* version */
772 buf[0] = 0x00;
773 buf[1] = 0x00;
774 buf[2] = 0x00;
775 buf[3] = 0x01;
777 /* zero signatures */
778 buf[4] = 0x00;
779 buf[5] = 0x00;
781 /* permission flags */
782 buf[6] = 0x00;
783 buf[7] = 0x00;
785 *DSIG = buf;
787 return TA_Err_Ok;
791 static void
792 TA_font_compute_table_offsets(FONT* font,
793 FT_ULong start)
795 FT_ULong i;
796 FT_ULong offset = start;
799 for (i = 0; i < font->num_tables; i++)
801 SFNT_Table* table = &font->tables[i];
804 table->offset = offset;
806 /* table offsets must be multiples of 4; */
807 /* this also fits the actual buffer lengths */
808 offset += (table->len + 3) & ~3;
813 /* If `do_complete' is 0, only return `header_len'. */
815 static FT_Error
816 TA_sfnt_build_TTF_header(SFNT* sfnt,
817 FONT* font,
818 FT_Byte** header_buf,
819 FT_ULong* header_len,
820 FT_Int do_complete)
822 SFNT_Table* tables = font->tables;
824 SFNT_Table_Info* table_infos = sfnt->table_infos;
825 FT_ULong num_table_infos = sfnt->num_table_infos;
827 FT_Byte* buf;
828 FT_ULong len;
830 FT_Byte* table_record;
832 FT_Byte* head_buf = NULL; /* pointer to `head' table */
833 FT_ULong head_checksum; /* checksum in `head' table */
835 FT_ULong num_tables_in_header;
836 FT_ULong i;
839 num_tables_in_header = 0;
840 for (i = 0; i < num_table_infos; i++)
842 /* ignore empty tables */
843 if (table_infos[i] != MISSING)
844 num_tables_in_header++;
847 len = 12 + 16 * num_tables_in_header;
848 if (!do_complete)
850 *header_len = len;
851 return TA_Err_Ok;
853 buf = (FT_Byte*)malloc(len);
854 if (!buf)
855 return FT_Err_Out_Of_Memory;
857 /* SFNT version */
858 buf[0] = 0x00;
859 buf[1] = 0x01;
860 buf[2] = 0x00;
861 buf[3] = 0x00;
863 /* number of tables */
864 buf[4] = HIGH(num_tables_in_header);
865 buf[5] = LOW(num_tables_in_header);
867 /* auxiliary data */
869 FT_ULong search_range, entry_selector, range_shift;
870 FT_ULong i, j;
873 for (i = 1, j = 2; j <= num_tables_in_header; i++, j <<= 1)
876 entry_selector = i - 1;
877 search_range = 0x10 << entry_selector;
878 range_shift = (num_tables_in_header << 4) - search_range;
880 buf[6] = HIGH(search_range);
881 buf[7] = LOW(search_range);
882 buf[8] = HIGH(entry_selector);
883 buf[9] = LOW(entry_selector);
884 buf[10] = HIGH(range_shift);
885 buf[11] = LOW(range_shift);
888 /* location of the first table info record */
889 table_record = &buf[12];
891 head_checksum = 0;
893 /* loop over all tables */
894 for (i = 0; i < num_table_infos; i++)
896 SFNT_Table_Info table_info = table_infos[i];
897 SFNT_Table* table;
900 /* ignore empty slots */
901 if (table_info == MISSING)
902 continue;
904 table = &tables[table_info];
906 if (table->tag == TTAG_head)
908 /* we always reach this IF clause since FreeType would */
909 /* have aborted already if the `head' table were missing */
911 head_buf = table->buf;
913 /* reset checksum in `head' table for recalculation */
914 head_buf[8] = 0x00;
915 head_buf[9] = 0x00;
916 head_buf[10] = 0x00;
917 head_buf[11] = 0x00;
920 head_checksum += table->checksum;
922 table_record[0] = BYTE1(table->tag);
923 table_record[1] = BYTE2(table->tag);
924 table_record[2] = BYTE3(table->tag);
925 table_record[3] = BYTE4(table->tag);
927 table_record[4] = BYTE1(table->checksum);
928 table_record[5] = BYTE2(table->checksum);
929 table_record[6] = BYTE3(table->checksum);
930 table_record[7] = BYTE4(table->checksum);
932 table_record[8] = BYTE1(table->offset);
933 table_record[9] = BYTE2(table->offset);
934 table_record[10] = BYTE3(table->offset);
935 table_record[11] = BYTE4(table->offset);
937 table_record[12] = BYTE1(table->len);
938 table_record[13] = BYTE2(table->len);
939 table_record[14] = BYTE3(table->len);
940 table_record[15] = BYTE4(table->len);
942 table_record += 16;
945 /* the font header is complete; compute `head' checksum */
946 head_checksum += TA_table_compute_checksum(buf, len);
947 head_checksum = 0xB1B0AFBAUL - head_checksum;
949 /* store checksum in `head' table; */
950 head_buf[8] = BYTE1(head_checksum);
951 head_buf[9] = BYTE2(head_checksum);
952 head_buf[10] = BYTE3(head_checksum);
953 head_buf[11] = BYTE4(head_checksum);
955 *header_buf = buf;
956 *header_len = len;
958 return TA_Err_Ok;
962 static FT_Error
963 TA_font_build_TTF(FONT* font)
965 SFNT* sfnt = &font->sfnts[0];
967 SFNT_Table* tables;
968 FT_ULong num_tables;
970 FT_ULong SFNT_offset;
972 FT_Byte* DSIG_buf;
974 FT_Byte* header_buf;
975 FT_ULong header_len;
977 FT_ULong i;
978 FT_Error error;
981 /* add a dummy `DSIG' table */
983 error = TA_sfnt_add_table_info(sfnt);
984 if (error)
985 return error;
987 error = TA_table_build_DSIG(&DSIG_buf);
988 if (error)
989 return error;
991 /* in case of success, `DSIG_buf' gets linked */
992 /* and is eventually freed in `TA_font_unload' */
993 error = TA_font_add_table(font,
994 &sfnt->table_infos[sfnt->num_table_infos - 1],
995 TTAG_DSIG, DSIG_LEN, DSIG_buf);
996 if (error)
998 free(DSIG_buf);
999 return error;
1002 TA_sfnt_sort_table_info(sfnt, font);
1004 /* the first SFNT table immediately follows the header */
1005 (void)TA_sfnt_build_TTF_header(sfnt, font, NULL, &SFNT_offset, 0);
1006 TA_font_compute_table_offsets(font, SFNT_offset);
1008 error = TA_sfnt_build_TTF_header(sfnt, font,
1009 &header_buf, &header_len, 1);
1010 if (error)
1011 return error;
1013 /* build font */
1015 tables = font->tables;
1016 num_tables = font->num_tables;
1018 /* get font length from last SFNT table array element */
1019 font->out_len = tables[num_tables - 1].offset
1020 + ((tables[num_tables - 1].len + 3) & ~3);
1021 font->out_buf = (FT_Byte*)malloc(font->out_len);
1022 if (!font->out_buf)
1024 error = FT_Err_Out_Of_Memory;
1025 goto Err;
1028 memcpy(font->out_buf, header_buf, header_len);
1030 for (i = 0; i < num_tables; i++)
1032 SFNT_Table* table = &tables[i];
1035 /* buffer length is a multiple of 4 */
1036 memcpy(font->out_buf + table->offset,
1037 table->buf, (table->len + 3) & ~3);
1040 error = TA_Err_Ok;
1042 Err:
1043 free(header_buf);
1045 return error;
1049 static FT_Error
1050 TA_font_build_TTC_header(FONT* font,
1051 FT_Byte** header_buf,
1052 FT_ULong* header_len)
1054 SFNT* sfnts = font->sfnts;
1055 FT_Long num_sfnts = font->num_sfnts;
1057 SFNT_Table* tables = font->tables;
1058 FT_ULong num_tables = font->num_tables;
1060 FT_ULong TTF_offset;
1061 FT_ULong DSIG_offset;
1063 FT_Byte* buf;
1064 FT_ULong len;
1066 FT_Long i;
1067 FT_Byte* p;
1070 len = 24 + 4 * num_sfnts;
1071 buf = (FT_Byte*)malloc(len);
1072 if (!buf)
1073 return FT_Err_Out_Of_Memory;
1075 p = buf;
1077 /* TTC ID string */
1078 *(p++) = 't';
1079 *(p++) = 't';
1080 *(p++) = 'c';
1081 *(p++) = 'f';
1083 /* TTC header version */
1084 *(p++) = 0x00;
1085 *(p++) = 0x02;
1086 *(p++) = 0x00;
1087 *(p++) = 0x00;
1089 /* number of subfonts */
1090 *(p++) = BYTE1(num_sfnts);
1091 *(p++) = BYTE2(num_sfnts);
1092 *(p++) = BYTE3(num_sfnts);
1093 *(p++) = BYTE4(num_sfnts);
1095 /* the first TTF subfont header immediately follows the TTC header */
1096 TTF_offset = len;
1098 /* loop over all subfonts */
1099 for (i = 0; i < num_sfnts; i++)
1101 SFNT* sfnt = &sfnts[i];
1102 FT_ULong l;
1105 TA_sfnt_sort_table_info(sfnt, font);
1106 /* only get header length */
1107 (void)TA_sfnt_build_TTF_header(sfnt, font, NULL, &l, 0);
1109 *(p++) = BYTE1(TTF_offset);
1110 *(p++) = BYTE2(TTF_offset);
1111 *(p++) = BYTE3(TTF_offset);
1112 *(p++) = BYTE4(TTF_offset);
1114 TTF_offset += l;
1117 /* the first SFNT table immediately follows the subfont TTF headers */
1118 TA_font_compute_table_offsets(font, TTF_offset);
1120 /* DSIG tag */
1121 *(p++) = 'D';
1122 *(p++) = 'S';
1123 *(p++) = 'I';
1124 *(p++) = 'G';
1126 /* DSIG length */
1127 *(p++) = 0x00;
1128 *(p++) = 0x00;
1129 *(p++) = 0x00;
1130 *(p++) = 0x08;
1132 /* DSIG offset; in a TTC this is always the last SFNT table */
1133 DSIG_offset = tables[num_tables - 1].offset;
1135 *(p++) = BYTE1(DSIG_offset);
1136 *(p++) = BYTE2(DSIG_offset);
1137 *(p++) = BYTE3(DSIG_offset);
1138 *(p++) = BYTE4(DSIG_offset);
1140 *header_buf = buf;
1141 *header_len = len;
1143 return TA_Err_Ok;
1147 static FT_Error
1148 TA_font_build_TTC(FONT* font)
1150 SFNT* sfnts = font->sfnts;
1151 FT_Long num_sfnts = font->num_sfnts;
1153 SFNT_Table* tables;
1154 FT_ULong num_tables;
1156 FT_Byte* DSIG_buf;
1157 SFNT_Table_Info dummy;
1159 FT_Byte* TTC_header_buf;
1160 FT_ULong TTC_header_len;
1162 FT_Byte** TTF_header_bufs;
1163 FT_ULong* TTF_header_lens;
1165 FT_ULong offset;
1166 FT_Long i;
1167 FT_ULong j;
1168 FT_Error error;
1171 /* add a dummy `DSIG' table */
1173 error = TA_table_build_DSIG(&DSIG_buf);
1174 if (error)
1175 return error;
1177 /* in case of success, `DSIG_buf' gets linked */
1178 /* and is eventually freed in `TA_font_unload' */
1179 error = TA_font_add_table(font, &dummy, TTAG_DSIG, DSIG_LEN, DSIG_buf);
1180 if (error)
1182 free(DSIG_buf);
1183 return error;
1186 /* this also computes the SFNT table offsets */
1187 error = TA_font_build_TTC_header(font,
1188 &TTC_header_buf, &TTC_header_len);
1189 if (error)
1190 return error;
1192 TTF_header_bufs = (FT_Byte**)calloc(1, num_sfnts * sizeof (FT_Byte*));
1193 if (!TTF_header_bufs)
1194 goto Err;
1196 TTF_header_lens = (FT_ULong*)malloc(num_sfnts * sizeof (FT_ULong));
1197 if (!TTF_header_lens)
1198 goto Err;
1200 for (i = 0; i < num_sfnts; i++)
1202 error = TA_sfnt_build_TTF_header(&sfnts[i], font,
1203 &TTF_header_bufs[i],
1204 &TTF_header_lens[i], 1);
1205 if (error)
1206 goto Err;
1209 /* build font */
1211 tables = font->tables;
1212 num_tables = font->num_tables;
1214 /* get font length from last SFNT table array element */
1215 font->out_len = tables[num_tables - 1].offset
1216 + ((tables[num_tables - 1].len + 3) & ~3);
1217 font->out_buf = (FT_Byte*)malloc(font->out_len);
1218 if (!font->out_buf)
1220 error = FT_Err_Out_Of_Memory;
1221 goto Err;
1224 memcpy(font->out_buf, TTC_header_buf, TTC_header_len);
1226 offset = TTC_header_len;
1228 for (i = 0; i < num_sfnts; i++)
1230 memcpy(font->out_buf + offset,
1231 TTF_header_bufs[i], TTF_header_lens[i]);
1233 offset += TTF_header_lens[i];
1236 for (j = 0; j < num_tables; j++)
1238 SFNT_Table* table = &tables[j];
1241 /* buffer length is a multiple of 4 */
1242 memcpy(font->out_buf + table->offset,
1243 table->buf, (table->len + 3) & ~3);
1246 error = TA_Err_Ok;
1248 Err:
1249 free(TTC_header_buf);
1250 if (TTF_header_bufs)
1252 for (i = 0; i < font->num_sfnts; i++)
1253 free(TTF_header_bufs[i]);
1254 free(TTF_header_bufs);
1256 free(TTF_header_lens);
1258 return error;
1262 static FT_Error
1263 TA_font_write(FONT* font,
1264 FILE* out)
1266 if (fwrite(font->out_buf, 1, font->out_len, out) != font->out_len)
1267 return TA_Err_Invalid_Stream_Write;
1269 return TA_Err_Ok;
1273 static void
1274 TA_font_unload(FONT* font)
1276 /* in case of error it is expected that unallocated pointers */
1277 /* are NULL (and counters are zero) */
1279 if (!font)
1280 return;
1282 if (font->loader)
1283 ta_loader_done(font->loader);
1285 if (font->tables)
1287 FT_ULong i;
1290 for (i = 0; i < font->num_tables; i++)
1292 free(font->tables[i].buf);
1293 if (font->tables[i].data)
1295 if (font->tables[i].tag == TTAG_glyf)
1297 glyf_Data* data = (glyf_Data*)font->tables[i].data;
1298 FT_UShort j;
1301 for (j = 0; j < data->num_glyphs; j++)
1302 free(data->glyphs[j].buf);
1303 free(data->glyphs);
1304 free(data);
1308 free(font->tables);
1311 if (font->sfnts)
1313 FT_Long i;
1316 for (i = 0; i < font->num_sfnts; i++)
1318 FT_Done_Face(font->sfnts[i].face);
1319 free(font->sfnts[i].table_infos);
1321 free(font->sfnts);
1324 FT_Done_FreeType(font->lib);
1325 free(font->in_buf);
1326 free(font->out_buf);
1327 free(font);
1331 TA_Error
1332 TTF_autohint(FILE* in,
1333 FILE* out)
1335 FONT* font;
1336 FT_Error error;
1337 FT_Long i;
1340 font = (FONT*)calloc(1, sizeof (FONT));
1341 if (!font)
1342 return FT_Err_Out_Of_Memory;
1344 error = TA_font_read(font, in);
1345 if (error)
1346 goto Err;
1348 error = TA_font_init(font);
1349 if (error)
1350 goto Err;
1352 /* loop over subfonts */
1353 for (i = 0; i < font->num_sfnts; i++)
1355 SFNT* sfnt = &font->sfnts[i];
1358 error = FT_New_Memory_Face(font->lib, font->in_buf, font->in_len,
1359 i, &sfnt->face);
1360 if (error)
1361 goto Err;
1363 error = TA_sfnt_split_into_SFNT_tables(sfnt, font);
1364 if (error)
1365 goto Err;
1367 error = TA_sfnt_split_glyf_table(sfnt, font);
1368 if (error)
1369 goto Err;
1372 /* XXX handle subfonts for bytecode tables? */
1374 /* build `cvt ' table */
1375 error = TA_sfnt_build_cvt_table(&font->sfnts[0], font);
1376 if (error)
1377 goto Err;
1379 /* build `fpgm' table */
1380 error = TA_sfnt_build_fpgm_table(&font->sfnts[0], font);
1381 if (error)
1382 goto Err;
1384 /* build `prep' table */
1386 /* handle all glyphs in a loop */
1387 /* hint the glyph */
1388 /* build bytecode */
1390 /* adjust `maxp' table */
1392 /* loop again over subfonts */
1393 for (i = 0; i < font->num_sfnts; i++)
1395 SFNT* sfnt = &font->sfnts[i];
1398 error = TA_sfnt_build_glyf_table(sfnt, font);
1399 if (error)
1400 goto Err;
1401 error = TA_sfnt_build_loca_table(sfnt, font);
1402 if (error)
1403 goto Err;
1404 error = TA_sfnt_update_maxp_table(sfnt, font);
1405 if (error)
1406 goto Err;
1409 if (font->num_sfnts == 1)
1410 error = TA_font_build_TTF(font);
1411 else
1412 error = TA_font_build_TTC(font);
1413 if (error)
1414 goto Err;
1416 error = TA_font_write(font, out);
1417 if (error)
1418 goto Err;
1420 error = TA_Err_Ok;
1422 Err:
1423 TA_font_unload(font);
1425 return error;
1428 /* end of ttfautohint.c */