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