4 * Copyright (C) 2011-2012 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
) [] =
70 cvtl_funits_to_pixels
,
72 WCVTF
, /* store value 1 in 16.16 format, scaled */
76 unsigned char PREP(test_exception_a
) [] =
87 unsigned char PREP(align_top_a
) [] =
90 /* optimize the alignment of the top of small letters to the pixel grid */
96 /* %c, index of alignment blue zone */
98 unsigned char PREP(align_top_b
) [] =
107 unsigned char PREP(align_top_c1a
) [] =
110 /* use this if option `increase_x_height' > 0 */
111 /* apply much `stronger' rounding up of x height for */
112 /* 6 <= PPEM <= increase_x_height */
118 /* %d, x height increase limit */
120 unsigned char PREP(align_top_c1b
) [] =
131 52, /* threshold = 52 */
135 40, /* threshold = 40 */
139 FLOOR
, /* fitted = FLOOR(scaled + threshold) */
143 unsigned char PREP(align_top_c2
) [] =
149 FLOOR
, /* fitted = FLOOR(scaled + 40) */
153 unsigned char PREP(align_top_d
) [] =
156 DUP
, /* s: scaled scaled fitted fitted */
159 IF
, /* s: scaled fitted */
163 SUB
, /* s: scaled (fitted-scaled) */
167 MUL
, /* (fitted-scaled) in 16.16 format */
169 DIV
, /* ((fitted-scaled) / scaled) in 16.16 format */
178 unsigned char PREP(loop_cvt_a
) [] =
181 /* loop over vertical CVT entries */
186 /* %c, first vertical index */
187 /* %c, last vertical index */
189 unsigned char PREP(loop_cvt_b
) [] =
196 /* loop over blue refs */
201 /* %c, first blue ref index */
202 /* %c, last blue ref index */
204 unsigned char PREP(loop_cvt_c
) [] =
211 /* loop over blue shoots */
216 /* %c, first blue shoot index */
217 /* %c, last blue shoot index */
219 unsigned char PREP(loop_cvt_d
) [] =
229 unsigned char PREP(test_exception_b
) [] =
236 unsigned char PREP(compute_extra_light_a
) [] =
239 /* compute (vertical) `extra_light' flag */
246 /* %c, index of vertical standard_width */
248 unsigned char PREP(compute_extra_light_b
) [] =
252 GT
, /* standard_width < 40 */
257 unsigned char PREP(round_blues_a
) [] =
260 /* use discrete values for blue zone widths */
265 /* %c, first blue ref index */
266 /* %c, last blue ref index */
268 unsigned char PREP(round_blues_b
) [] =
277 unsigned char PREP(set_stem_width_handling_a
) [] =
281 * There are two ClearType flavours available on Windows: The older GDI
282 * ClearType, introduced in 2000, and the recent DW ClearType, introduced
283 * in 2008. The main difference is that the older incarnation behaves
284 * like a B/W renderer along the y axis, while the newer version does
285 * vertical smoothing also.
287 * The only possibility to differentiate between GDI and DW ClearType is
288 * testing bit 10 in the GETINFO instruction (with return value in bit 17;
289 * this works for TrueType version >= 38), checking whether sub-pixel
290 * positioning is available.
292 * If GDI ClearType is active, we use a different stem width function
293 * which snaps to integer pixels as much as possible.
296 /* set default positioning */
298 cvtl_stem_width_function
,
302 /* %d, either bci_smooth_stem_width or bci_strong_stem_width */
304 unsigned char PREP(set_stem_width_handling_b
) [] =
309 /* get rasterizer version (bit 0) */
315 /* `GDI ClearType': */
316 /* version >= 36 and version < 38, ClearType enabled */
319 /* check whether ClearType is enabled (bit 6) */
325 cvtl_stem_width_function
,
328 /* %d, either bci_smooth_stem_width or bci_strong_stem_width */
330 unsigned char PREP(set_stem_width_handling_c
) [] =
335 /* get rasterizer version (bit 0) */
341 /* `DW ClearType': */
342 /* version >= 38, sub-pixel positioning is enabled */
345 /* check whether sub-pixel positioning is enabled (bit 10) */
352 cvtl_stem_width_function
,
356 /* %d, either bci_smooth_stem_width or bci_strong_stem_width */
358 unsigned char PREP(set_stem_width_handling_d
) [] =
369 unsigned char PREP(set_dropout_mode
) [] =
373 0x01, /* 0x01FF, activate dropout handling unconditionally */
377 4, /* smart dropout include stubs */
382 unsigned char PREP(reset_component_counter
) [] =
385 /* In case an application tries to render `.ttfautohint' */
386 /* (which it should never do), */
387 /* hinting of all glyphs rendered afterwards is disabled */
388 /* because the `cvtl_is_subglyph' counter gets incremented, */
389 /* but there is no counterpart to decrement it. */
390 /* Font inspection tools like the FreeType demo programs */
391 /* are an exception to that rule, however, */
392 /* since they can directly access a font by glyph indices. */
393 /* The following guard alleviates the problem a bit: */
394 /* Any change of the graphics state */
395 /* (for example, rendering at a different size or with a different mode) */
396 /* resets the counter to zero. */
405 /* this function allocates `buf', parsing `number_set' to create bytecode */
406 /* which eventually sets CVT index `cvtl_is_element' */
407 /* (in functions `bci_number_set_is_element' and */
408 /* `bci_number_set_is_element2') */
411 TA_sfnt_build_number_set(SFNT
* sfnt
,
413 number_range
* number_set
)
415 FT_Byte
* bufp
= NULL
;
418 FT_UInt num_singles2
= 0;
419 FT_UInt
* single2_args
;
420 FT_UInt
* single2_arg
;
421 FT_UInt num_singles
= 0;
422 FT_UInt
* single_args
;
425 FT_UInt num_ranges2
= 0;
426 FT_UInt
* range2_args
;
428 FT_UInt num_ranges
= 0;
432 FT_UInt have_single
= 0;
433 FT_UInt have_range
= 0;
435 FT_UShort num_stack_elements
;
438 /* build up four stacks to stay as compact as possible */
442 if (nr
->start
== nr
->end
)
451 if (nr
->start
< 256 && nr
->end
< 256)
459 /* collect all arguments temporarily in arrays (in reverse order) */
460 /* so that we can easily split into chunks of 255 args */
461 /* as needed by NPUSHB and friends; */
462 /* for simplicity, always allocate an extra slot */
463 single2_args
= (FT_UInt
*)malloc(num_singles2
* sizeof (FT_UInt
) + 1);
464 single_args
= (FT_UInt
*)malloc(num_singles
* sizeof (FT_UInt
) + 1);
465 range2_args
= (FT_UInt
*)malloc(2 * num_ranges2
* sizeof (FT_UInt
) + 1);
466 range_args
= (FT_UInt
*)malloc(2 * num_ranges
* sizeof (FT_UInt
) + 1);
467 if (!single2_args
|| !single_args
468 || !range2_args
|| !range_args
)
471 /* check whether we need the extra slot for the argument to CALL */
472 if (num_singles
|| num_singles2
)
474 if (num_ranges
|| num_ranges2
)
477 /* set function indices outside of argument loop (using the extra slot) */
479 single_args
[num_singles
] = bci_number_set_is_element
;
481 range_args
[num_singles
] = bci_number_set_is_element2
;
483 single2_arg
= single2_args
+ num_singles2
- 1;
484 single_arg
= single_args
+ num_singles
- 1;
485 range2_arg
= range2_args
+ num_ranges2
- 1;
486 range_arg
= range_args
+ num_ranges
- 1;
491 if (nr
->start
== nr
->end
)
494 *(single_arg
--) = nr
->start
;
496 *(single2_arg
--) = nr
->start
;
500 if (nr
->start
< 256 && nr
->end
< 256)
502 *(range_arg
--) = nr
->start
;
503 *(range_arg
--) = nr
->end
;
507 *(range2_arg
--) = nr
->start
;
508 *(range2_arg
--) = nr
->end
;
514 /* this rough estimate of the buffer size gets adjusted later on */
515 *buf
= (FT_Byte
*)malloc((2 + 1) * num_singles2
516 + (1 + 1) * num_singles
517 + (4 + 1) * num_ranges2
518 + (2 + 1) * num_ranges
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
, num_ranges2
, 1, 1);
530 bufp
= TA_build_push(bufp
, range_args
, 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
->clazz
->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_OFFSET(font
)
707 + CVT_VERT_WIDTHS_SIZE(font
) - 1);
708 /* don't loop over the artificial blue zones */
709 COPY_PREP(loop_cvt_b
);
710 *(buf_p
++) = (unsigned char)CVT_BLUE_REFS_OFFSET(font
);
711 *(buf_p
++) = (unsigned char)(CVT_BLUE_REFS_OFFSET(font
)
712 + CVT_BLUES_SIZE(font
) - 1 - 2);
713 COPY_PREP(loop_cvt_c
);
714 *(buf_p
++) = (unsigned char)CVT_BLUE_SHOOTS_OFFSET(font
);
715 *(buf_p
++) = (unsigned char)(CVT_BLUE_SHOOTS_OFFSET(font
)
716 + CVT_BLUES_SIZE(font
) - 1 - 2);
717 COPY_PREP(loop_cvt_d
);
719 if (font
->x_height_snapping_exceptions
)
720 COPY_PREP(test_exception_b
);
723 COPY_PREP(compute_extra_light_a
);
724 *(buf_p
++) = (unsigned char)CVT_VERT_STANDARD_WIDTH_OFFSET(font
);
725 COPY_PREP(compute_extra_light_b
);
727 if (CVT_BLUES_SIZE(font
))
729 COPY_PREP(round_blues_a
);
730 *(buf_p
++) = (unsigned char)CVT_BLUE_REFS_OFFSET(font
);
731 *(buf_p
++) = (unsigned char)(CVT_BLUE_REFS_OFFSET(font
)
732 + CVT_BLUES_SIZE(font
) - 1);
733 COPY_PREP(round_blues_b
);
736 COPY_PREP(set_stem_width_handling_a
);
737 *(buf_p
++) = font
->gray_strong_stem_width
? bci_strong_stem_width
738 : bci_smooth_stem_width
;
739 COPY_PREP(set_stem_width_handling_b
);
740 *(buf_p
++) = font
->gdi_cleartype_strong_stem_width
? bci_strong_stem_width
741 : bci_smooth_stem_width
;
742 COPY_PREP(set_stem_width_handling_c
);
743 *(buf_p
++) = font
->dw_cleartype_strong_stem_width
? bci_strong_stem_width
744 : bci_smooth_stem_width
;
745 COPY_PREP(set_stem_width_handling_d
);
746 COPY_PREP(set_dropout_mode
);
747 COPY_PREP(reset_component_counter
);
750 *prep_len
= buf_new_len
;
757 TA_sfnt_build_prep_table(SFNT
* sfnt
,
760 FT_Error error
= FT_Err_Ok
;
762 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
763 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
769 error
= TA_sfnt_add_table_info(sfnt
);
773 /* `glyf', `cvt', `fpgm', and `prep' are always used in parallel */
774 if (glyf_table
->processed
)
776 sfnt
->table_infos
[sfnt
->num_table_infos
- 1] = data
->prep_idx
;
780 error
= TA_table_build_prep(&prep_buf
, &prep_len
, sfnt
, font
);
785 /* ttfautohint's bytecode in `fpgm' is larger */
786 /* than the bytecode in `prep'; */
787 /* this commented out code here is just for completeness */
788 if (prep_len
> sfnt
->max_instructions
)
789 sfnt
->max_instructions
= prep_len
;
792 /* in case of success, `prep_buf' gets linked */
793 /* and is eventually freed in `TA_font_unload' */
794 error
= TA_font_add_table(font
,
795 &sfnt
->table_infos
[sfnt
->num_table_infos
- 1],
796 TTAG_prep
, prep_len
, prep_buf
);
800 data
->prep_idx
= sfnt
->table_infos
[sfnt
->num_table_infos
- 1];
806 /* end of taprep.c */