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.
19 #define PREP(snippet_name) prep_ ## snippet_name
22 static const unsigned char PREP(hinting_limit_a
) [] =
25 /* all our measurements are taken along the y axis, */
26 /* including the ppem and CVT values */
29 /* first of all, check whether we do hinting at all */
35 /* %d, hinting size limit */
37 static const unsigned char PREP(hinting_limit_b
) [] =
43 1, /* switch off hinting */
50 /* we store 0x10000 in CVT index `cvtl_funits_to_pixels' as a scaled value */
51 /* to have a conversion factor from FUnits to pixels */
53 static const unsigned char PREP(store_funits_to_pixels
) [] =
57 cvtl_funits_to_pixels
,
66 WCVTF
, /* store value 1 in 16.16 format, scaled */
70 /* if the current ppem value is an exception, don't apply scaling */
72 static const unsigned char PREP(test_exception_a
) [] =
83 /* provide scaling factors for all styles */
85 static const unsigned char PREP(align_x_height_a
) [] =
90 CVT_SCALING_VALUE_OFFSET(0),
95 /* PUSHB (num_used_styles + 2) */
97 /* %c, style 1's x height blue zone idx */
98 /* %c, style 0's x height blue zone idx */
99 /* %c, num_used_styles */
101 static const unsigned char PREP(align_x_height_b
) [] =
109 static const unsigned char PREP(loop_cvt_a
) [] =
112 /* loop over (almost all) vertical CVT entries of all styles, part 1 */
115 CVT_SCALING_VALUE_OFFSET(0),
120 /* PUSHB (2*num_used_styles + 2) */
122 /* %c, style 1's first vertical index */
123 /* %c, style 1's number of vertical indices */
124 /* (std. width, widths, flat blues zones without artifical ones) */
125 /* %c, style 0's first vertical index */
126 /* %c, style 0's number of vertical indices */
127 /* (std. width, widths, flat blues zones without artifical ones) */
128 /* %c, num_used_styles */
130 static const unsigned char PREP(loop_cvt_b
) [] =
133 bci_cvt_rescale_range
,
136 /* loop over (almost all) vertical CVT entries of all styles, part 2 */
139 CVT_SCALING_VALUE_OFFSET(0),
144 /* PUSHB (2*num_used_styles + 2) */
146 /* %c, style 1's first round blue zone index */
147 /* %c, style 1's number of round blue zones (without artificial ones) */
148 /* %c, style 0's first round blue zone index */
149 /* %c, style 0's number of round blue zones (without artificial ones) */
150 /* %c, num_used_styles */
152 static const unsigned char PREP(loop_cvt_c
) [] =
155 bci_cvt_rescale_range
,
160 static const unsigned char PREP(test_exception_b
) [] =
167 static const unsigned char PREP(store_vwidth_data_a
) [] =
175 /* %c, offset to vertical width offset data in CVT */
177 static const unsigned char PREP(store_vwidth_data_b
) [] =
184 /*PUSHW (num_used_styles + 2) */
186 /* %d, style 1's first vertical width index (in multiples of 64) */
187 /* %d, style 0's first vertical width index (in multiples of 64) */
188 /* %d, num_used_styles */
190 static const unsigned char PREP(store_vwidth_data_c
) [] =
193 0x00, /* high byte */
194 bci_vwidth_data_store
, /* low byte */
202 /* %c, offset to vertical width size data in CVT */
204 static const unsigned char PREP(store_vwidth_data_d
) [] =
211 /*PUSHW (num_used_styles + 2) */
213 /* %d, style 1's number of vertical widths (in multiples of 64) */
214 /* %d, style 0's number of vertical widths (in multiples of 64) */
215 /* %d, num_used_styles */
217 static const unsigned char PREP(store_vwidth_data_e
) [] =
220 0x00, /* high byte */
221 bci_vwidth_data_store
, /* low byte */
226 static const unsigned char PREP(set_stem_width_mode_a
) [] =
229 * ttfautohint provides two different functions for stem width computation
230 * and blue zone rounding: `smooth' and `strong'. The former tries to
231 * align stem widths and blue zones to some discrete, possibly non-integer
232 * values. The latter snaps everything to integer pixels as much as
235 * We test ClearType capabilities to find out which of the two functions
236 * should be used. Due to the various TrueType interpreter versions this
237 * is quite convoluted.
239 * interpreter version action
240 * ---------------------------------------------------------------------
241 * <= 35 this version predates ClearType -> smooth
243 * 36-38 use bit 6 in the GETINFO instruction to check
244 * whether ClearType is enabled; if set, we have
245 * (old) GDI ClearType -> strong, otherwise
246 * grayscale rendering -> smooth
248 * 39 if ClearType is enabled, use bit 10 in the
249 * GETINFO instruction to check whether ClearType
250 * sub-pixel positioning is available; if set, we
251 * have DW ClearType -> smooth, else GDI ClearType
254 * >= 40 if ClearType is enabled, use bit 11 in the
255 * GETINFO instruction to check whether ClearType
256 * symmetric rendering is available; if not set,
257 * the engine behaves like a B/W renderer along the
258 * y axis -> strong, else it does vertical
259 * smoothing -> smooth
261 * ClearType on Windows was introduced in 2000 for the GDI framework (no
262 * symmetric rendering, no sub-pixel positioning). In 2008, Windows got
263 * the DirectWrite (DW) framework which uses symmetric rendering and
264 * sub-pixel positioning.
266 * Note that in 2017 GDI on Windows 10 has changed rendering parameters:
267 * it now uses symmetric rendering but no sub-pixel positioning.
268 * Consequently, we treat this as `DW ClearType' also.
271 /* set default value */
274 cvtl_stem_width_mode
, /* target: grayscale rendering */
278 /* %d, either -100, 0 or 100 */
280 static const unsigned char PREP(set_stem_width_mode_b
) [] =
285 /* get rasterizer version (bit 0) */
291 /* `(old) GDI ClearType': version >= 36 || version <= 38 */
294 /* check whether ClearType is enabled (bit 6) */
301 cvtl_stem_width_mode
, /* target: GDI ClearType */
304 /* %d, either -100, 0 or 100 */
306 static const unsigned char PREP(set_stem_width_mode_c
) [] =
311 /* get rasterizer version (bit 0) */
317 /* `DW ClearType': version >= 40 */
320 /* check whether symmetric rendering is enabled (bit 11) */
328 cvtl_stem_width_mode
, /* target: DirectWrite ClearType */
332 /* %d, either -100, 0 or 100 */
334 static const unsigned char PREP(set_stem_width_mode_d
) [] =
341 /* get rasterizer version (bit 0) */
347 /* `DW ClearType': version == 39 */
350 /* check whether sub-pixel positioning is enabled (bit 10) -- */
351 /* due to a bug in FreeType 2.5.0 and earlier, */
352 /* bit 6 must be set also to get the correct information, */
353 /* so we test that both return values (in bits 13 and 17) are set */
355 0x08, /* bits 13 and 17 right-shifted by 6 bits */
357 0x00, /* we do `MUL' with value 1, */
358 0x01, /* which is essentially a division by 64 */
359 0x04, /* bits 6 and 10 */
367 cvtl_stem_width_mode
, /* target: DirectWrite ClearType */
371 /* %d, either -100, 0 or 100 */
373 static const unsigned char PREP(set_stem_width_mode_e
) [] =
385 /*PUSHB (2*num_used_styles + 2) */
387 /* %c, style 1's first blue ref index */
388 /* %c, style 1's number of blue ref indices */
389 /* %c, style 0's first blue ref index */
390 /* %c, style 0's number of blue ref indices */
391 /* %c, num_used_styles */
393 static const unsigned char PREP(round_blues
) [] =
396 bci_blue_round_range
,
401 static const unsigned char PREP(set_dropout_mode
) [] =
405 0x01, /* 0x01FF, activate dropout handling unconditionally */
409 4, /* smart dropout include stubs */
414 static const unsigned char PREP(reset_component_counter
) [] =
417 /* In case an application tries to render `.ttfautohint' */
418 /* (which it should never do), */
419 /* hinting of all glyphs rendered afterwards is disabled */
420 /* because the `cvtl_is_subglyph' counter gets incremented, */
421 /* but there is no counterpart to decrement it. */
422 /* Font inspection tools like the FreeType demo programs */
423 /* are an exception to that rule, however, */
424 /* since they can directly access a font by glyph indices. */
425 /* The following guard alleviates the problem a bit: */
426 /* Any change of the graphics state */
427 /* (for example, rendering at a different size or with a different mode) */
428 /* resets the counter to zero. */
436 static const unsigned char PREP(adjust_delta_exceptions
) [] =
441 CONTROL_DELTA_PPEM_MIN
,
447 static const unsigned char PREP(set_default_cvs_values
) [] =
450 /* We set a default value for `cvtl_do_iup_y'. */
451 /* If we have delta exceptions before IUP_y, */
452 /* the glyph's bytecode sets this CVT value temporarily to zero */
453 /* and manually inserts IUP_y afterwards. */
455 /* We set a default value for `cvtl_ignore_std_width'. */
456 /* As the name implies, the stem width computation routines */
457 /* ignore the standard width(s) if this flag gets set. */
459 /* It would be more elegant to use storage area locations instead, */
460 /* however, it is not possible to have default values for them */
461 /* since storage area locations might be reset on a per-glyph basis */
462 /* (this is dependent on the bytecode interpreter implementation). */
467 cvtl_ignore_std_width
,
475 /* this function allocates `buf', parsing `number_set' to create bytecode */
476 /* which eventually sets CVT index `cvtl_is_element' */
477 /* (in functions `bci_number_set_is_element' and */
478 /* `bci_number_set_is_element2') */
481 TA_sfnt_build_number_set(SFNT
* sfnt
,
483 number_range
* number_set
)
485 FT_Byte
* bufp
= NULL
;
488 FT_UInt num_singles2
= 0;
489 FT_UInt
* single2_args
;
490 FT_UInt
* single2_arg
;
491 FT_UInt num_singles
= 0;
492 FT_UInt
* single_args
;
495 FT_UInt num_ranges2
= 0;
496 FT_UInt
* range2_args
;
498 FT_UInt num_ranges
= 0;
502 FT_UInt have_single
= 0;
503 FT_UInt have_range
= 0;
505 FT_UShort num_stack_elements
;
508 /* build up four stacks to stay as compact as possible */
512 if (nr
->start
== nr
->end
)
521 if (nr
->start
< 256 && nr
->end
< 256)
529 /* collect all arguments temporarily in arrays (in reverse order) */
530 /* so that we can easily split into chunks of 255 args */
531 /* as needed by NPUSHB and friends; */
532 /* for simplicity, always allocate an extra slot */
533 single2_args
= (FT_UInt
*)malloc((num_singles2
+ 1) * sizeof (FT_UInt
));
534 single_args
= (FT_UInt
*)malloc((num_singles
+ 1) * sizeof (FT_UInt
));
535 range2_args
= (FT_UInt
*)malloc((2 * num_ranges2
+ 1) * sizeof (FT_UInt
));
536 range_args
= (FT_UInt
*)malloc((2 * num_ranges
+ 1) * sizeof (FT_UInt
));
537 if (!single2_args
|| !single_args
538 || !range2_args
|| !range_args
)
541 /* check whether we need the extra slot for the argument to CALL */
542 if (num_singles
|| num_singles2
)
544 if (num_ranges
|| num_ranges2
)
547 /* set function indices outside of argument loop (using the extra slot) */
549 single_args
[num_singles
] = bci_number_set_is_element
;
551 range_args
[2 * num_ranges
] = bci_number_set_is_element2
;
553 single2_arg
= single2_args
+ num_singles2
- 1;
554 single_arg
= single_args
+ num_singles
- 1;
555 range2_arg
= range2_args
+ 2 * num_ranges2
- 1;
556 range_arg
= range_args
+ 2 * num_ranges
- 1;
561 FT_UInt start
= (FT_UInt
)nr
->start
;
562 FT_UInt end
= (FT_UInt
)nr
->end
;
568 *(single_arg
--) = start
;
570 *(single2_arg
--) = start
;
574 if (start
< 256 && end
< 256)
576 *(range_arg
--) = start
;
577 *(range_arg
--) = end
;
581 *(range2_arg
--) = start
;
582 *(range2_arg
--) = end
;
588 /* this rough estimate of the buffer size gets adjusted later on */
589 *buf
= (FT_Byte
*)malloc((2 + 1) * num_singles2
590 + (1 + 1) * num_singles
591 + (4 + 1) * num_ranges2
592 + (2 + 1) * num_ranges
599 BCI(cvtl_is_element
);
603 bufp
= TA_build_push(bufp
, single2_args
, num_singles2
, 1, 1);
604 bufp
= TA_build_push(bufp
, single_args
, num_singles
+ have_single
, 0, 1);
608 bufp
= TA_build_push(bufp
, range2_args
, 2 * num_ranges2
, 1, 1);
609 bufp
= TA_build_push(bufp
, range_args
, 2 * num_ranges
+ have_range
, 0, 1);
613 num_stack_elements
= (FT_UShort
)(num_singles
+ num_singles2
);
614 if (num_stack_elements
> num_ranges
+ num_ranges2
)
615 num_stack_elements
= (FT_UShort
)(num_ranges
+ num_ranges2
);
616 num_stack_elements
+= ADDITIONAL_STACK_ELEMENTS
;
617 if (num_stack_elements
> sfnt
->max_stack_elements
)
618 sfnt
->max_stack_elements
= num_stack_elements
;
630 #define COPY_PREP(snippet_name) \
633 memcpy(bufp, prep_ ## snippet_name, \
634 sizeof (prep_ ## snippet_name)); \
635 bufp += sizeof (prep_ ## snippet_name); \
639 TA_table_build_prep(FT_Byte
** prep
,
644 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
645 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
646 /* XXX: make this work for more than 256 styles */
647 FT_Byte num_used_styles
= (FT_Byte
)data
->num_used_styles
;
657 FT_Byte
* bufp
= NULL
;
660 if (font
->x_height_snapping_exceptions
)
662 bufp
= TA_sfnt_build_number_set(sfnt
, &buf
,
663 font
->x_height_snapping_exceptions
);
665 return FT_Err_Out_Of_Memory
;
668 buf_len
= (FT_UInt
)(bufp
- buf
);
669 buf_new_len
= buf_len
;
671 if (font
->hinting_limit
)
672 buf_new_len
+= sizeof (PREP(hinting_limit_a
))
674 + sizeof (PREP(hinting_limit_b
));
676 buf_new_len
+= sizeof (PREP(store_funits_to_pixels
));
678 if (font
->x_height_snapping_exceptions
)
679 buf_new_len
+= sizeof (PREP(test_exception_a
));
681 buf_new_len
+= sizeof (PREP(align_x_height_a
))
682 + (num_used_styles
> 6 ? num_used_styles
+ 3
683 : num_used_styles
+ 2)
684 + sizeof (PREP(align_x_height_b
));
685 buf_new_len
+= sizeof (PREP(loop_cvt_a
))
686 + (num_used_styles
> 3 ? 2 * num_used_styles
+ 3
687 : 2 * num_used_styles
+ 2)
688 + sizeof (PREP(loop_cvt_b
))
689 + (num_used_styles
> 3 ? 2 * num_used_styles
+ 3
690 : 2 * num_used_styles
+ 2)
691 + sizeof (PREP(loop_cvt_c
));
693 if (font
->x_height_snapping_exceptions
)
694 buf_new_len
+= sizeof (PREP(test_exception_b
));
696 buf_new_len
+= sizeof (PREP(store_vwidth_data_a
))
698 + sizeof (PREP(store_vwidth_data_b
))
699 + (num_used_styles
> 6 ? 2 * (num_used_styles
+ 1) + 2
700 : 2 * (num_used_styles
+ 1) + 1)
701 + sizeof (PREP(store_vwidth_data_c
))
703 + sizeof (PREP(store_vwidth_data_d
))
704 + (num_used_styles
> 6 ? 2 * (num_used_styles
+ 1) + 2
705 : 2 * (num_used_styles
+ 1) + 1)
706 + sizeof (PREP(store_vwidth_data_e
));
707 buf_new_len
+= sizeof (PREP(set_stem_width_mode_a
))
709 + sizeof (PREP(set_stem_width_mode_b
))
711 + sizeof (PREP(set_stem_width_mode_c
))
713 + sizeof (PREP(set_stem_width_mode_d
))
715 + sizeof (PREP(set_stem_width_mode_e
));
716 buf_new_len
+= (num_used_styles
> 3 ? 2 * num_used_styles
+ 3
717 : 2 * num_used_styles
+ 2)
718 + sizeof (PREP(round_blues
));
719 buf_new_len
+= sizeof (PREP(set_dropout_mode
));
720 buf_new_len
+= sizeof (PREP(reset_component_counter
));
721 if (font
->control_data_head
)
722 buf_new_len
+= sizeof (PREP(adjust_delta_exceptions
));
723 buf_new_len
+= sizeof (PREP(set_default_cvs_values
));
725 /* buffer length must be a multiple of four */
726 len
= (buf_new_len
+ 3) & ~3U;
727 buf_new
= (FT_Byte
*)realloc(buf
, len
);
731 return FT_Err_Out_Of_Memory
;
735 /* pad end of buffer with zeros */
740 /* copy remaining cvt program into buffer */
741 /* and fill in the missing variables */
742 bufp
= buf
+ buf_len
;
744 if (font
->hinting_limit
)
746 COPY_PREP(hinting_limit_a
);
747 *(bufp
++) = HIGH(font
->hinting_limit
);
748 *(bufp
++) = LOW(font
->hinting_limit
);
749 COPY_PREP(hinting_limit_b
);
752 COPY_PREP(store_funits_to_pixels
);
754 if (font
->x_height_snapping_exceptions
)
755 COPY_PREP(test_exception_a
);
757 COPY_PREP(align_x_height_a
);
758 if (num_used_styles
> 6)
761 BCI(num_used_styles
+ 2);
764 BCI(PUSHB_1
- 1 + num_used_styles
+ 2);
765 /* XXX: make this work for offsets > 255 */
766 for (i
= TA_STYLE_MAX
- 1; i
>= 0; i
--)
768 if (data
->style_ids
[i
] == 0xFFFFU
)
771 *(bufp
++) = CVT_X_HEIGHT_BLUE_OFFSET(i
) >= 0xFFFFU
773 : (unsigned char)CVT_X_HEIGHT_BLUE_OFFSET(i
);
775 *(bufp
++) = num_used_styles
;
776 COPY_PREP(align_x_height_b
);
778 COPY_PREP(loop_cvt_a
);
779 if (num_used_styles
> 3)
782 BCI(2 * num_used_styles
+ 2);
785 BCI(PUSHB_1
- 1 + 2 * num_used_styles
+ 2);
786 /* XXX: make this work for offsets > 255 */
787 for (i
= TA_STYLE_MAX
- 1; i
>= 0; i
--)
789 if (data
->style_ids
[i
] == 0xFFFFU
)
792 /* don't loop over artificial blue zones */
793 *(bufp
++) = (unsigned char)CVT_VERT_STANDARD_WIDTH_OFFSET(i
);
794 *(bufp
++) = (unsigned char)(
796 + CVT_VERT_WIDTHS_SIZE(i
)
797 + (CVT_BLUES_SIZE(i
) > 1
798 ? CVT_BLUES_SIZE(i
) - (font
->windows_compatibility
? 2
802 *(bufp
++) = num_used_styles
;
803 COPY_PREP(loop_cvt_b
);
804 if (num_used_styles
> 3)
807 BCI(2 * num_used_styles
+ 2);
810 BCI(PUSHB_1
- 1 + 2 * num_used_styles
+ 2);
811 /* XXX: make this work for offsets > 255 */
812 for (i
= TA_STYLE_MAX
- 1; i
>= 0; i
--)
814 if (data
->style_ids
[i
] == 0xFFFFU
)
817 /* don't loop over artificial blue zones */
818 *(bufp
++) = (unsigned char)CVT_BLUE_SHOOTS_OFFSET(i
);
819 *(bufp
++) = (unsigned char)(
820 CVT_BLUES_SIZE(i
) > 1
821 ? CVT_BLUES_SIZE(i
) - (font
->windows_compatibility
? 2
825 *(bufp
++) = num_used_styles
;
826 COPY_PREP(loop_cvt_c
);
828 if (font
->x_height_snapping_exceptions
)
829 COPY_PREP(test_exception_b
);
831 COPY_PREP(store_vwidth_data_a
);
832 *(bufp
++) = (unsigned char)CVT_VWIDTH_OFFSET_DATA(0);
833 COPY_PREP(store_vwidth_data_b
);
834 if (num_used_styles
> 6)
837 BCI(num_used_styles
+ 2);
840 BCI(PUSHW_1
- 1 + num_used_styles
+ 2);
841 for (i
= TA_STYLE_MAX
- 1; i
>= 0; i
--)
843 if (data
->style_ids
[i
] == 0xFFFFU
)
846 *(bufp
++) = HIGH(CVT_VERT_WIDTHS_OFFSET(i
) * 64);
847 *(bufp
++) = LOW(CVT_VERT_WIDTHS_OFFSET(i
) * 64);
849 *(bufp
++) = HIGH(num_used_styles
);
850 *(bufp
++) = LOW(num_used_styles
);
851 COPY_PREP(store_vwidth_data_c
);
852 *(bufp
++) = (unsigned char)CVT_VWIDTH_SIZE_DATA(0);
853 COPY_PREP(store_vwidth_data_d
);
854 if (num_used_styles
> 6)
857 BCI(num_used_styles
+ 2);
860 BCI(PUSHW_1
- 1 + num_used_styles
+ 2);
861 for (i
= TA_STYLE_MAX
- 1; i
>= 0; i
--)
863 if (data
->style_ids
[i
] == 0xFFFFU
)
866 *(bufp
++) = HIGH(CVT_VERT_WIDTHS_SIZE(i
) * 64);
867 *(bufp
++) = LOW(CVT_VERT_WIDTHS_SIZE(i
) * 64);
869 *(bufp
++) = HIGH(num_used_styles
);
870 *(bufp
++) = LOW(num_used_styles
);
871 COPY_PREP(store_vwidth_data_e
);
873 COPY_PREP(set_stem_width_mode_a
);
874 *(bufp
++) = HIGH(font
->gray_stem_width_mode
* 100);
875 *(bufp
++) = LOW(font
->gray_stem_width_mode
* 100);
876 COPY_PREP(set_stem_width_mode_b
);
877 *(bufp
++) = HIGH(font
->gdi_cleartype_stem_width_mode
* 100);
878 *(bufp
++) = LOW(font
->gdi_cleartype_stem_width_mode
* 100);
879 COPY_PREP(set_stem_width_mode_c
);
880 *(bufp
++) = HIGH(font
->dw_cleartype_stem_width_mode
* 100);
881 *(bufp
++) = LOW(font
->dw_cleartype_stem_width_mode
* 100);
882 COPY_PREP(set_stem_width_mode_d
);
883 *(bufp
++) = HIGH(font
->dw_cleartype_stem_width_mode
* 100);
884 *(bufp
++) = LOW(font
->dw_cleartype_stem_width_mode
* 100);
885 COPY_PREP(set_stem_width_mode_e
);
887 if (num_used_styles
> 3)
890 BCI(2 * num_used_styles
+ 2);
893 BCI(PUSHB_1
- 1 + 2 * num_used_styles
+ 2);
894 /* XXX: make this work for offsets > 255 */
895 for (i
= TA_STYLE_MAX
- 1; i
>= 0; i
--)
897 if (data
->style_ids
[i
] == 0xFFFFU
)
900 *(bufp
++) = (unsigned char)CVT_BLUE_REFS_OFFSET(i
);
901 *(bufp
++) = (unsigned char)CVT_BLUES_SIZE(i
);
903 *(bufp
++) = num_used_styles
;
904 COPY_PREP(round_blues
);
906 COPY_PREP(set_dropout_mode
);
907 COPY_PREP(reset_component_counter
);
908 if (font
->control_data_head
)
909 COPY_PREP(adjust_delta_exceptions
);
910 COPY_PREP(set_default_cvs_values
);
913 *prep_len
= buf_new_len
;
920 TA_sfnt_build_prep_table(SFNT
* sfnt
,
925 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
926 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
932 error
= TA_sfnt_add_table_info(sfnt
);
936 /* `glyf', `cvt', `fpgm', and `prep' are always used in parallel */
937 if (glyf_table
->processed
)
939 sfnt
->table_infos
[sfnt
->num_table_infos
- 1] = data
->prep_idx
;
943 error
= TA_table_build_prep(&prep_buf
, &prep_len
, sfnt
, font
);
948 /* ttfautohint's bytecode in `fpgm' is larger */
949 /* than the bytecode in `prep'; */
950 /* this commented out code here is just for completeness */
951 if (prep_len
> sfnt
->max_instructions
)
952 sfnt
->max_instructions
= prep_len
;
955 /* in case of success, `prep_buf' gets linked */
956 /* and is eventually freed in `TA_font_unload' */
957 error
= TA_font_add_table(font
,
958 &sfnt
->table_infos
[sfnt
->num_table_infos
- 1],
959 TTAG_prep
, prep_len
, prep_buf
);
963 data
->prep_idx
= sfnt
->table_infos
[sfnt
->num_table_infos
- 1];
969 /* end of taprep.c */