Add NUMBERSET_NOT_ASCENDING error code.
[ttfautohint.git] / lib / taprep.c
blobfad4602f65e8d0adef80c54c09fc2ae5e62532c1
1 /* taprep.c */
3 /*
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.
16 #include "ta.h"
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 */
27 MPPEM,
28 PUSHW_1,
32 /* %d, hinting size limit */
34 unsigned char PREP(hinting_limit_b) [] =
37 GT,
38 IF,
39 PUSHB_2,
40 1, /* switch off hinting */
42 INSTCTRL,
43 EIF,
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) [] =
55 PUSHW_2,
56 0x08, /* 0x800 */
57 0x00,
58 0x08, /* 0x800 */
59 0x00,
60 MUL, /* 0x10000 */
62 DUP,
63 PUSHB_1,
64 cvtl_0x10000,
65 SWAP,
66 WCVTP,
68 DUP,
69 PUSHB_1,
70 cvtl_funits_to_pixels,
71 SWAP,
72 WCVTF, /* store value 1 in 16.16 format, scaled */
76 unsigned char PREP(test_exception_a) [] =
79 PUSHB_1,
80 cvtl_is_element,
81 RCVT,
82 NOT,
83 IF,
87 unsigned char PREP(align_top_a) [] =
90 /* optimize the alignment of the top of small letters to the pixel grid */
92 PUSHB_1,
96 /* %c, index of alignment blue zone */
98 unsigned char PREP(align_top_b) [] =
101 RCVT,
102 DUP,
103 DUP,
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 */
113 MPPEM,
114 PUSHW_1,
118 /* %d, x height increase limit */
120 unsigned char PREP(align_top_c1b) [] =
123 LTEQ,
124 MPPEM,
125 PUSHB_1,
127 GTEQ,
128 AND,
130 PUSHB_1,
131 52, /* threshold = 52 */
133 ELSE,
134 PUSHB_1,
135 40, /* threshold = 40 */
137 EIF,
138 ADD,
139 FLOOR, /* fitted = FLOOR(scaled + threshold) */
143 unsigned char PREP(align_top_c2) [] =
146 PUSHB_1,
148 ADD,
149 FLOOR, /* fitted = FLOOR(scaled + 40) */
153 unsigned char PREP(align_top_d) [] =
156 DUP, /* s: scaled scaled fitted fitted */
157 ROLL,
158 NEQ,
159 IF, /* s: scaled fitted */
160 PUSHB_1,
162 CINDEX,
163 SUB, /* s: scaled (fitted-scaled) */
164 PUSHB_1,
165 cvtl_0x10000,
166 RCVT,
167 MUL, /* (fitted-scaled) in 16.16 format */
168 SWAP,
169 DIV, /* ((fitted-scaled) / scaled) in 16.16 format */
171 PUSHB_1,
172 cvtl_scale,
173 SWAP,
174 WCVTP,
178 unsigned char PREP(loop_cvt_a) [] =
181 /* loop over vertical CVT entries */
182 PUSHB_4,
186 /* %c, first vertical index */
187 /* %c, last vertical index */
189 unsigned char PREP(loop_cvt_b) [] =
192 bci_cvt_rescale,
193 bci_loop,
194 CALL,
196 /* loop over blue refs */
197 PUSHB_4,
201 /* %c, first blue ref index */
202 /* %c, last blue ref index */
204 unsigned char PREP(loop_cvt_c) [] =
207 bci_cvt_rescale,
208 bci_loop,
209 CALL,
211 /* loop over blue shoots */
212 PUSHB_4,
216 /* %c, first blue shoot index */
217 /* %c, last blue shoot index */
219 unsigned char PREP(loop_cvt_d) [] =
222 bci_cvt_rescale,
223 bci_loop,
224 CALL,
225 EIF,
229 unsigned char PREP(test_exception_b) [] =
232 EIF,
236 unsigned char PREP(compute_extra_light_a) [] =
239 /* compute (vertical) `extra_light' flag */
240 PUSHB_3,
241 cvtl_is_extra_light,
246 /* %c, index of vertical standard_width */
248 unsigned char PREP(compute_extra_light_b) [] =
251 RCVT,
252 GT, /* standard_width < 40 */
253 WCVTP,
257 unsigned char PREP(round_blues_a) [] =
260 /* use discrete values for blue zone widths */
261 PUSHB_4,
265 /* %c, first blue ref index */
266 /* %c, last blue ref index */
268 unsigned char PREP(round_blues_b) [] =
271 bci_blue_round,
272 bci_loop,
273 CALL
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 */
297 PUSHB_2,
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) [] =
307 WCVTP,
309 /* get rasterizer version (bit 0) */
310 PUSHB_2,
312 0x01,
313 GETINFO,
315 /* `GDI ClearType': */
316 /* version >= 36 and version < 38, ClearType enabled */
317 LTEQ,
319 /* check whether ClearType is enabled (bit 6) */
320 PUSHB_1,
321 0x40,
322 GETINFO,
324 PUSHB_2,
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) [] =
333 WCVTP,
335 /* get rasterizer version (bit 0) */
336 PUSHB_2,
338 0x01,
339 GETINFO,
341 /* `DW ClearType': */
342 /* version >= 38, sub-pixel positioning is enabled */
343 LTEQ,
345 /* check whether sub-pixel positioning is enabled (bit 10) */
346 PUSHW_1,
347 0x04,
348 0x00,
349 GETINFO,
351 PUSHB_2,
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) [] =
361 WCVTP,
362 EIF,
363 EIF,
364 EIF,
365 EIF,
369 unsigned char PREP(set_dropout_mode) [] =
372 PUSHW_1,
373 0x01, /* 0x01FF, activate dropout handling unconditionally */
374 0xFF,
375 SCANCTRL,
376 PUSHB_1,
377 4, /* smart dropout include stubs */
378 SCANTYPE,
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. */
397 PUSHB_2,
398 cvtl_is_subglyph,
400 WCVTP,
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') */
410 static FT_Byte*
411 TA_sfnt_build_number_set(SFNT* sfnt,
412 FT_Byte** buf,
413 number_range* number_set)
415 FT_Byte* bufp = NULL;
416 number_range* nr;
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;
423 FT_UInt* single_arg;
425 FT_UInt num_ranges2 = 0;
426 FT_UInt* range2_args;
427 FT_UInt* range2_arg;
428 FT_UInt num_ranges = 0;
429 FT_UInt* range_args;
430 FT_UInt* range_arg;
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 */
439 nr = number_set;
440 while (nr)
442 if (nr->start == nr->end)
444 if (nr->start < 256)
445 num_singles++;
446 else
447 num_singles2++;
449 else
451 if (nr->start < 256 && nr->end < 256)
452 num_ranges++;
453 else
454 num_ranges2++;
456 nr = nr->next;
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)
469 goto Fail;
471 /* check whether we need the extra slot for the argument to CALL */
472 if (num_singles || num_singles2)
473 have_single = 1;
474 if (num_ranges || num_ranges2)
475 have_range = 1;
477 /* set function indices outside of argument loop (using the extra slot) */
478 if (have_single)
479 single_args[num_singles] = bci_number_set_is_element;
480 if (have_range)
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;
488 nr = number_set;
489 while (nr)
491 if (nr->start == nr->end)
493 if (nr->start < 256)
494 *(single_arg--) = nr->start;
495 else
496 *(single2_arg--) = nr->start;
498 else
500 if (nr->start < 256 && nr->end < 256)
502 *(range_arg--) = nr->start;
503 *(range_arg--) = nr->end;
505 else
507 *(range2_arg--) = nr->start;
508 *(range2_arg--) = nr->end;
511 nr = nr->next;
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
519 + 2);
520 if (!*buf)
521 goto Fail;
522 bufp = *buf;
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);
526 if (have_single)
527 BCI(CALL);
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);
531 if (have_range)
532 BCI(CALL);
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;
541 Fail:
542 free(single2_args);
543 free(single_args);
544 free(range2_args);
545 free(range_args);
547 return bufp;
551 #define COPY_PREP(snippet_name) \
552 do \
554 memcpy(buf_p, prep_ ## snippet_name, \
555 sizeof (prep_ ## snippet_name)); \
556 buf_p += sizeof (prep_ ## snippet_name); \
557 } while (0)
559 static FT_Error
560 TA_table_build_prep(FT_Byte** prep,
561 FT_ULong* prep_len,
562 SFNT* sfnt,
563 FONT* font)
565 TA_LatinAxis vaxis;
566 TA_LatinBlue blue_adjustment = NULL;
567 FT_UInt i;
569 FT_Byte* buf = NULL;
570 FT_Byte* buf_new;
571 FT_UInt buf_len;
572 FT_UInt buf_new_len;
574 FT_UInt len;
575 FT_Byte* buf_p = NULL;
578 if (font->loader->hints.metrics->clazz->script == TA_SCRIPT_NONE)
579 vaxis = NULL;
580 else
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];
589 break;
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);
598 if (!buf_p)
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));
612 if (blue_adjustment)
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);
658 if (!buf_new)
660 free(buf);
661 return FT_Err_Out_Of_Memory;
663 buf = buf_new;
665 /* pad end of buffer with zeros */
666 buf[len - 1] = 0x00;
667 buf[len - 2] = 0x00;
668 buf[len - 3] = 0x00;
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);
684 if (blue_adjustment)
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);
700 else
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);
749 *prep = buf;
750 *prep_len = buf_new_len;
752 return FT_Err_Ok;
756 FT_Error
757 TA_sfnt_build_prep_table(SFNT* sfnt,
758 FONT* font)
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;
765 FT_Byte* prep_buf;
766 FT_ULong prep_len;
769 error = TA_sfnt_add_table_info(sfnt);
770 if (error)
771 goto Exit;
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;
777 goto Exit;
780 error = TA_table_build_prep(&prep_buf, &prep_len, sfnt, font);
781 if (error)
782 goto Exit;
784 #if 0
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;
790 #endif
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);
797 if (error)
798 free(prep_buf);
799 else
800 data->prep_idx = sfnt->table_infos[sfnt->num_table_infos - 1];
802 Exit:
803 return error;
806 /* end of taprep.c */