4 * Copyright (C) 2011-2019 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.
20 TA_sfnt_compute_global_hints(SFNT
* sfnt
,
25 FT_Face face
= sfnt
->face
;
28 TA_FaceGlobals globals
= (TA_FaceGlobals
)sfnt
->face
->autohint
.data
;
31 error
= FT_Select_Charmap(face
, FT_ENCODING_UNICODE
);
36 error
= FT_Select_Charmap(face
, FT_ENCODING_MS_SYMBOL
);
38 return TA_Err_Missing_Symbol_CMap
;
41 return TA_Err_Missing_Unicode_CMap
;
44 if (!globals
->sample_glyphs
[style_idx
])
45 return TA_Err_Missing_Glyph
;
47 /* trigger computation of the current coverage's metrics */
48 load_flags
= 1 << 29; /* vertical hinting only */
49 return ta_loader_load_glyph(font
,
51 globals
->sample_glyphs
[style_idx
],
57 TA_table_build_cvt(FT_Byte
** cvt
,
62 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
63 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
82 /* loop over all styles and collect the relevant CVT data */
83 /* to compute the necessary array sizes and meta-information */
88 data
->num_used_styles
= 0;
90 for (i
= 0; i
< TA_STYLE_MAX
; i
++)
92 error
= TA_sfnt_compute_global_hints(sfnt
, font
, (TA_Style
)i
);
93 if (error
== TA_Err_Missing_Glyph
)
95 data
->style_ids
[i
] = 0xFFFFU
;
101 /* XXX: generalize this to handle other metrics also */
102 haxis
= &((TA_LatinMetrics
)font
->loader
->hints
.metrics
)->axis
[0];
103 vaxis
= &((TA_LatinMetrics
)font
->loader
->hints
.metrics
)->axis
[1];
105 if (!vaxis
->blue_count
)
107 TA_FaceGlobals globals
= (TA_FaceGlobals
)sfnt
->face
->autohint
.data
;
108 FT_UShort
* gstyles
= globals
->glyph_styles
;
112 data
->style_ids
[i
] = 0xFFFFU
;
113 globals
->sample_glyphs
[i
] = 0;
115 /* remove all references to this style; we have no blue zone data */
116 for (nn
= 0; nn
< globals
->glyph_count
; nn
++)
118 if ((gstyles
[nn
] & TA_STYLE_MASK
) == i
)
120 gstyles
[nn
] &= ~TA_STYLE_MASK
;
121 gstyles
[nn
] |= globals
->font
->fallback_style
;
128 data
->style_ids
[i
] = data
->num_used_styles
++;
130 hwidth_count
+= haxis
->width_count
;
131 vwidth_count
+= vaxis
->width_count
;
133 blue_count
+= vaxis
->blue_count
;
134 /* if windows compatibility mode is active */
135 /* we add two artificial blue zones at the end of the array */
136 /* that are not part of `vaxis->blue_count' */
137 if (font
->windows_compatibility
)
141 /* exit if the font doesn't contain a single supported style, */
142 /* and we don't have a symbol font */
143 if (!data
->num_used_styles
&& !font
->symbol
)
144 return TA_Err_Missing_Glyph
;
146 buf_len
= cvtl_max_runtime
/* runtime values 1 */
147 + data
->num_used_styles
/* runtime values 2 (for scaling) */
148 + 2 * data
->num_used_styles
/* runtime values 3 (blue data) */
149 + 2 * data
->num_used_styles
/* vert. and horiz. std. widths */
152 + 2 * blue_count
; /* round and flat blue zones */
153 buf_len
<<= 1; /* we have 16bit values */
155 /* buffer length must be a multiple of four */
156 len
= (buf_len
+ 3) & ~3U;
157 buf
= (FT_Byte
*)malloc(len
);
159 return FT_Err_Out_Of_Memory
;
161 /* pad end of buffer with zeros */
169 * some CVT values are initialized (and modified) at runtime:
171 * (1) the `cvtl_xxx' values (see `tabytecode.h')
172 * (2) a scaling value for each style
173 * (3) offset and size of the vertical widths array
174 * (needed by `bci_{smooth,strong}_stem_width') for each style
176 for (i
= 0; i
< (cvtl_max_runtime
177 + data
->num_used_styles
178 + 2 * data
->num_used_styles
) * 2; i
++)
181 cvt_offset
= (FT_UInt
)(bufp
- buf
);
183 /* loop again over all styles and copy CVT data */
184 for (i
= 0; i
< TA_STYLE_MAX
; i
++)
186 FT_UInt default_width
= 50 * sfnt
->face
->units_per_EM
/ 2048;
189 /* collect offsets */
190 data
->cvt_offsets
[i
] = ((FT_UInt
)(bufp
- buf
) - cvt_offset
) >> 1;
192 error
= TA_sfnt_compute_global_hints(sfnt
, font
, (TA_Style
)i
);
193 if (error
== TA_Err_Missing_Glyph
)
198 haxis
= &((TA_LatinMetrics
)font
->loader
->hints
.metrics
)->axis
[0];
199 vaxis
= &((TA_LatinMetrics
)font
->loader
->hints
.metrics
)->axis
[1];
201 if (!vaxis
->blue_count
)
204 hwidth_count
= haxis
->width_count
;
205 vwidth_count
= vaxis
->width_count
;
207 blue_count
= vaxis
->blue_count
;
208 if (font
->windows_compatibility
)
209 blue_count
+= 2; /* with artificial blue zones */
211 /* horizontal standard width */
212 if (hwidth_count
> 0)
214 *(bufp
++) = HIGH(haxis
->widths
[0].org
);
215 *(bufp
++) = LOW(haxis
->widths
[0].org
);
219 *(bufp
++) = HIGH(default_width
);
220 *(bufp
++) = LOW(default_width
);
223 for (j
= 0; j
< hwidth_count
; j
++)
225 if (haxis
->widths
[j
].org
> 0xFFFF)
227 *(bufp
++) = HIGH(haxis
->widths
[j
].org
);
228 *(bufp
++) = LOW(haxis
->widths
[j
].org
);
231 /* vertical standard width */
232 if (vwidth_count
> 0)
234 *(bufp
++) = HIGH(vaxis
->widths
[0].org
);
235 *(bufp
++) = LOW(vaxis
->widths
[0].org
);
239 *(bufp
++) = HIGH(default_width
);
240 *(bufp
++) = LOW(default_width
);
243 for (j
= 0; j
< vwidth_count
; j
++)
245 if (vaxis
->widths
[j
].org
> 0xFFFF)
247 *(bufp
++) = HIGH(vaxis
->widths
[j
].org
);
248 *(bufp
++) = LOW(vaxis
->widths
[j
].org
);
251 data
->cvt_blue_adjustment_offsets
[i
] = 0xFFFFU
;
253 for (j
= 0; j
< blue_count
; j
++)
255 if (vaxis
->blues
[j
].ref
.org
> 0xFFFF)
257 *(bufp
++) = HIGH(vaxis
->blues
[j
].ref
.org
);
258 *(bufp
++) = LOW(vaxis
->blues
[j
].ref
.org
);
261 for (j
= 0; j
< blue_count
; j
++)
263 if (vaxis
->blues
[j
].shoot
.org
> 0xFFFF)
265 *(bufp
++) = HIGH(vaxis
->blues
[j
].shoot
.org
);
266 *(bufp
++) = LOW(vaxis
->blues
[j
].shoot
.org
);
268 if (vaxis
->blues
[j
].flags
& TA_LATIN_BLUE_ADJUSTMENT
)
269 data
->cvt_blue_adjustment_offsets
[i
] = j
;
272 data
->cvt_horz_width_sizes
[i
] = hwidth_count
;
273 data
->cvt_vert_width_sizes
[i
] = vwidth_count
;
274 data
->cvt_blue_zone_sizes
[i
] = blue_count
;
284 return TA_Err_Hinter_Overflow
;
289 TA_sfnt_build_cvt_table(SFNT
* sfnt
,
294 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
295 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
301 error
= TA_sfnt_add_table_info(sfnt
);
305 /* `glyf', `cvt', `fpgm', and `prep' are always used in parallel */
306 if (glyf_table
->processed
)
308 sfnt
->table_infos
[sfnt
->num_table_infos
- 1] = data
->cvt_idx
;
312 error
= TA_table_build_cvt(&cvt_buf
, &cvt_len
, sfnt
, font
);
316 /* in case of success, `cvt_buf' gets linked */
317 /* and is eventually freed in `TA_font_unload' */
318 error
= TA_font_add_table(font
,
319 &sfnt
->table_infos
[sfnt
->num_table_infos
- 1],
320 TTAG_cvt
, cvt_len
, cvt_buf
);
324 data
->cvt_idx
= sfnt
->table_infos
[sfnt
->num_table_infos
- 1];