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
) [] = {
43 cvtl_funits_to_pixels
,
45 WCVTF
, /* store value 1 in 16.16 format, scaled */
49 unsigned char PREP(align_top_a
) [] = {
51 /* optimize the alignment of the top of small letters to the pixel grid */
57 /* %c, index of alignment blue zone */
59 unsigned char PREP(align_top_b
) [] = {
67 FLOOR
, /* fitted = FLOOR(scaled + 40) */
68 DUP
, /* s: scaled scaled fitted fitted */
71 IF
, /* s: scaled fitted */
75 SUB
, /* s: scaled (fitted-scaled) */
79 MUL
, /* (fitted-scaled) in 16.16 format */
81 DIV
, /* ((fitted-scaled) / scaled) in 16.16 format */
90 unsigned char PREP(loop_cvt_a
) [] = {
92 /* loop over vertical CVT entries */
97 /* %c, first vertical index */
98 /* %c, last vertical index */
100 unsigned char PREP(loop_cvt_b
) [] = {
106 /* loop over blue refs */
111 /* %c, first blue ref index */
112 /* %c, last blue ref index */
114 unsigned char PREP(loop_cvt_c
) [] = {
120 /* loop over blue shoots */
125 /* %c, first blue shoot index */
126 /* %c, last blue shoot index */
128 unsigned char PREP(loop_cvt_d
) [] = {
137 unsigned char PREP(compute_extra_light_a
) [] = {
139 /* compute (vertical) `extra_light' flag */
146 /* %c, index of vertical standard_width */
148 unsigned char PREP(compute_extra_light_b
) [] = {
151 GT
, /* standard_width < 40 */
156 unsigned char PREP(round_blues_a
) [] = {
158 /* use discrete values for blue zone widths */
163 /* %c, first blue ref index */
164 /* %c, last blue ref index */
166 unsigned char PREP(round_blues_b
) [] = {
174 unsigned char PREP(set_dropout_mode
) [] = {
177 0x01, /* 0x01FF, activate dropout handling unconditionally */
181 4, /* smart dropout include stubs */
186 unsigned char PREP(reset_component_counter
) [] = {
188 /* In case an application tries to render `.ttfautohint' */
189 /* (which it should never do), */
190 /* hinting of all glyphs rendered afterwards is disabled */
191 /* because the `cvtl_is_subglyph' counter gets incremented, */
192 /* but there is no counterpart to decrement it. */
193 /* Font inspection tools like the FreeType demo programs */
194 /* are an exception to that rule, however, */
195 /* since they can directly access a font by glyph indices. */
196 /* The following guard alleviates the problem a bit: */
197 /* Any change of the graphics state */
198 /* (for example, rendering at a different size or with a different mode) */
199 /* resets the counter to zero. */
208 #define COPY_PREP(snippet_name) \
209 memcpy(buf_p, prep_ ## snippet_name, \
210 sizeof (prep_ ## snippet_name)); \
211 buf_p += sizeof (prep_ ## snippet_name);
214 TA_table_build_prep(FT_Byte
** prep
,
219 TA_LatinBlue blue_adjustment
;
228 vaxis
= &((TA_LatinMetrics
)font
->loader
->hints
.metrics
)->axis
[1];
229 blue_adjustment
= NULL
;
231 for (i
= 0; i
< vaxis
->blue_count
; i
++)
233 if (vaxis
->blues
[i
].flags
& TA_LATIN_BLUE_ADJUSTMENT
)
235 blue_adjustment
= &vaxis
->blues
[i
];
240 buf_len
= sizeof (PREP(store_0x10000
));
243 buf_len
+= sizeof (PREP(align_top_a
))
245 + sizeof (PREP(align_top_b
))
246 + sizeof (PREP(loop_cvt_a
))
248 + sizeof (PREP(loop_cvt_b
))
250 + sizeof (PREP(loop_cvt_c
))
252 + sizeof (PREP(loop_cvt_d
));
254 buf_len
+= sizeof (PREP(compute_extra_light_a
))
256 + sizeof (PREP(compute_extra_light_b
));
258 if (CVT_BLUES_SIZE(font
))
259 buf_len
+= sizeof (PREP(round_blues_a
))
261 + sizeof (PREP(round_blues_b
));
263 buf_len
+= sizeof (PREP(set_dropout_mode
));
264 buf_len
+= sizeof (PREP(reset_component_counter
));
266 /* buffer length must be a multiple of four */
267 len
= (buf_len
+ 3) & ~3;
268 buf
= (FT_Byte
*)malloc(len
);
270 return FT_Err_Out_Of_Memory
;
272 /* pad end of buffer with zeros */
277 /* copy cvt program into buffer and fill in the missing variables */
280 COPY_PREP(store_0x10000
);
284 COPY_PREP(align_top_a
);
285 *(buf_p
++) = (unsigned char)(CVT_BLUE_SHOOTS_OFFSET(font
)
286 + blue_adjustment
- vaxis
->blues
);
287 COPY_PREP(align_top_b
);
289 COPY_PREP(loop_cvt_a
);
290 *(buf_p
++) = (unsigned char)CVT_VERT_WIDTHS_OFFSET(font
);
291 *(buf_p
++) = (unsigned char)(CVT_VERT_WIDTHS_OFFSET(font
)
292 + CVT_VERT_WIDTHS_SIZE(font
) - 1);
293 COPY_PREP(loop_cvt_b
);
294 *(buf_p
++) = (unsigned char)CVT_BLUE_REFS_OFFSET(font
);
295 *(buf_p
++) = (unsigned char)(CVT_BLUE_REFS_OFFSET(font
)
296 + CVT_BLUES_SIZE(font
) - 1);
297 COPY_PREP(loop_cvt_c
);
298 *(buf_p
++) = (unsigned char)CVT_BLUE_SHOOTS_OFFSET(font
);
299 *(buf_p
++) = (unsigned char)(CVT_BLUE_SHOOTS_OFFSET(font
)
300 + CVT_BLUES_SIZE(font
) - 1);
301 COPY_PREP(loop_cvt_d
);
304 COPY_PREP(compute_extra_light_a
);
305 *(buf_p
++) = (unsigned char)CVT_VERT_STANDARD_WIDTH_OFFSET(font
);
306 COPY_PREP(compute_extra_light_b
);
308 if (CVT_BLUES_SIZE(font
))
310 COPY_PREP(round_blues_a
);
311 *(buf_p
++) = (unsigned char)CVT_BLUE_REFS_OFFSET(font
);
312 *(buf_p
++) = (unsigned char)(CVT_BLUE_REFS_OFFSET(font
)
313 + CVT_BLUES_SIZE(font
) - 1);
314 COPY_PREP(round_blues_b
);
317 COPY_PREP(set_dropout_mode
);
318 COPY_PREP(reset_component_counter
);
328 TA_sfnt_build_prep_table(SFNT
* sfnt
,
337 error
= TA_sfnt_add_table_info(sfnt
);
341 error
= TA_table_build_prep(&prep_buf
, &prep_len
, font
);
346 /* ttfautohint's bytecode in `fpgm' is larger */
347 /* than the bytecode in `prep'; */
348 /* this commented out code here is just for completeness */
349 if (prep_len
> sfnt
->max_instructions
)
350 sfnt
->max_instructions
= prep_len
;
353 /* in case of success, `prep_buf' gets linked */
354 /* and is eventually freed in `TA_font_unload' */
355 error
= TA_font_add_table(font
,
356 &sfnt
->table_infos
[sfnt
->num_table_infos
- 1],
357 TTAG_prep
, prep_len
, prep_buf
);
367 /* end of taprep.c */