Recompute more fields of the `maxp' table.
[ttfautohint.git] / src / taglyf.c
blob4a16ee56b7322342cf44058c56b52c7ac47d87af
1 /* taglyf.c */
3 /*
4 * Copyright (C) 2011 by Werner Lemberg.
6 * This file is part of the ttfautohint library, and may only be used,
7 * modified, and distributed under the terms given in `COPYING'. By
8 * continuing to use, modify, or distribute this file you indicate that you
9 * have read `COPYING' and understand and accept it fully.
11 * The file `COPYING' mentioned in the previous paragraph is distributed
12 * with the ttfautohint library.
16 #include "ta.h"
19 FT_Error
20 TA_sfnt_build_glyf_hints(SFNT* sfnt,
21 FONT* font)
23 FT_Face face = sfnt->face;
24 FT_Long idx;
25 FT_Error error;
28 for (idx = 0; idx < face->num_glyphs; idx++)
30 error = TA_sfnt_build_glyph_instructions(sfnt, font, idx);
31 if (error)
32 return error;
33 if (font->progress)
34 font->progress(idx, face->num_glyphs,
35 sfnt - font->sfnts, font->num_sfnts,
36 font->progress_data);
39 return FT_Err_Ok;
43 static FT_Error
44 TA_glyph_parse_composite(GLYPH* glyph,
45 FT_Byte* buf,
46 FT_ULong len)
48 FT_ULong flags_offset; /* after the loop, this is the offset */
49 /* to the last element in the flags array */
50 FT_UShort flags;
51 FT_UShort component;
52 FT_UShort* components_new;
54 FT_Byte* p;
55 FT_Byte* endp;
58 p = buf;
59 endp = buf + len;
61 /* skip header */
62 p += 10;
64 /* walk over component records */
67 if (p + 4 > endp)
68 return FT_Err_Invalid_Table;
70 flags_offset = p - buf;
72 flags = *(p++) << 8;
73 flags += *(p++);
75 /* add component to list */
76 component = *(p++) << 8;
77 component += *(p++);
79 glyph->num_components++;
80 components_new = (FT_UShort*)realloc(glyph->components,
81 glyph->num_components
82 * sizeof (FT_UShort));
83 if (!components_new)
85 glyph->num_components--;
86 return FT_Err_Out_Of_Memory;
88 else
89 glyph->components = components_new;
91 glyph->components[glyph->num_components - 1] = component;
93 /* skip scaling and offset arguments */
94 if (flags & ARGS_ARE_WORDS)
95 p += 4;
96 else
97 p += 2;
99 if (flags & WE_HAVE_A_SCALE)
100 p += 2;
101 else if (flags & WE_HAVE_AN_XY_SCALE)
102 p += 4;
103 else if (flags & WE_HAVE_A_2X2)
104 p += 8;
105 } while (flags & MORE_COMPONENTS);
107 glyph->flags_offset = flags_offset;
109 /* adjust glyph record length */
110 len = p - buf;
112 glyph->len1 = len;
113 /* glyph->len2 = 0; */
114 glyph->buf = (FT_Byte*)malloc(len);
115 if (!glyph->buf)
116 return FT_Err_Out_Of_Memory;
118 /* copy record without instructions (if any) */
119 memcpy(glyph->buf, buf, len);
120 glyph->buf[flags_offset] &= ~(WE_HAVE_INSTR >> 8);
122 return TA_Err_Ok;
126 static FT_Error
127 TA_glyph_parse_simple(GLYPH* glyph,
128 FT_Byte* buf,
129 FT_UShort num_contours,
130 FT_ULong len)
132 FT_ULong ins_offset;
133 FT_Byte* flags_start;
135 FT_UShort num_ins;
136 FT_UShort num_pts;
138 FT_ULong flags_size; /* size of the flags array */
139 FT_ULong xy_size; /* size of x and y coordinate arrays together */
141 FT_Byte* p;
142 FT_Byte* endp;
144 FT_UShort i;
147 p = buf;
148 endp = buf + len;
150 ins_offset = 10 + num_contours * 2;
152 p += ins_offset;
154 if (p + 2 > endp)
155 return FT_Err_Invalid_Table;
157 /* get number of instructions */
158 num_ins = *(p++) << 8;
159 num_ins += *(p++);
161 p += num_ins;
163 if (p > endp)
164 return FT_Err_Invalid_Table;
166 /* get number of points from last outline point */
167 num_pts = buf[ins_offset - 2] << 8;
168 num_pts += buf[ins_offset - 1];
169 num_pts++;
171 flags_start = p;
172 xy_size = 0;
173 i = 0;
175 while (i < num_pts)
177 FT_Byte flags;
178 FT_Byte x_short;
179 FT_Byte y_short;
180 FT_Byte have_x;
181 FT_Byte have_y;
182 FT_Byte count;
185 if (p + 1 > endp)
186 return FT_Err_Invalid_Table;
188 flags = *(p++);
190 x_short = (flags & X_SHORT_VECTOR) ? 1 : 2;
191 y_short = (flags & Y_SHORT_VECTOR) ? 1 : 2;
193 have_x = ((flags & SAME_X) && !(flags & X_SHORT_VECTOR)) ? 0 : 1;
194 have_y = ((flags & SAME_Y) && !(flags & Y_SHORT_VECTOR)) ? 0 : 1;
196 count = 1;
198 if (flags & REPEAT)
200 if (p + 1 > endp)
201 return FT_Err_Invalid_Table;
203 count += *(p++);
205 if (i + count > num_pts)
206 return FT_Err_Invalid_Table;
209 xy_size += count * x_short * have_x;
210 xy_size += count * y_short * have_y;
212 i += count;
215 if (p + xy_size > endp)
216 return FT_Err_Invalid_Table;
218 flags_size = p - flags_start;
220 /* store the data before and after the bytecode instructions */
221 /* in the same array */
222 glyph->len1 = ins_offset;
223 glyph->len2 = flags_size + xy_size;
224 glyph->buf = (FT_Byte*)malloc(glyph->len1 + glyph->len2);
225 if (!glyph->buf)
226 return FT_Err_Out_Of_Memory;
228 /* now copy everything but the instructions */
229 memcpy(glyph->buf, buf, glyph->len1);
230 memcpy(glyph->buf + glyph->len1, flags_start, glyph->len2);
232 return TA_Err_Ok;
236 static FT_Error
237 TA_iterate_composite_glyph(glyf_Data* data,
238 FT_UShort* components,
239 FT_UShort num_components,
240 FT_UShort** endpoints,
241 FT_UShort* num_endpoints,
242 FT_UShort* num_composite_contours)
244 FT_UShort i;
247 for (i = 0; i < num_components; i++)
249 GLYPH* glyph;
250 FT_UShort component = components[i];
251 FT_Error error;
254 if (component >= data->num_glyphs)
255 return FT_Err_Invalid_Table;
257 glyph = &data->glyphs[component];
259 if (glyph->num_components)
261 error = TA_iterate_composite_glyph(data,
262 glyph->components,
263 glyph->num_components,
264 endpoints,
265 num_endpoints,
266 num_composite_contours);
267 if (error)
268 return error;
270 else
272 FT_UShort num_contours;
273 FT_UShort endpoint;
274 FT_UShort* endpoints_new;
277 /* collect end points of simple glyphs */
279 num_contours = glyph->buf[0] << 8;
280 num_contours += glyph->buf[1];
281 endpoint = glyph->buf[10 + (num_contours - 1) * 2] << 8;
282 endpoint += glyph->buf[10 + (num_contours - 1) * 2 + 1];
284 (*num_endpoints)++;
285 endpoints_new = (FT_UShort*)realloc(*endpoints,
286 *num_endpoints
287 * sizeof (FT_UShort));
288 if (!endpoints_new)
290 (*num_endpoints)--;
291 return FT_Err_Out_Of_Memory;
293 else
294 *endpoints = endpoints_new;
296 (*endpoints)[*num_endpoints - 1] = endpoint;
297 if (*num_endpoints > 1)
298 (*endpoints)[*num_endpoints - 1]
299 += (*endpoints)[*num_endpoints - 2] + 1;
301 *num_composite_contours += num_contours;
305 return TA_Err_Ok;
309 static FT_Error
310 TA_sfnt_compute_composite_endpoints(SFNT* sfnt,
311 FONT* font)
313 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
314 glyf_Data* data = (glyf_Data*)glyf_table->data;
316 FT_UShort i;
319 for (i = 0; i < data->num_glyphs; i++)
321 GLYPH* glyph = &data->glyphs[i];
324 if (glyph->num_components)
326 FT_Error error;
327 FT_UShort num_composite_contours = 0;
330 error = TA_iterate_composite_glyph(data,
331 glyph->components,
332 glyph->num_components,
333 &glyph->endpoints,
334 &glyph->num_endpoints,
335 &num_composite_contours);
336 if (error)
337 return error;
339 if (glyph->endpoints[glyph->num_endpoints - 1] + 1
340 > sfnt->max_composite_points)
341 sfnt->max_composite_points =
342 glyph->endpoints[glyph->num_endpoints - 1] + 1;
343 if (num_composite_contours > sfnt->max_composite_contours)
344 sfnt->max_composite_contours = num_composite_contours;
348 return TA_Err_Ok;
352 FT_Error
353 TA_sfnt_split_glyf_table(SFNT* sfnt,
354 FONT* font)
356 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
357 SFNT_Table* loca_table = &font->tables[sfnt->loca_idx];
358 SFNT_Table* head_table = &font->tables[sfnt->head_idx];
360 glyf_Data* data;
361 FT_Byte loca_format;
363 FT_ULong offset;
364 FT_ULong offset_next;
366 FT_Byte* p;
367 FT_UShort i;
369 FT_Error error;
372 /* in case of success, all allocated arrays are */
373 /* linked and eventually freed in `TA_font_unload' */
375 /* nothing to do if table has already been split */
376 if (glyf_table->data)
377 return TA_Err_Ok;
379 data = (glyf_Data*)calloc(1, sizeof (glyf_Data));
380 if (!data)
381 return FT_Err_Out_Of_Memory;
383 glyf_table->data = data;
385 loca_format = head_table->buf[LOCA_FORMAT_OFFSET];
387 data->num_glyphs = loca_format ? loca_table->len / 4 - 1
388 : loca_table->len / 2 - 1;
389 data->glyphs = (GLYPH*)calloc(1, data->num_glyphs * sizeof (GLYPH));
390 if (!data->glyphs)
391 return FT_Err_Out_Of_Memory;
393 p = loca_table->buf;
395 if (loca_format)
397 offset_next = *(p++) << 24;
398 offset_next += *(p++) << 16;
399 offset_next += *(p++) << 8;
400 offset_next += *(p++);
402 else
404 offset_next = *(p++) << 8;
405 offset_next += *(p++);
406 offset_next <<= 1;
409 /* loop over `loca' and `glyf' data */
410 for (i = 0; i < data->num_glyphs; i++)
412 GLYPH* glyph = &data->glyphs[i];
413 FT_ULong len;
416 offset = offset_next;
418 if (loca_format)
420 offset_next = *(p++) << 24;
421 offset_next += *(p++) << 16;
422 offset_next += *(p++) << 8;
423 offset_next += *(p++);
425 else
427 offset_next = *(p++) << 8;
428 offset_next += *(p++);
429 offset_next <<= 1;
432 if (offset_next < offset
433 || offset_next > glyf_table->len)
434 return FT_Err_Invalid_Table;
436 len = offset_next - offset;
437 if (!len)
438 continue; /* empty glyph */
439 else
441 FT_Byte* buf;
442 FT_Short num_contours;
445 /* check header size */
446 if (len < 10)
447 return FT_Err_Invalid_Table;
449 buf = glyf_table->buf + offset;
450 num_contours = (FT_Short)((buf[0] << 8) + buf[1]);
452 /* We must parse the rest of the glyph record to get the exact */
453 /* record length. Since the `loca' table rounds record lengths */
454 /* up to multiples of 4 (or 2 for older fonts), and we must round */
455 /* up again after stripping off the instructions, it would be */
456 /* possible otherwise to have more than 4 bytes of padding which */
457 /* is more or less invalid. */
459 if (num_contours < 0)
460 error = TA_glyph_parse_composite(glyph, buf, len);
461 else
462 error = TA_glyph_parse_simple(glyph, buf, num_contours, len);
463 if (error)
464 return error;
468 if (sfnt->max_components)
470 error = TA_sfnt_compute_composite_endpoints(sfnt, font);
471 if (error)
472 return error;
475 return TA_Err_Ok;
479 FT_Error
480 TA_sfnt_build_glyf_table(SFNT* sfnt,
481 FONT* font)
483 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
484 glyf_Data* data = (glyf_Data*)glyf_table->data;
486 GLYPH* glyph;
488 FT_ULong len;
489 FT_Byte* buf_new;
490 FT_Byte* p;
491 FT_UShort i;
494 if (glyf_table->processed)
495 return TA_Err_Ok;
497 /* get table size */
498 len = 0;
499 glyph = data->glyphs;
500 for (i = 0; i < data->num_glyphs; i++, glyph++)
502 /* glyph records should have offsets which are multiples of 4 */
503 len = (len + 3) & ~3;
504 len += glyph->len1 + glyph->len2 + glyph->ins_len;
505 /* add two bytes for the instructionLength field */
506 if (glyph->len2 || glyph->ins_len)
507 len += 2;
510 /* to make the short format of the `loca' table always work, */
511 /* assure an even length of the `glyf' table */
512 glyf_table->len = (len + 1) & ~1;
514 buf_new = (FT_Byte*)realloc(glyf_table->buf, (len + 3) & ~3);
515 if (!buf_new)
516 return FT_Err_Out_Of_Memory;
517 else
518 glyf_table->buf = buf_new;
520 p = glyf_table->buf;
521 glyph = data->glyphs;
522 for (i = 0; i < data->num_glyphs; i++, glyph++)
524 len = glyph->len1 + glyph->len2 + glyph->ins_len;
525 if (glyph->len2 || glyph->ins_len)
526 len += 2;
528 if (len)
530 /* copy glyph data and insert new instructions */
531 memcpy(p, glyph->buf, glyph->len1);
533 if (glyph->len2)
535 /* simple glyph */
536 p += glyph->len1;
537 *(p++) = HIGH(glyph->ins_len);
538 *(p++) = LOW(glyph->ins_len);
539 memcpy(p, glyph->ins_buf, glyph->ins_len);
540 p += glyph->ins_len;
541 memcpy(p, glyph->buf + glyph->len1, glyph->len2);
542 p += glyph->len2;
544 else
546 /* composite glyph */
547 if (glyph->ins_len)
549 *(p + glyph->flags_offset) |= (WE_HAVE_INSTR >> 8);
550 p += glyph->len1;
551 *(p++) = HIGH(glyph->ins_len);
552 *(p++) = LOW(glyph->ins_len);
553 memcpy(p, glyph->ins_buf, glyph->ins_len);
554 p += glyph->ins_len;
556 else
557 p += glyph->len1;
560 /* pad with zero bytes to have an offset which is a multiple of 4; */
561 /* this works even for the last glyph record since the `glyf' */
562 /* table length is a multiple of 4 also */
563 switch (len % 4)
565 case 1:
566 *(p++) = 0;
567 case 2:
568 *(p++) = 0;
569 case 3:
570 *(p++) = 0;
571 default:
572 break;
577 glyf_table->checksum = TA_table_compute_checksum(glyf_table->buf,
578 glyf_table->len);
579 glyf_table->processed = 1;
581 return TA_Err_Ok;
585 static FT_Error
586 TA_create_glyph_data(FT_Outline* outline,
587 GLYPH* glyph)
589 FT_Error error = TA_Err_Ok;
591 FT_Pos xmin, ymin;
592 FT_Pos xmax, ymax;
594 FT_Byte header[10];
595 FT_Byte* flags = NULL;
596 FT_Byte* flagsp;
597 FT_Byte oldf, f;
598 FT_Byte* x = NULL;
599 FT_Byte* xp;
600 FT_Byte* y = NULL;
601 FT_Byte* yp;
603 FT_Pos lastx, lasty;
605 FT_Short i;
606 FT_Byte* p;
609 if (!outline->n_contours)
610 return TA_Err_Ok; /* empty glyph */
612 /* in case of success, all non-local allocated arrays are */
613 /* linked and eventually freed in `TA_font_unload' */
615 glyph->buf = NULL;
617 /* we use `calloc' since we rely on the array */
618 /* being initialized to zero; */
619 /* additionally, we need one more byte for a test after the loop */
620 flags = (FT_Byte*)calloc(1, outline->n_points + 1);
621 if (!flags)
623 error = FT_Err_Out_Of_Memory;
624 goto Exit;
627 /* we have either one-byte or two-byte elements */
628 x = (FT_Byte*)malloc(2 * outline->n_points);
629 if (!x)
631 error = FT_Err_Out_Of_Memory;
632 goto Exit;
635 y = (FT_Byte*)malloc(2 * outline->n_points);
636 if (!y)
638 error = FT_Err_Out_Of_Memory;
639 goto Exit;
642 flagsp = flags;
643 xp = x;
644 yp = y;
645 xmin = xmax = (outline->points[0].x + 32) >> 6;
646 ymin = ymax = (outline->points[0].y + 32) >> 6;
647 lastx = 0;
648 lasty = 0;
649 oldf = 0x80; /* start with an impossible value */
651 /* convert the FreeType representation of the glyph's outline */
652 /* into the representation format of the `glyf' table */
653 for (i = 0; i < outline->n_points; i++)
655 FT_Pos xcur = (outline->points[i].x + 32) >> 6;
656 FT_Pos ycur = (outline->points[i].y + 32) >> 6;
658 FT_Pos xdelta = xcur - lastx;
659 FT_Pos ydelta = ycur - lasty;
662 /* we are only interested in bit 0 of the `tags' array */
663 f = outline->tags[i] & ON_CURVE;
665 /* x value */
667 if (xdelta == 0)
668 f |= SAME_X;
669 else
671 if (xdelta < 256 && xdelta > -256)
673 f |= X_SHORT_VECTOR;
675 if (xdelta < 0)
676 xdelta = -xdelta;
677 else
678 f |= SAME_X;
680 *(xp++) = (FT_Byte)xdelta;
682 else
684 *(xp++) = HIGH(xdelta);
685 *(xp++) = LOW(xdelta);
689 /* y value */
691 if (ydelta == 0)
692 f |= SAME_Y;
693 else
695 if (ydelta < 256 && ydelta > -256)
697 f |= Y_SHORT_VECTOR;
699 if (ydelta < 0)
700 ydelta = -ydelta;
701 else
702 f |= SAME_Y;
704 *(yp++) = (FT_Byte)ydelta;
706 else
708 *(yp++) = HIGH(ydelta);
709 *(yp++) = LOW(ydelta);
713 if (f == oldf)
715 /* set repeat flag */
716 *(flagsp - 1) |= REPEAT;
718 if (*flagsp == 255)
720 /* we can only handle 256 repetitions at once, */
721 /* so use a new counter */
722 flagsp++;
723 *(flagsp++) = f;
725 else
726 *flagsp += 1; /* increase repetition counter */
728 else
730 if (*flagsp)
731 flagsp++; /* skip repetition counter */
732 *(flagsp++) = f;
733 oldf = f;
736 if (xcur > xmax)
737 xmax = xcur;
738 if (ycur > ymax)
739 ymax = ycur;
740 if (xcur < xmin)
741 xmin = xcur;
742 if (ycur < ymin)
743 ymin = ycur;
745 lastx = xcur;
746 lasty = ycur;
749 /* if the last byte was a repetition counter, */
750 /* we must increase by one to get the correct array size */
751 if (*flagsp)
752 flagsp++;
754 header[0] = HIGH(outline->n_contours);
755 header[1] = LOW(outline->n_contours);
756 header[2] = HIGH(xmin);
757 header[3] = LOW(xmin);
758 header[4] = HIGH(ymin);
759 header[5] = LOW(ymin);
760 header[6] = HIGH(xmax);
761 header[7] = LOW(xmax);
762 header[8] = HIGH(ymax);
763 header[9] = LOW(ymax);
765 /* concatenate all arrays and fill needed GLYPH structure elements */
767 glyph->len1 = 10 + 2 * outline->n_contours;
768 glyph->len2 = (flagsp - flags) + (xp - x) + (yp - y);
770 glyph->buf = (FT_Byte*)malloc(glyph->len1 + glyph->len2);
771 if (!glyph->buf)
773 error = FT_Err_Out_Of_Memory;
774 goto Exit;
777 p = glyph->buf;
778 memcpy(p, header, 10);
779 p += 10;
781 glyph->ins_len = 0;
782 glyph->ins_buf = NULL;
784 for (i = 0; i < outline->n_contours; i++)
786 *(p++) = HIGH(outline->contours[i]);
787 *(p++) = LOW(outline->contours[i]);
790 memcpy(p, flags, flagsp - flags);
791 p += flagsp - flags;
792 memcpy(p, x, xp - x);
793 p += xp - x;
794 memcpy(p, y, yp - y);
796 Exit:
797 free(flags);
798 free(x);
799 free(y);
801 return error;
805 /* We hint each glyph at EM size and construct a new `glyf' table. */
806 /* Some fonts need this; in particular, */
807 /* there are CJK fonts which use hints to scale and position subglyphs. */
808 /* As a consequence, there are no longer composite glyphs. */
810 FT_Error
811 TA_sfnt_create_glyf_data(SFNT* sfnt,
812 FONT* font)
814 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
815 FT_Face face = sfnt->face;
816 FT_Error error;
818 glyf_Data* data;
820 FT_UShort i;
823 /* in case of success, all allocated arrays are */
824 /* linked and eventually freed in `TA_font_unload' */
826 /* nothing to do if table has already been created */
827 if (glyf_table->data)
828 return TA_Err_Ok;
830 data = (glyf_Data*)calloc(1, sizeof (glyf_Data));
831 if (!data)
832 return FT_Err_Out_Of_Memory;
834 glyf_table->data = data;
836 data->num_glyphs = face->num_glyphs;
837 data->glyphs = (GLYPH*)calloc(1, data->num_glyphs * sizeof (GLYPH));
838 if (!data->glyphs)
839 return FT_Err_Out_Of_Memory;
841 /* XXX: Make size configurable */
842 /* we use the EM size */
843 /* so that the resulting coordinates can be used without transformation */
844 error = FT_Set_Char_Size(face, face->units_per_EM * 64, 0, 72, 0);
845 if (error)
846 return error;
848 /* loop over all glyphs in font face */
849 for (i = 0; i < data->num_glyphs; i++)
851 GLYPH* glyph = &data->glyphs[i];
854 error = FT_Load_Glyph(face, i, FT_LOAD_NO_BITMAP | FT_LOAD_NO_AUTOHINT);
855 if (error)
856 return error;
858 error = TA_create_glyph_data(&face->glyph->outline, glyph);
859 if (error)
860 return error;
863 return TA_Err_Ok;
866 /* end of taglyf.c */