1 /**************************************************************************** 2 * 3 * t1objs.c 4 * 5 * Type 1 objects manager (body). 6 * 7 * Copyright (C) 1996-2021 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 <freetype/internal/ftcalc.h> 20 #include <freetype/internal/ftdebug.h> 21 #include <freetype/internal/ftstream.h> 22 #include <freetype/ttnameid.h> 23 #include <freetype/ftdriver.h> 24 25 #include "t1gload.h" 26 #include "t1load.h" 27 28 #include "t1errors.h" 29 30 #ifndef T1_CONFIG_OPTION_NO_AFM 31 #include "t1afm.h" 32 #endif 33 34 #include <freetype/internal/services/svpscmap.h> 35 #include <freetype/internal/psaux.h> 36 37 38 /************************************************************************** 39 * 40 * The macro FT_COMPONENT is used in trace mode. It is an implicit 41 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log 42 * messages during execution. 43 */ 44 #undef FT_COMPONENT 45 #define FT_COMPONENT t1objs 46 47 48 /************************************************************************** 49 * 50 * SIZE FUNCTIONS 51 * 52 */ 53 54 55 static PSH_Globals_Funcs T1_Size_Get_Globals_Funcs(T1_Size size)56 T1_Size_Get_Globals_Funcs( T1_Size size ) 57 { 58 T1_Face face = (T1_Face)size->root.face; 59 PSHinter_Service pshinter = (PSHinter_Service)face->pshinter; 60 FT_Module module; 61 62 63 module = FT_Get_Module( size->root.face->driver->root.library, 64 "pshinter" ); 65 return ( module && pshinter && pshinter->get_globals_funcs ) 66 ? pshinter->get_globals_funcs( module ) 67 : 0; 68 } 69 70 71 FT_LOCAL_DEF( void ) T1_Size_Done(FT_Size t1size)72 T1_Size_Done( FT_Size t1size ) /* T1_Size */ 73 { 74 T1_Size size = (T1_Size)t1size; 75 76 77 if ( t1size->internal->module_data ) 78 { 79 PSH_Globals_Funcs funcs; 80 81 82 funcs = T1_Size_Get_Globals_Funcs( size ); 83 if ( funcs ) 84 funcs->destroy( (PSH_Globals)t1size->internal->module_data ); 85 86 t1size->internal->module_data = NULL; 87 } 88 } 89 90 91 FT_LOCAL_DEF( FT_Error ) T1_Size_Init(FT_Size t1size)92 T1_Size_Init( FT_Size t1size ) /* T1_Size */ 93 { 94 T1_Size size = (T1_Size)t1size; 95 FT_Error error = FT_Err_Ok; 96 PSH_Globals_Funcs funcs = T1_Size_Get_Globals_Funcs( size ); 97 98 99 if ( funcs ) 100 { 101 PSH_Globals globals; 102 T1_Face face = (T1_Face)size->root.face; 103 104 105 error = funcs->create( size->root.face->memory, 106 &face->type1.private_dict, &globals ); 107 if ( !error ) 108 t1size->internal->module_data = globals; 109 } 110 111 return error; 112 } 113 114 115 FT_LOCAL_DEF( FT_Error ) T1_Size_Request(FT_Size t1size,FT_Size_Request req)116 T1_Size_Request( FT_Size t1size, /* T1_Size */ 117 FT_Size_Request req ) 118 { 119 FT_Error error; 120 121 T1_Size size = (T1_Size)t1size; 122 PSH_Globals_Funcs funcs = T1_Size_Get_Globals_Funcs( size ); 123 124 125 error = FT_Request_Metrics( size->root.face, req ); 126 if ( error ) 127 goto Exit; 128 129 if ( funcs ) 130 funcs->set_scale( (PSH_Globals)t1size->internal->module_data, 131 size->root.metrics.x_scale, 132 size->root.metrics.y_scale, 133 0, 0 ); 134 135 Exit: 136 return error; 137 } 138 139 140 /************************************************************************** 141 * 142 * SLOT FUNCTIONS 143 * 144 */ 145 146 FT_LOCAL_DEF( void ) T1_GlyphSlot_Done(FT_GlyphSlot slot)147 T1_GlyphSlot_Done( FT_GlyphSlot slot ) 148 { 149 slot->internal->glyph_hints = NULL; 150 } 151 152 153 FT_LOCAL_DEF( FT_Error ) T1_GlyphSlot_Init(FT_GlyphSlot slot)154 T1_GlyphSlot_Init( FT_GlyphSlot slot ) 155 { 156 T1_Face face; 157 PSHinter_Service pshinter; 158 159 160 face = (T1_Face)slot->face; 161 pshinter = (PSHinter_Service)face->pshinter; 162 163 if ( pshinter ) 164 { 165 FT_Module module; 166 167 168 module = FT_Get_Module( slot->face->driver->root.library, 169 "pshinter" ); 170 if ( module ) 171 { 172 T1_Hints_Funcs funcs; 173 174 175 funcs = pshinter->get_t1_funcs( module ); 176 slot->internal->glyph_hints = (void*)funcs; 177 } 178 } 179 180 return 0; 181 } 182 183 184 /************************************************************************** 185 * 186 * FACE FUNCTIONS 187 * 188 */ 189 190 191 /************************************************************************** 192 * 193 * @Function: 194 * T1_Face_Done 195 * 196 * @Description: 197 * The face object destructor. 198 * 199 * @Input: 200 * face :: 201 * A typeless pointer to the face object to destroy. 202 */ 203 FT_LOCAL_DEF( void ) T1_Face_Done(FT_Face t1face)204 T1_Face_Done( FT_Face t1face ) /* T1_Face */ 205 { 206 T1_Face face = (T1_Face)t1face; 207 FT_Memory memory; 208 T1_Font type1; 209 210 211 if ( !face ) 212 return; 213 214 memory = face->root.memory; 215 type1 = &face->type1; 216 217 #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT 218 /* release multiple masters information */ 219 FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) ); 220 221 if ( face->buildchar ) 222 { 223 FT_FREE( face->buildchar ); 224 225 face->len_buildchar = 0; 226 } 227 228 T1_Done_Blend( face ); 229 face->blend = NULL; 230 #endif 231 232 /* release font info strings */ 233 { 234 PS_FontInfo info = &type1->font_info; 235 236 237 FT_FREE( info->version ); 238 FT_FREE( info->notice ); 239 FT_FREE( info->full_name ); 240 FT_FREE( info->family_name ); 241 FT_FREE( info->weight ); 242 } 243 244 /* release top dictionary */ 245 FT_FREE( type1->charstrings_len ); 246 FT_FREE( type1->charstrings ); 247 FT_FREE( type1->glyph_names ); 248 249 FT_FREE( type1->subrs ); 250 FT_FREE( type1->subrs_len ); 251 252 ft_hash_num_free( type1->subrs_hash, memory ); 253 FT_FREE( type1->subrs_hash ); 254 255 FT_FREE( type1->subrs_block ); 256 FT_FREE( type1->charstrings_block ); 257 FT_FREE( type1->glyph_names_block ); 258 259 FT_FREE( type1->encoding.char_index ); 260 FT_FREE( type1->encoding.char_name ); 261 FT_FREE( type1->font_name ); 262 263 #ifndef T1_CONFIG_OPTION_NO_AFM 264 /* release afm data if present */ 265 if ( face->afm_data ) 266 T1_Done_Metrics( memory, (AFM_FontInfo)face->afm_data ); 267 #endif 268 269 /* release unicode map, if any */ 270 #if 0 271 FT_FREE( face->unicode_map_rec.maps ); 272 face->unicode_map_rec.num_maps = 0; 273 face->unicode_map = NULL; 274 #endif 275 276 face->root.family_name = NULL; 277 face->root.style_name = NULL; 278 } 279 280 281 /************************************************************************** 282 * 283 * @Function: 284 * T1_Face_Init 285 * 286 * @Description: 287 * The face object constructor. 288 * 289 * @Input: 290 * stream :: 291 * input stream where to load font data. 292 * 293 * face_index :: 294 * The index of the font face in the resource. 295 * 296 * num_params :: 297 * Number of additional generic parameters. Ignored. 298 * 299 * params :: 300 * Additional generic parameters. Ignored. 301 * 302 * @InOut: 303 * face :: 304 * The face record to build. 305 * 306 * @Return: 307 * FreeType error code. 0 means success. 308 */ 309 FT_LOCAL_DEF( FT_Error ) T1_Face_Init(FT_Stream stream,FT_Face t1face,FT_Int face_index,FT_Int num_params,FT_Parameter * params)310 T1_Face_Init( FT_Stream stream, 311 FT_Face t1face, /* T1_Face */ 312 FT_Int face_index, 313 FT_Int num_params, 314 FT_Parameter* params ) 315 { 316 T1_Face face = (T1_Face)t1face; 317 FT_Error error; 318 FT_Service_PsCMaps psnames; 319 PSAux_Service psaux; 320 T1_Font type1 = &face->type1; 321 PS_FontInfo info = &type1->font_info; 322 323 FT_UNUSED( num_params ); 324 FT_UNUSED( params ); 325 FT_UNUSED( stream ); 326 327 328 face->root.num_faces = 1; 329 330 FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); 331 face->psnames = psnames; 332 333 face->psaux = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), 334 "psaux" ); 335 psaux = (PSAux_Service)face->psaux; 336 if ( !psaux ) 337 { 338 FT_ERROR(( "T1_Face_Init: cannot access `psaux' module\n" )); 339 error = FT_THROW( Missing_Module ); 340 goto Exit; 341 } 342 343 face->pshinter = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), 344 "pshinter" ); 345 346 FT_TRACE2(( "Type 1 driver\n" )); 347 348 /* open the tokenizer; this will also check the font format */ 349 error = T1_Open_Face( face ); 350 if ( error ) 351 goto Exit; 352 353 FT_TRACE2(( "T1_Face_Init: %p (index %d)\n", 354 (void *)face, 355 face_index )); 356 357 /* if we just wanted to check the format, leave successfully now */ 358 if ( face_index < 0 ) 359 goto Exit; 360 361 /* check the face index */ 362 if ( ( face_index & 0xFFFF ) > 0 ) 363 { 364 FT_ERROR(( "T1_Face_Init: invalid face index\n" )); 365 error = FT_THROW( Invalid_Argument ); 366 goto Exit; 367 } 368 369 /* now load the font program into the face object */ 370 371 /* initialize the face object fields */ 372 373 /* set up root face fields */ 374 { 375 FT_Face root = (FT_Face)&face->root; 376 377 378 root->num_glyphs = type1->num_glyphs; 379 root->face_index = 0; 380 381 root->face_flags |= FT_FACE_FLAG_SCALABLE | 382 FT_FACE_FLAG_HORIZONTAL | 383 FT_FACE_FLAG_GLYPH_NAMES | 384 FT_FACE_FLAG_HINTER; 385 386 if ( info->is_fixed_pitch ) 387 root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; 388 389 if ( face->blend ) 390 root->face_flags |= FT_FACE_FLAG_MULTIPLE_MASTERS; 391 392 /* The following code to extract the family and the style is very */ 393 /* simplistic and might get some things wrong. For a full-featured */ 394 /* algorithm you might have a look at the whitepaper given at */ 395 /* */ 396 /* https://blogs.msdn.com/text/archive/2007/04/23/wpf-font-selection-model.aspx */ 397 398 /* get style name -- be careful, some broken fonts only */ 399 /* have a `/FontName' dictionary entry! */ 400 root->family_name = info->family_name; 401 root->style_name = NULL; 402 403 if ( root->family_name ) 404 { 405 char* full = info->full_name; 406 char* family = root->family_name; 407 408 409 if ( full ) 410 { 411 FT_Bool the_same = TRUE; 412 413 414 while ( *full ) 415 { 416 if ( *full == *family ) 417 { 418 family++; 419 full++; 420 } 421 else 422 { 423 if ( *full == ' ' || *full == '-' ) 424 full++; 425 else if ( *family == ' ' || *family == '-' ) 426 family++; 427 else 428 { 429 the_same = FALSE; 430 431 if ( !*family ) 432 root->style_name = full; 433 break; 434 } 435 } 436 } 437 438 if ( the_same ) 439 root->style_name = (char *)"Regular"; 440 } 441 } 442 else 443 { 444 /* do we have a `/FontName'? */ 445 if ( type1->font_name ) 446 root->family_name = type1->font_name; 447 } 448 449 if ( !root->style_name ) 450 { 451 if ( info->weight ) 452 root->style_name = info->weight; 453 else 454 /* assume `Regular' style because we don't know better */ 455 root->style_name = (char *)"Regular"; 456 } 457 458 /* compute style flags */ 459 root->style_flags = 0; 460 if ( info->italic_angle ) 461 root->style_flags |= FT_STYLE_FLAG_ITALIC; 462 if ( info->weight ) 463 { 464 if ( !ft_strcmp( info->weight, "Bold" ) || 465 !ft_strcmp( info->weight, "Black" ) ) 466 root->style_flags |= FT_STYLE_FLAG_BOLD; 467 } 468 469 /* no embedded bitmap support */ 470 root->num_fixed_sizes = 0; 471 root->available_sizes = NULL; 472 473 root->bbox.xMin = type1->font_bbox.xMin >> 16; 474 root->bbox.yMin = type1->font_bbox.yMin >> 16; 475 /* no `U' suffix here to 0xFFFF! */ 476 root->bbox.xMax = ( type1->font_bbox.xMax + 0xFFFF ) >> 16; 477 root->bbox.yMax = ( type1->font_bbox.yMax + 0xFFFF ) >> 16; 478 479 /* Set units_per_EM if we didn't set it in t1_parse_font_matrix. */ 480 if ( !root->units_per_EM ) 481 root->units_per_EM = 1000; 482 483 root->ascender = (FT_Short)( root->bbox.yMax ); 484 root->descender = (FT_Short)( root->bbox.yMin ); 485 486 root->height = (FT_Short)( ( root->units_per_EM * 12 ) / 10 ); 487 if ( root->height < root->ascender - root->descender ) 488 root->height = (FT_Short)( root->ascender - root->descender ); 489 490 /* now compute the maximum advance width */ 491 root->max_advance_width = 492 (FT_Short)( root->bbox.xMax ); 493 { 494 FT_Pos max_advance; 495 496 497 error = T1_Compute_Max_Advance( face, &max_advance ); 498 499 /* in case of error, keep the standard width */ 500 if ( !error ) 501 root->max_advance_width = (FT_Short)FIXED_TO_INT( max_advance ); 502 else 503 error = FT_Err_Ok; /* clear error */ 504 } 505 506 root->max_advance_height = root->height; 507 508 root->underline_position = (FT_Short)info->underline_position; 509 root->underline_thickness = (FT_Short)info->underline_thickness; 510 } 511 512 { 513 FT_Face root = &face->root; 514 515 516 if ( psnames ) 517 { 518 FT_CharMapRec charmap; 519 T1_CMap_Classes cmap_classes = psaux->t1_cmap_classes; 520 FT_CMap_Class clazz; 521 522 523 charmap.face = root; 524 525 /* first of all, try to synthesize a Unicode charmap */ 526 charmap.platform_id = TT_PLATFORM_MICROSOFT; 527 charmap.encoding_id = TT_MS_ID_UNICODE_CS; 528 charmap.encoding = FT_ENCODING_UNICODE; 529 530 error = FT_CMap_New( cmap_classes->unicode, NULL, &charmap, NULL ); 531 if ( error && 532 FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) && 533 FT_ERR_NEQ( error, Unimplemented_Feature ) ) 534 goto Exit; 535 error = FT_Err_Ok; 536 537 /* now, generate an Adobe Standard encoding when appropriate */ 538 charmap.platform_id = TT_PLATFORM_ADOBE; 539 clazz = NULL; 540 541 switch ( type1->encoding_type ) 542 { 543 case T1_ENCODING_TYPE_STANDARD: 544 charmap.encoding = FT_ENCODING_ADOBE_STANDARD; 545 charmap.encoding_id = TT_ADOBE_ID_STANDARD; 546 clazz = cmap_classes->standard; 547 break; 548 549 case T1_ENCODING_TYPE_EXPERT: 550 charmap.encoding = FT_ENCODING_ADOBE_EXPERT; 551 charmap.encoding_id = TT_ADOBE_ID_EXPERT; 552 clazz = cmap_classes->expert; 553 break; 554 555 case T1_ENCODING_TYPE_ARRAY: 556 charmap.encoding = FT_ENCODING_ADOBE_CUSTOM; 557 charmap.encoding_id = TT_ADOBE_ID_CUSTOM; 558 clazz = cmap_classes->custom; 559 break; 560 561 case T1_ENCODING_TYPE_ISOLATIN1: 562 charmap.encoding = FT_ENCODING_ADOBE_LATIN_1; 563 charmap.encoding_id = TT_ADOBE_ID_LATIN_1; 564 clazz = cmap_classes->unicode; 565 break; 566 567 default: 568 ; 569 } 570 571 if ( clazz ) 572 error = FT_CMap_New( clazz, NULL, &charmap, NULL ); 573 } 574 } 575 576 Exit: 577 return error; 578 } 579 580 581 /************************************************************************** 582 * 583 * @Function: 584 * T1_Driver_Init 585 * 586 * @Description: 587 * Initializes a given Type 1 driver object. 588 * 589 * @Input: 590 * driver :: 591 * A handle to the target driver object. 592 * 593 * @Return: 594 * FreeType error code. 0 means success. 595 */ 596 FT_LOCAL_DEF( FT_Error ) T1_Driver_Init(FT_Module module)597 T1_Driver_Init( FT_Module module ) 598 { 599 PS_Driver driver = (PS_Driver)module; 600 601 FT_UInt32 seed; 602 603 604 /* set default property values, cf. `ftt1drv.h' */ 605 driver->hinting_engine = FT_HINTING_ADOBE; 606 607 driver->no_stem_darkening = TRUE; 608 609 driver->darken_params[0] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1; 610 driver->darken_params[1] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1; 611 driver->darken_params[2] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2; 612 driver->darken_params[3] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2; 613 driver->darken_params[4] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3; 614 driver->darken_params[5] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3; 615 driver->darken_params[6] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4; 616 driver->darken_params[7] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4; 617 618 /* compute random seed from some memory addresses */ 619 seed = (FT_UInt32)( (FT_Offset)(char*)&seed ^ 620 (FT_Offset)(char*)&module ^ 621 (FT_Offset)(char*)module->memory ); 622 seed = seed ^ ( seed >> 10 ) ^ ( seed >> 20 ); 623 624 driver->random_seed = (FT_Int32)seed; 625 if ( driver->random_seed < 0 ) 626 driver->random_seed = -driver->random_seed; 627 else if ( driver->random_seed == 0 ) 628 driver->random_seed = 123456789; 629 630 return FT_Err_Ok; 631 } 632 633 634 /************************************************************************** 635 * 636 * @Function: 637 * T1_Driver_Done 638 * 639 * @Description: 640 * Finalizes a given Type 1 driver. 641 * 642 * @Input: 643 * driver :: 644 * A handle to the target Type 1 driver. 645 */ 646 FT_LOCAL_DEF( void ) T1_Driver_Done(FT_Module driver)647 T1_Driver_Done( FT_Module driver ) 648 { 649 FT_UNUSED( driver ); 650 } 651 652 653 /* END */ 654