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