| 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 |