Fix thinko in handling composite glyphs.
[ttfautohint.git] / src / tacvt.c
blob72ce20c71500793eb4fbb7677506703630af62a8
1 /* tacvt.c */
3 /*
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.
16 #include "ta.h"
19 static FT_Error
20 TA_sfnt_compute_global_hints(SFNT* sfnt,
21 FONT* font)
23 FT_Error error;
24 FT_Face face = sfnt->face;
25 FT_UInt idx;
28 error = ta_loader_init(font->loader);
29 if (error)
30 return error;
32 error = FT_Select_Charmap(face, FT_ENCODING_UNICODE);
33 if (error)
34 return TA_Err_Missing_Unicode_CMap;
36 /* load glyph `o' to trigger all initializations; */
37 /* XXX make this configurable for non-latin scripts */
38 /* XXX make this configurable to use a different letter */
39 idx = FT_Get_Char_Index(face, 'o');
40 if (!idx)
41 return TA_Err_Missing_Glyph;
43 error = ta_loader_load_glyph(font->loader, face, idx,
44 font->fallback_script << 30);
46 return error;
50 static FT_Error
51 TA_table_build_cvt(FT_Byte** cvt,
52 FT_ULong* cvt_len,
53 SFNT* sfnt,
54 FONT* font)
56 TA_LatinAxis haxis;
57 TA_LatinAxis vaxis;
59 FT_UInt i;
60 FT_UInt buf_len;
61 FT_UInt len;
62 FT_Byte* buf;
63 FT_Byte* buf_p;
65 FT_Error error;
68 error = TA_sfnt_compute_global_hints(sfnt, font);
69 if (error)
70 return error;
72 haxis = &((TA_LatinMetrics)font->loader->hints.metrics)->axis[0];
73 vaxis = &((TA_LatinMetrics)font->loader->hints.metrics)->axis[1];
75 buf_len = 2 * (cvtl_max_runtime /* runtime values */
76 + 2 /* vertical and horizontal standard width */
77 + haxis->width_count
78 + vaxis->width_count
79 + 2 * vaxis->blue_count);
81 /* buffer length must be a multiple of four */
82 len = (buf_len + 3) & ~3;
83 buf = (FT_Byte*)malloc(len);
84 if (!buf)
85 return FT_Err_Out_Of_Memory;
87 /* pad end of buffer with zeros */
88 buf[len - 1] = 0x00;
89 buf[len - 2] = 0x00;
90 buf[len - 3] = 0x00;
92 buf_p = buf;
94 /* some CVT values are initialized (and modified) at runtime; */
95 /* see the `cvtl_xxx' macros in tabytecode.h */
96 for (i = 0; i < cvtl_max_runtime; i++)
98 *(buf_p++) = 0;
99 *(buf_p++) = 0;
102 if (haxis->width_count > 0)
104 *(buf_p++) = HIGH(haxis->widths[0].org);
105 *(buf_p++) = LOW(haxis->widths[0].org);
107 else
109 *(buf_p++) = 0;
110 *(buf_p++) = 50;
112 if (vaxis->width_count > 0)
114 *(buf_p++) = HIGH(vaxis->widths[0].org);
115 *(buf_p++) = LOW(vaxis->widths[0].org);
117 else
119 *(buf_p++) = 0;
120 *(buf_p++) = 50;
123 for (i = 0; i < haxis->width_count; i++)
125 if (haxis->widths[i].org > 0xFFFF)
126 goto Err;
127 *(buf_p++) = HIGH(haxis->widths[i].org);
128 *(buf_p++) = LOW(haxis->widths[i].org);
131 for (i = 0; i < vaxis->width_count; i++)
133 if (vaxis->widths[i].org > 0xFFFF)
134 goto Err;
135 *(buf_p++) = HIGH(vaxis->widths[i].org);
136 *(buf_p++) = LOW(vaxis->widths[i].org);
139 for (i = 0; i < vaxis->blue_count; i++)
141 if (vaxis->blues[i].ref.org > 0xFFFF)
142 goto Err;
143 *(buf_p++) = HIGH(vaxis->blues[i].ref.org);
144 *(buf_p++) = LOW(vaxis->blues[i].ref.org);
147 for (i = 0; i < vaxis->blue_count; i++)
149 if (vaxis->blues[i].shoot.org > 0xFFFF)
150 goto Err;
151 *(buf_p++) = HIGH(vaxis->blues[i].shoot.org);
152 *(buf_p++) = LOW(vaxis->blues[i].shoot.org);
155 #if 0
156 TA_LOG(("--------------------------------------------------\n"));
157 TA_LOG(("glyph %d:\n", idx));
158 ta_glyph_hints_dump_edges(_ta_debug_hints);
159 ta_glyph_hints_dump_segments(_ta_debug_hints);
160 ta_glyph_hints_dump_points(_ta_debug_hints);
161 #endif
163 *cvt = buf;
164 *cvt_len = buf_len;
166 return FT_Err_Ok;
168 Err:
169 free(buf);
170 return TA_Err_Hinter_Overflow;
174 FT_Error
175 TA_sfnt_build_cvt_table(SFNT* sfnt,
176 FONT* font)
178 FT_Error error;
180 FT_Byte* cvt_buf;
181 FT_ULong cvt_len;
184 error = TA_sfnt_add_table_info(sfnt);
185 if (error)
186 return error;
188 error = TA_table_build_cvt(&cvt_buf, &cvt_len, sfnt, font);
189 if (error)
190 return error;
192 /* in case of success, `cvt_buf' gets linked */
193 /* and is eventually freed in `TA_font_unload' */
194 error = TA_font_add_table(font,
195 &sfnt->table_infos[sfnt->num_table_infos - 1],
196 TTAG_cvt, cvt_len, cvt_buf);
197 if (error)
199 free(cvt_buf);
200 return error;
203 return FT_Err_Ok;
206 /* end of tacvt.c */