1 /**************************************************************************** 2 * 3 * ttobjs.c 4 * 5 * Objects manager (body). 6 * 7 * Copyright (C) 1996-2019 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 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(const FT_String * name)151 tt_check_trickyness_family( const 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 FT_UInt i; 941 942 /* unscaled CVT values are already stored in 26.6 format */ 943 FT_Fixed scale = size->ttmetrics.scale >> 6; 944 945 946 /* Scale the cvt values to the new ppem. */ 947 /* By default, we use the y ppem value for scaling. */ 948 FT_TRACE6(( "CVT values:\n" )); 949 for ( i = 0; i < size->cvt_size; i++ ) 950 { 951 size->cvt[i] = FT_MulFix( face->cvt[i], scale ); 952 FT_TRACE6(( " %3d: %f (%f)\n", 953 i, face->cvt[i] / 64.0, size->cvt[i] / 64.0 )); 954 } 955 FT_TRACE6(( "\n" )); 956 957 exec = size->context; 958 959 error = TT_Load_Context( exec, face, size ); 960 if ( error ) 961 return error; 962 963 exec->callTop = 0; 964 exec->top = 0; 965 966 exec->instruction_trap = FALSE; 967 968 exec->pedantic_hinting = pedantic; 969 970 TT_Set_CodeRange( exec, 971 tt_coderange_cvt, 972 face->cvt_program, 973 (FT_Long)face->cvt_program_size ); 974 975 TT_Clear_CodeRange( exec, tt_coderange_glyph ); 976 977 if ( face->cvt_program_size > 0 ) 978 { 979 TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 ); 980 981 FT_TRACE4(( "Executing `prep' table.\n" )); 982 error = face->interpreter( exec ); 983 #ifdef FT_DEBUG_LEVEL_TRACE 984 if ( error ) 985 FT_TRACE4(( " interpretation failed with error code 0x%x\n", 986 error )); 987 #endif 988 } 989 else 990 error = FT_Err_Ok; 991 992 size->cvt_ready = error; 993 994 /* UNDOCUMENTED! The MS rasterizer doesn't allow the following */ 995 /* graphics state variables to be modified by the CVT program. */ 996 997 exec->GS.dualVector.x = 0x4000; 998 exec->GS.dualVector.y = 0; 999 exec->GS.projVector.x = 0x4000; 1000 exec->GS.projVector.y = 0x0; 1001 exec->GS.freeVector.x = 0x4000; 1002 exec->GS.freeVector.y = 0x0; 1003 1004 exec->GS.rp0 = 0; 1005 exec->GS.rp1 = 0; 1006 exec->GS.rp2 = 0; 1007 1008 exec->GS.gep0 = 1; 1009 exec->GS.gep1 = 1; 1010 exec->GS.gep2 = 1; 1011 1012 exec->GS.loop = 1; 1013 1014 /* save as default graphics state */ 1015 size->GS = exec->GS; 1016 1017 TT_Save_Context( exec, size ); 1018 1019 return error; 1020 } 1021 1022 1023 static void tt_size_done_bytecode(FT_Size ftsize)1024 tt_size_done_bytecode( FT_Size ftsize ) 1025 { 1026 TT_Size size = (TT_Size)ftsize; 1027 TT_Face face = (TT_Face)ftsize->face; 1028 FT_Memory memory = face->root.memory; 1029 1030 if ( size->context ) 1031 { 1032 TT_Done_Context( size->context ); 1033 size->context = NULL; 1034 } 1035 1036 FT_FREE( size->cvt ); 1037 size->cvt_size = 0; 1038 1039 /* free storage area */ 1040 FT_FREE( size->storage ); 1041 size->storage_size = 0; 1042 1043 /* twilight zone */ 1044 tt_glyphzone_done( &size->twilight ); 1045 1046 FT_FREE( size->function_defs ); 1047 FT_FREE( size->instruction_defs ); 1048 1049 size->num_function_defs = 0; 1050 size->max_function_defs = 0; 1051 size->num_instruction_defs = 0; 1052 size->max_instruction_defs = 0; 1053 1054 size->max_func = 0; 1055 size->max_ins = 0; 1056 1057 size->bytecode_ready = -1; 1058 size->cvt_ready = -1; 1059 } 1060 1061 1062 /* Initialize bytecode-related fields in the size object. */ 1063 /* We do this only if bytecode interpretation is really needed. */ 1064 static FT_Error tt_size_init_bytecode(FT_Size ftsize,FT_Bool pedantic)1065 tt_size_init_bytecode( FT_Size ftsize, 1066 FT_Bool pedantic ) 1067 { 1068 FT_Error error; 1069 TT_Size size = (TT_Size)ftsize; 1070 TT_Face face = (TT_Face)ftsize->face; 1071 FT_Memory memory = face->root.memory; 1072 1073 FT_UShort n_twilight; 1074 TT_MaxProfile* maxp = &face->max_profile; 1075 1076 1077 /* clean up bytecode related data */ 1078 FT_FREE( size->function_defs ); 1079 FT_FREE( size->instruction_defs ); 1080 FT_FREE( size->cvt ); 1081 FT_FREE( size->storage ); 1082 1083 if ( size->context ) 1084 TT_Done_Context( size->context ); 1085 tt_glyphzone_done( &size->twilight ); 1086 1087 size->bytecode_ready = -1; 1088 size->cvt_ready = -1; 1089 1090 size->context = TT_New_Context( (TT_Driver)face->root.driver ); 1091 1092 size->max_function_defs = maxp->maxFunctionDefs; 1093 size->max_instruction_defs = maxp->maxInstructionDefs; 1094 1095 size->num_function_defs = 0; 1096 size->num_instruction_defs = 0; 1097 1098 size->max_func = 0; 1099 size->max_ins = 0; 1100 1101 size->cvt_size = face->cvt_size; 1102 size->storage_size = maxp->maxStorage; 1103 1104 /* Set default metrics */ 1105 { 1106 TT_Size_Metrics* tt_metrics = &size->ttmetrics; 1107 1108 1109 tt_metrics->rotated = FALSE; 1110 tt_metrics->stretched = FALSE; 1111 1112 /* Set default engine compensation. Value 3 is not described */ 1113 /* in the OpenType specification (as of Mai 2019), but Greg */ 1114 /* says that MS handles it the same as `gray'. */ 1115 /* */ 1116 /* The Apple specification says that the compensation for */ 1117 /* `gray' is always zero. FreeType doesn't do any */ 1118 /* compensation at all. */ 1119 tt_metrics->compensations[0] = 0; /* gray */ 1120 tt_metrics->compensations[1] = 0; /* black */ 1121 tt_metrics->compensations[2] = 0; /* white */ 1122 tt_metrics->compensations[3] = 0; /* the same as gray */ 1123 } 1124 1125 /* allocate function defs, instruction defs, cvt, and storage area */ 1126 if ( FT_NEW_ARRAY( size->function_defs, size->max_function_defs ) || 1127 FT_NEW_ARRAY( size->instruction_defs, size->max_instruction_defs ) || 1128 FT_NEW_ARRAY( size->cvt, size->cvt_size ) || 1129 FT_NEW_ARRAY( size->storage, size->storage_size ) ) 1130 goto Exit; 1131 1132 /* reserve twilight zone */ 1133 n_twilight = maxp->maxTwilightPoints; 1134 1135 /* there are 4 phantom points (do we need this?) */ 1136 n_twilight += 4; 1137 1138 error = tt_glyphzone_new( memory, n_twilight, 0, &size->twilight ); 1139 if ( error ) 1140 goto Exit; 1141 1142 size->twilight.n_points = n_twilight; 1143 1144 size->GS = tt_default_graphics_state; 1145 1146 /* set `face->interpreter' according to the debug hook present */ 1147 { 1148 FT_Library library = face->root.driver->root.library; 1149 1150 1151 face->interpreter = (TT_Interpreter) 1152 library->debug_hooks[FT_DEBUG_HOOK_TRUETYPE]; 1153 if ( !face->interpreter ) 1154 face->interpreter = (TT_Interpreter)TT_RunIns; 1155 } 1156 1157 /* Fine, now run the font program! */ 1158 1159 /* In case of an error while executing `fpgm', we intentionally don't */ 1160 /* clean up immediately – bugs in the `fpgm' are so fundamental that */ 1161 /* all following hinting calls should fail. Additionally, `fpgm' is */ 1162 /* to be executed just once; calling it again is completely useless */ 1163 /* and might even lead to extremely slow behaviour if it is malformed */ 1164 /* (containing an infinite loop, for example). */ 1165 error = tt_size_run_fpgm( size, pedantic ); 1166 return error; 1167 1168 Exit: 1169 if ( error ) 1170 tt_size_done_bytecode( ftsize ); 1171 1172 return error; 1173 } 1174 1175 1176 FT_LOCAL_DEF( FT_Error ) tt_size_ready_bytecode(TT_Size size,FT_Bool pedantic)1177 tt_size_ready_bytecode( TT_Size size, 1178 FT_Bool pedantic ) 1179 { 1180 FT_Error error = FT_Err_Ok; 1181 1182 1183 if ( size->bytecode_ready < 0 ) 1184 error = tt_size_init_bytecode( (FT_Size)size, pedantic ); 1185 else 1186 error = size->bytecode_ready; 1187 1188 if ( error ) 1189 goto Exit; 1190 1191 /* rescale CVT when needed */ 1192 if ( size->cvt_ready < 0 ) 1193 { 1194 FT_UInt i; 1195 1196 1197 /* all twilight points are originally zero */ 1198 for ( i = 0; i < (FT_UInt)size->twilight.n_points; i++ ) 1199 { 1200 size->twilight.org[i].x = 0; 1201 size->twilight.org[i].y = 0; 1202 size->twilight.cur[i].x = 0; 1203 size->twilight.cur[i].y = 0; 1204 } 1205 1206 /* clear storage area */ 1207 for ( i = 0; i < (FT_UInt)size->storage_size; i++ ) 1208 size->storage[i] = 0; 1209 1210 size->GS = tt_default_graphics_state; 1211 1212 error = tt_size_run_prep( size, pedantic ); 1213 } 1214 else 1215 error = size->cvt_ready; 1216 1217 Exit: 1218 return error; 1219 } 1220 1221 #endif /* TT_USE_BYTECODE_INTERPRETER */ 1222 1223 1224 /************************************************************************** 1225 * 1226 * @Function: 1227 * tt_size_init 1228 * 1229 * @Description: 1230 * Initialize a new TrueType size object. 1231 * 1232 * @InOut: 1233 * size :: 1234 * A handle to the size object. 1235 * 1236 * @Return: 1237 * FreeType error code. 0 means success. 1238 */ 1239 FT_LOCAL_DEF( FT_Error ) tt_size_init(FT_Size ttsize)1240 tt_size_init( FT_Size ttsize ) /* TT_Size */ 1241 { 1242 TT_Size size = (TT_Size)ttsize; 1243 FT_Error error = FT_Err_Ok; 1244 1245 1246 #ifdef TT_USE_BYTECODE_INTERPRETER 1247 size->bytecode_ready = -1; 1248 size->cvt_ready = -1; 1249 #endif 1250 1251 size->ttmetrics.valid = FALSE; 1252 size->strike_index = 0xFFFFFFFFUL; 1253 1254 return error; 1255 } 1256 1257 1258 /************************************************************************** 1259 * 1260 * @Function: 1261 * tt_size_done 1262 * 1263 * @Description: 1264 * The TrueType size object finalizer. 1265 * 1266 * @Input: 1267 * size :: 1268 * A handle to the target size object. 1269 */ 1270 FT_LOCAL_DEF( void ) tt_size_done(FT_Size ttsize)1271 tt_size_done( FT_Size ttsize ) /* TT_Size */ 1272 { 1273 TT_Size size = (TT_Size)ttsize; 1274 1275 1276 #ifdef TT_USE_BYTECODE_INTERPRETER 1277 tt_size_done_bytecode( ttsize ); 1278 #endif 1279 1280 size->ttmetrics.valid = FALSE; 1281 } 1282 1283 1284 /************************************************************************** 1285 * 1286 * @Function: 1287 * tt_size_reset 1288 * 1289 * @Description: 1290 * Reset a TrueType size when resolutions and character dimensions 1291 * have been changed. 1292 * 1293 * @Input: 1294 * size :: 1295 * A handle to the target size object. 1296 * 1297 * only_height :: 1298 * Only recompute ascender, descender, and height; 1299 * this flag is used for variation fonts where 1300 * `tt_size_reset' is used as an iterator function. 1301 */ 1302 FT_LOCAL_DEF( FT_Error ) tt_size_reset(TT_Size size,FT_Bool only_height)1303 tt_size_reset( TT_Size size, 1304 FT_Bool only_height ) 1305 { 1306 TT_Face face; 1307 FT_Size_Metrics* size_metrics; 1308 1309 1310 face = (TT_Face)size->root.face; 1311 1312 /* nothing to do for CFF2 */ 1313 if ( face->is_cff2 ) 1314 return FT_Err_Ok; 1315 1316 size->ttmetrics.valid = FALSE; 1317 1318 size_metrics = &size->hinted_metrics; 1319 1320 /* copy the result from base layer */ 1321 *size_metrics = size->root.metrics; 1322 1323 if ( size_metrics->x_ppem < 1 || size_metrics->y_ppem < 1 ) 1324 return FT_THROW( Invalid_PPem ); 1325 1326 /* This bit flag, if set, indicates that the ppems must be */ 1327 /* rounded to integers. Nearly all TrueType fonts have this bit */ 1328 /* set, as hinting won't work really well otherwise. */ 1329 /* */ 1330 if ( face->header.Flags & 8 ) 1331 { 1332 /* the TT spec always asks for ROUND, not FLOOR or CEIL */ 1333 size_metrics->ascender = FT_PIX_ROUND( 1334 FT_MulFix( face->root.ascender, 1335 size_metrics->y_scale ) ); 1336 size_metrics->descender = FT_PIX_ROUND( 1337 FT_MulFix( face->root.descender, 1338 size_metrics->y_scale ) ); 1339 size_metrics->height = FT_PIX_ROUND( 1340 FT_MulFix( face->root.height, 1341 size_metrics->y_scale ) ); 1342 } 1343 1344 size->ttmetrics.valid = TRUE; 1345 1346 if ( only_height ) 1347 { 1348 /* we must not recompute the scaling values here since */ 1349 /* `tt_size_reset' was already called (with only_height = 0) */ 1350 return FT_Err_Ok; 1351 } 1352 1353 if ( face->header.Flags & 8 ) 1354 { 1355 /* base scaling values on integer ppem values, */ 1356 /* as mandated by the TrueType specification */ 1357 size_metrics->x_scale = FT_DivFix( size_metrics->x_ppem << 6, 1358 face->root.units_per_EM ); 1359 size_metrics->y_scale = FT_DivFix( size_metrics->y_ppem << 6, 1360 face->root.units_per_EM ); 1361 1362 size_metrics->max_advance = FT_PIX_ROUND( 1363 FT_MulFix( face->root.max_advance_width, 1364 size_metrics->x_scale ) ); 1365 } 1366 1367 /* compute new transformation */ 1368 if ( size_metrics->x_ppem >= size_metrics->y_ppem ) 1369 { 1370 size->ttmetrics.scale = size_metrics->x_scale; 1371 size->ttmetrics.ppem = size_metrics->x_ppem; 1372 size->ttmetrics.x_ratio = 0x10000L; 1373 size->ttmetrics.y_ratio = FT_DivFix( size_metrics->y_ppem, 1374 size_metrics->x_ppem ); 1375 } 1376 else 1377 { 1378 size->ttmetrics.scale = size_metrics->y_scale; 1379 size->ttmetrics.ppem = size_metrics->y_ppem; 1380 size->ttmetrics.x_ratio = FT_DivFix( size_metrics->x_ppem, 1381 size_metrics->y_ppem ); 1382 size->ttmetrics.y_ratio = 0x10000L; 1383 } 1384 1385 size->metrics = size_metrics; 1386 1387 #ifdef TT_USE_BYTECODE_INTERPRETER 1388 size->cvt_ready = -1; 1389 #endif /* TT_USE_BYTECODE_INTERPRETER */ 1390 1391 return FT_Err_Ok; 1392 } 1393 1394 1395 /************************************************************************** 1396 * 1397 * @Function: 1398 * tt_driver_init 1399 * 1400 * @Description: 1401 * Initialize a given TrueType driver object. 1402 * 1403 * @Input: 1404 * driver :: 1405 * A handle to the target driver object. 1406 * 1407 * @Return: 1408 * FreeType error code. 0 means success. 1409 */ 1410 FT_LOCAL_DEF( FT_Error ) tt_driver_init(FT_Module ttdriver)1411 tt_driver_init( FT_Module ttdriver ) /* TT_Driver */ 1412 { 1413 1414 #ifdef TT_USE_BYTECODE_INTERPRETER 1415 1416 TT_Driver driver = (TT_Driver)ttdriver; 1417 1418 driver->interpreter_version = TT_INTERPRETER_VERSION_35; 1419 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY 1420 driver->interpreter_version = TT_INTERPRETER_VERSION_38; 1421 #endif 1422 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL 1423 driver->interpreter_version = TT_INTERPRETER_VERSION_40; 1424 #endif 1425 1426 #else /* !TT_USE_BYTECODE_INTERPRETER */ 1427 1428 FT_UNUSED( ttdriver ); 1429 1430 #endif /* !TT_USE_BYTECODE_INTERPRETER */ 1431 1432 return FT_Err_Ok; 1433 } 1434 1435 1436 /************************************************************************** 1437 * 1438 * @Function: 1439 * tt_driver_done 1440 * 1441 * @Description: 1442 * Finalize a given TrueType driver. 1443 * 1444 * @Input: 1445 * driver :: 1446 * A handle to the target TrueType driver. 1447 */ 1448 FT_LOCAL_DEF( void ) tt_driver_done(FT_Module ttdriver)1449 tt_driver_done( FT_Module ttdriver ) /* TT_Driver */ 1450 { 1451 FT_UNUSED( ttdriver ); 1452 } 1453 1454 1455 /************************************************************************** 1456 * 1457 * @Function: 1458 * tt_slot_init 1459 * 1460 * @Description: 1461 * Initialize a new slot object. 1462 * 1463 * @InOut: 1464 * slot :: 1465 * A handle to the slot object. 1466 * 1467 * @Return: 1468 * FreeType error code. 0 means success. 1469 */ 1470 FT_LOCAL_DEF( FT_Error ) tt_slot_init(FT_GlyphSlot slot)1471 tt_slot_init( FT_GlyphSlot slot ) 1472 { 1473 return FT_GlyphLoader_CreateExtra( slot->internal->loader ); 1474 } 1475 1476 1477 /* END */ 1478