Add casts to assignments that decrease variable precision.
[ttfautohint.git] / lib / taglyf.c
bloba5f8fd5e0e2221a471c5666a4095837488c51e4c
1 /* taglyf.c */
3 /*
4 * Copyright (C) 2011-2015 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* glyph,
123 FT_Byte* buf,
124 FT_ULong len,
125 FT_UShort num_glyphs,
126 FT_Bool hint_composites)
128 FT_ULong flags_offset; /* after the loop, this is the offset */
129 /* to the last element in the flags array */
130 FT_UShort flags;
132 FT_Byte* p;
133 FT_Byte* q;
136 /* we allocate too large a buffer */
137 /* (including space for the new component */
138 /* and possible argument size changes for shifted point indices) */
139 /* and reallocate it later to its real size */
140 glyph->buf = (FT_Byte*)malloc(len + 8 + glyph->num_components * 2);
141 if (!glyph->buf)
142 return FT_Err_Out_Of_Memory;
144 p = buf;
145 q = glyph->buf;
147 /* copy header */
148 memcpy(q, p, 10);
149 p += 10;
150 q += 10;
152 /* if the composite glyph contains one or more contours, */
153 /* we prepend a composite glyph component to call some bytecode */
154 /* which eventually becomes the last glyph in the `glyf' table; */
155 /* for convenience, however, it is not added to the `components' array */
156 /* (doing so simplifies the conversion of point indices later on) */
157 if (glyph->num_composite_contours && hint_composites)
159 FT_Short x_min;
160 FT_Short x_max;
161 FT_Short y_min;
162 FT_Short y_max;
163 FT_Short x_offset;
164 FT_Short y_offset;
167 /* the composite glyph's bounding box */
168 x_min = (FT_Short)((buf[2] << 8) + buf[3]);
169 y_min = (FT_Short)((buf[4] << 8) + buf[5]);
170 x_max = (FT_Short)((buf[6] << 8) + buf[7]);
171 y_max = (FT_Short)((buf[8] << 8) + buf[9]);
173 /* use ARGS_ARE_WORDS only if necessary; */
174 /* note that the offset value of the component doesn't matter */
175 /* as long as it stays within the bounding box */
176 if (x_min <= 0 && x_max >= 0)
177 x_offset = 0;
178 else if (x_max < 0)
179 x_offset = x_max;
180 else
181 x_offset = x_min;
183 if (y_min <= 0 && y_max >= 0)
184 y_offset = 0;
185 else if (y_max < 0)
186 y_offset = y_max;
187 else
188 y_offset = y_min;
190 if (x_offset >= -128 && x_offset <= 127
191 && y_offset >= -128 && y_offset <= 127)
193 *(q++) = 0x00;
194 *(q++) = ARGS_ARE_XY_VALUES | MORE_COMPONENTS;
195 *(q++) = HIGH(num_glyphs - 1);
196 *(q++) = LOW(num_glyphs - 1);
197 *(q++) = (FT_Byte)x_offset;
198 *(q++) = (FT_Byte)y_offset;
200 else
202 *(q++) = 0x00;
203 *(q++) = ARGS_ARE_WORDS | ARGS_ARE_XY_VALUES | MORE_COMPONENTS;
204 *(q++) = HIGH(num_glyphs - 1);
205 *(q++) = LOW(num_glyphs - 1);
206 *(q++) = HIGH(x_offset);
207 *(q++) = LOW(x_offset);
208 *(q++) = HIGH(y_offset);
209 *(q++) = LOW(y_offset);
213 /* walk over component records */
216 flags_offset = q - glyph->buf;
218 *(q++) = *p;
219 *(q++) = *(p + 1);
220 flags = NEXT_USHORT(p);
222 /* copy component */
223 *(q++) = *(p++);
224 *(q++) = *(p++);
226 if (flags & ARGS_ARE_XY_VALUES)
228 /* copy offsets */
229 *(q++) = *(p++);
230 *(q++) = *(p++);
232 if (flags & ARGS_ARE_WORDS)
234 *(q++) = *(p++);
235 *(q++) = *(p++);
238 else
240 /* handle point numbers */
241 FT_UShort arg1;
242 FT_UShort arg2;
243 FT_UShort i;
246 if (flags & ARGS_ARE_WORDS)
248 arg1 = *(p++) >> 8;
249 arg1 += *(p++);
250 arg2 = *(p++) >> 8;
251 arg2 += *(p++);
253 else
255 arg1 = *(p++);
256 arg2 = *(p++);
259 /* adjust point numbers */
260 /* (see `TA_adjust_point_index' in `tabytecode.c' for more) */
261 for (i = 0; i < glyph->num_pointsums; i++)
262 if (arg1 < glyph->pointsums[i])
263 break;
264 arg1 += i;
266 for (i = 0; i < glyph->num_pointsums; i++)
267 if (arg2 < glyph->pointsums[i])
268 break;
269 arg2 += i;
271 if (arg1 <= 0xFF && arg2 <= 0xFF)
273 glyph->buf[flags_offset + 1] &= ~ARGS_ARE_WORDS;
275 *(q++) = (FT_Byte)arg1;
276 *(q++) = (FT_Byte)arg2;
278 else
280 glyph->buf[flags_offset + 1] |= ARGS_ARE_WORDS;
282 *(q++) = HIGH(arg1);
283 *(q++) = LOW(arg1);
284 *(q++) = HIGH(arg2);
285 *(q++) = LOW(arg2);
289 /* copy scaling arguments */
290 if (flags & (WE_HAVE_A_SCALE | WE_HAVE_AN_XY_SCALE | WE_HAVE_A_2X2))
292 *(q++) = *(p++);
293 *(q++) = *(p++);
295 if (flags & (WE_HAVE_AN_XY_SCALE | WE_HAVE_A_2X2))
297 *(q++) = *(p++);
298 *(q++) = *(p++);
300 if (flags & WE_HAVE_A_2X2)
302 *(q++) = *(p++);
303 *(q++) = *(p++);
304 *(q++) = *(p++);
305 *(q++) = *(p++);
307 } while (flags & MORE_COMPONENTS);
309 glyph->len1 = q - glyph->buf;
310 /* glyph->len2 = 0; */
311 glyph->flags_offset = flags_offset;
312 glyph->buf = (FT_Byte*)realloc(glyph->buf, glyph->len1);
314 /* we discard instructions (if any) */
315 glyph->buf[glyph->flags_offset] &= ~(WE_HAVE_INSTR >> 8);
317 return TA_Err_Ok;
321 static FT_Error
322 TA_glyph_parse_simple(GLYPH* glyph,
323 FT_Byte* buf,
324 FT_ULong len)
326 FT_ULong ins_offset;
327 FT_Byte* flags_start;
329 FT_UShort num_ins;
331 FT_ULong flags_size; /* size of the flags array */
332 FT_ULong xy_size; /* size of x and y coordinate arrays together */
334 FT_Byte* p;
335 FT_Byte* endp;
337 FT_UShort i;
340 p = buf;
341 endp = buf + len;
343 ins_offset = 10 + glyph->num_contours * 2;
345 p += ins_offset;
347 if (p + 2 > endp)
348 return FT_Err_Invalid_Table;
350 /* get number of instructions */
351 num_ins = NEXT_USHORT(p);
353 /* assure that we don't process a font */
354 /* which already contains a `.ttfautohint' glyph */
355 /* (a font with a `post' table version 3.0 doesn't contain glyph names, */
356 /* so we have to check it this way) */
357 if (glyph->num_points == 1
358 && num_ins >= sizeof (ttfautohint_glyph_bytecode))
360 if (!strncmp((char*)p, (char*)ttfautohint_glyph_bytecode,
361 sizeof (ttfautohint_glyph_bytecode)))
362 return TA_Err_Already_Processed;
365 p += num_ins;
367 if (p > endp)
368 return FT_Err_Invalid_Table;
370 flags_start = p;
371 xy_size = 0;
372 i = 0;
374 while (i < glyph->num_points)
376 FT_Byte flags;
377 FT_Byte x_short;
378 FT_Byte y_short;
379 FT_Byte have_x;
380 FT_Byte have_y;
381 FT_UInt count;
384 if (p + 1 > endp)
385 return FT_Err_Invalid_Table;
387 flags = *(p++);
389 x_short = (flags & X_SHORT_VECTOR) ? 1 : 2;
390 y_short = (flags & Y_SHORT_VECTOR) ? 1 : 2;
392 have_x = ((flags & SAME_X) && !(flags & X_SHORT_VECTOR)) ? 0 : 1;
393 have_y = ((flags & SAME_Y) && !(flags & Y_SHORT_VECTOR)) ? 0 : 1;
395 count = 1;
397 if (flags & REPEAT)
399 if (p + 1 > endp)
400 return FT_Err_Invalid_Table;
402 count += *(p++);
404 if (i + count > glyph->num_points)
405 return FT_Err_Invalid_Table;
408 xy_size += count * x_short * have_x;
409 xy_size += count * y_short * have_y;
411 i += count;
414 if (p + xy_size > endp)
415 return FT_Err_Invalid_Table;
417 flags_size = p - flags_start;
419 /* store the data before and after the bytecode instructions */
420 /* in the same array */
421 glyph->len1 = ins_offset;
422 glyph->len2 = flags_size + xy_size;
423 glyph->buf = (FT_Byte*)malloc(glyph->len1 + glyph->len2);
424 if (!glyph->buf)
425 return FT_Err_Out_Of_Memory;
427 /* now copy everything but the instructions */
428 memcpy(glyph->buf, buf, glyph->len1);
429 memcpy(glyph->buf + glyph->len1, flags_start, glyph->len2);
431 return TA_Err_Ok;
435 static FT_Error
436 TA_iterate_composite_glyph(glyf_Data* data,
437 FT_UShort* components,
438 FT_UShort num_components,
439 FT_UShort** pointsums,
440 FT_UShort* num_pointsums,
441 FT_UShort* num_composite_contours,
442 FT_UShort* num_composite_points)
444 FT_UShort* pointsums_new;
445 FT_UShort i;
448 /* save current state */
450 if (*num_pointsums == 0xFFFF)
451 return FT_Err_Invalid_Table;
453 (*num_pointsums)++;
454 pointsums_new = (FT_UShort*)realloc(*pointsums,
455 *num_pointsums
456 * sizeof (FT_UShort));
457 if (!pointsums_new)
459 (*num_pointsums)--;
460 return FT_Err_Out_Of_Memory;
462 else
463 *pointsums = pointsums_new;
465 (*pointsums)[*num_pointsums - 1] = *num_composite_points;
467 for (i = 0; i < num_components; i++)
469 GLYPH* glyph;
470 FT_UShort component = components[i];
471 FT_Error error;
474 if (component >= data->num_glyphs)
475 return FT_Err_Invalid_Table;
477 glyph = &data->glyphs[component];
479 if (glyph->num_components)
481 error = TA_iterate_composite_glyph(data,
482 glyph->components,
483 glyph->num_components,
484 pointsums,
485 num_pointsums,
486 num_composite_contours,
487 num_composite_points);
488 if (error)
489 return error;
491 else
493 /* no need for checking overflow of the number of contours */
494 /* since the number of points is always larger or equal */
495 if (*num_composite_points > 0xFFFF - glyph->num_points)
496 return FT_Err_Invalid_Table;
498 *num_composite_contours += glyph->num_contours;
499 *num_composite_points += glyph->num_points;
503 return TA_Err_Ok;
507 static FT_Error
508 TA_sfnt_compute_composite_pointsums(SFNT* sfnt,
509 FONT* font)
511 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
512 glyf_Data* data = (glyf_Data*)glyf_table->data;
514 FT_UShort i;
517 for (i = 0; i < data->num_glyphs; i++)
519 GLYPH* glyph = &data->glyphs[i];
522 if (glyph->num_components)
524 FT_Error error;
525 FT_UShort num_composite_contours = 0;
526 FT_UShort num_composite_points = 0;
529 error = TA_iterate_composite_glyph(data,
530 glyph->components,
531 glyph->num_components,
532 &glyph->pointsums,
533 &glyph->num_pointsums,
534 &num_composite_contours,
535 &num_composite_points);
536 if (error)
537 return error;
539 glyph->num_composite_contours = num_composite_contours;
541 if (font->hint_composites)
543 /* update maximum values, */
544 /* including the subglyphs not in `components' array */
545 /* (each of them has a single point in a single contour) */
546 if (num_composite_points + glyph->num_pointsums
547 > sfnt->max_composite_points)
548 sfnt->max_composite_points = num_composite_points
549 + glyph->num_pointsums;
550 if (num_composite_contours + glyph->num_pointsums
551 > sfnt->max_composite_contours)
552 sfnt->max_composite_contours = num_composite_contours
553 + glyph->num_pointsums;
558 return TA_Err_Ok;
562 FT_Error
563 TA_sfnt_split_glyf_table(SFNT* sfnt,
564 FONT* font)
566 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
567 SFNT_Table* loca_table = &font->tables[sfnt->loca_idx];
568 SFNT_Table* head_table = &font->tables[sfnt->head_idx];
570 glyf_Data* data;
571 FT_Byte loca_format;
573 FT_ULong offset;
574 FT_ULong offset_next;
576 FT_Byte* p;
577 FT_UShort i;
578 FT_UShort loop_count;
580 FT_Error error;
583 /* in case of success, all allocated arrays are */
584 /* linked and eventually freed in `TA_font_unload' */
586 /* nothing to do if table has already been split */
587 if (glyf_table->data)
588 return TA_Err_Ok;
590 data = (glyf_Data*)calloc(1, sizeof (glyf_Data));
591 if (!data)
592 return FT_Err_Out_Of_Memory;
594 glyf_table->data = data;
596 loca_format = head_table->buf[LOCA_FORMAT_OFFSET];
598 data->num_glyphs = (FT_UShort)(loca_format ? loca_table->len / 4
599 : loca_table->len / 2);
600 loop_count = data->num_glyphs - 1;
602 /* allocate one more glyph slot if we have composite glyphs */
603 if (!sfnt->max_components || !font->hint_composites)
604 data->num_glyphs -= 1;
605 data->glyphs = (GLYPH*)calloc(1, data->num_glyphs * sizeof (GLYPH));
606 if (!data->glyphs)
607 return FT_Err_Out_Of_Memory;
609 data->master_globals = NULL;
610 data->cvt_idx = MISSING;
611 data->fpgm_idx = MISSING;
612 data->prep_idx = MISSING;
614 /* first loop over `loca' and `glyf' data */
616 p = loca_table->buf;
618 if (loca_format)
619 offset_next = NEXT_ULONG(p);
620 else
622 offset_next = NEXT_USHORT(p);
623 offset_next <<= 1;
626 for (i = 0; i < loop_count; i++)
628 GLYPH* glyph = &data->glyphs[i];
629 FT_ULong len;
632 offset = offset_next;
634 if (loca_format)
635 offset_next = NEXT_ULONG(p);
636 else
638 offset_next = NEXT_USHORT(p);
639 offset_next <<= 1;
642 if (offset_next < offset
643 || offset_next > glyf_table->len)
644 return FT_Err_Invalid_Table;
646 len = offset_next - offset;
647 if (!len)
648 continue; /* empty glyph */
649 else
651 FT_Byte* buf;
654 /* check header size */
655 if (len < 10)
656 return FT_Err_Invalid_Table;
658 /* we need the number of contours and points for */
659 /* `TA_sfnt_compute_composite_pointsums' */
660 buf = glyf_table->buf + offset;
661 glyph->num_contours = (FT_Short)((buf[0] << 8) + buf[1]);
663 if (glyph->num_contours < 0)
665 error = TA_glyph_get_components(glyph, buf, len);
666 if (error)
667 return error;
669 else
671 FT_ULong off;
674 /* use the last contour's end point to compute number of points */
675 off = 10 + (glyph->num_contours - 1) * 2;
676 if (off >= len - 1)
677 return FT_Err_Invalid_Table;
679 glyph->num_points = (FT_UShort)((buf[off] << 8) + buf[off + 1] + 1);
684 if (sfnt->max_components && font->hint_composites)
686 error = TA_sfnt_compute_composite_pointsums(sfnt, font);
687 if (error)
688 return error;
691 /* second loop over `loca' and `glyf' data */
693 p = loca_table->buf;
695 if (loca_format)
696 offset_next = NEXT_ULONG(p);
697 else
699 offset_next = NEXT_USHORT(p);
700 offset_next <<= 1;
703 for (i = 0; i < loop_count; i++)
705 GLYPH* glyph = &data->glyphs[i];
706 FT_ULong len;
709 offset = offset_next;
711 if (loca_format)
712 offset_next = NEXT_ULONG(p);
713 else
715 offset_next = NEXT_USHORT(p);
716 offset_next <<= 1;
719 len = offset_next - offset;
720 if (!len)
721 continue; /* empty glyph */
722 else
724 FT_Byte* buf;
727 buf = glyf_table->buf + offset;
729 /* We must parse the rest of the glyph record to get the exact */
730 /* record length. Since the `loca' table rounds record lengths */
731 /* up to multiples of 4 (or 2 for older fonts), and we must round */
732 /* up again after stripping off the instructions, it would be */
733 /* possible otherwise to have more than 4 bytes of padding which */
734 /* is more or less invalid. */
736 if (glyph->num_contours < 0)
737 error = TA_glyph_parse_composite(glyph, buf, len,
738 data->num_glyphs,
739 font->hint_composites);
740 else
741 error = TA_glyph_parse_simple(glyph, buf, len);
742 if (error)
743 return error;
747 if (sfnt->max_components && font->hint_composites)
749 /* construct and append our special glyph used as a composite element */
750 GLYPH* glyph = &data->glyphs[data->num_glyphs - 1];
751 FT_Byte* buf;
753 glyph->len1 = 12;
754 glyph->len2 = 1;
755 glyph->buf = (FT_Byte*)malloc(glyph->len1 + glyph->len2);
756 if (!glyph->buf)
757 return FT_Err_Out_Of_Memory;
759 buf = glyph->buf;
761 buf[0] = 0x00; /* one contour */
762 buf[1] = 0x01;
763 buf[2] = 0x00; /* no dimensions */
764 buf[3] = 0x00;
765 buf[4] = 0x00;
766 buf[5] = 0x00;
767 buf[6] = 0x00;
768 buf[7] = 0x00;
769 buf[8] = 0x00;
770 buf[9] = 0x00;
771 buf[10] = 0x00; /* one contour end point */
772 buf[11] = 0x00;
774 buf[12] = ON_CURVE | SAME_X | SAME_Y; /* the flags for a point at 0,0 */
776 /* add bytecode also; */
777 /* this works because the loop in `TA_sfnt_build_glyf_hints' */
778 /* doesn't include the newly appended glyph */
779 glyph->ins_len = sizeof (ttfautohint_glyph_bytecode);
780 glyph->ins_buf = (FT_Byte*)malloc(glyph->ins_len);
781 if (!glyph->ins_buf)
782 return FT_Err_Out_Of_Memory;
783 memcpy(glyph->ins_buf, ttfautohint_glyph_bytecode, glyph->ins_len);
785 sfnt->max_components += 1;
788 return TA_Err_Ok;
792 FT_Error
793 TA_sfnt_build_glyf_table(SFNT* sfnt,
794 FONT* font)
796 FT_Error error;
798 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
799 glyf_Data* data = (glyf_Data*)glyf_table->data;
801 GLYPH* glyph;
803 FT_ULong len;
804 FT_Byte* buf_new;
805 FT_Byte* p;
806 FT_UShort i;
809 if (glyf_table->processed)
810 return TA_Err_Ok;
812 if (!font->dehint)
814 error = TA_sfnt_build_glyf_hints(sfnt, font);
815 if (error)
816 return error;
819 /* get table size */
820 len = 0;
821 glyph = data->glyphs;
822 for (i = 0; i < data->num_glyphs; i++, glyph++)
824 /* glyph records should have offsets which are multiples of 4 */
825 len = (len + 3) & ~3U;
826 len += glyph->len1 + glyph->len2
827 + glyph->ins_extra_len + glyph->ins_len;
828 /* add two bytes for the instructionLength field */
829 if (glyph->len2 || glyph->ins_len)
830 len += 2;
833 /* to make the short format of the `loca' table always work, */
834 /* assure an even length of the `glyf' table */
835 glyf_table->len = (len + 1) & ~1U;
837 buf_new = (FT_Byte*)realloc(glyf_table->buf, (len + 3) & ~3U);
838 if (!buf_new)
839 return FT_Err_Out_Of_Memory;
840 else
841 glyf_table->buf = buf_new;
843 p = glyf_table->buf;
844 glyph = data->glyphs;
845 for (i = 0; i < data->num_glyphs; i++, glyph++)
847 len = glyph->len1 + glyph->len2
848 + glyph->ins_extra_len + glyph->ins_len;
849 if (glyph->len2 || glyph->ins_len)
850 len += 2;
852 if (len)
854 /* copy glyph data and insert new instructions */
855 memcpy(p, glyph->buf, glyph->len1);
857 if (glyph->len2)
859 /* simple glyph */
860 p += glyph->len1;
861 *(p++) = HIGH(glyph->ins_extra_len + glyph->ins_len);
862 *(p++) = LOW(glyph->ins_extra_len + glyph->ins_len);
863 if (glyph->ins_extra_len)
865 memcpy(p, ins_extra_buf, glyph->ins_extra_len);
866 p += glyph->ins_extra_len;
868 memcpy(p, glyph->ins_buf, glyph->ins_len);
869 p += glyph->ins_len;
870 memcpy(p, glyph->buf + glyph->len1, glyph->len2);
871 p += glyph->len2;
873 else
875 /* composite glyph */
876 if (glyph->ins_len)
878 *(p + glyph->flags_offset) |= (WE_HAVE_INSTR >> 8);
879 p += glyph->len1;
880 *(p++) = HIGH(glyph->ins_extra_len + glyph->ins_len);
881 *(p++) = LOW(glyph->ins_extra_len + glyph->ins_len);
882 if (glyph->ins_extra_len)
884 memcpy(p, ins_extra_buf, glyph->ins_extra_len);
885 p += glyph->ins_extra_len;
887 memcpy(p, glyph->ins_buf, glyph->ins_len);
888 p += glyph->ins_len;
890 else
891 p += glyph->len1;
894 /* pad with zero bytes to have an offset which is a multiple of 4; */
895 /* this works even for the last glyph record since the `glyf' */
896 /* table length is a multiple of 4 also */
897 switch (len % 4)
899 case 1:
900 *(p++) = 0;
901 case 2:
902 *(p++) = 0;
903 case 3:
904 *(p++) = 0;
905 default:
906 break;
911 glyf_table->checksum = TA_table_compute_checksum(glyf_table->buf,
912 glyf_table->len);
913 glyf_table->processed = 1;
915 return TA_Err_Ok;
919 static FT_Error
920 TA_create_glyph_data(FT_Outline* outline,
921 GLYPH* glyph)
923 FT_Error error = TA_Err_Ok;
925 FT_Pos xmin, ymin;
926 FT_Pos xmax, ymax;
928 FT_Byte header[10];
929 FT_Byte* flags = NULL;
930 FT_Byte* flagsp;
931 FT_Byte oldf, f;
932 FT_Byte* x = NULL;
933 FT_Byte* xp;
934 FT_Byte* y = NULL;
935 FT_Byte* yp;
937 FT_Pos lastx, lasty;
939 FT_Short i;
940 FT_Byte* p;
943 if (!outline->n_contours)
944 return TA_Err_Ok; /* empty glyph */
946 /* in case of success, all non-local allocated arrays are */
947 /* linked and eventually freed in `TA_font_unload' */
949 glyph->buf = NULL;
951 /* we use `calloc' since we rely on the array */
952 /* being initialized to zero; */
953 /* additionally, we need one more byte for a test after the loop */
954 flags = (FT_Byte*)calloc(1, outline->n_points + 1);
955 if (!flags)
957 error = FT_Err_Out_Of_Memory;
958 goto Exit;
961 /* we have either one-byte or two-byte elements */
962 x = (FT_Byte*)malloc(2 * outline->n_points);
963 if (!x)
965 error = FT_Err_Out_Of_Memory;
966 goto Exit;
969 y = (FT_Byte*)malloc(2 * outline->n_points);
970 if (!y)
972 error = FT_Err_Out_Of_Memory;
973 goto Exit;
976 flagsp = flags;
977 xp = x;
978 yp = y;
979 xmin = xmax = (outline->points[0].x + 32) >> 6;
980 ymin = ymax = (outline->points[0].y + 32) >> 6;
981 lastx = 0;
982 lasty = 0;
983 oldf = 0x80; /* start with an impossible value */
985 /* convert the FreeType representation of the glyph's outline */
986 /* into the representation format of the `glyf' table */
987 for (i = 0; i < outline->n_points; i++)
989 FT_Pos xcur = (outline->points[i].x + 32) >> 6;
990 FT_Pos ycur = (outline->points[i].y + 32) >> 6;
992 FT_Pos xdelta = xcur - lastx;
993 FT_Pos ydelta = ycur - lasty;
996 /* we are only interested in bit 0 of the `tags' array */
997 f = outline->tags[i] & ON_CURVE;
999 /* x value */
1001 if (xdelta == 0)
1002 f |= SAME_X;
1003 else
1005 if (xdelta < 256 && xdelta > -256)
1007 f |= X_SHORT_VECTOR;
1009 if (xdelta < 0)
1010 xdelta = -xdelta;
1011 else
1012 f |= SAME_X;
1014 *(xp++) = (FT_Byte)xdelta;
1016 else
1018 *(xp++) = HIGH(xdelta);
1019 *(xp++) = LOW(xdelta);
1023 /* y value */
1025 if (ydelta == 0)
1026 f |= SAME_Y;
1027 else
1029 if (ydelta < 256 && ydelta > -256)
1031 f |= Y_SHORT_VECTOR;
1033 if (ydelta < 0)
1034 ydelta = -ydelta;
1035 else
1036 f |= SAME_Y;
1038 *(yp++) = (FT_Byte)ydelta;
1040 else
1042 *(yp++) = HIGH(ydelta);
1043 *(yp++) = LOW(ydelta);
1047 if (f == oldf)
1049 /* set repeat flag */
1050 *(flagsp - 1) |= REPEAT;
1052 if (*flagsp == 255)
1054 /* we can only handle 256 repetitions at once, */
1055 /* so use a new counter */
1056 flagsp++;
1057 *(flagsp++) = f;
1059 else
1060 *flagsp += 1; /* increase repetition counter */
1062 else
1064 if (*flagsp)
1065 flagsp++; /* skip repetition counter */
1066 *(flagsp++) = f;
1067 oldf = f;
1070 if (xcur > xmax)
1071 xmax = xcur;
1072 if (ycur > ymax)
1073 ymax = ycur;
1074 if (xcur < xmin)
1075 xmin = xcur;
1076 if (ycur < ymin)
1077 ymin = ycur;
1079 lastx = xcur;
1080 lasty = ycur;
1083 /* if the last byte was a repetition counter, */
1084 /* we must increase by one to get the correct array size */
1085 if (*flagsp)
1086 flagsp++;
1088 header[0] = HIGH(outline->n_contours);
1089 header[1] = LOW(outline->n_contours);
1090 header[2] = HIGH(xmin);
1091 header[3] = LOW(xmin);
1092 header[4] = HIGH(ymin);
1093 header[5] = LOW(ymin);
1094 header[6] = HIGH(xmax);
1095 header[7] = LOW(xmax);
1096 header[8] = HIGH(ymax);
1097 header[9] = LOW(ymax);
1099 /* concatenate all arrays and fill needed GLYPH structure elements */
1101 glyph->len1 = 10 + 2 * outline->n_contours;
1102 glyph->len2 = (flagsp - flags) + (xp - x) + (yp - y);
1104 glyph->buf = (FT_Byte*)malloc(glyph->len1 + glyph->len2);
1105 if (!glyph->buf)
1107 error = FT_Err_Out_Of_Memory;
1108 goto Exit;
1111 p = glyph->buf;
1112 memcpy(p, header, 10);
1113 p += 10;
1115 glyph->ins_extra_len = 0;
1116 glyph->ins_len = 0;
1117 glyph->ins_buf = NULL;
1119 for (i = 0; i < outline->n_contours; i++)
1121 *(p++) = HIGH(outline->contours[i]);
1122 *(p++) = LOW(outline->contours[i]);
1125 memcpy(p, flags, flagsp - flags);
1126 p += flagsp - flags;
1127 memcpy(p, x, xp - x);
1128 p += xp - x;
1129 memcpy(p, y, yp - y);
1131 Exit:
1132 free(flags);
1133 free(x);
1134 free(y);
1136 return error;
1140 /* We hint each glyph at EM size and construct a new `glyf' table. */
1141 /* Some fonts need this; in particular, */
1142 /* there are CJK fonts which use hints to scale and position subglyphs. */
1143 /* As a consequence, there are no longer composite glyphs. */
1145 FT_Error
1146 TA_sfnt_create_glyf_data(SFNT* sfnt,
1147 FONT* font)
1149 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
1150 FT_Face face = sfnt->face;
1151 FT_Error error;
1153 glyf_Data* data;
1155 FT_UShort i;
1158 /* in case of success, all allocated arrays are */
1159 /* linked and eventually freed in `TA_font_unload' */
1161 /* nothing to do if table has already been created */
1162 if (glyf_table->data)
1163 return TA_Err_Ok;
1165 data = (glyf_Data*)calloc(1, sizeof (glyf_Data));
1166 if (!data)
1167 return FT_Err_Out_Of_Memory;
1169 glyf_table->data = data;
1171 data->num_glyphs = (FT_UShort)face->num_glyphs;
1172 data->glyphs = (GLYPH*)calloc(1, data->num_glyphs * sizeof (GLYPH));
1173 if (!data->glyphs)
1174 return FT_Err_Out_Of_Memory;
1176 /* XXX: Make size configurable */
1177 /* we use the EM size */
1178 /* so that the resulting coordinates can be used without transformation */
1179 error = FT_Set_Char_Size(face, face->units_per_EM * 64, 0, 72, 0);
1180 if (error)
1181 return error;
1183 /* loop over all glyphs in font face */
1184 for (i = 0; i < data->num_glyphs; i++)
1186 GLYPH* glyph = &data->glyphs[i];
1189 error = FT_Load_Glyph(face, i, FT_LOAD_NO_BITMAP | FT_LOAD_NO_AUTOHINT);
1190 if (error)
1191 return error;
1193 error = TA_create_glyph_data(&face->glyph->outline, glyph);
1194 if (error)
1195 return error;
1198 return TA_Err_Ok;
1203 * While the auto-hinter is glyph oriented (this is, using `glyf' data), it
1204 * relies on the `cmap' table and OpenType features to get style coverage
1205 * data. In TTCs, subfonts normally share the same `glyf' table but use
1206 * different `cmap's and OpenType features (in `GSUB' and `GPOS' tables).
1207 * To handle this gracefully, ttfautohint collects (and merges) the coverage
1208 * information in the `glyf_Data' structure.
1211 FT_Error
1212 TA_sfnt_handle_coverage(SFNT* sfnt,
1213 FONT* font)
1215 FT_Error error;
1217 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
1218 glyf_Data* data = (glyf_Data*)glyf_table->data;
1220 FT_Face face = sfnt->face;
1221 TA_FaceGlobals curr_globals;
1223 TA_Style saved_fallback_style = font->fallback_style;
1226 /* using TA_STYLE_UNASSIGNED as the fallback style ensures */
1227 /* that uncovered glyphs stay as-is */
1228 /* (we handle the fallback style later on) */
1229 font->fallback_style = (TA_Style)TA_STYLE_UNASSIGNED;
1231 /* trigger computation of coverage */
1232 error = ta_loader_init(font);
1233 if (error)
1234 goto Exit;
1235 error = ta_loader_reset(font, face);
1236 if (error)
1237 goto Exit;
1238 ta_loader_done(font);
1240 font->fallback_style = saved_fallback_style;
1241 curr_globals = (TA_FaceGlobals)face->autohint.data;
1243 if (!data->master_globals)
1245 /* initialize */
1246 data->master_globals = curr_globals;
1247 goto Exit;
1250 /* we have the same `glyf' table for another subfont; */
1251 /* merge the current coverage info into the `master' coverage info */
1253 TA_FaceGlobals master_globals = data->master_globals;
1254 FT_Long count = master_globals->glyph_count;
1256 FT_Byte* master = master_globals->glyph_styles;
1257 FT_Byte* curr = curr_globals->glyph_styles;
1259 FT_Byte* limit = master + count;
1262 /* we simply copy the data, */
1263 /* assuming that a given glyph always has the same properties -- */
1264 /* as soon as we make the style selection more fine-grained, */
1265 /* it is possible that this assumption doesn't hold: */
1266 /* for example, glyph `A' can be used for both Cyrillic and Latin */
1267 while (master < limit)
1269 if ((*curr & ~TA_DIGIT) != TA_STYLE_UNASSIGNED)
1270 *master = *curr;
1272 master++;
1273 curr++;
1277 Exit:
1278 return error;
1282 void
1283 TA_sfnt_adjust_coverage(SFNT* sfnt,
1284 FONT* font)
1286 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
1287 glyf_Data* data = (glyf_Data*)glyf_table->data;
1289 TA_FaceGlobals master_globals = data->master_globals;
1292 /* use fallback style for uncovered glyphs */
1293 if (!data->adjusted)
1295 FT_Long nn;
1296 FT_Byte* gstyles = master_globals->glyph_styles;
1297 #ifdef TA_DEBUG
1298 FT_UInt count;
1299 #endif
1302 for (nn = 0; nn < master_globals->glyph_count; nn++)
1304 if ((gstyles[nn] & ~TA_DIGIT) == TA_STYLE_UNASSIGNED)
1306 gstyles[nn] &= ~TA_STYLE_UNASSIGNED;
1307 gstyles[nn] |= master_globals->font->fallback_style;
1311 #ifdef TA_DEBUG
1313 if (sfnt->face->num_faces > 1)
1314 TA_LOG_GLOBAL(("\n"
1315 "using fallback style `%s' for unassigned glyphs"
1316 " (glyf table index %d):\n",
1317 ta_style_names[master_globals->font->fallback_style],
1318 sfnt->glyf_idx));
1319 else
1320 TA_LOG_GLOBAL(("\n"
1321 "using fallback style `%s' for unassigned glyphs:\n",
1322 ta_style_names[master_globals->font->fallback_style]));
1324 count = 0;
1326 for (nn = 0; nn < master_globals->glyph_count; nn++)
1328 if ((gstyles[nn] & ~TA_DIGIT) == master_globals->font->fallback_style)
1330 if (!(count % 10))
1331 TA_LOG_GLOBAL((" "));
1333 TA_LOG_GLOBAL((" %d", nn));
1334 count++;
1336 if (!(count % 10))
1337 TA_LOG_GLOBAL(("\n"));
1341 if (!count)
1342 TA_LOG_GLOBAL((" (none)\n"));
1343 if (count % 10)
1344 TA_LOG_GLOBAL(("\n"));
1346 #endif /* TA_DEBUG */
1348 data->adjusted = 1;
1353 #if 0
1355 void
1356 TA_sfnt_copy_master_coverage(SFNT* sfnt,
1357 FONT* font)
1359 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
1360 glyf_Data* data = (glyf_Data*)glyf_table->data;
1362 FT_Face face = sfnt->face;
1364 TA_FaceGlobals master_globals = data->master_globals;
1365 TA_FaceGlobals curr_globals = (TA_FaceGlobals)face->autohint.data;
1368 if (master_globals != curr_globals)
1370 FT_Long count = master_globals->glyph_count;
1371 FT_Byte* master = master_globals->glyph_styles;
1372 FT_Byte* curr = curr_globals->glyph_styles;
1375 memcpy(curr, master, count);
1379 #endif /* 0 */
1381 /* end of taglyf.c */