Add `dehint' option to library.
[ttfautohint.git] / lib / taglyf.c
blob6797d7eb0c30168dac0ae88c183aba43e3610597
1 /* taglyf.c */
3 /*
4 * Copyright (C) 2011-2013 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 FT_Face face = sfnt->face;
24 FT_Long idx;
25 FT_Error error;
28 /* this loop doesn't include the artificial `.ttfautohint' glyph */
29 for (idx = 0; idx < face->num_glyphs; idx++)
31 error = TA_sfnt_build_glyph_instructions(sfnt, font, idx);
32 if (error)
33 return error;
34 if (font->progress)
36 FT_Int ret;
39 ret = font->progress(idx, face->num_glyphs,
40 sfnt - font->sfnts, font->num_sfnts,
41 font->progress_data);
42 if (ret)
43 return TA_Err_Canceled;
47 return FT_Err_Ok;
51 static FT_Error
52 TA_glyph_get_components(GLYPH* glyph,
53 FT_Byte* buf,
54 FT_ULong len)
56 FT_UShort flags;
57 FT_UShort component;
58 FT_UShort* components_new;
60 FT_Byte* p;
61 FT_Byte* endp;
64 p = buf;
65 endp = buf + len;
67 /* skip header */
68 p += 10;
70 /* walk over component records */
73 if (p + 4 > endp)
74 return FT_Err_Invalid_Table;
76 flags = *(p++) << 8;
77 flags += *(p++);
79 /* add component to list */
80 component = *(p++) << 8;
81 component += *(p++);
83 glyph->num_components++;
84 components_new = (FT_UShort*)realloc(glyph->components,
85 glyph->num_components
86 * sizeof (FT_UShort));
87 if (!components_new)
89 glyph->num_components--;
90 return FT_Err_Out_Of_Memory;
92 else
93 glyph->components = components_new;
95 glyph->components[glyph->num_components - 1] = component;
97 /* skip scaling and offset arguments */
98 if (flags & ARGS_ARE_WORDS)
99 p += 4;
100 else
101 p += 2;
103 if (flags & WE_HAVE_A_SCALE)
104 p += 2;
105 else if (flags & WE_HAVE_AN_XY_SCALE)
106 p += 4;
107 else if (flags & WE_HAVE_A_2X2)
108 p += 8;
109 } while (flags & MORE_COMPONENTS);
111 return TA_Err_Ok;
115 static FT_Error
116 TA_glyph_parse_composite(GLYPH* glyph,
117 FT_Byte* buf,
118 FT_ULong len,
119 FT_UShort num_glyphs,
120 FT_Bool hint_with_components)
122 FT_ULong flags_offset; /* after the loop, this is the offset */
123 /* to the last element in the flags array */
124 FT_UShort flags;
126 FT_Byte* p;
127 FT_Byte* q;
130 /* we allocate too large a buffer */
131 /* (including space for the new component */
132 /* and possible argument size changes for shifted point indices) */
133 /* and reallocate it later to its real size */
134 glyph->buf = (FT_Byte*)malloc(len + 8 + glyph->num_components * 2);
135 if (!glyph->buf)
136 return FT_Err_Out_Of_Memory;
138 p = buf;
139 q = glyph->buf;
141 /* copy header */
142 memcpy(q, p, 10);
143 p += 10;
144 q += 10;
146 /* if the composite glyph contains one or more contours, */
147 /* we prepend a composite glyph component to call some bytecode */
148 /* which eventually becomes the last glyph in the `glyf' table; */
149 /* for convenience, however, it is not added to the `components' array */
150 /* (doing so simplifies the conversion of point indices later on) */
151 if (glyph->num_composite_contours && hint_with_components)
153 FT_Short x_min;
154 FT_Short x_max;
155 FT_Short y_min;
156 FT_Short y_max;
157 FT_Short x_offset;
158 FT_Short y_offset;
161 /* the composite glyph's bounding box */
162 x_min = (FT_Short)((buf[2] << 8) + buf[3]);
163 y_min = (FT_Short)((buf[4] << 8) + buf[5]);
164 x_max = (FT_Short)((buf[6] << 8) + buf[7]);
165 y_max = (FT_Short)((buf[8] << 8) + buf[9]);
167 /* use ARGS_ARE_WORDS only if necessary; */
168 /* note that the offset value of the component doesn't matter */
169 /* as long as it stays within the bounding box */
170 if (x_min <= 0 && x_max >= 0)
171 x_offset = 0;
172 else if (x_max < 0)
173 x_offset = x_max;
174 else
175 x_offset = x_min;
177 if (y_min <= 0 && y_max >= 0)
178 y_offset = 0;
179 else if (y_max < 0)
180 y_offset = y_max;
181 else
182 y_offset = y_min;
184 if (x_offset >= -128 && x_offset <= 127
185 && y_offset >= -128 && y_offset <= 127)
187 *(q++) = 0x00;
188 *(q++) = ARGS_ARE_XY_VALUES | MORE_COMPONENTS;
189 *(q++) = HIGH(num_glyphs - 1);
190 *(q++) = LOW(num_glyphs - 1);
191 *(q++) = x_offset;
192 *(q++) = y_offset;
194 else
196 *(q++) = 0x00;
197 *(q++) = ARGS_ARE_WORDS | ARGS_ARE_XY_VALUES | MORE_COMPONENTS;
198 *(q++) = HIGH(num_glyphs - 1);
199 *(q++) = LOW(num_glyphs - 1);
200 *(q++) = HIGH(x_offset);
201 *(q++) = LOW(x_offset);
202 *(q++) = HIGH(y_offset);
203 *(q++) = LOW(y_offset);
207 /* walk over component records */
210 flags_offset = q - glyph->buf;
212 *(q++) = *p;
213 flags = *(p++) << 8;
214 *(q++) = *p;
215 flags += *(p++);
217 /* copy component */
218 *(q++) = *(p++);
219 *(q++) = *(p++);
221 if (flags & ARGS_ARE_XY_VALUES)
223 /* copy offsets */
224 *(q++) = *(p++);
225 *(q++) = *(p++);
227 if (flags & ARGS_ARE_WORDS)
229 *(q++) = *(p++);
230 *(q++) = *(p++);
233 else
235 /* handle point numbers */
236 FT_UShort arg1;
237 FT_UShort arg2;
238 FT_UShort i;
241 if (flags & ARGS_ARE_WORDS)
243 arg1 = *(p++) >> 8;
244 arg1 += *(p++);
245 arg2 = *(p++) >> 8;
246 arg2 += *(p++);
248 else
250 arg1 = *(p++);
251 arg2 = *(p++);
254 /* adjust point numbers */
255 /* (see `TA_adjust_point_index' in `tabytecode.c' for more) */
256 for (i = 0; i < glyph->num_pointsums; i++)
257 if (arg1 < glyph->pointsums[i])
258 break;
259 arg1 += i;
261 for (i = 0; i < glyph->num_pointsums; i++)
262 if (arg2 < glyph->pointsums[i])
263 break;
264 arg2 += i;
266 if (arg1 <= 0xFF && arg2 <= 0xFF)
268 glyph->buf[flags_offset + 1] &= ~ARGS_ARE_WORDS;
270 *(q++) = arg1;
271 *(q++) = arg2;
273 else
275 glyph->buf[flags_offset + 1] |= ARGS_ARE_WORDS;
277 *(q++) = HIGH(arg1);
278 *(q++) = LOW(arg1);
279 *(q++) = HIGH(arg2);
280 *(q++) = LOW(arg2);
284 /* copy scaling arguments */
285 if (flags & (WE_HAVE_A_SCALE | WE_HAVE_AN_XY_SCALE | WE_HAVE_A_2X2))
287 *(q++) = *(p++);
288 *(q++) = *(p++);
290 if (flags & (WE_HAVE_AN_XY_SCALE | WE_HAVE_A_2X2))
292 *(q++) = *(p++);
293 *(q++) = *(p++);
295 if (flags & WE_HAVE_A_2X2)
297 *(q++) = *(p++);
298 *(q++) = *(p++);
299 *(q++) = *(p++);
300 *(q++) = *(p++);
302 } while (flags & MORE_COMPONENTS);
304 glyph->len1 = q - glyph->buf;
305 /* glyph->len2 = 0; */
306 glyph->flags_offset = flags_offset;
307 glyph->buf = (FT_Byte*)realloc(glyph->buf, glyph->len1);
309 /* we discard instructions (if any) */
310 glyph->buf[glyph->flags_offset] &= ~(WE_HAVE_INSTR >> 8);
312 return TA_Err_Ok;
316 static FT_Error
317 TA_glyph_parse_simple(GLYPH* glyph,
318 FT_Byte* buf,
319 FT_ULong len)
321 FT_ULong ins_offset;
322 FT_Byte* flags_start;
324 FT_UShort num_ins;
326 FT_ULong flags_size; /* size of the flags array */
327 FT_ULong xy_size; /* size of x and y coordinate arrays together */
329 FT_Byte* p;
330 FT_Byte* endp;
332 FT_UShort i;
335 p = buf;
336 endp = buf + len;
338 ins_offset = 10 + glyph->num_contours * 2;
340 p += ins_offset;
342 if (p + 2 > endp)
343 return FT_Err_Invalid_Table;
345 /* get number of instructions */
346 num_ins = *(p++) << 8;
347 num_ins += *(p++);
349 /* assure that we don't process a font */
350 /* which already contains a `.ttfautohint' glyph */
351 /* (a font with a `post' table version 3.0 doesn't contain glyph names, */
352 /* so we have to check it this way) */
353 if (glyph->num_points == 1
354 && num_ins >= sizeof (ttfautohint_glyph_bytecode))
356 if (!strncmp((char*)p, (char*)ttfautohint_glyph_bytecode,
357 sizeof (ttfautohint_glyph_bytecode)))
358 return TA_Err_Already_Processed;
361 p += num_ins;
363 if (p > endp)
364 return FT_Err_Invalid_Table;
366 flags_start = p;
367 xy_size = 0;
368 i = 0;
370 while (i < glyph->num_points)
372 FT_Byte flags;
373 FT_Byte x_short;
374 FT_Byte y_short;
375 FT_Byte have_x;
376 FT_Byte have_y;
377 FT_UInt count;
380 if (p + 1 > endp)
381 return FT_Err_Invalid_Table;
383 flags = *(p++);
385 x_short = (flags & X_SHORT_VECTOR) ? 1 : 2;
386 y_short = (flags & Y_SHORT_VECTOR) ? 1 : 2;
388 have_x = ((flags & SAME_X) && !(flags & X_SHORT_VECTOR)) ? 0 : 1;
389 have_y = ((flags & SAME_Y) && !(flags & Y_SHORT_VECTOR)) ? 0 : 1;
391 count = 1;
393 if (flags & REPEAT)
395 if (p + 1 > endp)
396 return FT_Err_Invalid_Table;
398 count += *(p++);
400 if (i + count > glyph->num_points)
401 return FT_Err_Invalid_Table;
404 xy_size += count * x_short * have_x;
405 xy_size += count * y_short * have_y;
407 i += count;
410 if (p + xy_size > endp)
411 return FT_Err_Invalid_Table;
413 flags_size = p - flags_start;
415 /* store the data before and after the bytecode instructions */
416 /* in the same array */
417 glyph->len1 = ins_offset;
418 glyph->len2 = flags_size + xy_size;
419 glyph->buf = (FT_Byte*)malloc(glyph->len1 + glyph->len2);
420 if (!glyph->buf)
421 return FT_Err_Out_Of_Memory;
423 /* now copy everything but the instructions */
424 memcpy(glyph->buf, buf, glyph->len1);
425 memcpy(glyph->buf + glyph->len1, flags_start, glyph->len2);
427 return TA_Err_Ok;
431 static FT_Error
432 TA_iterate_composite_glyph(glyf_Data* data,
433 FT_UShort* components,
434 FT_UShort num_components,
435 FT_UShort** pointsums,
436 FT_UShort* num_pointsums,
437 FT_UShort* num_composite_contours,
438 FT_UShort* num_composite_points)
440 FT_UShort* pointsums_new;
441 FT_UShort i;
444 /* save current state */
446 if (*num_pointsums == 0xFFFF)
447 return FT_Err_Invalid_Table;
449 (*num_pointsums)++;
450 pointsums_new = (FT_UShort*)realloc(*pointsums,
451 *num_pointsums
452 * sizeof (FT_UShort));
453 if (!pointsums_new)
455 (*num_pointsums)--;
456 return FT_Err_Out_Of_Memory;
458 else
459 *pointsums = pointsums_new;
461 (*pointsums)[*num_pointsums - 1] = *num_composite_points;
463 for (i = 0; i < num_components; i++)
465 GLYPH* glyph;
466 FT_UShort component = components[i];
467 FT_Error error;
470 if (component >= data->num_glyphs)
471 return FT_Err_Invalid_Table;
473 glyph = &data->glyphs[component];
475 if (glyph->num_components)
477 error = TA_iterate_composite_glyph(data,
478 glyph->components,
479 glyph->num_components,
480 pointsums,
481 num_pointsums,
482 num_composite_contours,
483 num_composite_points);
484 if (error)
485 return error;
487 else
489 /* no need for checking overflow of the number of contours */
490 /* since the number of points is always larger or equal */
491 if (*num_composite_points > 0xFFFF - glyph->num_points)
492 return FT_Err_Invalid_Table;
494 *num_composite_contours += glyph->num_contours;
495 *num_composite_points += glyph->num_points;
499 return TA_Err_Ok;
503 static FT_Error
504 TA_sfnt_compute_composite_pointsums(SFNT* sfnt,
505 FONT* font)
507 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
508 glyf_Data* data = (glyf_Data*)glyf_table->data;
510 FT_UShort i;
513 for (i = 0; i < data->num_glyphs; i++)
515 GLYPH* glyph = &data->glyphs[i];
518 if (glyph->num_components)
520 FT_Error error;
521 FT_UShort num_composite_contours = 0;
522 FT_UShort num_composite_points = 0;
525 error = TA_iterate_composite_glyph(data,
526 glyph->components,
527 glyph->num_components,
528 &glyph->pointsums,
529 &glyph->num_pointsums,
530 &num_composite_contours,
531 &num_composite_points);
532 if (error)
533 return error;
535 glyph->num_composite_contours = num_composite_contours;
537 if (font->hint_with_components)
539 /* update maximum values, */
540 /* including the subglyphs not in `components' array */
541 /* (each of them has a single point in a single contour) */
542 if (num_composite_points + glyph->num_pointsums
543 > sfnt->max_composite_points)
544 sfnt->max_composite_points = num_composite_points
545 + glyph->num_pointsums;
546 if (num_composite_contours + glyph->num_pointsums
547 > sfnt->max_composite_contours)
548 sfnt->max_composite_contours = num_composite_contours
549 + glyph->num_pointsums;
554 return TA_Err_Ok;
558 FT_Error
559 TA_sfnt_split_glyf_table(SFNT* sfnt,
560 FONT* font)
562 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
563 SFNT_Table* loca_table = &font->tables[sfnt->loca_idx];
564 SFNT_Table* head_table = &font->tables[sfnt->head_idx];
566 glyf_Data* data;
567 FT_Byte loca_format;
569 FT_ULong offset;
570 FT_ULong offset_next;
572 FT_Byte* p;
573 FT_UShort i;
574 FT_UShort loop_count;
576 FT_Error error;
579 /* in case of success, all allocated arrays are */
580 /* linked and eventually freed in `TA_font_unload' */
582 /* nothing to do if table has already been split */
583 if (glyf_table->data)
584 return TA_Err_Ok;
586 data = (glyf_Data*)calloc(1, sizeof (glyf_Data));
587 if (!data)
588 return FT_Err_Out_Of_Memory;
590 glyf_table->data = data;
592 loca_format = head_table->buf[LOCA_FORMAT_OFFSET];
594 data->num_glyphs = loca_format ? loca_table->len / 4
595 : loca_table->len / 2;
596 loop_count = data->num_glyphs - 1;
598 /* allocate one more glyph slot if we have composite glyphs */
599 if (!sfnt->max_components || !font->hint_with_components)
600 data->num_glyphs -= 1;
601 data->glyphs = (GLYPH*)calloc(1, data->num_glyphs * sizeof (GLYPH));
602 if (!data->glyphs)
603 return FT_Err_Out_Of_Memory;
605 data->master_globals = NULL;
606 data->cvt_idx = MISSING;
607 data->fpgm_idx = MISSING;
608 data->prep_idx = MISSING;
610 /* first loop over `loca' and `glyf' data */
612 p = loca_table->buf;
614 if (loca_format)
616 offset_next = *(p++) << 24;
617 offset_next += *(p++) << 16;
618 offset_next += *(p++) << 8;
619 offset_next += *(p++);
621 else
623 offset_next = *(p++) << 8;
624 offset_next += *(p++);
625 offset_next <<= 1;
628 for (i = 0; i < loop_count; i++)
630 GLYPH* glyph = &data->glyphs[i];
631 FT_ULong len;
634 offset = offset_next;
636 if (loca_format)
638 offset_next = *(p++) << 24;
639 offset_next += *(p++) << 16;
640 offset_next += *(p++) << 8;
641 offset_next += *(p++);
643 else
645 offset_next = *(p++) << 8;
646 offset_next += *(p++);
647 offset_next <<= 1;
650 if (offset_next < offset
651 || offset_next > glyf_table->len)
652 return FT_Err_Invalid_Table;
654 len = offset_next - offset;
655 if (!len)
656 continue; /* empty glyph */
657 else
659 FT_Byte* buf;
662 /* check header size */
663 if (len < 10)
664 return FT_Err_Invalid_Table;
666 /* we need the number of contours and points for */
667 /* `TA_sfnt_compute_composite_pointsums' */
668 buf = glyf_table->buf + offset;
669 glyph->num_contours = (FT_Short)((buf[0] << 8) + buf[1]);
671 if (glyph->num_contours < 0)
673 error = TA_glyph_get_components(glyph, buf, len);
674 if (error)
675 return error;
677 else
679 FT_ULong off;
682 /* use the last contour's end point to compute number of points */
683 off = 10 + (glyph->num_contours - 1) * 2;
684 if (off >= len - 1)
685 return FT_Err_Invalid_Table;
687 glyph->num_points = buf[off] << 8;
688 glyph->num_points += buf[off + 1] + 1;
693 if (sfnt->max_components && font->hint_with_components)
695 error = TA_sfnt_compute_composite_pointsums(sfnt, font);
696 if (error)
697 return error;
700 /* second loop over `loca' and `glyf' data */
702 p = loca_table->buf;
704 if (loca_format)
706 offset_next = *(p++) << 24;
707 offset_next += *(p++) << 16;
708 offset_next += *(p++) << 8;
709 offset_next += *(p++);
711 else
713 offset_next = *(p++) << 8;
714 offset_next += *(p++);
715 offset_next <<= 1;
718 for (i = 0; i < loop_count; i++)
720 GLYPH* glyph = &data->glyphs[i];
721 FT_ULong len;
724 offset = offset_next;
726 if (loca_format)
728 offset_next = *(p++) << 24;
729 offset_next += *(p++) << 16;
730 offset_next += *(p++) << 8;
731 offset_next += *(p++);
733 else
735 offset_next = *(p++) << 8;
736 offset_next += *(p++);
737 offset_next <<= 1;
740 len = offset_next - offset;
741 if (!len)
742 continue; /* empty glyph */
743 else
745 FT_Byte* buf;
748 buf = glyf_table->buf + offset;
750 /* We must parse the rest of the glyph record to get the exact */
751 /* record length. Since the `loca' table rounds record lengths */
752 /* up to multiples of 4 (or 2 for older fonts), and we must round */
753 /* up again after stripping off the instructions, it would be */
754 /* possible otherwise to have more than 4 bytes of padding which */
755 /* is more or less invalid. */
757 if (glyph->num_contours < 0)
758 error = TA_glyph_parse_composite(glyph, buf, len,
759 data->num_glyphs,
760 font->hint_with_components);
761 else
762 error = TA_glyph_parse_simple(glyph, buf, len);
763 if (error)
764 return error;
768 if (sfnt->max_components && font->hint_with_components)
770 /* construct and append our special glyph used as a composite element */
771 GLYPH* glyph = &data->glyphs[data->num_glyphs - 1];
772 FT_Byte* buf;
774 glyph->len1 = 12;
775 glyph->len2 = 1;
776 glyph->buf = (FT_Byte*)malloc(glyph->len1 + glyph->len2);
777 if (!glyph->buf)
778 return FT_Err_Out_Of_Memory;
780 buf = glyph->buf;
782 buf[0] = 0x00; /* one contour */
783 buf[1] = 0x01;
784 buf[2] = 0x00; /* no dimensions */
785 buf[3] = 0x00;
786 buf[4] = 0x00;
787 buf[5] = 0x00;
788 buf[6] = 0x00;
789 buf[7] = 0x00;
790 buf[8] = 0x00;
791 buf[9] = 0x00;
792 buf[10] = 0x00; /* one contour end point */
793 buf[11] = 0x00;
795 buf[12] = ON_CURVE | SAME_X | SAME_Y; /* the flags for a point at 0,0 */
797 /* add bytecode also; */
798 /* this works because the loop in `TA_sfnt_build_glyf_hints' */
799 /* doesn't include the newly appended glyph */
800 glyph->ins_len = sizeof (ttfautohint_glyph_bytecode);
801 glyph->ins_buf = (FT_Byte*)malloc(glyph->ins_len);
802 if (!glyph->ins_buf)
803 return FT_Err_Out_Of_Memory;
804 memcpy(glyph->ins_buf, ttfautohint_glyph_bytecode, glyph->ins_len);
806 sfnt->max_components += 1;
809 return TA_Err_Ok;
813 FT_Error
814 TA_sfnt_build_glyf_table(SFNT* sfnt,
815 FONT* font)
817 FT_Error error;
819 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
820 glyf_Data* data = (glyf_Data*)glyf_table->data;
822 GLYPH* glyph;
824 FT_ULong len;
825 FT_Byte* buf_new;
826 FT_Byte* p;
827 FT_UShort i;
830 if (glyf_table->processed)
831 return TA_Err_Ok;
833 if (!font->dehint)
835 error = TA_sfnt_build_glyf_hints(sfnt, font);
836 if (error)
837 return error;
840 /* get table size */
841 len = 0;
842 glyph = data->glyphs;
843 for (i = 0; i < data->num_glyphs; i++, glyph++)
845 /* glyph records should have offsets which are multiples of 4 */
846 len = (len + 3) & ~3;
847 len += glyph->len1 + glyph->len2 + glyph->ins_len;
848 /* add two bytes for the instructionLength field */
849 if (glyph->len2 || glyph->ins_len)
850 len += 2;
853 /* to make the short format of the `loca' table always work, */
854 /* assure an even length of the `glyf' table */
855 glyf_table->len = (len + 1) & ~1;
857 buf_new = (FT_Byte*)realloc(glyf_table->buf, (len + 3) & ~3);
858 if (!buf_new)
859 return FT_Err_Out_Of_Memory;
860 else
861 glyf_table->buf = buf_new;
863 p = glyf_table->buf;
864 glyph = data->glyphs;
865 for (i = 0; i < data->num_glyphs; i++, glyph++)
867 len = glyph->len1 + glyph->len2 + glyph->ins_len;
868 if (glyph->len2 || glyph->ins_len)
869 len += 2;
871 if (len)
873 /* copy glyph data and insert new instructions */
874 memcpy(p, glyph->buf, glyph->len1);
876 if (glyph->len2)
878 /* simple glyph */
879 p += glyph->len1;
880 *(p++) = HIGH(glyph->ins_len);
881 *(p++) = LOW(glyph->ins_len);
882 memcpy(p, glyph->ins_buf, glyph->ins_len);
883 p += glyph->ins_len;
884 memcpy(p, glyph->buf + glyph->len1, glyph->len2);
885 p += glyph->len2;
887 else
889 /* composite glyph */
890 if (glyph->ins_len)
892 *(p + glyph->flags_offset) |= (WE_HAVE_INSTR >> 8);
893 p += glyph->len1;
894 *(p++) = HIGH(glyph->ins_len);
895 *(p++) = LOW(glyph->ins_len);
896 memcpy(p, glyph->ins_buf, glyph->ins_len);
897 p += glyph->ins_len;
899 else
900 p += glyph->len1;
903 /* pad with zero bytes to have an offset which is a multiple of 4; */
904 /* this works even for the last glyph record since the `glyf' */
905 /* table length is a multiple of 4 also */
906 switch (len % 4)
908 case 1:
909 *(p++) = 0;
910 case 2:
911 *(p++) = 0;
912 case 3:
913 *(p++) = 0;
914 default:
915 break;
920 glyf_table->checksum = TA_table_compute_checksum(glyf_table->buf,
921 glyf_table->len);
922 glyf_table->processed = 1;
924 return TA_Err_Ok;
928 static FT_Error
929 TA_create_glyph_data(FT_Outline* outline,
930 GLYPH* glyph)
932 FT_Error error = TA_Err_Ok;
934 FT_Pos xmin, ymin;
935 FT_Pos xmax, ymax;
937 FT_Byte header[10];
938 FT_Byte* flags = NULL;
939 FT_Byte* flagsp;
940 FT_Byte oldf, f;
941 FT_Byte* x = NULL;
942 FT_Byte* xp;
943 FT_Byte* y = NULL;
944 FT_Byte* yp;
946 FT_Pos lastx, lasty;
948 FT_Short i;
949 FT_Byte* p;
952 if (!outline->n_contours)
953 return TA_Err_Ok; /* empty glyph */
955 /* in case of success, all non-local allocated arrays are */
956 /* linked and eventually freed in `TA_font_unload' */
958 glyph->buf = NULL;
960 /* we use `calloc' since we rely on the array */
961 /* being initialized to zero; */
962 /* additionally, we need one more byte for a test after the loop */
963 flags = (FT_Byte*)calloc(1, outline->n_points + 1);
964 if (!flags)
966 error = FT_Err_Out_Of_Memory;
967 goto Exit;
970 /* we have either one-byte or two-byte elements */
971 x = (FT_Byte*)malloc(2 * outline->n_points);
972 if (!x)
974 error = FT_Err_Out_Of_Memory;
975 goto Exit;
978 y = (FT_Byte*)malloc(2 * outline->n_points);
979 if (!y)
981 error = FT_Err_Out_Of_Memory;
982 goto Exit;
985 flagsp = flags;
986 xp = x;
987 yp = y;
988 xmin = xmax = (outline->points[0].x + 32) >> 6;
989 ymin = ymax = (outline->points[0].y + 32) >> 6;
990 lastx = 0;
991 lasty = 0;
992 oldf = 0x80; /* start with an impossible value */
994 /* convert the FreeType representation of the glyph's outline */
995 /* into the representation format of the `glyf' table */
996 for (i = 0; i < outline->n_points; i++)
998 FT_Pos xcur = (outline->points[i].x + 32) >> 6;
999 FT_Pos ycur = (outline->points[i].y + 32) >> 6;
1001 FT_Pos xdelta = xcur - lastx;
1002 FT_Pos ydelta = ycur - lasty;
1005 /* we are only interested in bit 0 of the `tags' array */
1006 f = outline->tags[i] & ON_CURVE;
1008 /* x value */
1010 if (xdelta == 0)
1011 f |= SAME_X;
1012 else
1014 if (xdelta < 256 && xdelta > -256)
1016 f |= X_SHORT_VECTOR;
1018 if (xdelta < 0)
1019 xdelta = -xdelta;
1020 else
1021 f |= SAME_X;
1023 *(xp++) = (FT_Byte)xdelta;
1025 else
1027 *(xp++) = HIGH(xdelta);
1028 *(xp++) = LOW(xdelta);
1032 /* y value */
1034 if (ydelta == 0)
1035 f |= SAME_Y;
1036 else
1038 if (ydelta < 256 && ydelta > -256)
1040 f |= Y_SHORT_VECTOR;
1042 if (ydelta < 0)
1043 ydelta = -ydelta;
1044 else
1045 f |= SAME_Y;
1047 *(yp++) = (FT_Byte)ydelta;
1049 else
1051 *(yp++) = HIGH(ydelta);
1052 *(yp++) = LOW(ydelta);
1056 if (f == oldf)
1058 /* set repeat flag */
1059 *(flagsp - 1) |= REPEAT;
1061 if (*flagsp == 255)
1063 /* we can only handle 256 repetitions at once, */
1064 /* so use a new counter */
1065 flagsp++;
1066 *(flagsp++) = f;
1068 else
1069 *flagsp += 1; /* increase repetition counter */
1071 else
1073 if (*flagsp)
1074 flagsp++; /* skip repetition counter */
1075 *(flagsp++) = f;
1076 oldf = f;
1079 if (xcur > xmax)
1080 xmax = xcur;
1081 if (ycur > ymax)
1082 ymax = ycur;
1083 if (xcur < xmin)
1084 xmin = xcur;
1085 if (ycur < ymin)
1086 ymin = ycur;
1088 lastx = xcur;
1089 lasty = ycur;
1092 /* if the last byte was a repetition counter, */
1093 /* we must increase by one to get the correct array size */
1094 if (*flagsp)
1095 flagsp++;
1097 header[0] = HIGH(outline->n_contours);
1098 header[1] = LOW(outline->n_contours);
1099 header[2] = HIGH(xmin);
1100 header[3] = LOW(xmin);
1101 header[4] = HIGH(ymin);
1102 header[5] = LOW(ymin);
1103 header[6] = HIGH(xmax);
1104 header[7] = LOW(xmax);
1105 header[8] = HIGH(ymax);
1106 header[9] = LOW(ymax);
1108 /* concatenate all arrays and fill needed GLYPH structure elements */
1110 glyph->len1 = 10 + 2 * outline->n_contours;
1111 glyph->len2 = (flagsp - flags) + (xp - x) + (yp - y);
1113 glyph->buf = (FT_Byte*)malloc(glyph->len1 + glyph->len2);
1114 if (!glyph->buf)
1116 error = FT_Err_Out_Of_Memory;
1117 goto Exit;
1120 p = glyph->buf;
1121 memcpy(p, header, 10);
1122 p += 10;
1124 glyph->ins_len = 0;
1125 glyph->ins_buf = NULL;
1127 for (i = 0; i < outline->n_contours; i++)
1129 *(p++) = HIGH(outline->contours[i]);
1130 *(p++) = LOW(outline->contours[i]);
1133 memcpy(p, flags, flagsp - flags);
1134 p += flagsp - flags;
1135 memcpy(p, x, xp - x);
1136 p += xp - x;
1137 memcpy(p, y, yp - y);
1139 Exit:
1140 free(flags);
1141 free(x);
1142 free(y);
1144 return error;
1148 /* We hint each glyph at EM size and construct a new `glyf' table. */
1149 /* Some fonts need this; in particular, */
1150 /* there are CJK fonts which use hints to scale and position subglyphs. */
1151 /* As a consequence, there are no longer composite glyphs. */
1153 FT_Error
1154 TA_sfnt_create_glyf_data(SFNT* sfnt,
1155 FONT* font)
1157 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
1158 FT_Face face = sfnt->face;
1159 FT_Error error;
1161 glyf_Data* data;
1163 FT_UShort i;
1166 /* in case of success, all allocated arrays are */
1167 /* linked and eventually freed in `TA_font_unload' */
1169 /* nothing to do if table has already been created */
1170 if (glyf_table->data)
1171 return TA_Err_Ok;
1173 data = (glyf_Data*)calloc(1, sizeof (glyf_Data));
1174 if (!data)
1175 return FT_Err_Out_Of_Memory;
1177 glyf_table->data = data;
1179 data->num_glyphs = face->num_glyphs;
1180 data->glyphs = (GLYPH*)calloc(1, data->num_glyphs * sizeof (GLYPH));
1181 if (!data->glyphs)
1182 return FT_Err_Out_Of_Memory;
1184 /* XXX: Make size configurable */
1185 /* we use the EM size */
1186 /* so that the resulting coordinates can be used without transformation */
1187 error = FT_Set_Char_Size(face, face->units_per_EM * 64, 0, 72, 0);
1188 if (error)
1189 return error;
1191 /* loop over all glyphs in font face */
1192 for (i = 0; i < data->num_glyphs; i++)
1194 GLYPH* glyph = &data->glyphs[i];
1197 error = FT_Load_Glyph(face, i, FT_LOAD_NO_BITMAP | FT_LOAD_NO_AUTOHINT);
1198 if (error)
1199 return error;
1201 error = TA_create_glyph_data(&face->glyph->outline, glyph);
1202 if (error)
1203 return error;
1206 return TA_Err_Ok;
1210 FT_Error
1211 TA_sfnt_handle_coverage(SFNT* sfnt,
1212 FONT* font)
1214 FT_Error error;
1216 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
1217 glyf_Data* data = (glyf_Data*)glyf_table->data;
1219 FT_Face face = sfnt->face;
1220 TA_FaceGlobals curr_globals;
1222 FT_UInt saved_fallback_script = font->fallback_script;
1225 /* using TA_SCRIPT_NONE as the fallback script ensures */
1226 /* that uncovered glyphs stay as-is */
1227 /* (we handle the fallback script later on) */
1228 font->fallback_script = TA_SCRIPT_NONE;
1230 /* trigger computation of coverage */
1231 error = ta_loader_init(font);
1232 if (error)
1233 goto Exit;
1234 error = ta_loader_reset(font, face);
1235 if (error)
1236 goto Exit;
1237 ta_loader_done(font);
1239 font->fallback_script = saved_fallback_script;
1240 curr_globals = (TA_FaceGlobals)face->autohint.data;
1242 if (!data->master_globals)
1244 /* initialize */
1245 data->master_globals = curr_globals;
1246 goto Exit;
1249 /* we have the same `glyf' table for another subfont; */
1250 /* merge the current coverage info into the `master' coverage info */
1252 TA_FaceGlobals master_globals = data->master_globals;
1253 FT_Long count = master_globals->glyph_count;
1255 FT_Byte* master = master_globals->glyph_scripts;
1256 FT_Byte* curr = curr_globals->glyph_scripts;
1258 FT_Byte* limit = master + count;
1261 /* we simply copy the data, */
1262 /* assuming that a given glyph always has the same properties -- */
1263 /* as soon as we make the script selection more fine-grained, */
1264 /* it is possible that this assumption doesn't hold: */
1265 /* for example, glyph `A' can be used for both Cyrillic and Latin */
1266 while (master < limit)
1268 if ((*curr & ~TA_DIGIT) != TA_SCRIPT_NONE)
1269 *master = *curr;
1271 master++;
1272 curr++;
1276 Exit:
1277 return error;
1281 void
1282 TA_sfnt_adjust_master_coverage(SFNT* sfnt,
1283 FONT* font)
1285 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
1286 glyf_Data* data = (glyf_Data*)glyf_table->data;
1288 FT_Face face = sfnt->face;
1290 TA_FaceGlobals master_globals = data->master_globals;
1291 TA_FaceGlobals curr_globals = (TA_FaceGlobals)face->autohint.data;
1294 /* use fallback script for uncovered glyphs */
1295 if (master_globals == curr_globals)
1297 FT_Long nn;
1298 FT_Byte* gscripts = master_globals->glyph_scripts;
1301 for (nn = 0; nn < master_globals->glyph_count; nn++)
1303 if ((gscripts[nn] & ~TA_DIGIT) == TA_SCRIPT_NONE)
1305 gscripts[nn] &= ~TA_SCRIPT_NONE;
1306 gscripts[nn] |= master_globals->font->fallback_script;
1313 #if 0
1315 void
1316 TA_sfnt_copy_master_coverage(SFNT* sfnt,
1317 FONT* font)
1319 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
1320 glyf_Data* data = (glyf_Data*)glyf_table->data;
1322 FT_Face face = sfnt->face;
1324 TA_FaceGlobals master_globals = data->master_globals;
1325 TA_FaceGlobals curr_globals = (TA_FaceGlobals)face->autohint.data;
1328 if (master_globals != curr_globals)
1330 FT_Long count = master_globals->glyph_count;
1331 FT_Byte* master = master_globals->glyph_scripts;
1332 FT_Byte* curr = curr_globals->glyph_scripts;
1335 memcpy(curr, master, count);
1339 #endif /* 0 */
1341 /* end of taglyf.c */