4 * Copyright (C) 2011-2015 by Werner Lemberg.
6 * This file is part of the ttfautohint library, and may only be used,
7 * modified, and distributed under the terms given in `COPYING'. By
8 * continuing to use, modify, or distribute this file you indicate that you
9 * have read `COPYING' and understand and accept it fully.
11 * The file `COPYING' mentioned in the previous paragraph is distributed
12 * with the ttfautohint library.
20 TA_sfnt_build_glyf_hints(SFNT
* sfnt
,
23 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
24 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
32 /* this loop doesn't include the artificial `.ttfautohint' glyph */
33 loop_count
= data
->num_glyphs
;
34 if (sfnt
->max_components
&& font
->hint_composites
)
37 for (idx
= 0; idx
< loop_count
; idx
++)
39 error
= TA_sfnt_build_glyph_instructions(sfnt
, font
, idx
);
47 ret
= font
->progress(idx
, loop_count
,
48 sfnt
- font
->sfnts
, font
->num_sfnts
,
51 return TA_Err_Canceled
;
60 TA_glyph_get_components(GLYPH
* glyph
,
66 FT_UShort
* components_new
;
78 /* walk over component records */
82 return FT_Err_Invalid_Table
;
84 flags
= NEXT_USHORT(p
);
86 /* add component to list */
87 component
= NEXT_USHORT(p
);
89 glyph
->num_components
++;
90 components_new
= (FT_UShort
*)realloc(glyph
->components
,
92 * sizeof (FT_UShort
));
95 glyph
->num_components
--;
96 return FT_Err_Out_Of_Memory
;
99 glyph
->components
= components_new
;
101 glyph
->components
[glyph
->num_components
- 1] = component
;
103 /* skip scaling and offset arguments */
104 if (flags
& ARGS_ARE_WORDS
)
109 if (flags
& WE_HAVE_A_SCALE
)
111 else if (flags
& WE_HAVE_AN_XY_SCALE
)
113 else if (flags
& WE_HAVE_A_2X2
)
115 } while (flags
& MORE_COMPONENTS
);
122 TA_glyph_parse_composite(GLYPH
* glyph
,
125 FT_UShort num_glyphs
,
126 FT_Bool hint_composites
)
128 FT_ULong flags_offset
; /* after the loop, this is the offset */
129 /* to the last element in the flags array */
136 /* we allocate too large a buffer */
137 /* (including space for the new component */
138 /* and possible argument size changes for shifted point indices) */
139 /* and reallocate it later to its real size */
140 glyph
->buf
= (FT_Byte
*)malloc(len
+ 8 + glyph
->num_components
* 2);
142 return FT_Err_Out_Of_Memory
;
152 /* if the composite glyph contains one or more contours, */
153 /* we prepend a composite glyph component to call some bytecode */
154 /* which eventually becomes the last glyph in the `glyf' table; */
155 /* for convenience, however, it is not added to the `components' array */
156 /* (doing so simplifies the conversion of point indices later on) */
157 if (glyph
->num_composite_contours
&& hint_composites
)
167 /* the composite glyph's bounding box */
168 x_min
= (FT_Short
)((buf
[2] << 8) + buf
[3]);
169 y_min
= (FT_Short
)((buf
[4] << 8) + buf
[5]);
170 x_max
= (FT_Short
)((buf
[6] << 8) + buf
[7]);
171 y_max
= (FT_Short
)((buf
[8] << 8) + buf
[9]);
173 /* use ARGS_ARE_WORDS only if necessary; */
174 /* note that the offset value of the component doesn't matter */
175 /* as long as it stays within the bounding box */
176 if (x_min
<= 0 && x_max
>= 0)
183 if (y_min
<= 0 && y_max
>= 0)
190 if (x_offset
>= -128 && x_offset
<= 127
191 && y_offset
>= -128 && y_offset
<= 127)
194 *(q
++) = ARGS_ARE_XY_VALUES
| MORE_COMPONENTS
;
195 *(q
++) = HIGH(num_glyphs
- 1);
196 *(q
++) = LOW(num_glyphs
- 1);
197 *(q
++) = (FT_Byte
)x_offset
;
198 *(q
++) = (FT_Byte
)y_offset
;
203 *(q
++) = ARGS_ARE_WORDS
| ARGS_ARE_XY_VALUES
| MORE_COMPONENTS
;
204 *(q
++) = HIGH(num_glyphs
- 1);
205 *(q
++) = LOW(num_glyphs
- 1);
206 *(q
++) = HIGH(x_offset
);
207 *(q
++) = LOW(x_offset
);
208 *(q
++) = HIGH(y_offset
);
209 *(q
++) = LOW(y_offset
);
213 /* walk over component records */
216 flags_offset
= q
- glyph
->buf
;
220 flags
= NEXT_USHORT(p
);
226 if (flags
& ARGS_ARE_XY_VALUES
)
232 if (flags
& ARGS_ARE_WORDS
)
240 /* handle point numbers */
246 if (flags
& ARGS_ARE_WORDS
)
259 /* adjust point numbers */
260 /* (see `TA_adjust_point_index' in `tabytecode.c' for more) */
261 for (i
= 0; i
< glyph
->num_pointsums
; i
++)
262 if (arg1
< glyph
->pointsums
[i
])
266 for (i
= 0; i
< glyph
->num_pointsums
; i
++)
267 if (arg2
< glyph
->pointsums
[i
])
271 if (arg1
<= 0xFF && arg2
<= 0xFF)
273 glyph
->buf
[flags_offset
+ 1] &= ~ARGS_ARE_WORDS
;
275 *(q
++) = (FT_Byte
)arg1
;
276 *(q
++) = (FT_Byte
)arg2
;
280 glyph
->buf
[flags_offset
+ 1] |= ARGS_ARE_WORDS
;
289 /* copy scaling arguments */
290 if (flags
& (WE_HAVE_A_SCALE
| WE_HAVE_AN_XY_SCALE
| WE_HAVE_A_2X2
))
295 if (flags
& (WE_HAVE_AN_XY_SCALE
| WE_HAVE_A_2X2
))
300 if (flags
& WE_HAVE_A_2X2
)
307 } while (flags
& MORE_COMPONENTS
);
309 glyph
->len1
= q
- glyph
->buf
;
310 /* glyph->len2 = 0; */
311 glyph
->flags_offset
= flags_offset
;
312 glyph
->buf
= (FT_Byte
*)realloc(glyph
->buf
, glyph
->len1
);
314 /* we discard instructions (if any) */
315 glyph
->buf
[glyph
->flags_offset
] &= ~(WE_HAVE_INSTR
>> 8);
322 TA_glyph_parse_simple(GLYPH
* glyph
,
327 FT_Byte
* flags_start
;
331 FT_ULong flags_size
; /* size of the flags array */
332 FT_ULong xy_size
; /* size of x and y coordinate arrays together */
343 ins_offset
= 10 + glyph
->num_contours
* 2;
348 return FT_Err_Invalid_Table
;
350 /* get number of instructions */
351 num_ins
= NEXT_USHORT(p
);
353 /* assure that we don't process a font */
354 /* which already contains a `.ttfautohint' glyph */
355 /* (a font with a `post' table version 3.0 doesn't contain glyph names, */
356 /* so we have to check it this way) */
357 if (glyph
->num_points
== 1
358 && num_ins
>= sizeof (ttfautohint_glyph_bytecode
))
360 if (!strncmp((char*)p
, (char*)ttfautohint_glyph_bytecode
,
361 sizeof (ttfautohint_glyph_bytecode
)))
362 return TA_Err_Already_Processed
;
368 return FT_Err_Invalid_Table
;
374 while (i
< glyph
->num_points
)
385 return FT_Err_Invalid_Table
;
389 x_short
= (flags
& X_SHORT_VECTOR
) ? 1 : 2;
390 y_short
= (flags
& Y_SHORT_VECTOR
) ? 1 : 2;
392 have_x
= ((flags
& SAME_X
) && !(flags
& X_SHORT_VECTOR
)) ? 0 : 1;
393 have_y
= ((flags
& SAME_Y
) && !(flags
& Y_SHORT_VECTOR
)) ? 0 : 1;
400 return FT_Err_Invalid_Table
;
404 if (i
+ count
> glyph
->num_points
)
405 return FT_Err_Invalid_Table
;
408 xy_size
+= count
* x_short
* have_x
;
409 xy_size
+= count
* y_short
* have_y
;
414 if (p
+ xy_size
> endp
)
415 return FT_Err_Invalid_Table
;
417 flags_size
= p
- flags_start
;
419 /* store the data before and after the bytecode instructions */
420 /* in the same array */
421 glyph
->len1
= ins_offset
;
422 glyph
->len2
= flags_size
+ xy_size
;
423 glyph
->buf
= (FT_Byte
*)malloc(glyph
->len1
+ glyph
->len2
);
425 return FT_Err_Out_Of_Memory
;
427 /* now copy everything but the instructions */
428 memcpy(glyph
->buf
, buf
, glyph
->len1
);
429 memcpy(glyph
->buf
+ glyph
->len1
, flags_start
, glyph
->len2
);
436 TA_iterate_composite_glyph(glyf_Data
* data
,
437 FT_UShort
* components
,
438 FT_UShort num_components
,
439 FT_UShort
** pointsums
,
440 FT_UShort
* num_pointsums
,
441 FT_UShort
* num_composite_contours
,
442 FT_UShort
* num_composite_points
)
444 FT_UShort
* pointsums_new
;
448 /* save current state */
450 if (*num_pointsums
== 0xFFFF)
451 return FT_Err_Invalid_Table
;
454 pointsums_new
= (FT_UShort
*)realloc(*pointsums
,
456 * sizeof (FT_UShort
));
460 return FT_Err_Out_Of_Memory
;
463 *pointsums
= pointsums_new
;
465 (*pointsums
)[*num_pointsums
- 1] = *num_composite_points
;
467 for (i
= 0; i
< num_components
; i
++)
470 FT_UShort component
= components
[i
];
474 if (component
>= data
->num_glyphs
)
475 return FT_Err_Invalid_Table
;
477 glyph
= &data
->glyphs
[component
];
479 if (glyph
->num_components
)
481 error
= TA_iterate_composite_glyph(data
,
483 glyph
->num_components
,
486 num_composite_contours
,
487 num_composite_points
);
493 /* no need for checking overflow of the number of contours */
494 /* since the number of points is always larger or equal */
495 if (*num_composite_points
> 0xFFFF - glyph
->num_points
)
496 return FT_Err_Invalid_Table
;
498 *num_composite_contours
+= glyph
->num_contours
;
499 *num_composite_points
+= glyph
->num_points
;
508 TA_sfnt_compute_composite_pointsums(SFNT
* sfnt
,
511 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
512 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
517 for (i
= 0; i
< data
->num_glyphs
; i
++)
519 GLYPH
* glyph
= &data
->glyphs
[i
];
522 if (glyph
->num_components
)
525 FT_UShort num_composite_contours
= 0;
526 FT_UShort num_composite_points
= 0;
529 error
= TA_iterate_composite_glyph(data
,
531 glyph
->num_components
,
533 &glyph
->num_pointsums
,
534 &num_composite_contours
,
535 &num_composite_points
);
539 glyph
->num_composite_contours
= num_composite_contours
;
541 if (font
->hint_composites
)
543 /* update maximum values, */
544 /* including the subglyphs not in `components' array */
545 /* (each of them has a single point in a single contour) */
546 if (num_composite_points
+ glyph
->num_pointsums
547 > sfnt
->max_composite_points
)
548 sfnt
->max_composite_points
= num_composite_points
549 + glyph
->num_pointsums
;
550 if (num_composite_contours
+ glyph
->num_pointsums
551 > sfnt
->max_composite_contours
)
552 sfnt
->max_composite_contours
= num_composite_contours
553 + glyph
->num_pointsums
;
563 TA_sfnt_split_glyf_table(SFNT
* sfnt
,
566 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
567 SFNT_Table
* loca_table
= &font
->tables
[sfnt
->loca_idx
];
568 SFNT_Table
* head_table
= &font
->tables
[sfnt
->head_idx
];
574 FT_ULong offset_next
;
578 FT_UShort loop_count
;
583 /* in case of success, all allocated arrays are */
584 /* linked and eventually freed in `TA_font_unload' */
586 /* nothing to do if table has already been split */
587 if (glyf_table
->data
)
590 data
= (glyf_Data
*)calloc(1, sizeof (glyf_Data
));
592 return FT_Err_Out_Of_Memory
;
594 glyf_table
->data
= data
;
596 loca_format
= head_table
->buf
[LOCA_FORMAT_OFFSET
];
598 data
->num_glyphs
= (FT_UShort
)(loca_format
? loca_table
->len
/ 4
599 : loca_table
->len
/ 2);
600 loop_count
= data
->num_glyphs
- 1;
602 /* allocate one more glyph slot if we have composite glyphs */
603 if (!sfnt
->max_components
|| !font
->hint_composites
)
604 data
->num_glyphs
-= 1;
605 data
->glyphs
= (GLYPH
*)calloc(1, data
->num_glyphs
* sizeof (GLYPH
));
607 return FT_Err_Out_Of_Memory
;
609 data
->master_globals
= NULL
;
610 data
->cvt_idx
= MISSING
;
611 data
->fpgm_idx
= MISSING
;
612 data
->prep_idx
= MISSING
;
614 /* first loop over `loca' and `glyf' data */
619 offset_next
= NEXT_ULONG(p
);
622 offset_next
= NEXT_USHORT(p
);
626 for (i
= 0; i
< loop_count
; i
++)
628 GLYPH
* glyph
= &data
->glyphs
[i
];
632 offset
= offset_next
;
635 offset_next
= NEXT_ULONG(p
);
638 offset_next
= NEXT_USHORT(p
);
642 if (offset_next
< offset
643 || offset_next
> glyf_table
->len
)
644 return FT_Err_Invalid_Table
;
646 len
= offset_next
- offset
;
648 continue; /* empty glyph */
654 /* check header size */
656 return FT_Err_Invalid_Table
;
658 /* we need the number of contours and points for */
659 /* `TA_sfnt_compute_composite_pointsums' */
660 buf
= glyf_table
->buf
+ offset
;
661 glyph
->num_contours
= (FT_Short
)((buf
[0] << 8) + buf
[1]);
663 if (glyph
->num_contours
< 0)
665 error
= TA_glyph_get_components(glyph
, buf
, len
);
674 /* use the last contour's end point to compute number of points */
675 off
= 10 + (glyph
->num_contours
- 1) * 2;
677 return FT_Err_Invalid_Table
;
679 glyph
->num_points
= (FT_UShort
)((buf
[off
] << 8) + buf
[off
+ 1] + 1);
684 if (sfnt
->max_components
&& font
->hint_composites
)
686 error
= TA_sfnt_compute_composite_pointsums(sfnt
, font
);
691 /* second loop over `loca' and `glyf' data */
696 offset_next
= NEXT_ULONG(p
);
699 offset_next
= NEXT_USHORT(p
);
703 for (i
= 0; i
< loop_count
; i
++)
705 GLYPH
* glyph
= &data
->glyphs
[i
];
709 offset
= offset_next
;
712 offset_next
= NEXT_ULONG(p
);
715 offset_next
= NEXT_USHORT(p
);
719 len
= offset_next
- offset
;
721 continue; /* empty glyph */
727 buf
= glyf_table
->buf
+ offset
;
729 /* We must parse the rest of the glyph record to get the exact */
730 /* record length. Since the `loca' table rounds record lengths */
731 /* up to multiples of 4 (or 2 for older fonts), and we must round */
732 /* up again after stripping off the instructions, it would be */
733 /* possible otherwise to have more than 4 bytes of padding which */
734 /* is more or less invalid. */
736 if (glyph
->num_contours
< 0)
737 error
= TA_glyph_parse_composite(glyph
, buf
, len
,
739 font
->hint_composites
);
741 error
= TA_glyph_parse_simple(glyph
, buf
, len
);
747 if (sfnt
->max_components
&& font
->hint_composites
)
749 /* construct and append our special glyph used as a composite element */
750 GLYPH
* glyph
= &data
->glyphs
[data
->num_glyphs
- 1];
755 glyph
->buf
= (FT_Byte
*)malloc(glyph
->len1
+ glyph
->len2
);
757 return FT_Err_Out_Of_Memory
;
761 buf
[0] = 0x00; /* one contour */
763 buf
[2] = 0x00; /* no dimensions */
771 buf
[10] = 0x00; /* one contour end point */
774 buf
[12] = ON_CURVE
| SAME_X
| SAME_Y
; /* the flags for a point at 0,0 */
776 /* add bytecode also; */
777 /* this works because the loop in `TA_sfnt_build_glyf_hints' */
778 /* doesn't include the newly appended glyph */
779 glyph
->ins_len
= sizeof (ttfautohint_glyph_bytecode
);
780 glyph
->ins_buf
= (FT_Byte
*)malloc(glyph
->ins_len
);
782 return FT_Err_Out_Of_Memory
;
783 memcpy(glyph
->ins_buf
, ttfautohint_glyph_bytecode
, glyph
->ins_len
);
785 sfnt
->max_components
+= 1;
793 TA_sfnt_build_glyf_table(SFNT
* sfnt
,
798 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
799 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
809 if (glyf_table
->processed
)
814 error
= TA_sfnt_build_glyf_hints(sfnt
, font
);
821 glyph
= data
->glyphs
;
822 for (i
= 0; i
< data
->num_glyphs
; i
++, glyph
++)
824 /* glyph records should have offsets which are multiples of 4 */
825 len
= (len
+ 3) & ~3U;
826 len
+= glyph
->len1
+ glyph
->len2
827 + glyph
->ins_extra_len
+ glyph
->ins_len
;
828 /* add two bytes for the instructionLength field */
829 if (glyph
->len2
|| glyph
->ins_len
)
833 /* to make the short format of the `loca' table always work, */
834 /* assure an even length of the `glyf' table */
835 glyf_table
->len
= (len
+ 1) & ~1U;
837 buf_new
= (FT_Byte
*)realloc(glyf_table
->buf
, (len
+ 3) & ~3U);
839 return FT_Err_Out_Of_Memory
;
841 glyf_table
->buf
= buf_new
;
844 glyph
= data
->glyphs
;
845 for (i
= 0; i
< data
->num_glyphs
; i
++, glyph
++)
847 len
= glyph
->len1
+ glyph
->len2
848 + glyph
->ins_extra_len
+ glyph
->ins_len
;
849 if (glyph
->len2
|| glyph
->ins_len
)
854 /* copy glyph data and insert new instructions */
855 memcpy(p
, glyph
->buf
, glyph
->len1
);
861 *(p
++) = HIGH(glyph
->ins_extra_len
+ glyph
->ins_len
);
862 *(p
++) = LOW(glyph
->ins_extra_len
+ glyph
->ins_len
);
863 if (glyph
->ins_extra_len
)
865 memcpy(p
, ins_extra_buf
, glyph
->ins_extra_len
);
866 p
+= glyph
->ins_extra_len
;
868 memcpy(p
, glyph
->ins_buf
, glyph
->ins_len
);
870 memcpy(p
, glyph
->buf
+ glyph
->len1
, glyph
->len2
);
875 /* composite glyph */
878 *(p
+ glyph
->flags_offset
) |= (WE_HAVE_INSTR
>> 8);
880 *(p
++) = HIGH(glyph
->ins_extra_len
+ glyph
->ins_len
);
881 *(p
++) = LOW(glyph
->ins_extra_len
+ glyph
->ins_len
);
882 if (glyph
->ins_extra_len
)
884 memcpy(p
, ins_extra_buf
, glyph
->ins_extra_len
);
885 p
+= glyph
->ins_extra_len
;
887 memcpy(p
, glyph
->ins_buf
, glyph
->ins_len
);
894 /* pad with zero bytes to have an offset which is a multiple of 4; */
895 /* this works even for the last glyph record since the `glyf' */
896 /* table length is a multiple of 4 also */
911 glyf_table
->checksum
= TA_table_compute_checksum(glyf_table
->buf
,
913 glyf_table
->processed
= 1;
920 TA_create_glyph_data(FT_Outline
* outline
,
923 FT_Error error
= TA_Err_Ok
;
929 FT_Byte
* flags
= NULL
;
943 if (!outline
->n_contours
)
944 return TA_Err_Ok
; /* empty glyph */
946 /* in case of success, all non-local allocated arrays are */
947 /* linked and eventually freed in `TA_font_unload' */
951 /* we use `calloc' since we rely on the array */
952 /* being initialized to zero; */
953 /* additionally, we need one more byte for a test after the loop */
954 flags
= (FT_Byte
*)calloc(1, outline
->n_points
+ 1);
957 error
= FT_Err_Out_Of_Memory
;
961 /* we have either one-byte or two-byte elements */
962 x
= (FT_Byte
*)malloc(2 * outline
->n_points
);
965 error
= FT_Err_Out_Of_Memory
;
969 y
= (FT_Byte
*)malloc(2 * outline
->n_points
);
972 error
= FT_Err_Out_Of_Memory
;
979 xmin
= xmax
= (outline
->points
[0].x
+ 32) >> 6;
980 ymin
= ymax
= (outline
->points
[0].y
+ 32) >> 6;
983 oldf
= 0x80; /* start with an impossible value */
985 /* convert the FreeType representation of the glyph's outline */
986 /* into the representation format of the `glyf' table */
987 for (i
= 0; i
< outline
->n_points
; i
++)
989 FT_Pos xcur
= (outline
->points
[i
].x
+ 32) >> 6;
990 FT_Pos ycur
= (outline
->points
[i
].y
+ 32) >> 6;
992 FT_Pos xdelta
= xcur
- lastx
;
993 FT_Pos ydelta
= ycur
- lasty
;
996 /* we are only interested in bit 0 of the `tags' array */
997 f
= outline
->tags
[i
] & ON_CURVE
;
1005 if (xdelta
< 256 && xdelta
> -256)
1007 f
|= X_SHORT_VECTOR
;
1014 *(xp
++) = (FT_Byte
)xdelta
;
1018 *(xp
++) = HIGH(xdelta
);
1019 *(xp
++) = LOW(xdelta
);
1029 if (ydelta
< 256 && ydelta
> -256)
1031 f
|= Y_SHORT_VECTOR
;
1038 *(yp
++) = (FT_Byte
)ydelta
;
1042 *(yp
++) = HIGH(ydelta
);
1043 *(yp
++) = LOW(ydelta
);
1049 /* set repeat flag */
1050 *(flagsp
- 1) |= REPEAT
;
1054 /* we can only handle 256 repetitions at once, */
1055 /* so use a new counter */
1060 *flagsp
+= 1; /* increase repetition counter */
1065 flagsp
++; /* skip repetition counter */
1083 /* if the last byte was a repetition counter, */
1084 /* we must increase by one to get the correct array size */
1088 header
[0] = HIGH(outline
->n_contours
);
1089 header
[1] = LOW(outline
->n_contours
);
1090 header
[2] = HIGH(xmin
);
1091 header
[3] = LOW(xmin
);
1092 header
[4] = HIGH(ymin
);
1093 header
[5] = LOW(ymin
);
1094 header
[6] = HIGH(xmax
);
1095 header
[7] = LOW(xmax
);
1096 header
[8] = HIGH(ymax
);
1097 header
[9] = LOW(ymax
);
1099 /* concatenate all arrays and fill needed GLYPH structure elements */
1101 glyph
->len1
= 10 + 2 * outline
->n_contours
;
1102 glyph
->len2
= (flagsp
- flags
) + (xp
- x
) + (yp
- y
);
1104 glyph
->buf
= (FT_Byte
*)malloc(glyph
->len1
+ glyph
->len2
);
1107 error
= FT_Err_Out_Of_Memory
;
1112 memcpy(p
, header
, 10);
1115 glyph
->ins_extra_len
= 0;
1117 glyph
->ins_buf
= NULL
;
1119 for (i
= 0; i
< outline
->n_contours
; i
++)
1121 *(p
++) = HIGH(outline
->contours
[i
]);
1122 *(p
++) = LOW(outline
->contours
[i
]);
1125 memcpy(p
, flags
, flagsp
- flags
);
1126 p
+= flagsp
- flags
;
1127 memcpy(p
, x
, xp
- x
);
1129 memcpy(p
, y
, yp
- y
);
1140 /* We hint each glyph at EM size and construct a new `glyf' table. */
1141 /* Some fonts need this; in particular, */
1142 /* there are CJK fonts which use hints to scale and position subglyphs. */
1143 /* As a consequence, there are no longer composite glyphs. */
1146 TA_sfnt_create_glyf_data(SFNT
* sfnt
,
1149 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
1150 FT_Face face
= sfnt
->face
;
1158 /* in case of success, all allocated arrays are */
1159 /* linked and eventually freed in `TA_font_unload' */
1161 /* nothing to do if table has already been created */
1162 if (glyf_table
->data
)
1165 data
= (glyf_Data
*)calloc(1, sizeof (glyf_Data
));
1167 return FT_Err_Out_Of_Memory
;
1169 glyf_table
->data
= data
;
1171 data
->num_glyphs
= (FT_UShort
)face
->num_glyphs
;
1172 data
->glyphs
= (GLYPH
*)calloc(1, data
->num_glyphs
* sizeof (GLYPH
));
1174 return FT_Err_Out_Of_Memory
;
1176 /* XXX: Make size configurable */
1177 /* we use the EM size */
1178 /* so that the resulting coordinates can be used without transformation */
1179 error
= FT_Set_Char_Size(face
, face
->units_per_EM
* 64, 0, 72, 0);
1183 /* loop over all glyphs in font face */
1184 for (i
= 0; i
< data
->num_glyphs
; i
++)
1186 GLYPH
* glyph
= &data
->glyphs
[i
];
1189 error
= FT_Load_Glyph(face
, i
, FT_LOAD_NO_BITMAP
| FT_LOAD_NO_AUTOHINT
);
1193 error
= TA_create_glyph_data(&face
->glyph
->outline
, glyph
);
1203 * While the auto-hinter is glyph oriented (this is, using `glyf' data), it
1204 * relies on the `cmap' table and OpenType features to get style coverage
1205 * data. In TTCs, subfonts normally share the same `glyf' table but use
1206 * different `cmap's and OpenType features (in `GSUB' and `GPOS' tables).
1207 * To handle this gracefully, ttfautohint collects (and merges) the coverage
1208 * information in the `glyf_Data' structure.
1212 TA_sfnt_handle_coverage(SFNT
* sfnt
,
1217 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
1218 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
1220 FT_Face face
= sfnt
->face
;
1221 TA_FaceGlobals curr_globals
;
1223 TA_Style saved_fallback_style
= font
->fallback_style
;
1226 /* using TA_STYLE_UNASSIGNED as the fallback style ensures */
1227 /* that uncovered glyphs stay as-is */
1228 /* (we handle the fallback style later on) */
1229 font
->fallback_style
= (TA_Style
)TA_STYLE_UNASSIGNED
;
1231 /* trigger computation of coverage */
1232 error
= ta_loader_init(font
);
1235 error
= ta_loader_reset(font
, face
);
1238 ta_loader_done(font
);
1240 font
->fallback_style
= saved_fallback_style
;
1241 curr_globals
= (TA_FaceGlobals
)face
->autohint
.data
;
1243 if (!data
->master_globals
)
1246 data
->master_globals
= curr_globals
;
1250 /* we have the same `glyf' table for another subfont; */
1251 /* merge the current coverage info into the `master' coverage info */
1253 TA_FaceGlobals master_globals
= data
->master_globals
;
1254 FT_Long count
= master_globals
->glyph_count
;
1256 FT_Byte
* master
= master_globals
->glyph_styles
;
1257 FT_Byte
* curr
= curr_globals
->glyph_styles
;
1259 FT_Byte
* limit
= master
+ count
;
1262 /* we simply copy the data, */
1263 /* assuming that a given glyph always has the same properties -- */
1264 /* as soon as we make the style selection more fine-grained, */
1265 /* it is possible that this assumption doesn't hold: */
1266 /* for example, glyph `A' can be used for both Cyrillic and Latin */
1267 while (master
< limit
)
1269 if ((*curr
& ~TA_DIGIT
) != TA_STYLE_UNASSIGNED
)
1283 TA_sfnt_adjust_coverage(SFNT
* sfnt
,
1286 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
1287 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
1289 TA_FaceGlobals master_globals
= data
->master_globals
;
1292 /* use fallback style for uncovered glyphs */
1293 if (!data
->adjusted
)
1296 FT_Byte
* gstyles
= master_globals
->glyph_styles
;
1302 for (nn
= 0; nn
< master_globals
->glyph_count
; nn
++)
1304 if ((gstyles
[nn
] & ~TA_DIGIT
) == TA_STYLE_UNASSIGNED
)
1306 gstyles
[nn
] &= ~TA_STYLE_UNASSIGNED
;
1307 gstyles
[nn
] |= master_globals
->font
->fallback_style
;
1313 if (sfnt
->face
->num_faces
> 1)
1315 "using fallback style `%s' for unassigned glyphs"
1316 " (glyf table index %d):\n",
1317 ta_style_names
[master_globals
->font
->fallback_style
],
1321 "using fallback style `%s' for unassigned glyphs:\n",
1322 ta_style_names
[master_globals
->font
->fallback_style
]));
1326 for (nn
= 0; nn
< master_globals
->glyph_count
; nn
++)
1328 if ((gstyles
[nn
] & ~TA_DIGIT
) == master_globals
->font
->fallback_style
)
1331 TA_LOG_GLOBAL((" "));
1333 TA_LOG_GLOBAL((" %d", nn
));
1337 TA_LOG_GLOBAL(("\n"));
1342 TA_LOG_GLOBAL((" (none)\n"));
1344 TA_LOG_GLOBAL(("\n"));
1346 #endif /* TA_DEBUG */
1356 TA_sfnt_copy_master_coverage(SFNT
* sfnt
,
1359 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
1360 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
1362 FT_Face face
= sfnt
->face
;
1364 TA_FaceGlobals master_globals
= data
->master_globals
;
1365 TA_FaceGlobals curr_globals
= (TA_FaceGlobals
)face
->autohint
.data
;
1368 if (master_globals
!= curr_globals
)
1370 FT_Long count
= master_globals
->glyph_count
;
1371 FT_Byte
* master
= master_globals
->glyph_styles
;
1372 FT_Byte
* curr
= curr_globals
->glyph_styles
;
1375 memcpy(curr
, master
, count
);
1381 /* end of taglyf.c */