OLD | NEW |
1 /***************************************************************************/ | 1 /***************************************************************************/ |
2 /* */ | 2 /* */ |
3 /* afglobal.c */ | 3 /* afglobal.c */ |
4 /* */ | 4 /* */ |
5 /* Auto-fitter routines to compute global hinting values (body). */ | 5 /* Auto-fitter routines to compute global hinting values (body). */ |
6 /* */ | 6 /* */ |
7 /* Copyright 2003-2011 by */ | 7 /* Copyright 2003-2013 by */ |
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ | 8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
9 /* */ | 9 /* */ |
10 /* This file is part of the FreeType project, and may only be used, */ | 10 /* This file is part of the FreeType project, and may only be used, */ |
11 /* modified, and distributed under the terms of the FreeType project */ | 11 /* modified, and distributed under the terms of the FreeType project */ |
12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ | 12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
13 /* this file you indicate that you have read the license and */ | 13 /* this file you indicate that you have read the license and */ |
14 /* understand and accept it fully. */ | 14 /* understand and accept it fully. */ |
15 /* */ | 15 /* */ |
16 /***************************************************************************/ | 16 /***************************************************************************/ |
17 | 17 |
(...skipping 24 matching lines...) Expand all Loading... |
42 &af_latin2_script_class, | 42 &af_latin2_script_class, |
43 #endif | 43 #endif |
44 &af_latin_script_class, | 44 &af_latin_script_class, |
45 &af_cjk_script_class, | 45 &af_cjk_script_class, |
46 &af_indic_script_class, | 46 &af_indic_script_class, |
47 NULL /* do not remove */ | 47 NULL /* do not remove */ |
48 }; | 48 }; |
49 | 49 |
50 #endif /* !FT_CONFIG_OPTION_PIC */ | 50 #endif /* !FT_CONFIG_OPTION_PIC */ |
51 | 51 |
52 /* index of default script in `af_script_classes' */ | |
53 #define AF_SCRIPT_LIST_DEFAULT 2 | |
54 /* a bit mask indicating an uncovered glyph */ | |
55 #define AF_SCRIPT_LIST_NONE 0x7F | |
56 /* if this flag is set, we have an ASCII digit */ | |
57 #define AF_DIGIT 0x80 | |
58 | |
59 | |
60 /* | |
61 * Note that glyph_scripts[] is used to map each glyph into | |
62 * an index into the `af_script_classes' array. | |
63 * | |
64 */ | |
65 typedef struct AF_FaceGlobalsRec_ | |
66 { | |
67 FT_Face face; | |
68 FT_Long glyph_count; /* same as face->num_glyphs */ | |
69 FT_Byte* glyph_scripts; | |
70 | |
71 AF_ScriptMetrics metrics[AF_SCRIPT_MAX]; | |
72 | |
73 } AF_FaceGlobalsRec; | |
74 | |
75 | 52 |
76 /* Compute the script index of each glyph within a given face. */ | 53 /* Compute the script index of each glyph within a given face. */ |
77 | 54 |
78 static FT_Error | 55 static FT_Error |
79 af_face_globals_compute_script_coverage( AF_FaceGlobals globals ) | 56 af_face_globals_compute_script_coverage( AF_FaceGlobals globals ) |
80 { | 57 { |
81 FT_Error error = AF_Err_Ok; | 58 FT_Error error; |
82 FT_Face face = globals->face; | 59 FT_Face face = globals->face; |
83 FT_CharMap old_charmap = face->charmap; | 60 FT_CharMap old_charmap = face->charmap; |
84 FT_Byte* gscripts = globals->glyph_scripts; | 61 FT_Byte* gscripts = globals->glyph_scripts; |
85 FT_UInt ss, i; | 62 FT_UInt ss; |
| 63 FT_UInt i; |
86 | 64 |
87 | 65 |
88 /* the value AF_SCRIPT_LIST_NONE means `uncovered glyph' */ | 66 /* the value AF_SCRIPT_NONE means `uncovered glyph' */ |
89 FT_MEM_SET( globals->glyph_scripts, | 67 FT_MEM_SET( globals->glyph_scripts, |
90 AF_SCRIPT_LIST_NONE, | 68 AF_SCRIPT_NONE, |
91 globals->glyph_count ); | 69 globals->glyph_count ); |
92 | 70 |
93 error = FT_Select_Charmap( face, FT_ENCODING_UNICODE ); | 71 error = FT_Select_Charmap( face, FT_ENCODING_UNICODE ); |
94 if ( error ) | 72 if ( error ) |
95 { | 73 { |
96 /* | 74 /* |
97 * Ignore this error; we simply use the default script. | 75 * Ignore this error; we simply use the fallback script. |
98 * XXX: Shouldn't we rather disable hinting? | 76 * XXX: Shouldn't we rather disable hinting? |
99 */ | 77 */ |
100 error = AF_Err_Ok; | 78 error = FT_Err_Ok; |
101 goto Exit; | 79 goto Exit; |
102 } | 80 } |
103 | 81 |
104 /* scan each script in a Unicode charmap */ | 82 /* scan each script in a Unicode charmap */ |
105 for ( ss = 0; AF_SCRIPT_CLASSES_GET[ss]; ss++ ) | 83 for ( ss = 0; AF_SCRIPT_CLASSES_GET[ss]; ss++ ) |
106 { | 84 { |
107 AF_ScriptClass clazz = AF_SCRIPT_CLASSES_GET[ss]; | 85 AF_ScriptClass clazz = AF_SCRIPT_CLASSES_GET[ss]; |
108 AF_Script_UniRange range; | 86 AF_Script_UniRange range; |
109 | 87 |
110 | 88 |
111 if ( clazz->script_uni_ranges == NULL ) | 89 if ( clazz->script_uni_ranges == NULL ) |
112 continue; | 90 continue; |
113 | 91 |
114 /* | 92 /* |
115 * Scan all unicode points in the range and set the corresponding | 93 * Scan all Unicode points in the range and set the corresponding |
116 * glyph script index. | 94 * glyph script index. |
117 */ | 95 */ |
118 for ( range = clazz->script_uni_ranges; range->first != 0; range++ ) | 96 for ( range = clazz->script_uni_ranges; range->first != 0; range++ ) |
119 { | 97 { |
120 FT_ULong charcode = range->first; | 98 FT_ULong charcode = range->first; |
121 FT_UInt gindex; | 99 FT_UInt gindex; |
122 | 100 |
123 | 101 |
124 gindex = FT_Get_Char_Index( face, charcode ); | 102 gindex = FT_Get_Char_Index( face, charcode ); |
125 | 103 |
126 if ( gindex != 0 && | 104 if ( gindex != 0 && |
127 gindex < (FT_ULong)globals->glyph_count && | 105 gindex < (FT_ULong)globals->glyph_count && |
128 gscripts[gindex] == AF_SCRIPT_LIST_NONE ) | 106 gscripts[gindex] == AF_SCRIPT_NONE ) |
129 gscripts[gindex] = (FT_Byte)ss; | 107 gscripts[gindex] = (FT_Byte)ss; |
130 | 108 |
131 for (;;) | 109 for (;;) |
132 { | 110 { |
133 charcode = FT_Get_Next_Char( face, charcode, &gindex ); | 111 charcode = FT_Get_Next_Char( face, charcode, &gindex ); |
134 | 112 |
135 if ( gindex == 0 || charcode > range->last ) | 113 if ( gindex == 0 || charcode > range->last ) |
136 break; | 114 break; |
137 | 115 |
138 if ( gindex < (FT_ULong)globals->glyph_count && | 116 if ( gindex < (FT_ULong)globals->glyph_count && |
139 gscripts[gindex] == AF_SCRIPT_LIST_NONE ) | 117 gscripts[gindex] == AF_SCRIPT_NONE ) |
140 gscripts[gindex] = (FT_Byte)ss; | 118 gscripts[gindex] = (FT_Byte)ss; |
141 } | 119 } |
142 } | 120 } |
143 } | 121 } |
144 | 122 |
145 /* mark ASCII digits */ | 123 /* mark ASCII digits */ |
146 for ( i = 0x30; i <= 0x39; i++ ) | 124 for ( i = 0x30; i <= 0x39; i++ ) |
147 { | 125 { |
148 FT_UInt gindex = FT_Get_Char_Index( face, i ); | 126 FT_UInt gindex = FT_Get_Char_Index( face, i ); |
149 | 127 |
150 | 128 |
151 if ( gindex != 0 && gindex < (FT_ULong)globals->glyph_count ) | 129 if ( gindex != 0 && gindex < (FT_ULong)globals->glyph_count ) |
152 gscripts[gindex] |= AF_DIGIT; | 130 gscripts[gindex] |= AF_DIGIT; |
153 } | 131 } |
154 | 132 |
155 Exit: | 133 Exit: |
156 /* | 134 /* |
157 * By default, all uncovered glyphs are set to the latin script. | 135 * By default, all uncovered glyphs are set to the fallback script. |
158 * XXX: Shouldn't we disable hinting or do something similar? | 136 * XXX: Shouldn't we disable hinting or do something similar? |
159 */ | 137 */ |
| 138 if ( globals->module->fallback_script != AF_SCRIPT_NONE ) |
160 { | 139 { |
161 FT_Long nn; | 140 FT_Long nn; |
162 | 141 |
163 | 142 |
164 for ( nn = 0; nn < globals->glyph_count; nn++ ) | 143 for ( nn = 0; nn < globals->glyph_count; nn++ ) |
165 { | 144 { |
166 if ( ( gscripts[nn] & ~AF_DIGIT ) == AF_SCRIPT_LIST_NONE ) | 145 if ( ( gscripts[nn] & ~AF_DIGIT ) == AF_SCRIPT_NONE ) |
167 { | 146 { |
168 gscripts[nn] &= ~AF_SCRIPT_LIST_NONE; | 147 gscripts[nn] &= ~AF_SCRIPT_NONE; |
169 gscripts[nn] |= AF_SCRIPT_LIST_DEFAULT; | 148 gscripts[nn] |= globals->module->fallback_script; |
170 } | 149 } |
171 } | 150 } |
172 } | 151 } |
173 | 152 |
174 FT_Set_Charmap( face, old_charmap ); | 153 FT_Set_Charmap( face, old_charmap ); |
175 return error; | 154 return error; |
176 } | 155 } |
177 | 156 |
178 | 157 |
179 FT_LOCAL_DEF( FT_Error ) | 158 FT_LOCAL_DEF( FT_Error ) |
180 af_face_globals_new( FT_Face face, | 159 af_face_globals_new( FT_Face face, |
181 AF_FaceGlobals *aglobals ) | 160 AF_FaceGlobals *aglobals, |
| 161 AF_Module module ) |
182 { | 162 { |
183 FT_Error error; | 163 FT_Error error; |
184 FT_Memory memory; | 164 FT_Memory memory; |
185 AF_FaceGlobals globals = NULL; | 165 AF_FaceGlobals globals = NULL; |
186 | 166 |
187 | 167 |
188 memory = face->memory; | 168 memory = face->memory; |
189 | 169 |
190 if ( !FT_ALLOC( globals, sizeof ( *globals ) + | 170 if ( FT_ALLOC( globals, sizeof ( *globals ) + |
191 face->num_glyphs * sizeof ( FT_Byte ) ) ) | 171 face->num_glyphs * sizeof ( FT_Byte ) ) ) |
| 172 goto Exit; |
| 173 |
| 174 globals->face = face; |
| 175 globals->glyph_count = face->num_glyphs; |
| 176 globals->glyph_scripts = (FT_Byte*)( globals + 1 ); |
| 177 globals->module = module; |
| 178 |
| 179 error = af_face_globals_compute_script_coverage( globals ); |
| 180 if ( error ) |
192 { | 181 { |
193 globals->face = face; | 182 af_face_globals_free( globals ); |
194 globals->glyph_count = face->num_glyphs; | 183 globals = NULL; |
195 globals->glyph_scripts = (FT_Byte*)( globals + 1 ); | |
196 | |
197 error = af_face_globals_compute_script_coverage( globals ); | |
198 if ( error ) | |
199 { | |
200 af_face_globals_free( globals ); | |
201 globals = NULL; | |
202 } | |
203 } | 184 } |
204 | 185 |
| 186 globals->increase_x_height = AF_PROP_INCREASE_X_HEIGHT_MAX; |
| 187 |
| 188 Exit: |
205 *aglobals = globals; | 189 *aglobals = globals; |
206 return error; | 190 return error; |
207 } | 191 } |
208 | 192 |
209 | 193 |
210 FT_LOCAL_DEF( void ) | 194 FT_LOCAL_DEF( void ) |
211 af_face_globals_free( AF_FaceGlobals globals ) | 195 af_face_globals_free( AF_FaceGlobals globals ) |
212 { | 196 { |
213 if ( globals ) | 197 if ( globals ) |
214 { | 198 { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 FT_UInt gindex, | 230 FT_UInt gindex, |
247 FT_UInt options, | 231 FT_UInt options, |
248 AF_ScriptMetrics *ametrics ) | 232 AF_ScriptMetrics *ametrics ) |
249 { | 233 { |
250 AF_ScriptMetrics metrics = NULL; | 234 AF_ScriptMetrics metrics = NULL; |
251 FT_UInt gidx; | 235 FT_UInt gidx; |
252 AF_ScriptClass clazz; | 236 AF_ScriptClass clazz; |
253 FT_UInt script = options & 15; | 237 FT_UInt script = options & 15; |
254 const FT_Offset script_max = sizeof ( AF_SCRIPT_CLASSES_GET ) / | 238 const FT_Offset script_max = sizeof ( AF_SCRIPT_CLASSES_GET ) / |
255 sizeof ( AF_SCRIPT_CLASSES_GET[0] ); | 239 sizeof ( AF_SCRIPT_CLASSES_GET[0] ); |
256 FT_Error error = AF_Err_Ok; | 240 FT_Error error = FT_Err_Ok; |
257 | 241 |
258 | 242 |
259 if ( gindex >= (FT_ULong)globals->glyph_count ) | 243 if ( gindex >= (FT_ULong)globals->glyph_count ) |
260 { | 244 { |
261 error = AF_Err_Invalid_Argument; | 245 error = FT_THROW( Invalid_Argument ); |
262 goto Exit; | 246 goto Exit; |
263 } | 247 } |
264 | 248 |
265 gidx = script; | 249 gidx = script; |
266 if ( gidx == 0 || gidx + 1 >= script_max ) | 250 if ( gidx == 0 || gidx + 1 >= script_max ) |
267 gidx = globals->glyph_scripts[gindex] & AF_SCRIPT_LIST_NONE; | 251 gidx = globals->glyph_scripts[gindex] & AF_SCRIPT_NONE; |
268 | 252 |
269 clazz = AF_SCRIPT_CLASSES_GET[gidx]; | 253 clazz = AF_SCRIPT_CLASSES_GET[gidx]; |
270 if ( script == 0 ) | 254 if ( script == 0 ) |
271 script = clazz->script; | 255 script = clazz->script; |
272 | 256 |
273 metrics = globals->metrics[clazz->script]; | 257 metrics = globals->metrics[clazz->script]; |
274 if ( metrics == NULL ) | 258 if ( metrics == NULL ) |
275 { | 259 { |
276 /* create the global metrics object when needed */ | 260 /* create the global metrics object if necessary */ |
277 FT_Memory memory = globals->face->memory; | 261 FT_Memory memory = globals->face->memory; |
278 | 262 |
279 | 263 |
280 if ( FT_ALLOC( metrics, clazz->script_metrics_size ) ) | 264 if ( FT_ALLOC( metrics, clazz->script_metrics_size ) ) |
281 goto Exit; | 265 goto Exit; |
282 | 266 |
283 metrics->clazz = clazz; | 267 metrics->clazz = clazz; |
| 268 metrics->globals = globals; |
284 | 269 |
285 if ( clazz->script_metrics_init ) | 270 if ( clazz->script_metrics_init ) |
286 { | 271 { |
287 error = clazz->script_metrics_init( metrics, globals->face ); | 272 error = clazz->script_metrics_init( metrics, globals->face ); |
288 if ( error ) | 273 if ( error ) |
289 { | 274 { |
290 if ( clazz->script_metrics_done ) | 275 if ( clazz->script_metrics_done ) |
291 clazz->script_metrics_done( metrics ); | 276 clazz->script_metrics_done( metrics ); |
292 | 277 |
293 FT_FREE( metrics ); | 278 FT_FREE( metrics ); |
(...skipping 16 matching lines...) Expand all Loading... |
310 FT_UInt gindex ) | 295 FT_UInt gindex ) |
311 { | 296 { |
312 if ( gindex < (FT_ULong)globals->glyph_count ) | 297 if ( gindex < (FT_ULong)globals->glyph_count ) |
313 return (FT_Bool)( globals->glyph_scripts[gindex] & AF_DIGIT ); | 298 return (FT_Bool)( globals->glyph_scripts[gindex] & AF_DIGIT ); |
314 | 299 |
315 return (FT_Bool)0; | 300 return (FT_Bool)0; |
316 } | 301 } |
317 | 302 |
318 | 303 |
319 /* END */ | 304 /* END */ |
OLD | NEW |