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.
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
)
835 error
= TA_sfnt_build_glyf_hints(sfnt
, font
);
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
)
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);
859 return FT_Err_Out_Of_Memory
;
861 glyf_table
->buf
= buf_new
;
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
)
873 /* copy glyph data and insert new instructions */
874 memcpy(p
, glyph
->buf
, glyph
->len1
);
880 *(p
++) = HIGH(glyph
->ins_len
);
881 *(p
++) = LOW(glyph
->ins_len
);
882 memcpy(p
, glyph
->ins_buf
, glyph
->ins_len
);
884 memcpy(p
, glyph
->buf
+ glyph
->len1
, glyph
->len2
);
889 /* composite glyph */
892 *(p
+ glyph
->flags_offset
) |= (WE_HAVE_INSTR
>> 8);
894 *(p
++) = HIGH(glyph
->ins_len
);
895 *(p
++) = LOW(glyph
->ins_len
);
896 memcpy(p
, glyph
->ins_buf
, glyph
->ins_len
);
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 */
920 glyf_table
->checksum
= TA_table_compute_checksum(glyf_table
->buf
,
922 glyf_table
->processed
= 1;
929 TA_create_glyph_data(FT_Outline
* outline
,
932 FT_Error error
= TA_Err_Ok
;
938 FT_Byte
* flags
= NULL
;
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' */
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);
966 error
= FT_Err_Out_Of_Memory
;
970 /* we have either one-byte or two-byte elements */
971 x
= (FT_Byte
*)malloc(2 * outline
->n_points
);
974 error
= FT_Err_Out_Of_Memory
;
978 y
= (FT_Byte
*)malloc(2 * outline
->n_points
);
981 error
= FT_Err_Out_Of_Memory
;
988 xmin
= xmax
= (outline
->points
[0].x
+ 32) >> 6;
989 ymin
= ymax
= (outline
->points
[0].y
+ 32) >> 6;
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
;
1014 if (xdelta
< 256 && xdelta
> -256)
1016 f
|= X_SHORT_VECTOR
;
1023 *(xp
++) = (FT_Byte
)xdelta
;
1027 *(xp
++) = HIGH(xdelta
);
1028 *(xp
++) = LOW(xdelta
);
1038 if (ydelta
< 256 && ydelta
> -256)
1040 f
|= Y_SHORT_VECTOR
;
1047 *(yp
++) = (FT_Byte
)ydelta
;
1051 *(yp
++) = HIGH(ydelta
);
1052 *(yp
++) = LOW(ydelta
);
1058 /* set repeat flag */
1059 *(flagsp
- 1) |= REPEAT
;
1063 /* we can only handle 256 repetitions at once, */
1064 /* so use a new counter */
1069 *flagsp
+= 1; /* increase repetition counter */
1074 flagsp
++; /* skip repetition counter */
1092 /* if the last byte was a repetition counter, */
1093 /* we must increase by one to get the correct array size */
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
);
1116 error
= FT_Err_Out_Of_Memory
;
1121 memcpy(p
, header
, 10);
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
);
1137 memcpy(p
, y
, yp
- y
);
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. */
1154 TA_sfnt_create_glyf_data(SFNT
* sfnt
,
1157 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
1158 FT_Face face
= sfnt
->face
;
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
)
1173 data
= (glyf_Data
*)calloc(1, sizeof (glyf_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
));
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);
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
);
1201 error
= TA_create_glyph_data(&face
->glyph
->outline
, glyph
);
1211 TA_sfnt_handle_coverage(SFNT
* sfnt
,
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
);
1234 error
= ta_loader_reset(font
, face
);
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
)
1245 data
->master_globals
= curr_globals
;
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
)
1282 TA_sfnt_adjust_master_coverage(SFNT
* sfnt
,
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
)
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
;
1316 TA_sfnt_copy_master_coverage(SFNT
* sfnt
,
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
);
1341 /* end of taglyf.c */