00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <ft2build.h>
00020 #include FT_INTERNAL_OBJECTS_H
00021 #include FT_SERVICE_POSTSCRIPT_CMAPS_H
00022
00023 #include "psmodule.h"
00024 #include "pstables.h"
00025
00026 #include "psnamerr.h"
00027 #include "pspic.h"
00028
00029
00030 #ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
00031
00032
00033 #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
00034
00035
00036 #define VARIANT_BIT 0x80000000UL
00037 #define BASE_GLYPH( code ) ( (FT_UInt32)( (code) & ~VARIANT_BIT ) )
00038
00039
00040
00041
00042
00043
00044
00045 static FT_UInt32
00046 ps_unicode_value( const char* glyph_name )
00047 {
00048
00049
00050 if ( glyph_name[0] == 'u' &&
00051 glyph_name[1] == 'n' &&
00052 glyph_name[2] == 'i' )
00053 {
00054
00055
00056
00057
00058
00059
00060 FT_Int count;
00061 FT_UInt32 value = 0;
00062 const char* p = glyph_name + 3;
00063
00064
00065 for ( count = 4; count > 0; count--, p++ )
00066 {
00067 char c = *p;
00068 unsigned int d;
00069
00070
00071 d = (unsigned char)c - '0';
00072 if ( d >= 10 )
00073 {
00074 d = (unsigned char)c - 'A';
00075 if ( d >= 6 )
00076 d = 16;
00077 else
00078 d += 10;
00079 }
00080
00081
00082
00083
00084 if ( d >= 16 )
00085 break;
00086
00087 value = ( value << 4 ) + d;
00088 }
00089
00090
00091 if ( count == 0 )
00092 {
00093 if ( *p == '\0' )
00094 return value;
00095 if ( *p == '.' )
00096 return (FT_UInt32)( value | VARIANT_BIT );
00097 }
00098 }
00099
00100
00101
00102 if ( glyph_name[0] == 'u' )
00103 {
00104 FT_Int count;
00105 FT_UInt32 value = 0;
00106 const char* p = glyph_name + 1;
00107
00108
00109 for ( count = 6; count > 0; count--, p++ )
00110 {
00111 char c = *p;
00112 unsigned int d;
00113
00114
00115 d = (unsigned char)c - '0';
00116 if ( d >= 10 )
00117 {
00118 d = (unsigned char)c - 'A';
00119 if ( d >= 6 )
00120 d = 16;
00121 else
00122 d += 10;
00123 }
00124
00125 if ( d >= 16 )
00126 break;
00127
00128 value = ( value << 4 ) + d;
00129 }
00130
00131 if ( count <= 2 )
00132 {
00133 if ( *p == '\0' )
00134 return value;
00135 if ( *p == '.' )
00136 return (FT_UInt32)( value | VARIANT_BIT );
00137 }
00138 }
00139
00140
00141
00142 {
00143 const char* p = glyph_name;
00144 const char* dot = NULL;
00145
00146
00147 for ( ; *p; p++ )
00148 {
00149 if ( *p == '.' && p > glyph_name )
00150 {
00151 dot = p;
00152 break;
00153 }
00154 }
00155
00156
00157 if ( !dot )
00158 return (FT_UInt32)ft_get_adobe_glyph_index( glyph_name, p );
00159 else
00160 return (FT_UInt32)( ft_get_adobe_glyph_index( glyph_name, dot ) |
00161 VARIANT_BIT );
00162 }
00163 }
00164
00165
00166
00167 FT_CALLBACK_DEF( int )
00168 compare_uni_maps( const void* a,
00169 const void* b )
00170 {
00171 PS_UniMap* map1 = (PS_UniMap*)a;
00172 PS_UniMap* map2 = (PS_UniMap*)b;
00173 FT_UInt32 unicode1 = BASE_GLYPH( map1->unicode );
00174 FT_UInt32 unicode2 = BASE_GLYPH( map2->unicode );
00175
00176
00177
00178 if ( unicode1 == unicode2 )
00179 {
00180 if ( map1->unicode > map2->unicode )
00181 return 1;
00182 else if ( map1->unicode < map2->unicode )
00183 return -1;
00184 else
00185 return 0;
00186 }
00187 else
00188 {
00189 if ( unicode1 > unicode2 )
00190 return 1;
00191 else if ( unicode1 < unicode2 )
00192 return -1;
00193 else
00194 return 0;
00195 }
00196 }
00197
00198
00199
00200
00201
00202 #define EXTRA_GLYPH_LIST_SIZE 10
00203
00204 static const FT_UInt32 ft_extra_glyph_unicodes[EXTRA_GLYPH_LIST_SIZE] =
00205 {
00206
00207 0x0394,
00208 0x03A9,
00209 0x2215,
00210 0x00AD,
00211 0x02C9,
00212 0x03BC,
00213 0x2219,
00214 0x00A0,
00215
00216 0x021A,
00217 0x021B
00218 };
00219
00220 static const char ft_extra_glyph_names[] =
00221 {
00222 'D','e','l','t','a',0,
00223 'O','m','e','g','a',0,
00224 'f','r','a','c','t','i','o','n',0,
00225 'h','y','p','h','e','n',0,
00226 'm','a','c','r','o','n',0,
00227 'm','u',0,
00228 'p','e','r','i','o','d','c','e','n','t','e','r','e','d',0,
00229 's','p','a','c','e',0,
00230 'T','c','o','m','m','a','a','c','c','e','n','t',0,
00231 't','c','o','m','m','a','a','c','c','e','n','t',0
00232 };
00233
00234 static const FT_Int
00235 ft_extra_glyph_name_offsets[EXTRA_GLYPH_LIST_SIZE] =
00236 {
00237 0,
00238 6,
00239 12,
00240 21,
00241 28,
00242 35,
00243 38,
00244 53,
00245 59,
00246 72
00247 };
00248
00249
00250 static void
00251 ps_check_extra_glyph_name( const char* gname,
00252 FT_UInt glyph,
00253 FT_UInt* extra_glyphs,
00254 FT_UInt *states )
00255 {
00256 FT_UInt n;
00257
00258
00259 for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ )
00260 {
00261 if ( ft_strcmp( ft_extra_glyph_names +
00262 ft_extra_glyph_name_offsets[n], gname ) == 0 )
00263 {
00264 if ( states[n] == 0 )
00265 {
00266
00267 states[n] = 1;
00268 extra_glyphs[n] = glyph;
00269 }
00270
00271 return;
00272 }
00273 }
00274 }
00275
00276
00277 static void
00278 ps_check_extra_glyph_unicode( FT_UInt32 uni_char,
00279 FT_UInt *states )
00280 {
00281 FT_UInt n;
00282
00283
00284 for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ )
00285 {
00286 if ( uni_char == ft_extra_glyph_unicodes[n] )
00287 {
00288
00289 states[n] = 2;
00290
00291 return;
00292 }
00293 }
00294 }
00295
00296
00297
00298 static FT_Error
00299 ps_unicodes_init( FT_Memory memory,
00300 PS_Unicodes table,
00301 FT_UInt num_glyphs,
00302 PS_GetGlyphNameFunc get_glyph_name,
00303 PS_FreeGlyphNameFunc free_glyph_name,
00304 FT_Pointer glyph_data )
00305 {
00306 FT_Error error;
00307
00308 FT_UInt extra_glyph_list_states[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
00309 FT_UInt extra_glyphs[EXTRA_GLYPH_LIST_SIZE];
00310
00311
00312
00313 table->num_maps = 0;
00314 table->maps = 0;
00315
00316 if ( !FT_NEW_ARRAY( table->maps, num_glyphs + EXTRA_GLYPH_LIST_SIZE ) )
00317 {
00318 FT_UInt n;
00319 FT_UInt count;
00320 PS_UniMap* map;
00321 FT_UInt32 uni_char;
00322
00323
00324 map = table->maps;
00325
00326 for ( n = 0; n < num_glyphs; n++ )
00327 {
00328 const char* gname = get_glyph_name( glyph_data, n );
00329
00330
00331 if ( gname )
00332 {
00333 ps_check_extra_glyph_name( gname, n,
00334 extra_glyphs, extra_glyph_list_states );
00335 uni_char = ps_unicode_value( gname );
00336
00337 if ( BASE_GLYPH( uni_char ) != 0 )
00338 {
00339 ps_check_extra_glyph_unicode( uni_char,
00340 extra_glyph_list_states );
00341 map->unicode = uni_char;
00342 map->glyph_index = n;
00343 map++;
00344 }
00345
00346 if ( free_glyph_name )
00347 free_glyph_name( glyph_data, gname );
00348 }
00349 }
00350
00351 for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ )
00352 {
00353 if ( extra_glyph_list_states[n] == 1 )
00354 {
00355
00356
00357
00358 map->unicode = ft_extra_glyph_unicodes[n];
00359 map->glyph_index = extra_glyphs[n];
00360 map++;
00361 }
00362 }
00363
00364
00365 count = (FT_UInt)( map - table->maps );
00366
00367 if ( count == 0 )
00368 {
00369 FT_FREE( table->maps );
00370 if ( !error )
00371 error = PSnames_Err_Invalid_Argument;
00372 }
00373 else {
00374
00375 if ( count < num_glyphs / 2 )
00376 {
00377 (void)FT_RENEW_ARRAY( table->maps, num_glyphs, count );
00378 error = PSnames_Err_Ok;
00379 }
00380
00381
00382
00383 ft_qsort( table->maps, count, sizeof ( PS_UniMap ),
00384 compare_uni_maps );
00385 }
00386
00387 table->num_maps = count;
00388 }
00389
00390 return error;
00391 }
00392
00393
00394 static FT_UInt
00395 ps_unicodes_char_index( PS_Unicodes table,
00396 FT_UInt32 unicode )
00397 {
00398 PS_UniMap *min, *max, *mid, *result = NULL;
00399
00400
00401
00402
00403 min = table->maps;
00404 max = min + table->num_maps - 1;
00405
00406 while ( min <= max )
00407 {
00408 FT_UInt32 base_glyph;
00409
00410
00411 mid = min + ( ( max - min ) >> 1 );
00412
00413 if ( mid->unicode == unicode )
00414 {
00415 result = mid;
00416 break;
00417 }
00418
00419 base_glyph = BASE_GLYPH( mid->unicode );
00420
00421 if ( base_glyph == unicode )
00422 result = mid;
00423
00424 if ( min == max )
00425 break;
00426
00427 if ( base_glyph < unicode )
00428 min = mid + 1;
00429 else
00430 max = mid - 1;
00431 }
00432
00433 if ( result )
00434 return result->glyph_index;
00435 else
00436 return 0;
00437 }
00438
00439
00440 static FT_UInt32
00441 ps_unicodes_char_next( PS_Unicodes table,
00442 FT_UInt32 *unicode )
00443 {
00444 FT_UInt result = 0;
00445 FT_UInt32 char_code = *unicode + 1;
00446
00447
00448 {
00449 FT_UInt min = 0;
00450 FT_UInt max = table->num_maps;
00451 FT_UInt mid;
00452 PS_UniMap* map;
00453 FT_UInt32 base_glyph;
00454
00455
00456 while ( min < max )
00457 {
00458 mid = min + ( ( max - min ) >> 1 );
00459 map = table->maps + mid;
00460
00461 if ( map->unicode == char_code )
00462 {
00463 result = map->glyph_index;
00464 goto Exit;
00465 }
00466
00467 base_glyph = BASE_GLYPH( map->unicode );
00468
00469 if ( base_glyph == char_code )
00470 result = map->glyph_index;
00471
00472 if ( base_glyph < char_code )
00473 min = mid + 1;
00474 else
00475 max = mid;
00476 }
00477
00478 if ( result )
00479 goto Exit;
00480
00481
00482 char_code = 0;
00483
00484 if ( min < table->num_maps )
00485 {
00486 map = table->maps + min;
00487 result = map->glyph_index;
00488 char_code = BASE_GLYPH( map->unicode );
00489 }
00490 }
00491
00492 Exit:
00493 *unicode = char_code;
00494 return result;
00495 }
00496
00497
00498 #endif
00499
00500
00501 static const char*
00502 ps_get_macintosh_name( FT_UInt name_index )
00503 {
00504 if ( name_index >= FT_NUM_MAC_NAMES )
00505 name_index = 0;
00506
00507 return ft_standard_glyph_names + ft_mac_names[name_index];
00508 }
00509
00510
00511 static const char*
00512 ps_get_standard_strings( FT_UInt sid )
00513 {
00514 if ( sid >= FT_NUM_SID_NAMES )
00515 return 0;
00516
00517 return ft_standard_glyph_names + ft_sid_names[sid];
00518 }
00519
00520
00521 #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
00522 FT_DEFINE_SERVICE_PSCMAPSREC(pscmaps_interface,
00523 (PS_Unicode_ValueFunc) ps_unicode_value,
00524 (PS_Unicodes_InitFunc) ps_unicodes_init,
00525 (PS_Unicodes_CharIndexFunc)ps_unicodes_char_index,
00526 (PS_Unicodes_CharNextFunc) ps_unicodes_char_next,
00527
00528 (PS_Macintosh_NameFunc) ps_get_macintosh_name,
00529 (PS_Adobe_Std_StringsFunc) ps_get_standard_strings,
00530
00531 t1_standard_encoding,
00532 t1_expert_encoding
00533 )
00534
00535 #else
00536
00537 FT_DEFINE_SERVICE_PSCMAPSREC(pscmaps_interface,
00538 0,
00539 0,
00540 0,
00541 0,
00542
00543 (PS_Macintosh_NameFunc) ps_get_macintosh_name,
00544 (PS_Adobe_Std_StringsFunc) ps_get_standard_strings,
00545
00546 t1_standard_encoding,
00547 t1_expert_encoding
00548 )
00549
00550 #endif
00551
00552
00553 FT_DEFINE_SERVICEDESCREC1(pscmaps_services,
00554 FT_SERVICE_ID_POSTSCRIPT_CMAPS, &FT_PSCMAPS_INTERFACE_GET
00555 )
00556
00557
00558
00559
00560 static FT_Pointer
00561 psnames_get_service( FT_Module module,
00562 const char* service_id )
00563 {
00564 FT_UNUSED( module );
00565
00566 return ft_service_list_lookup( FT_PSCMAPS_SERVICES_GET, service_id );
00567 }
00568
00569 #endif
00570
00571
00572 #ifndef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
00573 #define PUT_PS_NAMES_SERVICE(a) 0
00574 #else
00575 #define PUT_PS_NAMES_SERVICE(a) a
00576 #endif
00577
00578 FT_DEFINE_MODULE(psnames_module_class,
00579
00580 0,
00581 sizeof ( FT_ModuleRec ),
00582
00583 "psnames",
00584 0x10000L,
00585 0x20000L,
00586
00587 PUT_PS_NAMES_SERVICE((void*)&FT_PSCMAPS_INTERFACE_GET),
00588 (FT_Module_Constructor)0,
00589 (FT_Module_Destructor) 0,
00590 (FT_Module_Requester) PUT_PS_NAMES_SERVICE(psnames_get_service)
00591 )
00592
00593
00594
00595