4 * Copyright (C) 2011 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 CVS 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
) [] = {
175 #define COPY_PREP(snippet_name) \
176 memcpy(buf_p, prep_ ## snippet_name, \
177 sizeof (prep_ ## snippet_name)); \
178 buf_p += sizeof (prep_ ## snippet_name);
181 TA_table_build_prep(FT_Byte
** prep
,
186 TA_LatinBlue blue_adjustment
;
195 vaxis
= &((TA_LatinMetrics
)font
->loader
->hints
.metrics
)->axis
[1];
196 blue_adjustment
= NULL
;
198 for (i
= 0; i
< vaxis
->blue_count
; i
++)
200 if (vaxis
->blues
[i
].flags
& TA_LATIN_BLUE_ADJUSTMENT
)
202 blue_adjustment
= &vaxis
->blues
[i
];
207 buf_len
= sizeof (PREP(store_0x10000
));
210 buf_len
+= sizeof (PREP(align_top_a
))
212 + sizeof (PREP(align_top_b
))
213 + sizeof (PREP(loop_cvt_a
))
215 + sizeof (PREP(loop_cvt_b
))
217 + sizeof (PREP(loop_cvt_c
))
219 + sizeof (PREP(loop_cvt_d
));
221 buf_len
+= sizeof (PREP(compute_extra_light_a
))
223 + sizeof (PREP(compute_extra_light_b
));
225 if (CVT_BLUES_SIZE(font
))
226 buf_len
+= sizeof (PREP(round_blues_a
))
228 + sizeof (PREP(round_blues_b
));
230 /* buffer length must be a multiple of four */
231 len
= (buf_len
+ 3) & ~3;
232 buf
= (FT_Byte
*)malloc(len
);
234 return FT_Err_Out_Of_Memory
;
236 /* pad end of buffer with zeros */
241 /* copy cvt program into buffer and fill in the missing variables */
244 COPY_PREP(store_0x10000
);
248 COPY_PREP(align_top_a
);
249 *(buf_p
++) = (unsigned char)(CVT_BLUE_SHOOTS_OFFSET(font
)
250 + blue_adjustment
- vaxis
->blues
);
251 COPY_PREP(align_top_b
);
253 COPY_PREP(loop_cvt_a
);
254 *(buf_p
++) = (unsigned char)CVT_VERT_WIDTHS_OFFSET(font
);
255 *(buf_p
++) = (unsigned char)(CVT_VERT_WIDTHS_OFFSET(font
)
256 + CVT_VERT_WIDTHS_SIZE(font
) - 1);
257 COPY_PREP(loop_cvt_b
);
258 *(buf_p
++) = (unsigned char)CVT_BLUE_REFS_OFFSET(font
);
259 *(buf_p
++) = (unsigned char)(CVT_BLUE_REFS_OFFSET(font
)
260 + CVT_BLUES_SIZE(font
) - 1);
261 COPY_PREP(loop_cvt_c
);
262 *(buf_p
++) = (unsigned char)CVT_BLUE_SHOOTS_OFFSET(font
);
263 *(buf_p
++) = (unsigned char)(CVT_BLUE_SHOOTS_OFFSET(font
)
264 + CVT_BLUES_SIZE(font
) - 1);
265 COPY_PREP(loop_cvt_d
);
268 COPY_PREP(compute_extra_light_a
);
269 *(buf_p
++) = (unsigned char)CVT_VERT_STANDARD_WIDTH_OFFSET(font
);
270 COPY_PREP(compute_extra_light_b
);
272 if (CVT_BLUES_SIZE(font
))
274 COPY_PREP(round_blues_a
);
275 *(buf_p
++) = (unsigned char)CVT_BLUE_REFS_OFFSET(font
);
276 *(buf_p
++) = (unsigned char)(CVT_BLUE_REFS_OFFSET(font
)
277 + CVT_BLUES_SIZE(font
) - 1);
278 COPY_PREP(round_blues_b
);
289 TA_sfnt_build_prep_table(SFNT
* sfnt
,
298 error
= TA_sfnt_add_table_info(sfnt
);
302 error
= TA_table_build_prep(&prep_buf
, &prep_len
, font
);
307 /* ttfautohint's bytecode in `fpgm' is larger */
308 /* than the bytecode in `prep'; */
309 /* this commented out code here is just for completeness */
310 if (prep_len
> sfnt
->max_instructions
)
311 sfnt
->max_instructions
= prep_len
;
314 /* in case of success, `prep_buf' gets linked */
315 /* and is eventually freed in `TA_font_unload' */
316 error
= TA_font_add_table(font
,
317 &sfnt
->table_infos
[sfnt
->num_table_infos
- 1],
318 TTAG_prep
, prep_len
, prep_buf
);
328 /* end of taprep.c */