4 * Copyright (C) 2011-2022 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
* glyphs
,
126 FT_UShort num_glyphs
,
127 FT_Bool hint_composites
)
129 GLYPH
* glyph
= &glyphs
[idx
];
131 FT_ULong flags_offset
; /* after the loop, this is the offset */
132 /* to the last element in the flags array */
138 FT_UShort
* curr_component
;
139 FT_UShort curr_num_points
;
142 /* we allocate too large a buffer */
143 /* (including space for the new component */
144 /* and possible argument size changes for shifted point indices) */
145 /* and reallocate it later to its real size */
146 glyph
->buf
= (FT_Byte
*)malloc(len
+ 8 + glyph
->num_components
* 2);
148 return FT_Err_Out_Of_Memory
;
158 /* if the composite glyph contains one or more contours, */
159 /* we prepend a composite glyph component to call some bytecode */
160 /* which eventually becomes the last glyph in the `glyf' table; */
161 /* for convenience, however, it is not added to the `components' array */
162 /* (doing so simplifies the conversion of point indices later on) */
163 if (glyph
->num_composite_contours
&& hint_composites
)
173 /* the composite glyph's bounding box */
174 x_min
= (FT_Short
)((buf
[2] << 8) + buf
[3]);
175 y_min
= (FT_Short
)((buf
[4] << 8) + buf
[5]);
176 x_max
= (FT_Short
)((buf
[6] << 8) + buf
[7]);
177 y_max
= (FT_Short
)((buf
[8] << 8) + buf
[9]);
179 /* use ARGS_ARE_WORDS only if necessary; */
180 /* note that the offset value of the component doesn't matter */
181 /* as long as it stays within the bounding box */
182 if (x_min
<= 0 && x_max
>= 0)
189 if (y_min
<= 0 && y_max
>= 0)
196 if (x_offset
>= -128 && x_offset
<= 127
197 && y_offset
>= -128 && y_offset
<= 127)
200 *(q
++) = ARGS_ARE_XY_VALUES
| MORE_COMPONENTS
;
201 *(q
++) = HIGH(num_glyphs
- 1);
202 *(q
++) = LOW(num_glyphs
- 1);
203 *(q
++) = (FT_Byte
)x_offset
;
204 *(q
++) = (FT_Byte
)y_offset
;
209 *(q
++) = ARGS_ARE_WORDS
| ARGS_ARE_XY_VALUES
| MORE_COMPONENTS
;
210 *(q
++) = HIGH(num_glyphs
- 1);
211 *(q
++) = LOW(num_glyphs
- 1);
212 *(q
++) = HIGH(x_offset
);
213 *(q
++) = LOW(x_offset
);
214 *(q
++) = HIGH(y_offset
);
215 *(q
++) = LOW(y_offset
);
219 curr_component
= glyph
->components
;
222 /* walk over component records */
225 flags_offset
= (FT_ULong
)(q
- glyph
->buf
);
229 flags
= NEXT_USHORT(p
);
235 if (flags
& ARGS_ARE_XY_VALUES
)
241 if (flags
& ARGS_ARE_WORDS
)
249 /* handle point numbers */
257 if (flags
& ARGS_ARE_WORDS
)
270 curr_num_points
+= glyphs
[*curr_component
++].num_points
;
272 /* compute the point index of arg2 after adding the subglyph */
273 idx2
= curr_num_points
+ arg2
;
275 /* adjust point indices */
276 /* (see `TA_adjust_point_index' in `tabytecode.c' for more) */
277 for (i
= 0; i
< glyph
->num_pointsums
; i
++)
278 if (arg1
< glyph
->pointsums
[i
])
282 for (j
= 0; j
< glyph
->num_pointsums
; j
++)
283 if (idx2
< glyph
->pointsums
[j
])
287 if (arg1
<= 0xFF && arg2
<= 0xFF)
289 glyph
->buf
[flags_offset
+ 1] &= ~ARGS_ARE_WORDS
;
291 *(q
++) = (FT_Byte
)arg1
;
292 *(q
++) = (FT_Byte
)arg2
;
296 glyph
->buf
[flags_offset
+ 1] |= ARGS_ARE_WORDS
;
305 /* copy scaling arguments */
306 if (flags
& (WE_HAVE_A_SCALE
| WE_HAVE_AN_XY_SCALE
| WE_HAVE_A_2X2
))
311 if (flags
& (WE_HAVE_AN_XY_SCALE
| WE_HAVE_A_2X2
))
316 if (flags
& WE_HAVE_A_2X2
)
323 } while (flags
& MORE_COMPONENTS
);
325 glyph
->len1
= (FT_ULong
)(q
- glyph
->buf
);
326 /* glyph->len2 = 0; */
327 glyph
->flags_offset
= flags_offset
;
328 glyph
->buf
= (FT_Byte
*)realloc(glyph
->buf
, glyph
->len1
);
330 /* we discard instructions (if any) */
331 glyph
->buf
[glyph
->flags_offset
] &= ~(WE_HAVE_INSTR
>> 8);
338 TA_glyph_parse_simple(GLYPH
* glyph
,
344 FT_Byte
* flags_start
;
348 FT_ULong flags_size
; /* size of the flags array */
349 FT_ULong xy_size
; /* size of x and y coordinate arrays together */
360 ins_offset
= 10 + (FT_ULong
)glyph
->num_contours
* 2;
365 return FT_Err_Invalid_Table
;
367 /* get number of instructions */
368 num_ins
= NEXT_USHORT(p
);
370 /* assure that we don't process a font */
371 /* which already contains a `.ttfautohint' glyph */
372 /* (a font with a `post' table version 3.0 doesn't contain glyph names, */
373 /* so we have to check it this way) */
374 if (glyph
->num_points
== 1
375 && num_ins
>= sizeof (ttfautohint_glyph_bytecode
)
378 if (!strncmp((char*)p
, (char*)ttfautohint_glyph_bytecode
,
379 sizeof (ttfautohint_glyph_bytecode
)))
380 return TA_Err_Already_Processed
;
386 return FT_Err_Invalid_Table
;
392 while (i
< glyph
->num_points
)
403 return FT_Err_Invalid_Table
;
407 x_short
= (flags
& X_SHORT_VECTOR
) ? 1 : 2;
408 y_short
= (flags
& Y_SHORT_VECTOR
) ? 1 : 2;
410 have_x
= ((flags
& SAME_X
) && !(flags
& X_SHORT_VECTOR
)) ? 0 : 1;
411 have_y
= ((flags
& SAME_Y
) && !(flags
& Y_SHORT_VECTOR
)) ? 0 : 1;
418 return FT_Err_Invalid_Table
;
422 if (i
+ count
> glyph
->num_points
)
423 return FT_Err_Invalid_Table
;
426 xy_size
+= count
* x_short
* have_x
;
427 xy_size
+= count
* y_short
* have_y
;
432 if (p
+ xy_size
> endp
)
433 return FT_Err_Invalid_Table
;
435 flags_size
= (FT_ULong
)(p
- flags_start
);
437 /* store the data before and after the bytecode instructions */
438 /* in the same array */
439 glyph
->len1
= ins_offset
;
440 glyph
->len2
= flags_size
+ xy_size
;
441 glyph
->buf
= (FT_Byte
*)malloc(glyph
->len1
+ glyph
->len2
);
443 return FT_Err_Out_Of_Memory
;
445 /* now copy everything but the instructions */
446 memcpy(glyph
->buf
, buf
, glyph
->len1
);
447 memcpy(glyph
->buf
+ glyph
->len1
, flags_start
, glyph
->len2
);
454 TA_iterate_composite_glyph(glyf_Data
* data
,
455 FT_UShort
* components
,
456 FT_UShort num_components
,
457 FT_UShort
** pointsums
,
458 FT_UShort
* num_pointsums
,
459 FT_UShort
* num_composite_contours
,
460 FT_UShort
* num_composite_points
)
462 FT_UShort
* pointsums_new
;
466 /* save current state */
468 if (*num_pointsums
== 0xFFFF)
469 return FT_Err_Invalid_Table
;
472 pointsums_new
= (FT_UShort
*)realloc(*pointsums
,
474 * sizeof (FT_UShort
));
478 return FT_Err_Out_Of_Memory
;
481 *pointsums
= pointsums_new
;
483 (*pointsums
)[*num_pointsums
- 1] = *num_composite_points
;
485 for (i
= 0; i
< num_components
; i
++)
488 FT_UShort component
= components
[i
];
492 if (component
>= data
->num_glyphs
)
493 return FT_Err_Invalid_Table
;
495 glyph
= &data
->glyphs
[component
];
497 if (glyph
->num_components
)
499 error
= TA_iterate_composite_glyph(data
,
501 glyph
->num_components
,
504 num_composite_contours
,
505 num_composite_points
);
511 /* no need for checking overflow of the number of contours */
512 /* since the number of points is always larger or equal */
513 if (*num_composite_points
> 0xFFFF - glyph
->num_points
)
514 return FT_Err_Invalid_Table
;
516 *num_composite_contours
+= glyph
->num_contours
;
517 *num_composite_points
+= glyph
->num_points
;
526 TA_sfnt_compute_composite_pointsums(SFNT
* sfnt
,
529 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
530 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
535 for (i
= 0; i
< data
->num_glyphs
; i
++)
537 GLYPH
* glyph
= &data
->glyphs
[i
];
540 if (glyph
->num_components
)
543 FT_UShort num_composite_contours
= 0;
544 FT_UShort num_composite_points
= 0;
547 error
= TA_iterate_composite_glyph(data
,
549 glyph
->num_components
,
551 &glyph
->num_pointsums
,
552 &num_composite_contours
,
553 &num_composite_points
);
557 glyph
->num_composite_contours
= num_composite_contours
;
558 /* we set the number of points (after expanding all subglyphs) */
559 /* for composite glyphs also */
560 glyph
->num_points
= num_composite_points
;
562 if (font
->hint_composites
)
564 /* update maximum values, */
565 /* including the subglyphs not in `components' array */
566 /* (each of them has a single point in a single contour) */
567 if (num_composite_points
+ glyph
->num_pointsums
568 > sfnt
->max_composite_points
)
569 sfnt
->max_composite_points
= num_composite_points
570 + glyph
->num_pointsums
;
571 if (num_composite_contours
+ glyph
->num_pointsums
572 > sfnt
->max_composite_contours
)
573 sfnt
->max_composite_contours
= num_composite_contours
574 + glyph
->num_pointsums
;
584 TA_sfnt_split_glyf_table(SFNT
* sfnt
,
587 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
588 SFNT_Table
* loca_table
= &font
->tables
[sfnt
->loca_idx
];
589 SFNT_Table
* head_table
= &font
->tables
[sfnt
->head_idx
];
595 FT_ULong offset_next
;
599 FT_UShort loop_count
;
604 /* in case of success, all allocated arrays are */
605 /* linked and eventually freed in `TA_font_unload' */
607 /* nothing to do if table has already been split */
608 if (glyf_table
->data
)
611 data
= (glyf_Data
*)calloc(1, sizeof (glyf_Data
));
613 return FT_Err_Out_Of_Memory
;
615 glyf_table
->data
= data
;
617 loca_format
= head_table
->buf
[LOCA_FORMAT_OFFSET
];
619 data
->num_glyphs
= (FT_UShort
)(loca_format
? loca_table
->len
/ 4
620 : loca_table
->len
/ 2);
621 loop_count
= data
->num_glyphs
- 1;
623 /* allocate one more glyph slot if we have composite glyphs */
624 if (!sfnt
->max_components
|| !font
->hint_composites
)
625 data
->num_glyphs
-= 1;
626 data
->glyphs
= (GLYPH
*)calloc(1, data
->num_glyphs
* sizeof (GLYPH
));
628 return FT_Err_Out_Of_Memory
;
630 data
->master_globals
= NULL
;
631 data
->cvt_idx
= MISSING
;
632 data
->fpgm_idx
= MISSING
;
633 data
->prep_idx
= MISSING
;
635 /* first loop over `loca' and `glyf' data */
640 offset_next
= NEXT_ULONG(p
);
643 offset_next
= NEXT_USHORT(p
);
647 for (i
= 0; i
< loop_count
; i
++)
649 GLYPH
* glyph
= &data
->glyphs
[i
];
653 offset
= offset_next
;
656 offset_next
= NEXT_ULONG(p
);
659 offset_next
= NEXT_USHORT(p
);
663 if (offset_next
< offset
664 || offset_next
> glyf_table
->len
)
665 return FT_Err_Invalid_Table
;
667 len
= offset_next
- offset
;
669 continue; /* empty glyph */
675 /* check header size */
677 return FT_Err_Invalid_Table
;
679 /* we need the number of contours and points for */
680 /* `TA_sfnt_compute_composite_pointsums' */
681 buf
= glyf_table
->buf
+ offset
;
682 glyph
->num_contours
= (FT_Short
)((buf
[0] << 8) + buf
[1]);
684 if (glyph
->num_contours
< 0)
686 error
= TA_glyph_get_components(glyph
, buf
, len
);
695 /* use the last contour's end point to compute number of points */
696 off
= 10 + ((FT_ULong
)glyph
->num_contours
- 1) * 2;
698 return FT_Err_Invalid_Table
;
700 glyph
->num_points
= (FT_UShort
)((buf
[off
] << 8) + buf
[off
+ 1] + 1);
705 /* second loop over `loca' and `glyf' data */
710 offset_next
= NEXT_ULONG(p
);
713 offset_next
= NEXT_USHORT(p
);
717 for (i
= 0; i
< loop_count
; i
++)
719 GLYPH
* glyph
= &data
->glyphs
[i
];
723 offset
= offset_next
;
726 offset_next
= NEXT_ULONG(p
);
729 offset_next
= NEXT_USHORT(p
);
733 len
= offset_next
- offset
;
735 continue; /* empty glyph */
741 buf
= glyf_table
->buf
+ offset
;
743 /* We must parse the rest of the glyph record to get the exact */
744 /* record length. Since the `loca' table rounds record lengths */
745 /* up to multiples of 4 (or 2 for older fonts), and we must round */
746 /* up again after stripping off the instructions, it would be */
747 /* possible otherwise to have more than 4 bytes of padding which */
748 /* is more or less invalid. */
750 if (glyph
->num_contours
< 0)
751 error
= TA_glyph_parse_composite(data
->glyphs
, i
, buf
, len
,
753 font
->hint_composites
);
755 error
= TA_glyph_parse_simple(glyph
, buf
, len
, font
->dehint
);
761 if (sfnt
->max_components
&& font
->hint_composites
)
763 /* construct and append our special glyph used as a composite element */
764 GLYPH
* glyph
= &data
->glyphs
[data
->num_glyphs
- 1];
769 glyph
->buf
= (FT_Byte
*)malloc(glyph
->len1
+ glyph
->len2
);
771 return FT_Err_Out_Of_Memory
;
775 buf
[0] = 0x00; /* one contour */
777 buf
[2] = 0x00; /* no dimensions */
785 buf
[10] = 0x00; /* one contour end point */
788 buf
[12] = ON_CURVE
| SAME_X
| SAME_Y
; /* the flags for a point at 0,0 */
790 /* add bytecode also; */
791 /* this works because the loop in `TA_sfnt_build_glyf_hints' */
792 /* doesn't include the newly appended glyph */
793 glyph
->ins_len
= sizeof (ttfautohint_glyph_bytecode
);
794 glyph
->ins_buf
= (FT_Byte
*)malloc(glyph
->ins_len
);
796 return FT_Err_Out_Of_Memory
;
797 memcpy(glyph
->ins_buf
, ttfautohint_glyph_bytecode
, glyph
->ins_len
);
799 sfnt
->max_components
+= 1;
807 TA_sfnt_build_glyf_table(SFNT
* sfnt
,
812 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
813 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
823 if (glyf_table
->processed
)
828 error
= TA_sfnt_build_glyf_hints(sfnt
, font
);
835 glyph
= data
->glyphs
;
836 for (i
= 0; i
< data
->num_glyphs
; i
++, glyph
++)
838 /* glyph records should have offsets which are multiples of 4 */
839 len
= (len
+ 3) & ~3U;
840 len
+= glyph
->len1
+ glyph
->len2
841 + glyph
->ins_extra_len
+ glyph
->ins_len
;
842 /* add two bytes for the instructionLength field */
843 if (glyph
->len2
|| glyph
->ins_len
)
847 /* to make the short format of the `loca' table always work, */
848 /* assure an even length of the `glyf' table */
849 glyf_table
->len
= (len
+ 1) & ~1U;
851 buf_new
= (FT_Byte
*)realloc(glyf_table
->buf
, (len
+ 3) & ~3U);
853 return FT_Err_Out_Of_Memory
;
855 glyf_table
->buf
= buf_new
;
858 glyph
= data
->glyphs
;
859 for (i
= 0; i
< data
->num_glyphs
; i
++, glyph
++)
861 len
= glyph
->len1
+ glyph
->len2
862 + glyph
->ins_extra_len
+ glyph
->ins_len
;
863 if (glyph
->len2
|| glyph
->ins_len
)
868 /* copy glyph data and insert new instructions */
869 memcpy(p
, glyph
->buf
, glyph
->len1
);
875 *(p
++) = HIGH(glyph
->ins_extra_len
+ glyph
->ins_len
);
876 *(p
++) = LOW(glyph
->ins_extra_len
+ glyph
->ins_len
);
877 if (glyph
->ins_extra_len
)
879 memcpy(p
, glyph
->ins_extra_buf
, glyph
->ins_extra_len
);
880 p
+= glyph
->ins_extra_len
;
884 memcpy(p
, glyph
->ins_buf
, glyph
->ins_len
);
887 memcpy(p
, glyph
->buf
+ glyph
->len1
, glyph
->len2
);
892 /* composite glyph */
895 *(p
+ glyph
->flags_offset
) |= (WE_HAVE_INSTR
>> 8);
897 *(p
++) = HIGH(glyph
->ins_extra_len
+ glyph
->ins_len
);
898 *(p
++) = LOW(glyph
->ins_extra_len
+ glyph
->ins_len
);
899 if (glyph
->ins_extra_len
)
901 memcpy(p
, glyph
->ins_extra_buf
, glyph
->ins_extra_len
);
902 p
+= glyph
->ins_extra_len
;
904 memcpy(p
, glyph
->ins_buf
, glyph
->ins_len
);
911 /* pad with zero bytes to have an offset which is a multiple of 4; */
912 /* this works even for the last glyph record since the `glyf' */
913 /* table length is a multiple of 4 also */
931 glyf_table
->checksum
= TA_table_compute_checksum(glyf_table
->buf
,
933 glyf_table
->processed
= 1;
940 TA_create_glyph_data(FT_Outline
* outline
,
943 FT_Error error
= TA_Err_Ok
;
949 FT_Byte
* flags
= NULL
;
963 if (!outline
->n_contours
)
964 return TA_Err_Ok
; /* empty glyph */
966 /* in case of success, all non-local allocated arrays are */
967 /* linked and eventually freed in `TA_font_unload' */
971 /* we use `calloc' since we rely on the array */
972 /* being initialized to zero; */
973 /* additionally, we need one more byte for a test after the loop */
974 flags
= (FT_Byte
*)calloc(1, (size_t)outline
->n_points
+ 1);
977 error
= FT_Err_Out_Of_Memory
;
981 /* we have either one-byte or two-byte elements */
982 x
= (FT_Byte
*)malloc(2 * (size_t)outline
->n_points
);
985 error
= FT_Err_Out_Of_Memory
;
989 y
= (FT_Byte
*)malloc(2 * (size_t)outline
->n_points
);
992 error
= FT_Err_Out_Of_Memory
;
999 xmin
= xmax
= (outline
->points
[0].x
+ 32) >> 6;
1000 ymin
= ymax
= (outline
->points
[0].y
+ 32) >> 6;
1003 oldf
= 0x80; /* start with an impossible value */
1005 /* convert the FreeType representation of the glyph's outline */
1006 /* into the representation format of the `glyf' table */
1007 for (i
= 0; i
< outline
->n_points
; i
++)
1009 FT_Pos xcur
= (outline
->points
[i
].x
+ 32) >> 6;
1010 FT_Pos ycur
= (outline
->points
[i
].y
+ 32) >> 6;
1012 FT_Pos xdelta
= xcur
- lastx
;
1013 FT_Pos ydelta
= ycur
- lasty
;
1016 /* we are only interested in bit 0 of the `tags' array */
1017 f
= outline
->tags
[i
] & ON_CURVE
;
1025 if (xdelta
< 256 && xdelta
> -256)
1027 f
|= X_SHORT_VECTOR
;
1034 *(xp
++) = (FT_Byte
)xdelta
;
1038 *(xp
++) = HIGH(xdelta
);
1039 *(xp
++) = LOW(xdelta
);
1049 if (ydelta
< 256 && ydelta
> -256)
1051 f
|= Y_SHORT_VECTOR
;
1058 *(yp
++) = (FT_Byte
)ydelta
;
1062 *(yp
++) = HIGH(ydelta
);
1063 *(yp
++) = LOW(ydelta
);
1069 /* set repeat flag */
1070 *(flagsp
- 1) |= REPEAT
;
1074 /* we can only handle 256 repetitions at once, */
1075 /* so use a new counter */
1080 *flagsp
+= 1; /* increase repetition counter */
1085 flagsp
++; /* skip repetition counter */
1103 /* if the last byte was a repetition counter, */
1104 /* we must increase by one to get the correct array size */
1108 header
[0] = HIGH(outline
->n_contours
);
1109 header
[1] = LOW(outline
->n_contours
);
1110 header
[2] = HIGH(xmin
);
1111 header
[3] = LOW(xmin
);
1112 header
[4] = HIGH(ymin
);
1113 header
[5] = LOW(ymin
);
1114 header
[6] = HIGH(xmax
);
1115 header
[7] = LOW(xmax
);
1116 header
[8] = HIGH(ymax
);
1117 header
[9] = LOW(ymax
);
1119 /* concatenate all arrays and fill needed GLYPH structure elements */
1121 glyph
->len1
= (FT_ULong
)(10 + 2 * outline
->n_contours
);
1122 glyph
->len2
= (FT_ULong
)((flagsp
- flags
) + (xp
- x
) + (yp
- y
));
1124 glyph
->buf
= (FT_Byte
*)malloc(glyph
->len1
+ glyph
->len2
);
1127 error
= FT_Err_Out_Of_Memory
;
1132 memcpy(p
, header
, 10);
1135 glyph
->ins_extra_len
= 0;
1136 glyph
->ins_extra_buf
= NULL
;
1138 glyph
->ins_buf
= NULL
;
1140 for (i
= 0; i
< outline
->n_contours
; i
++)
1142 *(p
++) = HIGH(outline
->contours
[i
]);
1143 *(p
++) = LOW(outline
->contours
[i
]);
1146 memcpy(p
, flags
, (size_t)(flagsp
- flags
));
1147 p
+= flagsp
- flags
;
1148 memcpy(p
, x
, (size_t)(xp
- x
));
1150 memcpy(p
, y
, (size_t)(yp
- y
));
1161 /* We hint each glyph at EM size and construct a new `glyf' table. */
1162 /* Some fonts need this; in particular, */
1163 /* there are CJK fonts which use hints to scale and position subglyphs. */
1164 /* As a consequence, there are no longer composite glyphs. */
1167 TA_sfnt_create_glyf_data(SFNT
* sfnt
,
1170 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
1171 FT_Face face
= sfnt
->face
;
1179 /* in case of success, all allocated arrays are */
1180 /* linked and eventually freed in `TA_font_unload' */
1182 /* nothing to do if table has already been created */
1183 if (glyf_table
->data
)
1186 data
= (glyf_Data
*)calloc(1, sizeof (glyf_Data
));
1188 return FT_Err_Out_Of_Memory
;
1190 glyf_table
->data
= data
;
1192 data
->num_glyphs
= (FT_UShort
)face
->num_glyphs
;
1193 data
->glyphs
= (GLYPH
*)calloc(1, data
->num_glyphs
* sizeof (GLYPH
));
1195 return FT_Err_Out_Of_Memory
;
1197 /* XXX: Make size configurable */
1198 /* we use the EM size */
1199 /* so that the resulting coordinates can be used without transformation */
1200 error
= FT_Set_Char_Size(face
, face
->units_per_EM
* 64, 0, 72, 0);
1204 /* loop over all glyphs in font face */
1205 for (i
= 0; i
< data
->num_glyphs
; i
++)
1207 GLYPH
* glyph
= &data
->glyphs
[i
];
1210 error
= FT_Load_Glyph(face
, i
, FT_LOAD_NO_BITMAP
| FT_LOAD_NO_AUTOHINT
);
1214 error
= TA_create_glyph_data(&face
->glyph
->outline
, glyph
);
1224 * While the auto-hinter is glyph oriented (this is, using `glyf' data), it
1225 * relies on the `cmap' table and OpenType features to get style coverage
1226 * data. In TTCs, subfonts normally share the same `glyf' table but use
1227 * different `cmap's and OpenType features (in `GSUB' and `GPOS' tables).
1228 * To handle this gracefully, ttfautohint collects (and merges) the coverage
1229 * information in the `glyf_Data' structure.
1233 TA_sfnt_handle_coverage(SFNT
* sfnt
,
1238 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
1239 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
1241 FT_Face face
= sfnt
->face
;
1242 TA_FaceGlobals curr_globals
;
1244 TA_Style saved_fallback_style
= font
->fallback_style
;
1247 /* using TA_STYLE_UNASSIGNED as the fallback style ensures */
1248 /* that uncovered glyphs stay as-is */
1249 /* (we handle the fallback style later on) */
1250 font
->fallback_style
= (TA_Style
)TA_STYLE_UNASSIGNED
;
1252 /* trigger computation of coverage */
1253 error
= ta_loader_init(font
);
1256 error
= ta_loader_reset(font
, face
);
1259 ta_loader_done(font
);
1261 font
->fallback_style
= saved_fallback_style
;
1262 curr_globals
= (TA_FaceGlobals
)face
->autohint
.data
;
1264 if (!data
->master_globals
)
1267 data
->master_globals
= curr_globals
;
1271 /* we have the same `glyf' table for another subfont; */
1272 /* merge the current coverage info into the `master' coverage info */
1274 TA_FaceGlobals master_globals
= data
->master_globals
;
1275 FT_Long count
= master_globals
->glyph_count
;
1277 FT_UShort
* master
= master_globals
->glyph_styles
;
1278 FT_UShort
* curr
= curr_globals
->glyph_styles
;
1280 FT_UShort
* limit
= master
+ count
;
1283 /* we simply copy the data, */
1284 /* assuming that a given glyph always has the same properties -- */
1285 /* as soon as we make the style selection more fine-grained, */
1286 /* it is possible that this assumption doesn't hold: */
1287 /* for example, glyph `A' can be used for both Cyrillic and Latin */
1288 while (master
< limit
)
1290 if ((*curr
& TA_STYLE_MASK
) != TA_STYLE_UNASSIGNED
)
1304 TA_sfnt_adjust_coverage(SFNT
* sfnt
,
1307 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
1308 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
1310 TA_FaceGlobals master_globals
= data
->master_globals
;
1313 /* use fallback style for uncovered glyphs */
1314 if (!data
->adjusted
)
1317 FT_UShort
* gstyles
= master_globals
->glyph_styles
;
1322 if (sfnt
->face
->num_faces
> 1)
1324 "using fallback style `%s' for unassigned glyphs"
1325 " (glyf table index %d):\n",
1326 ta_style_names
[master_globals
->font
->fallback_style
],
1330 "using fallback style `%s' for unassigned glyphs:\n",
1331 ta_style_names
[master_globals
->font
->fallback_style
]));
1335 for (nn
= 0; nn
< master_globals
->glyph_count
; nn
++)
1337 if ((gstyles
[nn
] & TA_STYLE_MASK
) == TA_STYLE_UNASSIGNED
)
1340 TA_LOG_GLOBAL((" "));
1342 TA_LOG_GLOBAL((" %d", nn
));
1346 TA_LOG_GLOBAL(("\n"));
1351 TA_LOG_GLOBAL((" (none)\n"));
1353 TA_LOG_GLOBAL(("\n"));
1355 #endif /* TA_DEBUG */
1357 for (nn
= 0; nn
< master_globals
->glyph_count
; nn
++)
1359 if ((gstyles
[nn
] & TA_STYLE_MASK
) == TA_STYLE_UNASSIGNED
)
1361 gstyles
[nn
] &= ~TA_STYLE_MASK
;
1362 gstyles
[nn
] |= master_globals
->font
->fallback_style
;
1374 TA_sfnt_copy_master_coverage(SFNT
* sfnt
,
1377 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
1378 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
1380 FT_Face face
= sfnt
->face
;
1382 TA_FaceGlobals master_globals
= data
->master_globals
;
1383 TA_FaceGlobals curr_globals
= (TA_FaceGlobals
)face
->autohint
.data
;
1386 if (master_globals
!= curr_globals
)
1388 FT_Long count
= master_globals
->glyph_count
;
1389 FT_UShort
* master
= master_globals
->glyph_styles
;
1390 FT_UShort
* curr
= curr_globals
->glyph_styles
;
1393 memcpy(curr
, master
, count
* sizeof (FT_UShort
));
1399 /* end of taglyf.c */