1 /***************************************************************************/ 2 /* */ 3 /* ttdriver.c */ 4 /* */ 5 /* TrueType font driver implementation (body). */ 6 /* */ 7 /* Copyright 1996-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 FT_INTERNAL_DEBUG_H 21 #include FT_INTERNAL_STREAM_H 22 #include FT_INTERNAL_SFNT_H 23 #include FT_SERVICE_XFREE86_NAME_H 24 25 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 26 #include FT_MULTIPLE_MASTERS_H 27 #include FT_SERVICE_MULTIPLE_MASTERS_H 28 #endif 29 30 #include FT_SERVICE_TRUETYPE_ENGINE_H 31 #include FT_SERVICE_TRUETYPE_GLYF_H 32 #include FT_SERVICE_PROPERTIES_H 33 #include FT_TRUETYPE_DRIVER_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 #include "ttpic.h" 46 47 /*************************************************************************/ 48 /* */ 49 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 50 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 51 /* messages during execution. */ 52 /* */ 53 #undef FT_COMPONENT 54 #define FT_COMPONENT trace_ttdriver 55 56 57 /* 58 * PROPERTY SERVICE 59 * 60 */ 61 static FT_Error 62 tt_property_set( FT_Module module, /* TT_Driver */ 63 const char* property_name, 64 const void* value ) 65 { 66 FT_Error error = FT_Err_Ok; 67 TT_Driver driver = (TT_Driver)module; 68 69 70 if ( !ft_strcmp( property_name, "interpreter-version" ) ) 71 { 72 FT_UInt* interpreter_version = (FT_UInt*)value; 73 74 75 #ifndef TT_CONFIG_OPTION_SUBPIXEL_HINTING 76 if ( *interpreter_version != TT_INTERPRETER_VERSION_35 ) 77 error = FT_ERR( Unimplemented_Feature ); 78 else 79 #endif 80 driver->interpreter_version = *interpreter_version; 81 82 return error; 83 } 84 85 FT_TRACE0(( "tt_property_set: missing property `%s'\n", 86 property_name )); 87 return FT_THROW( Missing_Property ); 88 } 89 90 91 static FT_Error 92 tt_property_get( FT_Module module, /* TT_Driver */ 93 const char* property_name, 94 const void* value ) 95 { 96 FT_Error error = FT_Err_Ok; 97 TT_Driver driver = (TT_Driver)module; 98 99 FT_UInt interpreter_version = driver->interpreter_version; 100 101 102 if ( !ft_strcmp( property_name, "interpreter-version" ) ) 103 { 104 FT_UInt* val = (FT_UInt*)value; 105 106 107 *val = interpreter_version; 108 109 return error; 110 } 111 112 FT_TRACE0(( "tt_property_get: missing property `%s'\n", 113 property_name )); 114 return FT_THROW( Missing_Property ); 115 } 116 117 118 FT_DEFINE_SERVICE_PROPERTIESREC( 119 tt_service_properties, 120 (FT_Properties_SetFunc)tt_property_set, 121 (FT_Properties_GetFunc)tt_property_get ) 122 123 124 /*************************************************************************/ 125 /*************************************************************************/ 126 /*************************************************************************/ 127 /**** ****/ 128 /**** ****/ 129 /**** F A C E S ****/ 130 /**** ****/ 131 /**** ****/ 132 /*************************************************************************/ 133 /*************************************************************************/ 134 /*************************************************************************/ 135 136 137 #undef PAIR_TAG 138 #define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \ 139 (FT_ULong)right ) 140 141 142 /*************************************************************************/ 143 /* */ 144 /* <Function> */ 145 /* tt_get_kerning */ 146 /* */ 147 /* <Description> */ 148 /* A driver method used to return the kerning vector between two */ 149 /* glyphs of the same face. */ 150 /* */ 151 /* <Input> */ 152 /* face :: A handle to the source face object. */ 153 /* */ 154 /* left_glyph :: The index of the left glyph in the kern pair. */ 155 /* */ 156 /* right_glyph :: The index of the right glyph in the kern pair. */ 157 /* */ 158 /* <Output> */ 159 /* kerning :: The kerning vector. This is in font units for */ 160 /* scalable formats, and in pixels for fixed-sizes */ 161 /* formats. */ 162 /* */ 163 /* <Return> */ 164 /* FreeType error code. 0 means success. */ 165 /* */ 166 /* <Note> */ 167 /* Only horizontal layouts (left-to-right & right-to-left) are */ 168 /* supported by this function. Other layouts, or more sophisticated */ 169 /* kernings, are out of scope of this method (the basic driver */ 170 /* interface is meant to be simple). */ 171 /* */ 172 /* They can be implemented by format-specific interfaces. */ 173 /* */ 174 static FT_Error 175 tt_get_kerning( FT_Face ttface, /* TT_Face */ 176 FT_UInt left_glyph, 177 FT_UInt right_glyph, 178 FT_Vector* kerning ) 179 { 180 TT_Face face = (TT_Face)ttface; 181 SFNT_Service sfnt = (SFNT_Service)face->sfnt; 182 183 184 kerning->x = 0; 185 kerning->y = 0; 186 187 if ( sfnt ) 188 kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph ); 189 190 return 0; 191 } 192 193 194 #undef PAIR_TAG 195 196 197 static FT_Error 198 tt_get_advances( FT_Face ttface, 199 FT_UInt start, 200 FT_UInt count, 201 FT_Int32 flags, 202 FT_Fixed *advances ) 203 { 204 FT_UInt nn; 205 TT_Face face = (TT_Face) ttface; 206 207 208 /* XXX: TODO: check for sbits */ 209 210 if ( flags & FT_LOAD_VERTICAL_LAYOUT ) 211 { 212 for ( nn = 0; nn < count; nn++ ) 213 { 214 FT_Short tsb; 215 FT_UShort ah; 216 217 218 TT_Get_VMetrics( face, start + nn, &tsb, &ah ); 219 advances[nn] = ah; 220 } 221 } 222 else 223 { 224 for ( nn = 0; nn < count; nn++ ) 225 { 226 FT_Short lsb; 227 FT_UShort aw; 228 229 230 TT_Get_HMetrics( face, start + nn, &lsb, &aw ); 231 advances[nn] = aw; 232 } 233 } 234 235 return FT_Err_Ok; 236 } 237 238 /*************************************************************************/ 239 /*************************************************************************/ 240 /*************************************************************************/ 241 /**** ****/ 242 /**** ****/ 243 /**** S I Z E S ****/ 244 /**** ****/ 245 /**** ****/ 246 /*************************************************************************/ 247 /*************************************************************************/ 248 /*************************************************************************/ 249 250 251 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS 252 253 static FT_Error 254 tt_size_select( FT_Size size, 255 FT_ULong strike_index ) 256 { 257 TT_Face ttface = (TT_Face)size->face; 258 TT_Size ttsize = (TT_Size)size; 259 FT_Error error = FT_Err_Ok; 260 261 262 ttsize->strike_index = strike_index; 263 264 if ( FT_IS_SCALABLE( size->face ) ) 265 { 266 /* use the scaled metrics, even when tt_size_reset fails */ 267 FT_Select_Metrics( size->face, strike_index ); 268 269 tt_size_reset( ttsize ); 270 } 271 else 272 { 273 SFNT_Service sfnt = (SFNT_Service) ttface->sfnt; 274 FT_Size_Metrics* metrics = &size->metrics; 275 276 277 error = sfnt->load_strike_metrics( ttface, strike_index, metrics ); 278 if ( error ) 279 ttsize->strike_index = 0xFFFFFFFFUL; 280 } 281 282 return error; 283 } 284 285 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ 286 287 288 static FT_Error 289 tt_size_request( FT_Size size, 290 FT_Size_Request req ) 291 { 292 TT_Size ttsize = (TT_Size)size; 293 FT_Error error = FT_Err_Ok; 294 295 296 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS 297 298 if ( FT_HAS_FIXED_SIZES( size->face ) ) 299 { 300 TT_Face ttface = (TT_Face)size->face; 301 SFNT_Service sfnt = (SFNT_Service) ttface->sfnt; 302 FT_ULong strike_index; 303 304 305 error = sfnt->set_sbit_strike( ttface, req, &strike_index ); 306 307 if ( error ) 308 ttsize->strike_index = 0xFFFFFFFFUL; 309 else 310 return tt_size_select( size, strike_index ); 311 } 312 313 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ 314 315 FT_Request_Metrics( size->face, req ); 316 317 if ( FT_IS_SCALABLE( size->face ) ) 318 { 319 error = tt_size_reset( ttsize ); 320 ttsize->root.metrics = ttsize->metrics; 321 } 322 323 return error; 324 } 325 326 327 /*************************************************************************/ 328 /* */ 329 /* <Function> */ 330 /* tt_glyph_load */ 331 /* */ 332 /* <Description> */ 333 /* A driver method used to load a glyph within a given glyph slot. */ 334 /* */ 335 /* <Input> */ 336 /* slot :: A handle to the target slot object where the glyph */ 337 /* will be loaded. */ 338 /* */ 339 /* size :: A handle to the source face size at which the glyph */ 340 /* must be scaled, loaded, etc. */ 341 /* */ 342 /* glyph_index :: The index of the glyph in the font file. */ 343 /* */ 344 /* load_flags :: A flag indicating what to load for this glyph. The */ 345 /* FT_LOAD_XXX constants can be used to control the */ 346 /* glyph loading process (e.g., whether the outline */ 347 /* should be scaled, whether to load bitmaps or not, */ 348 /* whether to hint the outline, etc). */ 349 /* */ 350 /* <Return> */ 351 /* FreeType error code. 0 means success. */ 352 /* */ 353 static FT_Error 354 tt_glyph_load( FT_GlyphSlot ttslot, /* TT_GlyphSlot */ 355 FT_Size ttsize, /* TT_Size */ 356 FT_UInt glyph_index, 357 FT_Int32 load_flags ) 358 { 359 TT_GlyphSlot slot = (TT_GlyphSlot)ttslot; 360 TT_Size size = (TT_Size)ttsize; 361 FT_Face face = ttslot->face; 362 FT_Error error; 363 364 365 if ( !slot ) 366 return FT_THROW( Invalid_Slot_Handle ); 367 368 if ( !size ) 369 return FT_THROW( Invalid_Size_Handle ); 370 371 if ( !face ) 372 return FT_THROW( Invalid_Argument ); 373 374 #ifdef FT_CONFIG_OPTION_INCREMENTAL 375 if ( glyph_index >= (FT_UInt)face->num_glyphs && 376 !face->internal->incremental_interface ) 377 #else 378 if ( glyph_index >= (FT_UInt)face->num_glyphs ) 379 #endif 380 return FT_THROW( Invalid_Argument ); 381 382 if ( load_flags & FT_LOAD_NO_HINTING ) 383 { 384 /* both FT_LOAD_NO_HINTING and FT_LOAD_NO_AUTOHINT */ 385 /* are necessary to disable hinting for tricky fonts */ 386 387 if ( FT_IS_TRICKY( face ) ) 388 load_flags &= ~FT_LOAD_NO_HINTING; 389 390 if ( load_flags & FT_LOAD_NO_AUTOHINT ) 391 load_flags |= FT_LOAD_NO_HINTING; 392 } 393 394 if ( load_flags & ( FT_LOAD_NO_RECURSE | FT_LOAD_NO_SCALE ) ) 395 { 396 load_flags |= FT_LOAD_NO_BITMAP | FT_LOAD_NO_SCALE; 397 398 if ( !FT_IS_TRICKY( face ) ) 399 load_flags |= FT_LOAD_NO_HINTING; 400 } 401 402 /* now load the glyph outline if necessary */ 403 error = TT_Load_Glyph( size, slot, glyph_index, load_flags ); 404 405 /* force drop-out mode to 2 - irrelevant now */ 406 /* slot->outline.dropout_mode = 2; */ 407 408 return error; 409 } 410 411 412 /*************************************************************************/ 413 /*************************************************************************/ 414 /*************************************************************************/ 415 /**** ****/ 416 /**** ****/ 417 /**** D R I V E R I N T E R F A C E ****/ 418 /**** ****/ 419 /**** ****/ 420 /*************************************************************************/ 421 /*************************************************************************/ 422 /*************************************************************************/ 423 424 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 425 FT_DEFINE_SERVICE_MULTIMASTERSREC( 426 tt_service_gx_multi_masters, 427 (FT_Get_MM_Func) NULL, 428 (FT_Set_MM_Design_Func) NULL, 429 (FT_Set_MM_Blend_Func) TT_Set_MM_Blend, 430 (FT_Get_MM_Var_Func) TT_Get_MM_Var, 431 (FT_Set_Var_Design_Func)TT_Set_Var_Design ) 432 #endif 433 434 static const FT_Service_TrueTypeEngineRec tt_service_truetype_engine = 435 { 436 #ifdef TT_USE_BYTECODE_INTERPRETER 437 438 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING 439 FT_TRUETYPE_ENGINE_TYPE_UNPATENTED 440 #else 441 FT_TRUETYPE_ENGINE_TYPE_PATENTED 442 #endif 443 444 #else /* !TT_USE_BYTECODE_INTERPRETER */ 445 446 FT_TRUETYPE_ENGINE_TYPE_NONE 447 448 #endif /* TT_USE_BYTECODE_INTERPRETER */ 449 }; 450 451 FT_DEFINE_SERVICE_TTGLYFREC( 452 tt_service_truetype_glyf, 453 (TT_Glyf_GetLocationFunc)tt_face_get_location ) 454 455 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 456 FT_DEFINE_SERVICEDESCREC5( 457 tt_services, 458 FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE, 459 FT_SERVICE_ID_MULTI_MASTERS, &TT_SERVICE_GX_MULTI_MASTERS_GET, 460 FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, 461 FT_SERVICE_ID_TT_GLYF, &TT_SERVICE_TRUETYPE_GLYF_GET, 462 FT_SERVICE_ID_PROPERTIES, &TT_SERVICE_PROPERTIES_GET ) 463 #else 464 FT_DEFINE_SERVICEDESCREC4( 465 tt_services, 466 FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE, 467 FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, 468 FT_SERVICE_ID_TT_GLYF, &TT_SERVICE_TRUETYPE_GLYF_GET, 469 FT_SERVICE_ID_PROPERTIES, &TT_SERVICE_PROPERTIES_GET ) 470 #endif 471 472 473 FT_CALLBACK_DEF( FT_Module_Interface ) 474 tt_get_interface( FT_Module driver, /* TT_Driver */ 475 const char* tt_interface ) 476 { 477 FT_Library library; 478 FT_Module_Interface result; 479 FT_Module sfntd; 480 SFNT_Service sfnt; 481 482 483 /* TT_SERVICES_GET derefers `library' in PIC mode */ 484 #ifdef FT_CONFIG_OPTION_PIC 485 if ( !driver ) 486 return NULL; 487 library = driver->library; 488 if ( !library ) 489 return NULL; 490 #endif 491 492 result = ft_service_list_lookup( TT_SERVICES_GET, tt_interface ); 493 if ( result != NULL ) 494 return result; 495 496 #ifndef FT_CONFIG_OPTION_PIC 497 if ( !driver ) 498 return NULL; 499 library = driver->library; 500 if ( !library ) 501 return NULL; 502 #endif 503 504 /* only return the default interface from the SFNT module */ 505 sfntd = FT_Get_Module( library, "sfnt" ); 506 if ( sfntd ) 507 { 508 sfnt = (SFNT_Service)( sfntd->clazz->module_interface ); 509 if ( sfnt ) 510 return sfnt->get_interface( driver, tt_interface ); 511 } 512 513 return 0; 514 } 515 516 517 /* The FT_DriverInterface structure is defined in ftdriver.h. */ 518 519 #ifdef TT_USE_BYTECODE_INTERPRETER 520 #define TT_HINTER_FLAG FT_MODULE_DRIVER_HAS_HINTER 521 #else 522 #define TT_HINTER_FLAG 0 523 #endif 524 525 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS 526 #define TT_SIZE_SELECT tt_size_select 527 #else 528 #define TT_SIZE_SELECT 0 529 #endif 530 531 FT_DEFINE_DRIVER( 532 tt_driver_class, 533 534 FT_MODULE_FONT_DRIVER | 535 FT_MODULE_DRIVER_SCALABLE | 536 TT_HINTER_FLAG, 537 538 sizeof ( TT_DriverRec ), 539 540 "truetype", /* driver name */ 541 0x10000L, /* driver version == 1.0 */ 542 0x20000L, /* driver requires FreeType 2.0 or above */ 543 544 (void*)0, /* driver specific interface */ 545 546 tt_driver_init, 547 tt_driver_done, 548 tt_get_interface, 549 550 sizeof ( TT_FaceRec ), 551 sizeof ( TT_SizeRec ), 552 sizeof ( FT_GlyphSlotRec ), 553 554 tt_face_init, 555 tt_face_done, 556 tt_size_init, 557 tt_size_done, 558 tt_slot_init, 559 0, /* FT_Slot_DoneFunc */ 560 561 tt_glyph_load, 562 563 tt_get_kerning, 564 0, /* FT_Face_AttachFunc */ 565 tt_get_advances, 566 567 tt_size_request, 568 TT_SIZE_SELECT 569 ) 570 571 572 /* END */ 573