4 * Copyright (C) 2011-2017 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
;
30 error
= FT_Select_Charmap(face
, FT_ENCODING_UNICODE
);
35 error
= FT_Select_Charmap(face
, FT_ENCODING_MS_SYMBOL
);
37 return TA_Err_Missing_Symbol_CMap
;
40 return TA_Err_Missing_Unicode_CMap
;
44 TA_FaceGlobals globals
= (TA_FaceGlobals
)sfnt
->face
->autohint
.data
;
45 FT_UShort
* gstyles
= globals
->glyph_styles
;
47 TA_StyleClass style_class
= ta_style_classes
[style_idx
];
48 TA_ScriptClass script_class
= ta_script_classes
[style_class
->script
];
50 TA_StyleMetricsRec dummy
;
56 /* we don't have a `TA_Loader' object yet */
57 dummy
.globals
= globals
;
58 dummy
.style_class
= style_class
;
60 p
= script_class
->standard_charstring
;
61 shaper_buf
= ta_shaper_buf_create(face
);
64 * We check more than a single standard character to catch features
65 * like `c2sc' (small caps from caps) that don't contain lowercase
66 * letters by definition, or other features that mainly operate on
79 /* reject input that maps to more than a single glyph */
80 p
= ta_shaper_get_cluster(p
, &dummy
, shaper_buf
, &num_idx
);
84 /* otherwise exit loop if we have a result */
85 glyph_index
= ta_shaper_get_elem(&dummy
,
94 ta_shaper_buf_destroy(face
, shaper_buf
);
98 if (font
->fallback_style
== style_idx
)
100 /* Having TA_STYLE_NONE_DFLT as the fallback script means */
101 /* hinting without default characters */
102 /* (and without script-specific blue zones), so we proceed */
103 if (style_idx
== TA_STYLE_NONE_DFLT
)
106 /* in case of a symbol font, we also proceed */
111 /* no standard characters to set up this style */
112 return TA_Err_Missing_Glyph
;
116 * We now know that HarfBuzz can access the standard character in the
117 * current OpenType feature. However, this doesn't guarantee that there
118 * actually *is* a standard character in the corresponding coverage,
119 * since glyphs shifted with data from the GPOS table are ignored in the
120 * coverage (but neverless used to derive stem widths). For this
121 * reason, search an arbitrary character from the current coverage to
122 * trigger the coverage's metrics computation.
124 if ((gstyles
[glyph_index
] & TA_STYLE_MASK
) != style_idx
)
129 for (i
= 0; i
< (FT_ULong
)globals
->glyph_count
; i
++)
131 if ((gstyles
[i
] & TA_STYLE_MASK
) == style_idx
)
135 if (i
== (FT_ULong
)globals
->glyph_count
)
136 return TA_Err_Missing_Glyph
;
143 load_flags
= 1 << 29; /* vertical hinting only */
144 error
= ta_loader_load_glyph(font
, face
, (FT_UInt
)glyph_index
, load_flags
);
151 TA_table_build_cvt(FT_Byte
** cvt
,
156 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
157 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
162 FT_UInt hwidth_count
;
163 FT_UInt vwidth_count
;
176 /* loop over all styles and collect the relevant CVT data */
177 /* to compute the necessary array sizes and meta-information */
182 data
->num_used_styles
= 0;
184 for (i
= 0; i
< TA_STYLE_MAX
; i
++)
186 error
= TA_sfnt_compute_global_hints(sfnt
, font
, (TA_Style
)i
);
187 if (error
== TA_Err_Missing_Glyph
)
189 TA_FaceGlobals globals
= (TA_FaceGlobals
)sfnt
->face
->autohint
.data
;
190 FT_UShort
* gstyles
= globals
->glyph_styles
;
194 data
->style_ids
[i
] = 0xFFFFU
;
196 /* remove all references to this style; */
197 /* otherwise blue zones are computed later on, which we don't want */
198 for (nn
= 0; nn
< globals
->glyph_count
; nn
++)
200 if ((gstyles
[nn
] & TA_STYLE_MASK
) == i
)
202 gstyles
[nn
] &= ~TA_STYLE_MASK
;
203 gstyles
[nn
] |= globals
->font
->fallback_style
;
212 data
->style_ids
[i
] = data
->num_used_styles
++;
214 /* XXX: generalize this to handle other metrics also */
215 haxis
= &((TA_LatinMetrics
)font
->loader
->hints
.metrics
)->axis
[0];
216 vaxis
= &((TA_LatinMetrics
)font
->loader
->hints
.metrics
)->axis
[1];
218 hwidth_count
+= haxis
->width_count
;
219 vwidth_count
+= vaxis
->width_count
;
221 blue_count
+= vaxis
->blue_count
;
222 /* if windows compatibility mode is active */
223 /* we add two artificial blue zones at the end of the array */
224 /* that are not part of `vaxis->blue_count' */
225 if (font
->windows_compatibility
)
229 /* exit if the font doesn't contain a single supported style, */
230 /* and we don't have a symbol font */
231 if (!data
->num_used_styles
&& !font
->symbol
)
232 return TA_Err_Missing_Glyph
;
234 buf_len
= cvtl_max_runtime
/* runtime values 1 */
235 + data
->num_used_styles
/* runtime values 2 (for scaling) */
236 + 2 * data
->num_used_styles
/* runtime values 3 (blue data) */
237 + 2 * data
->num_used_styles
/* vert. and horiz. std. widths */
240 + 2 * blue_count
; /* round and flat blue zones */
241 buf_len
<<= 1; /* we have 16bit values */
243 /* buffer length must be a multiple of four */
244 len
= (buf_len
+ 3) & ~3U;
245 buf
= (FT_Byte
*)malloc(len
);
247 return FT_Err_Out_Of_Memory
;
249 /* pad end of buffer with zeros */
257 * some CVT values are initialized (and modified) at runtime:
259 * (1) the `cvtl_xxx' values (see `tabytecode.h')
260 * (2) a scaling value for each style
261 * (3) offset and size of the vertical widths array
262 * (needed by `bci_{smooth,strong}_stem_width') for each style
264 for (i
= 0; i
< (cvtl_max_runtime
265 + data
->num_used_styles
266 + 2 * data
->num_used_styles
) * 2; i
++)
269 cvt_offset
= (FT_UInt
)(bufp
- buf
);
271 /* loop again over all styles and copy CVT data */
272 for (i
= 0; i
< TA_STYLE_MAX
; i
++)
274 FT_UInt default_width
= 50 * sfnt
->face
->units_per_EM
/ 2048;
277 /* collect offsets */
278 data
->cvt_offsets
[i
] = ((FT_UInt
)(bufp
- buf
) - cvt_offset
) >> 1;
280 error
= TA_sfnt_compute_global_hints(sfnt
, font
, (TA_Style
)i
);
281 if (error
== TA_Err_Missing_Glyph
)
286 haxis
= &((TA_LatinMetrics
)font
->loader
->hints
.metrics
)->axis
[0];
287 vaxis
= &((TA_LatinMetrics
)font
->loader
->hints
.metrics
)->axis
[1];
289 hwidth_count
= haxis
->width_count
;
290 vwidth_count
= vaxis
->width_count
;
292 blue_count
= vaxis
->blue_count
;
293 if (font
->windows_compatibility
)
294 blue_count
+= 2; /* with artificial blue zones */
296 /* horizontal standard width */
297 if (hwidth_count
> 0)
299 *(bufp
++) = HIGH(haxis
->widths
[0].org
);
300 *(bufp
++) = LOW(haxis
->widths
[0].org
);
304 *(bufp
++) = HIGH(default_width
);
305 *(bufp
++) = LOW(default_width
);
308 for (j
= 0; j
< hwidth_count
; j
++)
310 if (haxis
->widths
[j
].org
> 0xFFFF)
312 *(bufp
++) = HIGH(haxis
->widths
[j
].org
);
313 *(bufp
++) = LOW(haxis
->widths
[j
].org
);
316 /* vertical standard width */
317 if (vwidth_count
> 0)
319 *(bufp
++) = HIGH(vaxis
->widths
[0].org
);
320 *(bufp
++) = LOW(vaxis
->widths
[0].org
);
324 *(bufp
++) = HIGH(default_width
);
325 *(bufp
++) = LOW(default_width
);
328 for (j
= 0; j
< vwidth_count
; j
++)
330 if (vaxis
->widths
[j
].org
> 0xFFFF)
332 *(bufp
++) = HIGH(vaxis
->widths
[j
].org
);
333 *(bufp
++) = LOW(vaxis
->widths
[j
].org
);
336 data
->cvt_blue_adjustment_offsets
[i
] = 0xFFFFU
;
338 for (j
= 0; j
< blue_count
; j
++)
340 if (vaxis
->blues
[j
].ref
.org
> 0xFFFF)
342 *(bufp
++) = HIGH(vaxis
->blues
[j
].ref
.org
);
343 *(bufp
++) = LOW(vaxis
->blues
[j
].ref
.org
);
346 for (j
= 0; j
< blue_count
; j
++)
348 if (vaxis
->blues
[j
].shoot
.org
> 0xFFFF)
350 *(bufp
++) = HIGH(vaxis
->blues
[j
].shoot
.org
);
351 *(bufp
++) = LOW(vaxis
->blues
[j
].shoot
.org
);
353 if (vaxis
->blues
[j
].flags
& TA_LATIN_BLUE_ADJUSTMENT
)
354 data
->cvt_blue_adjustment_offsets
[i
] = j
;
357 data
->cvt_horz_width_sizes
[i
] = hwidth_count
;
358 data
->cvt_vert_width_sizes
[i
] = vwidth_count
;
359 data
->cvt_blue_zone_sizes
[i
] = blue_count
;
369 return TA_Err_Hinter_Overflow
;
374 TA_sfnt_build_cvt_table(SFNT
* sfnt
,
379 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
380 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
386 error
= TA_sfnt_add_table_info(sfnt
);
390 /* `glyf', `cvt', `fpgm', and `prep' are always used in parallel */
391 if (glyf_table
->processed
)
393 sfnt
->table_infos
[sfnt
->num_table_infos
- 1] = data
->cvt_idx
;
397 error
= TA_table_build_cvt(&cvt_buf
, &cvt_len
, sfnt
, font
);
401 /* in case of success, `cvt_buf' gets linked */
402 /* and is eventually freed in `TA_font_unload' */
403 error
= TA_font_add_table(font
,
404 &sfnt
->table_infos
[sfnt
->num_table_infos
- 1],
405 TTAG_cvt
, cvt_len
, cvt_buf
);
409 data
->cvt_idx
= sfnt
->table_infos
[sfnt
->num_table_infos
- 1];