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
21 /* we often need 0x10000 which can't be pushed directly onto the stack, */
22 /* thus we provide it in the CVT as `cvtl_0x10000'; */
23 /* at the same time, we store it in CVT index `cvtl_funits_to_pixels' also */
24 /* as a scaled value to have a conversion factor from FUnits to pixels */
26 unsigned char PREP(store_0x10000
) [] =
44 cvtl_funits_to_pixels
,
46 WCVTF
, /* store value 1 in 16.16 format, scaled */
50 unsigned char PREP(align_top_a
) [] =
53 /* optimize the alignment of the top of small letters to the pixel grid */
59 /* %c, index of alignment blue zone */
61 unsigned char PREP(align_top_b
) [] =
70 unsigned char PREP(align_top_c1
) [] =
73 /* this is for option `increase_x_height': */
74 /* apply much `stronger' rounding up of x height for 5 < PPEM < 15 */
86 52, /* threshold = 52 */
90 40, /* threshold = 40 */
94 FLOOR
, /* fitted = FLOOR(scaled + threshold) */
98 unsigned char PREP(align_top_c2
) [] =
104 FLOOR
, /* fitted = FLOOR(scaled + 40) */
108 unsigned char PREP(align_top_d
) [] =
111 DUP
, /* s: scaled scaled fitted fitted */
114 IF
, /* s: scaled fitted */
118 SUB
, /* s: scaled (fitted-scaled) */
122 MUL
, /* (fitted-scaled) in 16.16 format */
124 DIV
, /* ((fitted-scaled) / scaled) in 16.16 format */
133 unsigned char PREP(loop_cvt_a
) [] =
136 /* loop over vertical CVT entries */
141 /* %c, first vertical index */
142 /* %c, last vertical index */
144 unsigned char PREP(loop_cvt_b
) [] =
151 /* loop over blue refs */
156 /* %c, first blue ref index */
157 /* %c, last blue ref index */
159 unsigned char PREP(loop_cvt_c
) [] =
166 /* loop over blue shoots */
171 /* %c, first blue shoot index */
172 /* %c, last blue shoot index */
174 unsigned char PREP(loop_cvt_d
) [] =
184 unsigned char PREP(compute_extra_light_a
) [] =
187 /* compute (vertical) `extra_light' flag */
194 /* %c, index of vertical standard_width */
196 unsigned char PREP(compute_extra_light_b
) [] =
200 GT
, /* standard_width < 40 */
205 unsigned char PREP(round_blues_a
) [] =
208 /* use discrete values for blue zone widths */
213 /* %c, first blue ref index */
214 /* %c, last blue ref index */
216 unsigned char PREP(round_blues_b
) [] =
225 unsigned char PREP(set_dropout_mode
) [] =
229 0x01, /* 0x01FF, activate dropout handling unconditionally */
233 4, /* smart dropout include stubs */
238 unsigned char PREP(reset_component_counter
) [] =
241 /* In case an application tries to render `.ttfautohint' */
242 /* (which it should never do), */
243 /* hinting of all glyphs rendered afterwards is disabled */
244 /* because the `cvtl_is_subglyph' counter gets incremented, */
245 /* but there is no counterpart to decrement it. */
246 /* Font inspection tools like the FreeType demo programs */
247 /* are an exception to that rule, however, */
248 /* since they can directly access a font by glyph indices. */
249 /* The following guard alleviates the problem a bit: */
250 /* Any change of the graphics state */
251 /* (for example, rendering at a different size or with a different mode) */
252 /* resets the counter to zero. */
261 #define COPY_PREP(snippet_name) \
263 memcpy(buf_p, prep_ ## snippet_name, \
264 sizeof (prep_ ## snippet_name)); \
265 buf_p += sizeof (prep_ ## snippet_name); \
269 TA_table_build_prep(FT_Byte
** prep
,
274 TA_LatinBlue blue_adjustment
;
283 vaxis
= &((TA_LatinMetrics
)font
->loader
->hints
.metrics
)->axis
[1];
284 blue_adjustment
= NULL
;
286 for (i
= 0; i
< vaxis
->blue_count
; i
++)
288 if (vaxis
->blues
[i
].flags
& TA_LATIN_BLUE_ADJUSTMENT
)
290 blue_adjustment
= &vaxis
->blues
[i
];
295 buf_len
= sizeof (PREP(store_0x10000
));
298 buf_len
+= sizeof (PREP(align_top_a
))
300 + sizeof (PREP(align_top_b
))
301 + (font
->increase_x_height
? sizeof (PREP(align_top_c1
))
302 : sizeof (PREP(align_top_c2
)))
303 + sizeof (PREP(align_top_d
))
304 + sizeof (PREP(loop_cvt_a
))
306 + sizeof (PREP(loop_cvt_b
))
308 + sizeof (PREP(loop_cvt_c
))
310 + sizeof (PREP(loop_cvt_d
));
312 buf_len
+= sizeof (PREP(compute_extra_light_a
))
314 + sizeof (PREP(compute_extra_light_b
));
316 if (CVT_BLUES_SIZE(font
))
317 buf_len
+= sizeof (PREP(round_blues_a
))
319 + sizeof (PREP(round_blues_b
));
321 buf_len
+= sizeof (PREP(set_dropout_mode
));
322 buf_len
+= sizeof (PREP(reset_component_counter
));
324 /* buffer length must be a multiple of four */
325 len
= (buf_len
+ 3) & ~3;
326 buf
= (FT_Byte
*)malloc(len
);
328 return FT_Err_Out_Of_Memory
;
330 /* pad end of buffer with zeros */
335 /* copy cvt program into buffer and fill in the missing variables */
338 COPY_PREP(store_0x10000
);
342 COPY_PREP(align_top_a
);
343 *(buf_p
++) = (unsigned char)(CVT_BLUE_SHOOTS_OFFSET(font
)
344 + blue_adjustment
- vaxis
->blues
);
345 COPY_PREP(align_top_b
);
346 if (font
->increase_x_height
)
347 COPY_PREP(align_top_c1
);
349 COPY_PREP(align_top_c2
);
350 COPY_PREP(align_top_d
);
352 COPY_PREP(loop_cvt_a
);
353 *(buf_p
++) = (unsigned char)CVT_VERT_WIDTHS_OFFSET(font
);
354 *(buf_p
++) = (unsigned char)(CVT_VERT_WIDTHS_OFFSET(font
)
355 + CVT_VERT_WIDTHS_SIZE(font
) - 1);
356 COPY_PREP(loop_cvt_b
);
357 *(buf_p
++) = (unsigned char)CVT_BLUE_REFS_OFFSET(font
);
358 *(buf_p
++) = (unsigned char)(CVT_BLUE_REFS_OFFSET(font
)
359 + CVT_BLUES_SIZE(font
) - 1);
360 COPY_PREP(loop_cvt_c
);
361 *(buf_p
++) = (unsigned char)CVT_BLUE_SHOOTS_OFFSET(font
);
362 *(buf_p
++) = (unsigned char)(CVT_BLUE_SHOOTS_OFFSET(font
)
363 + CVT_BLUES_SIZE(font
) - 1);
364 COPY_PREP(loop_cvt_d
);
367 COPY_PREP(compute_extra_light_a
);
368 *(buf_p
++) = (unsigned char)CVT_VERT_STANDARD_WIDTH_OFFSET(font
);
369 COPY_PREP(compute_extra_light_b
);
371 if (CVT_BLUES_SIZE(font
))
373 COPY_PREP(round_blues_a
);
374 *(buf_p
++) = (unsigned char)CVT_BLUE_REFS_OFFSET(font
);
375 *(buf_p
++) = (unsigned char)(CVT_BLUE_REFS_OFFSET(font
)
376 + CVT_BLUES_SIZE(font
) - 1);
377 COPY_PREP(round_blues_b
);
380 COPY_PREP(set_dropout_mode
);
381 COPY_PREP(reset_component_counter
);
391 TA_sfnt_build_prep_table(SFNT
* sfnt
,
400 error
= TA_sfnt_add_table_info(sfnt
);
404 error
= TA_table_build_prep(&prep_buf
, &prep_len
, font
);
409 /* ttfautohint's bytecode in `fpgm' is larger */
410 /* than the bytecode in `prep'; */
411 /* this commented out code here is just for completeness */
412 if (prep_len
> sfnt
->max_instructions
)
413 sfnt
->max_instructions
= prep_len
;
416 /* in case of success, `prep_buf' gets linked */
417 /* and is eventually freed in `TA_font_unload' */
418 error
= TA_font_add_table(font
,
419 &sfnt
->table_infos
[sfnt
->num_table_infos
- 1],
420 TTAG_prep
, prep_len
, prep_buf
);
430 /* end of taprep.c */