4 * Copyright (C) 2011-2014 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
;
47 /* load standard character to trigger script initializations */
48 /* XXX make this configurable to use a different letter */
49 idx
= FT_Get_Char_Index(face
,
50 ta_script_classes
[script_idx
]->standard_char
);
52 return TA_Err_Missing_Glyph
;
55 load_flags
= 1 << 29; /* vertical hinting only */
56 error
= ta_loader_load_glyph(font
, face
, idx
, load_flags
);
63 TA_table_build_cvt(FT_Byte
** cvt
,
68 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
69 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
88 /* checking multiple scripts doesn't make sense for symbol fonts */
89 i_max
= font
->symbol
? 1 : TA_SCRIPT_MAX
;
91 /* loop over all scripts and collect the relevant CVT data */
92 /* to compute the necessary array sizes and meta-information */
97 data
->num_used_scripts
= 0;
99 for (i
= 0; i
< i_max
; i
++)
101 error
= TA_sfnt_compute_global_hints(sfnt
, font
, i
);
102 if (error
== TA_Err_Missing_Glyph
)
104 TA_FaceGlobals globals
= (TA_FaceGlobals
)sfnt
->face
->autohint
.data
;
105 FT_Byte
* gscripts
= globals
->glyph_scripts
;
109 data
->script_ids
[i
] = 0xFFFFU
;
111 /* remove all references to this script; */
112 /* otherwise blue zones are computed later on, which we don't want */
113 for (nn
= 0; nn
< globals
->glyph_count
; nn
++)
115 if ((gscripts
[nn
] & ~TA_DIGIT
) == i
)
117 gscripts
[nn
] &= ~TA_SCRIPT_UNASSIGNED
;
118 gscripts
[nn
] |= globals
->font
->fallback_script
;
127 data
->script_ids
[i
] = data
->num_used_scripts
++;
129 if (font
->loader
->hints
.metrics
->script_class
->script
== TA_SCRIPT_NONE
)
133 /* XXX: generalize this to handle other metrics also */
134 haxis
= &((TA_LatinMetrics
)font
->loader
->hints
.metrics
)->axis
[0];
135 vaxis
= &((TA_LatinMetrics
)font
->loader
->hints
.metrics
)->axis
[1];
137 hwidth_count
+= haxis
->width_count
;
138 vwidth_count
+= vaxis
->width_count
;
139 /* there are two artificial blue zones at the end of the array */
140 /* that are not part of `vaxis->blue_count' */
141 blue_count
+= vaxis
->blue_count
+ 2;
145 /* exit if the font doesn't contain a single supported script */
146 if (!data
->num_used_scripts
)
147 return TA_Err_Missing_Glyph
;
149 buf_len
= cvtl_max_runtime
/* runtime values 1 */
150 + data
->num_used_scripts
/* runtime values 2 (for scaling) */
151 + 2 * data
->num_used_scripts
/* runtime values 3 (blue data) */
152 + 2 * data
->num_used_scripts
/* vert. and horiz. std. widths */
155 + 2 * blue_count
; /* round and flat blue zones */
156 buf_len
<<= 1; /* we have 16bit values */
158 /* buffer length must be a multiple of four */
159 len
= (buf_len
+ 3) & ~3;
160 buf
= (FT_Byte
*)malloc(len
);
162 return FT_Err_Out_Of_Memory
;
164 /* pad end of buffer with zeros */
172 * some CVT values are initialized (and modified) at runtime:
174 * (1) the `cvtl_xxx' values (see `tabytecode.h')
175 * (2) a scaling value for each script
176 * (3) offset and size of the vertical widths array
177 * (needed by `bci_{smooth,strong}_stem_width') for each script
179 for (i
= 0; i
< (cvtl_max_runtime
180 + data
->num_used_scripts
181 + 2 * data
->num_used_scripts
) * 2; i
++)
184 cvt_offset
= bufp
- buf
;
186 /* loop again over all scripts and copy CVT data */
187 for (i
= 0; i
< i_max
; i
++)
189 /* collect offsets */
190 data
->cvt_offsets
[i
] = ((FT_UInt
)(bufp
- buf
) - cvt_offset
) >> 1;
192 error
= TA_sfnt_compute_global_hints(sfnt
, font
, i
);
193 if (error
== TA_Err_Missing_Glyph
)
198 if (font
->loader
->hints
.metrics
->script_class
->script
== TA_SCRIPT_NONE
)
209 haxis
= &((TA_LatinMetrics
)font
->loader
->hints
.metrics
)->axis
[0];
210 vaxis
= &((TA_LatinMetrics
)font
->loader
->hints
.metrics
)->axis
[1];
212 hwidth_count
= haxis
->width_count
;
213 vwidth_count
= vaxis
->width_count
;
214 blue_count
= vaxis
->blue_count
+ 2; /* with artificial blue zones */
217 /* horizontal standard width */
218 if (hwidth_count
> 0)
220 *(bufp
++) = HIGH(haxis
->widths
[0].org
);
221 *(bufp
++) = LOW(haxis
->widths
[0].org
);
229 for (j
= 0; j
< hwidth_count
; j
++)
231 if (haxis
->widths
[j
].org
> 0xFFFF)
233 *(bufp
++) = HIGH(haxis
->widths
[j
].org
);
234 *(bufp
++) = LOW(haxis
->widths
[j
].org
);
237 /* vertical standard width */
238 if (vwidth_count
> 0)
240 *(bufp
++) = HIGH(vaxis
->widths
[0].org
);
241 *(bufp
++) = LOW(vaxis
->widths
[0].org
);
249 for (j
= 0; j
< vwidth_count
; j
++)
251 if (vaxis
->widths
[j
].org
> 0xFFFF)
253 *(bufp
++) = HIGH(vaxis
->widths
[j
].org
);
254 *(bufp
++) = LOW(vaxis
->widths
[j
].org
);
257 data
->cvt_blue_adjustment_offsets
[i
] = 0xFFFFU
;
259 for (j
= 0; j
< blue_count
; j
++)
261 if (vaxis
->blues
[j
].ref
.org
> 0xFFFF)
263 *(bufp
++) = HIGH(vaxis
->blues
[j
].ref
.org
);
264 *(bufp
++) = LOW(vaxis
->blues
[j
].ref
.org
);
267 for (j
= 0; j
< blue_count
; j
++)
269 if (vaxis
->blues
[j
].shoot
.org
> 0xFFFF)
271 *(bufp
++) = HIGH(vaxis
->blues
[j
].shoot
.org
);
272 *(bufp
++) = LOW(vaxis
->blues
[j
].shoot
.org
);
274 if (vaxis
->blues
[j
].flags
& TA_LATIN_BLUE_ADJUSTMENT
)
275 data
->cvt_blue_adjustment_offsets
[i
] = j
;
278 data
->cvt_horz_width_sizes
[i
] = hwidth_count
;
279 data
->cvt_vert_width_sizes
[i
] = vwidth_count
;
280 data
->cvt_blue_zone_sizes
[i
] = blue_count
;
290 return TA_Err_Hinter_Overflow
;
295 TA_sfnt_build_cvt_table(SFNT
* sfnt
,
300 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
301 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
307 error
= TA_sfnt_add_table_info(sfnt
);
311 /* `glyf', `cvt', `fpgm', and `prep' are always used in parallel */
312 if (glyf_table
->processed
)
314 sfnt
->table_infos
[sfnt
->num_table_infos
- 1] = data
->cvt_idx
;
318 error
= TA_table_build_cvt(&cvt_buf
, &cvt_len
, sfnt
, font
);
322 /* in case of success, `cvt_buf' gets linked */
323 /* and is eventually freed in `TA_font_unload' */
324 error
= TA_font_add_table(font
,
325 &sfnt
->table_infos
[sfnt
->num_table_infos
- 1],
326 TTAG_cvt
, cvt_len
, cvt_buf
);
330 data
->cvt_idx
= sfnt
->table_infos
[sfnt
->num_table_infos
- 1];