3 /* written 2011 by Werner Lemberg <wl@gnu.org> */
6 #include "tabytecode.h"
11 int _ta_debug_disable_horz_hints
;
12 int _ta_debug_disable_vert_hints
;
13 int _ta_debug_disable_blue_hints
;
14 void* _ta_debug_hints
;
19 TA_sfnt_compute_global_hints(SFNT
* sfnt
,
23 FT_Face face
= sfnt
->face
;
27 static const FT_Encoding latin_encs
[] =
30 FT_ENCODING_APPLE_ROMAN
,
31 FT_ENCODING_ADOBE_STANDARD
,
32 FT_ENCODING_ADOBE_LATIN_1
,
34 FT_ENCODING_NONE
/* end of list */
38 error
= ta_loader_init(font
->loader
);
42 /* try to select a latin charmap */
43 for (enc
= 0; latin_encs
[enc
] != FT_ENCODING_NONE
; enc
++)
45 error
= FT_Select_Charmap(face
, latin_encs
[enc
]);
50 /* load latin glyph `a' to trigger all initializations */
51 idx
= FT_Get_Char_Index(face
, 'a');
52 error
= ta_loader_load_glyph(font
->loader
, face
, idx
, 0);
59 TA_table_build_cvt(FT_Byte
** cvt
,
76 error
= TA_sfnt_compute_global_hints(sfnt
, font
);
80 /* XXX check validity of pointers */
81 haxis
= &((TA_LatinMetrics
)font
->loader
->hints
.metrics
)->axis
[0];
82 vaxis
= &((TA_LatinMetrics
)font
->loader
->hints
.metrics
)->axis
[1];
84 buf_len
= 2 * (haxis
->width_count
+ vaxis
->width_count
85 + 2 * vaxis
->blue_count
);
87 /* buffer length must be a multiple of four */
88 len
= (buf_len
+ 3) & ~3;
89 buf
= (FT_Byte
*)malloc(len
);
91 return FT_Err_Out_Of_Memory
;
93 /* pad end of buffer with zeros */
100 /* XXX emit standard_width also? */
102 for (i
= 0; i
< haxis
->width_count
; i
++)
104 if (haxis
->widths
[i
].org
> 0xFFFF)
106 *(buf_p
++) = HIGH(haxis
->widths
[i
].org
);
107 *(buf_p
++) = LOW(haxis
->widths
[i
].org
);
110 for (i
= 0; i
< vaxis
->width_count
; i
++)
112 if (vaxis
->widths
[i
].org
> 0xFFFF)
114 *(buf_p
++) = HIGH(vaxis
->widths
[i
].org
);
115 *(buf_p
++) = LOW(vaxis
->widths
[i
].org
);
118 for (i
= 0; i
< vaxis
->blue_count
; i
++)
120 if (vaxis
->blues
[i
].ref
.org
> 0xFFFF)
122 *(buf_p
++) = HIGH(vaxis
->blues
[i
].ref
.org
);
123 *(buf_p
++) = LOW(vaxis
->blues
[i
].ref
.org
);
124 if (vaxis
->blues
[i
].shoot
.org
> 0xFFFF)
126 *(buf_p
++) = HIGH(vaxis
->blues
[i
].shoot
.org
);
127 *(buf_p
++) = LOW(vaxis
->blues
[i
].shoot
.org
);
131 TA_LOG(("--------------------------------------------------\n"));
132 TA_LOG(("glyph %d:\n", idx
));
133 ta_glyph_hints_dump_edges(_ta_debug_hints
);
134 ta_glyph_hints_dump_segments(_ta_debug_hints
);
135 ta_glyph_hints_dump_points(_ta_debug_hints
);
145 return TA_Err_Hinter_Overflow
;
150 TA_sfnt_build_cvt_table(SFNT
* sfnt
,
159 error
= TA_sfnt_add_table_info(sfnt
);
163 error
= TA_table_build_cvt(&cvt_buf
, &cvt_len
, sfnt
, font
);
167 /* in case of success, `cvt_buf' gets linked */
168 /* and is eventually freed in `TA_font_unload' */
169 error
= TA_font_add_table(font
,
170 &sfnt
->table_infos
[sfnt
->num_table_infos
- 1],
171 TTAG_cvt
, cvt_len
, cvt_buf
);
180 /* the horizontal stem widths */
181 #define CVT_HORZ_WIDTHS_OFFSET(font) 0
182 #define CVT_HORZ_WIDTHS_SIZE(font) \
183 ((TA_LatinMetrics)font->loader->hints.metrics)->axis[0].width_count
185 /* the vertical stem widths */
186 #define CVT_VERT_WIDTHS_OFFSET(font) \
187 CVT_HORZ_WIDTHS_OFFSET(font) \
188 + ((TA_LatinMetrics)font->loader->hints.metrics)->axis[0].width_count
189 #define CVT_VERT_WIDTHS_SIZE(font) \
190 ((TA_LatinMetrics)font->loader->hints.metrics)->axis[1].width_count
192 /* the blue zone values for flat edges */
193 #define CVT_BLUE_REFS_OFFSET(font) \
194 CVT_VERT_WIDTHS_OFFSET(font) \
195 + ((TA_LatinMetrics)font->loader->hints.metrics)->axis[1].width_count
196 #define CVT_BLUE_REFS_SIZE(font) \
197 ((TA_LatinMetrics)font->loader->hints.metrics)->axis[1].blue_count
199 /* the blue zone values for round edges */
200 #define CVT_BLUE_SHOOTS_OFFSET(font) \
201 CVT_BLUE_REFS_OFFSET(font) \
202 + ((TA_LatinMetrics)font->loader->hints.metrics)->axis[1].blue_count
203 #define CVT_BLUE_SHOOTS_SIZE(font) \
204 ((TA_LatinMetrics)font->loader->hints.metrics)->axis[1].blue_count
207 /* symbolic names for storage area locations */
209 #define sal_counter 0
212 #define sal_0x10000 3
215 /* in the comments below, the top of the stack (`s:') */
216 /* is the rightmost element; the stack is shown */
217 /* after the instruction on the same line has been executed */
222 * This is the equivalent to the following code from function
223 * `ta_latin_compute_stem_width':
230 * else if base_is_round:
234 * dist = MIN(56, dist)
236 * delta = ABS(dist - std_width)
239 * dist = MIN(48, std_width)
245 * delta = delta - dist
248 * dist = dist + delta
249 * else if delta < 32:
251 * else if delta < 54:
254 * dist = dist + delta
265 * Function 0: compute_stem_width
271 * CVT: is_extra_light XXX
275 #define compute_stem_width 0
277 unsigned char fpgm_0a
[] = {
284 ABS
, /* s: base_is_round stem_is_serif width dist */
289 LT
, /* dist < 3*64 */
293 MINDEX
, /* s: base_is_round width dist (dist<3*64) stem_is_serif */
295 AND
, /* stem_is_serif && dist < 3*64 */
296 IF
, /* s: base_is_round width dist */
302 ROLL
, /* s: width dist base_is_round */
303 IF
, /* s: width dist */
308 IF
, /* s: width dist */
317 MIN
, /* dist = min(56, dist) */
320 DUP
, /* s: width dist dist */
325 /* %c, index of std_width */
327 unsigned char fpgm_0b
[] = {
331 ABS
, /* s: width dist delta */
336 IF
, /* s: width dist */
343 /* %c, index of std_width */
345 unsigned char fpgm_0c
[] = {
348 MIN
, /* dist = min(48, std_width) */
351 DUP
, /* s: width dist dist */
354 LT
, /* dist < 3*64 */
356 DUP
, /* s: width delta dist */
357 FLOOR
, /* dist = FLOOR(dist) */
358 DUP
, /* s: width delta dist dist */
360 ROLL
, /* s: width dist delta dist */
361 SUB
, /* delta = delta - dist */
363 DUP
, /* s: width dist delta delta */
367 IF
, /* s: width dist delta */
368 ADD
, /* dist = dist + delta */
379 ADD
, /* dist = dist + 10 */
390 ADD
, /* dist = dist + 54 */
393 ADD
, /* dist = dist + delta */
403 FLOOR
, /* dist = round(dist) */
408 SWAP
, /* s: dist width */
412 NEG
, /* dist = -dist */
425 * Take a range and a function number and apply the function to all
426 * elements of the range. The called function must not change the
435 * uses: sal_counter (counter initialized with `start')
441 unsigned char fpgm_1
[] = {
447 ROLL
, /* s: func_num start end */
465 LTEQ
, /* start <= end */
466 IF
, /* s: func_num */
473 ADD
, /* start = start + 1 */
482 JMPR
, /* goto start_loop */
495 * All entries in the CVT table get scaled automatically using the
496 * vertical resolution. However, some widths must be scaled with the
497 * horizontal resolution, and others get adjusted later on.
499 * Function 2: rescale
501 * uses: sal_counter (CVT index)
502 * sal_scale (scale in 16.16 format)
507 unsigned char fpgm_2
[] = {
521 MUL
, /* CVT * scale * 2^10 */
525 DIV
, /* CVT * scale */
535 /* we often need 0x10000 which can't be pushed directly onto the stack, */
536 /* thus we provide it in the storage area */
538 unsigned char fpgm_A
[] = {
554 TA_table_build_fpgm(FT_Byte
** fpgm
,
564 buf_len
= sizeof (fpgm_0a
)
572 /* buffer length must be a multiple of four */
573 len
= (buf_len
+ 3) & ~3;
574 buf
= (FT_Byte
*)malloc(len
);
576 return FT_Err_Out_Of_Memory
;
578 /* pad end of buffer with zeros */
583 /* copy font program into buffer and fill in the missing variables */
586 memcpy(buf_p
, fpgm_0a
, sizeof (fpgm_0a
));
587 buf_p
+= sizeof (fpgm_0a
);
589 *(buf_p
++) = (unsigned char)CVT_VERT_WIDTHS_OFFSET(font
);
591 memcpy(buf_p
, fpgm_0b
, sizeof (fpgm_0b
));
592 buf_p
+= sizeof (fpgm_0b
);
594 *(buf_p
++) = (unsigned char)CVT_VERT_WIDTHS_OFFSET(font
);
596 memcpy(buf_p
, fpgm_0c
, sizeof (fpgm_0c
));
597 buf_p
+= sizeof (fpgm_0c
);
599 memcpy(buf_p
, fpgm_1
, sizeof (fpgm_1
));
600 buf_p
+= sizeof (fpgm_1
);
602 memcpy(buf_p
, fpgm_2
, sizeof (fpgm_2
));
603 buf_p
+= sizeof (fpgm_2
);
605 memcpy(buf_p
, fpgm_A
, sizeof (fpgm_A
));
615 TA_sfnt_build_fpgm_table(SFNT
* sfnt
,
624 error
= TA_sfnt_add_table_info(sfnt
);
628 error
= TA_table_build_fpgm(&fpgm_buf
, &fpgm_len
, font
);
632 /* in case of success, `fpgm_buf' gets linked */
633 /* and is eventually freed in `TA_font_unload' */
634 error
= TA_font_add_table(font
,
635 &sfnt
->table_infos
[sfnt
->num_table_infos
- 1],
636 TTAG_fpgm
, fpgm_len
, fpgm_buf
);
645 /* the `prep' instructions */
647 unsigned char prep_a
[] = {
649 /* scale horizontal CVT entries */
650 /* if horizontal and vertical resolutions differ */
656 NEQ
, /* horz_ppem != vert_ppem */
663 MUL
, /* horz_ppem in 22.10 format */
667 DIV
, /* (horz_ppem / vert_ppem) in 16.16 format */
674 /* loop over horizontal CVT entries */
679 /* %c, first horizontal index */
680 /* %c, last horizontal index */
682 unsigned char prep_b
[] = {
691 unsigned char prep_c
[] = {
693 /* optimize the alignment of the top of small letters to the pixel grid */
699 /* %c, index of alignment blue zone */
701 unsigned char prep_d
[] = {
709 FLOOR
, /* fitted = FLOOR(scaled + 40) */
710 DUP
, /* s: scaled scaled fitted fitted */
713 IF
, /* s: scaled fitted */
718 MUL
, /* scaled in 16.16 format */
720 DIV
, /* (scaled / fitted) in 16.16 format */
727 /* loop over vertical CVT entries */
732 /* %c, first vertical index */
733 /* %c, last vertical index */
735 unsigned char prep_e
[] = {
741 /* loop over blue refs */
746 /* %c, first blue ref index */
747 /* %c, last blue ref index */
749 unsigned char prep_f
[] = {
755 /* loop over blue shoots */
760 /* %c, first blue shoot index */
761 /* %c, last blue shoot index */
763 unsigned char prep_g
[] = {
775 TA_table_build_prep(FT_Byte
** prep
,
780 TA_LatinBlue blue_adjustment
;
789 vaxis
= &((TA_LatinMetrics
)font
->loader
->hints
.metrics
)->axis
[1];
790 blue_adjustment
= NULL
;
792 for (i
= 0; i
< vaxis
->blue_count
; i
++)
794 if (vaxis
->blues
[i
].flags
& TA_LATIN_BLUE_ADJUSTMENT
)
796 blue_adjustment
= &vaxis
->blues
[i
];
801 buf_len
= sizeof (prep_a
)
807 buf_len
+= sizeof (prep_c
)
818 /* buffer length must be a multiple of four */
819 len
= (buf_len
+ 3) & ~3;
820 buf
= (FT_Byte
*)malloc(len
);
822 return FT_Err_Out_Of_Memory
;
824 /* pad end of buffer with zeros */
829 /* copy cvt program into buffer and fill in the missing variables */
832 memcpy(buf_p
, prep_a
, sizeof (prep_a
));
833 buf_p
+= sizeof (prep_a
);
835 *(buf_p
++) = (unsigned char)CVT_HORZ_WIDTHS_OFFSET(font
);
836 *(buf_p
++) = (unsigned char)(CVT_HORZ_WIDTHS_OFFSET(font
)
837 + CVT_HORZ_WIDTHS_SIZE(font
) - 1);
839 memcpy(buf_p
, prep_b
, sizeof (prep_b
));
843 buf_p
+= sizeof (prep_b
);
845 memcpy(buf_p
, prep_c
, sizeof (prep_c
));
846 buf_p
+= sizeof (prep_c
);
848 *(buf_p
++) = blue_adjustment
- vaxis
->blues
;
850 memcpy(buf_p
, prep_d
, sizeof (prep_d
));
851 buf_p
+= sizeof (prep_d
);
853 *(buf_p
++) = (unsigned char)CVT_VERT_WIDTHS_OFFSET(font
);
854 *(buf_p
++) = (unsigned char)(CVT_VERT_WIDTHS_OFFSET(font
)
855 + CVT_VERT_WIDTHS_SIZE(font
) - 1);
857 memcpy(buf_p
, prep_e
, sizeof (prep_e
));
858 buf_p
+= sizeof (prep_e
);
860 *(buf_p
++) = (unsigned char)CVT_BLUE_REFS_OFFSET(font
);
861 *(buf_p
++) = (unsigned char)(CVT_BLUE_REFS_OFFSET(font
)
862 + CVT_BLUE_REFS_SIZE(font
) - 1);
864 memcpy(buf_p
, prep_f
, sizeof (prep_f
));
865 buf_p
+= sizeof (prep_f
);
867 *(buf_p
++) = (unsigned char)CVT_BLUE_SHOOTS_OFFSET(font
);
868 *(buf_p
++) = (unsigned char)(CVT_BLUE_SHOOTS_OFFSET(font
)
869 + CVT_BLUE_SHOOTS_SIZE(font
) - 1);
871 memcpy(buf_p
, prep_g
, sizeof (prep_g
));
882 TA_sfnt_build_prep_table(SFNT
* sfnt
,
891 error
= TA_sfnt_add_table_info(sfnt
);
895 error
= TA_table_build_prep(&prep_buf
, &prep_len
, font
);
899 /* in case of success, `prep_buf' gets linked */
900 /* and is eventually freed in `TA_font_unload' */
901 error
= TA_font_add_table(font
,
902 &sfnt
->table_infos
[sfnt
->num_table_infos
- 1],
903 TTAG_prep
, prep_len
, prep_buf
);
911 /* end of tabytecode.c */