1 /***************************************************************************/ 2 /* */ 3 /* ttdriver.c */ 4 /* */ 5 /* TrueType font driver implementation (body). */ 6 /* */ 7 /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 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_TRUETYPE_IDS_H 24 #include FT_SERVICE_XFREE86_NAME_H 25 26 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 27 #include FT_MULTIPLE_MASTERS_H 28 #include FT_SERVICE_MULTIPLE_MASTERS_H 29 #endif 30 31 #include FT_SERVICE_TRUETYPE_ENGINE_H 32 #include FT_SERVICE_TRUETYPE_GLYF_H 33 34 #include "ttdriver.h" 35 #include "ttgload.h" 36 #include "ttpload.h" 37 38 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 39 #include "ttgxvar.h" 40 #endif 41 42 #include "tterrors.h" 43 44 45 /*************************************************************************/ 46 /* */ 47 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 48 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 49 /* messages during execution. */ 50 /* */ 51 #undef FT_COMPONENT 52 #define FT_COMPONENT trace_ttdriver 53 54 55 /*************************************************************************/ 56 /*************************************************************************/ 57 /*************************************************************************/ 58 /**** ****/ 59 /**** ****/ 60 /**** F A C E S ****/ 61 /**** ****/ 62 /**** ****/ 63 /*************************************************************************/ 64 /*************************************************************************/ 65 /*************************************************************************/ 66 67 68 #undef PAIR_TAG 69 #define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \ 70 (FT_ULong)right ) 71 72 73 /*************************************************************************/ 74 /* */ 75 /* <Function> */ 76 /* tt_get_kerning */ 77 /* */ 78 /* <Description> */ 79 /* A driver method used to return the kerning vector between two */ 80 /* glyphs of the same face. */ 81 /* */ 82 /* <Input> */ 83 /* face :: A handle to the source face object. */ 84 /* */ 85 /* left_glyph :: The index of the left glyph in the kern pair. */ 86 /* */ 87 /* right_glyph :: The index of the right glyph in the kern pair. */ 88 /* */ 89 /* <Output> */ 90 /* kerning :: The kerning vector. This is in font units for */ 91 /* scalable formats, and in pixels for fixed-sizes */ 92 /* formats. */ 93 /* */ 94 /* <Return> */ 95 /* FreeType error code. 0 means success. */ 96 /* */ 97 /* <Note> */ 98 /* Only horizontal layouts (left-to-right & right-to-left) are */ 99 /* supported by this function. Other layouts, or more sophisticated */ 100 /* kernings, are out of scope of this method (the basic driver */ 101 /* interface is meant to be simple). */ 102 /* */ 103 /* They can be implemented by format-specific interfaces. */ 104 /* */ 105 static FT_Error tt_get_kerning(FT_Face ttface,FT_UInt left_glyph,FT_UInt right_glyph,FT_Vector * kerning)106 tt_get_kerning( FT_Face ttface, /* TT_Face */ 107 FT_UInt left_glyph, 108 FT_UInt right_glyph, 109 FT_Vector* kerning ) 110 { 111 TT_Face face = (TT_Face)ttface; 112 SFNT_Service sfnt = (SFNT_Service)face->sfnt; 113 114 115 kerning->x = 0; 116 kerning->y = 0; 117 118 if ( sfnt ) 119 kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph ); 120 121 return 0; 122 } 123 124 125 #undef PAIR_TAG 126 127 128 static FT_Error tt_get_advances(FT_Face ttface,FT_UInt start,FT_UInt count,FT_Int32 flags,FT_Fixed * advances)129 tt_get_advances( FT_Face ttface, 130 FT_UInt start, 131 FT_UInt count, 132 FT_Int32 flags, 133 FT_Fixed *advances ) 134 { 135 FT_UInt nn; 136 TT_Face face = (TT_Face) ttface; 137 FT_Bool check = FT_BOOL( 138 !( flags & FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ) ); 139 140 141 /* XXX: TODO: check for sbits */ 142 143 if ( flags & FT_LOAD_VERTICAL_LAYOUT ) 144 { 145 for ( nn = 0; nn < count; nn++ ) 146 { 147 FT_Short tsb; 148 FT_UShort ah; 149 150 151 TT_Get_VMetrics( face, start + nn, check, &tsb, &ah ); 152 advances[nn] = ah; 153 } 154 } 155 else 156 { 157 for ( nn = 0; nn < count; nn++ ) 158 { 159 FT_Short lsb; 160 FT_UShort aw; 161 162 163 TT_Get_HMetrics( face, start + nn, check, &lsb, &aw ); 164 advances[nn] = aw; 165 } 166 } 167 168 return TT_Err_Ok; 169 } 170 171 /*************************************************************************/ 172 /*************************************************************************/ 173 /*************************************************************************/ 174 /**** ****/ 175 /**** ****/ 176 /**** S I Z E S ****/ 177 /**** ****/ 178 /**** ****/ 179 /*************************************************************************/ 180 /*************************************************************************/ 181 /*************************************************************************/ 182 183 184 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS 185 186 static FT_Error tt_size_select(FT_Size size,FT_ULong strike_index)187 tt_size_select( FT_Size size, 188 FT_ULong strike_index ) 189 { 190 TT_Face ttface = (TT_Face)size->face; 191 TT_Size ttsize = (TT_Size)size; 192 FT_Error error = TT_Err_Ok; 193 194 195 ttsize->strike_index = strike_index; 196 197 if ( FT_IS_SCALABLE( size->face ) ) 198 { 199 /* use the scaled metrics, even when tt_size_reset fails */ 200 FT_Select_Metrics( size->face, strike_index ); 201 202 tt_size_reset( ttsize ); 203 } 204 else 205 { 206 SFNT_Service sfnt = (SFNT_Service) ttface->sfnt; 207 FT_Size_Metrics* metrics = &size->metrics; 208 209 210 error = sfnt->load_strike_metrics( ttface, strike_index, metrics ); 211 if ( error ) 212 ttsize->strike_index = 0xFFFFFFFFUL; 213 } 214 215 return error; 216 } 217 218 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ 219 220 221 static FT_Error tt_size_request(FT_Size size,FT_Size_Request req)222 tt_size_request( FT_Size size, 223 FT_Size_Request req ) 224 { 225 TT_Size ttsize = (TT_Size)size; 226 FT_Error error = TT_Err_Ok; 227 228 229 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS 230 231 if ( FT_HAS_FIXED_SIZES( size->face ) ) 232 { 233 TT_Face ttface = (TT_Face)size->face; 234 SFNT_Service sfnt = (SFNT_Service) ttface->sfnt; 235 FT_ULong strike_index; 236 237 238 error = sfnt->set_sbit_strike( ttface, req, &strike_index ); 239 240 if ( error ) 241 ttsize->strike_index = 0xFFFFFFFFUL; 242 else 243 return tt_size_select( size, strike_index ); 244 } 245 246 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ 247 248 FT_Request_Metrics( size->face, req ); 249 250 if ( FT_IS_SCALABLE( size->face ) ) 251 error = tt_size_reset( ttsize ); 252 253 return error; 254 } 255 256 257 /*************************************************************************/ 258 /* */ 259 /* <Function> */ 260 /* Load_Glyph */ 261 /* */ 262 /* <Description> */ 263 /* A driver method used to load a glyph within a given glyph slot. */ 264 /* */ 265 /* <Input> */ 266 /* slot :: A handle to the target slot object where the glyph */ 267 /* will be loaded. */ 268 /* */ 269 /* size :: A handle to the source face size at which the glyph */ 270 /* must be scaled, loaded, etc. */ 271 /* */ 272 /* glyph_index :: The index of the glyph in the font file. */ 273 /* */ 274 /* load_flags :: A flag indicating what to load for this glyph. The */ 275 /* FT_LOAD_XXX constants can be used to control the */ 276 /* glyph loading process (e.g., whether the outline */ 277 /* should be scaled, whether to load bitmaps or not, */ 278 /* whether to hint the outline, etc). */ 279 /* */ 280 /* <Return> */ 281 /* FreeType error code. 0 means success. */ 282 /* */ 283 static FT_Error Load_Glyph(FT_GlyphSlot ttslot,FT_Size ttsize,FT_UInt glyph_index,FT_Int32 load_flags)284 Load_Glyph( FT_GlyphSlot ttslot, /* TT_GlyphSlot */ 285 FT_Size ttsize, /* TT_Size */ 286 FT_UInt glyph_index, 287 FT_Int32 load_flags ) 288 { 289 TT_GlyphSlot slot = (TT_GlyphSlot)ttslot; 290 TT_Size size = (TT_Size)ttsize; 291 FT_Face face = ttslot->face; 292 FT_Error error; 293 294 295 if ( !slot ) 296 return TT_Err_Invalid_Slot_Handle; 297 298 if ( !size ) 299 return TT_Err_Invalid_Size_Handle; 300 301 if ( !face || glyph_index >= (FT_UInt)face->num_glyphs ) 302 return TT_Err_Invalid_Argument; 303 304 if ( load_flags & FT_LOAD_NO_HINTING ) 305 { 306 /* both FT_LOAD_NO_HINTING and FT_LOAD_NO_AUTOHINT */ 307 /* are necessary to disable hinting for tricky fonts */ 308 309 if ( FT_IS_TRICKY( face ) ) 310 load_flags &= ~FT_LOAD_NO_HINTING; 311 312 if ( load_flags & FT_LOAD_NO_AUTOHINT ) 313 load_flags |= FT_LOAD_NO_HINTING; 314 } 315 316 if ( load_flags & ( FT_LOAD_NO_RECURSE | FT_LOAD_NO_SCALE ) ) 317 { 318 load_flags |= FT_LOAD_NO_BITMAP | FT_LOAD_NO_SCALE; 319 320 if ( !FT_IS_TRICKY( face ) ) 321 load_flags |= FT_LOAD_NO_HINTING; 322 } 323 324 /* now load the glyph outline if necessary */ 325 error = TT_Load_Glyph( size, slot, glyph_index, load_flags ); 326 327 /* force drop-out mode to 2 - irrelevant now */ 328 /* slot->outline.dropout_mode = 2; */ 329 330 return error; 331 } 332 333 334 /*************************************************************************/ 335 /*************************************************************************/ 336 /*************************************************************************/ 337 /**** ****/ 338 /**** ****/ 339 /**** D R I V E R I N T E R F A C E ****/ 340 /**** ****/ 341 /**** ****/ 342 /*************************************************************************/ 343 /*************************************************************************/ 344 /*************************************************************************/ 345 346 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 347 static const FT_Service_MultiMastersRec tt_service_gx_multi_masters = 348 { 349 (FT_Get_MM_Func) NULL, 350 (FT_Set_MM_Design_Func) NULL, 351 (FT_Set_MM_Blend_Func) TT_Set_MM_Blend, 352 (FT_Get_MM_Var_Func) TT_Get_MM_Var, 353 (FT_Set_Var_Design_Func)TT_Set_Var_Design 354 }; 355 #endif 356 357 static const FT_Service_TrueTypeEngineRec tt_service_truetype_engine = 358 { 359 #ifdef TT_USE_BYTECODE_INTERPRETER 360 361 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING 362 FT_TRUETYPE_ENGINE_TYPE_UNPATENTED 363 #else 364 FT_TRUETYPE_ENGINE_TYPE_PATENTED 365 #endif 366 367 #else /* !TT_USE_BYTECODE_INTERPRETER */ 368 369 FT_TRUETYPE_ENGINE_TYPE_NONE 370 371 #endif /* TT_USE_BYTECODE_INTERPRETER */ 372 }; 373 374 static const FT_Service_TTGlyfRec tt_service_truetype_glyf = 375 { 376 (TT_Glyf_GetLocationFunc)tt_face_get_location 377 }; 378 379 static const FT_ServiceDescRec tt_services[] = 380 { 381 { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE }, 382 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 383 { FT_SERVICE_ID_MULTI_MASTERS, &tt_service_gx_multi_masters }, 384 #endif 385 { FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine }, 386 { FT_SERVICE_ID_TT_GLYF, &tt_service_truetype_glyf }, 387 { NULL, NULL } 388 }; 389 390 391 FT_CALLBACK_DEF( FT_Module_Interface ) tt_get_interface(FT_Module driver,const char * tt_interface)392 tt_get_interface( FT_Module driver, /* TT_Driver */ 393 const char* tt_interface ) 394 { 395 FT_Module_Interface result; 396 FT_Module sfntd; 397 SFNT_Service sfnt; 398 399 400 result = ft_service_list_lookup( tt_services, tt_interface ); 401 if ( result != NULL ) 402 return result; 403 404 /* only return the default interface from the SFNT module */ 405 sfntd = FT_Get_Module( driver->library, "sfnt" ); 406 if ( sfntd ) 407 { 408 sfnt = (SFNT_Service)( sfntd->clazz->module_interface ); 409 if ( sfnt ) 410 return sfnt->get_interface( driver, tt_interface ); 411 } 412 413 return 0; 414 } 415 416 417 /* The FT_DriverInterface structure is defined in ftdriver.h. */ 418 419 FT_CALLBACK_TABLE_DEF 420 const FT_Driver_ClassRec tt_driver_class = 421 { 422 { 423 FT_MODULE_FONT_DRIVER | 424 FT_MODULE_DRIVER_SCALABLE | 425 #ifdef TT_USE_BYTECODE_INTERPRETER 426 FT_MODULE_DRIVER_HAS_HINTER, 427 #else 428 0, 429 #endif 430 431 sizeof ( TT_DriverRec ), 432 433 "truetype", /* driver name */ 434 0x10000L, /* driver version == 1.0 */ 435 0x20000L, /* driver requires FreeType 2.0 or above */ 436 437 (void*)0, /* driver specific interface */ 438 439 tt_driver_init, 440 tt_driver_done, 441 tt_get_interface, 442 }, 443 444 sizeof ( TT_FaceRec ), 445 sizeof ( TT_SizeRec ), 446 sizeof ( FT_GlyphSlotRec ), 447 448 tt_face_init, 449 tt_face_done, 450 tt_size_init, 451 tt_size_done, 452 tt_slot_init, 453 0, /* FT_Slot_DoneFunc */ 454 455 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS 456 ft_stub_set_char_sizes, 457 ft_stub_set_pixel_sizes, 458 #endif 459 Load_Glyph, 460 461 tt_get_kerning, 462 0, /* FT_Face_AttachFunc */ 463 tt_get_advances, 464 465 tt_size_request, 466 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS 467 tt_size_select 468 #else 469 0 /* FT_Size_SelectFunc */ 470 #endif 471 }; 472 473 474 /* END */ 475