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
;
87 /* add component to list */
88 component
= *(p
++) << 8;
91 glyph
->num_components
++;
92 components_new
= (FT_UShort
*)realloc(glyph
->components
,
94 * sizeof (FT_UShort
));
97 glyph
->num_components
--;
98 return FT_Err_Out_Of_Memory
;
101 glyph
->components
= components_new
;
103 glyph
->components
[glyph
->num_components
- 1] = component
;
105 /* skip scaling and offset arguments */
106 if (flags
& ARGS_ARE_WORDS
)
111 if (flags
& WE_HAVE_A_SCALE
)
113 else if (flags
& WE_HAVE_AN_XY_SCALE
)
115 else if (flags
& WE_HAVE_A_2X2
)
117 } while (flags
& MORE_COMPONENTS
);
124 TA_glyph_parse_composite(GLYPH
* glyph
,
127 FT_UShort num_glyphs
,
128 FT_Bool hint_composites
)
130 FT_ULong flags_offset
; /* after the loop, this is the offset */
131 /* to the last element in the flags array */
138 /* we allocate too large a buffer */
139 /* (including space for the new component */
140 /* and possible argument size changes for shifted point indices) */
141 /* and reallocate it later to its real size */
142 glyph
->buf
= (FT_Byte
*)malloc(len
+ 8 + glyph
->num_components
* 2);
144 return FT_Err_Out_Of_Memory
;
154 /* if the composite glyph contains one or more contours, */
155 /* we prepend a composite glyph component to call some bytecode */
156 /* which eventually becomes the last glyph in the `glyf' table; */
157 /* for convenience, however, it is not added to the `components' array */
158 /* (doing so simplifies the conversion of point indices later on) */
159 if (glyph
->num_composite_contours
&& hint_composites
)
169 /* the composite glyph's bounding box */
170 x_min
= (FT_Short
)((buf
[2] << 8) + buf
[3]);
171 y_min
= (FT_Short
)((buf
[4] << 8) + buf
[5]);
172 x_max
= (FT_Short
)((buf
[6] << 8) + buf
[7]);
173 y_max
= (FT_Short
)((buf
[8] << 8) + buf
[9]);
175 /* use ARGS_ARE_WORDS only if necessary; */
176 /* note that the offset value of the component doesn't matter */
177 /* as long as it stays within the bounding box */
178 if (x_min
<= 0 && x_max
>= 0)
185 if (y_min
<= 0 && y_max
>= 0)
192 if (x_offset
>= -128 && x_offset
<= 127
193 && y_offset
>= -128 && y_offset
<= 127)
196 *(q
++) = ARGS_ARE_XY_VALUES
| MORE_COMPONENTS
;
197 *(q
++) = HIGH(num_glyphs
- 1);
198 *(q
++) = LOW(num_glyphs
- 1);
205 *(q
++) = ARGS_ARE_WORDS
| ARGS_ARE_XY_VALUES
| MORE_COMPONENTS
;
206 *(q
++) = HIGH(num_glyphs
- 1);
207 *(q
++) = LOW(num_glyphs
- 1);
208 *(q
++) = HIGH(x_offset
);
209 *(q
++) = LOW(x_offset
);
210 *(q
++) = HIGH(y_offset
);
211 *(q
++) = LOW(y_offset
);
215 /* walk over component records */
218 flags_offset
= q
- glyph
->buf
;
229 if (flags
& ARGS_ARE_XY_VALUES
)
235 if (flags
& ARGS_ARE_WORDS
)
243 /* handle point numbers */
249 if (flags
& ARGS_ARE_WORDS
)
262 /* adjust point numbers */
263 /* (see `TA_adjust_point_index' in `tabytecode.c' for more) */
264 for (i
= 0; i
< glyph
->num_pointsums
; i
++)
265 if (arg1
< glyph
->pointsums
[i
])
269 for (i
= 0; i
< glyph
->num_pointsums
; i
++)
270 if (arg2
< glyph
->pointsums
[i
])
274 if (arg1
<= 0xFF && arg2
<= 0xFF)
276 glyph
->buf
[flags_offset
+ 1] &= ~ARGS_ARE_WORDS
;
283 glyph
->buf
[flags_offset
+ 1] |= ARGS_ARE_WORDS
;
292 /* copy scaling arguments */
293 if (flags
& (WE_HAVE_A_SCALE
| WE_HAVE_AN_XY_SCALE
| WE_HAVE_A_2X2
))
298 if (flags
& (WE_HAVE_AN_XY_SCALE
| WE_HAVE_A_2X2
))
303 if (flags
& WE_HAVE_A_2X2
)
310 } while (flags
& MORE_COMPONENTS
);
312 glyph
->len1
= q
- glyph
->buf
;
313 /* glyph->len2 = 0; */
314 glyph
->flags_offset
= flags_offset
;
315 glyph
->buf
= (FT_Byte
*)realloc(glyph
->buf
, glyph
->len1
);
317 /* we discard instructions (if any) */
318 glyph
->buf
[glyph
->flags_offset
] &= ~(WE_HAVE_INSTR
>> 8);
325 TA_glyph_parse_simple(GLYPH
* glyph
,
330 FT_Byte
* flags_start
;
334 FT_ULong flags_size
; /* size of the flags array */
335 FT_ULong xy_size
; /* size of x and y coordinate arrays together */
346 ins_offset
= 10 + glyph
->num_contours
* 2;
351 return FT_Err_Invalid_Table
;
353 /* get number of instructions */
354 num_ins
= *(p
++) << 8;
357 /* assure that we don't process a font */
358 /* which already contains a `.ttfautohint' glyph */
359 /* (a font with a `post' table version 3.0 doesn't contain glyph names, */
360 /* so we have to check it this way) */
361 if (glyph
->num_points
== 1
362 && num_ins
>= sizeof (ttfautohint_glyph_bytecode
))
364 if (!strncmp((char*)p
, (char*)ttfautohint_glyph_bytecode
,
365 sizeof (ttfautohint_glyph_bytecode
)))
366 return TA_Err_Already_Processed
;
372 return FT_Err_Invalid_Table
;
378 while (i
< glyph
->num_points
)
389 return FT_Err_Invalid_Table
;
393 x_short
= (flags
& X_SHORT_VECTOR
) ? 1 : 2;
394 y_short
= (flags
& Y_SHORT_VECTOR
) ? 1 : 2;
396 have_x
= ((flags
& SAME_X
) && !(flags
& X_SHORT_VECTOR
)) ? 0 : 1;
397 have_y
= ((flags
& SAME_Y
) && !(flags
& Y_SHORT_VECTOR
)) ? 0 : 1;
404 return FT_Err_Invalid_Table
;
408 if (i
+ count
> glyph
->num_points
)
409 return FT_Err_Invalid_Table
;
412 xy_size
+= count
* x_short
* have_x
;
413 xy_size
+= count
* y_short
* have_y
;
418 if (p
+ xy_size
> endp
)
419 return FT_Err_Invalid_Table
;
421 flags_size
= p
- flags_start
;
423 /* store the data before and after the bytecode instructions */
424 /* in the same array */
425 glyph
->len1
= ins_offset
;
426 glyph
->len2
= flags_size
+ xy_size
;
427 glyph
->buf
= (FT_Byte
*)malloc(glyph
->len1
+ glyph
->len2
);
429 return FT_Err_Out_Of_Memory
;
431 /* now copy everything but the instructions */
432 memcpy(glyph
->buf
, buf
, glyph
->len1
);
433 memcpy(glyph
->buf
+ glyph
->len1
, flags_start
, glyph
->len2
);
440 TA_iterate_composite_glyph(glyf_Data
* data
,
441 FT_UShort
* components
,
442 FT_UShort num_components
,
443 FT_UShort
** pointsums
,
444 FT_UShort
* num_pointsums
,
445 FT_UShort
* num_composite_contours
,
446 FT_UShort
* num_composite_points
)
448 FT_UShort
* pointsums_new
;
452 /* save current state */
454 if (*num_pointsums
== 0xFFFF)
455 return FT_Err_Invalid_Table
;
458 pointsums_new
= (FT_UShort
*)realloc(*pointsums
,
460 * sizeof (FT_UShort
));
464 return FT_Err_Out_Of_Memory
;
467 *pointsums
= pointsums_new
;
469 (*pointsums
)[*num_pointsums
- 1] = *num_composite_points
;
471 for (i
= 0; i
< num_components
; i
++)
474 FT_UShort component
= components
[i
];
478 if (component
>= data
->num_glyphs
)
479 return FT_Err_Invalid_Table
;
481 glyph
= &data
->glyphs
[component
];
483 if (glyph
->num_components
)
485 error
= TA_iterate_composite_glyph(data
,
487 glyph
->num_components
,
490 num_composite_contours
,
491 num_composite_points
);
497 /* no need for checking overflow of the number of contours */
498 /* since the number of points is always larger or equal */
499 if (*num_composite_points
> 0xFFFF - glyph
->num_points
)
500 return FT_Err_Invalid_Table
;
502 *num_composite_contours
+= glyph
->num_contours
;
503 *num_composite_points
+= glyph
->num_points
;
512 TA_sfnt_compute_composite_pointsums(SFNT
* sfnt
,
515 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
516 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
521 for (i
= 0; i
< data
->num_glyphs
; i
++)
523 GLYPH
* glyph
= &data
->glyphs
[i
];
526 if (glyph
->num_components
)
529 FT_UShort num_composite_contours
= 0;
530 FT_UShort num_composite_points
= 0;
533 error
= TA_iterate_composite_glyph(data
,
535 glyph
->num_components
,
537 &glyph
->num_pointsums
,
538 &num_composite_contours
,
539 &num_composite_points
);
543 glyph
->num_composite_contours
= num_composite_contours
;
545 if (font
->hint_composites
)
547 /* update maximum values, */
548 /* including the subglyphs not in `components' array */
549 /* (each of them has a single point in a single contour) */
550 if (num_composite_points
+ glyph
->num_pointsums
551 > sfnt
->max_composite_points
)
552 sfnt
->max_composite_points
= num_composite_points
553 + glyph
->num_pointsums
;
554 if (num_composite_contours
+ glyph
->num_pointsums
555 > sfnt
->max_composite_contours
)
556 sfnt
->max_composite_contours
= num_composite_contours
557 + glyph
->num_pointsums
;
567 TA_sfnt_split_glyf_table(SFNT
* sfnt
,
570 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
571 SFNT_Table
* loca_table
= &font
->tables
[sfnt
->loca_idx
];
572 SFNT_Table
* head_table
= &font
->tables
[sfnt
->head_idx
];
578 FT_ULong offset_next
;
582 FT_UShort loop_count
;
587 /* in case of success, all allocated arrays are */
588 /* linked and eventually freed in `TA_font_unload' */
590 /* nothing to do if table has already been split */
591 if (glyf_table
->data
)
594 data
= (glyf_Data
*)calloc(1, sizeof (glyf_Data
));
596 return FT_Err_Out_Of_Memory
;
598 glyf_table
->data
= data
;
600 loca_format
= head_table
->buf
[LOCA_FORMAT_OFFSET
];
602 data
->num_glyphs
= loca_format
? loca_table
->len
/ 4
603 : loca_table
->len
/ 2;
604 loop_count
= data
->num_glyphs
- 1;
606 /* allocate one more glyph slot if we have composite glyphs */
607 if (!sfnt
->max_components
|| !font
->hint_composites
)
608 data
->num_glyphs
-= 1;
609 data
->glyphs
= (GLYPH
*)calloc(1, data
->num_glyphs
* sizeof (GLYPH
));
611 return FT_Err_Out_Of_Memory
;
613 data
->master_globals
= NULL
;
614 data
->cvt_idx
= MISSING
;
615 data
->fpgm_idx
= MISSING
;
616 data
->prep_idx
= MISSING
;
618 /* first loop over `loca' and `glyf' data */
624 offset_next
= *(p
++) << 24;
625 offset_next
+= *(p
++) << 16;
626 offset_next
+= *(p
++) << 8;
627 offset_next
+= *(p
++);
631 offset_next
= *(p
++) << 8;
632 offset_next
+= *(p
++);
636 for (i
= 0; i
< loop_count
; i
++)
638 GLYPH
* glyph
= &data
->glyphs
[i
];
642 offset
= offset_next
;
646 offset_next
= *(p
++) << 24;
647 offset_next
+= *(p
++) << 16;
648 offset_next
+= *(p
++) << 8;
649 offset_next
+= *(p
++);
653 offset_next
= *(p
++) << 8;
654 offset_next
+= *(p
++);
658 if (offset_next
< offset
659 || offset_next
> glyf_table
->len
)
660 return FT_Err_Invalid_Table
;
662 len
= offset_next
- offset
;
664 continue; /* empty glyph */
670 /* check header size */
672 return FT_Err_Invalid_Table
;
674 /* we need the number of contours and points for */
675 /* `TA_sfnt_compute_composite_pointsums' */
676 buf
= glyf_table
->buf
+ offset
;
677 glyph
->num_contours
= (FT_Short
)((buf
[0] << 8) + buf
[1]);
679 if (glyph
->num_contours
< 0)
681 error
= TA_glyph_get_components(glyph
, buf
, len
);
690 /* use the last contour's end point to compute number of points */
691 off
= 10 + (glyph
->num_contours
- 1) * 2;
693 return FT_Err_Invalid_Table
;
695 glyph
->num_points
= buf
[off
] << 8;
696 glyph
->num_points
+= buf
[off
+ 1] + 1;
701 if (sfnt
->max_components
&& font
->hint_composites
)
703 error
= TA_sfnt_compute_composite_pointsums(sfnt
, font
);
708 /* second loop over `loca' and `glyf' data */
714 offset_next
= *(p
++) << 24;
715 offset_next
+= *(p
++) << 16;
716 offset_next
+= *(p
++) << 8;
717 offset_next
+= *(p
++);
721 offset_next
= *(p
++) << 8;
722 offset_next
+= *(p
++);
726 for (i
= 0; i
< loop_count
; i
++)
728 GLYPH
* glyph
= &data
->glyphs
[i
];
732 offset
= offset_next
;
736 offset_next
= *(p
++) << 24;
737 offset_next
+= *(p
++) << 16;
738 offset_next
+= *(p
++) << 8;
739 offset_next
+= *(p
++);
743 offset_next
= *(p
++) << 8;
744 offset_next
+= *(p
++);
748 len
= offset_next
- offset
;
750 continue; /* empty glyph */
756 buf
= glyf_table
->buf
+ offset
;
758 /* We must parse the rest of the glyph record to get the exact */
759 /* record length. Since the `loca' table rounds record lengths */
760 /* up to multiples of 4 (or 2 for older fonts), and we must round */
761 /* up again after stripping off the instructions, it would be */
762 /* possible otherwise to have more than 4 bytes of padding which */
763 /* is more or less invalid. */
765 if (glyph
->num_contours
< 0)
766 error
= TA_glyph_parse_composite(glyph
, buf
, len
,
768 font
->hint_composites
);
770 error
= TA_glyph_parse_simple(glyph
, buf
, len
);
776 if (sfnt
->max_components
&& font
->hint_composites
)
778 /* construct and append our special glyph used as a composite element */
779 GLYPH
* glyph
= &data
->glyphs
[data
->num_glyphs
- 1];
784 glyph
->buf
= (FT_Byte
*)malloc(glyph
->len1
+ glyph
->len2
);
786 return FT_Err_Out_Of_Memory
;
790 buf
[0] = 0x00; /* one contour */
792 buf
[2] = 0x00; /* no dimensions */
800 buf
[10] = 0x00; /* one contour end point */
803 buf
[12] = ON_CURVE
| SAME_X
| SAME_Y
; /* the flags for a point at 0,0 */
805 /* add bytecode also; */
806 /* this works because the loop in `TA_sfnt_build_glyf_hints' */
807 /* doesn't include the newly appended glyph */
808 glyph
->ins_len
= sizeof (ttfautohint_glyph_bytecode
);
809 glyph
->ins_buf
= (FT_Byte
*)malloc(glyph
->ins_len
);
811 return FT_Err_Out_Of_Memory
;
812 memcpy(glyph
->ins_buf
, ttfautohint_glyph_bytecode
, glyph
->ins_len
);
814 sfnt
->max_components
+= 1;
822 TA_sfnt_build_glyf_table(SFNT
* sfnt
,
827 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
828 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
838 if (glyf_table
->processed
)
843 error
= TA_sfnt_build_glyf_hints(sfnt
, font
);
850 glyph
= data
->glyphs
;
851 for (i
= 0; i
< data
->num_glyphs
; i
++, glyph
++)
853 /* glyph records should have offsets which are multiples of 4 */
854 len
= (len
+ 3) & ~3;
855 len
+= glyph
->len1
+ glyph
->len2
856 + glyph
->ins_extra_len
+ glyph
->ins_len
;
857 /* add two bytes for the instructionLength field */
858 if (glyph
->len2
|| glyph
->ins_len
)
862 /* to make the short format of the `loca' table always work, */
863 /* assure an even length of the `glyf' table */
864 glyf_table
->len
= (len
+ 1) & ~1;
866 buf_new
= (FT_Byte
*)realloc(glyf_table
->buf
, (len
+ 3) & ~3);
868 return FT_Err_Out_Of_Memory
;
870 glyf_table
->buf
= buf_new
;
873 glyph
= data
->glyphs
;
874 for (i
= 0; i
< data
->num_glyphs
; i
++, glyph
++)
876 len
= glyph
->len1
+ glyph
->len2
877 + glyph
->ins_extra_len
+ glyph
->ins_len
;
878 if (glyph
->len2
|| glyph
->ins_len
)
883 /* copy glyph data and insert new instructions */
884 memcpy(p
, glyph
->buf
, glyph
->len1
);
890 *(p
++) = HIGH(glyph
->ins_extra_len
+ glyph
->ins_len
);
891 *(p
++) = LOW(glyph
->ins_extra_len
+ glyph
->ins_len
);
892 if (glyph
->ins_extra_len
)
894 memcpy(p
, ins_extra_buf
, glyph
->ins_extra_len
);
895 p
+= glyph
->ins_extra_len
;
897 memcpy(p
, glyph
->ins_buf
, glyph
->ins_len
);
899 memcpy(p
, glyph
->buf
+ glyph
->len1
, glyph
->len2
);
904 /* composite glyph */
907 *(p
+ glyph
->flags_offset
) |= (WE_HAVE_INSTR
>> 8);
909 *(p
++) = HIGH(glyph
->ins_extra_len
+ glyph
->ins_len
);
910 *(p
++) = LOW(glyph
->ins_extra_len
+ glyph
->ins_len
);
911 if (glyph
->ins_extra_len
)
913 memcpy(p
, ins_extra_buf
, glyph
->ins_extra_len
);
914 p
+= glyph
->ins_extra_len
;
916 memcpy(p
, glyph
->ins_buf
, glyph
->ins_len
);
923 /* pad with zero bytes to have an offset which is a multiple of 4; */
924 /* this works even for the last glyph record since the `glyf' */
925 /* table length is a multiple of 4 also */
940 glyf_table
->checksum
= TA_table_compute_checksum(glyf_table
->buf
,
942 glyf_table
->processed
= 1;
949 TA_create_glyph_data(FT_Outline
* outline
,
952 FT_Error error
= TA_Err_Ok
;
958 FT_Byte
* flags
= NULL
;
972 if (!outline
->n_contours
)
973 return TA_Err_Ok
; /* empty glyph */
975 /* in case of success, all non-local allocated arrays are */
976 /* linked and eventually freed in `TA_font_unload' */
980 /* we use `calloc' since we rely on the array */
981 /* being initialized to zero; */
982 /* additionally, we need one more byte for a test after the loop */
983 flags
= (FT_Byte
*)calloc(1, outline
->n_points
+ 1);
986 error
= FT_Err_Out_Of_Memory
;
990 /* we have either one-byte or two-byte elements */
991 x
= (FT_Byte
*)malloc(2 * outline
->n_points
);
994 error
= FT_Err_Out_Of_Memory
;
998 y
= (FT_Byte
*)malloc(2 * outline
->n_points
);
1001 error
= FT_Err_Out_Of_Memory
;
1008 xmin
= xmax
= (outline
->points
[0].x
+ 32) >> 6;
1009 ymin
= ymax
= (outline
->points
[0].y
+ 32) >> 6;
1012 oldf
= 0x80; /* start with an impossible value */
1014 /* convert the FreeType representation of the glyph's outline */
1015 /* into the representation format of the `glyf' table */
1016 for (i
= 0; i
< outline
->n_points
; i
++)
1018 FT_Pos xcur
= (outline
->points
[i
].x
+ 32) >> 6;
1019 FT_Pos ycur
= (outline
->points
[i
].y
+ 32) >> 6;
1021 FT_Pos xdelta
= xcur
- lastx
;
1022 FT_Pos ydelta
= ycur
- lasty
;
1025 /* we are only interested in bit 0 of the `tags' array */
1026 f
= outline
->tags
[i
] & ON_CURVE
;
1034 if (xdelta
< 256 && xdelta
> -256)
1036 f
|= X_SHORT_VECTOR
;
1043 *(xp
++) = (FT_Byte
)xdelta
;
1047 *(xp
++) = HIGH(xdelta
);
1048 *(xp
++) = LOW(xdelta
);
1058 if (ydelta
< 256 && ydelta
> -256)
1060 f
|= Y_SHORT_VECTOR
;
1067 *(yp
++) = (FT_Byte
)ydelta
;
1071 *(yp
++) = HIGH(ydelta
);
1072 *(yp
++) = LOW(ydelta
);
1078 /* set repeat flag */
1079 *(flagsp
- 1) |= REPEAT
;
1083 /* we can only handle 256 repetitions at once, */
1084 /* so use a new counter */
1089 *flagsp
+= 1; /* increase repetition counter */
1094 flagsp
++; /* skip repetition counter */
1112 /* if the last byte was a repetition counter, */
1113 /* we must increase by one to get the correct array size */
1117 header
[0] = HIGH(outline
->n_contours
);
1118 header
[1] = LOW(outline
->n_contours
);
1119 header
[2] = HIGH(xmin
);
1120 header
[3] = LOW(xmin
);
1121 header
[4] = HIGH(ymin
);
1122 header
[5] = LOW(ymin
);
1123 header
[6] = HIGH(xmax
);
1124 header
[7] = LOW(xmax
);
1125 header
[8] = HIGH(ymax
);
1126 header
[9] = LOW(ymax
);
1128 /* concatenate all arrays and fill needed GLYPH structure elements */
1130 glyph
->len1
= 10 + 2 * outline
->n_contours
;
1131 glyph
->len2
= (flagsp
- flags
) + (xp
- x
) + (yp
- y
);
1133 glyph
->buf
= (FT_Byte
*)malloc(glyph
->len1
+ glyph
->len2
);
1136 error
= FT_Err_Out_Of_Memory
;
1141 memcpy(p
, header
, 10);
1144 glyph
->ins_extra_len
= 0;
1146 glyph
->ins_buf
= NULL
;
1148 for (i
= 0; i
< outline
->n_contours
; i
++)
1150 *(p
++) = HIGH(outline
->contours
[i
]);
1151 *(p
++) = LOW(outline
->contours
[i
]);
1154 memcpy(p
, flags
, flagsp
- flags
);
1155 p
+= flagsp
- flags
;
1156 memcpy(p
, x
, xp
- x
);
1158 memcpy(p
, y
, yp
- y
);
1169 /* We hint each glyph at EM size and construct a new `glyf' table. */
1170 /* Some fonts need this; in particular, */
1171 /* there are CJK fonts which use hints to scale and position subglyphs. */
1172 /* As a consequence, there are no longer composite glyphs. */
1175 TA_sfnt_create_glyf_data(SFNT
* sfnt
,
1178 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
1179 FT_Face face
= sfnt
->face
;
1187 /* in case of success, all allocated arrays are */
1188 /* linked and eventually freed in `TA_font_unload' */
1190 /* nothing to do if table has already been created */
1191 if (glyf_table
->data
)
1194 data
= (glyf_Data
*)calloc(1, sizeof (glyf_Data
));
1196 return FT_Err_Out_Of_Memory
;
1198 glyf_table
->data
= data
;
1200 data
->num_glyphs
= face
->num_glyphs
;
1201 data
->glyphs
= (GLYPH
*)calloc(1, data
->num_glyphs
* sizeof (GLYPH
));
1203 return FT_Err_Out_Of_Memory
;
1205 /* XXX: Make size configurable */
1206 /* we use the EM size */
1207 /* so that the resulting coordinates can be used without transformation */
1208 error
= FT_Set_Char_Size(face
, face
->units_per_EM
* 64, 0, 72, 0);
1212 /* loop over all glyphs in font face */
1213 for (i
= 0; i
< data
->num_glyphs
; i
++)
1215 GLYPH
* glyph
= &data
->glyphs
[i
];
1218 error
= FT_Load_Glyph(face
, i
, FT_LOAD_NO_BITMAP
| FT_LOAD_NO_AUTOHINT
);
1222 error
= TA_create_glyph_data(&face
->glyph
->outline
, glyph
);
1232 * While the auto-hinter is glyph oriented (this is, using `glyf' data), it
1233 * relies on the `cmap' table and OpenType features to get style coverage
1234 * data. In TTCs, subfonts normally share the same `glyf' table but use
1235 * different `cmap's and OpenType features (in `GSUB' and `GPOS' tables).
1236 * To handle this gracefully, ttfautohint collects (and merges) the coverage
1237 * information in the `glyf_Data' structure.
1241 TA_sfnt_handle_coverage(SFNT
* sfnt
,
1246 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
1247 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
1249 FT_Face face
= sfnt
->face
;
1250 TA_FaceGlobals curr_globals
;
1252 TA_Style saved_fallback_style
= font
->fallback_style
;
1255 /* using TA_STYLE_UNASSIGNED as the fallback style ensures */
1256 /* that uncovered glyphs stay as-is */
1257 /* (we handle the fallback style later on) */
1258 font
->fallback_style
= (TA_Style
)TA_STYLE_UNASSIGNED
;
1260 /* trigger computation of coverage */
1261 error
= ta_loader_init(font
);
1264 error
= ta_loader_reset(font
, face
);
1267 ta_loader_done(font
);
1269 font
->fallback_style
= saved_fallback_style
;
1270 curr_globals
= (TA_FaceGlobals
)face
->autohint
.data
;
1272 if (!data
->master_globals
)
1275 data
->master_globals
= curr_globals
;
1279 /* we have the same `glyf' table for another subfont; */
1280 /* merge the current coverage info into the `master' coverage info */
1282 TA_FaceGlobals master_globals
= data
->master_globals
;
1283 FT_Long count
= master_globals
->glyph_count
;
1285 FT_Byte
* master
= master_globals
->glyph_styles
;
1286 FT_Byte
* curr
= curr_globals
->glyph_styles
;
1288 FT_Byte
* limit
= master
+ count
;
1291 /* we simply copy the data, */
1292 /* assuming that a given glyph always has the same properties -- */
1293 /* as soon as we make the style selection more fine-grained, */
1294 /* it is possible that this assumption doesn't hold: */
1295 /* for example, glyph `A' can be used for both Cyrillic and Latin */
1296 while (master
< limit
)
1298 if ((*curr
& ~TA_DIGIT
) != TA_STYLE_UNASSIGNED
)
1312 TA_sfnt_adjust_coverage(SFNT
* sfnt
,
1315 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
1316 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
1318 TA_FaceGlobals master_globals
= data
->master_globals
;
1321 /* use fallback style for uncovered glyphs */
1322 if (!data
->adjusted
)
1325 FT_Byte
* gstyles
= master_globals
->glyph_styles
;
1331 for (nn
= 0; nn
< master_globals
->glyph_count
; nn
++)
1333 if ((gstyles
[nn
] & ~TA_DIGIT
) == TA_STYLE_UNASSIGNED
)
1335 gstyles
[nn
] &= ~TA_STYLE_UNASSIGNED
;
1336 gstyles
[nn
] |= master_globals
->font
->fallback_style
;
1342 if (sfnt
->face
->num_faces
> 1)
1344 "using fallback style `%s' for unassigned glyphs"
1345 " (glyf table index %d):\n",
1346 ta_style_names
[master_globals
->font
->fallback_style
],
1350 "using fallback style `%s' for unassigned glyphs:\n",
1351 ta_style_names
[master_globals
->font
->fallback_style
]));
1355 for (nn
= 0; nn
< master_globals
->glyph_count
; nn
++)
1357 if ((gstyles
[nn
] & ~TA_DIGIT
) == master_globals
->font
->fallback_style
)
1360 TA_LOG_GLOBAL((" "));
1362 TA_LOG_GLOBAL((" %d", nn
));
1366 TA_LOG_GLOBAL(("\n"));
1371 TA_LOG_GLOBAL((" (none)\n"));
1373 TA_LOG_GLOBAL(("\n"));
1375 #endif /* TA_DEBUG */
1385 TA_sfnt_copy_master_coverage(SFNT
* sfnt
,
1388 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
1389 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
1391 FT_Face face
= sfnt
->face
;
1393 TA_FaceGlobals master_globals
= data
->master_globals
;
1394 TA_FaceGlobals curr_globals
= (TA_FaceGlobals
)face
->autohint
.data
;
1397 if (master_globals
!= curr_globals
)
1399 FT_Long count
= master_globals
->glyph_count
;
1400 FT_Byte
* master
= master_globals
->glyph_styles
;
1401 FT_Byte
* curr
= curr_globals
->glyph_styles
;
1404 memcpy(curr
, master
, count
);
1410 /* end of taglyf.c */