| OLD | NEW |
| (Empty) |
| 1 #if !defined(_FXFT_VERSION_) || _FXFT_VERSION_ == 2501 | |
| 2 /***************************************************************************/ | |
| 3 /* */ | |
| 4 /* psmodule.c */ | |
| 5 /* */ | |
| 6 /* PSNames module implementation (body). */ | |
| 7 /* */ | |
| 8 /* Copyright 1996-2003, 2005-2008, 2012, 2013 by */ | |
| 9 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ | |
| 10 /* */ | |
| 11 /* This file is part of the FreeType project, and may only be used, */ | |
| 12 /* modified, and distributed under the terms of the FreeType project */ | |
| 13 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ | |
| 14 /* this file you indicate that you have read the license and */ | |
| 15 /* understand and accept it fully. */ | |
| 16 /* */ | |
| 17 /***************************************************************************/ | |
| 18 | |
| 19 #define FT2_BUILD_LIBRARY | |
| 20 #include "../../include/ft2build.h" | |
| 21 #include "../../include/freetype/internal/ftdebug.h" | |
| 22 #include "../../include/freetype/internal/ftobjs.h" | |
| 23 #include "../../include/freetype/internal/services/svpscmap.h" | |
| 24 | |
| 25 #include "psmodule.h" | |
| 26 #include "pstables.h" | |
| 27 | |
| 28 #include "psnamerr.h" | |
| 29 #include "pspic.h" | |
| 30 | |
| 31 | |
| 32 #ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES | |
| 33 | |
| 34 | |
| 35 #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST | |
| 36 | |
| 37 | |
| 38 #define VARIANT_BIT 0x80000000UL | |
| 39 #define BASE_GLYPH( code ) ( (FT_UInt32)( (code) & ~VARIANT_BIT ) ) | |
| 40 | |
| 41 #ifdef __cplusplus | |
| 42 extern "C" { | |
| 43 #endif | |
| 44 /* Return the Unicode value corresponding to a given glyph. Note that */ | |
| 45 /* we do deal with glyph variants by detecting a non-initial dot in */ | |
| 46 /* the name, as in `A.swash' or `e.final'; in this case, the */ | |
| 47 /* VARIANT_BIT is set in the return value. */ | |
| 48 /* */ | |
| 49 int FXFT_unicode_from_adobe_name( const char* glyph_name ) | |
| 50 { | |
| 51 /* If the name begins with `uni', then the glyph name may be a */ | |
| 52 /* hard-coded unicode character code. */ | |
| 53 if ( glyph_name[0] == 'u' && | |
| 54 glyph_name[1] == 'n' && | |
| 55 glyph_name[2] == 'i' ) | |
| 56 { | |
| 57 /* determine whether the next four characters following are */ | |
| 58 /* hexadecimal. */ | |
| 59 | |
| 60 /* XXX: Add code to deal with ligatures, i.e. glyph names like */ | |
| 61 /* `uniXXXXYYYYZZZZ'... */ | |
| 62 | |
| 63 FT_Int count; | |
| 64 FT_UInt32 value = 0; | |
| 65 const char* p = glyph_name + 3; | |
| 66 | |
| 67 | |
| 68 for ( count = 4; count > 0; count--, p++ ) | |
| 69 { | |
| 70 char c = *p; | |
| 71 unsigned int d; | |
| 72 | |
| 73 | |
| 74 d = (unsigned char)c - '0'; | |
| 75 if ( d >= 10 ) | |
| 76 { | |
| 77 d = (unsigned char)c - 'A'; | |
| 78 if ( d >= 6 ) | |
| 79 d = 16; | |
| 80 else | |
| 81 d += 10; | |
| 82 } | |
| 83 | |
| 84 /* Exit if a non-uppercase hexadecimal character was found */ | |
| 85 /* -- this also catches character codes below `0' since such */ | |
| 86 /* negative numbers cast to `unsigned int' are far too big. */ | |
| 87 if ( d >= 16 ) | |
| 88 break; | |
| 89 | |
| 90 value = ( value << 4 ) + d; | |
| 91 } | |
| 92 | |
| 93 /* there must be exactly four hex digits */ | |
| 94 if ( count == 0 ) | |
| 95 { | |
| 96 if ( *p == '\0' ) | |
| 97 return value; | |
| 98 if ( *p == '.' ) | |
| 99 return (FT_UInt32)( value | VARIANT_BIT ); | |
| 100 } | |
| 101 } | |
| 102 | |
| 103 /* If the name begins with `u', followed by four to six uppercase */ | |
| 104 /* hexadecimal digits, it is a hard-coded unicode character code. */ | |
| 105 if ( glyph_name[0] == 'u' ) | |
| 106 { | |
| 107 FT_Int count; | |
| 108 FT_UInt32 value = 0; | |
| 109 const char* p = glyph_name + 1; | |
| 110 | |
| 111 | |
| 112 for ( count = 6; count > 0; count--, p++ ) | |
| 113 { | |
| 114 char c = *p; | |
| 115 unsigned int d; | |
| 116 | |
| 117 | |
| 118 d = (unsigned char)c - '0'; | |
| 119 if ( d >= 10 ) | |
| 120 { | |
| 121 d = (unsigned char)c - 'A'; | |
| 122 if ( d >= 6 ) | |
| 123 d = 16; | |
| 124 else | |
| 125 d += 10; | |
| 126 } | |
| 127 | |
| 128 if ( d >= 16 ) | |
| 129 break; | |
| 130 | |
| 131 value = ( value << 4 ) + d; | |
| 132 } | |
| 133 | |
| 134 if ( count <= 2 ) | |
| 135 { | |
| 136 if ( *p == '\0' ) | |
| 137 return value; | |
| 138 if ( *p == '.' ) | |
| 139 return (FT_UInt32)( value | VARIANT_BIT ); | |
| 140 } | |
| 141 } | |
| 142 | |
| 143 /* Look for a non-initial dot in the glyph name in order to */ | |
| 144 /* find variants like `A.swash', `e.final', etc. */ | |
| 145 { | |
| 146 const char* p = glyph_name; | |
| 147 const char* dot = NULL; | |
| 148 | |
| 149 | |
| 150 for ( ; *p; p++ ) | |
| 151 { | |
| 152 if ( *p == '.' && p > glyph_name ) | |
| 153 { | |
| 154 dot = p; | |
| 155 break; | |
| 156 } | |
| 157 } | |
| 158 | |
| 159 /* now look up the glyph in the Adobe Glyph List */ | |
| 160 if ( !dot ) | |
| 161 return (FT_UInt32)ft_get_adobe_glyph_index( glyph_name, p ); | |
| 162 else | |
| 163 return (FT_UInt32)( ft_get_adobe_glyph_index( glyph_name, dot ) | | |
| 164 VARIANT_BIT ); | |
| 165 } | |
| 166 } | |
| 167 #ifdef __cplusplus | |
| 168 } | |
| 169 #endif | |
| 170 | |
| 171 static int xyq_search_node(char* glyph_name, int name_offset, int table_offset,
FT_UInt32 unicode) | |
| 172 { | |
| 173 int i, count; | |
| 174 | |
| 175 // copy letters | |
| 176 while (1) { | |
| 177 glyph_name[name_offset] = ft_adobe_glyph_list[table_offset] & 0x
7f; | |
| 178 name_offset ++; | |
| 179 table_offset ++; | |
| 180 if (!(ft_adobe_glyph_list[table_offset-1] & 0x80)) break; | |
| 181 } | |
| 182 glyph_name[name_offset] = 0; | |
| 183 | |
| 184 // get child count | |
| 185 count = ft_adobe_glyph_list[table_offset] & 0x7f; | |
| 186 | |
| 187 // check if we have value for this node | |
| 188 if (ft_adobe_glyph_list[table_offset] & 0x80) { | |
| 189 unsigned short thiscode = ft_adobe_glyph_list[table_offset+1] *
256 + ft_adobe_glyph_list[table_offset+2]; | |
| 190 if (thiscode == unicode) // found it! | |
| 191 return 1; | |
| 192 table_offset += 3; | |
| 193 } else | |
| 194 table_offset ++; | |
| 195 | |
| 196 // now search in sub-nodes | |
| 197 if (count == 0) return 0; | |
| 198 for (i = 0; i < count; i ++) { | |
| 199 int child_offset = ft_adobe_glyph_list[table_offset+i*2] * 256 +
ft_adobe_glyph_list[table_offset+i*2+1]; | |
| 200 if (xyq_search_node(glyph_name, name_offset, child_offset, unico
de)) | |
| 201 // found in child | |
| 202 return 1; | |
| 203 } | |
| 204 return 0; | |
| 205 } | |
| 206 | |
| 207 // XYQ: function for searching Unicode in the glyph list | |
| 208 void FXFT_adobe_name_from_unicode(char* glyph_name, FT_UInt32 unicode) | |
| 209 { | |
| 210 int i, count; | |
| 211 | |
| 212 // start from top level node | |
| 213 count = ft_adobe_glyph_list[1]; | |
| 214 for (i = 0; i < count; i ++) { | |
| 215 int child_offset = ft_adobe_glyph_list[i*2+2] * 256 + ft_adobe_g
lyph_list[i*2+3]; | |
| 216 if (xyq_search_node(glyph_name, 0, child_offset, unicode)) | |
| 217 return; | |
| 218 } | |
| 219 | |
| 220 // failed, clear the buffer | |
| 221 glyph_name[0] = 0; | |
| 222 } | |
| 223 | |
| 224 /* ft_qsort callback to sort the unicode map */ | |
| 225 FT_CALLBACK_DEF( int ) | |
| 226 compare_uni_maps( const void* a, | |
| 227 const void* b ) | |
| 228 { | |
| 229 PS_UniMap* map1 = (PS_UniMap*)a; | |
| 230 PS_UniMap* map2 = (PS_UniMap*)b; | |
| 231 FT_UInt32 unicode1 = BASE_GLYPH( map1->unicode ); | |
| 232 FT_UInt32 unicode2 = BASE_GLYPH( map2->unicode ); | |
| 233 | |
| 234 | |
| 235 /* sort base glyphs before glyph variants */ | |
| 236 if ( unicode1 == unicode2 ) | |
| 237 { | |
| 238 if ( map1->unicode > map2->unicode ) | |
| 239 return 1; | |
| 240 else if ( map1->unicode < map2->unicode ) | |
| 241 return -1; | |
| 242 else | |
| 243 return 0; | |
| 244 } | |
| 245 else | |
| 246 { | |
| 247 if ( unicode1 > unicode2 ) | |
| 248 return 1; | |
| 249 else if ( unicode1 < unicode2 ) | |
| 250 return -1; | |
| 251 else | |
| 252 return 0; | |
| 253 } | |
| 254 } | |
| 255 | |
| 256 | |
| 257 /* support for extra glyphs not handled (well) in AGL; */ | |
| 258 /* we add extra mappings for them if necessary */ | |
| 259 | |
| 260 #define EXTRA_GLYPH_LIST_SIZE 10 | |
| 261 | |
| 262 static const FT_UInt32 ft_extra_glyph_unicodes[EXTRA_GLYPH_LIST_SIZE] = | |
| 263 { | |
| 264 /* WGL 4 */ | |
| 265 0x0394, | |
| 266 0x03A9, | |
| 267 0x2215, | |
| 268 0x00AD, | |
| 269 0x02C9, | |
| 270 0x03BC, | |
| 271 0x2219, | |
| 272 0x00A0, | |
| 273 /* Romanian */ | |
| 274 0x021A, | |
| 275 0x021B | |
| 276 }; | |
| 277 | |
| 278 static const char ft_extra_glyph_names[] = | |
| 279 { | |
| 280 'D','e','l','t','a',0, | |
| 281 'O','m','e','g','a',0, | |
| 282 'f','r','a','c','t','i','o','n',0, | |
| 283 'h','y','p','h','e','n',0, | |
| 284 'm','a','c','r','o','n',0, | |
| 285 'm','u',0, | |
| 286 'p','e','r','i','o','d','c','e','n','t','e','r','e','d',0, | |
| 287 's','p','a','c','e',0, | |
| 288 'T','c','o','m','m','a','a','c','c','e','n','t',0, | |
| 289 't','c','o','m','m','a','a','c','c','e','n','t',0 | |
| 290 }; | |
| 291 | |
| 292 static const FT_Int | |
| 293 ft_extra_glyph_name_offsets[EXTRA_GLYPH_LIST_SIZE] = | |
| 294 { | |
| 295 0, | |
| 296 6, | |
| 297 12, | |
| 298 21, | |
| 299 28, | |
| 300 35, | |
| 301 38, | |
| 302 53, | |
| 303 59, | |
| 304 72 | |
| 305 }; | |
| 306 | |
| 307 | |
| 308 static void | |
| 309 ps_check_extra_glyph_name( const char* gname, | |
| 310 FT_UInt glyph, | |
| 311 FT_UInt* extra_glyphs, | |
| 312 FT_UInt *states ) | |
| 313 { | |
| 314 FT_UInt n; | |
| 315 | |
| 316 | |
| 317 for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ ) | |
| 318 { | |
| 319 if ( ft_strcmp( ft_extra_glyph_names + | |
| 320 ft_extra_glyph_name_offsets[n], gname ) == 0 ) | |
| 321 { | |
| 322 if ( states[n] == 0 ) | |
| 323 { | |
| 324 /* mark this extra glyph as a candidate for the cmap */ | |
| 325 states[n] = 1; | |
| 326 extra_glyphs[n] = glyph; | |
| 327 } | |
| 328 | |
| 329 return; | |
| 330 } | |
| 331 } | |
| 332 } | |
| 333 | |
| 334 | |
| 335 static void | |
| 336 ps_check_extra_glyph_unicode( FT_UInt32 uni_char, | |
| 337 FT_UInt *states ) | |
| 338 { | |
| 339 FT_UInt n; | |
| 340 | |
| 341 | |
| 342 for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ ) | |
| 343 { | |
| 344 if ( uni_char == ft_extra_glyph_unicodes[n] ) | |
| 345 { | |
| 346 /* disable this extra glyph from being added to the cmap */ | |
| 347 states[n] = 2; | |
| 348 | |
| 349 return; | |
| 350 } | |
| 351 } | |
| 352 } | |
| 353 | |
| 354 | |
| 355 /* Build a table that maps Unicode values to glyph indices. */ | |
| 356 static FT_Error | |
| 357 ps_unicodes_init( FT_Memory memory, | |
| 358 PS_Unicodes table, | |
| 359 FT_UInt num_glyphs, | |
| 360 PS_GetGlyphNameFunc get_glyph_name, | |
| 361 PS_FreeGlyphNameFunc free_glyph_name, | |
| 362 FT_Pointer glyph_data ) | |
| 363 { | |
| 364 FT_Error error; | |
| 365 | |
| 366 FT_UInt extra_glyph_list_states[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; | |
| 367 FT_UInt extra_glyphs[EXTRA_GLYPH_LIST_SIZE]; | |
| 368 | |
| 369 | |
| 370 /* we first allocate the table */ | |
| 371 table->num_maps = 0; | |
| 372 table->maps = 0; | |
| 373 | |
| 374 if ( !FT_NEW_ARRAY( table->maps, num_glyphs + EXTRA_GLYPH_LIST_SIZE ) ) | |
| 375 { | |
| 376 FT_UInt n; | |
| 377 FT_UInt count; | |
| 378 PS_UniMap* map; | |
| 379 FT_UInt32 uni_char; | |
| 380 | |
| 381 | |
| 382 map = table->maps; | |
| 383 | |
| 384 for ( n = 0; n < num_glyphs; n++ ) | |
| 385 { | |
| 386 const char* gname = get_glyph_name( glyph_data, n ); | |
| 387 | |
| 388 | |
| 389 if ( gname ) | |
| 390 { | |
| 391 ps_check_extra_glyph_name( gname, n, | |
| 392 extra_glyphs, extra_glyph_list_states ); | |
| 393 uni_char = FXFT_unicode_from_adobe_name( gname ); | |
| 394 | |
| 395 if ( BASE_GLYPH( uni_char ) != 0 ) | |
| 396 { | |
| 397 ps_check_extra_glyph_unicode( uni_char, | |
| 398 extra_glyph_list_states ); | |
| 399 map->unicode = uni_char; | |
| 400 map->glyph_index = n; | |
| 401 map++; | |
| 402 } | |
| 403 | |
| 404 if ( free_glyph_name ) | |
| 405 free_glyph_name( glyph_data, gname ); | |
| 406 } | |
| 407 } | |
| 408 | |
| 409 for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ ) | |
| 410 { | |
| 411 if ( extra_glyph_list_states[n] == 1 ) | |
| 412 { | |
| 413 /* This glyph name has an additional representation. */ | |
| 414 /* Add it to the cmap. */ | |
| 415 | |
| 416 map->unicode = ft_extra_glyph_unicodes[n]; | |
| 417 map->glyph_index = extra_glyphs[n]; | |
| 418 map++; | |
| 419 } | |
| 420 } | |
| 421 | |
| 422 /* now compress the table a bit */ | |
| 423 count = (FT_UInt)( map - table->maps ); | |
| 424 | |
| 425 if ( count == 0 ) | |
| 426 { | |
| 427 /* No unicode chars here! */ | |
| 428 FT_FREE( table->maps ); | |
| 429 if ( !error ) | |
| 430 error = FT_THROW( No_Unicode_Glyph_Name ); | |
| 431 } | |
| 432 else | |
| 433 { | |
| 434 /* Reallocate if the number of used entries is much smaller. */ | |
| 435 if ( count < num_glyphs / 2 ) | |
| 436 { | |
| 437 (void)FT_RENEW_ARRAY( table->maps, num_glyphs, count ); | |
| 438 error = FT_Err_Ok; | |
| 439 } | |
| 440 | |
| 441 /* Sort the table in increasing order of unicode values, */ | |
| 442 /* taking care of glyph variants. */ | |
| 443 ft_qsort( table->maps, count, sizeof ( PS_UniMap ), | |
| 444 compare_uni_maps ); | |
| 445 } | |
| 446 | |
| 447 table->num_maps = count; | |
| 448 } | |
| 449 | |
| 450 return error; | |
| 451 } | |
| 452 | |
| 453 | |
| 454 static FT_UInt | |
| 455 ps_unicodes_char_index( PS_Unicodes table, | |
| 456 FT_UInt32 unicode ) | |
| 457 { | |
| 458 PS_UniMap *min, *max, *mid, *result = NULL; | |
| 459 | |
| 460 | |
| 461 /* Perform a binary search on the table. */ | |
| 462 | |
| 463 min = table->maps; | |
| 464 max = min + table->num_maps - 1; | |
| 465 | |
| 466 while ( min <= max ) | |
| 467 { | |
| 468 FT_UInt32 base_glyph; | |
| 469 | |
| 470 | |
| 471 mid = min + ( ( max - min ) >> 1 ); | |
| 472 | |
| 473 if ( mid->unicode == unicode ) | |
| 474 { | |
| 475 result = mid; | |
| 476 break; | |
| 477 } | |
| 478 | |
| 479 base_glyph = BASE_GLYPH( mid->unicode ); | |
| 480 | |
| 481 if ( base_glyph == unicode ) | |
| 482 result = mid; /* remember match but continue search for base glyph */ | |
| 483 | |
| 484 if ( min == max ) | |
| 485 break; | |
| 486 | |
| 487 if ( base_glyph < unicode ) | |
| 488 min = mid + 1; | |
| 489 else | |
| 490 max = mid - 1; | |
| 491 } | |
| 492 | |
| 493 if ( result ) | |
| 494 return result->glyph_index; | |
| 495 else | |
| 496 return 0; | |
| 497 } | |
| 498 | |
| 499 | |
| 500 static FT_UInt32 | |
| 501 ps_unicodes_char_next( PS_Unicodes table, | |
| 502 FT_UInt32 *unicode ) | |
| 503 { | |
| 504 FT_UInt result = 0; | |
| 505 FT_UInt32 char_code = *unicode + 1; | |
| 506 | |
| 507 | |
| 508 { | |
| 509 FT_UInt min = 0; | |
| 510 FT_UInt max = table->num_maps; | |
| 511 FT_UInt mid; | |
| 512 PS_UniMap* map; | |
| 513 FT_UInt32 base_glyph; | |
| 514 | |
| 515 | |
| 516 while ( min < max ) | |
| 517 { | |
| 518 mid = min + ( ( max - min ) >> 1 ); | |
| 519 map = table->maps + mid; | |
| 520 | |
| 521 if ( map->unicode == char_code ) | |
| 522 { | |
| 523 result = map->glyph_index; | |
| 524 goto Exit; | |
| 525 } | |
| 526 | |
| 527 base_glyph = BASE_GLYPH( map->unicode ); | |
| 528 | |
| 529 if ( base_glyph == char_code ) | |
| 530 result = map->glyph_index; | |
| 531 | |
| 532 if ( base_glyph < char_code ) | |
| 533 min = mid + 1; | |
| 534 else | |
| 535 max = mid; | |
| 536 } | |
| 537 | |
| 538 if ( result ) | |
| 539 goto Exit; /* we have a variant glyph */ | |
| 540 | |
| 541 /* we didn't find it; check whether we have a map just above it */ | |
| 542 char_code = 0; | |
| 543 | |
| 544 if ( min < table->num_maps ) | |
| 545 { | |
| 546 map = table->maps + min; | |
| 547 result = map->glyph_index; | |
| 548 char_code = BASE_GLYPH( map->unicode ); | |
| 549 } | |
| 550 } | |
| 551 | |
| 552 Exit: | |
| 553 *unicode = char_code; | |
| 554 return result; | |
| 555 } | |
| 556 | |
| 557 | |
| 558 #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ | |
| 559 | |
| 560 | |
| 561 static const char* | |
| 562 ps_get_macintosh_name( FT_UInt name_index ) | |
| 563 { | |
| 564 if ( name_index >= FT_NUM_MAC_NAMES ) | |
| 565 name_index = 0; | |
| 566 | |
| 567 return ft_standard_glyph_names + ft_mac_names[name_index]; | |
| 568 } | |
| 569 | |
| 570 | |
| 571 static const char* | |
| 572 ps_get_standard_strings( FT_UInt sid ) | |
| 573 { | |
| 574 if ( sid >= FT_NUM_SID_NAMES ) | |
| 575 return 0; | |
| 576 | |
| 577 return ft_standard_glyph_names + ft_sid_names[sid]; | |
| 578 } | |
| 579 | |
| 580 | |
| 581 #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST | |
| 582 | |
| 583 FT_DEFINE_SERVICE_PSCMAPSREC( | |
| 584 pscmaps_interface, | |
| 585 (PS_Unicode_ValueFunc) FXFT_unicode_from_adobe_name, | |
| 586 (PS_Unicodes_InitFunc) ps_unicodes_init, | |
| 587 (PS_Unicodes_CharIndexFunc)ps_unicodes_char_index, | |
| 588 (PS_Unicodes_CharNextFunc) ps_unicodes_char_next, | |
| 589 | |
| 590 (PS_Macintosh_NameFunc) ps_get_macintosh_name, | |
| 591 (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, | |
| 592 | |
| 593 t1_standard_encoding, | |
| 594 t1_expert_encoding ) | |
| 595 | |
| 596 #else | |
| 597 | |
| 598 FT_DEFINE_SERVICE_PSCMAPSREC( | |
| 599 pscmaps_interface, | |
| 600 NULL, | |
| 601 NULL, | |
| 602 NULL, | |
| 603 NULL, | |
| 604 | |
| 605 (PS_Macintosh_NameFunc) ps_get_macintosh_name, | |
| 606 (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, | |
| 607 | |
| 608 t1_standard_encoding, | |
| 609 t1_expert_encoding ) | |
| 610 | |
| 611 #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ | |
| 612 | |
| 613 | |
| 614 FT_DEFINE_SERVICEDESCREC1( | |
| 615 pscmaps_services, | |
| 616 FT_SERVICE_ID_POSTSCRIPT_CMAPS, &PSCMAPS_INTERFACE_GET ) | |
| 617 | |
| 618 | |
| 619 static FT_Pointer | |
| 620 psnames_get_service( FT_Module module, | |
| 621 const char* service_id ) | |
| 622 { | |
| 623 /* PSCMAPS_SERVICES_GET derefers `library' in PIC mode */ | |
| 624 #ifdef FT_CONFIG_OPTION_PIC | |
| 625 FT_Library library; | |
| 626 | |
| 627 | |
| 628 if ( !module ) | |
| 629 return NULL; | |
| 630 library = module->library; | |
| 631 if ( !library ) | |
| 632 return NULL; | |
| 633 #else | |
| 634 FT_UNUSED( module ); | |
| 635 #endif | |
| 636 | |
| 637 return ft_service_list_lookup( PSCMAPS_SERVICES_GET, service_id ); | |
| 638 } | |
| 639 | |
| 640 #endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */ | |
| 641 | |
| 642 | |
| 643 #ifndef FT_CONFIG_OPTION_POSTSCRIPT_NAMES | |
| 644 #define PUT_PS_NAMES_SERVICE( a ) NULL | |
| 645 #else | |
| 646 #define PUT_PS_NAMES_SERVICE( a ) a | |
| 647 #endif | |
| 648 | |
| 649 FT_DEFINE_MODULE( | |
| 650 psnames_module_class, | |
| 651 | |
| 652 0, /* this is not a font driver, nor a renderer */ | |
| 653 sizeof ( FT_ModuleRec ), | |
| 654 | |
| 655 "psnames", /* driver name */ | |
| 656 0x10000L, /* driver version */ | |
| 657 0x20000L, /* driver requires FreeType 2 or above */ | |
| 658 | |
| 659 PUT_PS_NAMES_SERVICE( | |
| 660 (void*)&PSCMAPS_INTERFACE_GET ), /* module specific interface */ | |
| 661 (FT_Module_Constructor)NULL, | |
| 662 (FT_Module_Destructor) NULL, | |
| 663 (FT_Module_Requester) PUT_PS_NAMES_SERVICE( psnames_get_service ) ) | |
| 664 | |
| 665 | |
| 666 /* END */ | |
| 667 #endif | |
| 668 | |
| OLD | NEW |