Add code to adjust `hmtx' table.
[ttfautohint.git] / src / taglyf.c
blob6f8bb8caa51b62489ae2bba3153abbb4cf375965
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 level,
241 FT_UShort* depth)
243 FT_UShort i;
246 if (level > *depth)
247 *depth = level;
249 for (i = 0; i < num_components; i++)
251 FT_UShort component = components[i];
252 FT_Error error;
255 if (component >= data->num_glyphs)
256 return FT_Err_Invalid_Table;
258 error = TA_iterate_composite_glyph(data,
259 data->glyphs[component].components,
260 data->glyphs[component].num_components,
261 level + 1,
262 depth);
263 if (error)
264 return error;
267 return TA_Err_Ok;
271 static FT_Error
272 TA_compute_composite_depths(glyf_Data* data)
274 FT_UShort i;
277 for (i = 0; i < data->num_glyphs; i++)
279 GLYPH* glyph = &data->glyphs[i];
282 if (glyph->num_components)
284 FT_UShort depth = 0;
285 FT_Error error;
288 error = TA_iterate_composite_glyph(data,
289 glyph->components,
290 glyph->num_components,
292 &depth);
293 if (error)
294 return error;
296 glyph->depth = depth;
300 return TA_Err_Ok;
304 FT_Error
305 TA_sfnt_split_glyf_table(SFNT* sfnt,
306 FONT* font)
308 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
309 SFNT_Table* loca_table = &font->tables[sfnt->loca_idx];
310 SFNT_Table* head_table = &font->tables[sfnt->head_idx];
312 glyf_Data* data;
313 FT_Byte loca_format;
315 FT_ULong offset;
316 FT_ULong offset_next;
318 FT_Byte* p;
319 FT_UShort i;
321 FT_Error error;
324 /* in case of success, all allocated arrays are */
325 /* linked and eventually freed in `TA_font_unload' */
327 /* nothing to do if table has already been split */
328 if (glyf_table->data)
329 return TA_Err_Ok;
331 data = (glyf_Data*)calloc(1, sizeof (glyf_Data));
332 if (!data)
333 return FT_Err_Out_Of_Memory;
335 glyf_table->data = data;
337 loca_format = head_table->buf[LOCA_FORMAT_OFFSET];
339 data->num_glyphs = loca_format ? loca_table->len / 4 - 1
340 : loca_table->len / 2 - 1;
341 data->glyphs = (GLYPH*)calloc(1, data->num_glyphs * sizeof (GLYPH));
342 if (!data->glyphs)
343 return FT_Err_Out_Of_Memory;
345 p = loca_table->buf;
347 if (loca_format)
349 offset_next = *(p++) << 24;
350 offset_next += *(p++) << 16;
351 offset_next += *(p++) << 8;
352 offset_next += *(p++);
354 else
356 offset_next = *(p++) << 8;
357 offset_next += *(p++);
358 offset_next <<= 1;
361 /* loop over `loca' and `glyf' data */
362 for (i = 0; i < data->num_glyphs; i++)
364 GLYPH* glyph = &data->glyphs[i];
365 FT_ULong len;
368 offset = offset_next;
370 if (loca_format)
372 offset_next = *(p++) << 24;
373 offset_next += *(p++) << 16;
374 offset_next += *(p++) << 8;
375 offset_next += *(p++);
377 else
379 offset_next = *(p++) << 8;
380 offset_next += *(p++);
381 offset_next <<= 1;
384 if (offset_next < offset
385 || offset_next > glyf_table->len)
386 return FT_Err_Invalid_Table;
388 len = offset_next - offset;
389 if (!len)
390 continue; /* empty glyph */
391 else
393 FT_Byte* buf;
394 FT_Short num_contours;
397 /* check header size */
398 if (len < 10)
399 return FT_Err_Invalid_Table;
401 buf = glyf_table->buf + offset;
402 num_contours = (FT_Short)((buf[0] << 8) + buf[1]);
404 /* We must parse the rest of the glyph record to get the exact */
405 /* record length. Since the `loca' table rounds record lengths */
406 /* up to multiples of 4 (or 2 for older fonts), and we must round */
407 /* up again after stripping off the instructions, it would be */
408 /* possible otherwise to have more than 4 bytes of padding which */
409 /* is more or less invalid. */
411 if (num_contours < 0)
412 error = TA_glyph_parse_composite(glyph, buf, len);
413 else
414 error = TA_glyph_parse_simple(glyph, buf, num_contours, len);
415 if (error)
416 return error;
420 error = TA_compute_composite_depths(data);
421 if (error)
422 return error;
424 return TA_Err_Ok;
428 FT_Error
429 TA_sfnt_build_glyf_table(SFNT* sfnt,
430 FONT* font)
432 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
433 glyf_Data* data = (glyf_Data*)glyf_table->data;
435 GLYPH* glyph;
437 FT_ULong len;
438 FT_Byte* buf_new;
439 FT_Byte* p;
440 FT_UShort i;
443 if (glyf_table->processed)
444 return TA_Err_Ok;
446 /* get table size */
447 len = 0;
448 glyph = data->glyphs;
449 for (i = 0; i < data->num_glyphs; i++, glyph++)
451 /* glyph records should have offsets which are multiples of 4 */
452 len = (len + 3) & ~3;
453 len += glyph->len1 + glyph->len2 + glyph->ins_len;
454 /* add two bytes for the instructionLength field */
455 if (glyph->len2 || glyph->ins_len)
456 len += 2;
459 /* to make the short format of the `loca' table always work, */
460 /* assure an even length of the `glyf' table */
461 glyf_table->len = (len + 1) & ~1;
463 buf_new = (FT_Byte*)realloc(glyf_table->buf, (len + 3) & ~3);
464 if (!buf_new)
465 return FT_Err_Out_Of_Memory;
466 else
467 glyf_table->buf = buf_new;
469 p = glyf_table->buf;
470 glyph = data->glyphs;
471 for (i = 0; i < data->num_glyphs; i++, glyph++)
473 len = glyph->len1 + glyph->len2 + glyph->ins_len;
474 if (glyph->len2 || glyph->ins_len)
475 len += 2;
477 if (len)
479 /* copy glyph data and insert new instructions */
480 memcpy(p, glyph->buf, glyph->len1);
482 if (glyph->len2)
484 /* simple glyph */
485 p += glyph->len1;
486 *(p++) = HIGH(glyph->ins_len);
487 *(p++) = LOW(glyph->ins_len);
488 memcpy(p, glyph->ins_buf, glyph->ins_len);
489 p += glyph->ins_len;
490 memcpy(p, glyph->buf + glyph->len1, glyph->len2);
491 p += glyph->len2;
493 else
495 /* composite glyph */
496 if (glyph->ins_len)
498 *(p + glyph->flags_offset) |= (WE_HAVE_INSTR >> 8);
499 p += glyph->len1;
500 *(p++) = HIGH(glyph->ins_len);
501 *(p++) = LOW(glyph->ins_len);
502 memcpy(p, glyph->ins_buf, glyph->ins_len);
503 p += glyph->ins_len;
505 else
506 p += glyph->len1;
509 /* pad with zero bytes to have an offset which is a multiple of 4; */
510 /* this works even for the last glyph record since the `glyf' */
511 /* table length is a multiple of 4 also */
512 switch (len % 4)
514 case 1:
515 *(p++) = 0;
516 case 2:
517 *(p++) = 0;
518 case 3:
519 *(p++) = 0;
520 default:
521 break;
526 glyf_table->checksum = TA_table_compute_checksum(glyf_table->buf,
527 glyf_table->len);
528 glyf_table->processed = 1;
530 return TA_Err_Ok;
534 static FT_Error
535 TA_create_glyph_data(FT_Outline* outline,
536 GLYPH* glyph)
538 FT_Error error = TA_Err_Ok;
540 FT_Pos xmin, ymin;
541 FT_Pos xmax, ymax;
543 FT_Byte header[10];
544 FT_Byte* flags = NULL;
545 FT_Byte* flagsp;
546 FT_Byte oldf, f;
547 FT_Byte* x = NULL;
548 FT_Byte* xp;
549 FT_Byte* y = NULL;
550 FT_Byte* yp;
552 FT_Pos lastx, lasty;
554 FT_Short i;
555 FT_Byte* p;
558 if (!outline->n_contours)
559 return TA_Err_Ok; /* empty glyph */
561 /* in case of success, all non-local allocated arrays are */
562 /* linked and eventually freed in `TA_font_unload' */
564 glyph->buf = NULL;
566 /* we use `calloc' since we rely on the array */
567 /* being initialized to zero; */
568 /* additionally, we need one more byte for a test after the loop */
569 flags = (FT_Byte*)calloc(1, outline->n_points + 1);
570 if (!flags)
572 error = FT_Err_Out_Of_Memory;
573 goto Exit;
576 /* we have either one-byte or two-byte elements */
577 x = (FT_Byte*)malloc(2 * outline->n_points);
578 if (!x)
580 error = FT_Err_Out_Of_Memory;
581 goto Exit;
584 y = (FT_Byte*)malloc(2 * outline->n_points);
585 if (!y)
587 error = FT_Err_Out_Of_Memory;
588 goto Exit;
591 flagsp = flags;
592 xp = x;
593 yp = y;
594 xmin = xmax = (outline->points[0].x + 32) >> 6;
595 ymin = ymax = (outline->points[0].y + 32) >> 6;
596 lastx = 0;
597 lasty = 0;
598 oldf = 0x80; /* start with an impossible value */
600 /* convert the FreeType representation of the glyph's outline */
601 /* into the representation format of the `glyf' table */
602 for (i = 0; i < outline->n_points; i++)
604 FT_Pos xcur = (outline->points[i].x + 32) >> 6;
605 FT_Pos ycur = (outline->points[i].y + 32) >> 6;
607 FT_Pos xdelta = xcur - lastx;
608 FT_Pos ydelta = ycur - lasty;
611 /* we are only interested in bit 0 of the `tags' array */
612 f = outline->tags[i] & ON_CURVE;
614 /* x value */
616 if (xdelta == 0)
617 f |= SAME_X;
618 else
620 if (xdelta < 256 && xdelta > -256)
622 f |= X_SHORT_VECTOR;
624 if (xdelta < 0)
625 xdelta = -xdelta;
626 else
627 f |= SAME_X;
629 *(xp++) = (FT_Byte)xdelta;
631 else
633 *(xp++) = HIGH(xdelta);
634 *(xp++) = LOW(xdelta);
638 /* y value */
640 if (ydelta == 0)
641 f |= SAME_Y;
642 else
644 if (ydelta < 256 && ydelta > -256)
646 f |= Y_SHORT_VECTOR;
648 if (ydelta < 0)
649 ydelta = -ydelta;
650 else
651 f |= SAME_Y;
653 *(yp++) = (FT_Byte)ydelta;
655 else
657 *(yp++) = HIGH(ydelta);
658 *(yp++) = LOW(ydelta);
662 if (f == oldf)
664 /* set repeat flag */
665 *(flagsp - 1) |= REPEAT;
667 if (*flagsp == 255)
669 /* we can only handle 256 repetitions at once, */
670 /* so use a new counter */
671 flagsp++;
672 *(flagsp++) = f;
674 else
675 *flagsp += 1; /* increase repetition counter */
677 else
679 if (*flagsp)
680 flagsp++; /* skip repetition counter */
681 *(flagsp++) = f;
682 oldf = f;
685 if (xcur > xmax)
686 xmax = xcur;
687 if (ycur > ymax)
688 ymax = ycur;
689 if (xcur < xmin)
690 xmin = xcur;
691 if (ycur < ymin)
692 ymin = ycur;
694 lastx = xcur;
695 lasty = ycur;
698 /* if the last byte was a repetition counter, */
699 /* we must increase by one to get the correct array size */
700 if (*flagsp)
701 flagsp++;
703 header[0] = HIGH(outline->n_contours);
704 header[1] = LOW(outline->n_contours);
705 header[2] = HIGH(xmin);
706 header[3] = LOW(xmin);
707 header[4] = HIGH(ymin);
708 header[5] = LOW(ymin);
709 header[6] = HIGH(xmax);
710 header[7] = LOW(xmax);
711 header[8] = HIGH(ymax);
712 header[9] = LOW(ymax);
714 /* concatenate all arrays and fill needed GLYPH structure elements */
716 glyph->len1 = 10 + 2 * outline->n_contours;
717 glyph->len2 = (flagsp - flags) + (xp - x) + (yp - y);
719 glyph->buf = (FT_Byte*)malloc(glyph->len1 + glyph->len2);
720 if (!glyph->buf)
722 error = FT_Err_Out_Of_Memory;
723 goto Exit;
726 p = glyph->buf;
727 memcpy(p, header, 10);
728 p += 10;
730 glyph->ins_len = 0;
731 glyph->ins_buf = NULL;
733 for (i = 0; i < outline->n_contours; i++)
735 *(p++) = HIGH(outline->contours[i]);
736 *(p++) = LOW(outline->contours[i]);
739 memcpy(p, flags, flagsp - flags);
740 p += flagsp - flags;
741 memcpy(p, x, xp - x);
742 p += xp - x;
743 memcpy(p, y, yp - y);
745 Exit:
746 free(flags);
747 free(x);
748 free(y);
750 return error;
754 /* We hint each glyph at EM size and construct a new `glyf' table. */
755 /* Some fonts need this; in particular, */
756 /* there are CJK fonts which use hints to scale and position subglyphs. */
757 /* As a consequence, there are no longer composite glyphs. */
759 FT_Error
760 TA_sfnt_create_glyf_data(SFNT* sfnt,
761 FONT* font)
763 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
764 FT_Face face = sfnt->face;
765 FT_Error error;
767 glyf_Data* data;
769 FT_UShort i;
772 /* in case of success, all allocated arrays are */
773 /* linked and eventually freed in `TA_font_unload' */
775 /* nothing to do if table has already been created */
776 if (glyf_table->data)
777 return TA_Err_Ok;
779 data = (glyf_Data*)calloc(1, sizeof (glyf_Data));
780 if (!data)
781 return FT_Err_Out_Of_Memory;
783 glyf_table->data = data;
785 data->num_glyphs = face->num_glyphs;
786 data->glyphs = (GLYPH*)calloc(1, data->num_glyphs * sizeof (GLYPH));
787 if (!data->glyphs)
788 return FT_Err_Out_Of_Memory;
790 /* XXX: Make size configurable */
791 /* we use the EM size */
792 /* so that the resulting coordinates can be used without transformation */
793 error = FT_Set_Char_Size(face, face->units_per_EM * 64, 0, 72, 0);
794 if (error)
795 return error;
797 /* loop over all glyphs in font face */
798 for (i = 0; i < data->num_glyphs; i++)
800 GLYPH* glyph = &data->glyphs[i];
803 error = FT_Load_Glyph(face, i, FT_LOAD_NO_BITMAP | FT_LOAD_NO_AUTOHINT);
804 if (error)
805 return error;
807 error = TA_create_glyph_data(&face->glyph->outline, glyph);
808 if (error)
809 return error;
812 return TA_Err_Ok;
815 /* end of taglyf.c */