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