4 * Copyright (C) 2011-2014 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 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 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 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 unsigned char PREP(test_exception_a
) [] =
83 /* provide scaling factors for all styles */
85 unsigned char PREP(align_top_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 unsigned char PREP(align_top_b
) [] =
109 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 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 unsigned char PREP(loop_cvt_c
) [] =
155 bci_cvt_rescale_range
,
160 unsigned char PREP(test_exception_b
) [] =
167 unsigned char PREP(store_vwidth_data_a
) [] =
175 /* %c, offset to vertical width offset data in CVT */
177 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 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 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 unsigned char PREP(store_vwidth_data_e
) [] =
220 0x00, /* high byte */
221 bci_vwidth_data_store
, /* low byte */
226 unsigned char PREP(set_smooth_or_strong_a
) [] =
230 * There are two ClearType flavours available on Windows: The older GDI
231 * ClearType, introduced in 2000, and the recent DW ClearType, introduced
232 * in 2008. The main difference is that the older incarnation behaves
233 * like a B/W renderer along the y axis, while the newer version does
234 * vertical smoothing also.
236 * The only possibility to differentiate between GDI and DW ClearType is
237 * testing bit 10 in the GETINFO instruction (with return value in bit 17;
238 * this works for TrueType version >= 38), checking whether sub-pixel
239 * positioning is available.
241 * If GDI ClearType is active, we use different functions for stem width
242 * computation and blue zone rounding that snap to integer pixels as much
246 /* set default value */
248 cvtl_use_strong_functions
,
252 /* %c, either 0 or 100 */
254 unsigned char PREP(set_smooth_or_strong_b
) [] =
259 /* get rasterizer version (bit 0) */
265 /* `GDI ClearType': */
266 /* version >= 36 and version < 38, ClearType enabled */
269 /* check whether ClearType is enabled (bit 6) */
275 cvtl_use_strong_functions
,
278 /* %c, either 0 or 100 */
280 unsigned char PREP(set_smooth_or_strong_c
) [] =
285 /* get rasterizer version (bit 0) */
291 /* `DW ClearType': */
292 /* version >= 38, sub-pixel positioning is enabled */
295 /* check whether sub-pixel positioning is enabled (bit 10) -- */
296 /* due to a bug in FreeType 2.5.0 and earlier, */
297 /* bit 6 must be set also to get the correct information, */
298 /* so we test that both return values (in bits 13 and 17) are set */
300 0x08, /* bits 13 and 17 shifted by 6 bits */
302 0x00, /* we do `MUL' with value 1, */
303 0x01, /* which is essentially a division by 64 */
304 0x04, /* bits 6 and 10 */
311 cvtl_use_strong_functions
,
315 /* %c, either 0 or 100 */
317 unsigned char PREP(set_smooth_or_strong_d
) [] =
328 /*PUSHB (2*num_used_styles + 2) */
330 /* %c, style 1's first blue ref index */
331 /* %c, style 1's number of blue ref indices */
332 /* %c, style 0's first blue ref index */
333 /* %c, style 0's number of blue ref indices */
334 /* %c, num_used_styles */
336 unsigned char PREP(round_blues
) [] =
339 bci_blue_round_range
,
344 unsigned char PREP(set_dropout_mode
) [] =
348 0x01, /* 0x01FF, activate dropout handling unconditionally */
352 4, /* smart dropout include stubs */
357 unsigned char PREP(reset_component_counter
) [] =
360 /* In case an application tries to render `.ttfautohint' */
361 /* (which it should never do), */
362 /* hinting of all glyphs rendered afterwards is disabled */
363 /* because the `cvtl_is_subglyph' counter gets incremented, */
364 /* but there is no counterpart to decrement it. */
365 /* Font inspection tools like the FreeType demo programs */
366 /* are an exception to that rule, however, */
367 /* since they can directly access a font by glyph indices. */
368 /* The following guard alleviates the problem a bit: */
369 /* Any change of the graphics state */
370 /* (for example, rendering at a different size or with a different mode) */
371 /* resets the counter to zero. */
379 unsigned char PREP(adjust_delta_exceptions
) [] =
390 /* this function allocates `buf', parsing `number_set' to create bytecode */
391 /* which eventually sets CVT index `cvtl_is_element' */
392 /* (in functions `bci_number_set_is_element' and */
393 /* `bci_number_set_is_element2') */
396 TA_sfnt_build_number_set(SFNT
* sfnt
,
398 number_range
* number_set
)
400 FT_Byte
* bufp
= NULL
;
403 FT_UInt num_singles2
= 0;
404 FT_UInt
* single2_args
;
405 FT_UInt
* single2_arg
;
406 FT_UInt num_singles
= 0;
407 FT_UInt
* single_args
;
410 FT_UInt num_ranges2
= 0;
411 FT_UInt
* range2_args
;
413 FT_UInt num_ranges
= 0;
417 FT_UInt have_single
= 0;
418 FT_UInt have_range
= 0;
420 FT_UShort num_stack_elements
;
423 /* build up four stacks to stay as compact as possible */
427 if (nr
->start
== nr
->end
)
436 if (nr
->start
< 256 && nr
->end
< 256)
444 /* collect all arguments temporarily in arrays (in reverse order) */
445 /* so that we can easily split into chunks of 255 args */
446 /* as needed by NPUSHB and friends; */
447 /* for simplicity, always allocate an extra slot */
448 single2_args
= (FT_UInt
*)malloc((num_singles2
+ 1) * sizeof (FT_UInt
));
449 single_args
= (FT_UInt
*)malloc((num_singles
+ 1) * sizeof (FT_UInt
));
450 range2_args
= (FT_UInt
*)malloc((2 * num_ranges2
+ 1) * sizeof (FT_UInt
));
451 range_args
= (FT_UInt
*)malloc((2 * num_ranges
+ 1) * sizeof (FT_UInt
));
452 if (!single2_args
|| !single_args
453 || !range2_args
|| !range_args
)
456 /* check whether we need the extra slot for the argument to CALL */
457 if (num_singles
|| num_singles2
)
459 if (num_ranges
|| num_ranges2
)
462 /* set function indices outside of argument loop (using the extra slot) */
464 single_args
[num_singles
] = bci_number_set_is_element
;
466 range_args
[2 * num_ranges
] = bci_number_set_is_element2
;
468 single2_arg
= single2_args
+ num_singles2
- 1;
469 single_arg
= single_args
+ num_singles
- 1;
470 range2_arg
= range2_args
+ 2 * num_ranges2
- 1;
471 range_arg
= range_args
+ 2 * num_ranges
- 1;
476 if (nr
->start
== nr
->end
)
479 *(single_arg
--) = nr
->start
;
481 *(single2_arg
--) = nr
->start
;
485 if (nr
->start
< 256 && nr
->end
< 256)
487 *(range_arg
--) = nr
->start
;
488 *(range_arg
--) = nr
->end
;
492 *(range2_arg
--) = nr
->start
;
493 *(range2_arg
--) = nr
->end
;
499 /* this rough estimate of the buffer size gets adjusted later on */
500 *buf
= (FT_Byte
*)malloc((2 + 1) * num_singles2
501 + (1 + 1) * num_singles
502 + (4 + 1) * num_ranges2
503 + (2 + 1) * num_ranges
510 BCI(cvtl_is_element
);
514 bufp
= TA_build_push(bufp
, single2_args
, num_singles2
, 1, 1);
515 bufp
= TA_build_push(bufp
, single_args
, num_singles
+ have_single
, 0, 1);
519 bufp
= TA_build_push(bufp
, range2_args
, 2 * num_ranges2
, 1, 1);
520 bufp
= TA_build_push(bufp
, range_args
, 2 * num_ranges
+ have_range
, 0, 1);
524 num_stack_elements
= num_singles
+ num_singles2
;
525 if (num_stack_elements
> num_ranges
+ num_ranges2
)
526 num_stack_elements
= num_ranges
+ num_ranges2
;
527 num_stack_elements
+= ADDITIONAL_STACK_ELEMENTS
;
528 if (num_stack_elements
> sfnt
->max_stack_elements
)
529 sfnt
->max_stack_elements
= num_stack_elements
;
541 #define COPY_PREP(snippet_name) \
544 memcpy(bufp, prep_ ## snippet_name, \
545 sizeof (prep_ ## snippet_name)); \
546 bufp += sizeof (prep_ ## snippet_name); \
550 TA_table_build_prep(FT_Byte
** prep
,
555 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
556 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
566 FT_Byte
* bufp
= NULL
;
569 if (font
->x_height_snapping_exceptions
)
571 bufp
= TA_sfnt_build_number_set(sfnt
, &buf
,
572 font
->x_height_snapping_exceptions
);
574 return FT_Err_Out_Of_Memory
;
577 buf_len
= bufp
- buf
;
578 buf_new_len
= buf_len
;
580 if (font
->hinting_limit
)
581 buf_new_len
+= sizeof (PREP(hinting_limit_a
))
583 + sizeof (PREP(hinting_limit_b
));
585 buf_new_len
+= sizeof (PREP(store_funits_to_pixels
));
587 if (font
->x_height_snapping_exceptions
)
588 buf_new_len
+= sizeof (PREP(test_exception_a
));
590 buf_new_len
+= sizeof (PREP(align_top_a
))
591 + (data
->num_used_styles
> 6
592 ? data
->num_used_styles
+ 3
593 : data
->num_used_styles
+ 2)
594 + sizeof (PREP(align_top_b
));
595 buf_new_len
+= sizeof (PREP(loop_cvt_a
))
596 + (data
->num_used_styles
> 3
597 ? 2 * data
->num_used_styles
+ 3
598 : 2 * data
->num_used_styles
+ 2)
599 + sizeof (PREP(loop_cvt_b
))
600 + (data
->num_used_styles
> 3
601 ? 2 * data
->num_used_styles
+ 3
602 : 2 * data
->num_used_styles
+ 2)
603 + sizeof (PREP(loop_cvt_c
));
605 if (font
->x_height_snapping_exceptions
)
606 buf_new_len
+= sizeof (PREP(test_exception_b
));
608 buf_new_len
+= sizeof (PREP(store_vwidth_data_a
))
610 + sizeof (PREP(store_vwidth_data_b
))
611 + (data
->num_used_styles
> 6
612 ? 2 * (data
->num_used_styles
+ 1) + 2
613 : 2 * (data
->num_used_styles
+ 1) + 1)
614 + sizeof (PREP(store_vwidth_data_c
))
616 + sizeof (PREP(store_vwidth_data_d
))
617 + (data
->num_used_styles
> 6
618 ? 2 * (data
->num_used_styles
+ 1) + 2
619 : 2 * (data
->num_used_styles
+ 1) + 1)
620 + sizeof (PREP(store_vwidth_data_e
));
621 buf_new_len
+= sizeof (PREP(set_smooth_or_strong_a
))
623 + sizeof (PREP(set_smooth_or_strong_b
))
625 + sizeof (PREP(set_smooth_or_strong_c
))
627 + sizeof (PREP(set_smooth_or_strong_d
));
628 buf_new_len
+= (data
->num_used_styles
> 3
629 ? 2 * data
->num_used_styles
+ 3
630 : 2 * data
->num_used_styles
+ 2)
631 + sizeof (PREP(round_blues
));
632 buf_new_len
+= sizeof (PREP(set_dropout_mode
));
633 buf_new_len
+= sizeof (PREP(reset_component_counter
));
634 if (font
->deltas_data_head
)
635 buf_new_len
+= sizeof (PREP(adjust_delta_exceptions
));
637 /* buffer length must be a multiple of four */
638 len
= (buf_new_len
+ 3) & ~3;
639 buf_new
= (FT_Byte
*)realloc(buf
, len
);
643 return FT_Err_Out_Of_Memory
;
647 /* pad end of buffer with zeros */
652 /* copy remaining cvt program into buffer */
653 /* and fill in the missing variables */
654 bufp
= buf
+ buf_len
;
656 if (font
->hinting_limit
)
658 COPY_PREP(hinting_limit_a
);
659 *(bufp
++) = HIGH(font
->hinting_limit
);
660 *(bufp
++) = LOW(font
->hinting_limit
);
661 COPY_PREP(hinting_limit_b
);
664 COPY_PREP(store_funits_to_pixels
);
666 if (font
->x_height_snapping_exceptions
)
667 COPY_PREP(test_exception_a
);
669 COPY_PREP(align_top_a
);
670 if (data
->num_used_styles
> 6)
673 BCI(data
->num_used_styles
+ 2);
676 BCI(PUSHB_1
- 1 + data
->num_used_styles
+ 2);
677 /* XXX: make this work for offsets > 255 */
678 for (i
= TA_STYLE_MAX
- 1; i
>= 0; i
--)
680 if (data
->style_ids
[i
] == 0xFFFFU
)
683 *(bufp
++) = CVT_X_HEIGHT_BLUE_OFFSET(i
) >= 0xFFFFU
685 : (unsigned char)CVT_X_HEIGHT_BLUE_OFFSET(i
);
687 *(bufp
++) = data
->num_used_styles
;
688 COPY_PREP(align_top_b
);
690 COPY_PREP(loop_cvt_a
);
691 if (data
->num_used_styles
> 3)
694 BCI(2 * data
->num_used_styles
+ 2);
697 BCI(PUSHB_1
- 1 + 2 * data
->num_used_styles
+ 2);
698 /* XXX: make this work for offsets > 255 */
699 for (i
= TA_STYLE_MAX
- 1; i
>= 0; i
--)
701 if (data
->style_ids
[i
] == 0xFFFFU
)
704 /* don't loop over artificial blue zones */
705 *(bufp
++) = (unsigned char)CVT_VERT_STANDARD_WIDTH_OFFSET(i
);
706 *(bufp
++) = (unsigned char)(
708 + CVT_VERT_WIDTHS_SIZE(i
)
709 + (CVT_BLUES_SIZE(i
) > 1 ? CVT_BLUES_SIZE(i
) - 2 : 0));
711 *(bufp
++) = data
->num_used_styles
;
712 COPY_PREP(loop_cvt_b
);
713 if (data
->num_used_styles
> 3)
716 BCI(2 * data
->num_used_styles
+ 2);
719 BCI(PUSHB_1
- 1 + 2 * data
->num_used_styles
+ 2);
720 /* XXX: make this work for offsets > 255 */
721 for (i
= TA_STYLE_MAX
- 1; i
>= 0; i
--)
723 if (data
->style_ids
[i
] == 0xFFFFU
)
726 /* don't loop over artificial blue zones */
727 *(bufp
++) = (unsigned char)CVT_BLUE_SHOOTS_OFFSET(i
);
728 *(bufp
++) = (unsigned char)(
729 CVT_BLUES_SIZE(i
) > 1 ? CVT_BLUES_SIZE(i
) - 2 : 0);
731 *(bufp
++) = data
->num_used_styles
;
732 COPY_PREP(loop_cvt_c
);
734 if (font
->x_height_snapping_exceptions
)
735 COPY_PREP(test_exception_b
);
737 COPY_PREP(store_vwidth_data_a
);
738 *(bufp
++) = (unsigned char)CVT_VWIDTH_OFFSET_DATA(0);
739 COPY_PREP(store_vwidth_data_b
);
740 if (data
->num_used_styles
> 6)
743 BCI(data
->num_used_styles
+ 2);
746 BCI(PUSHW_1
- 1 + data
->num_used_styles
+ 2);
747 for (i
= TA_STYLE_MAX
- 1; i
>= 0; i
--)
749 if (data
->style_ids
[i
] == 0xFFFFU
)
752 *(bufp
++) = HIGH(CVT_VERT_WIDTHS_OFFSET(i
) * 64);
753 *(bufp
++) = LOW(CVT_VERT_WIDTHS_OFFSET(i
) * 64);
755 *(bufp
++) = HIGH(data
->num_used_styles
);
756 *(bufp
++) = LOW(data
->num_used_styles
);
757 COPY_PREP(store_vwidth_data_c
);
758 *(bufp
++) = (unsigned char)CVT_VWIDTH_SIZE_DATA(0);
759 COPY_PREP(store_vwidth_data_d
);
760 if (data
->num_used_styles
> 6)
763 BCI(data
->num_used_styles
+ 2);
766 BCI(PUSHW_1
- 1 + data
->num_used_styles
+ 2);
767 for (i
= TA_STYLE_MAX
- 1; i
>= 0; i
--)
769 if (data
->style_ids
[i
] == 0xFFFFU
)
772 *(bufp
++) = HIGH(CVT_VERT_WIDTHS_SIZE(i
) * 64);
773 *(bufp
++) = LOW(CVT_VERT_WIDTHS_SIZE(i
) * 64);
775 *(bufp
++) = HIGH(data
->num_used_styles
);
776 *(bufp
++) = LOW(data
->num_used_styles
);
777 COPY_PREP(store_vwidth_data_e
);
779 COPY_PREP(set_smooth_or_strong_a
);
780 *(bufp
++) = font
->gray_strong_stem_width
? 100 : 0;
781 COPY_PREP(set_smooth_or_strong_b
);
782 *(bufp
++) = font
->gdi_cleartype_strong_stem_width
? 100 : 0;
783 COPY_PREP(set_smooth_or_strong_c
);
784 *(bufp
++) = font
->dw_cleartype_strong_stem_width
? 100 : 0;
785 COPY_PREP(set_smooth_or_strong_d
);
787 if (data
->num_used_styles
> 3)
790 BCI(2 * data
->num_used_styles
+ 2);
793 BCI(PUSHB_1
- 1 + 2 * data
->num_used_styles
+ 2);
794 /* XXX: make this work for offsets > 255 */
795 for (i
= TA_STYLE_MAX
- 1; i
>= 0; i
--)
797 if (data
->style_ids
[i
] == 0xFFFFU
)
800 *(bufp
++) = (unsigned char)CVT_BLUE_REFS_OFFSET(i
);
801 *(bufp
++) = (unsigned char)CVT_BLUES_SIZE(i
);
803 *(bufp
++) = data
->num_used_styles
;
804 COPY_PREP(round_blues
);
806 COPY_PREP(set_dropout_mode
);
807 COPY_PREP(reset_component_counter
);
808 if (font
->deltas_data_head
)
809 COPY_PREP(adjust_delta_exceptions
);
812 *prep_len
= buf_new_len
;
819 TA_sfnt_build_prep_table(SFNT
* sfnt
,
824 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
825 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
831 error
= TA_sfnt_add_table_info(sfnt
);
835 /* `glyf', `cvt', `fpgm', and `prep' are always used in parallel */
836 if (glyf_table
->processed
)
838 sfnt
->table_infos
[sfnt
->num_table_infos
- 1] = data
->prep_idx
;
842 error
= TA_table_build_prep(&prep_buf
, &prep_len
, sfnt
, font
);
847 /* ttfautohint's bytecode in `fpgm' is larger */
848 /* than the bytecode in `prep'; */
849 /* this commented out code here is just for completeness */
850 if (prep_len
> sfnt
->max_instructions
)
851 sfnt
->max_instructions
= prep_len
;
854 /* in case of success, `prep_buf' gets linked */
855 /* and is eventually freed in `TA_font_unload' */
856 error
= TA_font_add_table(font
,
857 &sfnt
->table_infos
[sfnt
->num_table_infos
- 1],
858 TTAG_prep
, prep_len
, prep_buf
);
862 data
->prep_idx
= sfnt
->table_infos
[sfnt
->num_table_infos
- 1];
868 /* end of taprep.c */