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(align_top_a
) [] =
79 /* optimize the alignment of the top of small letters to the pixel grid */
85 /* %c, index of alignment blue zone */
87 unsigned char PREP(align_top_b
) [] =
96 unsigned char PREP(align_top_c1a
) [] =
99 /* use this if option `increase_x_height' > 0 */
100 /* apply much `stronger' rounding up of x height for */
101 /* 6 <= PPEM <= increase_x_height */
107 /* %d, x height increase limit */
109 unsigned char PREP(align_top_c1b
) [] =
120 52, /* threshold = 52 */
124 40, /* threshold = 40 */
128 FLOOR
, /* fitted = FLOOR(scaled + threshold) */
132 unsigned char PREP(align_top_c2
) [] =
138 FLOOR
, /* fitted = FLOOR(scaled + 40) */
142 unsigned char PREP(align_top_d
) [] =
145 DUP
, /* s: scaled scaled fitted fitted */
148 IF
, /* s: scaled fitted */
152 SUB
, /* s: scaled (fitted-scaled) */
156 MUL
, /* (fitted-scaled) in 16.16 format */
158 DIV
, /* ((fitted-scaled) / scaled) in 16.16 format */
167 unsigned char PREP(loop_cvt_a
) [] =
170 /* loop over vertical CVT entries */
175 /* %c, first vertical index */
176 /* %c, last vertical index */
178 unsigned char PREP(loop_cvt_b
) [] =
185 /* loop over blue refs */
190 /* %c, first blue ref index */
191 /* %c, last blue ref index */
193 unsigned char PREP(loop_cvt_c
) [] =
200 /* loop over blue shoots */
205 /* %c, first blue shoot index */
206 /* %c, last blue shoot index */
208 unsigned char PREP(loop_cvt_d
) [] =
218 unsigned char PREP(compute_extra_light_a
) [] =
221 /* compute (vertical) `extra_light' flag */
228 /* %c, index of vertical standard_width */
230 unsigned char PREP(compute_extra_light_b
) [] =
234 GT
, /* standard_width < 40 */
239 unsigned char PREP(round_blues_a
) [] =
242 /* use discrete values for blue zone widths */
247 /* %c, first blue ref index */
248 /* %c, last blue ref index */
250 unsigned char PREP(round_blues_b
) [] =
259 unsigned char PREP(set_stem_width_handling_a
) [] =
263 * There are two ClearType flavours available on Windows: The older GDI
264 * ClearType, introduced in 2000, and the recent DW ClearType, introduced
265 * in 2008. The main difference is that the older incarnation behaves
266 * like a B/W renderer along the y axis, while the newer version does
267 * vertical smoothing also.
269 * The only possibility to differentiate between GDI and DW ClearType is
270 * testing bit 10 in the GETINFO instruction (with return value in bit 17;
271 * this works for TrueType version >= 38), checking whether sub-pixel
272 * positioning is available.
274 * If GDI ClearType is active, we use a different stem width function
275 * which snaps to integer pixels as much as possible.
278 /* set default positioning */
280 cvtl_stem_width_function
,
284 /* %d, either bci_smooth_stem_width or bci_strong_stem_width */
286 unsigned char PREP(set_stem_width_handling_b
) [] =
291 /* get rasterizer version (bit 0) */
297 /* `GDI ClearType': */
298 /* version >= 36 and version < 38, ClearType enabled */
301 /* check whether ClearType is enabled (bit 6) */
307 cvtl_stem_width_function
,
310 /* %d, either bci_smooth_stem_width or bci_strong_stem_width */
312 unsigned char PREP(set_stem_width_handling_c
) [] =
317 /* get rasterizer version (bit 0) */
323 /* `DW ClearType': */
324 /* version >= 38, sub-pixel positioning is enabled */
327 /* check whether sub-pixel positioning is enabled (bit 10) */
334 cvtl_stem_width_function
,
338 /* %d, either bci_smooth_stem_width or bci_strong_stem_width */
340 unsigned char PREP(set_stem_width_handling_d
) [] =
351 unsigned char PREP(set_dropout_mode
) [] =
355 0x01, /* 0x01FF, activate dropout handling unconditionally */
359 4, /* smart dropout include stubs */
364 unsigned char PREP(reset_component_counter
) [] =
367 /* In case an application tries to render `.ttfautohint' */
368 /* (which it should never do), */
369 /* hinting of all glyphs rendered afterwards is disabled */
370 /* because the `cvtl_is_subglyph' counter gets incremented, */
371 /* but there is no counterpart to decrement it. */
372 /* Font inspection tools like the FreeType demo programs */
373 /* are an exception to that rule, however, */
374 /* since they can directly access a font by glyph indices. */
375 /* The following guard alleviates the problem a bit: */
376 /* Any change of the graphics state */
377 /* (for example, rendering at a different size or with a different mode) */
378 /* resets the counter to zero. */
387 #define COPY_PREP(snippet_name) \
390 memcpy(buf_p, prep_ ## snippet_name, \
391 sizeof (prep_ ## snippet_name)); \
392 buf_p += sizeof (prep_ ## snippet_name); \
396 TA_table_build_prep(FT_Byte
** prep
,
401 TA_LatinBlue blue_adjustment
= NULL
;
410 if (font
->loader
->hints
.metrics
->clazz
->script
== TA_SCRIPT_NONE
)
414 vaxis
= &((TA_LatinMetrics
)font
->loader
->hints
.metrics
)->axis
[1];
416 for (i
= 0; i
< vaxis
->blue_count
; i
++)
418 if (vaxis
->blues
[i
].flags
& TA_LATIN_BLUE_ADJUSTMENT
)
420 blue_adjustment
= &vaxis
->blues
[i
];
426 if (font
->hinting_limit
)
427 buf_len
+= sizeof (PREP(hinting_limit_a
))
429 + sizeof (PREP(hinting_limit_b
));
431 buf_len
+= sizeof (PREP(store_0x10000
));
434 buf_len
+= sizeof (PREP(align_top_a
))
436 + sizeof (PREP(align_top_b
))
437 + (font
->increase_x_height
? (sizeof (PREP(align_top_c1a
))
439 + sizeof (PREP(align_top_c1b
)))
440 : sizeof (PREP(align_top_c2
)))
441 + sizeof (PREP(align_top_d
))
442 + sizeof (PREP(loop_cvt_a
))
444 + sizeof (PREP(loop_cvt_b
))
446 + sizeof (PREP(loop_cvt_c
))
448 + sizeof (PREP(loop_cvt_d
));
450 buf_len
+= sizeof (PREP(compute_extra_light_a
))
452 + sizeof (PREP(compute_extra_light_b
));
454 if (CVT_BLUES_SIZE(font
))
455 buf_len
+= sizeof (PREP(round_blues_a
))
457 + sizeof (PREP(round_blues_b
));
459 buf_len
+= sizeof (PREP(set_stem_width_handling_a
))
461 + sizeof (PREP(set_stem_width_handling_b
))
463 + sizeof (PREP(set_stem_width_handling_c
))
465 + sizeof (PREP(set_stem_width_handling_d
));
466 buf_len
+= sizeof (PREP(set_dropout_mode
));
467 buf_len
+= sizeof (PREP(reset_component_counter
));
469 /* buffer length must be a multiple of four */
470 len
= (buf_len
+ 3) & ~3;
471 buf
= (FT_Byte
*)malloc(len
);
473 return FT_Err_Out_Of_Memory
;
475 /* pad end of buffer with zeros */
480 /* copy cvt program into buffer and fill in the missing variables */
483 if (font
->hinting_limit
)
485 COPY_PREP(hinting_limit_a
);
486 *(buf_p
++) = HIGH(font
->hinting_limit
);
487 *(buf_p
++) = LOW(font
->hinting_limit
);
488 COPY_PREP(hinting_limit_b
);
491 COPY_PREP(store_0x10000
);
495 COPY_PREP(align_top_a
);
496 *(buf_p
++) = (unsigned char)(CVT_BLUE_SHOOTS_OFFSET(font
)
497 + blue_adjustment
- vaxis
->blues
);
498 COPY_PREP(align_top_b
);
499 if (font
->increase_x_height
)
501 COPY_PREP(align_top_c1a
);
502 *(buf_p
++) = HIGH(font
->increase_x_height
);
503 *(buf_p
++) = LOW(font
->increase_x_height
);
504 COPY_PREP(align_top_c1b
);
507 COPY_PREP(align_top_c2
);
508 COPY_PREP(align_top_d
);
510 COPY_PREP(loop_cvt_a
);
511 *(buf_p
++) = (unsigned char)CVT_VERT_WIDTHS_OFFSET(font
);
512 *(buf_p
++) = (unsigned char)(CVT_VERT_WIDTHS_OFFSET(font
)
513 + CVT_VERT_WIDTHS_SIZE(font
) - 1);
514 /* don't loop over the artificial blue zones */
515 COPY_PREP(loop_cvt_b
);
516 *(buf_p
++) = (unsigned char)CVT_BLUE_REFS_OFFSET(font
);
517 *(buf_p
++) = (unsigned char)(CVT_BLUE_REFS_OFFSET(font
)
518 + CVT_BLUES_SIZE(font
) - 1 - 2);
519 COPY_PREP(loop_cvt_c
);
520 *(buf_p
++) = (unsigned char)CVT_BLUE_SHOOTS_OFFSET(font
);
521 *(buf_p
++) = (unsigned char)(CVT_BLUE_SHOOTS_OFFSET(font
)
522 + CVT_BLUES_SIZE(font
) - 1 - 2);
523 COPY_PREP(loop_cvt_d
);
526 COPY_PREP(compute_extra_light_a
);
527 *(buf_p
++) = (unsigned char)CVT_VERT_STANDARD_WIDTH_OFFSET(font
);
528 COPY_PREP(compute_extra_light_b
);
530 if (CVT_BLUES_SIZE(font
))
532 COPY_PREP(round_blues_a
);
533 *(buf_p
++) = (unsigned char)CVT_BLUE_REFS_OFFSET(font
);
534 *(buf_p
++) = (unsigned char)(CVT_BLUE_REFS_OFFSET(font
)
535 + CVT_BLUES_SIZE(font
) - 1);
536 COPY_PREP(round_blues_b
);
539 COPY_PREP(set_stem_width_handling_a
);
540 *(buf_p
++) = font
->gray_strong_stem_width
? bci_strong_stem_width
541 : bci_smooth_stem_width
;
542 COPY_PREP(set_stem_width_handling_b
);
543 *(buf_p
++) = font
->gdi_cleartype_strong_stem_width
? bci_strong_stem_width
544 : bci_smooth_stem_width
;
545 COPY_PREP(set_stem_width_handling_c
);
546 *(buf_p
++) = font
->dw_cleartype_strong_stem_width
? bci_strong_stem_width
547 : bci_smooth_stem_width
;
548 COPY_PREP(set_stem_width_handling_d
);
549 COPY_PREP(set_dropout_mode
);
550 COPY_PREP(reset_component_counter
);
560 TA_sfnt_build_prep_table(SFNT
* sfnt
,
563 FT_Error error
= FT_Err_Ok
;
565 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
566 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
572 error
= TA_sfnt_add_table_info(sfnt
);
576 /* `glyf', `cvt', `fpgm', and `prep' are always used in parallel */
577 if (glyf_table
->processed
)
579 sfnt
->table_infos
[sfnt
->num_table_infos
- 1] = data
->prep_idx
;
583 error
= TA_table_build_prep(&prep_buf
, &prep_len
, font
);
588 /* ttfautohint's bytecode in `fpgm' is larger */
589 /* than the bytecode in `prep'; */
590 /* this commented out code here is just for completeness */
591 if (prep_len
> sfnt
->max_instructions
)
592 sfnt
->max_instructions
= prep_len
;
595 /* in case of success, `prep_buf' gets linked */
596 /* and is eventually freed in `TA_font_unload' */
597 error
= TA_font_add_table(font
,
598 &sfnt
->table_infos
[sfnt
->num_table_infos
- 1],
599 TTAG_prep
, prep_len
, prep_buf
);
603 data
->prep_idx
= sfnt
->table_infos
[sfnt
->num_table_infos
- 1];
609 /* end of taprep.c */