1 /**************************************************************************** 2 * 3 * ttdriver.c 4 * 5 * TrueType font driver implementation (body). 6 * 7 * Copyright (C) 1996-2023 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/ftdebug.h> 20 #include <freetype/internal/ftstream.h> 21 #include <freetype/internal/sfnt.h> 22 #include <freetype/internal/services/svfntfmt.h> 23 24 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 25 #include <freetype/ftmm.h> 26 #include <freetype/internal/services/svmm.h> 27 #include <freetype/internal/services/svmetric.h> 28 #endif 29 30 #include <freetype/internal/services/svtteng.h> 31 #include <freetype/internal/services/svttglyf.h> 32 #include <freetype/internal/services/svprop.h> 33 #include <freetype/ftdriver.h> 34 35 #include "ttdriver.h" 36 #include "ttgload.h" 37 #include "ttpload.h" 38 39 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 40 #include "ttgxvar.h" 41 #endif 42 43 #include "tterrors.h" 44 45 46 /************************************************************************** 47 * 48 * The macro FT_COMPONENT is used in trace mode. It is an implicit 49 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log 50 * messages during execution. 51 */ 52 #undef FT_COMPONENT 53 #define FT_COMPONENT ttdriver 54 55 56 /* 57 * PROPERTY SERVICE 58 * 59 */ 60 FT_CALLBACK_DEF( FT_Error ) tt_property_set(FT_Module module,const char * property_name,const void * value,FT_Bool value_is_string)61 tt_property_set( FT_Module module, /* TT_Driver */ 62 const char* property_name, 63 const void* value, 64 FT_Bool value_is_string ) 65 { 66 FT_Error error = FT_Err_Ok; 67 TT_Driver driver = (TT_Driver)module; 68 69 #ifndef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES 70 FT_UNUSED( value_is_string ); 71 #endif 72 73 74 if ( !ft_strcmp( property_name, "interpreter-version" ) ) 75 { 76 FT_UInt interpreter_version; 77 78 79 #ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES 80 if ( value_is_string ) 81 { 82 const char* s = (const char*)value; 83 84 85 interpreter_version = (FT_UInt)ft_strtol( s, NULL, 10 ); 86 } 87 else 88 #endif 89 { 90 FT_UInt* iv = (FT_UInt*)value; 91 92 93 interpreter_version = *iv; 94 } 95 96 switch ( interpreter_version ) 97 { 98 case TT_INTERPRETER_VERSION_35: 99 driver->interpreter_version = TT_INTERPRETER_VERSION_35; 100 break; 101 102 case TT_INTERPRETER_VERSION_38: 103 case TT_INTERPRETER_VERSION_40: 104 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL 105 driver->interpreter_version = TT_INTERPRETER_VERSION_40; 106 break; 107 #endif 108 109 default: 110 error = FT_ERR( Unimplemented_Feature ); 111 } 112 113 return error; 114 } 115 116 FT_TRACE2(( "tt_property_set: missing property `%s'\n", 117 property_name )); 118 return FT_THROW( Missing_Property ); 119 } 120 121 122 FT_CALLBACK_DEF( FT_Error ) tt_property_get(FT_Module module,const char * property_name,void * value)123 tt_property_get( FT_Module module, /* TT_Driver */ 124 const char* property_name, 125 void* value ) 126 { 127 FT_Error error = FT_Err_Ok; 128 TT_Driver driver = (TT_Driver)module; 129 130 FT_UInt interpreter_version = driver->interpreter_version; 131 132 133 if ( !ft_strcmp( property_name, "interpreter-version" ) ) 134 { 135 FT_UInt* val = (FT_UInt*)value; 136 137 138 *val = interpreter_version; 139 140 return error; 141 } 142 143 FT_TRACE2(( "tt_property_get: missing property `%s'\n", 144 property_name )); 145 return FT_THROW( Missing_Property ); 146 } 147 148 FT_DEFINE_SERVICE_PROPERTIESREC(tt_service_properties,tt_property_set,tt_property_get)149 FT_DEFINE_SERVICE_PROPERTIESREC( 150 tt_service_properties, 151 152 tt_property_set, /* FT_Properties_SetFunc set_property */ 153 tt_property_get /* FT_Properties_GetFunc get_property */ 154 ) 155 156 157 /*************************************************************************/ 158 /*************************************************************************/ 159 /*************************************************************************/ 160 /**** ****/ 161 /**** ****/ 162 /**** F A C E S ****/ 163 /**** ****/ 164 /**** ****/ 165 /*************************************************************************/ 166 /*************************************************************************/ 167 /*************************************************************************/ 168 169 170 /************************************************************************** 171 * 172 * @Function: 173 * tt_get_kerning 174 * 175 * @Description: 176 * A driver method used to return the kerning vector between two 177 * glyphs of the same face. 178 * 179 * @Input: 180 * face :: 181 * A handle to the source face object. 182 * 183 * left_glyph :: 184 * The index of the left glyph in the kern pair. 185 * 186 * right_glyph :: 187 * The index of the right glyph in the kern pair. 188 * 189 * @Output: 190 * kerning :: 191 * The kerning vector. This is in font units for 192 * scalable formats, and in pixels for fixed-sizes 193 * formats. 194 * 195 * @Return: 196 * FreeType error code. 0 means success. 197 * 198 * @Note: 199 * Only horizontal layouts (left-to-right & right-to-left) are 200 * supported by this function. Other layouts, or more sophisticated 201 * kernings, are out of scope of this method (the basic driver 202 * interface is meant to be simple). 203 * 204 * They can be implemented by format-specific interfaces. 205 */ 206 FT_CALLBACK_DEF( FT_Error ) 207 tt_get_kerning( FT_Face face, /* TT_Face */ 208 FT_UInt left_glyph, 209 FT_UInt right_glyph, 210 FT_Vector* kerning ) 211 { 212 TT_Face ttface = (TT_Face)face; 213 SFNT_Service sfnt = (SFNT_Service)ttface->sfnt; 214 215 216 kerning->x = 0; 217 kerning->y = 0; 218 219 if ( sfnt ) 220 kerning->x = sfnt->get_kerning( ttface, left_glyph, right_glyph ); 221 222 return 0; 223 } 224 225 226 FT_CALLBACK_DEF( FT_Error ) tt_get_advances(FT_Face face,FT_UInt start,FT_UInt count,FT_Int32 flags,FT_Fixed * advances)227 tt_get_advances( FT_Face face, /* TT_Face */ 228 FT_UInt start, 229 FT_UInt count, 230 FT_Int32 flags, 231 FT_Fixed *advances ) 232 { 233 FT_UInt nn; 234 TT_Face ttface = (TT_Face)face; 235 236 237 /* XXX: TODO: check for sbits */ 238 239 if ( flags & FT_LOAD_VERTICAL_LAYOUT ) 240 { 241 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 242 /* no fast retrieval for blended MM fonts without VVAR table */ 243 if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) && 244 !( ttface->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) 245 return FT_THROW( Unimplemented_Feature ); 246 #endif 247 248 for ( nn = 0; nn < count; nn++ ) 249 { 250 FT_Short tsb; 251 FT_UShort ah; 252 253 254 /* since we don't need `tsb', we use zero for `yMax' parameter */ 255 TT_Get_VMetrics( ttface, start + nn, 0, &tsb, &ah ); 256 advances[nn] = ah; 257 } 258 } 259 else 260 { 261 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 262 /* no fast retrieval for blended MM fonts without HVAR table */ 263 if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) && 264 !( ttface->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) 265 return FT_THROW( Unimplemented_Feature ); 266 #endif 267 268 for ( nn = 0; nn < count; nn++ ) 269 { 270 FT_Short lsb; 271 FT_UShort aw; 272 273 274 TT_Get_HMetrics( ttface, start + nn, &lsb, &aw ); 275 advances[nn] = aw; 276 } 277 } 278 279 return FT_Err_Ok; 280 } 281 282 283 /*************************************************************************/ 284 /*************************************************************************/ 285 /*************************************************************************/ 286 /**** ****/ 287 /**** ****/ 288 /**** S I Z E S ****/ 289 /**** ****/ 290 /**** ****/ 291 /*************************************************************************/ 292 /*************************************************************************/ 293 /*************************************************************************/ 294 295 296 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS 297 298 FT_CALLBACK_DEF( FT_Error ) tt_size_select(FT_Size size,FT_ULong strike_index)299 tt_size_select( FT_Size size, 300 FT_ULong strike_index ) 301 { 302 TT_Face ttface = (TT_Face)size->face; 303 TT_Size ttsize = (TT_Size)size; 304 FT_Error error = FT_Err_Ok; 305 306 307 ttsize->strike_index = strike_index; 308 309 if ( FT_IS_SCALABLE( size->face ) ) 310 { 311 /* use the scaled metrics, even when tt_size_reset fails */ 312 FT_Select_Metrics( size->face, strike_index ); 313 314 tt_size_reset( ttsize ); /* ignore return value */ 315 } 316 else 317 { 318 SFNT_Service sfnt = (SFNT_Service)ttface->sfnt; 319 FT_Size_Metrics* size_metrics = &size->metrics; 320 321 322 error = sfnt->load_strike_metrics( ttface, 323 strike_index, 324 size_metrics ); 325 if ( error ) 326 ttsize->strike_index = 0xFFFFFFFFUL; 327 } 328 329 return error; 330 } 331 332 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ 333 334 335 FT_CALLBACK_DEF( FT_Error ) tt_size_request(FT_Size size,FT_Size_Request req)336 tt_size_request( FT_Size size, 337 FT_Size_Request req ) 338 { 339 TT_Size ttsize = (TT_Size)size; 340 FT_Error error = FT_Err_Ok; 341 342 343 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS 344 345 if ( FT_HAS_FIXED_SIZES( size->face ) ) 346 { 347 TT_Face ttface = (TT_Face)size->face; 348 SFNT_Service sfnt = (SFNT_Service)ttface->sfnt; 349 FT_ULong strike_index; 350 351 352 error = sfnt->set_sbit_strike( ttface, req, &strike_index ); 353 354 if ( error ) 355 ttsize->strike_index = 0xFFFFFFFFUL; 356 else 357 return tt_size_select( size, strike_index ); 358 } 359 360 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ 361 362 { 363 FT_Error err = FT_Request_Metrics( size->face, req ); 364 365 366 if ( err ) 367 { 368 error = err; 369 goto Exit; 370 } 371 } 372 373 if ( FT_IS_SCALABLE( size->face ) ) 374 { 375 error = tt_size_reset( ttsize ); 376 377 #ifdef TT_USE_BYTECODE_INTERPRETER 378 /* for the `MPS' bytecode instruction we need the point size */ 379 if ( !error ) 380 { 381 FT_UInt resolution = 382 ttsize->metrics->x_ppem > ttsize->metrics->y_ppem 383 ? req->horiResolution 384 : req->vertResolution; 385 386 387 /* if we don't have a resolution value, assume 72dpi */ 388 if ( req->type == FT_SIZE_REQUEST_TYPE_SCALES || 389 !resolution ) 390 resolution = 72; 391 392 ttsize->point_size = FT_MulDiv( ttsize->ttmetrics.ppem, 393 64 * 72, 394 resolution ); 395 } 396 #endif 397 } 398 399 Exit: 400 return error; 401 } 402 403 404 /************************************************************************** 405 * 406 * @Function: 407 * tt_glyph_load 408 * 409 * @Description: 410 * A driver method used to load a glyph within a given glyph slot. 411 * 412 * @Input: 413 * slot :: 414 * A handle to the target slot object where the glyph 415 * will be loaded. 416 * 417 * size :: 418 * A handle to the source face size at which the glyph 419 * must be scaled, loaded, etc. 420 * 421 * glyph_index :: 422 * The index of the glyph in the font file. 423 * 424 * load_flags :: 425 * A flag indicating what to load for this glyph. The 426 * FT_LOAD_XXX constants can be used to control the 427 * glyph loading process (e.g., whether the outline 428 * should be scaled, whether to load bitmaps or not, 429 * whether to hint the outline, etc). 430 * 431 * @Return: 432 * FreeType error code. 0 means success. 433 */ 434 FT_CALLBACK_DEF( FT_Error ) tt_glyph_load(FT_GlyphSlot slot,FT_Size size,FT_UInt glyph_index,FT_Int32 load_flags)435 tt_glyph_load( FT_GlyphSlot slot, /* TT_GlyphSlot */ 436 FT_Size size, /* TT_Size */ 437 FT_UInt glyph_index, 438 FT_Int32 load_flags ) 439 { 440 TT_GlyphSlot ttslot = (TT_GlyphSlot)slot; 441 TT_Size ttsize = (TT_Size)size; 442 FT_Face face = ttslot->face; 443 FT_Error error; 444 445 446 if ( !slot ) 447 return FT_THROW( Invalid_Slot_Handle ); 448 449 if ( !size ) 450 return FT_THROW( Invalid_Size_Handle ); 451 452 if ( !face ) 453 return FT_THROW( Invalid_Face_Handle ); 454 455 #ifdef FT_CONFIG_OPTION_INCREMENTAL 456 if ( glyph_index >= (FT_UInt)face->num_glyphs && 457 !face->internal->incremental_interface ) 458 #else 459 if ( glyph_index >= (FT_UInt)face->num_glyphs ) 460 #endif 461 return FT_THROW( Invalid_Argument ); 462 463 if ( load_flags & FT_LOAD_NO_HINTING ) 464 { 465 /* both FT_LOAD_NO_HINTING and FT_LOAD_NO_AUTOHINT */ 466 /* are necessary to disable hinting for tricky fonts */ 467 468 if ( FT_IS_TRICKY( face ) ) 469 load_flags &= ~FT_LOAD_NO_HINTING; 470 471 if ( load_flags & FT_LOAD_NO_AUTOHINT ) 472 load_flags |= FT_LOAD_NO_HINTING; 473 } 474 475 if ( load_flags & ( FT_LOAD_NO_RECURSE | FT_LOAD_NO_SCALE ) ) 476 { 477 load_flags |= FT_LOAD_NO_BITMAP | FT_LOAD_NO_SCALE; 478 479 if ( !FT_IS_TRICKY( face ) ) 480 load_flags |= FT_LOAD_NO_HINTING; 481 } 482 483 /* use hinted metrics only if we load a glyph with hinting */ 484 ttsize->metrics = ( load_flags & FT_LOAD_NO_HINTING ) 485 ? &size->metrics 486 : &ttsize->hinted_metrics; 487 488 /* now fill in the glyph slot with outline/bitmap/layered */ 489 error = TT_Load_Glyph( ttsize, ttslot, glyph_index, load_flags ); 490 491 /* force drop-out mode to 2 - irrelevant now */ 492 /* slot->outline.dropout_mode = 2; */ 493 494 return error; 495 } 496 497 498 /*************************************************************************/ 499 /*************************************************************************/ 500 /*************************************************************************/ 501 /**** ****/ 502 /**** ****/ 503 /**** D R I V E R I N T E R F A C E ****/ 504 /**** ****/ 505 /**** ****/ 506 /*************************************************************************/ 507 /*************************************************************************/ 508 /*************************************************************************/ 509 510 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 511 512 FT_DEFINE_SERVICE_MULTIMASTERSREC( 513 tt_service_gx_multi_masters, 514 515 NULL, /* FT_Get_MM_Func get_mm */ 516 NULL, /* FT_Set_MM_Design_Func set_mm_design */ 517 TT_Set_MM_Blend, /* FT_Set_MM_Blend_Func set_mm_blend */ 518 TT_Get_MM_Blend, /* FT_Get_MM_Blend_Func get_mm_blend */ 519 TT_Get_MM_Var, /* FT_Get_MM_Var_Func get_mm_var */ 520 TT_Set_Var_Design, /* FT_Set_Var_Design_Func set_var_design */ 521 TT_Get_Var_Design, /* FT_Get_Var_Design_Func get_var_design */ 522 TT_Set_Named_Instance, /* FT_Set_Named_Instance_Func set_named_instance */ 523 TT_Get_Default_Named_Instance, 524 /* FT_Get_Default_Named_Instance_Func get_default_named_instance */ 525 NULL, /* FT_Set_MM_WeightVector_Func set_mm_weightvector */ 526 NULL, /* FT_Get_MM_WeightVector_Func get_mm_weightvector */ 527 528 tt_construct_ps_name, /* FT_Construct_PS_Name_Func construct_ps_name */ 529 tt_var_load_delta_set_index_mapping, 530 /* FT_Var_Load_Delta_Set_Idx_Map_Func load_delta_set_idx_map */ 531 tt_var_load_item_variation_store, 532 /* FT_Var_Load_Item_Var_Store_Func load_item_variation_store */ 533 tt_var_get_item_delta, /* FT_Var_Get_Item_Delta_Func get_item_delta */ 534 tt_var_done_item_variation_store, 535 /* FT_Var_Done_Item_Var_Store_Func done_item_variation_store */ 536 tt_var_done_delta_set_index_map, 537 /* FT_Var_Done_Delta_Set_Idx_Map_Func done_delta_set_index_map */ 538 tt_get_var_blend, /* FT_Get_Var_Blend_Func get_var_blend */ 539 tt_done_blend /* FT_Done_Blend_Func done_blend */ 540 ) 541 542 FT_DEFINE_SERVICE_METRICSVARIATIONSREC( 543 tt_service_metrics_variations, 544 545 tt_hadvance_adjust, /* FT_HAdvance_Adjust_Func hadvance_adjust */ 546 NULL, /* FT_LSB_Adjust_Func lsb_adjust */ 547 NULL, /* FT_RSB_Adjust_Func rsb_adjust */ 548 549 tt_vadvance_adjust, /* FT_VAdvance_Adjust_Func vadvance_adjust */ 550 NULL, /* FT_TSB_Adjust_Func tsb_adjust */ 551 NULL, /* FT_BSB_Adjust_Func bsb_adjust */ 552 NULL, /* FT_VOrg_Adjust_Func vorg_adjust */ 553 554 tt_apply_mvar, /* FT_Metrics_Adjust_Func metrics_adjust */ 555 tt_size_reset_height /* FT_Size_Reset_Func size_reset */ 556 ) 557 558 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ 559 560 561 static const FT_Service_TrueTypeEngineRec tt_service_truetype_engine = 562 { 563 #ifdef TT_USE_BYTECODE_INTERPRETER 564 565 FT_TRUETYPE_ENGINE_TYPE_PATENTED 566 567 #else /* !TT_USE_BYTECODE_INTERPRETER */ 568 569 FT_TRUETYPE_ENGINE_TYPE_NONE 570 571 #endif /* TT_USE_BYTECODE_INTERPRETER */ 572 }; 573 574 575 FT_DEFINE_SERVICE_TTGLYFREC( 576 tt_service_truetype_glyf, 577 578 (TT_Glyf_GetLocationFunc)tt_face_get_location /* get_location */ 579 ) 580 581 582 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 583 FT_DEFINE_SERVICEDESCREC6( 584 tt_services, 585 586 FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_TRUETYPE, 587 FT_SERVICE_ID_MULTI_MASTERS, &tt_service_gx_multi_masters, 588 FT_SERVICE_ID_METRICS_VARIATIONS, &tt_service_metrics_variations, 589 FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, 590 FT_SERVICE_ID_TT_GLYF, &tt_service_truetype_glyf, 591 FT_SERVICE_ID_PROPERTIES, &tt_service_properties ) 592 #else 593 FT_DEFINE_SERVICEDESCREC4( 594 tt_services, 595 596 FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_TRUETYPE, 597 FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, 598 FT_SERVICE_ID_TT_GLYF, &tt_service_truetype_glyf, 599 FT_SERVICE_ID_PROPERTIES, &tt_service_properties ) 600 #endif 601 602 FT_CALLBACK_DEF(FT_Module_Interface)603 FT_CALLBACK_DEF( FT_Module_Interface ) 604 tt_get_interface( FT_Module driver, /* TT_Driver */ 605 const char* tt_interface ) 606 { 607 FT_Library library; 608 FT_Module_Interface result; 609 FT_Module sfntd; 610 SFNT_Service sfnt; 611 612 613 result = ft_service_list_lookup( tt_services, tt_interface ); 614 if ( result ) 615 return result; 616 617 if ( !driver ) 618 return NULL; 619 library = driver->library; 620 if ( !library ) 621 return NULL; 622 623 /* only return the default interface from the SFNT module */ 624 sfntd = FT_Get_Module( library, "sfnt" ); 625 if ( sfntd ) 626 { 627 sfnt = (SFNT_Service)( sfntd->clazz->module_interface ); 628 if ( sfnt ) 629 return sfnt->get_interface( driver, tt_interface ); 630 } 631 632 return 0; 633 } 634 635 636 /* The FT_DriverInterface structure is defined in ftdriver.h. */ 637 638 #ifdef TT_USE_BYTECODE_INTERPRETER 639 #define TT_HINTER_FLAG FT_MODULE_DRIVER_HAS_HINTER 640 #else 641 #define TT_HINTER_FLAG 0 642 #endif 643 644 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS 645 #define TT_SIZE_SELECT tt_size_select 646 #else 647 #define TT_SIZE_SELECT 0 648 #endif 649 650 FT_DEFINE_DRIVER( 651 tt_driver_class, 652 653 FT_MODULE_FONT_DRIVER | 654 FT_MODULE_DRIVER_SCALABLE | 655 TT_HINTER_FLAG, 656 657 sizeof ( TT_DriverRec ), 658 659 "truetype", /* driver name */ 660 0x10000L, /* driver version == 1.0 */ 661 0x20000L, /* driver requires FreeType 2.0 or above */ 662 663 NULL, /* module-specific interface */ 664 665 tt_driver_init, /* FT_Module_Constructor module_init */ 666 tt_driver_done, /* FT_Module_Destructor module_done */ 667 tt_get_interface, /* FT_Module_Requester get_interface */ 668 669 sizeof ( TT_FaceRec ), 670 sizeof ( TT_SizeRec ), 671 sizeof ( FT_GlyphSlotRec ), 672 673 tt_face_init, /* FT_Face_InitFunc init_face */ 674 tt_face_done, /* FT_Face_DoneFunc done_face */ 675 tt_size_init, /* FT_Size_InitFunc init_size */ 676 tt_size_done, /* FT_Size_DoneFunc done_size */ 677 tt_slot_init, /* FT_Slot_InitFunc init_slot */ 678 NULL, /* FT_Slot_DoneFunc done_slot */ 679 680 tt_glyph_load, /* FT_Slot_LoadFunc load_glyph */ 681 682 tt_get_kerning, /* FT_Face_GetKerningFunc get_kerning */ 683 NULL, /* FT_Face_AttachFunc attach_file */ 684 tt_get_advances, /* FT_Face_GetAdvancesFunc get_advances */ 685 686 tt_size_request, /* FT_Size_RequestFunc request_size */ 687 TT_SIZE_SELECT /* FT_Size_SelectFunc select_size */ 688 ) 689 690 691 /* END */ 692