Fix OTS warning about `maxp.maxSizeOfInstructions`.
[ttfautohint.git] / lib / taglyf.c
blobf9ce049de0d386483193ed866f3394dda9a992be
1 /* taglyf.c */
3 /*
4 * Copyright (C) 2011-2022 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 static FT_Error
20 TA_sfnt_build_glyf_hints(SFNT* sfnt,
21 FONT* font)
23 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
24 glyf_Data* data = (glyf_Data*)glyf_table->data;
26 FT_Long idx;
27 FT_Error error;
29 FT_UShort loop_count;
32 /* this loop doesn't include the artificial `.ttfautohint' glyph */
33 loop_count = data->num_glyphs;
34 if (sfnt->max_components && font->hint_composites)
35 loop_count--;
37 for (idx = 0; idx < loop_count; idx++)
39 error = TA_sfnt_build_glyph_instructions(sfnt, font, idx);
40 if (error)
41 return error;
42 if (font->progress)
44 FT_Int ret;
47 ret = font->progress(idx, loop_count,
48 sfnt - font->sfnts, font->num_sfnts,
49 font->progress_data);
50 if (ret)
51 return TA_Err_Canceled;
55 return FT_Err_Ok;
59 static FT_Error
60 TA_glyph_get_components(GLYPH* glyph,
61 FT_Byte* buf,
62 FT_ULong len)
64 FT_UShort flags;
65 FT_UShort component;
66 FT_UShort* components_new;
68 FT_Byte* p;
69 FT_Byte* endp;
72 p = buf;
73 endp = buf + len;
75 /* skip header */
76 p += 10;
78 /* walk over component records */
81 if (p + 4 > endp)
82 return FT_Err_Invalid_Table;
84 flags = NEXT_USHORT(p);
86 /* add component to list */
87 component = NEXT_USHORT(p);
89 glyph->num_components++;
90 components_new = (FT_UShort*)realloc(glyph->components,
91 glyph->num_components
92 * sizeof (FT_UShort));
93 if (!components_new)
95 glyph->num_components--;
96 return FT_Err_Out_Of_Memory;
98 else
99 glyph->components = components_new;
101 glyph->components[glyph->num_components - 1] = component;
103 /* skip scaling and offset arguments */
104 if (flags & ARGS_ARE_WORDS)
105 p += 4;
106 else
107 p += 2;
109 if (flags & WE_HAVE_A_SCALE)
110 p += 2;
111 else if (flags & WE_HAVE_AN_XY_SCALE)
112 p += 4;
113 else if (flags & WE_HAVE_A_2X2)
114 p += 8;
115 } while (flags & MORE_COMPONENTS);
117 return TA_Err_Ok;
121 static FT_Error
122 TA_glyph_parse_composite(GLYPH* glyphs,
123 FT_UShort idx,
124 FT_Byte* buf,
125 FT_ULong len,
126 FT_UShort num_glyphs,
127 FT_Bool hint_composites)
129 GLYPH* glyph = &glyphs[idx];
131 FT_ULong flags_offset; /* after the loop, this is the offset */
132 /* to the last element in the flags array */
133 FT_UShort flags;
135 FT_Byte* p;
136 FT_Byte* q;
138 FT_UShort* curr_component;
139 FT_UShort curr_num_points;
142 /* we allocate too large a buffer */
143 /* (including space for the new component */
144 /* and possible argument size changes for shifted point indices) */
145 /* and reallocate it later to its real size */
146 glyph->buf = (FT_Byte*)malloc(len + 8 + glyph->num_components * 2);
147 if (!glyph->buf)
148 return FT_Err_Out_Of_Memory;
150 p = buf;
151 q = glyph->buf;
153 /* copy header */
154 memcpy(q, p, 10);
155 p += 10;
156 q += 10;
158 /* if the composite glyph contains one or more contours, */
159 /* we prepend a composite glyph component to call some bytecode */
160 /* which eventually becomes the last glyph in the `glyf' table; */
161 /* for convenience, however, it is not added to the `components' array */
162 /* (doing so simplifies the conversion of point indices later on) */
163 if (glyph->num_composite_contours && hint_composites)
165 FT_Short x_min;
166 FT_Short x_max;
167 FT_Short y_min;
168 FT_Short y_max;
169 FT_Short x_offset;
170 FT_Short y_offset;
173 /* the composite glyph's bounding box */
174 x_min = (FT_Short)((buf[2] << 8) + buf[3]);
175 y_min = (FT_Short)((buf[4] << 8) + buf[5]);
176 x_max = (FT_Short)((buf[6] << 8) + buf[7]);
177 y_max = (FT_Short)((buf[8] << 8) + buf[9]);
179 /* use ARGS_ARE_WORDS only if necessary; */
180 /* note that the offset value of the component doesn't matter */
181 /* as long as it stays within the bounding box */
182 if (x_min <= 0 && x_max >= 0)
183 x_offset = 0;
184 else if (x_max < 0)
185 x_offset = x_max;
186 else
187 x_offset = x_min;
189 if (y_min <= 0 && y_max >= 0)
190 y_offset = 0;
191 else if (y_max < 0)
192 y_offset = y_max;
193 else
194 y_offset = y_min;
196 if (x_offset >= -128 && x_offset <= 127
197 && y_offset >= -128 && y_offset <= 127)
199 *(q++) = 0x00;
200 *(q++) = ARGS_ARE_XY_VALUES | MORE_COMPONENTS;
201 *(q++) = HIGH(num_glyphs - 1);
202 *(q++) = LOW(num_glyphs - 1);
203 *(q++) = (FT_Byte)x_offset;
204 *(q++) = (FT_Byte)y_offset;
206 else
208 *(q++) = 0x00;
209 *(q++) = ARGS_ARE_WORDS | ARGS_ARE_XY_VALUES | MORE_COMPONENTS;
210 *(q++) = HIGH(num_glyphs - 1);
211 *(q++) = LOW(num_glyphs - 1);
212 *(q++) = HIGH(x_offset);
213 *(q++) = LOW(x_offset);
214 *(q++) = HIGH(y_offset);
215 *(q++) = LOW(y_offset);
219 curr_component = glyph->components;
220 curr_num_points = 0;
222 /* walk over component records */
225 flags_offset = (FT_ULong)(q - glyph->buf);
227 *(q++) = *p;
228 *(q++) = *(p + 1);
229 flags = NEXT_USHORT(p);
231 /* copy component */
232 *(q++) = *(p++);
233 *(q++) = *(p++);
235 if (flags & ARGS_ARE_XY_VALUES)
237 /* copy offsets */
238 *(q++) = *(p++);
239 *(q++) = *(p++);
241 if (flags & ARGS_ARE_WORDS)
243 *(q++) = *(p++);
244 *(q++) = *(p++);
247 else
249 /* handle point numbers */
250 FT_UShort arg1;
251 FT_UShort arg2;
252 FT_UShort idx2;
253 FT_UShort i;
254 FT_UShort j;
257 if (flags & ARGS_ARE_WORDS)
259 arg1 = *(p++) >> 8;
260 arg1 += *(p++);
261 arg2 = *(p++) >> 8;
262 arg2 += *(p++);
264 else
266 arg1 = *(p++);
267 arg2 = *(p++);
270 curr_num_points += glyphs[*curr_component++].num_points;
272 /* compute the point index of arg2 after adding the subglyph */
273 idx2 = curr_num_points + arg2;
275 /* adjust point indices */
276 /* (see `TA_adjust_point_index' in `tabytecode.c' for more) */
277 for (i = 0; i < glyph->num_pointsums; i++)
278 if (arg1 < glyph->pointsums[i])
279 break;
280 arg1 += i;
282 for (j = 0; j < glyph->num_pointsums; j++)
283 if (idx2 < glyph->pointsums[j])
284 break;
285 arg2 += j - i;
287 if (arg1 <= 0xFF && arg2 <= 0xFF)
289 glyph->buf[flags_offset + 1] &= ~ARGS_ARE_WORDS;
291 *(q++) = (FT_Byte)arg1;
292 *(q++) = (FT_Byte)arg2;
294 else
296 glyph->buf[flags_offset + 1] |= ARGS_ARE_WORDS;
298 *(q++) = HIGH(arg1);
299 *(q++) = LOW(arg1);
300 *(q++) = HIGH(arg2);
301 *(q++) = LOW(arg2);
305 /* copy scaling arguments */
306 if (flags & (WE_HAVE_A_SCALE | WE_HAVE_AN_XY_SCALE | WE_HAVE_A_2X2))
308 *(q++) = *(p++);
309 *(q++) = *(p++);
311 if (flags & (WE_HAVE_AN_XY_SCALE | WE_HAVE_A_2X2))
313 *(q++) = *(p++);
314 *(q++) = *(p++);
316 if (flags & WE_HAVE_A_2X2)
318 *(q++) = *(p++);
319 *(q++) = *(p++);
320 *(q++) = *(p++);
321 *(q++) = *(p++);
323 } while (flags & MORE_COMPONENTS);
325 glyph->len1 = (FT_ULong)(q - glyph->buf);
326 /* glyph->len2 = 0; */
327 glyph->flags_offset = flags_offset;
328 glyph->buf = (FT_Byte*)realloc(glyph->buf, glyph->len1);
330 /* we discard instructions (if any) */
331 glyph->buf[glyph->flags_offset] &= ~(WE_HAVE_INSTR >> 8);
333 return TA_Err_Ok;
337 static FT_Error
338 TA_glyph_parse_simple(GLYPH* glyph,
339 FT_Byte* buf,
340 FT_ULong len,
341 FT_Bool dehint)
343 FT_ULong ins_offset;
344 FT_Byte* flags_start;
346 FT_UShort num_ins;
348 FT_ULong flags_size; /* size of the flags array */
349 FT_ULong xy_size; /* size of x and y coordinate arrays together */
351 FT_Byte* p;
352 FT_Byte* endp;
354 FT_UShort i;
357 p = buf;
358 endp = buf + len;
360 ins_offset = 10 + (FT_ULong)glyph->num_contours * 2;
362 p += ins_offset;
364 if (p + 2 > endp)
365 return FT_Err_Invalid_Table;
367 /* get number of instructions */
368 num_ins = NEXT_USHORT(p);
370 /* assure that we don't process a font */
371 /* which already contains a `.ttfautohint' glyph */
372 /* (a font with a `post' table version 3.0 doesn't contain glyph names, */
373 /* so we have to check it this way) */
374 if (glyph->num_points == 1
375 && num_ins >= sizeof (ttfautohint_glyph_bytecode)
376 && !dehint)
378 if (!strncmp((char*)p, (char*)ttfautohint_glyph_bytecode,
379 sizeof (ttfautohint_glyph_bytecode)))
380 return TA_Err_Already_Processed;
383 p += num_ins;
385 if (p > endp)
386 return FT_Err_Invalid_Table;
388 flags_start = p;
389 xy_size = 0;
390 i = 0;
392 while (i < glyph->num_points)
394 FT_Byte flags;
395 FT_Byte x_short;
396 FT_Byte y_short;
397 FT_Byte have_x;
398 FT_Byte have_y;
399 FT_UInt count;
402 if (p + 1 > endp)
403 return FT_Err_Invalid_Table;
405 flags = *(p++);
407 x_short = (flags & X_SHORT_VECTOR) ? 1 : 2;
408 y_short = (flags & Y_SHORT_VECTOR) ? 1 : 2;
410 have_x = ((flags & SAME_X) && !(flags & X_SHORT_VECTOR)) ? 0 : 1;
411 have_y = ((flags & SAME_Y) && !(flags & Y_SHORT_VECTOR)) ? 0 : 1;
413 count = 1;
415 if (flags & REPEAT)
417 if (p + 1 > endp)
418 return FT_Err_Invalid_Table;
420 count += *(p++);
422 if (i + count > glyph->num_points)
423 return FT_Err_Invalid_Table;
426 xy_size += count * x_short * have_x;
427 xy_size += count * y_short * have_y;
429 i += count;
432 if (p + xy_size > endp)
433 return FT_Err_Invalid_Table;
435 flags_size = (FT_ULong)(p - flags_start);
437 /* store the data before and after the bytecode instructions */
438 /* in the same array */
439 glyph->len1 = ins_offset;
440 glyph->len2 = flags_size + xy_size;
441 glyph->buf = (FT_Byte*)malloc(glyph->len1 + glyph->len2);
442 if (!glyph->buf)
443 return FT_Err_Out_Of_Memory;
445 /* now copy everything but the instructions */
446 memcpy(glyph->buf, buf, glyph->len1);
447 memcpy(glyph->buf + glyph->len1, flags_start, glyph->len2);
449 return TA_Err_Ok;
453 static FT_Error
454 TA_iterate_composite_glyph(glyf_Data* data,
455 FT_UShort* components,
456 FT_UShort num_components,
457 FT_UShort** pointsums,
458 FT_UShort* num_pointsums,
459 FT_UShort* num_composite_contours,
460 FT_UShort* num_composite_points)
462 FT_UShort* pointsums_new;
463 FT_UShort i;
466 /* save current state */
468 if (*num_pointsums == 0xFFFF)
469 return FT_Err_Invalid_Table;
471 (*num_pointsums)++;
472 pointsums_new = (FT_UShort*)realloc(*pointsums,
473 *num_pointsums
474 * sizeof (FT_UShort));
475 if (!pointsums_new)
477 (*num_pointsums)--;
478 return FT_Err_Out_Of_Memory;
480 else
481 *pointsums = pointsums_new;
483 (*pointsums)[*num_pointsums - 1] = *num_composite_points;
485 for (i = 0; i < num_components; i++)
487 GLYPH* glyph;
488 FT_UShort component = components[i];
489 FT_Error error;
492 if (component >= data->num_glyphs)
493 return FT_Err_Invalid_Table;
495 glyph = &data->glyphs[component];
497 if (glyph->num_components)
499 error = TA_iterate_composite_glyph(data,
500 glyph->components,
501 glyph->num_components,
502 pointsums,
503 num_pointsums,
504 num_composite_contours,
505 num_composite_points);
506 if (error)
507 return error;
509 else
511 /* no need for checking overflow of the number of contours */
512 /* since the number of points is always larger or equal */
513 if (*num_composite_points > 0xFFFF - glyph->num_points)
514 return FT_Err_Invalid_Table;
516 *num_composite_contours += glyph->num_contours;
517 *num_composite_points += glyph->num_points;
521 return TA_Err_Ok;
525 FT_Error
526 TA_sfnt_compute_composite_pointsums(SFNT* sfnt,
527 FONT* font)
529 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
530 glyf_Data* data = (glyf_Data*)glyf_table->data;
532 FT_UShort i;
535 for (i = 0; i < data->num_glyphs; i++)
537 GLYPH* glyph = &data->glyphs[i];
540 if (glyph->num_components)
542 FT_Error error;
543 FT_UShort num_composite_contours = 0;
544 FT_UShort num_composite_points = 0;
547 error = TA_iterate_composite_glyph(data,
548 glyph->components,
549 glyph->num_components,
550 &glyph->pointsums,
551 &glyph->num_pointsums,
552 &num_composite_contours,
553 &num_composite_points);
554 if (error)
555 return error;
557 glyph->num_composite_contours = num_composite_contours;
558 /* we set the number of points (after expanding all subglyphs) */
559 /* for composite glyphs also */
560 glyph->num_points = num_composite_points;
562 if (font->hint_composites)
564 /* update maximum values, */
565 /* including the subglyphs not in `components' array */
566 /* (each of them has a single point in a single contour) */
567 if (num_composite_points + glyph->num_pointsums
568 > sfnt->max_composite_points)
569 sfnt->max_composite_points = num_composite_points
570 + glyph->num_pointsums;
571 if (num_composite_contours + glyph->num_pointsums
572 > sfnt->max_composite_contours)
573 sfnt->max_composite_contours = num_composite_contours
574 + glyph->num_pointsums;
579 return TA_Err_Ok;
583 FT_Error
584 TA_sfnt_split_glyf_table(SFNT* sfnt,
585 FONT* font)
587 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
588 SFNT_Table* loca_table = &font->tables[sfnt->loca_idx];
589 SFNT_Table* head_table = &font->tables[sfnt->head_idx];
591 glyf_Data* data;
592 FT_Byte loca_format;
594 FT_ULong offset;
595 FT_ULong offset_next;
597 FT_Byte* p;
598 FT_UShort i;
599 FT_UShort loop_count;
601 FT_Error error;
604 /* in case of success, all allocated arrays are */
605 /* linked and eventually freed in `TA_font_unload' */
607 /* nothing to do if table has already been split */
608 if (glyf_table->data)
609 return TA_Err_Ok;
611 data = (glyf_Data*)calloc(1, sizeof (glyf_Data));
612 if (!data)
613 return FT_Err_Out_Of_Memory;
615 glyf_table->data = data;
617 loca_format = head_table->buf[LOCA_FORMAT_OFFSET];
619 data->num_glyphs = (FT_UShort)(loca_format ? loca_table->len / 4
620 : loca_table->len / 2);
621 loop_count = data->num_glyphs - 1;
623 /* allocate one more glyph slot if we have composite glyphs */
624 if (!sfnt->max_components || !font->hint_composites)
625 data->num_glyphs -= 1;
626 data->glyphs = (GLYPH*)calloc(1, data->num_glyphs * sizeof (GLYPH));
627 if (!data->glyphs)
628 return FT_Err_Out_Of_Memory;
630 data->master_globals = NULL;
631 data->cvt_idx = MISSING;
632 data->fpgm_idx = MISSING;
633 data->prep_idx = MISSING;
635 /* first loop over `loca' and `glyf' data */
637 p = loca_table->buf;
639 if (loca_format)
640 offset_next = NEXT_ULONG(p);
641 else
643 offset_next = NEXT_USHORT(p);
644 offset_next <<= 1;
647 for (i = 0; i < loop_count; i++)
649 GLYPH* glyph = &data->glyphs[i];
650 FT_ULong len;
653 offset = offset_next;
655 if (loca_format)
656 offset_next = NEXT_ULONG(p);
657 else
659 offset_next = NEXT_USHORT(p);
660 offset_next <<= 1;
663 if (offset_next < offset
664 || offset_next > glyf_table->len)
665 return FT_Err_Invalid_Table;
667 len = offset_next - offset;
668 if (!len)
669 continue; /* empty glyph */
670 else
672 FT_Byte* buf;
675 /* check header size */
676 if (len < 10)
677 return FT_Err_Invalid_Table;
679 /* we need the number of contours and points for */
680 /* `TA_sfnt_compute_composite_pointsums' */
681 buf = glyf_table->buf + offset;
682 glyph->num_contours = (FT_Short)((buf[0] << 8) + buf[1]);
684 if (glyph->num_contours < 0)
686 error = TA_glyph_get_components(glyph, buf, len);
687 if (error)
688 return error;
690 else
692 FT_ULong off;
695 /* use the last contour's end point to compute number of points */
696 off = 10 + ((FT_ULong)glyph->num_contours - 1) * 2;
697 if (off >= len - 1)
698 return FT_Err_Invalid_Table;
700 glyph->num_points = (FT_UShort)((buf[off] << 8) + buf[off + 1] + 1);
705 /* second loop over `loca' and `glyf' data */
707 p = loca_table->buf;
709 if (loca_format)
710 offset_next = NEXT_ULONG(p);
711 else
713 offset_next = NEXT_USHORT(p);
714 offset_next <<= 1;
717 for (i = 0; i < loop_count; i++)
719 GLYPH* glyph = &data->glyphs[i];
720 FT_ULong len;
723 offset = offset_next;
725 if (loca_format)
726 offset_next = NEXT_ULONG(p);
727 else
729 offset_next = NEXT_USHORT(p);
730 offset_next <<= 1;
733 len = offset_next - offset;
734 if (!len)
735 continue; /* empty glyph */
736 else
738 FT_Byte* buf;
741 buf = glyf_table->buf + offset;
743 /* We must parse the rest of the glyph record to get the exact */
744 /* record length. Since the `loca' table rounds record lengths */
745 /* up to multiples of 4 (or 2 for older fonts), and we must round */
746 /* up again after stripping off the instructions, it would be */
747 /* possible otherwise to have more than 4 bytes of padding which */
748 /* is more or less invalid. */
750 if (glyph->num_contours < 0)
751 error = TA_glyph_parse_composite(data->glyphs, i, buf, len,
752 data->num_glyphs,
753 font->hint_composites);
754 else
755 error = TA_glyph_parse_simple(glyph, buf, len, font->dehint);
756 if (error)
757 return error;
761 if (sfnt->max_components && font->hint_composites)
763 /* construct and append our special glyph used as a composite element */
764 GLYPH* glyph = &data->glyphs[data->num_glyphs - 1];
765 FT_Byte* buf;
767 glyph->len1 = 12;
768 glyph->len2 = 1;
769 glyph->buf = (FT_Byte*)malloc(glyph->len1 + glyph->len2);
770 if (!glyph->buf)
771 return FT_Err_Out_Of_Memory;
773 buf = glyph->buf;
775 buf[0] = 0x00; /* one contour */
776 buf[1] = 0x01;
777 buf[2] = 0x00; /* no dimensions */
778 buf[3] = 0x00;
779 buf[4] = 0x00;
780 buf[5] = 0x00;
781 buf[6] = 0x00;
782 buf[7] = 0x00;
783 buf[8] = 0x00;
784 buf[9] = 0x00;
785 buf[10] = 0x00; /* one contour end point */
786 buf[11] = 0x00;
788 buf[12] = ON_CURVE | SAME_X | SAME_Y; /* the flags for a point at 0,0 */
790 /* add bytecode also; */
791 /* this works because the loop in `TA_sfnt_build_glyf_hints' */
792 /* doesn't include the newly appended glyph */
793 glyph->ins_len = sizeof (ttfautohint_glyph_bytecode);
794 glyph->ins_buf = (FT_Byte*)malloc(glyph->ins_len);
795 if (!glyph->ins_buf)
796 return FT_Err_Out_Of_Memory;
797 memcpy(glyph->ins_buf, ttfautohint_glyph_bytecode, glyph->ins_len);
799 sfnt->max_components += 1;
802 return TA_Err_Ok;
806 FT_Error
807 TA_sfnt_build_glyf_table(SFNT* sfnt,
808 FONT* font)
810 FT_Error error;
812 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
813 glyf_Data* data = (glyf_Data*)glyf_table->data;
815 GLYPH* glyph;
817 FT_ULong len;
818 FT_Byte* buf_new;
819 FT_Byte* p;
820 FT_UShort i;
823 if (glyf_table->processed)
824 return TA_Err_Ok;
826 if (!font->dehint)
828 error = TA_sfnt_build_glyf_hints(sfnt, font);
829 if (error)
830 return error;
833 /* get table size */
834 len = 0;
835 glyph = data->glyphs;
836 for (i = 0; i < data->num_glyphs; i++, glyph++)
838 /* glyph records should have offsets which are multiples of 4 */
839 len = (len + 3) & ~3U;
840 len += glyph->len1 + glyph->len2
841 + glyph->ins_extra_len + glyph->ins_len;
842 /* add two bytes for the instructionLength field */
843 if (glyph->len2 || glyph->ins_len)
844 len += 2;
847 /* to make the short format of the `loca' table always work, */
848 /* assure an even length of the `glyf' table */
849 glyf_table->len = (len + 1) & ~1U;
851 buf_new = (FT_Byte*)realloc(glyf_table->buf, (len + 3) & ~3U);
852 if (!buf_new)
853 return FT_Err_Out_Of_Memory;
854 else
855 glyf_table->buf = buf_new;
857 p = glyf_table->buf;
858 glyph = data->glyphs;
859 for (i = 0; i < data->num_glyphs; i++, glyph++)
861 len = glyph->len1 + glyph->len2
862 + glyph->ins_extra_len + glyph->ins_len;
863 if (glyph->len2 || glyph->ins_len)
864 len += 2;
866 if (len)
868 /* copy glyph data and insert new instructions */
869 memcpy(p, glyph->buf, glyph->len1);
871 if (glyph->len2)
873 /* simple glyph */
874 p += glyph->len1;
875 *(p++) = HIGH(glyph->ins_extra_len + glyph->ins_len);
876 *(p++) = LOW(glyph->ins_extra_len + glyph->ins_len);
877 if (glyph->ins_extra_len)
879 memcpy(p, glyph->ins_extra_buf, glyph->ins_extra_len);
880 p += glyph->ins_extra_len;
882 if (glyph->ins_len)
884 memcpy(p, glyph->ins_buf, glyph->ins_len);
885 p += glyph->ins_len;
887 memcpy(p, glyph->buf + glyph->len1, glyph->len2);
888 p += glyph->len2;
890 else
892 /* composite glyph */
893 if (glyph->ins_len)
895 *(p + glyph->flags_offset) |= (WE_HAVE_INSTR >> 8);
896 p += glyph->len1;
897 *(p++) = HIGH(glyph->ins_extra_len + glyph->ins_len);
898 *(p++) = LOW(glyph->ins_extra_len + glyph->ins_len);
899 if (glyph->ins_extra_len)
901 memcpy(p, glyph->ins_extra_buf, glyph->ins_extra_len);
902 p += glyph->ins_extra_len;
904 memcpy(p, glyph->ins_buf, glyph->ins_len);
905 p += glyph->ins_len;
907 else
908 p += glyph->len1;
911 /* pad with zero bytes to have an offset which is a multiple of 4; */
912 /* this works even for the last glyph record since the `glyf' */
913 /* table length is a multiple of 4 also */
914 switch (len % 4)
916 case 1:
917 *(p++) = 0;
918 /* fall through */
919 case 2:
920 *(p++) = 0;
921 /* fall through */
922 case 3:
923 *(p++) = 0;
924 /* fall through */
925 default:
926 break;
931 glyf_table->checksum = TA_table_compute_checksum(glyf_table->buf,
932 glyf_table->len);
933 glyf_table->processed = 1;
935 return TA_Err_Ok;
939 static FT_Error
940 TA_create_glyph_data(FT_Outline* outline,
941 GLYPH* glyph)
943 FT_Error error = TA_Err_Ok;
945 FT_Pos xmin, ymin;
946 FT_Pos xmax, ymax;
948 FT_Byte header[10];
949 FT_Byte* flags = NULL;
950 FT_Byte* flagsp;
951 FT_Byte oldf, f;
952 FT_Byte* x = NULL;
953 FT_Byte* xp;
954 FT_Byte* y = NULL;
955 FT_Byte* yp;
957 FT_Pos lastx, lasty;
959 FT_Short i;
960 FT_Byte* p;
963 if (!outline->n_contours)
964 return TA_Err_Ok; /* empty glyph */
966 /* in case of success, all non-local allocated arrays are */
967 /* linked and eventually freed in `TA_font_unload' */
969 glyph->buf = NULL;
971 /* we use `calloc' since we rely on the array */
972 /* being initialized to zero; */
973 /* additionally, we need one more byte for a test after the loop */
974 flags = (FT_Byte*)calloc(1, (size_t)outline->n_points + 1);
975 if (!flags)
977 error = FT_Err_Out_Of_Memory;
978 goto Exit;
981 /* we have either one-byte or two-byte elements */
982 x = (FT_Byte*)malloc(2 * (size_t)outline->n_points);
983 if (!x)
985 error = FT_Err_Out_Of_Memory;
986 goto Exit;
989 y = (FT_Byte*)malloc(2 * (size_t)outline->n_points);
990 if (!y)
992 error = FT_Err_Out_Of_Memory;
993 goto Exit;
996 flagsp = flags;
997 xp = x;
998 yp = y;
999 xmin = xmax = (outline->points[0].x + 32) >> 6;
1000 ymin = ymax = (outline->points[0].y + 32) >> 6;
1001 lastx = 0;
1002 lasty = 0;
1003 oldf = 0x80; /* start with an impossible value */
1005 /* convert the FreeType representation of the glyph's outline */
1006 /* into the representation format of the `glyf' table */
1007 for (i = 0; i < outline->n_points; i++)
1009 FT_Pos xcur = (outline->points[i].x + 32) >> 6;
1010 FT_Pos ycur = (outline->points[i].y + 32) >> 6;
1012 FT_Pos xdelta = xcur - lastx;
1013 FT_Pos ydelta = ycur - lasty;
1016 /* we are only interested in bit 0 of the `tags' array */
1017 f = outline->tags[i] & ON_CURVE;
1019 /* x value */
1021 if (xdelta == 0)
1022 f |= SAME_X;
1023 else
1025 if (xdelta < 256 && xdelta > -256)
1027 f |= X_SHORT_VECTOR;
1029 if (xdelta < 0)
1030 xdelta = -xdelta;
1031 else
1032 f |= SAME_X;
1034 *(xp++) = (FT_Byte)xdelta;
1036 else
1038 *(xp++) = HIGH(xdelta);
1039 *(xp++) = LOW(xdelta);
1043 /* y value */
1045 if (ydelta == 0)
1046 f |= SAME_Y;
1047 else
1049 if (ydelta < 256 && ydelta > -256)
1051 f |= Y_SHORT_VECTOR;
1053 if (ydelta < 0)
1054 ydelta = -ydelta;
1055 else
1056 f |= SAME_Y;
1058 *(yp++) = (FT_Byte)ydelta;
1060 else
1062 *(yp++) = HIGH(ydelta);
1063 *(yp++) = LOW(ydelta);
1067 if (f == oldf)
1069 /* set repeat flag */
1070 *(flagsp - 1) |= REPEAT;
1072 if (*flagsp == 255)
1074 /* we can only handle 256 repetitions at once, */
1075 /* so use a new counter */
1076 flagsp++;
1077 *(flagsp++) = f;
1079 else
1080 *flagsp += 1; /* increase repetition counter */
1082 else
1084 if (*flagsp)
1085 flagsp++; /* skip repetition counter */
1086 *(flagsp++) = f;
1087 oldf = f;
1090 if (xcur > xmax)
1091 xmax = xcur;
1092 if (ycur > ymax)
1093 ymax = ycur;
1094 if (xcur < xmin)
1095 xmin = xcur;
1096 if (ycur < ymin)
1097 ymin = ycur;
1099 lastx = xcur;
1100 lasty = ycur;
1103 /* if the last byte was a repetition counter, */
1104 /* we must increase by one to get the correct array size */
1105 if (*flagsp)
1106 flagsp++;
1108 header[0] = HIGH(outline->n_contours);
1109 header[1] = LOW(outline->n_contours);
1110 header[2] = HIGH(xmin);
1111 header[3] = LOW(xmin);
1112 header[4] = HIGH(ymin);
1113 header[5] = LOW(ymin);
1114 header[6] = HIGH(xmax);
1115 header[7] = LOW(xmax);
1116 header[8] = HIGH(ymax);
1117 header[9] = LOW(ymax);
1119 /* concatenate all arrays and fill needed GLYPH structure elements */
1121 glyph->len1 = (FT_ULong)(10 + 2 * outline->n_contours);
1122 glyph->len2 = (FT_ULong)((flagsp - flags) + (xp - x) + (yp - y));
1124 glyph->buf = (FT_Byte*)malloc(glyph->len1 + glyph->len2);
1125 if (!glyph->buf)
1127 error = FT_Err_Out_Of_Memory;
1128 goto Exit;
1131 p = glyph->buf;
1132 memcpy(p, header, 10);
1133 p += 10;
1135 glyph->ins_extra_len = 0;
1136 glyph->ins_extra_buf = NULL;
1137 glyph->ins_len = 0;
1138 glyph->ins_buf = NULL;
1140 for (i = 0; i < outline->n_contours; i++)
1142 *(p++) = HIGH(outline->contours[i]);
1143 *(p++) = LOW(outline->contours[i]);
1146 memcpy(p, flags, (size_t)(flagsp - flags));
1147 p += flagsp - flags;
1148 memcpy(p, x, (size_t)(xp - x));
1149 p += xp - x;
1150 memcpy(p, y, (size_t)(yp - y));
1152 Exit:
1153 free(flags);
1154 free(x);
1155 free(y);
1157 return error;
1161 /* We hint each glyph at EM size and construct a new `glyf' table. */
1162 /* Some fonts need this; in particular, */
1163 /* there are CJK fonts which use hints to scale and position subglyphs. */
1164 /* As a consequence, there are no longer composite glyphs. */
1166 FT_Error
1167 TA_sfnt_create_glyf_data(SFNT* sfnt,
1168 FONT* font)
1170 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
1171 FT_Face face = sfnt->face;
1172 FT_Error error;
1174 glyf_Data* data;
1176 FT_UShort i;
1179 /* in case of success, all allocated arrays are */
1180 /* linked and eventually freed in `TA_font_unload' */
1182 /* nothing to do if table has already been created */
1183 if (glyf_table->data)
1184 return TA_Err_Ok;
1186 data = (glyf_Data*)calloc(1, sizeof (glyf_Data));
1187 if (!data)
1188 return FT_Err_Out_Of_Memory;
1190 glyf_table->data = data;
1192 data->num_glyphs = (FT_UShort)face->num_glyphs;
1193 data->glyphs = (GLYPH*)calloc(1, data->num_glyphs * sizeof (GLYPH));
1194 if (!data->glyphs)
1195 return FT_Err_Out_Of_Memory;
1197 /* XXX: Make size configurable */
1198 /* we use the EM size */
1199 /* so that the resulting coordinates can be used without transformation */
1200 error = FT_Set_Char_Size(face, face->units_per_EM * 64, 0, 72, 0);
1201 if (error)
1202 return error;
1204 /* loop over all glyphs in font face */
1205 for (i = 0; i < data->num_glyphs; i++)
1207 GLYPH* glyph = &data->glyphs[i];
1210 error = FT_Load_Glyph(face, i, FT_LOAD_NO_BITMAP | FT_LOAD_NO_AUTOHINT);
1211 if (error)
1212 return error;
1214 error = TA_create_glyph_data(&face->glyph->outline, glyph);
1215 if (error)
1216 return error;
1219 return TA_Err_Ok;
1224 * While the auto-hinter is glyph oriented (this is, using `glyf' data), it
1225 * relies on the `cmap' table and OpenType features to get style coverage
1226 * data. In TTCs, subfonts normally share the same `glyf' table but use
1227 * different `cmap's and OpenType features (in `GSUB' and `GPOS' tables).
1228 * To handle this gracefully, ttfautohint collects (and merges) the coverage
1229 * information in the `glyf_Data' structure.
1232 FT_Error
1233 TA_sfnt_handle_coverage(SFNT* sfnt,
1234 FONT* font)
1236 FT_Error error;
1238 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
1239 glyf_Data* data = (glyf_Data*)glyf_table->data;
1241 FT_Face face = sfnt->face;
1242 TA_FaceGlobals curr_globals;
1244 TA_Style saved_fallback_style = font->fallback_style;
1247 /* using TA_STYLE_UNASSIGNED as the fallback style ensures */
1248 /* that uncovered glyphs stay as-is */
1249 /* (we handle the fallback style later on) */
1250 font->fallback_style = (TA_Style)TA_STYLE_UNASSIGNED;
1252 /* trigger computation of coverage */
1253 error = ta_loader_init(font);
1254 if (error)
1255 goto Exit;
1256 error = ta_loader_reset(font, face);
1257 if (error)
1258 goto Exit;
1259 ta_loader_done(font);
1261 font->fallback_style = saved_fallback_style;
1262 curr_globals = (TA_FaceGlobals)face->autohint.data;
1264 if (!data->master_globals)
1266 /* initialize */
1267 data->master_globals = curr_globals;
1268 goto Exit;
1271 /* we have the same `glyf' table for another subfont; */
1272 /* merge the current coverage info into the `master' coverage info */
1274 TA_FaceGlobals master_globals = data->master_globals;
1275 FT_Long count = master_globals->glyph_count;
1277 FT_UShort* master = master_globals->glyph_styles;
1278 FT_UShort* curr = curr_globals->glyph_styles;
1280 FT_UShort* limit = master + count;
1283 /* we simply copy the data, */
1284 /* assuming that a given glyph always has the same properties -- */
1285 /* as soon as we make the style selection more fine-grained, */
1286 /* it is possible that this assumption doesn't hold: */
1287 /* for example, glyph `A' can be used for both Cyrillic and Latin */
1288 while (master < limit)
1290 if ((*curr & TA_STYLE_MASK) != TA_STYLE_UNASSIGNED)
1291 *master = *curr;
1293 master++;
1294 curr++;
1298 Exit:
1299 return error;
1303 void
1304 TA_sfnt_adjust_coverage(SFNT* sfnt,
1305 FONT* font)
1307 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
1308 glyf_Data* data = (glyf_Data*)glyf_table->data;
1310 TA_FaceGlobals master_globals = data->master_globals;
1313 /* use fallback style for uncovered glyphs */
1314 if (!data->adjusted)
1316 FT_Long nn;
1317 FT_UShort* gstyles = master_globals->glyph_styles;
1318 #ifdef TA_DEBUG
1319 FT_UInt count;
1322 if (sfnt->face->num_faces > 1)
1323 TA_LOG_GLOBAL(("\n"
1324 "using fallback style `%s' for unassigned glyphs"
1325 " (glyf table index %d):\n",
1326 ta_style_names[master_globals->font->fallback_style],
1327 sfnt->glyf_idx));
1328 else
1329 TA_LOG_GLOBAL(("\n"
1330 "using fallback style `%s' for unassigned glyphs:\n",
1331 ta_style_names[master_globals->font->fallback_style]));
1333 count = 0;
1335 for (nn = 0; nn < master_globals->glyph_count; nn++)
1337 if ((gstyles[nn] & TA_STYLE_MASK) == TA_STYLE_UNASSIGNED)
1339 if (!(count % 10))
1340 TA_LOG_GLOBAL((" "));
1342 TA_LOG_GLOBAL((" %d", nn));
1343 count++;
1345 if (!(count % 10))
1346 TA_LOG_GLOBAL(("\n"));
1350 if (!count)
1351 TA_LOG_GLOBAL((" (none)\n"));
1352 if (count % 10)
1353 TA_LOG_GLOBAL(("\n"));
1355 #endif /* TA_DEBUG */
1357 for (nn = 0; nn < master_globals->glyph_count; nn++)
1359 if ((gstyles[nn] & TA_STYLE_MASK) == TA_STYLE_UNASSIGNED)
1361 gstyles[nn] &= ~TA_STYLE_MASK;
1362 gstyles[nn] |= master_globals->font->fallback_style;
1366 data->adjusted = 1;
1371 #if 0
1373 void
1374 TA_sfnt_copy_master_coverage(SFNT* sfnt,
1375 FONT* font)
1377 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
1378 glyf_Data* data = (glyf_Data*)glyf_table->data;
1380 FT_Face face = sfnt->face;
1382 TA_FaceGlobals master_globals = data->master_globals;
1383 TA_FaceGlobals curr_globals = (TA_FaceGlobals)face->autohint.data;
1386 if (master_globals != curr_globals)
1388 FT_Long count = master_globals->glyph_count;
1389 FT_UShort* master = master_globals->glyph_styles;
1390 FT_UShort* curr = curr_globals->glyph_styles;
1393 memcpy(curr, master, count * sizeof (FT_UShort));
1397 #endif /* 0 */
1399 /* end of taglyf.c */