Reduce memory consumption.
[ttfautohint.git] / lib / tacvt.c
blobf895846a17e3ee5f2564928807a87d723a95928d
1 /* tacvt.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 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;
26 FT_Int32 load_flags;
29 error = ta_loader_init(font);
30 if (error)
31 return error;
33 error = FT_Select_Charmap(face, FT_ENCODING_UNICODE);
34 if (error)
36 if (font->symbol)
38 error = FT_Select_Charmap(face, FT_ENCODING_MS_SYMBOL);
39 if (error)
40 return TA_Err_Missing_Symbol_CMap;
42 else
43 return TA_Err_Missing_Unicode_CMap;
46 if (font->symbol)
47 idx = 0;
48 else
50 /* load glyph `o' to trigger all initializations */
51 /* XXX make this configurable for non-latin scripts */
52 /* XXX make this configurable to use a different letter */
53 idx = FT_Get_Char_Index(face, 'o');
54 if (!idx)
55 return TA_Err_Missing_Glyph;
58 load_flags = 1 << 29; /* vertical hinting only */
59 error = ta_loader_load_glyph(font, face, idx, load_flags);
61 return error;
65 static FT_Error
66 TA_table_build_cvt(FT_Byte** cvt,
67 FT_ULong* cvt_len,
68 SFNT* sfnt,
69 FONT* font)
71 TA_LatinAxis haxis;
72 TA_LatinAxis vaxis;
74 FT_UInt hwidth_count;
75 FT_UInt vwidth_count;
76 FT_UInt blue_count;
78 FT_UInt i;
79 FT_UInt buf_len;
80 FT_UInt len;
81 FT_Byte* buf;
82 FT_Byte* buf_p;
84 FT_Error error;
87 error = TA_sfnt_compute_global_hints(sfnt, font);
88 if (error)
89 return error;
91 if (font->loader->hints.metrics->clazz->script == TA_SCRIPT_NONE)
93 haxis = NULL;
94 vaxis = NULL;
96 hwidth_count = 0;
97 vwidth_count = 0;
98 blue_count = 0;
100 else
102 haxis = &((TA_LatinMetrics)font->loader->hints.metrics)->axis[0];
103 vaxis = &((TA_LatinMetrics)font->loader->hints.metrics)->axis[1];
105 hwidth_count = haxis->width_count;
106 vwidth_count = vaxis->width_count;
107 blue_count = vaxis->blue_count;
110 buf_len = 2 * (cvtl_max_runtime /* runtime values */
111 + 2 /* vertical and horizontal standard width */
112 + hwidth_count
113 + vwidth_count
114 + 2 * blue_count);
116 /* buffer length must be a multiple of four */
117 len = (buf_len + 3) & ~3;
118 buf = (FT_Byte*)malloc(len);
119 if (!buf)
120 return FT_Err_Out_Of_Memory;
122 /* pad end of buffer with zeros */
123 buf[len - 1] = 0x00;
124 buf[len - 2] = 0x00;
125 buf[len - 3] = 0x00;
127 buf_p = buf;
129 /* some CVT values are initialized (and modified) at runtime; */
130 /* see the `cvtl_xxx' macros in tabytecode.h */
131 for (i = 0; i < cvtl_max_runtime; i++)
133 *(buf_p++) = 0;
134 *(buf_p++) = 0;
137 if (hwidth_count > 0)
139 *(buf_p++) = HIGH(haxis->widths[0].org);
140 *(buf_p++) = LOW(haxis->widths[0].org);
142 else
144 *(buf_p++) = 0;
145 *(buf_p++) = 50;
147 if (vwidth_count > 0)
149 *(buf_p++) = HIGH(vaxis->widths[0].org);
150 *(buf_p++) = LOW(vaxis->widths[0].org);
152 else
154 *(buf_p++) = 0;
155 *(buf_p++) = 50;
158 for (i = 0; i < hwidth_count; i++)
160 if (haxis->widths[i].org > 0xFFFF)
161 goto Err;
162 *(buf_p++) = HIGH(haxis->widths[i].org);
163 *(buf_p++) = LOW(haxis->widths[i].org);
166 for (i = 0; i < vwidth_count; i++)
168 if (vaxis->widths[i].org > 0xFFFF)
169 goto Err;
170 *(buf_p++) = HIGH(vaxis->widths[i].org);
171 *(buf_p++) = LOW(vaxis->widths[i].org);
174 for (i = 0; i < blue_count; i++)
176 if (vaxis->blues[i].ref.org > 0xFFFF)
177 goto Err;
178 *(buf_p++) = HIGH(vaxis->blues[i].ref.org);
179 *(buf_p++) = LOW(vaxis->blues[i].ref.org);
182 for (i = 0; i < blue_count; i++)
184 if (vaxis->blues[i].shoot.org > 0xFFFF)
185 goto Err;
186 *(buf_p++) = HIGH(vaxis->blues[i].shoot.org);
187 *(buf_p++) = LOW(vaxis->blues[i].shoot.org);
190 *cvt = buf;
191 *cvt_len = buf_len;
193 return FT_Err_Ok;
195 Err:
196 free(buf);
197 return TA_Err_Hinter_Overflow;
201 FT_Error
202 TA_sfnt_build_cvt_table(SFNT* sfnt,
203 FONT* font)
205 FT_Error error;
207 FT_Byte* cvt_buf;
208 FT_ULong cvt_len;
211 error = TA_sfnt_add_table_info(sfnt);
212 if (error)
213 return error;
215 error = TA_table_build_cvt(&cvt_buf, &cvt_len, sfnt, font);
216 if (error)
217 return error;
219 /* in case of success, `cvt_buf' gets linked */
220 /* and is eventually freed in `TA_font_unload' */
221 error = TA_font_add_table(font,
222 &sfnt->table_infos[sfnt->num_table_infos - 1],
223 TTAG_cvt, cvt_len, cvt_buf);
224 if (error)
226 free(cvt_buf);
227 return error;
230 return FT_Err_Ok;
233 /* end of tacvt.c */