Make pre-hinting work again.
[ttfautohint.git] / src / taglyf.c
blobd806d924a69421c165a917d7954a0ce2e37ccb1b
1 /* taglyf.c */
3 /*
4 * Copyright (C) 2011-2012 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 /* 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)
35 font->progress(idx, face->num_glyphs,
36 sfnt - font->sfnts, font->num_sfnts,
37 font->progress_data);
40 return FT_Err_Ok;
44 static FT_Error
45 TA_glyph_get_components(GLYPH* glyph,
46 FT_Byte* buf,
47 FT_ULong len)
49 FT_UShort flags;
50 FT_UShort component;
51 FT_UShort* components_new;
53 FT_Byte* p;
54 FT_Byte* endp;
57 p = buf;
58 endp = buf + len;
60 /* skip header */
61 p += 10;
63 /* walk over component records */
66 if (p + 4 > endp)
67 return FT_Err_Invalid_Table;
69 flags = *(p++) << 8;
70 flags += *(p++);
72 /* add component to list */
73 component = *(p++) << 8;
74 component += *(p++);
76 glyph->num_components++;
77 components_new = (FT_UShort*)realloc(glyph->components,
78 glyph->num_components
79 * sizeof (FT_UShort));
80 if (!components_new)
82 glyph->num_components--;
83 return FT_Err_Out_Of_Memory;
85 else
86 glyph->components = components_new;
88 glyph->components[glyph->num_components - 1] = component;
90 /* skip scaling and offset arguments */
91 if (flags & ARGS_ARE_WORDS)
92 p += 4;
93 else
94 p += 2;
96 if (flags & WE_HAVE_A_SCALE)
97 p += 2;
98 else if (flags & WE_HAVE_AN_XY_SCALE)
99 p += 4;
100 else if (flags & WE_HAVE_A_2X2)
101 p += 8;
102 } while (flags & MORE_COMPONENTS);
104 return TA_Err_Ok;
108 static FT_Error
109 TA_glyph_parse_composite(GLYPH* glyph,
110 FT_Byte* buf,
111 FT_ULong len,
112 FT_UShort num_glyphs)
114 FT_ULong flags_offset; /* after the loop, this is the offset */
115 /* to the last element in the flags array */
116 FT_UShort flags;
118 FT_Byte* p;
119 FT_Byte* q;
122 /* we allocate too large a buffer */
123 /* (including space for the new component */
124 /* and possible argument size changes for shifted point indices) */
125 /* and reallocate it later to its real size */
126 glyph->buf = (FT_Byte*)malloc(len + 8 + glyph->num_components * 2);
127 if (!glyph->buf)
128 return FT_Err_Out_Of_Memory;
130 p = buf;
131 q = glyph->buf;
133 /* copy header */
134 memcpy(q, p, 10);
135 p += 10;
136 q += 10;
138 /* if the composite glyph contains one or more contours, */
139 /* we prepend a composite glyph component to call some bytecode */
140 /* which eventually becomes the last glyph in the `glyf' table; */
141 /* for convenience, however, it is not added to the `components' array */
142 /* (doing so simplifies the conversion of point indices later on) */
143 if (glyph->num_composite_contours)
145 FT_Short x_min;
146 FT_Short x_max;
147 FT_Short y_min;
148 FT_Short y_max;
149 FT_Short x_offset;
150 FT_Short y_offset;
153 /* the composite glyph's bounding box */
154 x_min = (FT_Short)((buf[2] << 8) + buf[3]);
155 y_min = (FT_Short)((buf[4] << 8) + buf[5]);
156 x_max = (FT_Short)((buf[6] << 8) + buf[7]);
157 y_max = (FT_Short)((buf[8] << 8) + buf[9]);
159 /* use ARGS_ARE_WORDS only if necessary; */
160 /* note that the offset value of the component doesn't matter */
161 /* as long as it stays within the bounding box */
162 if (x_min <= 0 && x_max >= 0)
163 x_offset = 0;
164 else if (x_max < 0)
165 x_offset = x_max;
166 else
167 x_offset = x_min;
169 if (y_min <= 0 && y_max >= 0)
170 y_offset = 0;
171 else if (y_max < 0)
172 y_offset = y_max;
173 else
174 y_offset = y_min;
176 if (x_offset >= -128 && x_offset <= 127
177 && y_offset >= -128 && y_offset <= 127)
179 *(q++) = 0x00;
180 *(q++) = ARGS_ARE_XY_VALUES | MORE_COMPONENTS;
181 *(q++) = HIGH(num_glyphs - 1);
182 *(q++) = LOW(num_glyphs - 1);
183 *(q++) = x_offset;
184 *(q++) = y_offset;
186 else
188 *(q++) = 0x00;
189 *(q++) = ARGS_ARE_WORDS | ARGS_ARE_XY_VALUES | MORE_COMPONENTS;
190 *(q++) = HIGH(num_glyphs - 1);
191 *(q++) = LOW(num_glyphs - 1);
192 *(q++) = HIGH(x_offset);
193 *(q++) = LOW(x_offset);
194 *(q++) = HIGH(y_offset);
195 *(q++) = LOW(y_offset);
199 /* walk over component records */
202 flags_offset = q - glyph->buf;
204 *(q++) = *p;
205 flags = *(p++) << 8;
206 *(q++) = *p;
207 flags += *(p++);
209 /* copy component */
210 *(q++) = *(p++);
211 *(q++) = *(p++);
213 if (flags & ARGS_ARE_XY_VALUES)
215 /* copy offsets */
216 *(q++) = *(p++);
217 *(q++) = *(p++);
219 if (flags & ARGS_ARE_WORDS)
221 *(q++) = *(p++);
222 *(q++) = *(p++);
225 else
227 /* handle point numbers */
228 FT_UShort arg1;
229 FT_UShort arg2;
230 FT_UShort i;
233 if (flags & ARGS_ARE_WORDS)
235 arg1 = *(p++) >> 8;
236 arg1 += *(p++);
237 arg2 = *(p++) >> 8;
238 arg2 += *(p++);
240 else
242 arg1 = *(p++);
243 arg2 = *(p++);
246 /* adjust point numbers */
247 /* (see `TA_adjust_point_index' in `tabytecode.c' for more) */
248 for (i = 0; i < glyph->num_pointsums; i++)
249 if (arg1 < glyph->pointsums[i])
250 break;
251 arg1 += i;
253 for (i = 0; i < glyph->num_pointsums; i++)
254 if (arg2 < glyph->pointsums[i])
255 break;
256 arg2 += i;
258 if (arg1 <= 0xFF && arg2 <= 0xFF)
260 glyph->buf[flags_offset + 1] &= ~ARGS_ARE_WORDS;
262 *(q++) = arg1;
263 *(q++) = arg2;
265 else
267 glyph->buf[flags_offset + 1] |= ARGS_ARE_WORDS;
269 *(q++) = HIGH(arg1);
270 *(q++) = LOW(arg1);
271 *(q++) = HIGH(arg2);
272 *(q++) = LOW(arg2);
276 /* copy scaling arguments */
277 if (flags & (WE_HAVE_A_SCALE | WE_HAVE_AN_XY_SCALE | WE_HAVE_A_2X2))
279 *(q++) = *(p++);
280 *(q++) = *(p++);
282 if (flags & (WE_HAVE_AN_XY_SCALE | WE_HAVE_A_2X2))
284 *(q++) = *(p++);
285 *(q++) = *(p++);
287 if (flags & WE_HAVE_A_2X2)
289 *(q++) = *(p++);
290 *(q++) = *(p++);
291 *(q++) = *(p++);
292 *(q++) = *(p++);
294 } while (flags & MORE_COMPONENTS);
296 glyph->len1 = q - glyph->buf;
297 /* glyph->len2 = 0; */
298 glyph->flags_offset = flags_offset;
299 glyph->buf = (FT_Byte*)realloc(glyph->buf, glyph->len1);
301 /* we discard instructions (if any) */
302 glyph->buf[glyph->flags_offset] &= ~(WE_HAVE_INSTR >> 8);
304 return TA_Err_Ok;
308 static FT_Error
309 TA_glyph_parse_simple(GLYPH* glyph,
310 FT_Byte* buf,
311 FT_ULong len)
313 FT_ULong ins_offset;
314 FT_Byte* flags_start;
316 FT_UShort num_ins;
318 FT_ULong flags_size; /* size of the flags array */
319 FT_ULong xy_size; /* size of x and y coordinate arrays together */
321 FT_Byte* p;
322 FT_Byte* endp;
324 FT_UShort i;
327 p = buf;
328 endp = buf + len;
330 ins_offset = 10 + glyph->num_contours * 2;
332 p += ins_offset;
334 if (p + 2 > endp)
335 return FT_Err_Invalid_Table;
337 /* get number of instructions */
338 num_ins = *(p++) << 8;
339 num_ins += *(p++);
341 p += num_ins;
343 if (p > endp)
344 return FT_Err_Invalid_Table;
346 flags_start = p;
347 xy_size = 0;
348 i = 0;
350 while (i < glyph->num_points)
352 FT_Byte flags;
353 FT_Byte x_short;
354 FT_Byte y_short;
355 FT_Byte have_x;
356 FT_Byte have_y;
357 FT_Byte count;
360 if (p + 1 > endp)
361 return FT_Err_Invalid_Table;
363 flags = *(p++);
365 x_short = (flags & X_SHORT_VECTOR) ? 1 : 2;
366 y_short = (flags & Y_SHORT_VECTOR) ? 1 : 2;
368 have_x = ((flags & SAME_X) && !(flags & X_SHORT_VECTOR)) ? 0 : 1;
369 have_y = ((flags & SAME_Y) && !(flags & Y_SHORT_VECTOR)) ? 0 : 1;
371 count = 1;
373 if (flags & REPEAT)
375 if (p + 1 > endp)
376 return FT_Err_Invalid_Table;
378 count += *(p++);
380 if (i + count > glyph->num_points)
381 return FT_Err_Invalid_Table;
384 xy_size += count * x_short * have_x;
385 xy_size += count * y_short * have_y;
387 i += count;
390 if (p + xy_size > endp)
391 return FT_Err_Invalid_Table;
393 flags_size = p - flags_start;
395 /* store the data before and after the bytecode instructions */
396 /* in the same array */
397 glyph->len1 = ins_offset;
398 glyph->len2 = flags_size + xy_size;
399 glyph->buf = (FT_Byte*)malloc(glyph->len1 + glyph->len2);
400 if (!glyph->buf)
401 return FT_Err_Out_Of_Memory;
403 /* now copy everything but the instructions */
404 memcpy(glyph->buf, buf, glyph->len1);
405 memcpy(glyph->buf + glyph->len1, flags_start, glyph->len2);
407 return TA_Err_Ok;
411 static FT_Error
412 TA_iterate_composite_glyph(glyf_Data* data,
413 FT_UShort* components,
414 FT_UShort num_components,
415 FT_UShort** pointsums,
416 FT_UShort* num_pointsums,
417 FT_UShort* num_composite_contours,
418 FT_UShort* num_composite_points)
420 FT_UShort* pointsums_new;
421 FT_UShort i;
424 /* save current state */
426 if (*num_pointsums == 0xFFFF)
427 return FT_Err_Invalid_Table;
429 (*num_pointsums)++;
430 pointsums_new = (FT_UShort*)realloc(*pointsums,
431 *num_pointsums
432 * sizeof (FT_UShort));
433 if (!pointsums_new)
435 (*num_pointsums)--;
436 return FT_Err_Out_Of_Memory;
438 else
439 *pointsums = pointsums_new;
441 (*pointsums)[*num_pointsums - 1] = *num_composite_points;
443 for (i = 0; i < num_components; i++)
445 GLYPH* glyph;
446 FT_UShort component = components[i];
447 FT_Error error;
450 if (component >= data->num_glyphs)
451 return FT_Err_Invalid_Table;
453 glyph = &data->glyphs[component];
455 if (glyph->num_components)
457 error = TA_iterate_composite_glyph(data,
458 glyph->components,
459 glyph->num_components,
460 pointsums,
461 num_pointsums,
462 num_composite_contours,
463 num_composite_points);
464 if (error)
465 return error;
467 else
469 /* no need for checking overflow of the number of contours */
470 /* since the number of points is always larger or equal */
471 if (*num_composite_points > 0xFFFF - glyph->num_points)
472 return FT_Err_Invalid_Table;
474 *num_composite_contours += glyph->num_contours;
475 *num_composite_points += glyph->num_points;
479 return TA_Err_Ok;
483 static FT_Error
484 TA_sfnt_compute_composite_pointsums(SFNT* sfnt,
485 FONT* font)
487 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
488 glyf_Data* data = (glyf_Data*)glyf_table->data;
490 FT_UShort i;
493 for (i = 0; i < data->num_glyphs; i++)
495 GLYPH* glyph = &data->glyphs[i];
498 if (glyph->num_components)
500 FT_Error error;
501 FT_UShort num_composite_contours = 0;
502 FT_UShort num_composite_points = 0;
505 error = TA_iterate_composite_glyph(data,
506 glyph->components,
507 glyph->num_components,
508 &glyph->pointsums,
509 &glyph->num_pointsums,
510 &num_composite_contours,
511 &num_composite_points);
512 if (error)
513 return error;
515 glyph->num_composite_contours = num_composite_contours;
517 /* update maximum values, */
518 /* including the subglyphs not in `components' array */
519 /* (each of them has a single point in a single contour) */
520 if (num_composite_points + glyph->num_pointsums
521 > sfnt->max_composite_points)
522 sfnt->max_composite_points = num_composite_points
523 + glyph->num_pointsums;
524 if (num_composite_contours + glyph->num_pointsums
525 > sfnt->max_composite_contours)
526 sfnt->max_composite_contours = num_composite_contours
527 + glyph->num_pointsums;
531 return TA_Err_Ok;
535 FT_Error
536 TA_sfnt_split_glyf_table(SFNT* sfnt,
537 FONT* font)
539 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
540 SFNT_Table* loca_table = &font->tables[sfnt->loca_idx];
541 SFNT_Table* head_table = &font->tables[sfnt->head_idx];
543 glyf_Data* data;
544 FT_Byte loca_format;
546 FT_ULong offset;
547 FT_ULong offset_next;
549 FT_Byte* p;
550 FT_UShort i;
551 FT_UShort loop_count;
553 FT_Error error;
556 /* in case of success, all allocated arrays are */
557 /* linked and eventually freed in `TA_font_unload' */
559 /* nothing to do if table has already been split */
560 if (glyf_table->data)
561 return TA_Err_Ok;
563 data = (glyf_Data*)calloc(1, sizeof (glyf_Data));
564 if (!data)
565 return FT_Err_Out_Of_Memory;
567 glyf_table->data = data;
569 loca_format = head_table->buf[LOCA_FORMAT_OFFSET];
571 data->num_glyphs = loca_format ? loca_table->len / 4
572 : loca_table->len / 2;
573 loop_count = data->num_glyphs - 1;
575 /* allocate one more glyph slot if we have composite glyphs */
576 if (!sfnt->max_components)
577 data->num_glyphs -= 1;
578 data->glyphs = (GLYPH*)calloc(1, data->num_glyphs * sizeof (GLYPH));
579 if (!data->glyphs)
580 return FT_Err_Out_Of_Memory;
582 /* first loop over `loca' and `glyf' data */
584 p = loca_table->buf;
586 if (loca_format)
588 offset_next = *(p++) << 24;
589 offset_next += *(p++) << 16;
590 offset_next += *(p++) << 8;
591 offset_next += *(p++);
593 else
595 offset_next = *(p++) << 8;
596 offset_next += *(p++);
597 offset_next <<= 1;
600 for (i = 0; i < loop_count; i++)
602 GLYPH* glyph = &data->glyphs[i];
603 FT_ULong len;
606 offset = offset_next;
608 if (loca_format)
610 offset_next = *(p++) << 24;
611 offset_next += *(p++) << 16;
612 offset_next += *(p++) << 8;
613 offset_next += *(p++);
615 else
617 offset_next = *(p++) << 8;
618 offset_next += *(p++);
619 offset_next <<= 1;
622 if (offset_next < offset
623 || offset_next > glyf_table->len)
624 return FT_Err_Invalid_Table;
626 len = offset_next - offset;
627 if (!len)
628 continue; /* empty glyph */
629 else
631 FT_Byte* buf;
634 /* check header size */
635 if (len < 10)
636 return FT_Err_Invalid_Table;
638 /* we need the number of contours and points for */
639 /* `TA_sfnt_compute_composite_pointsums' */
640 buf = glyf_table->buf + offset;
641 glyph->num_contours = (FT_Short)((buf[0] << 8) + buf[1]);
643 if (glyph->num_contours < 0)
645 error = TA_glyph_get_components(glyph, buf, len);
646 if (error)
647 return error;
649 else
651 FT_ULong off;
654 /* use the last contour's end point to compute number of points */
655 off = 10 + (glyph->num_contours - 1) * 2;
656 glyph->num_points = buf[off] << 8;
657 glyph->num_points += buf[off + 1] + 1;
662 if (sfnt->max_components)
664 error = TA_sfnt_compute_composite_pointsums(sfnt, font);
665 if (error)
666 return error;
669 /* second loop over `loca' and `glyf' data */
671 p = loca_table->buf;
673 if (loca_format)
675 offset_next = *(p++) << 24;
676 offset_next += *(p++) << 16;
677 offset_next += *(p++) << 8;
678 offset_next += *(p++);
680 else
682 offset_next = *(p++) << 8;
683 offset_next += *(p++);
684 offset_next <<= 1;
687 for (i = 0; i < loop_count; i++)
689 GLYPH* glyph = &data->glyphs[i];
690 FT_ULong len;
693 offset = offset_next;
695 if (loca_format)
697 offset_next = *(p++) << 24;
698 offset_next += *(p++) << 16;
699 offset_next += *(p++) << 8;
700 offset_next += *(p++);
702 else
704 offset_next = *(p++) << 8;
705 offset_next += *(p++);
706 offset_next <<= 1;
709 len = offset_next - offset;
710 if (!len)
711 continue; /* empty glyph */
712 else
714 FT_Byte* buf;
717 buf = glyf_table->buf + offset;
719 /* We must parse the rest of the glyph record to get the exact */
720 /* record length. Since the `loca' table rounds record lengths */
721 /* up to multiples of 4 (or 2 for older fonts), and we must round */
722 /* up again after stripping off the instructions, it would be */
723 /* possible otherwise to have more than 4 bytes of padding which */
724 /* is more or less invalid. */
726 if (glyph->num_contours < 0)
727 error = TA_glyph_parse_composite(glyph, buf, len, data->num_glyphs);
728 else
729 error = TA_glyph_parse_simple(glyph, buf, len);
730 if (error)
731 return error;
735 if (sfnt->max_components)
737 /* construct and append our special glyph used as a composite element */
738 GLYPH* glyph = &data->glyphs[data->num_glyphs - 1];
739 FT_Byte* buf;
741 FT_Byte bytecode[] = {
743 /* increment `cvtl_is_subglyph' counter */
744 PUSHB_3,
745 cvtl_is_subglyph,
747 cvtl_is_subglyph,
748 RCVT,
749 ADD,
750 WCVTP,
754 glyph->len1 = 12;
755 glyph->len2 = 1;
756 glyph->buf = (FT_Byte*)malloc(glyph->len1 + glyph->len2);
757 if (!glyph->buf)
758 return FT_Err_Out_Of_Memory;
760 buf = glyph->buf;
762 buf[0] = 0x00; /* one contour */
763 buf[1] = 0x01;
764 buf[2] = 0x00; /* no dimensions */
765 buf[3] = 0x00;
766 buf[4] = 0x00;
767 buf[5] = 0x00;
768 buf[6] = 0x00;
769 buf[7] = 0x00;
770 buf[8] = 0x00;
771 buf[9] = 0x00;
772 buf[10] = 0x00; /* one contour end point */
773 buf[11] = 0x00;
775 buf[12] = ON_CURVE | SAME_X | SAME_Y; /* the flags for a point at 0,0 */
777 /* add bytecode also; */
778 /* this works because the loop in `TA_sfnt_build_glyf_hints' */
779 /* doesn't include the newly appended glyph */
780 glyph->ins_len = sizeof (bytecode);
781 glyph->ins_buf = (FT_Byte*)malloc(glyph->ins_len);
782 if (!glyph->ins_buf)
783 return FT_Err_Out_Of_Memory;
784 memcpy(glyph->ins_buf, bytecode, glyph->ins_len);
786 sfnt->max_components += 1;
789 return TA_Err_Ok;
793 FT_Error
794 TA_sfnt_build_glyf_table(SFNT* sfnt,
795 FONT* font)
797 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
798 glyf_Data* data = (glyf_Data*)glyf_table->data;
800 GLYPH* glyph;
802 FT_ULong len;
803 FT_Byte* buf_new;
804 FT_Byte* p;
805 FT_UShort i;
808 if (glyf_table->processed)
809 return TA_Err_Ok;
811 /* get table size */
812 len = 0;
813 glyph = data->glyphs;
814 for (i = 0; i < data->num_glyphs; i++, glyph++)
816 /* glyph records should have offsets which are multiples of 4 */
817 len = (len + 3) & ~3;
818 len += glyph->len1 + glyph->len2 + glyph->ins_len;
819 /* add two bytes for the instructionLength field */
820 if (glyph->len2 || glyph->ins_len)
821 len += 2;
824 /* to make the short format of the `loca' table always work, */
825 /* assure an even length of the `glyf' table */
826 glyf_table->len = (len + 1) & ~1;
828 buf_new = (FT_Byte*)realloc(glyf_table->buf, (len + 3) & ~3);
829 if (!buf_new)
830 return FT_Err_Out_Of_Memory;
831 else
832 glyf_table->buf = buf_new;
834 p = glyf_table->buf;
835 glyph = data->glyphs;
836 for (i = 0; i < data->num_glyphs; i++, glyph++)
838 len = glyph->len1 + glyph->len2 + glyph->ins_len;
839 if (glyph->len2 || glyph->ins_len)
840 len += 2;
842 if (len)
844 /* copy glyph data and insert new instructions */
845 memcpy(p, glyph->buf, glyph->len1);
847 if (glyph->len2)
849 /* simple glyph */
850 p += glyph->len1;
851 *(p++) = HIGH(glyph->ins_len);
852 *(p++) = LOW(glyph->ins_len);
853 memcpy(p, glyph->ins_buf, glyph->ins_len);
854 p += glyph->ins_len;
855 memcpy(p, glyph->buf + glyph->len1, glyph->len2);
856 p += glyph->len2;
858 else
860 /* composite glyph */
861 if (glyph->ins_len)
863 *(p + glyph->flags_offset) |= (WE_HAVE_INSTR >> 8);
864 p += glyph->len1;
865 *(p++) = HIGH(glyph->ins_len);
866 *(p++) = LOW(glyph->ins_len);
867 memcpy(p, glyph->ins_buf, glyph->ins_len);
868 p += glyph->ins_len;
870 else
871 p += glyph->len1;
874 /* pad with zero bytes to have an offset which is a multiple of 4; */
875 /* this works even for the last glyph record since the `glyf' */
876 /* table length is a multiple of 4 also */
877 switch (len % 4)
879 case 1:
880 *(p++) = 0;
881 case 2:
882 *(p++) = 0;
883 case 3:
884 *(p++) = 0;
885 default:
886 break;
891 glyf_table->checksum = TA_table_compute_checksum(glyf_table->buf,
892 glyf_table->len);
893 glyf_table->processed = 1;
895 return TA_Err_Ok;
899 static FT_Error
900 TA_create_glyph_data(FT_Outline* outline,
901 GLYPH* glyph)
903 FT_Error error = TA_Err_Ok;
905 FT_Pos xmin, ymin;
906 FT_Pos xmax, ymax;
908 FT_Byte header[10];
909 FT_Byte* flags = NULL;
910 FT_Byte* flagsp;
911 FT_Byte oldf, f;
912 FT_Byte* x = NULL;
913 FT_Byte* xp;
914 FT_Byte* y = NULL;
915 FT_Byte* yp;
917 FT_Pos lastx, lasty;
919 FT_Short i;
920 FT_Byte* p;
923 if (!outline->n_contours)
924 return TA_Err_Ok; /* empty glyph */
926 /* in case of success, all non-local allocated arrays are */
927 /* linked and eventually freed in `TA_font_unload' */
929 glyph->buf = NULL;
931 /* we use `calloc' since we rely on the array */
932 /* being initialized to zero; */
933 /* additionally, we need one more byte for a test after the loop */
934 flags = (FT_Byte*)calloc(1, outline->n_points + 1);
935 if (!flags)
937 error = FT_Err_Out_Of_Memory;
938 goto Exit;
941 /* we have either one-byte or two-byte elements */
942 x = (FT_Byte*)malloc(2 * outline->n_points);
943 if (!x)
945 error = FT_Err_Out_Of_Memory;
946 goto Exit;
949 y = (FT_Byte*)malloc(2 * outline->n_points);
950 if (!y)
952 error = FT_Err_Out_Of_Memory;
953 goto Exit;
956 flagsp = flags;
957 xp = x;
958 yp = y;
959 xmin = xmax = (outline->points[0].x + 32) >> 6;
960 ymin = ymax = (outline->points[0].y + 32) >> 6;
961 lastx = 0;
962 lasty = 0;
963 oldf = 0x80; /* start with an impossible value */
965 /* convert the FreeType representation of the glyph's outline */
966 /* into the representation format of the `glyf' table */
967 for (i = 0; i < outline->n_points; i++)
969 FT_Pos xcur = (outline->points[i].x + 32) >> 6;
970 FT_Pos ycur = (outline->points[i].y + 32) >> 6;
972 FT_Pos xdelta = xcur - lastx;
973 FT_Pos ydelta = ycur - lasty;
976 /* we are only interested in bit 0 of the `tags' array */
977 f = outline->tags[i] & ON_CURVE;
979 /* x value */
981 if (xdelta == 0)
982 f |= SAME_X;
983 else
985 if (xdelta < 256 && xdelta > -256)
987 f |= X_SHORT_VECTOR;
989 if (xdelta < 0)
990 xdelta = -xdelta;
991 else
992 f |= SAME_X;
994 *(xp++) = (FT_Byte)xdelta;
996 else
998 *(xp++) = HIGH(xdelta);
999 *(xp++) = LOW(xdelta);
1003 /* y value */
1005 if (ydelta == 0)
1006 f |= SAME_Y;
1007 else
1009 if (ydelta < 256 && ydelta > -256)
1011 f |= Y_SHORT_VECTOR;
1013 if (ydelta < 0)
1014 ydelta = -ydelta;
1015 else
1016 f |= SAME_Y;
1018 *(yp++) = (FT_Byte)ydelta;
1020 else
1022 *(yp++) = HIGH(ydelta);
1023 *(yp++) = LOW(ydelta);
1027 if (f == oldf)
1029 /* set repeat flag */
1030 *(flagsp - 1) |= REPEAT;
1032 if (*flagsp == 255)
1034 /* we can only handle 256 repetitions at once, */
1035 /* so use a new counter */
1036 flagsp++;
1037 *(flagsp++) = f;
1039 else
1040 *flagsp += 1; /* increase repetition counter */
1042 else
1044 if (*flagsp)
1045 flagsp++; /* skip repetition counter */
1046 *(flagsp++) = f;
1047 oldf = f;
1050 if (xcur > xmax)
1051 xmax = xcur;
1052 if (ycur > ymax)
1053 ymax = ycur;
1054 if (xcur < xmin)
1055 xmin = xcur;
1056 if (ycur < ymin)
1057 ymin = ycur;
1059 lastx = xcur;
1060 lasty = ycur;
1063 /* if the last byte was a repetition counter, */
1064 /* we must increase by one to get the correct array size */
1065 if (*flagsp)
1066 flagsp++;
1068 header[0] = HIGH(outline->n_contours);
1069 header[1] = LOW(outline->n_contours);
1070 header[2] = HIGH(xmin);
1071 header[3] = LOW(xmin);
1072 header[4] = HIGH(ymin);
1073 header[5] = LOW(ymin);
1074 header[6] = HIGH(xmax);
1075 header[7] = LOW(xmax);
1076 header[8] = HIGH(ymax);
1077 header[9] = LOW(ymax);
1079 /* concatenate all arrays and fill needed GLYPH structure elements */
1081 glyph->len1 = 10 + 2 * outline->n_contours;
1082 glyph->len2 = (flagsp - flags) + (xp - x) + (yp - y);
1084 glyph->buf = (FT_Byte*)malloc(glyph->len1 + glyph->len2);
1085 if (!glyph->buf)
1087 error = FT_Err_Out_Of_Memory;
1088 goto Exit;
1091 p = glyph->buf;
1092 memcpy(p, header, 10);
1093 p += 10;
1095 glyph->ins_len = 0;
1096 glyph->ins_buf = NULL;
1098 for (i = 0; i < outline->n_contours; i++)
1100 *(p++) = HIGH(outline->contours[i]);
1101 *(p++) = LOW(outline->contours[i]);
1104 memcpy(p, flags, flagsp - flags);
1105 p += flagsp - flags;
1106 memcpy(p, x, xp - x);
1107 p += xp - x;
1108 memcpy(p, y, yp - y);
1110 Exit:
1111 free(flags);
1112 free(x);
1113 free(y);
1115 return error;
1119 /* We hint each glyph at EM size and construct a new `glyf' table. */
1120 /* Some fonts need this; in particular, */
1121 /* there are CJK fonts which use hints to scale and position subglyphs. */
1122 /* As a consequence, there are no longer composite glyphs. */
1124 FT_Error
1125 TA_sfnt_create_glyf_data(SFNT* sfnt,
1126 FONT* font)
1128 SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
1129 FT_Face face = sfnt->face;
1130 FT_Error error;
1132 glyf_Data* data;
1134 FT_UShort i;
1137 /* in case of success, all allocated arrays are */
1138 /* linked and eventually freed in `TA_font_unload' */
1140 /* nothing to do if table has already been created */
1141 if (glyf_table->data)
1142 return TA_Err_Ok;
1144 data = (glyf_Data*)calloc(1, sizeof (glyf_Data));
1145 if (!data)
1146 return FT_Err_Out_Of_Memory;
1148 glyf_table->data = data;
1150 data->num_glyphs = face->num_glyphs;
1151 data->glyphs = (GLYPH*)calloc(1, data->num_glyphs * sizeof (GLYPH));
1152 if (!data->glyphs)
1153 return FT_Err_Out_Of_Memory;
1155 /* XXX: Make size configurable */
1156 /* we use the EM size */
1157 /* so that the resulting coordinates can be used without transformation */
1158 error = FT_Set_Char_Size(face, face->units_per_EM * 64, 0, 72, 0);
1159 if (error)
1160 return error;
1162 /* loop over all glyphs in font face */
1163 for (i = 0; i < data->num_glyphs; i++)
1165 GLYPH* glyph = &data->glyphs[i];
1168 error = FT_Load_Glyph(face, i, FT_LOAD_NO_BITMAP | FT_LOAD_NO_AUTOHINT);
1169 if (error)
1170 return error;
1172 error = TA_create_glyph_data(&face->glyph->outline, glyph);
1173 if (error)
1174 return error;
1177 return TA_Err_Ok;
1180 /* end of taglyf.c */