4 * Copyright (C) 2011-2013 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 /* first of all, check whether we do hinting at all */
32 /* %d, hinting size limit */
34 unsigned char PREP(hinting_limit_b
) [] =
40 1, /* switch off hinting */
47 /* we often need 0x10000 which can't be pushed directly onto the stack, */
48 /* thus we provide it in the CVT as `cvtl_0x10000'; */
49 /* at the same time, we store it in CVT index `cvtl_funits_to_pixels' also */
50 /* as a scaled value to have a conversion factor from FUnits to pixels */
52 unsigned char PREP(store_0x10000
) [] =
69 cvtl_funits_to_pixels
,
71 WCVTF
, /* store value 1 in 16.16 format, scaled */
75 unsigned char PREP(test_exception_a
) [] =
86 unsigned char PREP(align_top_a
) [] =
89 /* optimize the alignment of the top of small letters to the pixel grid */
95 /* %c, index of alignment blue zone */
97 unsigned char PREP(align_top_b
) [] =
106 unsigned char PREP(align_top_c1a
) [] =
109 /* use this if option `increase_x_height' > 0 */
110 /* apply much `stronger' rounding up of x height for */
111 /* 6 <= PPEM <= increase_x_height */
117 /* %d, x height increase limit */
119 unsigned char PREP(align_top_c1b
) [] =
130 52, /* threshold = 52 */
134 40, /* threshold = 40 */
138 FLOOR
, /* fitted = FLOOR(scaled + threshold) */
142 unsigned char PREP(align_top_c2
) [] =
148 FLOOR
, /* fitted = FLOOR(scaled + 40) */
152 unsigned char PREP(align_top_d
) [] =
155 DUP
, /* s: scaled scaled fitted fitted */
158 IF
, /* s: scaled fitted */
162 SUB
, /* s: scaled (fitted-scaled) */
166 MUL
, /* (fitted-scaled) in 16.16 format */
168 DIV
, /* ((fitted-scaled) / scaled) in 16.16 format */
177 unsigned char PREP(loop_cvt_a
) [] =
180 /* loop over vertical CVT entries */
185 /* %c, first vertical index */
186 /* %c, number of vertical indices */
188 unsigned char PREP(loop_cvt_b
) [] =
194 /* loop over blue refs */
199 /* %c, first blue ref index */
200 /* %c, number of blue ref indices */
202 unsigned char PREP(loop_cvt_c
) [] =
208 /* loop over blue shoots */
213 /* %c, first blue shoot index */
214 /* %c, number of blue shoot indices */
216 unsigned char PREP(loop_cvt_d
) [] =
225 unsigned char PREP(test_exception_b
) [] =
232 unsigned char PREP(compute_extra_light_a
) [] =
235 /* compute (vertical) `extra_light' flag */
242 /* %c, index of vertical standard_width */
244 unsigned char PREP(compute_extra_light_b
) [] =
248 GT
, /* standard_width < 40 */
253 unsigned char PREP(round_blues_a
) [] =
256 /* use discrete values for blue zone widths */
261 /* %c, first blue ref index */
262 /* %c, number of blue ref indices */
264 unsigned char PREP(round_blues_b
) [] =
272 unsigned char PREP(set_stem_width_handling_a
) [] =
276 * There are two ClearType flavours available on Windows: The older GDI
277 * ClearType, introduced in 2000, and the recent DW ClearType, introduced
278 * in 2008. The main difference is that the older incarnation behaves
279 * like a B/W renderer along the y axis, while the newer version does
280 * vertical smoothing also.
282 * The only possibility to differentiate between GDI and DW ClearType is
283 * testing bit 10 in the GETINFO instruction (with return value in bit 17;
284 * this works for TrueType version >= 38), checking whether sub-pixel
285 * positioning is available.
287 * If GDI ClearType is active, we use a different stem width function
288 * which snaps to integer pixels as much as possible.
291 /* set default positioning */
293 cvtl_stem_width_function
,
297 /* %d, either bci_smooth_stem_width or bci_strong_stem_width */
299 unsigned char PREP(set_stem_width_handling_b
) [] =
304 /* get rasterizer version (bit 0) */
310 /* `GDI ClearType': */
311 /* version >= 36 and version < 38, ClearType enabled */
314 /* check whether ClearType is enabled (bit 6) */
320 cvtl_stem_width_function
,
323 /* %d, either bci_smooth_stem_width or bci_strong_stem_width */
325 unsigned char PREP(set_stem_width_handling_c
) [] =
330 /* get rasterizer version (bit 0) */
336 /* `DW ClearType': */
337 /* version >= 38, sub-pixel positioning is enabled */
340 /* check whether sub-pixel positioning is enabled (bit 10) */
347 cvtl_stem_width_function
,
351 /* %d, either bci_smooth_stem_width or bci_strong_stem_width */
353 unsigned char PREP(set_stem_width_handling_d
) [] =
364 unsigned char PREP(set_dropout_mode
) [] =
368 0x01, /* 0x01FF, activate dropout handling unconditionally */
372 4, /* smart dropout include stubs */
377 unsigned char PREP(reset_component_counter
) [] =
380 /* In case an application tries to render `.ttfautohint' */
381 /* (which it should never do), */
382 /* hinting of all glyphs rendered afterwards is disabled */
383 /* because the `cvtl_is_subglyph' counter gets incremented, */
384 /* but there is no counterpart to decrement it. */
385 /* Font inspection tools like the FreeType demo programs */
386 /* are an exception to that rule, however, */
387 /* since they can directly access a font by glyph indices. */
388 /* The following guard alleviates the problem a bit: */
389 /* Any change of the graphics state */
390 /* (for example, rendering at a different size or with a different mode) */
391 /* resets the counter to zero. */
400 /* this function allocates `buf', parsing `number_set' to create bytecode */
401 /* which eventually sets CVT index `cvtl_is_element' */
402 /* (in functions `bci_number_set_is_element' and */
403 /* `bci_number_set_is_element2') */
406 TA_sfnt_build_number_set(SFNT
* sfnt
,
408 number_range
* number_set
)
410 FT_Byte
* bufp
= NULL
;
413 FT_UInt num_singles2
= 0;
414 FT_UInt
* single2_args
;
415 FT_UInt
* single2_arg
;
416 FT_UInt num_singles
= 0;
417 FT_UInt
* single_args
;
420 FT_UInt num_ranges2
= 0;
421 FT_UInt
* range2_args
;
423 FT_UInt num_ranges
= 0;
427 FT_UInt have_single
= 0;
428 FT_UInt have_range
= 0;
430 FT_UShort num_stack_elements
;
433 /* build up four stacks to stay as compact as possible */
437 if (nr
->start
== nr
->end
)
446 if (nr
->start
< 256 && nr
->end
< 256)
454 /* collect all arguments temporarily in arrays (in reverse order) */
455 /* so that we can easily split into chunks of 255 args */
456 /* as needed by NPUSHB and friends; */
457 /* for simplicity, always allocate an extra slot */
458 single2_args
= (FT_UInt
*)malloc((num_singles2
+ 1) * sizeof (FT_UInt
));
459 single_args
= (FT_UInt
*)malloc((num_singles
+ 1) * sizeof (FT_UInt
));
460 range2_args
= (FT_UInt
*)malloc((2 * num_ranges2
+ 1) * sizeof (FT_UInt
));
461 range_args
= (FT_UInt
*)malloc((2 * num_ranges
+ 1) * sizeof (FT_UInt
));
462 if (!single2_args
|| !single_args
463 || !range2_args
|| !range_args
)
466 /* check whether we need the extra slot for the argument to CALL */
467 if (num_singles
|| num_singles2
)
469 if (num_ranges
|| num_ranges2
)
472 /* set function indices outside of argument loop (using the extra slot) */
474 single_args
[num_singles
] = bci_number_set_is_element
;
476 range_args
[2 * num_ranges
] = bci_number_set_is_element2
;
478 single2_arg
= single2_args
+ num_singles2
- 1;
479 single_arg
= single_args
+ num_singles
- 1;
480 range2_arg
= range2_args
+ 2 * num_ranges2
- 1;
481 range_arg
= range_args
+ 2 * num_ranges
- 1;
486 if (nr
->start
== nr
->end
)
489 *(single_arg
--) = nr
->start
;
491 *(single2_arg
--) = nr
->start
;
495 if (nr
->start
< 256 && nr
->end
< 256)
497 *(range_arg
--) = nr
->start
;
498 *(range_arg
--) = nr
->end
;
502 *(range2_arg
--) = nr
->start
;
503 *(range2_arg
--) = nr
->end
;
509 /* this rough estimate of the buffer size gets adjusted later on */
510 *buf
= (FT_Byte
*)malloc((2 + 1) * num_singles2
511 + (1 + 1) * num_singles
512 + (4 + 1) * num_ranges2
513 + (2 + 1) * num_ranges
520 BCI(cvtl_is_element
);
524 bufp
= TA_build_push(bufp
, single2_args
, num_singles2
, 1, 1);
525 bufp
= TA_build_push(bufp
, single_args
, num_singles
+ have_single
, 0, 1);
529 bufp
= TA_build_push(bufp
, range2_args
, 2 * num_ranges2
, 1, 1);
530 bufp
= TA_build_push(bufp
, range_args
, 2 * num_ranges
+ have_range
, 0, 1);
534 num_stack_elements
= num_singles
+ num_singles2
;
535 if (num_stack_elements
> num_ranges
+ num_ranges2
)
536 num_stack_elements
= num_ranges
+ num_ranges2
;
537 num_stack_elements
+= ADDITIONAL_STACK_ELEMENTS
;
538 if (num_stack_elements
> sfnt
->max_stack_elements
)
539 sfnt
->max_stack_elements
= num_stack_elements
;
551 #define COPY_PREP(snippet_name) \
554 memcpy(buf_p, prep_ ## snippet_name, \
555 sizeof (prep_ ## snippet_name)); \
556 buf_p += sizeof (prep_ ## snippet_name); \
560 TA_table_build_prep(FT_Byte
** prep
,
566 TA_LatinBlue blue_adjustment
= NULL
;
575 FT_Byte
* buf_p
= NULL
;
578 if (font
->loader
->hints
.metrics
->script_class
->script
== TA_SCRIPT_NONE
)
582 vaxis
= &((TA_LatinMetrics
)font
->loader
->hints
.metrics
)->axis
[1];
584 for (i
= 0; i
< vaxis
->blue_count
; i
++)
586 if (vaxis
->blues
[i
].flags
& TA_LATIN_BLUE_ADJUSTMENT
)
588 blue_adjustment
= &vaxis
->blues
[i
];
594 if (blue_adjustment
&& font
->x_height_snapping_exceptions
)
596 buf_p
= TA_sfnt_build_number_set(sfnt
, &buf
,
597 font
->x_height_snapping_exceptions
);
599 return FT_Err_Out_Of_Memory
;
602 buf_len
= buf_p
- buf
;
603 buf_new_len
= buf_len
;
605 if (font
->hinting_limit
)
606 buf_new_len
+= sizeof (PREP(hinting_limit_a
))
608 + sizeof (PREP(hinting_limit_b
));
610 buf_new_len
+= sizeof (PREP(store_0x10000
));
614 if (font
->x_height_snapping_exceptions
)
615 buf_new_len
+= sizeof (PREP(test_exception_a
));
616 buf_new_len
+= sizeof (PREP(align_top_a
))
618 + sizeof (PREP(align_top_b
))
619 + (font
->increase_x_height
620 ? (sizeof (PREP(align_top_c1a
))
622 + sizeof (PREP(align_top_c1b
)))
623 : sizeof (PREP(align_top_c2
)))
624 + sizeof (PREP(align_top_d
))
625 + sizeof (PREP(loop_cvt_a
))
627 + sizeof (PREP(loop_cvt_b
))
629 + sizeof (PREP(loop_cvt_c
))
631 + sizeof (PREP(loop_cvt_d
));
632 if (font
->x_height_snapping_exceptions
)
633 buf_new_len
+= sizeof (PREP(test_exception_b
));
636 buf_new_len
+= sizeof (PREP(compute_extra_light_a
))
638 + sizeof (PREP(compute_extra_light_b
));
640 if (CVT_BLUES_SIZE(font
))
641 buf_new_len
+= sizeof (PREP(round_blues_a
))
643 + sizeof (PREP(round_blues_b
));
645 buf_new_len
+= sizeof (PREP(set_stem_width_handling_a
))
647 + sizeof (PREP(set_stem_width_handling_b
))
649 + sizeof (PREP(set_stem_width_handling_c
))
651 + sizeof (PREP(set_stem_width_handling_d
));
652 buf_new_len
+= sizeof (PREP(set_dropout_mode
));
653 buf_new_len
+= sizeof (PREP(reset_component_counter
));
655 /* buffer length must be a multiple of four */
656 len
= (buf_new_len
+ 3) & ~3;
657 buf_new
= (FT_Byte
*)realloc(buf
, len
);
661 return FT_Err_Out_Of_Memory
;
665 /* pad end of buffer with zeros */
670 /* copy remaining cvt program into buffer */
671 /* and fill in the missing variables */
672 buf_p
= buf
+ buf_len
;
674 if (font
->hinting_limit
)
676 COPY_PREP(hinting_limit_a
);
677 *(buf_p
++) = HIGH(font
->hinting_limit
);
678 *(buf_p
++) = LOW(font
->hinting_limit
);
679 COPY_PREP(hinting_limit_b
);
682 COPY_PREP(store_0x10000
);
686 if (font
->x_height_snapping_exceptions
)
687 COPY_PREP(test_exception_a
);
689 COPY_PREP(align_top_a
);
690 *(buf_p
++) = (unsigned char)(CVT_BLUE_SHOOTS_OFFSET(font
)
691 + blue_adjustment
- vaxis
->blues
);
692 COPY_PREP(align_top_b
);
693 if (font
->increase_x_height
)
695 COPY_PREP(align_top_c1a
);
696 *(buf_p
++) = HIGH(font
->increase_x_height
);
697 *(buf_p
++) = LOW(font
->increase_x_height
);
698 COPY_PREP(align_top_c1b
);
701 COPY_PREP(align_top_c2
);
702 COPY_PREP(align_top_d
);
704 COPY_PREP(loop_cvt_a
);
705 *(buf_p
++) = (unsigned char)CVT_VERT_WIDTHS_OFFSET(font
);
706 *(buf_p
++) = (unsigned char)CVT_VERT_WIDTHS_SIZE(font
);
707 /* don't loop over the artificial blue zones */
708 COPY_PREP(loop_cvt_b
);
709 *(buf_p
++) = (unsigned char)CVT_BLUE_REFS_OFFSET(font
);
710 *(buf_p
++) = (unsigned char)(CVT_BLUES_SIZE(font
) - 2);
711 COPY_PREP(loop_cvt_c
);
712 *(buf_p
++) = (unsigned char)CVT_BLUE_SHOOTS_OFFSET(font
);
713 *(buf_p
++) = (unsigned char)(CVT_BLUES_SIZE(font
) - 2);
714 COPY_PREP(loop_cvt_d
);
716 if (font
->x_height_snapping_exceptions
)
717 COPY_PREP(test_exception_b
);
720 COPY_PREP(compute_extra_light_a
);
721 *(buf_p
++) = (unsigned char)CVT_VERT_STANDARD_WIDTH_OFFSET(font
);
722 COPY_PREP(compute_extra_light_b
);
724 if (CVT_BLUES_SIZE(font
))
726 COPY_PREP(round_blues_a
);
727 *(buf_p
++) = (unsigned char)CVT_BLUE_REFS_OFFSET(font
);
728 *(buf_p
++) = (unsigned char)CVT_BLUES_SIZE(font
);
729 COPY_PREP(round_blues_b
);
732 COPY_PREP(set_stem_width_handling_a
);
733 *(buf_p
++) = font
->gray_strong_stem_width
? bci_strong_stem_width
734 : bci_smooth_stem_width
;
735 COPY_PREP(set_stem_width_handling_b
);
736 *(buf_p
++) = font
->gdi_cleartype_strong_stem_width
? bci_strong_stem_width
737 : bci_smooth_stem_width
;
738 COPY_PREP(set_stem_width_handling_c
);
739 *(buf_p
++) = font
->dw_cleartype_strong_stem_width
? bci_strong_stem_width
740 : bci_smooth_stem_width
;
741 COPY_PREP(set_stem_width_handling_d
);
742 COPY_PREP(set_dropout_mode
);
743 COPY_PREP(reset_component_counter
);
746 *prep_len
= buf_new_len
;
753 TA_sfnt_build_prep_table(SFNT
* sfnt
,
758 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
759 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
765 error
= TA_sfnt_add_table_info(sfnt
);
769 /* `glyf', `cvt', `fpgm', and `prep' are always used in parallel */
770 if (glyf_table
->processed
)
772 sfnt
->table_infos
[sfnt
->num_table_infos
- 1] = data
->prep_idx
;
776 error
= TA_table_build_prep(&prep_buf
, &prep_len
, sfnt
, font
);
781 /* ttfautohint's bytecode in `fpgm' is larger */
782 /* than the bytecode in `prep'; */
783 /* this commented out code here is just for completeness */
784 if (prep_len
> sfnt
->max_instructions
)
785 sfnt
->max_instructions
= prep_len
;
788 /* in case of success, `prep_buf' gets linked */
789 /* and is eventually freed in `TA_font_unload' */
790 error
= TA_font_add_table(font
,
791 &sfnt
->table_infos
[sfnt
->num_table_infos
- 1],
792 TTAG_prep
, prep_len
, prep_buf
);
796 data
->prep_idx
= sfnt
->table_infos
[sfnt
->num_table_infos
- 1];
802 /* end of taprep.c */