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