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