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.
20 TA_sfnt_build_glyf_hints(SFNT
* sfnt
,
23 FT_Face face
= sfnt
->face
;
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
);
39 ret
= font
->progress(idx
, face
->num_glyphs
,
40 sfnt
- font
->sfnts
, font
->num_sfnts
,
43 return TA_Err_Canceled
;
52 TA_glyph_get_components(GLYPH
* glyph
,
58 FT_UShort
* components_new
;
70 /* walk over component records */
74 return FT_Err_Invalid_Table
;
79 /* add component to list */
80 component
= *(p
++) << 8;
83 glyph
->num_components
++;
84 components_new
= (FT_UShort
*)realloc(glyph
->components
,
86 * sizeof (FT_UShort
));
89 glyph
->num_components
--;
90 return FT_Err_Out_Of_Memory
;
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
)
103 if (flags
& WE_HAVE_A_SCALE
)
105 else if (flags
& WE_HAVE_AN_XY_SCALE
)
107 else if (flags
& WE_HAVE_A_2X2
)
109 } while (flags
& MORE_COMPONENTS
);
116 TA_glyph_parse_composite(GLYPH
* glyph
,
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 */
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);
136 return FT_Err_Out_Of_Memory
;
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
)
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)
177 if (y_min
<= 0 && y_max
>= 0)
184 if (x_offset
>= -128 && x_offset
<= 127
185 && y_offset
>= -128 && y_offset
<= 127)
188 *(q
++) = ARGS_ARE_XY_VALUES
| MORE_COMPONENTS
;
189 *(q
++) = HIGH(num_glyphs
- 1);
190 *(q
++) = LOW(num_glyphs
- 1);
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
;
221 if (flags
& ARGS_ARE_XY_VALUES
)
227 if (flags
& ARGS_ARE_WORDS
)
235 /* handle point numbers */
241 if (flags
& ARGS_ARE_WORDS
)
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
])
261 for (i
= 0; i
< glyph
->num_pointsums
; i
++)
262 if (arg2
< glyph
->pointsums
[i
])
266 if (arg1
<= 0xFF && arg2
<= 0xFF)
268 glyph
->buf
[flags_offset
+ 1] &= ~ARGS_ARE_WORDS
;
275 glyph
->buf
[flags_offset
+ 1] |= ARGS_ARE_WORDS
;
284 /* copy scaling arguments */
285 if (flags
& (WE_HAVE_A_SCALE
| WE_HAVE_AN_XY_SCALE
| WE_HAVE_A_2X2
))
290 if (flags
& (WE_HAVE_AN_XY_SCALE
| WE_HAVE_A_2X2
))
295 if (flags
& WE_HAVE_A_2X2
)
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);
317 TA_glyph_parse_simple(GLYPH
* glyph
,
322 FT_Byte
* flags_start
;
326 FT_ULong flags_size
; /* size of the flags array */
327 FT_ULong xy_size
; /* size of x and y coordinate arrays together */
338 ins_offset
= 10 + glyph
->num_contours
* 2;
343 return FT_Err_Invalid_Table
;
345 /* get number of instructions */
346 num_ins
= *(p
++) << 8;
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
;
364 return FT_Err_Invalid_Table
;
370 while (i
< glyph
->num_points
)
381 return FT_Err_Invalid_Table
;
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;
396 return FT_Err_Invalid_Table
;
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
;
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
);
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
);
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
;
444 /* save current state */
446 if (*num_pointsums
== 0xFFFF)
447 return FT_Err_Invalid_Table
;
450 pointsums_new
= (FT_UShort
*)realloc(*pointsums
,
452 * sizeof (FT_UShort
));
456 return FT_Err_Out_Of_Memory
;
459 *pointsums
= pointsums_new
;
461 (*pointsums
)[*num_pointsums
- 1] = *num_composite_points
;
463 for (i
= 0; i
< num_components
; i
++)
466 FT_UShort component
= components
[i
];
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
,
479 glyph
->num_components
,
482 num_composite_contours
,
483 num_composite_points
);
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
;
504 TA_sfnt_compute_composite_pointsums(SFNT
* sfnt
,
507 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
508 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
513 for (i
= 0; i
< data
->num_glyphs
; i
++)
515 GLYPH
* glyph
= &data
->glyphs
[i
];
518 if (glyph
->num_components
)
521 FT_UShort num_composite_contours
= 0;
522 FT_UShort num_composite_points
= 0;
525 error
= TA_iterate_composite_glyph(data
,
527 glyph
->num_components
,
529 &glyph
->num_pointsums
,
530 &num_composite_contours
,
531 &num_composite_points
);
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
;
559 TA_sfnt_split_glyf_table(SFNT
* sfnt
,
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
];
570 FT_ULong offset_next
;
574 FT_UShort loop_count
;
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
)
586 data
= (glyf_Data
*)calloc(1, sizeof (glyf_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
));
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 */
616 offset_next
= *(p
++) << 24;
617 offset_next
+= *(p
++) << 16;
618 offset_next
+= *(p
++) << 8;
619 offset_next
+= *(p
++);
623 offset_next
= *(p
++) << 8;
624 offset_next
+= *(p
++);
628 for (i
= 0; i
< loop_count
; i
++)
630 GLYPH
* glyph
= &data
->glyphs
[i
];
634 offset
= offset_next
;
638 offset_next
= *(p
++) << 24;
639 offset_next
+= *(p
++) << 16;
640 offset_next
+= *(p
++) << 8;
641 offset_next
+= *(p
++);
645 offset_next
= *(p
++) << 8;
646 offset_next
+= *(p
++);
650 if (offset_next
< offset
651 || offset_next
> glyf_table
->len
)
652 return FT_Err_Invalid_Table
;
654 len
= offset_next
- offset
;
656 continue; /* empty glyph */
662 /* check header size */
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
);
682 /* use the last contour's end point to compute number of points */
683 off
= 10 + (glyph
->num_contours
- 1) * 2;
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
);
700 /* second loop over `loca' and `glyf' data */
706 offset_next
= *(p
++) << 24;
707 offset_next
+= *(p
++) << 16;
708 offset_next
+= *(p
++) << 8;
709 offset_next
+= *(p
++);
713 offset_next
= *(p
++) << 8;
714 offset_next
+= *(p
++);
718 for (i
= 0; i
< loop_count
; i
++)
720 GLYPH
* glyph
= &data
->glyphs
[i
];
724 offset
= offset_next
;
728 offset_next
= *(p
++) << 24;
729 offset_next
+= *(p
++) << 16;
730 offset_next
+= *(p
++) << 8;
731 offset_next
+= *(p
++);
735 offset_next
= *(p
++) << 8;
736 offset_next
+= *(p
++);
740 len
= offset_next
- offset
;
742 continue; /* empty glyph */
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
,
760 font
->hint_with_components
);
762 error
= TA_glyph_parse_simple(glyph
, buf
, len
);
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];
776 glyph
->buf
= (FT_Byte
*)malloc(glyph
->len1
+ glyph
->len2
);
778 return FT_Err_Out_Of_Memory
;
782 buf
[0] = 0x00; /* one contour */
784 buf
[2] = 0x00; /* no dimensions */
792 buf
[10] = 0x00; /* one contour end point */
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
);
803 return FT_Err_Out_Of_Memory
;
804 memcpy(glyph
->ins_buf
, ttfautohint_glyph_bytecode
, glyph
->ins_len
);
806 sfnt
->max_components
+= 1;
814 TA_sfnt_build_glyf_table(SFNT
* sfnt
,
819 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
820 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
830 if (glyf_table
->processed
)
833 error
= TA_sfnt_build_glyf_hints(sfnt
, font
);
839 glyph
= data
->glyphs
;
840 for (i
= 0; i
< data
->num_glyphs
; i
++, glyph
++)
842 /* glyph records should have offsets which are multiples of 4 */
843 len
= (len
+ 3) & ~3;
844 len
+= glyph
->len1
+ glyph
->len2
+ glyph
->ins_len
;
845 /* add two bytes for the instructionLength field */
846 if (glyph
->len2
|| glyph
->ins_len
)
850 /* to make the short format of the `loca' table always work, */
851 /* assure an even length of the `glyf' table */
852 glyf_table
->len
= (len
+ 1) & ~1;
854 buf_new
= (FT_Byte
*)realloc(glyf_table
->buf
, (len
+ 3) & ~3);
856 return FT_Err_Out_Of_Memory
;
858 glyf_table
->buf
= buf_new
;
861 glyph
= data
->glyphs
;
862 for (i
= 0; i
< data
->num_glyphs
; i
++, glyph
++)
864 len
= glyph
->len1
+ glyph
->len2
+ glyph
->ins_len
;
865 if (glyph
->len2
|| glyph
->ins_len
)
870 /* copy glyph data and insert new instructions */
871 memcpy(p
, glyph
->buf
, glyph
->len1
);
877 *(p
++) = HIGH(glyph
->ins_len
);
878 *(p
++) = LOW(glyph
->ins_len
);
879 memcpy(p
, glyph
->ins_buf
, glyph
->ins_len
);
881 memcpy(p
, glyph
->buf
+ glyph
->len1
, glyph
->len2
);
886 /* composite glyph */
889 *(p
+ glyph
->flags_offset
) |= (WE_HAVE_INSTR
>> 8);
891 *(p
++) = HIGH(glyph
->ins_len
);
892 *(p
++) = LOW(glyph
->ins_len
);
893 memcpy(p
, glyph
->ins_buf
, glyph
->ins_len
);
900 /* pad with zero bytes to have an offset which is a multiple of 4; */
901 /* this works even for the last glyph record since the `glyf' */
902 /* table length is a multiple of 4 also */
917 glyf_table
->checksum
= TA_table_compute_checksum(glyf_table
->buf
,
919 glyf_table
->processed
= 1;
926 TA_create_glyph_data(FT_Outline
* outline
,
929 FT_Error error
= TA_Err_Ok
;
935 FT_Byte
* flags
= NULL
;
949 if (!outline
->n_contours
)
950 return TA_Err_Ok
; /* empty glyph */
952 /* in case of success, all non-local allocated arrays are */
953 /* linked and eventually freed in `TA_font_unload' */
957 /* we use `calloc' since we rely on the array */
958 /* being initialized to zero; */
959 /* additionally, we need one more byte for a test after the loop */
960 flags
= (FT_Byte
*)calloc(1, outline
->n_points
+ 1);
963 error
= FT_Err_Out_Of_Memory
;
967 /* we have either one-byte or two-byte elements */
968 x
= (FT_Byte
*)malloc(2 * outline
->n_points
);
971 error
= FT_Err_Out_Of_Memory
;
975 y
= (FT_Byte
*)malloc(2 * outline
->n_points
);
978 error
= FT_Err_Out_Of_Memory
;
985 xmin
= xmax
= (outline
->points
[0].x
+ 32) >> 6;
986 ymin
= ymax
= (outline
->points
[0].y
+ 32) >> 6;
989 oldf
= 0x80; /* start with an impossible value */
991 /* convert the FreeType representation of the glyph's outline */
992 /* into the representation format of the `glyf' table */
993 for (i
= 0; i
< outline
->n_points
; i
++)
995 FT_Pos xcur
= (outline
->points
[i
].x
+ 32) >> 6;
996 FT_Pos ycur
= (outline
->points
[i
].y
+ 32) >> 6;
998 FT_Pos xdelta
= xcur
- lastx
;
999 FT_Pos ydelta
= ycur
- lasty
;
1002 /* we are only interested in bit 0 of the `tags' array */
1003 f
= outline
->tags
[i
] & ON_CURVE
;
1011 if (xdelta
< 256 && xdelta
> -256)
1013 f
|= X_SHORT_VECTOR
;
1020 *(xp
++) = (FT_Byte
)xdelta
;
1024 *(xp
++) = HIGH(xdelta
);
1025 *(xp
++) = LOW(xdelta
);
1035 if (ydelta
< 256 && ydelta
> -256)
1037 f
|= Y_SHORT_VECTOR
;
1044 *(yp
++) = (FT_Byte
)ydelta
;
1048 *(yp
++) = HIGH(ydelta
);
1049 *(yp
++) = LOW(ydelta
);
1055 /* set repeat flag */
1056 *(flagsp
- 1) |= REPEAT
;
1060 /* we can only handle 256 repetitions at once, */
1061 /* so use a new counter */
1066 *flagsp
+= 1; /* increase repetition counter */
1071 flagsp
++; /* skip repetition counter */
1089 /* if the last byte was a repetition counter, */
1090 /* we must increase by one to get the correct array size */
1094 header
[0] = HIGH(outline
->n_contours
);
1095 header
[1] = LOW(outline
->n_contours
);
1096 header
[2] = HIGH(xmin
);
1097 header
[3] = LOW(xmin
);
1098 header
[4] = HIGH(ymin
);
1099 header
[5] = LOW(ymin
);
1100 header
[6] = HIGH(xmax
);
1101 header
[7] = LOW(xmax
);
1102 header
[8] = HIGH(ymax
);
1103 header
[9] = LOW(ymax
);
1105 /* concatenate all arrays and fill needed GLYPH structure elements */
1107 glyph
->len1
= 10 + 2 * outline
->n_contours
;
1108 glyph
->len2
= (flagsp
- flags
) + (xp
- x
) + (yp
- y
);
1110 glyph
->buf
= (FT_Byte
*)malloc(glyph
->len1
+ glyph
->len2
);
1113 error
= FT_Err_Out_Of_Memory
;
1118 memcpy(p
, header
, 10);
1122 glyph
->ins_buf
= NULL
;
1124 for (i
= 0; i
< outline
->n_contours
; i
++)
1126 *(p
++) = HIGH(outline
->contours
[i
]);
1127 *(p
++) = LOW(outline
->contours
[i
]);
1130 memcpy(p
, flags
, flagsp
- flags
);
1131 p
+= flagsp
- flags
;
1132 memcpy(p
, x
, xp
- x
);
1134 memcpy(p
, y
, yp
- y
);
1145 /* We hint each glyph at EM size and construct a new `glyf' table. */
1146 /* Some fonts need this; in particular, */
1147 /* there are CJK fonts which use hints to scale and position subglyphs. */
1148 /* As a consequence, there are no longer composite glyphs. */
1151 TA_sfnt_create_glyf_data(SFNT
* sfnt
,
1154 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
1155 FT_Face face
= sfnt
->face
;
1163 /* in case of success, all allocated arrays are */
1164 /* linked and eventually freed in `TA_font_unload' */
1166 /* nothing to do if table has already been created */
1167 if (glyf_table
->data
)
1170 data
= (glyf_Data
*)calloc(1, sizeof (glyf_Data
));
1172 return FT_Err_Out_Of_Memory
;
1174 glyf_table
->data
= data
;
1176 data
->num_glyphs
= face
->num_glyphs
;
1177 data
->glyphs
= (GLYPH
*)calloc(1, data
->num_glyphs
* sizeof (GLYPH
));
1179 return FT_Err_Out_Of_Memory
;
1181 /* XXX: Make size configurable */
1182 /* we use the EM size */
1183 /* so that the resulting coordinates can be used without transformation */
1184 error
= FT_Set_Char_Size(face
, face
->units_per_EM
* 64, 0, 72, 0);
1188 /* loop over all glyphs in font face */
1189 for (i
= 0; i
< data
->num_glyphs
; i
++)
1191 GLYPH
* glyph
= &data
->glyphs
[i
];
1194 error
= FT_Load_Glyph(face
, i
, FT_LOAD_NO_BITMAP
| FT_LOAD_NO_AUTOHINT
);
1198 error
= TA_create_glyph_data(&face
->glyph
->outline
, glyph
);
1208 TA_sfnt_handle_coverage(SFNT
* sfnt
,
1213 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
1214 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
1216 FT_Face face
= sfnt
->face
;
1217 TA_FaceGlobals curr_globals
;
1219 FT_UInt saved_fallback_script
= font
->fallback_script
;
1222 /* using TA_SCRIPT_NONE as the fallback script ensures */
1223 /* that uncovered glyphs stay as-is */
1224 /* (we handle the fallback script later on) */
1225 font
->fallback_script
= TA_SCRIPT_NONE
;
1227 /* trigger computation of coverage */
1228 error
= ta_loader_init(font
);
1231 error
= ta_loader_reset(font
, face
);
1234 ta_loader_done(font
);
1236 font
->fallback_script
= saved_fallback_script
;
1237 curr_globals
= (TA_FaceGlobals
)face
->autohint
.data
;
1239 if (!data
->master_globals
)
1242 data
->master_globals
= curr_globals
;
1246 /* we have the same `glyf' table for another subfont; */
1247 /* merge the current coverage info into the `master' coverage info */
1249 TA_FaceGlobals master_globals
= data
->master_globals
;
1250 FT_Long count
= master_globals
->glyph_count
;
1252 FT_Byte
* master
= master_globals
->glyph_scripts
;
1253 FT_Byte
* curr
= curr_globals
->glyph_scripts
;
1255 FT_Byte
* limit
= master
+ count
;
1258 /* we simply copy the data, */
1259 /* assuming that a given glyph always has the same properties -- */
1260 /* as soon as we make the script selection more fine-grained, */
1261 /* it is possible that this assumption doesn't hold: */
1262 /* for example, glyph `A' can be used for both Cyrillic and Latin */
1263 while (master
< limit
)
1265 if ((*curr
& ~TA_DIGIT
) != TA_SCRIPT_NONE
)
1279 TA_sfnt_adjust_master_coverage(SFNT
* sfnt
,
1282 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
1283 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
1285 FT_Face face
= sfnt
->face
;
1287 TA_FaceGlobals master_globals
= data
->master_globals
;
1288 TA_FaceGlobals curr_globals
= (TA_FaceGlobals
)face
->autohint
.data
;
1291 /* use fallback script for uncovered glyphs */
1292 if (master_globals
== curr_globals
)
1295 FT_Byte
* gscripts
= master_globals
->glyph_scripts
;
1298 for (nn
= 0; nn
< master_globals
->glyph_count
; nn
++)
1300 if ((gscripts
[nn
] & ~TA_DIGIT
) == TA_SCRIPT_NONE
)
1302 gscripts
[nn
] &= ~TA_SCRIPT_NONE
;
1303 gscripts
[nn
] |= master_globals
->font
->fallback_script
;
1313 TA_sfnt_copy_master_coverage(SFNT
* sfnt
,
1316 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
1317 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
1319 FT_Face face
= sfnt
->face
;
1321 TA_FaceGlobals master_globals
= data
->master_globals
;
1322 TA_FaceGlobals curr_globals
= (TA_FaceGlobals
)face
->autohint
.data
;
1325 if (master_globals
!= curr_globals
)
1327 FT_Long count
= master_globals
->glyph_count
;
1328 FT_Byte
* master
= master_globals
->glyph_scripts
;
1329 FT_Byte
* curr
= curr_globals
->glyph_scripts
;
1332 memcpy(curr
, master
, count
);
1338 /* end of taglyf.c */