1 /***************************************************************************/ 2 /* */ 3 /* t1driver.c */ 4 /* */ 5 /* Type 1 driver interface (body). */ 6 /* */ 7 /* Copyright 1996-2016 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 "t1driver.h" 21 #include "t1gload.h" 22 #include "t1load.h" 23 24 #include "t1errors.h" 25 26 #ifndef T1_CONFIG_OPTION_NO_AFM 27 #include "t1afm.h" 28 #endif 29 30 #include FT_INTERNAL_DEBUG_H 31 #include FT_INTERNAL_STREAM_H 32 #include FT_INTERNAL_HASH_H 33 34 #include FT_SERVICE_MULTIPLE_MASTERS_H 35 #include FT_SERVICE_GLYPH_DICT_H 36 #include FT_SERVICE_FONT_FORMAT_H 37 #include FT_SERVICE_POSTSCRIPT_NAME_H 38 #include FT_SERVICE_POSTSCRIPT_CMAPS_H 39 #include FT_SERVICE_POSTSCRIPT_INFO_H 40 #include FT_SERVICE_KERNING_H 41 42 43 /*************************************************************************/ 44 /* */ 45 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 46 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 47 /* messages during execution. */ 48 /* */ 49 #undef FT_COMPONENT 50 #define FT_COMPONENT trace_t1driver 51 52 /* 53 * GLYPH DICT SERVICE 54 * 55 */ 56 57 static FT_Error t1_get_glyph_name(T1_Face face,FT_UInt glyph_index,FT_Pointer buffer,FT_UInt buffer_max)58 t1_get_glyph_name( T1_Face face, 59 FT_UInt glyph_index, 60 FT_Pointer buffer, 61 FT_UInt buffer_max ) 62 { 63 FT_STRCPYN( buffer, face->type1.glyph_names[glyph_index], buffer_max ); 64 65 return FT_Err_Ok; 66 } 67 68 69 static FT_UInt t1_get_name_index(T1_Face face,FT_String * glyph_name)70 t1_get_name_index( T1_Face face, 71 FT_String* glyph_name ) 72 { 73 FT_Int i; 74 75 76 for ( i = 0; i < face->type1.num_glyphs; i++ ) 77 { 78 FT_String* gname = face->type1.glyph_names[i]; 79 80 81 if ( !ft_strcmp( glyph_name, gname ) ) 82 return (FT_UInt)i; 83 } 84 85 return 0; 86 } 87 88 89 static const FT_Service_GlyphDictRec t1_service_glyph_dict = 90 { 91 (FT_GlyphDict_GetNameFunc) t1_get_glyph_name, /* get_name */ 92 (FT_GlyphDict_NameIndexFunc)t1_get_name_index /* name_index */ 93 }; 94 95 96 /* 97 * POSTSCRIPT NAME SERVICE 98 * 99 */ 100 101 static const char* t1_get_ps_name(T1_Face face)102 t1_get_ps_name( T1_Face face ) 103 { 104 return (const char*) face->type1.font_name; 105 } 106 107 108 static const FT_Service_PsFontNameRec t1_service_ps_name = 109 { 110 (FT_PsName_GetFunc)t1_get_ps_name /* get_ps_font_name */ 111 }; 112 113 114 /* 115 * MULTIPLE MASTERS SERVICE 116 * 117 */ 118 119 #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT 120 static const FT_Service_MultiMastersRec t1_service_multi_masters = 121 { 122 (FT_Get_MM_Func) T1_Get_Multi_Master, /* get_mm */ 123 (FT_Set_MM_Design_Func) T1_Set_MM_Design, /* set_mm_design */ 124 (FT_Set_MM_Blend_Func) T1_Set_MM_Blend, /* set_mm_blend */ 125 (FT_Get_MM_Blend_Func) T1_Get_MM_Blend, /* get_mm_blend */ 126 (FT_Get_MM_Var_Func) T1_Get_MM_Var, /* get_mm_var */ 127 (FT_Set_Var_Design_Func)T1_Set_Var_Design, /* set_var_design */ 128 (FT_Get_Var_Design_Func)T1_Get_Var_Design, /* get_var_design */ 129 130 (FT_Get_Var_Blend_Func) NULL, /* get_var_blend */ 131 (FT_Done_Blend_Func) T1_Done_Blend /* done_blend */ 132 }; 133 #endif 134 135 136 /* 137 * POSTSCRIPT INFO SERVICE 138 * 139 */ 140 141 static FT_Error t1_ps_get_font_info(FT_Face face,PS_FontInfoRec * afont_info)142 t1_ps_get_font_info( FT_Face face, 143 PS_FontInfoRec* afont_info ) 144 { 145 *afont_info = ((T1_Face)face)->type1.font_info; 146 147 return FT_Err_Ok; 148 } 149 150 151 static FT_Error t1_ps_get_font_extra(FT_Face face,PS_FontExtraRec * afont_extra)152 t1_ps_get_font_extra( FT_Face face, 153 PS_FontExtraRec* afont_extra ) 154 { 155 *afont_extra = ((T1_Face)face)->type1.font_extra; 156 157 return FT_Err_Ok; 158 } 159 160 161 static FT_Int t1_ps_has_glyph_names(FT_Face face)162 t1_ps_has_glyph_names( FT_Face face ) 163 { 164 FT_UNUSED( face ); 165 166 return 1; 167 } 168 169 170 static FT_Error t1_ps_get_font_private(FT_Face face,PS_PrivateRec * afont_private)171 t1_ps_get_font_private( FT_Face face, 172 PS_PrivateRec* afont_private ) 173 { 174 *afont_private = ((T1_Face)face)->type1.private_dict; 175 176 return FT_Err_Ok; 177 } 178 179 180 static FT_Long t1_ps_get_font_value(FT_Face face,PS_Dict_Keys key,FT_UInt idx,void * value,FT_Long value_len_)181 t1_ps_get_font_value( FT_Face face, 182 PS_Dict_Keys key, 183 FT_UInt idx, 184 void *value, 185 FT_Long value_len_ ) 186 { 187 FT_ULong retval = 0; /* always >= 1 if valid */ 188 FT_ULong value_len = value_len_ < 0 ? 0 : (FT_ULong)value_len_; 189 190 T1_Face t1face = (T1_Face)face; 191 T1_Font type1 = &t1face->type1; 192 193 194 switch ( key ) 195 { 196 case PS_DICT_FONT_TYPE: 197 retval = sizeof ( type1->font_type ); 198 if ( value && value_len >= retval ) 199 *((FT_Byte *)value) = type1->font_type; 200 break; 201 202 case PS_DICT_FONT_MATRIX: 203 if ( idx < sizeof ( type1->font_matrix ) / 204 sizeof ( type1->font_matrix.xx ) ) 205 { 206 FT_Fixed val = 0; 207 208 209 retval = sizeof ( val ); 210 if ( value && value_len >= retval ) 211 { 212 switch ( idx ) 213 { 214 case 0: 215 val = type1->font_matrix.xx; 216 break; 217 case 1: 218 val = type1->font_matrix.xy; 219 break; 220 case 2: 221 val = type1->font_matrix.yx; 222 break; 223 case 3: 224 val = type1->font_matrix.yy; 225 break; 226 } 227 *((FT_Fixed *)value) = val; 228 } 229 } 230 break; 231 232 case PS_DICT_FONT_BBOX: 233 if ( idx < sizeof ( type1->font_bbox ) / 234 sizeof ( type1->font_bbox.xMin ) ) 235 { 236 FT_Fixed val = 0; 237 238 239 retval = sizeof ( val ); 240 if ( value && value_len >= retval ) 241 { 242 switch ( idx ) 243 { 244 case 0: 245 val = type1->font_bbox.xMin; 246 break; 247 case 1: 248 val = type1->font_bbox.yMin; 249 break; 250 case 2: 251 val = type1->font_bbox.xMax; 252 break; 253 case 3: 254 val = type1->font_bbox.yMax; 255 break; 256 } 257 *((FT_Fixed *)value) = val; 258 } 259 } 260 break; 261 262 case PS_DICT_PAINT_TYPE: 263 retval = sizeof ( type1->paint_type ); 264 if ( value && value_len >= retval ) 265 *((FT_Byte *)value) = type1->paint_type; 266 break; 267 268 case PS_DICT_FONT_NAME: 269 retval = ft_strlen( type1->font_name ) + 1; 270 if ( value && value_len >= retval ) 271 ft_memcpy( value, (void *)( type1->font_name ), retval ); 272 break; 273 274 case PS_DICT_UNIQUE_ID: 275 retval = sizeof ( type1->private_dict.unique_id ); 276 if ( value && value_len >= retval ) 277 *((FT_Int *)value) = type1->private_dict.unique_id; 278 break; 279 280 case PS_DICT_NUM_CHAR_STRINGS: 281 retval = sizeof ( type1->num_glyphs ); 282 if ( value && value_len >= retval ) 283 *((FT_Int *)value) = type1->num_glyphs; 284 break; 285 286 case PS_DICT_CHAR_STRING_KEY: 287 if ( idx < (FT_UInt)type1->num_glyphs ) 288 { 289 retval = ft_strlen( type1->glyph_names[idx] ) + 1; 290 if ( value && value_len >= retval ) 291 { 292 ft_memcpy( value, (void *)( type1->glyph_names[idx] ), retval ); 293 ((FT_Char *)value)[retval - 1] = (FT_Char)'\0'; 294 } 295 } 296 break; 297 298 case PS_DICT_CHAR_STRING: 299 if ( idx < (FT_UInt)type1->num_glyphs ) 300 { 301 retval = type1->charstrings_len[idx] + 1; 302 if ( value && value_len >= retval ) 303 { 304 ft_memcpy( value, (void *)( type1->charstrings[idx] ), 305 retval - 1 ); 306 ((FT_Char *)value)[retval - 1] = (FT_Char)'\0'; 307 } 308 } 309 break; 310 311 case PS_DICT_ENCODING_TYPE: 312 retval = sizeof ( type1->encoding_type ); 313 if ( value && value_len >= retval ) 314 *((T1_EncodingType *)value) = type1->encoding_type; 315 break; 316 317 case PS_DICT_ENCODING_ENTRY: 318 if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY && 319 idx < (FT_UInt)type1->encoding.num_chars ) 320 { 321 retval = ft_strlen( type1->encoding.char_name[idx] ) + 1; 322 if ( value && value_len >= retval ) 323 { 324 ft_memcpy( value, (void *)( type1->encoding.char_name[idx] ), 325 retval - 1 ); 326 ((FT_Char *)value)[retval - 1] = (FT_Char)'\0'; 327 } 328 } 329 break; 330 331 case PS_DICT_NUM_SUBRS: 332 retval = sizeof ( type1->num_subrs ); 333 if ( value && value_len >= retval ) 334 *((FT_Int *)value) = type1->num_subrs; 335 break; 336 337 case PS_DICT_SUBR: 338 { 339 FT_Bool ok = 0; 340 341 342 if ( type1->subrs_hash ) 343 { 344 /* convert subr index to array index */ 345 size_t* val = ft_hash_num_lookup( (FT_Int)idx, 346 type1->subrs_hash ); 347 348 349 if ( val ) 350 { 351 idx = *val; 352 ok = 1; 353 } 354 } 355 else 356 { 357 if ( idx < (FT_UInt)type1->num_subrs ) 358 ok = 1; 359 } 360 361 if ( ok ) 362 { 363 retval = type1->subrs_len[idx] + 1; 364 if ( value && value_len >= retval ) 365 { 366 ft_memcpy( value, (void *)( type1->subrs[idx] ), retval - 1 ); 367 ((FT_Char *)value)[retval - 1] = (FT_Char)'\0'; 368 } 369 } 370 } 371 break; 372 373 case PS_DICT_STD_HW: 374 retval = sizeof ( type1->private_dict.standard_width[0] ); 375 if ( value && value_len >= retval ) 376 *((FT_UShort *)value) = type1->private_dict.standard_width[0]; 377 break; 378 379 case PS_DICT_STD_VW: 380 retval = sizeof ( type1->private_dict.standard_height[0] ); 381 if ( value && value_len >= retval ) 382 *((FT_UShort *)value) = type1->private_dict.standard_height[0]; 383 break; 384 385 case PS_DICT_NUM_BLUE_VALUES: 386 retval = sizeof ( type1->private_dict.num_blue_values ); 387 if ( value && value_len >= retval ) 388 *((FT_Byte *)value) = type1->private_dict.num_blue_values; 389 break; 390 391 case PS_DICT_BLUE_VALUE: 392 if ( idx < type1->private_dict.num_blue_values ) 393 { 394 retval = sizeof ( type1->private_dict.blue_values[idx] ); 395 if ( value && value_len >= retval ) 396 *((FT_Short *)value) = type1->private_dict.blue_values[idx]; 397 } 398 break; 399 400 case PS_DICT_BLUE_SCALE: 401 retval = sizeof ( type1->private_dict.blue_scale ); 402 if ( value && value_len >= retval ) 403 *((FT_Fixed *)value) = type1->private_dict.blue_scale; 404 break; 405 406 case PS_DICT_BLUE_FUZZ: 407 retval = sizeof ( type1->private_dict.blue_fuzz ); 408 if ( value && value_len >= retval ) 409 *((FT_Int *)value) = type1->private_dict.blue_fuzz; 410 break; 411 412 case PS_DICT_BLUE_SHIFT: 413 retval = sizeof ( type1->private_dict.blue_shift ); 414 if ( value && value_len >= retval ) 415 *((FT_Int *)value) = type1->private_dict.blue_shift; 416 break; 417 418 case PS_DICT_NUM_OTHER_BLUES: 419 retval = sizeof ( type1->private_dict.num_other_blues ); 420 if ( value && value_len >= retval ) 421 *((FT_Byte *)value) = type1->private_dict.num_other_blues; 422 break; 423 424 case PS_DICT_OTHER_BLUE: 425 if ( idx < type1->private_dict.num_other_blues ) 426 { 427 retval = sizeof ( type1->private_dict.other_blues[idx] ); 428 if ( value && value_len >= retval ) 429 *((FT_Short *)value) = type1->private_dict.other_blues[idx]; 430 } 431 break; 432 433 case PS_DICT_NUM_FAMILY_BLUES: 434 retval = sizeof ( type1->private_dict.num_family_blues ); 435 if ( value && value_len >= retval ) 436 *((FT_Byte *)value) = type1->private_dict.num_family_blues; 437 break; 438 439 case PS_DICT_FAMILY_BLUE: 440 if ( idx < type1->private_dict.num_family_blues ) 441 { 442 retval = sizeof ( type1->private_dict.family_blues[idx] ); 443 if ( value && value_len >= retval ) 444 *((FT_Short *)value) = type1->private_dict.family_blues[idx]; 445 } 446 break; 447 448 case PS_DICT_NUM_FAMILY_OTHER_BLUES: 449 retval = sizeof ( type1->private_dict.num_family_other_blues ); 450 if ( value && value_len >= retval ) 451 *((FT_Byte *)value) = type1->private_dict.num_family_other_blues; 452 break; 453 454 case PS_DICT_FAMILY_OTHER_BLUE: 455 if ( idx < type1->private_dict.num_family_other_blues ) 456 { 457 retval = sizeof ( type1->private_dict.family_other_blues[idx] ); 458 if ( value && value_len >= retval ) 459 *((FT_Short *)value) = type1->private_dict.family_other_blues[idx]; 460 } 461 break; 462 463 case PS_DICT_NUM_STEM_SNAP_H: 464 retval = sizeof ( type1->private_dict.num_snap_widths ); 465 if ( value && value_len >= retval ) 466 *((FT_Byte *)value) = type1->private_dict.num_snap_widths; 467 break; 468 469 case PS_DICT_STEM_SNAP_H: 470 if ( idx < type1->private_dict.num_snap_widths ) 471 { 472 retval = sizeof ( type1->private_dict.snap_widths[idx] ); 473 if ( value && value_len >= retval ) 474 *((FT_Short *)value) = type1->private_dict.snap_widths[idx]; 475 } 476 break; 477 478 case PS_DICT_NUM_STEM_SNAP_V: 479 retval = sizeof ( type1->private_dict.num_snap_heights ); 480 if ( value && value_len >= retval ) 481 *((FT_Byte *)value) = type1->private_dict.num_snap_heights; 482 break; 483 484 case PS_DICT_STEM_SNAP_V: 485 if ( idx < type1->private_dict.num_snap_heights ) 486 { 487 retval = sizeof ( type1->private_dict.snap_heights[idx] ); 488 if ( value && value_len >= retval ) 489 *((FT_Short *)value) = type1->private_dict.snap_heights[idx]; 490 } 491 break; 492 493 case PS_DICT_RND_STEM_UP: 494 retval = sizeof ( type1->private_dict.round_stem_up ); 495 if ( value && value_len >= retval ) 496 *((FT_Bool *)value) = type1->private_dict.round_stem_up; 497 break; 498 499 case PS_DICT_FORCE_BOLD: 500 retval = sizeof ( type1->private_dict.force_bold ); 501 if ( value && value_len >= retval ) 502 *((FT_Bool *)value) = type1->private_dict.force_bold; 503 break; 504 505 case PS_DICT_MIN_FEATURE: 506 if ( idx < sizeof ( type1->private_dict.min_feature ) / 507 sizeof ( type1->private_dict.min_feature[0] ) ) 508 { 509 retval = sizeof ( type1->private_dict.min_feature[idx] ); 510 if ( value && value_len >= retval ) 511 *((FT_Short *)value) = type1->private_dict.min_feature[idx]; 512 } 513 break; 514 515 case PS_DICT_LEN_IV: 516 retval = sizeof ( type1->private_dict.lenIV ); 517 if ( value && value_len >= retval ) 518 *((FT_Int *)value) = type1->private_dict.lenIV; 519 break; 520 521 case PS_DICT_PASSWORD: 522 retval = sizeof ( type1->private_dict.password ); 523 if ( value && value_len >= retval ) 524 *((FT_Long *)value) = type1->private_dict.password; 525 break; 526 527 case PS_DICT_LANGUAGE_GROUP: 528 retval = sizeof ( type1->private_dict.language_group ); 529 if ( value && value_len >= retval ) 530 *((FT_Long *)value) = type1->private_dict.language_group; 531 break; 532 533 case PS_DICT_IS_FIXED_PITCH: 534 retval = sizeof ( type1->font_info.is_fixed_pitch ); 535 if ( value && value_len >= retval ) 536 *((FT_Bool *)value) = type1->font_info.is_fixed_pitch; 537 break; 538 539 case PS_DICT_UNDERLINE_POSITION: 540 retval = sizeof ( type1->font_info.underline_position ); 541 if ( value && value_len >= retval ) 542 *((FT_Short *)value) = type1->font_info.underline_position; 543 break; 544 545 case PS_DICT_UNDERLINE_THICKNESS: 546 retval = sizeof ( type1->font_info.underline_thickness ); 547 if ( value && value_len >= retval ) 548 *((FT_UShort *)value) = type1->font_info.underline_thickness; 549 break; 550 551 case PS_DICT_FS_TYPE: 552 retval = sizeof ( type1->font_extra.fs_type ); 553 if ( value && value_len >= retval ) 554 *((FT_UShort *)value) = type1->font_extra.fs_type; 555 break; 556 557 case PS_DICT_VERSION: 558 retval = ft_strlen( type1->font_info.version ) + 1; 559 if ( value && value_len >= retval ) 560 ft_memcpy( value, (void *)( type1->font_info.version ), retval ); 561 break; 562 563 case PS_DICT_NOTICE: 564 retval = ft_strlen( type1->font_info.notice ) + 1; 565 if ( value && value_len >= retval ) 566 ft_memcpy( value, (void *)( type1->font_info.notice ), retval ); 567 break; 568 569 case PS_DICT_FULL_NAME: 570 retval = ft_strlen( type1->font_info.full_name ) + 1; 571 if ( value && value_len >= retval ) 572 ft_memcpy( value, (void *)( type1->font_info.full_name ), retval ); 573 break; 574 575 case PS_DICT_FAMILY_NAME: 576 retval = ft_strlen( type1->font_info.family_name ) + 1; 577 if ( value && value_len >= retval ) 578 ft_memcpy( value, (void *)( type1->font_info.family_name ), retval ); 579 break; 580 581 case PS_DICT_WEIGHT: 582 retval = ft_strlen( type1->font_info.weight ) + 1; 583 if ( value && value_len >= retval ) 584 ft_memcpy( value, (void *)( type1->font_info.weight ), retval ); 585 break; 586 587 case PS_DICT_ITALIC_ANGLE: 588 retval = sizeof ( type1->font_info.italic_angle ); 589 if ( value && value_len >= retval ) 590 *((FT_Long *)value) = type1->font_info.italic_angle; 591 break; 592 } 593 594 return retval == 0 ? -1 : (FT_Long)retval; 595 } 596 597 598 static const FT_Service_PsInfoRec t1_service_ps_info = 599 { 600 (PS_GetFontInfoFunc) t1_ps_get_font_info, /* ps_get_font_info */ 601 (PS_GetFontExtraFunc) t1_ps_get_font_extra, /* ps_get_font_extra */ 602 (PS_HasGlyphNamesFunc) t1_ps_has_glyph_names, /* ps_has_glyph_names */ 603 (PS_GetFontPrivateFunc)t1_ps_get_font_private, /* ps_get_font_private */ 604 (PS_GetFontValueFunc) t1_ps_get_font_value, /* ps_get_font_value */ 605 }; 606 607 608 #ifndef T1_CONFIG_OPTION_NO_AFM 609 static const FT_Service_KerningRec t1_service_kerning = 610 { 611 T1_Get_Track_Kerning, /* get_track */ 612 }; 613 #endif 614 615 616 /* 617 * SERVICE LIST 618 * 619 */ 620 621 static const FT_ServiceDescRec t1_services[] = 622 { 623 { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &t1_service_ps_name }, 624 { FT_SERVICE_ID_GLYPH_DICT, &t1_service_glyph_dict }, 625 { FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_TYPE_1 }, 626 { FT_SERVICE_ID_POSTSCRIPT_INFO, &t1_service_ps_info }, 627 628 #ifndef T1_CONFIG_OPTION_NO_AFM 629 { FT_SERVICE_ID_KERNING, &t1_service_kerning }, 630 #endif 631 632 #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT 633 { FT_SERVICE_ID_MULTI_MASTERS, &t1_service_multi_masters }, 634 #endif 635 { NULL, NULL } 636 }; 637 638 639 FT_CALLBACK_DEF( FT_Module_Interface ) Get_Interface(FT_Module module,const FT_String * t1_interface)640 Get_Interface( FT_Module module, 641 const FT_String* t1_interface ) 642 { 643 FT_UNUSED( module ); 644 645 return ft_service_list_lookup( t1_services, t1_interface ); 646 } 647 648 649 #ifndef T1_CONFIG_OPTION_NO_AFM 650 651 /*************************************************************************/ 652 /* */ 653 /* <Function> */ 654 /* Get_Kerning */ 655 /* */ 656 /* <Description> */ 657 /* A driver method used to return the kerning vector between two */ 658 /* glyphs of the same face. */ 659 /* */ 660 /* <Input> */ 661 /* face :: A handle to the source face object. */ 662 /* */ 663 /* left_glyph :: The index of the left glyph in the kern pair. */ 664 /* */ 665 /* right_glyph :: The index of the right glyph in the kern pair. */ 666 /* */ 667 /* <Output> */ 668 /* kerning :: The kerning vector. This is in font units for */ 669 /* scalable formats, and in pixels for fixed-sizes */ 670 /* formats. */ 671 /* */ 672 /* <Return> */ 673 /* FreeType error code. 0 means success. */ 674 /* */ 675 /* <Note> */ 676 /* Only horizontal layouts (left-to-right & right-to-left) are */ 677 /* supported by this function. Other layouts, or more sophisticated */ 678 /* kernings are out of scope of this method (the basic driver */ 679 /* interface is meant to be simple). */ 680 /* */ 681 /* They can be implemented by format-specific interfaces. */ 682 /* */ 683 static FT_Error Get_Kerning(FT_Face t1face,FT_UInt left_glyph,FT_UInt right_glyph,FT_Vector * kerning)684 Get_Kerning( FT_Face t1face, /* T1_Face */ 685 FT_UInt left_glyph, 686 FT_UInt right_glyph, 687 FT_Vector* kerning ) 688 { 689 T1_Face face = (T1_Face)t1face; 690 691 692 kerning->x = 0; 693 kerning->y = 0; 694 695 if ( face->afm_data ) 696 T1_Get_Kerning( (AFM_FontInfo)face->afm_data, 697 left_glyph, 698 right_glyph, 699 kerning ); 700 701 return FT_Err_Ok; 702 } 703 704 705 #endif /* T1_CONFIG_OPTION_NO_AFM */ 706 707 708 FT_CALLBACK_TABLE_DEF 709 const FT_Driver_ClassRec t1_driver_class = 710 { 711 { 712 FT_MODULE_FONT_DRIVER | 713 FT_MODULE_DRIVER_SCALABLE | 714 FT_MODULE_DRIVER_HAS_HINTER, 715 716 sizeof ( FT_DriverRec ), 717 718 "type1", 719 0x10000L, 720 0x20000L, 721 722 NULL, /* module-specific interface */ 723 724 T1_Driver_Init, /* FT_Module_Constructor module_init */ 725 T1_Driver_Done, /* FT_Module_Destructor module_done */ 726 Get_Interface, /* FT_Module_Requester get_interface */ 727 }, 728 729 sizeof ( T1_FaceRec ), 730 sizeof ( T1_SizeRec ), 731 sizeof ( T1_GlyphSlotRec ), 732 733 T1_Face_Init, /* FT_Face_InitFunc init_face */ 734 T1_Face_Done, /* FT_Face_DoneFunc done_face */ 735 T1_Size_Init, /* FT_Size_InitFunc init_size */ 736 T1_Size_Done, /* FT_Size_DoneFunc done_size */ 737 T1_GlyphSlot_Init, /* FT_Slot_InitFunc init_slot */ 738 T1_GlyphSlot_Done, /* FT_Slot_DoneFunc done_slot */ 739 740 T1_Load_Glyph, /* FT_Slot_LoadFunc load_glyph */ 741 742 #ifdef T1_CONFIG_OPTION_NO_AFM 743 NULL, /* FT_Face_GetKerningFunc get_kerning */ 744 NULL, /* FT_Face_AttachFunc attach_file */ 745 #else 746 Get_Kerning, /* FT_Face_GetKerningFunc get_kerning */ 747 T1_Read_Metrics, /* FT_Face_AttachFunc attach_file */ 748 #endif 749 T1_Get_Advances, /* FT_Face_GetAdvancesFunc get_advances */ 750 751 T1_Size_Request, /* FT_Size_RequestFunc request_size */ 752 NULL /* FT_Size_SelectFunc select_size */ 753 }; 754 755 756 /* END */ 757