1 /***************************************************************************/ 2 /* */ 3 /* cffobjs.c */ 4 /* */ 5 /* OpenType objects manager (body). */ 6 /* */ 7 /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 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_INTERNAL_DEBUG_H 21 #include FT_INTERNAL_CALC_H 22 #include FT_INTERNAL_STREAM_H 23 #include FT_ERRORS_H 24 #include FT_TRUETYPE_IDS_H 25 #include FT_TRUETYPE_TAGS_H 26 #include FT_INTERNAL_SFNT_H 27 #include FT_SERVICE_POSTSCRIPT_CMAPS_H 28 #include FT_INTERNAL_POSTSCRIPT_HINTS_H 29 #include "cffobjs.h" 30 #include "cffload.h" 31 #include "cffcmap.h" 32 #include "cfferrs.h" 33 #include "cffpic.h" 34 35 36 /*************************************************************************/ 37 /* */ 38 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 39 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 40 /* messages during execution. */ 41 /* */ 42 #undef FT_COMPONENT 43 #define FT_COMPONENT trace_cffobjs 44 45 46 /*************************************************************************/ 47 /* */ 48 /* SIZE FUNCTIONS */ 49 /* */ 50 /* Note that we store the global hints in the size's `internal' root */ 51 /* field. */ 52 /* */ 53 /*************************************************************************/ 54 55 56 static PSH_Globals_Funcs 57 cff_size_get_globals_funcs( CFF_Size size ) 58 { 59 CFF_Face face = (CFF_Face)size->root.face; 60 CFF_Font font = (CFF_Font)face->extra.data; 61 PSHinter_Service pshinter = (PSHinter_Service)font->pshinter; 62 FT_Module module; 63 64 65 module = FT_Get_Module( size->root.face->driver->root.library, 66 "pshinter" ); 67 return ( module && pshinter && pshinter->get_globals_funcs ) 68 ? pshinter->get_globals_funcs( module ) 69 : 0; 70 } 71 72 73 FT_LOCAL_DEF( void ) 74 cff_size_done( FT_Size cffsize ) /* CFF_Size */ 75 { 76 CFF_Size size = (CFF_Size)cffsize; 77 CFF_Face face = (CFF_Face)size->root.face; 78 CFF_Font font = (CFF_Font)face->extra.data; 79 CFF_Internal internal = (CFF_Internal)cffsize->internal; 80 81 82 if ( internal ) 83 { 84 PSH_Globals_Funcs funcs; 85 86 87 funcs = cff_size_get_globals_funcs( size ); 88 if ( funcs ) 89 { 90 FT_UInt i; 91 92 93 funcs->destroy( internal->topfont ); 94 95 for ( i = font->num_subfonts; i > 0; i-- ) 96 funcs->destroy( internal->subfonts[i - 1] ); 97 } 98 99 /* `internal' is freed by destroy_size (in ftobjs.c) */ 100 } 101 } 102 103 104 /* CFF and Type 1 private dictionaries have slightly different */ 105 /* structures; we need to synthesize a Type 1 dictionary on the fly */ 106 107 static void 108 cff_make_private_dict( CFF_SubFont subfont, 109 PS_Private priv ) 110 { 111 CFF_Private cpriv = &subfont->private_dict; 112 FT_UInt n, count; 113 114 115 FT_MEM_ZERO( priv, sizeof ( *priv ) ); 116 117 count = priv->num_blue_values = cpriv->num_blue_values; 118 for ( n = 0; n < count; n++ ) 119 priv->blue_values[n] = (FT_Short)cpriv->blue_values[n]; 120 121 count = priv->num_other_blues = cpriv->num_other_blues; 122 for ( n = 0; n < count; n++ ) 123 priv->other_blues[n] = (FT_Short)cpriv->other_blues[n]; 124 125 count = priv->num_family_blues = cpriv->num_family_blues; 126 for ( n = 0; n < count; n++ ) 127 priv->family_blues[n] = (FT_Short)cpriv->family_blues[n]; 128 129 count = priv->num_family_other_blues = cpriv->num_family_other_blues; 130 for ( n = 0; n < count; n++ ) 131 priv->family_other_blues[n] = (FT_Short)cpriv->family_other_blues[n]; 132 133 priv->blue_scale = cpriv->blue_scale; 134 priv->blue_shift = (FT_Int)cpriv->blue_shift; 135 priv->blue_fuzz = (FT_Int)cpriv->blue_fuzz; 136 137 priv->standard_width[0] = (FT_UShort)cpriv->standard_width; 138 priv->standard_height[0] = (FT_UShort)cpriv->standard_height; 139 140 count = priv->num_snap_widths = cpriv->num_snap_widths; 141 for ( n = 0; n < count; n++ ) 142 priv->snap_widths[n] = (FT_Short)cpriv->snap_widths[n]; 143 144 count = priv->num_snap_heights = cpriv->num_snap_heights; 145 for ( n = 0; n < count; n++ ) 146 priv->snap_heights[n] = (FT_Short)cpriv->snap_heights[n]; 147 148 priv->force_bold = cpriv->force_bold; 149 priv->language_group = cpriv->language_group; 150 priv->lenIV = cpriv->lenIV; 151 } 152 153 154 FT_LOCAL_DEF( FT_Error ) 155 cff_size_init( FT_Size cffsize ) /* CFF_Size */ 156 { 157 CFF_Size size = (CFF_Size)cffsize; 158 FT_Error error = CFF_Err_Ok; 159 PSH_Globals_Funcs funcs = cff_size_get_globals_funcs( size ); 160 161 162 if ( funcs ) 163 { 164 CFF_Face face = (CFF_Face)cffsize->face; 165 CFF_Font font = (CFF_Font)face->extra.data; 166 CFF_Internal internal; 167 168 PS_PrivateRec priv; 169 FT_Memory memory = cffsize->face->memory; 170 171 FT_UInt i; 172 173 174 if ( FT_NEW( internal ) ) 175 goto Exit; 176 177 cff_make_private_dict( &font->top_font, &priv ); 178 error = funcs->create( cffsize->face->memory, &priv, 179 &internal->topfont ); 180 if ( error ) 181 goto Exit; 182 183 for ( i = font->num_subfonts; i > 0; i-- ) 184 { 185 CFF_SubFont sub = font->subfonts[i - 1]; 186 187 188 cff_make_private_dict( sub, &priv ); 189 error = funcs->create( cffsize->face->memory, &priv, 190 &internal->subfonts[i - 1] ); 191 if ( error ) 192 goto Exit; 193 } 194 195 cffsize->internal = (FT_Size_Internal)(void*)internal; 196 } 197 198 size->strike_index = 0xFFFFFFFFUL; 199 200 Exit: 201 return error; 202 } 203 204 205 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS 206 207 FT_LOCAL_DEF( FT_Error ) 208 cff_size_select( FT_Size size, 209 FT_ULong strike_index ) 210 { 211 CFF_Size cffsize = (CFF_Size)size; 212 PSH_Globals_Funcs funcs; 213 214 215 cffsize->strike_index = strike_index; 216 217 FT_Select_Metrics( size->face, strike_index ); 218 219 funcs = cff_size_get_globals_funcs( cffsize ); 220 221 if ( funcs ) 222 { 223 CFF_Face face = (CFF_Face)size->face; 224 CFF_Font font = (CFF_Font)face->extra.data; 225 CFF_Internal internal = (CFF_Internal)size->internal; 226 227 FT_ULong top_upm = font->top_font.font_dict.units_per_em; 228 FT_UInt i; 229 230 231 funcs->set_scale( internal->topfont, 232 size->metrics.x_scale, size->metrics.y_scale, 233 0, 0 ); 234 235 for ( i = font->num_subfonts; i > 0; i-- ) 236 { 237 CFF_SubFont sub = font->subfonts[i - 1]; 238 FT_ULong sub_upm = sub->font_dict.units_per_em; 239 FT_Pos x_scale, y_scale; 240 241 242 if ( top_upm != sub_upm ) 243 { 244 x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm ); 245 y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm ); 246 } 247 else 248 { 249 x_scale = size->metrics.x_scale; 250 y_scale = size->metrics.y_scale; 251 } 252 253 funcs->set_scale( internal->subfonts[i - 1], 254 x_scale, y_scale, 0, 0 ); 255 } 256 } 257 258 return CFF_Err_Ok; 259 } 260 261 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ 262 263 264 FT_LOCAL_DEF( FT_Error ) 265 cff_size_request( FT_Size size, 266 FT_Size_Request req ) 267 { 268 CFF_Size cffsize = (CFF_Size)size; 269 PSH_Globals_Funcs funcs; 270 271 272 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS 273 274 if ( FT_HAS_FIXED_SIZES( size->face ) ) 275 { 276 CFF_Face cffface = (CFF_Face)size->face; 277 SFNT_Service sfnt = (SFNT_Service)cffface->sfnt; 278 FT_ULong strike_index; 279 280 281 if ( sfnt->set_sbit_strike( cffface, req, &strike_index ) ) 282 cffsize->strike_index = 0xFFFFFFFFUL; 283 else 284 return cff_size_select( size, strike_index ); 285 } 286 287 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ 288 289 FT_Request_Metrics( size->face, req ); 290 291 funcs = cff_size_get_globals_funcs( cffsize ); 292 293 if ( funcs ) 294 { 295 CFF_Face cffface = (CFF_Face)size->face; 296 CFF_Font font = (CFF_Font)cffface->extra.data; 297 CFF_Internal internal = (CFF_Internal)size->internal; 298 299 FT_ULong top_upm = font->top_font.font_dict.units_per_em; 300 FT_UInt i; 301 302 303 funcs->set_scale( internal->topfont, 304 size->metrics.x_scale, size->metrics.y_scale, 305 0, 0 ); 306 307 for ( i = font->num_subfonts; i > 0; i-- ) 308 { 309 CFF_SubFont sub = font->subfonts[i - 1]; 310 FT_ULong sub_upm = sub->font_dict.units_per_em; 311 FT_Pos x_scale, y_scale; 312 313 314 if ( top_upm != sub_upm ) 315 { 316 x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm ); 317 y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm ); 318 } 319 else 320 { 321 x_scale = size->metrics.x_scale; 322 y_scale = size->metrics.y_scale; 323 } 324 325 funcs->set_scale( internal->subfonts[i - 1], 326 x_scale, y_scale, 0, 0 ); 327 } 328 } 329 330 return CFF_Err_Ok; 331 } 332 333 334 /*************************************************************************/ 335 /* */ 336 /* SLOT FUNCTIONS */ 337 /* */ 338 /*************************************************************************/ 339 340 FT_LOCAL_DEF( void ) 341 cff_slot_done( FT_GlyphSlot slot ) 342 { 343 slot->internal->glyph_hints = 0; 344 } 345 346 347 FT_LOCAL_DEF( FT_Error ) 348 cff_slot_init( FT_GlyphSlot slot ) 349 { 350 CFF_Face face = (CFF_Face)slot->face; 351 CFF_Font font = (CFF_Font)face->extra.data; 352 PSHinter_Service pshinter = (PSHinter_Service)font->pshinter; 353 354 355 if ( pshinter ) 356 { 357 FT_Module module; 358 359 360 module = FT_Get_Module( slot->face->driver->root.library, 361 "pshinter" ); 362 if ( module ) 363 { 364 T2_Hints_Funcs funcs; 365 366 367 funcs = pshinter->get_t2_funcs( module ); 368 slot->internal->glyph_hints = (void*)funcs; 369 } 370 } 371 372 return CFF_Err_Ok; 373 } 374 375 376 /*************************************************************************/ 377 /* */ 378 /* FACE FUNCTIONS */ 379 /* */ 380 /*************************************************************************/ 381 382 static FT_String* 383 cff_strcpy( FT_Memory memory, 384 const FT_String* source ) 385 { 386 FT_Error error; 387 FT_String* result; 388 389 390 (void)FT_STRDUP( result, source ); 391 392 FT_UNUSED( error ); 393 394 return result; 395 } 396 397 398 FT_LOCAL_DEF( FT_Error ) 399 cff_face_init( FT_Stream stream, 400 FT_Face cffface, /* CFF_Face */ 401 FT_Int face_index, 402 FT_Int num_params, 403 FT_Parameter* params ) 404 { 405 CFF_Face face = (CFF_Face)cffface; 406 FT_Error error; 407 SFNT_Service sfnt; 408 FT_Service_PsCMaps psnames; 409 PSHinter_Service pshinter; 410 FT_Bool pure_cff = 1; 411 FT_Bool sfnt_format = 0; 412 FT_Library library = cffface->driver->root.library; 413 414 415 #if 0 416 FT_FACE_FIND_GLOBAL_SERVICE( face, sfnt, SFNT ); 417 FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_NAMES ); 418 FT_FACE_FIND_GLOBAL_SERVICE( face, pshinter, POSTSCRIPT_HINTER ); 419 420 if ( !sfnt ) 421 goto Bad_Format; 422 #else 423 sfnt = (SFNT_Service)FT_Get_Module_Interface( 424 library, "sfnt" ); 425 if ( !sfnt ) 426 goto Bad_Format; 427 428 FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); 429 430 pshinter = (PSHinter_Service)FT_Get_Module_Interface( 431 library, "pshinter" ); 432 #endif 433 434 /* create input stream from resource */ 435 if ( FT_STREAM_SEEK( 0 ) ) 436 goto Exit; 437 438 /* check whether we have a valid OpenType file */ 439 error = sfnt->init_face( stream, face, face_index, num_params, params ); 440 if ( !error ) 441 { 442 if ( face->format_tag != TTAG_OTTO ) /* `OTTO'; OpenType/CFF font */ 443 { 444 FT_TRACE2(( "[not a valid OpenType/CFF font]\n" )); 445 goto Bad_Format; 446 } 447 448 /* if we are performing a simple font format check, exit immediately */ 449 if ( face_index < 0 ) 450 return CFF_Err_Ok; 451 452 /* UNDOCUMENTED! A CFF in an SFNT can have only a single font. */ 453 if ( face_index > 0 ) 454 { 455 FT_ERROR(( "cff_face_init: invalid face index\n" )); 456 error = CFF_Err_Invalid_Argument; 457 goto Exit; 458 } 459 460 sfnt_format = 1; 461 462 /* now, the font can be either an OpenType/CFF font, or an SVG CEF */ 463 /* font; in the latter case it doesn't have a `head' table */ 464 error = face->goto_table( face, TTAG_head, stream, 0 ); 465 if ( !error ) 466 { 467 pure_cff = 0; 468 469 /* load font directory */ 470 error = sfnt->load_face( stream, face, 0, num_params, params ); 471 if ( error ) 472 goto Exit; 473 } 474 else 475 { 476 /* load the `cmap' table explicitly */ 477 error = sfnt->load_cmap( face, stream ); 478 if ( error ) 479 goto Exit; 480 481 /* XXX: we don't load the GPOS table, as OpenType Layout */ 482 /* support will be added later to a layout library on top of */ 483 /* FreeType 2 */ 484 } 485 486 /* now load the CFF part of the file */ 487 error = face->goto_table( face, TTAG_CFF, stream, 0 ); 488 if ( error ) 489 goto Exit; 490 } 491 else 492 { 493 /* rewind to start of file; we are going to load a pure-CFF font */ 494 if ( FT_STREAM_SEEK( 0 ) ) 495 goto Exit; 496 error = CFF_Err_Ok; 497 } 498 499 /* now load and parse the CFF table in the file */ 500 { 501 CFF_Font cff; 502 CFF_FontRecDict dict; 503 FT_Memory memory = cffface->memory; 504 FT_Int32 flags; 505 FT_UInt i; 506 507 508 if ( FT_NEW( cff ) ) 509 goto Exit; 510 511 face->extra.data = cff; 512 error = cff_font_load( library, stream, face_index, cff, pure_cff ); 513 if ( error ) 514 goto Exit; 515 516 cff->pshinter = pshinter; 517 cff->psnames = (void*)psnames; 518 519 cffface->face_index = face_index; 520 521 /* Complement the root flags with some interesting information. */ 522 /* Note that this is only necessary for pure CFF and CEF fonts; */ 523 /* SFNT based fonts use the `name' table instead. */ 524 525 cffface->num_glyphs = cff->num_glyphs; 526 527 dict = &cff->top_font.font_dict; 528 529 /* we need the `PSNames' module for CFF and CEF formats */ 530 /* which aren't CID-keyed */ 531 if ( dict->cid_registry == 0xFFFFU && !psnames ) 532 { 533 FT_ERROR(( "cff_face_init:" 534 " cannot open CFF & CEF fonts\n" 535 " " 536 " without the `PSNames' module\n" )); 537 goto Bad_Format; 538 } 539 540 if ( !dict->units_per_em ) 541 dict->units_per_em = pure_cff ? 1000 : face->root.units_per_EM; 542 543 /* Normalize the font matrix so that `matrix->xx' is 1; the */ 544 /* scaling is done with `units_per_em' then (at this point, */ 545 /* it already contains the scaling factor, but without */ 546 /* normalization of the matrix). */ 547 /* */ 548 /* Note that the offsets must be expressed in integer font */ 549 /* units. */ 550 551 { 552 FT_Matrix* matrix = &dict->font_matrix; 553 FT_Vector* offset = &dict->font_offset; 554 FT_ULong* upm = &dict->units_per_em; 555 FT_Fixed temp = FT_ABS( matrix->yy ); 556 557 558 if ( temp != 0x10000L ) 559 { 560 *upm = FT_DivFix( *upm, temp ); 561 562 matrix->xx = FT_DivFix( matrix->xx, temp ); 563 matrix->yx = FT_DivFix( matrix->yx, temp ); 564 matrix->xy = FT_DivFix( matrix->xy, temp ); 565 matrix->yy = FT_DivFix( matrix->yy, temp ); 566 offset->x = FT_DivFix( offset->x, temp ); 567 offset->y = FT_DivFix( offset->y, temp ); 568 } 569 570 offset->x >>= 16; 571 offset->y >>= 16; 572 } 573 574 for ( i = cff->num_subfonts; i > 0; i-- ) 575 { 576 CFF_FontRecDict sub = &cff->subfonts[i - 1]->font_dict; 577 CFF_FontRecDict top = &cff->top_font.font_dict; 578 579 FT_Matrix* matrix; 580 FT_Vector* offset; 581 FT_ULong* upm; 582 FT_Fixed temp; 583 584 585 if ( sub->units_per_em ) 586 { 587 FT_Long scaling; 588 589 590 if ( top->units_per_em > 1 && sub->units_per_em > 1 ) 591 scaling = FT_MIN( top->units_per_em, sub->units_per_em ); 592 else 593 scaling = 1; 594 595 FT_Matrix_Multiply_Scaled( &top->font_matrix, 596 &sub->font_matrix, 597 scaling ); 598 FT_Vector_Transform_Scaled( &sub->font_offset, 599 &top->font_matrix, 600 scaling ); 601 602 sub->units_per_em = FT_MulDiv( sub->units_per_em, 603 top->units_per_em, 604 scaling ); 605 } 606 else 607 { 608 sub->font_matrix = top->font_matrix; 609 sub->font_offset = top->font_offset; 610 611 sub->units_per_em = top->units_per_em; 612 } 613 614 matrix = &sub->font_matrix; 615 offset = &sub->font_offset; 616 upm = &sub->units_per_em; 617 temp = FT_ABS( matrix->yy ); 618 619 if ( temp != 0x10000L ) 620 { 621 *upm = FT_DivFix( *upm, temp ); 622 623 /* if *upm is larger than 100*1000 we divide by 1000 -- */ 624 /* this can happen if e.g. there is no top-font FontMatrix */ 625 /* and the subfont FontMatrix already contains the complete */ 626 /* scaling for the subfont (see section 5.11 of the PLRM) */ 627 628 /* 100 is a heuristic value */ 629 630 if ( *upm > 100L * 1000L ) 631 *upm = ( *upm + 500 ) / 1000; 632 633 matrix->xx = FT_DivFix( matrix->xx, temp ); 634 matrix->yx = FT_DivFix( matrix->yx, temp ); 635 matrix->xy = FT_DivFix( matrix->xy, temp ); 636 matrix->yy = FT_DivFix( matrix->yy, temp ); 637 offset->x = FT_DivFix( offset->x, temp ); 638 offset->y = FT_DivFix( offset->y, temp ); 639 } 640 641 offset->x >>= 16; 642 offset->y >>= 16; 643 } 644 645 if ( pure_cff ) 646 { 647 char* style_name = NULL; 648 649 650 /* set up num_faces */ 651 cffface->num_faces = cff->num_faces; 652 653 /* compute number of glyphs */ 654 if ( dict->cid_registry != 0xFFFFU ) 655 cffface->num_glyphs = cff->charset.max_cid; 656 else 657 cffface->num_glyphs = cff->charstrings_index.count; 658 659 /* set global bbox, as well as EM size */ 660 cffface->bbox.xMin = dict->font_bbox.xMin >> 16; 661 cffface->bbox.yMin = dict->font_bbox.yMin >> 16; 662 /* no `U' suffix here to 0xFFFF! */ 663 cffface->bbox.xMax = ( dict->font_bbox.xMax + 0xFFFF ) >> 16; 664 cffface->bbox.yMax = ( dict->font_bbox.yMax + 0xFFFF ) >> 16; 665 666 cffface->units_per_EM = (FT_UShort)( dict->units_per_em ); 667 668 cffface->ascender = (FT_Short)( cffface->bbox.yMax ); 669 cffface->descender = (FT_Short)( cffface->bbox.yMin ); 670 671 cffface->height = (FT_Short)( ( cffface->units_per_EM * 12 ) / 10 ); 672 if ( cffface->height < cffface->ascender - cffface->descender ) 673 cffface->height = (FT_Short)( cffface->ascender - cffface->descender ); 674 675 cffface->underline_position = 676 (FT_Short)( dict->underline_position >> 16 ); 677 cffface->underline_thickness = 678 (FT_Short)( dict->underline_thickness >> 16 ); 679 680 /* retrieve font family & style name */ 681 cffface->family_name = cff_index_get_name( &cff->name_index, 682 face_index ); 683 684 if ( cffface->family_name ) 685 { 686 char* full = cff_index_get_sid_string( &cff->string_index, 687 dict->full_name, 688 psnames ); 689 char* fullp = full; 690 char* family = cffface->family_name; 691 char* family_name = 0; 692 693 694 if ( dict->family_name ) 695 { 696 family_name = cff_index_get_sid_string( &cff->string_index, 697 dict->family_name, 698 psnames); 699 if ( family_name ) 700 family = family_name; 701 } 702 703 /* We try to extract the style name from the full name. */ 704 /* We need to ignore spaces and dashes during the search. */ 705 if ( full && family ) 706 { 707 while ( *fullp ) 708 { 709 /* skip common characters at the start of both strings */ 710 if ( *fullp == *family ) 711 { 712 family++; 713 fullp++; 714 continue; 715 } 716 717 /* ignore spaces and dashes in full name during comparison */ 718 if ( *fullp == ' ' || *fullp == '-' ) 719 { 720 fullp++; 721 continue; 722 } 723 724 /* ignore spaces and dashes in family name during comparison */ 725 if ( *family == ' ' || *family == '-' ) 726 { 727 family++; 728 continue; 729 } 730 731 if ( !*family && *fullp ) 732 { 733 /* The full name begins with the same characters as the */ 734 /* family name, with spaces and dashes removed. In this */ 735 /* case, the remaining string in `fullp' will be used as */ 736 /* the style name. */ 737 style_name = cff_strcpy( memory, fullp ); 738 } 739 break; 740 } 741 742 if ( family_name ) 743 FT_FREE( family_name ); 744 FT_FREE( full ); 745 } 746 } 747 else 748 { 749 char *cid_font_name = 750 cff_index_get_sid_string( &cff->string_index, 751 dict->cid_font_name, 752 psnames ); 753 754 755 /* do we have a `/FontName' for a CID-keyed font? */ 756 if ( cid_font_name ) 757 cffface->family_name = cid_font_name; 758 } 759 760 if ( style_name ) 761 cffface->style_name = style_name; 762 else 763 /* assume "Regular" style if we don't know better */ 764 cffface->style_name = cff_strcpy( memory, (char *)"Regular" ); 765 766 /*******************************************************************/ 767 /* */ 768 /* Compute face flags. */ 769 /* */ 770 flags = (FT_UInt32)( FT_FACE_FLAG_SCALABLE | /* scalable outlines */ 771 FT_FACE_FLAG_HORIZONTAL | /* horizontal data */ 772 FT_FACE_FLAG_HINTER ); /* has native hinter */ 773 774 if ( sfnt_format ) 775 flags |= (FT_UInt32)FT_FACE_FLAG_SFNT; 776 777 /* fixed width font? */ 778 if ( dict->is_fixed_pitch ) 779 flags |= (FT_UInt32)FT_FACE_FLAG_FIXED_WIDTH; 780 781 /* XXX: WE DO NOT SUPPORT KERNING METRICS IN THE GPOS TABLE FOR NOW */ 782 #if 0 783 /* kerning available? */ 784 if ( face->kern_pairs ) 785 flags |= (FT_UInt32)FT_FACE_FLAG_KERNING; 786 #endif 787 788 cffface->face_flags = flags; 789 790 /*******************************************************************/ 791 /* */ 792 /* Compute style flags. */ 793 /* */ 794 flags = 0; 795 796 if ( dict->italic_angle ) 797 flags |= FT_STYLE_FLAG_ITALIC; 798 799 { 800 char *weight = cff_index_get_sid_string( &cff->string_index, 801 dict->weight, 802 psnames ); 803 804 805 if ( weight ) 806 if ( !ft_strcmp( weight, "Bold" ) || 807 !ft_strcmp( weight, "Black" ) ) 808 flags |= FT_STYLE_FLAG_BOLD; 809 FT_FREE( weight ); 810 } 811 812 /* double check */ 813 if ( !(flags & FT_STYLE_FLAG_BOLD) && cffface->style_name ) 814 if ( !ft_strncmp( cffface->style_name, "Bold", 4 ) || 815 !ft_strncmp( cffface->style_name, "Black", 5 ) ) 816 flags |= FT_STYLE_FLAG_BOLD; 817 818 cffface->style_flags = flags; 819 } 820 821 822 #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES 823 /* CID-keyed CFF fonts don't have glyph names -- the SFNT loader */ 824 /* has unset this flag because of the 3.0 `post' table. */ 825 if ( dict->cid_registry == 0xFFFFU ) 826 cffface->face_flags |= FT_FACE_FLAG_GLYPH_NAMES; 827 #endif 828 829 if ( dict->cid_registry != 0xFFFFU && pure_cff ) 830 cffface->face_flags |= FT_FACE_FLAG_CID_KEYED; 831 832 833 /*******************************************************************/ 834 /* */ 835 /* Compute char maps. */ 836 /* */ 837 838 /* Try to synthesize a Unicode charmap if there is none available */ 839 /* already. If an OpenType font contains a Unicode "cmap", we */ 840 /* will use it, whatever be in the CFF part of the file. */ 841 { 842 FT_CharMapRec cmaprec; 843 FT_CharMap cmap; 844 FT_UInt nn; 845 CFF_Encoding encoding = &cff->encoding; 846 847 848 for ( nn = 0; nn < (FT_UInt)cffface->num_charmaps; nn++ ) 849 { 850 cmap = cffface->charmaps[nn]; 851 852 /* Windows Unicode (3,1)? */ 853 if ( cmap->platform_id == 3 && cmap->encoding_id == 1 ) 854 goto Skip_Unicode; 855 856 /* Deprecated Unicode platform id? */ 857 if ( cmap->platform_id == 0 ) 858 goto Skip_Unicode; /* Standard Unicode (deprecated) */ 859 } 860 861 /* since CID-keyed fonts don't contain glyph names, we can't */ 862 /* construct a cmap */ 863 if ( pure_cff && cff->top_font.font_dict.cid_registry != 0xFFFFU ) 864 goto Exit; 865 866 /* we didn't find a Unicode charmap -- synthesize one */ 867 cmaprec.face = cffface; 868 cmaprec.platform_id = 3; 869 cmaprec.encoding_id = 1; 870 cmaprec.encoding = FT_ENCODING_UNICODE; 871 872 nn = (FT_UInt)cffface->num_charmaps; 873 874 FT_CMap_New( &FT_CFF_CMAP_UNICODE_CLASS_REC_GET, NULL, &cmaprec, NULL ); 875 876 /* if no Unicode charmap was previously selected, select this one */ 877 if ( cffface->charmap == NULL && nn != (FT_UInt)cffface->num_charmaps ) 878 cffface->charmap = cffface->charmaps[nn]; 879 880 Skip_Unicode: 881 if ( encoding->count > 0 ) 882 { 883 FT_CMap_Class clazz; 884 885 886 cmaprec.face = cffface; 887 cmaprec.platform_id = 7; /* Adobe platform id */ 888 889 if ( encoding->offset == 0 ) 890 { 891 cmaprec.encoding_id = TT_ADOBE_ID_STANDARD; 892 cmaprec.encoding = FT_ENCODING_ADOBE_STANDARD; 893 clazz = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET; 894 } 895 else if ( encoding->offset == 1 ) 896 { 897 cmaprec.encoding_id = TT_ADOBE_ID_EXPERT; 898 cmaprec.encoding = FT_ENCODING_ADOBE_EXPERT; 899 clazz = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET; 900 } 901 else 902 { 903 cmaprec.encoding_id = TT_ADOBE_ID_CUSTOM; 904 cmaprec.encoding = FT_ENCODING_ADOBE_CUSTOM; 905 clazz = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET; 906 } 907 908 FT_CMap_New( clazz, NULL, &cmaprec, NULL ); 909 } 910 } 911 } 912 913 Exit: 914 return error; 915 916 Bad_Format: 917 error = CFF_Err_Unknown_File_Format; 918 goto Exit; 919 } 920 921 922 FT_LOCAL_DEF( void ) 923 cff_face_done( FT_Face cffface ) /* CFF_Face */ 924 { 925 CFF_Face face = (CFF_Face)cffface; 926 FT_Memory memory; 927 SFNT_Service sfnt; 928 929 930 if ( !face ) 931 return; 932 933 memory = cffface->memory; 934 sfnt = (SFNT_Service)face->sfnt; 935 936 if ( sfnt ) 937 sfnt->done_face( face ); 938 939 { 940 CFF_Font cff = (CFF_Font)face->extra.data; 941 942 943 if ( cff ) 944 { 945 cff_font_done( cff ); 946 FT_FREE( face->extra.data ); 947 } 948 } 949 } 950 951 952 FT_LOCAL_DEF( FT_Error ) 953 cff_driver_init( FT_Module module ) 954 { 955 FT_UNUSED( module ); 956 957 return CFF_Err_Ok; 958 } 959 960 961 FT_LOCAL_DEF( void ) 962 cff_driver_done( FT_Module module ) 963 { 964 FT_UNUSED( module ); 965 } 966 967 968 /* END */ 969