1 /***************************************************************************/ 2 /* */ 3 /* ttobjs.c */ 4 /* */ 5 /* Objects manager (body). */ 6 /* */ 7 /* Copyright 1996-2018 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_TRUETYPE_TAGS_H 23 #include FT_INTERNAL_SFNT_H 24 #include FT_DRIVER_H 25 26 #include "ttgload.h" 27 #include "ttpload.h" 28 29 #include "tterrors.h" 30 31 #ifdef TT_USE_BYTECODE_INTERPRETER 32 #include "ttinterp.h" 33 #endif 34 35 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 36 #include "ttgxvar.h" 37 #endif 38 39 /*************************************************************************/ 40 /* */ 41 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 42 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 43 /* messages during execution. */ 44 /* */ 45 #undef FT_COMPONENT 46 #define FT_COMPONENT trace_ttobjs 47 48 49 #ifdef TT_USE_BYTECODE_INTERPRETER 50 51 /*************************************************************************/ 52 /* */ 53 /* GLYPH ZONE FUNCTIONS */ 54 /* */ 55 /*************************************************************************/ 56 57 58 /*************************************************************************/ 59 /* */ 60 /* <Function> */ 61 /* tt_glyphzone_done */ 62 /* */ 63 /* <Description> */ 64 /* Deallocate a glyph zone. */ 65 /* */ 66 /* <Input> */ 67 /* zone :: A pointer to the target glyph zone. */ 68 /* */ 69 FT_LOCAL_DEF( void ) tt_glyphzone_done(TT_GlyphZone zone)70 tt_glyphzone_done( TT_GlyphZone zone ) 71 { 72 FT_Memory memory = zone->memory; 73 74 75 if ( memory ) 76 { 77 FT_FREE( zone->contours ); 78 FT_FREE( zone->tags ); 79 FT_FREE( zone->cur ); 80 FT_FREE( zone->org ); 81 FT_FREE( zone->orus ); 82 83 zone->max_points = zone->n_points = 0; 84 zone->max_contours = zone->n_contours = 0; 85 zone->memory = NULL; 86 } 87 } 88 89 90 /*************************************************************************/ 91 /* */ 92 /* <Function> */ 93 /* tt_glyphzone_new */ 94 /* */ 95 /* <Description> */ 96 /* Allocate a new glyph zone. */ 97 /* */ 98 /* <Input> */ 99 /* memory :: A handle to the current memory object. */ 100 /* */ 101 /* maxPoints :: The capacity of glyph zone in points. */ 102 /* */ 103 /* maxContours :: The capacity of glyph zone in contours. */ 104 /* */ 105 /* <Output> */ 106 /* zone :: A pointer to the target glyph zone record. */ 107 /* */ 108 /* <Return> */ 109 /* FreeType error code. 0 means success. */ 110 /* */ 111 FT_LOCAL_DEF( FT_Error ) tt_glyphzone_new(FT_Memory memory,FT_UShort maxPoints,FT_Short maxContours,TT_GlyphZone zone)112 tt_glyphzone_new( FT_Memory memory, 113 FT_UShort maxPoints, 114 FT_Short maxContours, 115 TT_GlyphZone zone ) 116 { 117 FT_Error error; 118 119 120 FT_ZERO( zone ); 121 zone->memory = memory; 122 123 if ( FT_NEW_ARRAY( zone->org, maxPoints ) || 124 FT_NEW_ARRAY( zone->cur, maxPoints ) || 125 FT_NEW_ARRAY( zone->orus, maxPoints ) || 126 FT_NEW_ARRAY( zone->tags, maxPoints ) || 127 FT_NEW_ARRAY( zone->contours, maxContours ) ) 128 { 129 tt_glyphzone_done( zone ); 130 } 131 else 132 { 133 zone->max_points = maxPoints; 134 zone->max_contours = maxContours; 135 } 136 137 return error; 138 } 139 #endif /* TT_USE_BYTECODE_INTERPRETER */ 140 141 142 /* Compare the face with a list of well-known `tricky' fonts. */ 143 /* This list shall be expanded as we find more of them. */ 144 145 static FT_Bool tt_check_trickyness_family(FT_String * name)146 tt_check_trickyness_family( FT_String* name ) 147 { 148 149 #define TRICK_NAMES_MAX_CHARACTERS 19 150 #define TRICK_NAMES_COUNT 23 151 152 static const char trick_names[TRICK_NAMES_COUNT] 153 [TRICK_NAMES_MAX_CHARACTERS + 1] = 154 { 155 /* 156 PostScript names are given in brackets if they differ from the 157 family name. The version numbers, together with the copyright or 158 release year data, are taken from fonts available to the 159 developers. 160 161 Note that later versions of the fonts might be no longer tricky; 162 for example, `MingLiU' version 7.00 (file `mingliu.ttc' from 163 Windows 7) is an ordinary TTC with non-tricky subfonts. 164 */ 165 166 "cpop", /* dftt-p7.ttf; version 1.00, 1992 [DLJGyShoMedium] */ 167 "DFGirl-W6-WIN-BF", /* dftt-h6.ttf; version 1.00, 1993 */ 168 "DFGothic-EB", /* DynaLab Inc. 1992-1995 */ 169 "DFGyoSho-Lt", /* DynaLab Inc. 1992-1995 */ 170 "DFHSGothic-W5", /* DynaLab Inc. 1992-1995 */ 171 "DFHSMincho-W3", /* DynaLab Inc. 1992-1995 */ 172 "DFHSMincho-W7", /* DynaLab Inc. 1992-1995 */ 173 "DFKaiSho-SB", /* dfkaisb.ttf */ 174 "DFKaiShu", 175 "DFKai-SB", /* kaiu.ttf; version 3.00, 1998 [DFKaiShu-SB-Estd-BF] */ 176 "DLC", /* dftt-m7.ttf; version 1.00, 1993 [DLCMingBold] */ 177 /* dftt-f5.ttf; version 1.00, 1993 [DLCFongSung] */ 178 "DLCHayMedium", /* dftt-b5.ttf; version 1.00, 1993 */ 179 "DLCHayBold", /* dftt-b7.ttf; version 1.00, 1993 */ 180 "DLCKaiMedium", /* dftt-k5.ttf; version 1.00, 1992 */ 181 "DLCLiShu", /* dftt-l5.ttf; version 1.00, 1992 */ 182 "DLCRoundBold", /* dftt-r7.ttf; version 1.00, 1993 */ 183 "HuaTianKaiTi?", /* htkt2.ttf */ 184 "HuaTianSongTi?", /* htst3.ttf */ 185 "Ming(for ISO10646)", /* hkscsiic.ttf; version 0.12, 2007 [Ming] */ 186 /* iicore.ttf; version 0.07, 2007 [Ming] */ 187 "MingLiU", /* mingliu.ttf */ 188 /* mingliu.ttc; version 3.21, 2001 */ 189 "MingMedium", /* dftt-m5.ttf; version 1.00, 1993 [DLCMingMedium] */ 190 "PMingLiU", /* mingliu.ttc; version 3.21, 2001 */ 191 "MingLi43", /* mingli.ttf; version 1.00, 1992 */ 192 }; 193 194 int nn; 195 196 197 for ( nn = 0; nn < TRICK_NAMES_COUNT; nn++ ) 198 if ( ft_strstr( name, trick_names[nn] ) ) 199 return TRUE; 200 201 return FALSE; 202 } 203 204 205 /* XXX: This function should be in the `sfnt' module. */ 206 207 /* Some PDF generators clear the checksums in the TrueType header table. */ 208 /* For example, Quartz ContextPDF clears all entries, or Bullzip PDF */ 209 /* Printer clears the entries for subsetted subtables. We thus have to */ 210 /* recalculate the checksums where necessary. */ 211 212 static FT_UInt32 tt_synth_sfnt_checksum(FT_Stream stream,FT_ULong length)213 tt_synth_sfnt_checksum( FT_Stream stream, 214 FT_ULong length ) 215 { 216 FT_Error error; 217 FT_UInt32 checksum = 0; 218 FT_UInt i; 219 220 221 if ( FT_FRAME_ENTER( length ) ) 222 return 0; 223 224 for ( ; length > 3; length -= 4 ) 225 checksum += (FT_UInt32)FT_GET_ULONG(); 226 227 for ( i = 3; length > 0; length--, i-- ) 228 checksum += (FT_UInt32)FT_GET_BYTE() << ( i * 8 ); 229 230 FT_FRAME_EXIT(); 231 232 return checksum; 233 } 234 235 236 /* XXX: This function should be in the `sfnt' module. */ 237 238 static FT_ULong tt_get_sfnt_checksum(TT_Face face,FT_UShort i)239 tt_get_sfnt_checksum( TT_Face face, 240 FT_UShort i ) 241 { 242 #if 0 /* if we believe the written value, use following part. */ 243 if ( face->dir_tables[i].CheckSum ) 244 return face->dir_tables[i].CheckSum; 245 #endif 246 247 if ( !face->goto_table ) 248 return 0; 249 250 if ( face->goto_table( face, 251 face->dir_tables[i].Tag, 252 face->root.stream, 253 NULL ) ) 254 return 0; 255 256 return (FT_ULong)tt_synth_sfnt_checksum( face->root.stream, 257 face->dir_tables[i].Length ); 258 } 259 260 261 typedef struct tt_sfnt_id_rec_ 262 { 263 FT_ULong CheckSum; 264 FT_ULong Length; 265 266 } tt_sfnt_id_rec; 267 268 269 static FT_Bool tt_check_trickyness_sfnt_ids(TT_Face face)270 tt_check_trickyness_sfnt_ids( TT_Face face ) 271 { 272 #define TRICK_SFNT_IDS_PER_FACE 3 273 #define TRICK_SFNT_IDS_NUM_FACES 26 274 275 static const tt_sfnt_id_rec sfnt_id[TRICK_SFNT_IDS_NUM_FACES] 276 [TRICK_SFNT_IDS_PER_FACE] = { 277 278 #define TRICK_SFNT_ID_cvt 0 279 #define TRICK_SFNT_ID_fpgm 1 280 #define TRICK_SFNT_ID_prep 2 281 282 { /* MingLiU 1995 */ 283 { 0x05BCF058UL, 0x000002E4UL }, /* cvt */ 284 { 0x28233BF1UL, 0x000087C4UL }, /* fpgm */ 285 { 0xA344A1EAUL, 0x000001E1UL } /* prep */ 286 }, 287 { /* MingLiU 1996- */ 288 { 0x05BCF058UL, 0x000002E4UL }, /* cvt */ 289 { 0x28233BF1UL, 0x000087C4UL }, /* fpgm */ 290 { 0xA344A1EBUL, 0x000001E1UL } /* prep */ 291 }, 292 { /* DFGothic-EB */ 293 { 0x12C3EBB2UL, 0x00000350UL }, /* cvt */ 294 { 0xB680EE64UL, 0x000087A7UL }, /* fpgm */ 295 { 0xCE939563UL, 0x00000758UL } /* prep */ 296 }, 297 { /* DFGyoSho-Lt */ 298 { 0x11E5EAD4UL, 0x00000350UL }, /* cvt */ 299 { 0xCE5956E9UL, 0x0000BC85UL }, /* fpgm */ 300 { 0x8272F416UL, 0x00000045UL } /* prep */ 301 }, 302 { /* DFHSGothic-W5 */ 303 { 0x1262EB4EUL, 0x00000350UL }, /* cvt */ 304 { 0xE86A5D64UL, 0x00007940UL }, /* fpgm */ 305 { 0x7850F729UL, 0x000005FFUL } /* prep */ 306 }, 307 { /* DFHSMincho-W3 */ 308 { 0x122DEB0AUL, 0x00000350UL }, /* cvt */ 309 { 0x3D16328AUL, 0x0000859BUL }, /* fpgm */ 310 { 0xA93FC33BUL, 0x000002CBUL } /* prep */ 311 }, 312 { /* DFHSMincho-W7 */ 313 { 0x125FEB26UL, 0x00000350UL }, /* cvt */ 314 { 0xA5ACC982UL, 0x00007EE1UL }, /* fpgm */ 315 { 0x90999196UL, 0x0000041FUL } /* prep */ 316 }, 317 { /* DFKaiShu */ 318 { 0x11E5EAD4UL, 0x00000350UL }, /* cvt */ 319 { 0x5A30CA3BUL, 0x00009063UL }, /* fpgm */ 320 { 0x13A42602UL, 0x0000007EUL } /* prep */ 321 }, 322 { /* DFKaiShu, variant */ 323 { 0x11E5EAD4UL, 0x00000350UL }, /* cvt */ 324 { 0xA6E78C01UL, 0x00008998UL }, /* fpgm */ 325 { 0x13A42602UL, 0x0000007EUL } /* prep */ 326 }, 327 { /* DLCLiShu */ 328 { 0x07DCF546UL, 0x00000308UL }, /* cvt */ 329 { 0x40FE7C90UL, 0x00008E2AUL }, /* fpgm */ 330 { 0x608174B5UL, 0x0000007AUL } /* prep */ 331 }, 332 { /* DLCHayBold */ 333 { 0xEB891238UL, 0x00000308UL }, /* cvt */ 334 { 0xD2E4DCD4UL, 0x0000676FUL }, /* fpgm */ 335 { 0x8EA5F293UL, 0x000003B8UL } /* prep */ 336 }, 337 { /* HuaTianKaiTi */ 338 { 0xFFFBFFFCUL, 0x00000008UL }, /* cvt */ 339 { 0x9C9E48B8UL, 0x0000BEA2UL }, /* fpgm */ 340 { 0x70020112UL, 0x00000008UL } /* prep */ 341 }, 342 { /* HuaTianSongTi */ 343 { 0xFFFBFFFCUL, 0x00000008UL }, /* cvt */ 344 { 0x0A5A0483UL, 0x00017C39UL }, /* fpgm */ 345 { 0x70020112UL, 0x00000008UL } /* prep */ 346 }, 347 { /* NEC fadpop7.ttf */ 348 { 0x00000000UL, 0x00000000UL }, /* cvt */ 349 { 0x40C92555UL, 0x000000E5UL }, /* fpgm */ 350 { 0xA39B58E3UL, 0x0000117CUL } /* prep */ 351 }, 352 { /* NEC fadrei5.ttf */ 353 { 0x00000000UL, 0x00000000UL }, /* cvt */ 354 { 0x33C41652UL, 0x000000E5UL }, /* fpgm */ 355 { 0x26D6C52AUL, 0x00000F6AUL } /* prep */ 356 }, 357 { /* NEC fangot7.ttf */ 358 { 0x00000000UL, 0x00000000UL }, /* cvt */ 359 { 0x6DB1651DUL, 0x0000019DUL }, /* fpgm */ 360 { 0x6C6E4B03UL, 0x00002492UL } /* prep */ 361 }, 362 { /* NEC fangyo5.ttf */ 363 { 0x00000000UL, 0x00000000UL }, /* cvt */ 364 { 0x40C92555UL, 0x000000E5UL }, /* fpgm */ 365 { 0xDE51FAD0UL, 0x0000117CUL } /* prep */ 366 }, 367 { /* NEC fankyo5.ttf */ 368 { 0x00000000UL, 0x00000000UL }, /* cvt */ 369 { 0x85E47664UL, 0x000000E5UL }, /* fpgm */ 370 { 0xA6C62831UL, 0x00001CAAUL } /* prep */ 371 }, 372 { /* NEC fanrgo5.ttf */ 373 { 0x00000000UL, 0x00000000UL }, /* cvt */ 374 { 0x2D891CFDUL, 0x0000019DUL }, /* fpgm */ 375 { 0xA0604633UL, 0x00001DE8UL } /* prep */ 376 }, 377 { /* NEC fangot5.ttc */ 378 { 0x00000000UL, 0x00000000UL }, /* cvt */ 379 { 0x40AA774CUL, 0x000001CBUL }, /* fpgm */ 380 { 0x9B5CAA96UL, 0x00001F9AUL } /* prep */ 381 }, 382 { /* NEC fanmin3.ttc */ 383 { 0x00000000UL, 0x00000000UL }, /* cvt */ 384 { 0x0D3DE9CBUL, 0x00000141UL }, /* fpgm */ 385 { 0xD4127766UL, 0x00002280UL } /* prep */ 386 }, 387 { /* NEC FA-Gothic, 1996 */ 388 { 0x00000000UL, 0x00000000UL }, /* cvt */ 389 { 0x4A692698UL, 0x000001F0UL }, /* fpgm */ 390 { 0x340D4346UL, 0x00001FCAUL } /* prep */ 391 }, 392 { /* NEC FA-Minchou, 1996 */ 393 { 0x00000000UL, 0x00000000UL }, /* cvt */ 394 { 0xCD34C604UL, 0x00000166UL }, /* fpgm */ 395 { 0x6CF31046UL, 0x000022B0UL } /* prep */ 396 }, 397 { /* NEC FA-RoundGothicB, 1996 */ 398 { 0x00000000UL, 0x00000000UL }, /* cvt */ 399 { 0x5DA75315UL, 0x0000019DUL }, /* fpgm */ 400 { 0x40745A5FUL, 0x000022E0UL } /* prep */ 401 }, 402 { /* NEC FA-RoundGothicM, 1996 */ 403 { 0x00000000UL, 0x00000000UL }, /* cvt */ 404 { 0xF055FC48UL, 0x000001C2UL }, /* fpgm */ 405 { 0x3900DED3UL, 0x00001E18UL } /* prep */ 406 }, 407 { /* MINGLI.TTF, 1992 */ 408 { 0x00170003UL, 0x00000060UL }, /* cvt */ 409 { 0xDBB4306EUL, 0x000058AAUL }, /* fpgm */ 410 { 0xD643482AUL, 0x00000035UL } /* prep */ 411 } 412 }; 413 414 FT_ULong checksum; 415 int num_matched_ids[TRICK_SFNT_IDS_NUM_FACES]; 416 FT_Bool has_cvt, has_fpgm, has_prep; 417 FT_UShort i; 418 int j, k; 419 420 421 FT_MEM_SET( num_matched_ids, 0, 422 sizeof ( int ) * TRICK_SFNT_IDS_NUM_FACES ); 423 has_cvt = FALSE; 424 has_fpgm = FALSE; 425 has_prep = FALSE; 426 427 for ( i = 0; i < face->num_tables; i++ ) 428 { 429 checksum = 0; 430 431 switch( face->dir_tables[i].Tag ) 432 { 433 case TTAG_cvt: 434 k = TRICK_SFNT_ID_cvt; 435 has_cvt = TRUE; 436 break; 437 438 case TTAG_fpgm: 439 k = TRICK_SFNT_ID_fpgm; 440 has_fpgm = TRUE; 441 break; 442 443 case TTAG_prep: 444 k = TRICK_SFNT_ID_prep; 445 has_prep = TRUE; 446 break; 447 448 default: 449 continue; 450 } 451 452 for ( j = 0; j < TRICK_SFNT_IDS_NUM_FACES; j++ ) 453 if ( face->dir_tables[i].Length == sfnt_id[j][k].Length ) 454 { 455 if ( !checksum ) 456 checksum = tt_get_sfnt_checksum( face, i ); 457 458 if ( sfnt_id[j][k].CheckSum == checksum ) 459 num_matched_ids[j]++; 460 461 if ( num_matched_ids[j] == TRICK_SFNT_IDS_PER_FACE ) 462 return TRUE; 463 } 464 } 465 466 for ( j = 0; j < TRICK_SFNT_IDS_NUM_FACES; j++ ) 467 { 468 if ( !has_cvt && !sfnt_id[j][TRICK_SFNT_ID_cvt].Length ) 469 num_matched_ids[j]++; 470 if ( !has_fpgm && !sfnt_id[j][TRICK_SFNT_ID_fpgm].Length ) 471 num_matched_ids[j]++; 472 if ( !has_prep && !sfnt_id[j][TRICK_SFNT_ID_prep].Length ) 473 num_matched_ids[j]++; 474 if ( num_matched_ids[j] == TRICK_SFNT_IDS_PER_FACE ) 475 return TRUE; 476 } 477 478 return FALSE; 479 } 480 481 482 static FT_Bool tt_check_trickyness(FT_Face face)483 tt_check_trickyness( FT_Face face ) 484 { 485 if ( !face ) 486 return FALSE; 487 488 /* For first, check the face name for quick check. */ 489 if ( face->family_name && 490 tt_check_trickyness_family( face->family_name ) ) 491 return TRUE; 492 493 /* Type42 fonts may lack `name' tables, we thus try to identify */ 494 /* tricky fonts by checking the checksums of Type42-persistent */ 495 /* sfnt tables (`cvt', `fpgm', and `prep'). */ 496 if ( tt_check_trickyness_sfnt_ids( (TT_Face)face ) ) 497 return TRUE; 498 499 return FALSE; 500 } 501 502 503 /* Check whether `.notdef' is the only glyph in the `loca' table. */ 504 static FT_Bool tt_check_single_notdef(FT_Face ttface)505 tt_check_single_notdef( FT_Face ttface ) 506 { 507 FT_Bool result = FALSE; 508 509 TT_Face face = (TT_Face)ttface; 510 FT_UInt asize; 511 FT_ULong i; 512 FT_ULong glyph_index = 0; 513 FT_UInt count = 0; 514 515 516 for( i = 0; i < face->num_locations; i++ ) 517 { 518 tt_face_get_location( face, i, &asize ); 519 if ( asize > 0 ) 520 { 521 count += 1; 522 if ( count > 1 ) 523 break; 524 glyph_index = i; 525 } 526 } 527 528 /* Only have a single outline. */ 529 if ( count == 1 ) 530 { 531 if ( glyph_index == 0 ) 532 result = TRUE; 533 else 534 { 535 /* FIXME: Need to test glyphname == .notdef ? */ 536 FT_Error error; 537 char buf[8]; 538 539 540 error = FT_Get_Glyph_Name( ttface, glyph_index, buf, 8 ); 541 if ( !error && 542 buf[0] == '.' && !ft_strncmp( buf, ".notdef", 8 ) ) 543 result = TRUE; 544 } 545 } 546 547 return result; 548 } 549 550 551 /*************************************************************************/ 552 /* */ 553 /* <Function> */ 554 /* tt_face_init */ 555 /* */ 556 /* <Description> */ 557 /* Initialize a given TrueType face object. */ 558 /* */ 559 /* <Input> */ 560 /* stream :: The source font stream. */ 561 /* */ 562 /* face_index :: The index of the TrueType font, if we are opening a */ 563 /* collection, in bits 0-15. The numbered instance */ 564 /* index~+~1 of a GX (sub)font, if applicable, in bits */ 565 /* 16-30. */ 566 /* */ 567 /* num_params :: Number of additional generic parameters. Ignored. */ 568 /* */ 569 /* params :: Additional generic parameters. Ignored. */ 570 /* */ 571 /* <InOut> */ 572 /* face :: The newly built face object. */ 573 /* */ 574 /* <Return> */ 575 /* FreeType error code. 0 means success. */ 576 /* */ 577 FT_LOCAL_DEF( FT_Error ) tt_face_init(FT_Stream stream,FT_Face ttface,FT_Int face_index,FT_Int num_params,FT_Parameter * params)578 tt_face_init( FT_Stream stream, 579 FT_Face ttface, /* TT_Face */ 580 FT_Int face_index, 581 FT_Int num_params, 582 FT_Parameter* params ) 583 { 584 FT_Error error; 585 FT_Library library; 586 SFNT_Service sfnt; 587 TT_Face face = (TT_Face)ttface; 588 589 590 FT_TRACE2(( "TTF driver\n" )); 591 592 library = ttface->driver->root.library; 593 594 sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" ); 595 if ( !sfnt ) 596 { 597 FT_ERROR(( "tt_face_init: cannot access `sfnt' module\n" )); 598 error = FT_THROW( Missing_Module ); 599 goto Exit; 600 } 601 602 /* create input stream from resource */ 603 if ( FT_STREAM_SEEK( 0 ) ) 604 goto Exit; 605 606 /* check that we have a valid TrueType file */ 607 FT_TRACE2(( " " )); 608 error = sfnt->init_face( stream, face, face_index, num_params, params ); 609 610 /* Stream may have changed. */ 611 stream = face->root.stream; 612 613 if ( error ) 614 goto Exit; 615 616 /* We must also be able to accept Mac/GX fonts, as well as OT ones. */ 617 /* The 0x00020000 tag is completely undocumented; some fonts from */ 618 /* Arphic made for Chinese Windows 3.1 have this. */ 619 if ( face->format_tag != 0x00010000L && /* MS fonts */ 620 face->format_tag != 0x00020000L && /* CJK fonts for Win 3.1 */ 621 face->format_tag != TTAG_true && /* Mac fonts */ 622 face->format_tag != TTAG_0xA5kbd && /* `Keyboard.dfont' (legacy Mac OS X) */ 623 face->format_tag != TTAG_0xA5lst ) /* `LastResort.dfont' (legacy Mac OS X) */ 624 { 625 FT_TRACE2(( " not a TTF font\n" )); 626 goto Bad_Format; 627 } 628 629 #ifdef TT_USE_BYTECODE_INTERPRETER 630 ttface->face_flags |= FT_FACE_FLAG_HINTER; 631 #endif 632 633 /* If we are performing a simple font format check, exit immediately. */ 634 if ( face_index < 0 ) 635 return FT_Err_Ok; 636 637 /* Load font directory */ 638 error = sfnt->load_face( stream, face, face_index, num_params, params ); 639 if ( error ) 640 goto Exit; 641 642 if ( tt_check_trickyness( ttface ) ) 643 ttface->face_flags |= FT_FACE_FLAG_TRICKY; 644 645 error = tt_face_load_hdmx( face, stream ); 646 if ( error ) 647 goto Exit; 648 649 if ( FT_IS_SCALABLE( ttface ) ) 650 { 651 #ifdef FT_CONFIG_OPTION_INCREMENTAL 652 if ( !ttface->internal->incremental_interface ) 653 #endif 654 { 655 error = tt_face_load_loca( face, stream ); 656 657 /* having a (non-zero) `glyf' table without */ 658 /* a `loca' table is not valid */ 659 if ( face->glyf_len && FT_ERR_EQ( error, Table_Missing ) ) 660 goto Exit; 661 if ( error ) 662 goto Exit; 663 } 664 665 /* `fpgm', `cvt', and `prep' are optional */ 666 error = tt_face_load_cvt( face, stream ); 667 if ( error && FT_ERR_NEQ( error, Table_Missing ) ) 668 goto Exit; 669 670 error = tt_face_load_fpgm( face, stream ); 671 if ( error && FT_ERR_NEQ( error, Table_Missing ) ) 672 goto Exit; 673 674 error = tt_face_load_prep( face, stream ); 675 if ( error && FT_ERR_NEQ( error, Table_Missing ) ) 676 goto Exit; 677 678 /* Check the scalable flag based on `loca'. */ 679 #ifdef FT_CONFIG_OPTION_INCREMENTAL 680 if ( !ttface->internal->incremental_interface ) 681 #endif 682 { 683 if ( ttface->num_fixed_sizes && 684 face->glyph_locations && 685 tt_check_single_notdef( ttface ) ) 686 { 687 FT_TRACE5(( "tt_face_init:" 688 " Only the `.notdef' glyph has an outline.\n" 689 " " 690 " Resetting scalable flag to FALSE.\n" )); 691 692 ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE; 693 } 694 } 695 } 696 697 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 698 699 { 700 FT_UInt instance_index = (FT_UInt)face_index >> 16; 701 702 703 if ( FT_HAS_MULTIPLE_MASTERS( ttface ) && 704 instance_index > 0 ) 705 { 706 error = TT_Set_Named_Instance( face, instance_index ); 707 if ( error ) 708 goto Exit; 709 710 tt_apply_mvar( face ); 711 } 712 } 713 714 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ 715 716 /* initialize standard glyph loading routines */ 717 TT_Init_Glyph_Loading( face ); 718 719 Exit: 720 return error; 721 722 Bad_Format: 723 error = FT_THROW( Unknown_File_Format ); 724 goto Exit; 725 } 726 727 728 /*************************************************************************/ 729 /* */ 730 /* <Function> */ 731 /* tt_face_done */ 732 /* */ 733 /* <Description> */ 734 /* Finalize a given face object. */ 735 /* */ 736 /* <Input> */ 737 /* face :: A pointer to the face object to destroy. */ 738 /* */ 739 FT_LOCAL_DEF( void ) tt_face_done(FT_Face ttface)740 tt_face_done( FT_Face ttface ) /* TT_Face */ 741 { 742 TT_Face face = (TT_Face)ttface; 743 FT_Memory memory; 744 FT_Stream stream; 745 SFNT_Service sfnt; 746 747 748 if ( !face ) 749 return; 750 751 memory = ttface->memory; 752 stream = ttface->stream; 753 sfnt = (SFNT_Service)face->sfnt; 754 755 /* for `extended TrueType formats' (i.e. compressed versions) */ 756 if ( face->extra.finalizer ) 757 face->extra.finalizer( face->extra.data ); 758 759 if ( sfnt ) 760 sfnt->done_face( face ); 761 762 /* freeing the locations table */ 763 tt_face_done_loca( face ); 764 765 tt_face_free_hdmx( face ); 766 767 /* freeing the CVT */ 768 FT_FREE( face->cvt ); 769 face->cvt_size = 0; 770 771 /* freeing the programs */ 772 FT_FRAME_RELEASE( face->font_program ); 773 FT_FRAME_RELEASE( face->cvt_program ); 774 face->font_program_size = 0; 775 face->cvt_program_size = 0; 776 777 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 778 tt_done_blend( face ); 779 face->blend = NULL; 780 #endif 781 } 782 783 784 /*************************************************************************/ 785 /* */ 786 /* SIZE FUNCTIONS */ 787 /* */ 788 /*************************************************************************/ 789 790 #ifdef TT_USE_BYTECODE_INTERPRETER 791 792 /*************************************************************************/ 793 /* */ 794 /* <Function> */ 795 /* tt_size_run_fpgm */ 796 /* */ 797 /* <Description> */ 798 /* Run the font program. */ 799 /* */ 800 /* <Input> */ 801 /* size :: A handle to the size object. */ 802 /* */ 803 /* pedantic :: Set if bytecode execution should be pedantic. */ 804 /* */ 805 /* <Return> */ 806 /* FreeType error code. 0 means success. */ 807 /* */ 808 FT_LOCAL_DEF( FT_Error ) tt_size_run_fpgm(TT_Size size,FT_Bool pedantic)809 tt_size_run_fpgm( TT_Size size, 810 FT_Bool pedantic ) 811 { 812 TT_Face face = (TT_Face)size->root.face; 813 TT_ExecContext exec; 814 FT_Error error; 815 816 817 exec = size->context; 818 819 error = TT_Load_Context( exec, face, size ); 820 if ( error ) 821 return error; 822 823 exec->callTop = 0; 824 exec->top = 0; 825 826 exec->period = 64; 827 exec->phase = 0; 828 exec->threshold = 0; 829 830 exec->instruction_trap = FALSE; 831 exec->F_dot_P = 0x4000L; 832 833 exec->pedantic_hinting = pedantic; 834 835 { 836 FT_Size_Metrics* size_metrics = &exec->metrics; 837 TT_Size_Metrics* tt_metrics = &exec->tt_metrics; 838 839 840 size_metrics->x_ppem = 0; 841 size_metrics->y_ppem = 0; 842 size_metrics->x_scale = 0; 843 size_metrics->y_scale = 0; 844 845 tt_metrics->ppem = 0; 846 tt_metrics->scale = 0; 847 tt_metrics->ratio = 0x10000L; 848 } 849 850 /* allow font program execution */ 851 TT_Set_CodeRange( exec, 852 tt_coderange_font, 853 face->font_program, 854 (FT_Long)face->font_program_size ); 855 856 /* disable CVT and glyph programs coderange */ 857 TT_Clear_CodeRange( exec, tt_coderange_cvt ); 858 TT_Clear_CodeRange( exec, tt_coderange_glyph ); 859 860 if ( face->font_program_size > 0 ) 861 { 862 TT_Goto_CodeRange( exec, tt_coderange_font, 0 ); 863 864 FT_TRACE4(( "Executing `fpgm' table.\n" )); 865 error = face->interpreter( exec ); 866 #ifdef FT_DEBUG_LEVEL_TRACE 867 if ( error ) 868 FT_TRACE4(( " interpretation failed with error code 0x%x\n", 869 error )); 870 #endif 871 } 872 else 873 error = FT_Err_Ok; 874 875 size->bytecode_ready = error; 876 877 if ( !error ) 878 TT_Save_Context( exec, size ); 879 880 return error; 881 } 882 883 884 /*************************************************************************/ 885 /* */ 886 /* <Function> */ 887 /* tt_size_run_prep */ 888 /* */ 889 /* <Description> */ 890 /* Run the control value program. */ 891 /* */ 892 /* <Input> */ 893 /* size :: A handle to the size object. */ 894 /* */ 895 /* pedantic :: Set if bytecode execution should be pedantic. */ 896 /* */ 897 /* <Return> */ 898 /* FreeType error code. 0 means success. */ 899 /* */ 900 FT_LOCAL_DEF( FT_Error ) tt_size_run_prep(TT_Size size,FT_Bool pedantic)901 tt_size_run_prep( TT_Size size, 902 FT_Bool pedantic ) 903 { 904 TT_Face face = (TT_Face)size->root.face; 905 TT_ExecContext exec; 906 FT_Error error; 907 908 909 exec = size->context; 910 911 error = TT_Load_Context( exec, face, size ); 912 if ( error ) 913 return error; 914 915 exec->callTop = 0; 916 exec->top = 0; 917 918 exec->instruction_trap = FALSE; 919 920 exec->pedantic_hinting = pedantic; 921 922 TT_Set_CodeRange( exec, 923 tt_coderange_cvt, 924 face->cvt_program, 925 (FT_Long)face->cvt_program_size ); 926 927 TT_Clear_CodeRange( exec, tt_coderange_glyph ); 928 929 if ( face->cvt_program_size > 0 ) 930 { 931 TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 ); 932 933 FT_TRACE4(( "Executing `prep' table.\n" )); 934 error = face->interpreter( exec ); 935 #ifdef FT_DEBUG_LEVEL_TRACE 936 if ( error ) 937 FT_TRACE4(( " interpretation failed with error code 0x%x\n", 938 error )); 939 #endif 940 } 941 else 942 error = FT_Err_Ok; 943 944 size->cvt_ready = error; 945 946 /* UNDOCUMENTED! The MS rasterizer doesn't allow the following */ 947 /* graphics state variables to be modified by the CVT program. */ 948 949 exec->GS.dualVector.x = 0x4000; 950 exec->GS.dualVector.y = 0; 951 exec->GS.projVector.x = 0x4000; 952 exec->GS.projVector.y = 0x0; 953 exec->GS.freeVector.x = 0x4000; 954 exec->GS.freeVector.y = 0x0; 955 956 exec->GS.rp0 = 0; 957 exec->GS.rp1 = 0; 958 exec->GS.rp2 = 0; 959 960 exec->GS.gep0 = 1; 961 exec->GS.gep1 = 1; 962 exec->GS.gep2 = 1; 963 964 exec->GS.loop = 1; 965 966 /* save as default graphics state */ 967 size->GS = exec->GS; 968 969 TT_Save_Context( exec, size ); 970 971 return error; 972 } 973 974 975 static void tt_size_done_bytecode(FT_Size ftsize)976 tt_size_done_bytecode( FT_Size ftsize ) 977 { 978 TT_Size size = (TT_Size)ftsize; 979 TT_Face face = (TT_Face)ftsize->face; 980 FT_Memory memory = face->root.memory; 981 982 if ( size->context ) 983 { 984 TT_Done_Context( size->context ); 985 size->context = NULL; 986 } 987 988 FT_FREE( size->cvt ); 989 size->cvt_size = 0; 990 991 /* free storage area */ 992 FT_FREE( size->storage ); 993 size->storage_size = 0; 994 995 /* twilight zone */ 996 tt_glyphzone_done( &size->twilight ); 997 998 FT_FREE( size->function_defs ); 999 FT_FREE( size->instruction_defs ); 1000 1001 size->num_function_defs = 0; 1002 size->max_function_defs = 0; 1003 size->num_instruction_defs = 0; 1004 size->max_instruction_defs = 0; 1005 1006 size->max_func = 0; 1007 size->max_ins = 0; 1008 1009 size->bytecode_ready = -1; 1010 size->cvt_ready = -1; 1011 } 1012 1013 1014 /* Initialize bytecode-related fields in the size object. */ 1015 /* We do this only if bytecode interpretation is really needed. */ 1016 static FT_Error tt_size_init_bytecode(FT_Size ftsize,FT_Bool pedantic)1017 tt_size_init_bytecode( FT_Size ftsize, 1018 FT_Bool pedantic ) 1019 { 1020 FT_Error error; 1021 TT_Size size = (TT_Size)ftsize; 1022 TT_Face face = (TT_Face)ftsize->face; 1023 FT_Memory memory = face->root.memory; 1024 1025 FT_UShort n_twilight; 1026 TT_MaxProfile* maxp = &face->max_profile; 1027 1028 1029 /* clean up bytecode related data */ 1030 FT_FREE( size->function_defs ); 1031 FT_FREE( size->instruction_defs ); 1032 FT_FREE( size->cvt ); 1033 FT_FREE( size->storage ); 1034 1035 if ( size->context ) 1036 TT_Done_Context( size->context ); 1037 tt_glyphzone_done( &size->twilight ); 1038 1039 size->bytecode_ready = -1; 1040 size->cvt_ready = -1; 1041 1042 size->context = TT_New_Context( (TT_Driver)face->root.driver ); 1043 1044 size->max_function_defs = maxp->maxFunctionDefs; 1045 size->max_instruction_defs = maxp->maxInstructionDefs; 1046 1047 size->num_function_defs = 0; 1048 size->num_instruction_defs = 0; 1049 1050 size->max_func = 0; 1051 size->max_ins = 0; 1052 1053 size->cvt_size = face->cvt_size; 1054 size->storage_size = maxp->maxStorage; 1055 1056 /* Set default metrics */ 1057 { 1058 TT_Size_Metrics* tt_metrics = &size->ttmetrics; 1059 1060 1061 tt_metrics->rotated = FALSE; 1062 tt_metrics->stretched = FALSE; 1063 1064 /* set default engine compensation */ 1065 tt_metrics->compensations[0] = 0; /* gray */ 1066 tt_metrics->compensations[1] = 0; /* black */ 1067 tt_metrics->compensations[2] = 0; /* white */ 1068 tt_metrics->compensations[3] = 0; /* reserved */ 1069 } 1070 1071 /* allocate function defs, instruction defs, cvt, and storage area */ 1072 if ( FT_NEW_ARRAY( size->function_defs, size->max_function_defs ) || 1073 FT_NEW_ARRAY( size->instruction_defs, size->max_instruction_defs ) || 1074 FT_NEW_ARRAY( size->cvt, size->cvt_size ) || 1075 FT_NEW_ARRAY( size->storage, size->storage_size ) ) 1076 goto Exit; 1077 1078 /* reserve twilight zone */ 1079 n_twilight = maxp->maxTwilightPoints; 1080 1081 /* there are 4 phantom points (do we need this?) */ 1082 n_twilight += 4; 1083 1084 error = tt_glyphzone_new( memory, n_twilight, 0, &size->twilight ); 1085 if ( error ) 1086 goto Exit; 1087 1088 size->twilight.n_points = n_twilight; 1089 1090 size->GS = tt_default_graphics_state; 1091 1092 /* set `face->interpreter' according to the debug hook present */ 1093 { 1094 FT_Library library = face->root.driver->root.library; 1095 1096 1097 face->interpreter = (TT_Interpreter) 1098 library->debug_hooks[FT_DEBUG_HOOK_TRUETYPE]; 1099 if ( !face->interpreter ) 1100 face->interpreter = (TT_Interpreter)TT_RunIns; 1101 } 1102 1103 /* Fine, now run the font program! */ 1104 1105 /* In case of an error while executing `fpgm', we intentionally don't */ 1106 /* clean up immediately – bugs in the `fpgm' are so fundamental that */ 1107 /* all following hinting calls should fail. Additionally, `fpgm' is */ 1108 /* to be executed just once; calling it again is completely useless */ 1109 /* and might even lead to extremely slow behaviour if it is malformed */ 1110 /* (containing an infinite loop, for example). */ 1111 error = tt_size_run_fpgm( size, pedantic ); 1112 return error; 1113 1114 Exit: 1115 if ( error ) 1116 tt_size_done_bytecode( ftsize ); 1117 1118 return error; 1119 } 1120 1121 1122 FT_LOCAL_DEF( FT_Error ) tt_size_ready_bytecode(TT_Size size,FT_Bool pedantic)1123 tt_size_ready_bytecode( TT_Size size, 1124 FT_Bool pedantic ) 1125 { 1126 FT_Error error = FT_Err_Ok; 1127 1128 1129 if ( size->bytecode_ready < 0 ) 1130 error = tt_size_init_bytecode( (FT_Size)size, pedantic ); 1131 else 1132 error = size->bytecode_ready; 1133 1134 if ( error ) 1135 goto Exit; 1136 1137 /* rescale CVT when needed */ 1138 if ( size->cvt_ready < 0 ) 1139 { 1140 FT_UInt i; 1141 TT_Face face = (TT_Face)size->root.face; 1142 1143 1144 /* Scale the cvt values to the new ppem. */ 1145 /* We use by default the y ppem to scale the CVT. */ 1146 for ( i = 0; i < size->cvt_size; i++ ) 1147 size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale ); 1148 1149 /* all twilight points are originally zero */ 1150 for ( i = 0; i < (FT_UInt)size->twilight.n_points; i++ ) 1151 { 1152 size->twilight.org[i].x = 0; 1153 size->twilight.org[i].y = 0; 1154 size->twilight.cur[i].x = 0; 1155 size->twilight.cur[i].y = 0; 1156 } 1157 1158 /* clear storage area */ 1159 for ( i = 0; i < (FT_UInt)size->storage_size; i++ ) 1160 size->storage[i] = 0; 1161 1162 size->GS = tt_default_graphics_state; 1163 1164 error = tt_size_run_prep( size, pedantic ); 1165 } 1166 else 1167 error = size->cvt_ready; 1168 1169 Exit: 1170 return error; 1171 } 1172 1173 #endif /* TT_USE_BYTECODE_INTERPRETER */ 1174 1175 1176 /*************************************************************************/ 1177 /* */ 1178 /* <Function> */ 1179 /* tt_size_init */ 1180 /* */ 1181 /* <Description> */ 1182 /* Initialize a new TrueType size object. */ 1183 /* */ 1184 /* <InOut> */ 1185 /* size :: A handle to the size object. */ 1186 /* */ 1187 /* <Return> */ 1188 /* FreeType error code. 0 means success. */ 1189 /* */ 1190 FT_LOCAL_DEF( FT_Error ) tt_size_init(FT_Size ttsize)1191 tt_size_init( FT_Size ttsize ) /* TT_Size */ 1192 { 1193 TT_Size size = (TT_Size)ttsize; 1194 FT_Error error = FT_Err_Ok; 1195 1196 1197 #ifdef TT_USE_BYTECODE_INTERPRETER 1198 size->bytecode_ready = -1; 1199 size->cvt_ready = -1; 1200 #endif 1201 1202 size->ttmetrics.valid = FALSE; 1203 size->strike_index = 0xFFFFFFFFUL; 1204 1205 return error; 1206 } 1207 1208 1209 /*************************************************************************/ 1210 /* */ 1211 /* <Function> */ 1212 /* tt_size_done */ 1213 /* */ 1214 /* <Description> */ 1215 /* The TrueType size object finalizer. */ 1216 /* */ 1217 /* <Input> */ 1218 /* size :: A handle to the target size object. */ 1219 /* */ 1220 FT_LOCAL_DEF( void ) tt_size_done(FT_Size ttsize)1221 tt_size_done( FT_Size ttsize ) /* TT_Size */ 1222 { 1223 TT_Size size = (TT_Size)ttsize; 1224 1225 1226 #ifdef TT_USE_BYTECODE_INTERPRETER 1227 tt_size_done_bytecode( ttsize ); 1228 #endif 1229 1230 size->ttmetrics.valid = FALSE; 1231 } 1232 1233 1234 /*************************************************************************/ 1235 /* */ 1236 /* <Function> */ 1237 /* tt_size_reset */ 1238 /* */ 1239 /* <Description> */ 1240 /* Reset a TrueType size when resolutions and character dimensions */ 1241 /* have been changed. */ 1242 /* */ 1243 /* <Input> */ 1244 /* size :: A handle to the target size object. */ 1245 /* */ 1246 /* only_height :: Only recompute ascender, descender, and height; */ 1247 /* this flag is used for variation fonts where */ 1248 /* `tt_size_reset' is used as an iterator function. */ 1249 /* */ 1250 FT_LOCAL_DEF( FT_Error ) tt_size_reset(TT_Size size,FT_Bool only_height)1251 tt_size_reset( TT_Size size, 1252 FT_Bool only_height ) 1253 { 1254 TT_Face face; 1255 FT_Size_Metrics* size_metrics; 1256 1257 1258 face = (TT_Face)size->root.face; 1259 1260 /* nothing to do for CFF2 */ 1261 if ( face->is_cff2 ) 1262 return FT_Err_Ok; 1263 1264 size->ttmetrics.valid = FALSE; 1265 1266 size_metrics = &size->hinted_metrics; 1267 1268 /* copy the result from base layer */ 1269 *size_metrics = size->root.metrics; 1270 1271 if ( size_metrics->x_ppem < 1 || size_metrics->y_ppem < 1 ) 1272 return FT_THROW( Invalid_PPem ); 1273 1274 /* This bit flag, if set, indicates that the ppems must be */ 1275 /* rounded to integers. Nearly all TrueType fonts have this bit */ 1276 /* set, as hinting won't work really well otherwise. */ 1277 /* */ 1278 if ( face->header.Flags & 8 ) 1279 { 1280 /* the TT spec always asks for ROUND, not FLOOR or CEIL */ 1281 size_metrics->ascender = FT_PIX_ROUND( 1282 FT_MulFix( face->root.ascender, 1283 size_metrics->y_scale ) ); 1284 size_metrics->descender = FT_PIX_ROUND( 1285 FT_MulFix( face->root.descender, 1286 size_metrics->y_scale ) ); 1287 size_metrics->height = FT_PIX_ROUND( 1288 FT_MulFix( face->root.height, 1289 size_metrics->y_scale ) ); 1290 } 1291 1292 size->ttmetrics.valid = TRUE; 1293 1294 if ( only_height ) 1295 { 1296 /* we must not recompute the scaling values here since */ 1297 /* `tt_size_reset' was already called (with only_height = 0) */ 1298 return FT_Err_Ok; 1299 } 1300 1301 if ( face->header.Flags & 8 ) 1302 { 1303 /* base scaling values on integer ppem values, */ 1304 /* as mandated by the TrueType specification */ 1305 size_metrics->x_scale = FT_DivFix( size_metrics->x_ppem << 6, 1306 face->root.units_per_EM ); 1307 size_metrics->y_scale = FT_DivFix( size_metrics->y_ppem << 6, 1308 face->root.units_per_EM ); 1309 1310 size_metrics->max_advance = FT_PIX_ROUND( 1311 FT_MulFix( face->root.max_advance_width, 1312 size_metrics->x_scale ) ); 1313 } 1314 1315 /* compute new transformation */ 1316 if ( size_metrics->x_ppem >= size_metrics->y_ppem ) 1317 { 1318 size->ttmetrics.scale = size_metrics->x_scale; 1319 size->ttmetrics.ppem = size_metrics->x_ppem; 1320 size->ttmetrics.x_ratio = 0x10000L; 1321 size->ttmetrics.y_ratio = FT_DivFix( size_metrics->y_ppem, 1322 size_metrics->x_ppem ); 1323 } 1324 else 1325 { 1326 size->ttmetrics.scale = size_metrics->y_scale; 1327 size->ttmetrics.ppem = size_metrics->y_ppem; 1328 size->ttmetrics.x_ratio = FT_DivFix( size_metrics->x_ppem, 1329 size_metrics->y_ppem ); 1330 size->ttmetrics.y_ratio = 0x10000L; 1331 } 1332 1333 size->metrics = size_metrics; 1334 1335 #ifdef TT_USE_BYTECODE_INTERPRETER 1336 size->cvt_ready = -1; 1337 #endif /* TT_USE_BYTECODE_INTERPRETER */ 1338 1339 return FT_Err_Ok; 1340 } 1341 1342 1343 /*************************************************************************/ 1344 /* */ 1345 /* <Function> */ 1346 /* tt_driver_init */ 1347 /* */ 1348 /* <Description> */ 1349 /* Initialize a given TrueType driver object. */ 1350 /* */ 1351 /* <Input> */ 1352 /* driver :: A handle to the target driver object. */ 1353 /* */ 1354 /* <Return> */ 1355 /* FreeType error code. 0 means success. */ 1356 /* */ 1357 FT_LOCAL_DEF( FT_Error ) tt_driver_init(FT_Module ttdriver)1358 tt_driver_init( FT_Module ttdriver ) /* TT_Driver */ 1359 { 1360 1361 #ifdef TT_USE_BYTECODE_INTERPRETER 1362 1363 TT_Driver driver = (TT_Driver)ttdriver; 1364 1365 driver->interpreter_version = TT_INTERPRETER_VERSION_35; 1366 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY 1367 driver->interpreter_version = TT_INTERPRETER_VERSION_38; 1368 #endif 1369 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL 1370 driver->interpreter_version = TT_INTERPRETER_VERSION_40; 1371 #endif 1372 1373 #else /* !TT_USE_BYTECODE_INTERPRETER */ 1374 1375 FT_UNUSED( ttdriver ); 1376 1377 #endif /* !TT_USE_BYTECODE_INTERPRETER */ 1378 1379 return FT_Err_Ok; 1380 } 1381 1382 1383 /*************************************************************************/ 1384 /* */ 1385 /* <Function> */ 1386 /* tt_driver_done */ 1387 /* */ 1388 /* <Description> */ 1389 /* Finalize a given TrueType driver. */ 1390 /* */ 1391 /* <Input> */ 1392 /* driver :: A handle to the target TrueType driver. */ 1393 /* */ 1394 FT_LOCAL_DEF( void ) tt_driver_done(FT_Module ttdriver)1395 tt_driver_done( FT_Module ttdriver ) /* TT_Driver */ 1396 { 1397 FT_UNUSED( ttdriver ); 1398 } 1399 1400 1401 /*************************************************************************/ 1402 /* */ 1403 /* <Function> */ 1404 /* tt_slot_init */ 1405 /* */ 1406 /* <Description> */ 1407 /* Initialize a new slot object. */ 1408 /* */ 1409 /* <InOut> */ 1410 /* slot :: A handle to the slot object. */ 1411 /* */ 1412 /* <Return> */ 1413 /* FreeType error code. 0 means success. */ 1414 /* */ 1415 FT_LOCAL_DEF( FT_Error ) tt_slot_init(FT_GlyphSlot slot)1416 tt_slot_init( FT_GlyphSlot slot ) 1417 { 1418 return FT_GlyphLoader_CreateExtra( slot->internal->loader ); 1419 } 1420 1421 1422 /* END */ 1423