cffdrivr.c (38045B)
1 /**************************************************************************** 2 * 3 * cffdrivr.c 4 * 5 * OpenType font driver implementation (body). 6 * 7 * Copyright (C) 1996-2025 by 8 * David Turner, Robert Wilhelm, Werner Lemberg, and Dominik Röttsches. 9 * 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 12 * license, LICENSE.TXT. By continuing to use, modify, or distribute 13 * this file you indicate that you have read the license and 14 * understand and accept it fully. 15 * 16 */ 17 18 19 #include <freetype/freetype.h> 20 #include <freetype/internal/ftdebug.h> 21 #include <freetype/internal/ftstream.h> 22 #include <freetype/internal/sfnt.h> 23 #include <freetype/internal/psaux.h> 24 #include <freetype/internal/ftpsprop.h> 25 #include <freetype/internal/services/svcid.h> 26 #include <freetype/internal/services/svpsinfo.h> 27 #include <freetype/internal/services/svpostnm.h> 28 #include <freetype/internal/services/svttcmap.h> 29 #include <freetype/internal/services/svcfftl.h> 30 31 #include "cffdrivr.h" 32 #include "cffgload.h" 33 #include "cffload.h" 34 #include "cffcmap.h" 35 #include "cffparse.h" 36 #include "cffobjs.h" 37 38 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 39 #include <freetype/internal/services/svmm.h> 40 #include <freetype/internal/services/svmetric.h> 41 #endif 42 43 #include "cfferrs.h" 44 45 #include <freetype/internal/services/svfntfmt.h> 46 #include <freetype/internal/services/svgldict.h> 47 #include <freetype/internal/services/svprop.h> 48 #include <freetype/ftdriver.h> 49 50 51 /************************************************************************** 52 * 53 * The macro FT_COMPONENT is used in trace mode. It is an implicit 54 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log 55 * messages during execution. 56 */ 57 #undef FT_COMPONENT 58 #define FT_COMPONENT cffdriver 59 60 61 /*************************************************************************/ 62 /*************************************************************************/ 63 /*************************************************************************/ 64 /**** ****/ 65 /**** ****/ 66 /**** F A C E S ****/ 67 /**** ****/ 68 /**** ****/ 69 /*************************************************************************/ 70 /*************************************************************************/ 71 /*************************************************************************/ 72 73 74 /************************************************************************** 75 * 76 * @Function: 77 * cff_get_kerning 78 * 79 * @Description: 80 * A driver method used to return the kerning vector between two 81 * glyphs of the same face. 82 * 83 * @Input: 84 * face :: 85 * A handle to the source face object. 86 * 87 * left_glyph :: 88 * The index of the left glyph in the kern pair. 89 * 90 * right_glyph :: 91 * The index of the right glyph in the kern pair. 92 * 93 * @Output: 94 * kerning :: 95 * The kerning vector. This is in font units for 96 * scalable formats, and in pixels for fixed-sizes 97 * formats. 98 * 99 * @Return: 100 * FreeType error code. 0 means success. 101 * 102 * @Note: 103 * Only horizontal layouts (left-to-right & right-to-left) are 104 * supported by this function. Other layouts, or more sophisticated 105 * kernings, are out of scope of this method (the basic driver 106 * interface is meant to be simple). 107 * 108 * They can be implemented by format-specific interfaces. 109 */ 110 FT_CALLBACK_DEF( FT_Error ) 111 cff_get_kerning( FT_Face face, /* CFF_Face */ 112 FT_UInt left_glyph, 113 FT_UInt right_glyph, 114 FT_Vector* kerning ) 115 { 116 CFF_Face cffface = (CFF_Face)face; 117 SFNT_Service sfnt = (SFNT_Service)cffface->sfnt; 118 119 120 kerning->x = 0; 121 kerning->y = 0; 122 123 if ( sfnt ) 124 { 125 /* Use 'kern' table if available since that can be faster; otherwise */ 126 /* use GPOS kerning pairs if available. */ 127 if ( cffface->kern_avail_bits ) 128 kerning->x = sfnt->get_kerning( cffface, 129 left_glyph, 130 right_glyph ); 131 #ifdef TT_CONFIG_OPTION_GPOS_KERNING 132 else if ( cffface->num_gpos_lookups_kerning ) 133 kerning->x = sfnt->get_gpos_kerning( cffface, 134 left_glyph, 135 right_glyph ); 136 #endif 137 } 138 139 return FT_Err_Ok; 140 } 141 142 143 /************************************************************************** 144 * 145 * @Function: 146 * cff_glyph_load 147 * 148 * @Description: 149 * A driver method used to load a glyph within a given glyph slot. 150 * 151 * @Input: 152 * slot :: 153 * A handle to the target slot object where the glyph 154 * will be loaded. 155 * 156 * size :: 157 * A handle to the source face size at which the glyph 158 * must be scaled, loaded, etc. 159 * 160 * glyph_index :: 161 * The index of the glyph in the font file. 162 * 163 * load_flags :: 164 * A flag indicating what to load for this glyph. The 165 * FT_LOAD_??? constants can be used to control the 166 * glyph loading process (e.g., whether the outline 167 * should be scaled, whether to load bitmaps or not, 168 * whether to hint the outline, etc). 169 * 170 * @Return: 171 * FreeType error code. 0 means success. 172 */ 173 FT_CALLBACK_DEF( FT_Error ) 174 cff_glyph_load( FT_GlyphSlot slot, /* CFF_GlyphSlot */ 175 FT_Size size, /* CFF_Size */ 176 FT_UInt glyph_index, 177 FT_Int32 load_flags ) 178 { 179 FT_Error error; 180 CFF_GlyphSlot cffslot = (CFF_GlyphSlot)slot; 181 CFF_Size cffsize = (CFF_Size)size; 182 183 184 FT_TRACE1(( "cff_glyph_load: glyph index %u\n", glyph_index )); 185 186 /* now load the glyph outline if necessary */ 187 error = cff_slot_load( cffslot, cffsize, glyph_index, load_flags ); 188 189 /* force drop-out mode to 2 - irrelevant now */ 190 /* slot->outline.dropout_mode = 2; */ 191 192 return error; 193 } 194 195 196 FT_CALLBACK_DEF( FT_Error ) 197 cff_get_advances( FT_Face face, 198 FT_UInt start, 199 FT_UInt count, 200 FT_Int32 flags, 201 FT_Fixed* advances ) 202 { 203 CFF_Face cffface = (CFF_Face)face; 204 FT_Bool horz; 205 FT_UInt nn; 206 207 208 if ( !FT_IS_SFNT( face ) ) 209 return FT_THROW( Unimplemented_Feature ); 210 211 horz = !( flags & FT_LOAD_VERTICAL_LAYOUT ); 212 213 if ( horz ) 214 { 215 /* OpenType 1.7 mandates that the data from `hmtx' table be used; */ 216 /* it is no longer necessary that those values are identical to */ 217 /* the values in the `CFF' table */ 218 if ( !cffface->horizontal.number_Of_HMetrics ) 219 return FT_THROW( Unimplemented_Feature ); 220 221 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 222 /* no fast retrieval for blended MM fonts without HVAR table */ 223 if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) && 224 !( cffface->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) 225 return FT_THROW( Unimplemented_Feature ); 226 #endif 227 } 228 else /* vertical */ 229 { 230 /* check whether we have data from the `vmtx' table at all; */ 231 /* otherwise we extract the info from the CFF glyphstrings */ 232 /* (instead of synthesizing a global value using the `OS/2' */ 233 /* table) */ 234 if ( !cffface->vertical_info ) 235 return FT_THROW( Unimplemented_Feature ); 236 237 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 238 /* no fast retrieval for blended MM fonts without VVAR table */ 239 if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) && 240 !( cffface->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) 241 return FT_THROW( Unimplemented_Feature ); 242 #endif 243 } 244 245 /* proceed to fast advances */ 246 for ( nn = 0; nn < count; nn++ ) 247 { 248 FT_UShort aw; 249 FT_Short dummy; 250 251 252 ( (SFNT_Service)cffface->sfnt )->get_metrics( cffface, 253 !horz, 254 start + nn, 255 &dummy, 256 &aw ); 257 258 FT_TRACE5(( " idx %u: advance %s %d font unit%s\n", 259 start + nn, 260 horz ? "width" : "height", 261 aw, 262 aw == 1 ? "" : "s" )); 263 advances[nn] = aw; 264 } 265 266 return FT_Err_Ok; 267 } 268 269 270 /* 271 * GLYPH DICT SERVICE 272 * 273 */ 274 275 FT_CALLBACK_DEF( FT_Error ) 276 cff_get_glyph_name( FT_Face face, /* CFF_Face */ 277 FT_UInt glyph_index, 278 FT_Pointer buffer, 279 FT_UInt buffer_max ) 280 { 281 CFF_Face cffface = (CFF_Face)face; 282 CFF_Font font = (CFF_Font)cffface->extra.data; 283 FT_String* gname; 284 FT_UShort sid; 285 FT_Error error; 286 287 288 /* CFF2 table does not have glyph names; */ 289 /* we need to use `post' table method */ 290 if ( font->version_major == 2 ) 291 { 292 FT_Library library = FT_FACE_LIBRARY( face ); 293 FT_Module sfnt_module = FT_Get_Module( library, "sfnt" ); 294 FT_Service_GlyphDict service = 295 (FT_Service_GlyphDict)ft_module_get_service( 296 sfnt_module, 297 FT_SERVICE_ID_GLYPH_DICT, 298 0 ); 299 300 301 if ( service && service->get_name ) 302 return service->get_name( face, glyph_index, buffer, buffer_max ); 303 else 304 { 305 FT_ERROR(( "cff_get_glyph_name:" 306 " cannot get glyph name from a CFF2 font\n" )); 307 FT_ERROR(( " " 308 " without the `psnames' module\n" )); 309 error = FT_THROW( Missing_Module ); 310 goto Exit; 311 } 312 } 313 314 if ( !font->psnames ) 315 { 316 FT_ERROR(( "cff_get_glyph_name:" 317 " cannot get glyph name from CFF & CEF fonts\n" )); 318 FT_ERROR(( " " 319 " without the `psnames' module\n" )); 320 error = FT_THROW( Missing_Module ); 321 goto Exit; 322 } 323 324 /* first, locate the sid in the charset table */ 325 sid = font->charset.sids[glyph_index]; 326 327 /* now, look up the name itself */ 328 gname = cff_index_get_sid_string( font, sid ); 329 330 if ( gname ) 331 FT_STRCPYN( buffer, gname, buffer_max ); 332 333 error = FT_Err_Ok; 334 335 Exit: 336 return error; 337 } 338 339 340 FT_CALLBACK_DEF( FT_UInt ) 341 cff_get_name_index( FT_Face face, /* CFF_Face */ 342 const FT_String* glyph_name ) 343 { 344 CFF_Face cffface = (CFF_Face)face; 345 CFF_Font cff = (CFF_Font)cffface->extra.data; 346 CFF_Charset charset = &cff->charset; 347 FT_Service_PsCMaps psnames; 348 FT_String* name; 349 FT_UShort sid; 350 FT_UInt i; 351 352 353 /* CFF2 table does not have glyph names; */ 354 /* we need to use `post' table method */ 355 if ( cff->version_major == 2 ) 356 { 357 FT_Library library = FT_FACE_LIBRARY( face ); 358 FT_Module sfnt_module = FT_Get_Module( library, "sfnt" ); 359 FT_Service_GlyphDict service = 360 (FT_Service_GlyphDict)ft_module_get_service( 361 sfnt_module, 362 FT_SERVICE_ID_GLYPH_DICT, 363 0 ); 364 365 366 if ( service && service->name_index ) 367 return service->name_index( face, glyph_name ); 368 else 369 { 370 FT_ERROR(( "cff_get_name_index:" 371 " cannot get glyph index from a CFF2 font\n" )); 372 FT_ERROR(( " " 373 " without the `psnames' module\n" )); 374 return 0; 375 } 376 } 377 378 FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); 379 if ( !psnames ) 380 return 0; 381 382 for ( i = 0; i < cff->num_glyphs; i++ ) 383 { 384 sid = charset->sids[i]; 385 386 if ( sid > 390 ) 387 name = cff_index_get_string( cff, sid - 391 ); 388 else 389 name = (FT_String *)psnames->adobe_std_strings( sid ); 390 391 if ( !name ) 392 continue; 393 394 if ( !ft_strcmp( glyph_name, name ) ) 395 return i; 396 } 397 398 return 0; 399 } 400 401 402 FT_DEFINE_SERVICE_GLYPHDICTREC( 403 cff_service_glyph_dict, 404 405 cff_get_glyph_name, /* FT_GlyphDict_GetNameFunc get_name */ 406 cff_get_name_index /* FT_GlyphDict_NameIndexFunc name_index */ 407 ) 408 409 410 /* 411 * POSTSCRIPT INFO SERVICE 412 * 413 */ 414 415 FT_CALLBACK_DEF( FT_Int ) 416 cff_ps_has_glyph_names( FT_Face face ) 417 { 418 return ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) > 0; 419 } 420 421 422 FT_CALLBACK_DEF( FT_Error ) 423 cff_ps_get_font_info( FT_Face face, /* CFF_Face */ 424 PS_FontInfoRec* afont_info ) 425 { 426 CFF_Face cffface = (CFF_Face)face; 427 CFF_Font cff = (CFF_Font)cffface->extra.data; 428 FT_Error error = FT_Err_Ok; 429 430 431 if ( cffface->is_cff2 ) 432 { 433 error = FT_THROW( Invalid_Argument ); 434 goto Fail; 435 } 436 437 if ( cff && !cff->font_info ) 438 { 439 CFF_FontRecDict dict = &cff->top_font.font_dict; 440 FT_Memory memory = FT_FACE_MEMORY( face ); 441 PS_FontInfoRec* font_info = NULL; 442 443 444 if ( FT_QNEW( font_info ) ) 445 goto Fail; 446 447 font_info->version = cff_index_get_sid_string( cff, 448 dict->version ); 449 font_info->notice = cff_index_get_sid_string( cff, 450 dict->notice ); 451 font_info->full_name = cff_index_get_sid_string( cff, 452 dict->full_name ); 453 font_info->family_name = cff_index_get_sid_string( cff, 454 dict->family_name ); 455 font_info->weight = cff_index_get_sid_string( cff, 456 dict->weight ); 457 font_info->italic_angle = dict->italic_angle; 458 font_info->is_fixed_pitch = dict->is_fixed_pitch; 459 font_info->underline_position = (FT_Short)dict->underline_position; 460 font_info->underline_thickness = (FT_UShort)dict->underline_thickness; 461 462 cff->font_info = font_info; 463 } 464 465 if ( cff ) 466 *afont_info = *cff->font_info; 467 468 Fail: 469 return error; 470 } 471 472 473 FT_CALLBACK_DEF( FT_Error ) 474 cff_ps_get_font_extra( FT_Face face, /* CFF_Face */ 475 PS_FontExtraRec* afont_extra ) 476 { 477 CFF_Face cffface = (CFF_Face)face; 478 CFF_Font cff = (CFF_Font)cffface->extra.data; 479 FT_Error error = FT_Err_Ok; 480 481 482 if ( cff && !cff->font_extra ) 483 { 484 CFF_FontRecDict dict = &cff->top_font.font_dict; 485 FT_Memory memory = FT_FACE_MEMORY( face ); 486 PS_FontExtraRec* font_extra = NULL; 487 FT_String* embedded_postscript; 488 489 490 if ( FT_QNEW( font_extra ) ) 491 goto Fail; 492 493 font_extra->fs_type = 0U; 494 495 embedded_postscript = cff_index_get_sid_string( 496 cff, 497 dict->embedded_postscript ); 498 if ( embedded_postscript ) 499 { 500 FT_String* start_fstype; 501 FT_String* start_def; 502 503 504 /* Identify the XYZ integer in `/FSType XYZ def' substring. */ 505 if ( ( start_fstype = ft_strstr( embedded_postscript, 506 "/FSType" ) ) != NULL && 507 ( start_def = ft_strstr( start_fstype + 508 sizeof ( "/FSType" ) - 1, 509 "def" ) ) != NULL ) 510 { 511 FT_String* s; 512 513 514 for ( s = start_fstype + sizeof ( "/FSType" ) - 1; 515 s != start_def; 516 s++ ) 517 { 518 if ( *s >= '0' && *s <= '9' ) 519 { 520 if ( font_extra->fs_type >= ( FT_USHORT_MAX - 9 ) / 10 ) 521 { 522 /* Overflow - ignore the FSType value. */ 523 font_extra->fs_type = 0U; 524 break; 525 } 526 527 font_extra->fs_type *= 10; 528 font_extra->fs_type += (FT_UShort)( *s - '0' ); 529 } 530 else if ( *s != ' ' && *s != '\n' && *s != '\r' ) 531 { 532 /* Non-whitespace character between `/FSType' and next `def' */ 533 /* - ignore the FSType value. */ 534 font_extra->fs_type = 0U; 535 break; 536 } 537 } 538 } 539 } 540 541 cff->font_extra = font_extra; 542 } 543 544 if ( cff ) 545 *afont_extra = *cff->font_extra; 546 547 Fail: 548 return error; 549 } 550 551 552 FT_DEFINE_SERVICE_PSINFOREC( 553 cff_service_ps_info, 554 555 cff_ps_get_font_info, /* PS_GetFontInfoFunc ps_get_font_info */ 556 cff_ps_get_font_extra, /* PS_GetFontExtraFunc ps_get_font_extra */ 557 cff_ps_has_glyph_names, /* PS_HasGlyphNamesFunc ps_has_glyph_names */ 558 /* unsupported with CFF fonts */ 559 NULL, /* PS_GetFontPrivateFunc ps_get_font_private */ 560 /* not implemented */ 561 NULL /* PS_GetFontValueFunc ps_get_font_value */ 562 ) 563 564 565 /* 566 * POSTSCRIPT NAME SERVICE 567 * 568 */ 569 570 FT_CALLBACK_DEF( const char* ) 571 cff_get_ps_name( FT_Face face ) /* CFF_Face */ 572 { 573 CFF_Face cffface = (CFF_Face)face; 574 CFF_Font cff = (CFF_Font)cffface->extra.data; 575 SFNT_Service sfnt = (SFNT_Service)cffface->sfnt; 576 577 578 /* following the OpenType specification 1.7, we return the name stored */ 579 /* in the `name' table for a CFF wrapped into an SFNT container */ 580 581 if ( FT_IS_SFNT( face ) && sfnt ) 582 { 583 FT_Library library = FT_FACE_LIBRARY( face ); 584 FT_Module sfnt_module = FT_Get_Module( library, "sfnt" ); 585 FT_Service_PsFontName service = 586 (FT_Service_PsFontName)ft_module_get_service( 587 sfnt_module, 588 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, 589 0 ); 590 591 592 if ( service && service->get_ps_font_name ) 593 return service->get_ps_font_name( face ); 594 } 595 596 return cff ? (const char*)cff->font_name : NULL; 597 } 598 599 600 FT_DEFINE_SERVICE_PSFONTNAMEREC( 601 cff_service_ps_name, 602 603 cff_get_ps_name /* FT_PsName_GetFunc get_ps_font_name */ 604 ) 605 606 607 /* 608 * TT CMAP INFO 609 * 610 * If the charmap is a synthetic Unicode encoding cmap or 611 * a Type 1 standard (or expert) encoding cmap, hide TT CMAP INFO 612 * service defined in SFNT module. 613 * 614 * Otherwise call the service function in the sfnt module. 615 * 616 */ 617 FT_CALLBACK_DEF( FT_Error ) 618 cff_get_cmap_info( FT_CharMap charmap, 619 TT_CMapInfo *cmap_info ) 620 { 621 FT_CMap cmap = FT_CMAP( charmap ); 622 FT_Error error = FT_Err_Ok; 623 624 FT_Face face = FT_CMAP_FACE( cmap ); 625 FT_Library library = FT_FACE_LIBRARY( face ); 626 627 628 if ( cmap->clazz != &cff_cmap_encoding_class_rec && 629 cmap->clazz != &cff_cmap_unicode_class_rec ) 630 { 631 FT_Module sfnt = FT_Get_Module( library, "sfnt" ); 632 FT_Service_TTCMaps service = 633 (FT_Service_TTCMaps)ft_module_get_service( sfnt, 634 FT_SERVICE_ID_TT_CMAP, 635 0 ); 636 637 638 if ( service && service->get_cmap_info ) 639 error = service->get_cmap_info( charmap, cmap_info ); 640 } 641 else 642 error = FT_THROW( Invalid_CharMap_Format ); 643 644 return error; 645 } 646 647 648 FT_DEFINE_SERVICE_TTCMAPSREC( 649 cff_service_get_cmap_info, 650 651 cff_get_cmap_info /* TT_CMap_Info_GetFunc get_cmap_info */ 652 ) 653 654 655 /* 656 * CID INFO SERVICE 657 * 658 */ 659 FT_CALLBACK_DEF( FT_Error ) 660 cff_get_ros( FT_Face face, /* FT_Face */ 661 const char* *registry, 662 const char* *ordering, 663 FT_Int *supplement ) 664 { 665 FT_Error error = FT_Err_Ok; 666 CFF_Face cffface = (CFF_Face)face; 667 CFF_Font cff = (CFF_Font)cffface->extra.data; 668 669 670 if ( cff ) 671 { 672 CFF_FontRecDict dict = &cff->top_font.font_dict; 673 674 675 if ( dict->cid_registry == 0xFFFFU ) 676 { 677 error = FT_THROW( Invalid_Argument ); 678 goto Fail; 679 } 680 681 if ( registry ) 682 { 683 if ( !cff->registry ) 684 cff->registry = cff_index_get_sid_string( cff, 685 dict->cid_registry ); 686 *registry = cff->registry; 687 } 688 689 if ( ordering ) 690 { 691 if ( !cff->ordering ) 692 cff->ordering = cff_index_get_sid_string( cff, 693 dict->cid_ordering ); 694 *ordering = cff->ordering; 695 } 696 697 /* 698 * XXX: According to Adobe TechNote #5176, the supplement in CFF 699 * can be a real number. We truncate it to fit public API 700 * since freetype-2.3.6. 701 */ 702 if ( supplement ) 703 { 704 if ( dict->cid_supplement < FT_INT_MIN || 705 dict->cid_supplement > FT_INT_MAX ) 706 FT_TRACE1(( "cff_get_ros: too large supplement %ld is truncated\n", 707 dict->cid_supplement )); 708 *supplement = (FT_Int)dict->cid_supplement; 709 } 710 } 711 712 Fail: 713 return error; 714 } 715 716 717 FT_CALLBACK_DEF( FT_Error ) 718 cff_get_is_cid( FT_Face face, /* CFF_Face */ 719 FT_Bool *is_cid ) 720 { 721 FT_Error error = FT_Err_Ok; 722 CFF_Face cffface = (CFF_Face)face; 723 CFF_Font cff = (CFF_Font)cffface->extra.data; 724 725 726 *is_cid = 0; 727 728 if ( cff ) 729 { 730 CFF_FontRecDict dict = &cff->top_font.font_dict; 731 732 733 if ( dict->cid_registry != 0xFFFFU ) 734 *is_cid = 1; 735 } 736 737 return error; 738 } 739 740 741 FT_CALLBACK_DEF( FT_Error ) 742 cff_get_cid_from_glyph_index( FT_Face face, /* CFF_Face */ 743 FT_UInt glyph_index, 744 FT_UInt *cid ) 745 { 746 FT_Error error = FT_Err_Ok; 747 CFF_Face cffface = (CFF_Face)face; 748 CFF_Font cff = (CFF_Font)cffface->extra.data; 749 750 751 if ( cff ) 752 { 753 FT_UInt c; 754 CFF_FontRecDict dict = &cff->top_font.font_dict; 755 756 757 if ( dict->cid_registry == 0xFFFFU ) 758 { 759 error = FT_THROW( Invalid_Argument ); 760 goto Fail; 761 } 762 763 if ( glyph_index >= cff->num_glyphs ) 764 { 765 error = FT_THROW( Invalid_Argument ); 766 goto Fail; 767 } 768 769 c = cff->charset.sids[glyph_index]; 770 771 if ( cid ) 772 *cid = c; 773 } 774 775 Fail: 776 return error; 777 } 778 779 780 FT_DEFINE_SERVICE_CIDREC( 781 cff_service_cid_info, 782 783 cff_get_ros, 784 /* FT_CID_GetRegistryOrderingSupplementFunc get_ros */ 785 cff_get_is_cid, 786 /* FT_CID_GetIsInternallyCIDKeyedFunc get_is_cid */ 787 cff_get_cid_from_glyph_index 788 /* FT_CID_GetCIDFromGlyphIndexFunc get_cid_from_glyph_index */ 789 ) 790 791 792 /* 793 * PROPERTY SERVICE 794 * 795 */ 796 797 FT_DEFINE_SERVICE_PROPERTIESREC( 798 cff_service_properties, 799 800 ps_property_set, /* FT_Properties_SetFunc set_property */ 801 ps_property_get /* FT_Properties_GetFunc get_property */ 802 ) 803 804 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 805 806 /* 807 * MULTIPLE MASTER SERVICE 808 * 809 */ 810 811 FT_CALLBACK_DEF( FT_Error ) 812 cff_set_mm_blend( FT_Face face, /* CFF_Face */ 813 FT_UInt num_coords, 814 FT_Fixed* coords ) 815 { 816 CFF_Face cffface = (CFF_Face)face; 817 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm; 818 819 820 return mm->set_mm_blend( face, num_coords, coords ); 821 } 822 823 824 FT_CALLBACK_DEF( FT_Error ) 825 cff_get_mm_blend( FT_Face face, /* CFF_Face */ 826 FT_UInt num_coords, 827 FT_Fixed* coords ) 828 { 829 CFF_Face cffface = (CFF_Face)face; 830 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm; 831 832 833 return mm->get_mm_blend( face, num_coords, coords ); 834 } 835 836 837 FT_CALLBACK_DEF( FT_Error ) 838 cff_set_mm_weightvector( FT_Face face, /* CFF_Face */ 839 FT_UInt len, 840 FT_Fixed* weightvector ) 841 { 842 CFF_Face cffface = (CFF_Face)face; 843 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm; 844 845 846 return mm->set_mm_weightvector( face, len, weightvector ); 847 } 848 849 850 FT_CALLBACK_DEF( FT_Error ) 851 cff_get_mm_weightvector( FT_Face face, /* CFF_Face */ 852 FT_UInt* len, 853 FT_Fixed* weightvector ) 854 { 855 CFF_Face cffface = (CFF_Face)face; 856 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm; 857 858 859 return mm->get_mm_weightvector( face, len, weightvector ); 860 } 861 862 863 FT_CALLBACK_DEF( void ) 864 cff_construct_ps_name( FT_Face face ) /* CFF_Face */ 865 { 866 CFF_Face cffface = (CFF_Face)face; 867 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm; 868 869 870 mm->construct_ps_name( face ); 871 } 872 873 874 FT_CALLBACK_DEF( FT_Error ) 875 cff_get_mm_var( FT_Face face, /* CFF_Face */ 876 FT_MM_Var* *master ) 877 { 878 CFF_Face cffface = (CFF_Face)face; 879 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm; 880 881 882 return mm->get_mm_var( face, master ); 883 } 884 885 886 FT_CALLBACK_DEF( FT_Error ) 887 cff_set_var_design( FT_Face face, /* CFF_Face */ 888 FT_UInt num_coords, 889 FT_Fixed* coords ) 890 { 891 CFF_Face cffface = (CFF_Face)face; 892 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm; 893 894 895 return mm->set_var_design( face, num_coords, coords ); 896 } 897 898 899 FT_CALLBACK_DEF( FT_Error ) 900 cff_get_var_design( FT_Face face, /* CFF_Face */ 901 FT_UInt num_coords, 902 FT_Fixed* coords ) 903 { 904 CFF_Face cffface = (CFF_Face)face; 905 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm; 906 907 908 return mm->get_var_design( face, num_coords, coords ); 909 } 910 911 912 FT_CALLBACK_DEF( FT_Error ) 913 cff_set_named_instance( FT_Face face, /* CFF_Face */ 914 FT_UInt instance_index ) 915 { 916 CFF_Face cffface = (CFF_Face)face; 917 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm; 918 919 920 return mm->set_named_instance( face, instance_index ); 921 } 922 923 924 FT_CALLBACK_DEF( FT_Error ) 925 cff_get_default_named_instance( FT_Face face, /* CFF_Face */ 926 FT_UInt *instance_index ) 927 { 928 CFF_Face cffface = (CFF_Face)face; 929 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm; 930 931 932 return mm->get_default_named_instance( face, instance_index ); 933 } 934 935 936 FT_CALLBACK_DEF( FT_Error ) 937 cff_load_item_variation_store( FT_Face face, /* CFF_Face */ 938 FT_ULong offset, 939 GX_ItemVarStore itemStore ) 940 { 941 CFF_Face cffface = (CFF_Face)face; 942 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm; 943 944 945 return mm->load_item_var_store( face, offset, itemStore ); 946 } 947 948 949 FT_CALLBACK_DEF( FT_Error ) 950 cff_load_delta_set_index_mapping( FT_Face face, /* CFF_Face */ 951 FT_ULong offset, 952 GX_DeltaSetIdxMap map, 953 GX_ItemVarStore itemStore, 954 FT_ULong table_len ) 955 { 956 CFF_Face cffface = (CFF_Face)face; 957 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm; 958 959 960 return mm->load_delta_set_idx_map( face, offset, map, 961 itemStore, table_len ); 962 } 963 964 965 FT_CALLBACK_DEF( FT_Int ) 966 cff_get_item_delta( FT_Face face, /* CFF_Face */ 967 GX_ItemVarStore itemStore, 968 FT_UInt outerIndex, 969 FT_UInt innerIndex ) 970 { 971 CFF_Face cffface = (CFF_Face)face; 972 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm; 973 974 975 return mm->get_item_delta( face, itemStore, outerIndex, innerIndex ); 976 } 977 978 979 FT_CALLBACK_DEF( void ) 980 cff_done_item_variation_store( FT_Face face, /* CFF_Face */ 981 GX_ItemVarStore itemStore ) 982 { 983 CFF_Face cffface = (CFF_Face)face; 984 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm; 985 986 987 mm->done_item_var_store( face, itemStore ); 988 } 989 990 991 FT_CALLBACK_DEF( void ) 992 cff_done_delta_set_index_map( FT_Face face, /* CFF_Face */ 993 GX_DeltaSetIdxMap deltaSetIdxMap ) 994 { 995 CFF_Face cffface = (CFF_Face)face; 996 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm; 997 998 999 mm->done_delta_set_idx_map( face, deltaSetIdxMap ); 1000 } 1001 1002 1003 1004 FT_DEFINE_SERVICE_MULTIMASTERSREC( 1005 cff_service_multi_masters, 1006 1007 NULL, /* FT_Get_MM_Func get_mm */ 1008 NULL, /* FT_Set_MM_Design_Func set_mm_design */ 1009 cff_set_mm_blend, /* FT_Set_MM_Blend_Func set_mm_blend */ 1010 cff_get_mm_blend, /* FT_Get_MM_Blend_Func get_mm_blend */ 1011 cff_get_mm_var, /* FT_Get_MM_Var_Func get_mm_var */ 1012 cff_set_var_design, /* FT_Set_Var_Design_Func set_var_design */ 1013 cff_get_var_design, /* FT_Get_Var_Design_Func get_var_design */ 1014 cff_set_named_instance, 1015 /* FT_Set_Named_Instance_Func set_named_instance */ 1016 cff_get_default_named_instance, 1017 /* FT_Get_Default_Named_Instance_Func get_default_named_instance */ 1018 cff_set_mm_weightvector, 1019 /* FT_Set_MM_WeightVector_Func set_mm_weightvector */ 1020 cff_get_mm_weightvector, 1021 /* FT_Get_MM_WeightVector_Func get_mm_weightvector */ 1022 cff_construct_ps_name, 1023 /* FT_Construct_PS_Name_Func construct_ps_name */ 1024 cff_load_delta_set_index_mapping, 1025 /* FT_Var_Load_Delta_Set_Idx_Map_Func load_delta_set_idx_map */ 1026 cff_load_item_variation_store, 1027 /* FT_Var_Load_Item_Var_Store_Func load_item_variation_store */ 1028 cff_get_item_delta, 1029 /* FT_Var_Get_Item_Delta_Func get_item_delta */ 1030 cff_done_item_variation_store, 1031 /* FT_Var_Done_Item_Var_Store_Func done_item_variation_store */ 1032 cff_done_delta_set_index_map, 1033 /* FT_Var_Done_Delta_Set_Idx_Map_Func done_delta_set_index_map */ 1034 cff_get_var_blend, /* FT_Get_Var_Blend_Func get_var_blend */ 1035 cff_done_blend /* FT_Done_Blend_Func done_blend */ 1036 ) 1037 1038 1039 /* 1040 * METRICS VARIATIONS SERVICE 1041 * 1042 */ 1043 1044 FT_CALLBACK_DEF( FT_Error ) 1045 cff_hadvance_adjust( FT_Face face, /* CFF_Face */ 1046 FT_UInt gindex, 1047 FT_Int *avalue ) 1048 { 1049 CFF_Face cffface = (CFF_Face)face; 1050 FT_Service_MetricsVariations 1051 var = (FT_Service_MetricsVariations)cffface->tt_var; 1052 1053 1054 return var->hadvance_adjust( face, gindex, avalue ); 1055 } 1056 1057 1058 FT_CALLBACK_DEF( void ) 1059 cff_metrics_adjust( FT_Face face ) /* CFF_Face */ 1060 { 1061 CFF_Face cffface = (CFF_Face)face; 1062 FT_Service_MetricsVariations 1063 var = (FT_Service_MetricsVariations)cffface->tt_var; 1064 1065 1066 var->metrics_adjust( face ); 1067 } 1068 1069 1070 FT_DEFINE_SERVICE_METRICSVARIATIONSREC( 1071 cff_service_metrics_variations, 1072 1073 cff_hadvance_adjust, /* FT_HAdvance_Adjust_Func hadvance_adjust */ 1074 NULL, /* FT_LSB_Adjust_Func lsb_adjust */ 1075 NULL, /* FT_RSB_Adjust_Func rsb_adjust */ 1076 1077 NULL, /* FT_VAdvance_Adjust_Func vadvance_adjust */ 1078 NULL, /* FT_TSB_Adjust_Func tsb_adjust */ 1079 NULL, /* FT_BSB_Adjust_Func bsb_adjust */ 1080 NULL, /* FT_VOrg_Adjust_Func vorg_adjust */ 1081 1082 cff_metrics_adjust, /* FT_Metrics_Adjust_Func metrics_adjust */ 1083 NULL /* FT_Size_Reset_Func size_reset */ 1084 ) 1085 #endif 1086 1087 1088 /* 1089 * CFFLOAD SERVICE 1090 * 1091 */ 1092 1093 FT_DEFINE_SERVICE_CFFLOADREC( 1094 cff_service_cff_load, 1095 1096 cff_get_standard_encoding, /* FT_Get_Standard_Encoding_Func get_standard_encoding */ 1097 cff_load_private_dict, /* FT_Load_Private_Dict_Func load_private_dict */ 1098 cff_fd_select_get, /* FT_FD_Select_Get_Func fd_select_get */ 1099 cff_blend_check_vector, /* FT_Blend_Check_Vector_Func blend_check_vector */ 1100 cff_blend_build_vector /* FT_Blend_Build_Vector_Func blend_build_vector */ 1101 ) 1102 1103 1104 /*************************************************************************/ 1105 /*************************************************************************/ 1106 /*************************************************************************/ 1107 /**** ****/ 1108 /**** ****/ 1109 /**** D R I V E R I N T E R F A C E ****/ 1110 /**** ****/ 1111 /**** ****/ 1112 /*************************************************************************/ 1113 /*************************************************************************/ 1114 /*************************************************************************/ 1115 1116 #if defined TT_CONFIG_OPTION_GX_VAR_SUPPORT 1117 FT_DEFINE_SERVICEDESCREC10( 1118 cff_services, 1119 1120 FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_CFF, 1121 FT_SERVICE_ID_MULTI_MASTERS, &cff_service_multi_masters, 1122 FT_SERVICE_ID_METRICS_VARIATIONS, &cff_service_metrics_variations, 1123 FT_SERVICE_ID_POSTSCRIPT_INFO, &cff_service_ps_info, 1124 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cff_service_ps_name, 1125 FT_SERVICE_ID_GLYPH_DICT, &cff_service_glyph_dict, 1126 FT_SERVICE_ID_TT_CMAP, &cff_service_get_cmap_info, 1127 FT_SERVICE_ID_CID, &cff_service_cid_info, 1128 FT_SERVICE_ID_PROPERTIES, &cff_service_properties, 1129 FT_SERVICE_ID_CFF_LOAD, &cff_service_cff_load 1130 ) 1131 #else 1132 FT_DEFINE_SERVICEDESCREC8( 1133 cff_services, 1134 1135 FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_CFF, 1136 FT_SERVICE_ID_POSTSCRIPT_INFO, &cff_service_ps_info, 1137 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cff_service_ps_name, 1138 FT_SERVICE_ID_GLYPH_DICT, &cff_service_glyph_dict, 1139 FT_SERVICE_ID_TT_CMAP, &cff_service_get_cmap_info, 1140 FT_SERVICE_ID_CID, &cff_service_cid_info, 1141 FT_SERVICE_ID_PROPERTIES, &cff_service_properties, 1142 FT_SERVICE_ID_CFF_LOAD, &cff_service_cff_load 1143 ) 1144 #endif 1145 1146 1147 FT_CALLBACK_DEF( FT_Module_Interface ) 1148 cff_get_interface( FT_Module driver, /* CFF_Driver */ 1149 const char* module_interface ) 1150 { 1151 FT_Library library; 1152 FT_Module sfnt; 1153 FT_Module_Interface result; 1154 1155 1156 result = ft_service_list_lookup( cff_services, module_interface ); 1157 if ( result ) 1158 return result; 1159 1160 /* `driver' is not yet evaluated */ 1161 if ( !driver ) 1162 return NULL; 1163 library = driver->library; 1164 if ( !library ) 1165 return NULL; 1166 1167 /* we pass our request to the `sfnt' module */ 1168 sfnt = FT_Get_Module( library, "sfnt" ); 1169 1170 return sfnt ? sfnt->clazz->get_interface( sfnt, module_interface ) : 0; 1171 } 1172 1173 1174 /* The FT_DriverInterface structure is defined in ftdriver.h. */ 1175 1176 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS 1177 #define CFF_SIZE_SELECT cff_size_select 1178 #else 1179 #define CFF_SIZE_SELECT 0 1180 #endif 1181 1182 FT_DEFINE_DRIVER( 1183 cff_driver_class, 1184 1185 FT_MODULE_FONT_DRIVER | 1186 FT_MODULE_DRIVER_SCALABLE | 1187 FT_MODULE_DRIVER_HAS_HINTER | 1188 FT_MODULE_DRIVER_HINTS_LIGHTLY, 1189 1190 sizeof ( PS_DriverRec ), 1191 "cff", 1192 0x10000L, 1193 0x20000L, 1194 1195 NULL, /* module-specific interface */ 1196 1197 cff_driver_init, /* FT_Module_Constructor module_init */ 1198 cff_driver_done, /* FT_Module_Destructor module_done */ 1199 cff_get_interface, /* FT_Module_Requester get_interface */ 1200 1201 sizeof ( TT_FaceRec ), 1202 sizeof ( CFF_SizeRec ), 1203 sizeof ( CFF_GlyphSlotRec ), 1204 1205 cff_face_init, /* FT_Face_InitFunc init_face */ 1206 cff_face_done, /* FT_Face_DoneFunc done_face */ 1207 cff_size_init, /* FT_Size_InitFunc init_size */ 1208 cff_size_done, /* FT_Size_DoneFunc done_size */ 1209 cff_slot_init, /* FT_Slot_InitFunc init_slot */ 1210 cff_slot_done, /* FT_Slot_DoneFunc done_slot */ 1211 1212 cff_glyph_load, /* FT_Slot_LoadFunc load_glyph */ 1213 1214 cff_get_kerning, /* FT_Face_GetKerningFunc get_kerning */ 1215 NULL, /* FT_Face_AttachFunc attach_file */ 1216 cff_get_advances, /* FT_Face_GetAdvancesFunc get_advances */ 1217 1218 cff_size_request, /* FT_Size_RequestFunc request_size */ 1219 CFF_SIZE_SELECT /* FT_Size_SelectFunc select_size */ 1220 ) 1221 1222 1223 /* END */