1/***************************************************************************/ 2/* */ 3/* cf2ft.c */ 4/* */ 5/* FreeType Glue Component to Adobe's Interpreter (body). */ 6/* */ 7/* Copyright 2013-2014 Adobe Systems Incorporated. */ 8/* */ 9/* This software, and all works of authorship, whether in source or */ 10/* object code form as indicated by the copyright notice(s) included */ 11/* herein (collectively, the "Work") is made available, and may only be */ 12/* used, modified, and distributed under the FreeType Project License, */ 13/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ 14/* FreeType Project License, each contributor to the Work hereby grants */ 15/* to any individual or legal entity exercising permissions granted by */ 16/* the FreeType Project License and this section (hereafter, "You" or */ 17/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ 18/* royalty-free, irrevocable (except as stated in this section) patent */ 19/* license to make, have made, use, offer to sell, sell, import, and */ 20/* otherwise transfer the Work, where such license applies only to those */ 21/* patent claims licensable by such contributor that are necessarily */ 22/* infringed by their contribution(s) alone or by combination of their */ 23/* contribution(s) with the Work to which such contribution(s) was */ 24/* submitted. If You institute patent litigation against any entity */ 25/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ 26/* the Work or a contribution incorporated within the Work constitutes */ 27/* direct or contributory patent infringement, then any patent licenses */ 28/* granted to You under this License for that Work shall terminate as of */ 29/* the date such litigation is filed. */ 30/* */ 31/* By using, modifying, or distributing the Work you indicate that you */ 32/* have read and understood the terms and conditions of the */ 33/* FreeType Project License as well as those provided in this section, */ 34/* and you accept them fully. */ 35/* */ 36/***************************************************************************/ 37 38 39#include "cf2ft.h" 40#include FT_INTERNAL_DEBUG_H 41 42#include "cf2font.h" 43#include "cf2error.h" 44 45 46#define CF2_MAX_SIZE cf2_intToFixed( 2000 ) /* max ppem */ 47 48 49 /* 50 * This check should avoid most internal overflow cases. Clients should 51 * generally respond to `Glyph_Too_Big' by getting a glyph outline 52 * at EM size, scaling it and filling it as a graphics operation. 53 * 54 */ 55 static FT_Error 56 cf2_checkTransform( const CF2_Matrix* transform, 57 CF2_Int unitsPerEm ) 58 { 59 CF2_Fixed maxScale; 60 61 62 FT_ASSERT( unitsPerEm > 0 ); 63 64 if ( transform->a <= 0 || transform->d <= 0 ) 65 return FT_THROW( Invalid_Size_Handle ); 66 67 FT_ASSERT( transform->b == 0 && transform->c == 0 ); 68 FT_ASSERT( transform->tx == 0 && transform->ty == 0 ); 69 70 if ( unitsPerEm > 0x7FFF ) 71 return FT_THROW( Glyph_Too_Big ); 72 73 maxScale = FT_DivFix( CF2_MAX_SIZE, cf2_intToFixed( unitsPerEm ) ); 74 75 if ( transform->a > maxScale || transform->d > maxScale ) 76 return FT_THROW( Glyph_Too_Big ); 77 78 return FT_Err_Ok; 79 } 80 81 82 static void 83 cf2_setGlyphWidth( CF2_Outline outline, 84 CF2_Fixed width ) 85 { 86 CFF_Decoder* decoder = outline->decoder; 87 88 89 FT_ASSERT( decoder ); 90 91 decoder->glyph_width = cf2_fixedToInt( width ); 92 } 93 94 95 /* Clean up font instance. */ 96 static void 97 cf2_free_instance( void* ptr ) 98 { 99 CF2_Font font = (CF2_Font)ptr; 100 101 102 if ( font ) 103 { 104 FT_Memory memory = font->memory; 105 106 107 (void)memory; 108 } 109 } 110 111 112 /********************************************/ 113 /* */ 114 /* functions for handling client outline; */ 115 /* FreeType uses coordinates in 26.6 format */ 116 /* */ 117 /********************************************/ 118 119 static void 120 cf2_builder_moveTo( CF2_OutlineCallbacks callbacks, 121 const CF2_CallbackParams params ) 122 { 123 /* downcast the object pointer */ 124 CF2_Outline outline = (CF2_Outline)callbacks; 125 CFF_Builder* builder; 126 127 (void)params; /* only used in debug mode */ 128 129 130 FT_ASSERT( outline && outline->decoder ); 131 FT_ASSERT( params->op == CF2_PathOpMoveTo ); 132 133 builder = &outline->decoder->builder; 134 135 /* note: two successive moves simply close the contour twice */ 136 cff_builder_close_contour( builder ); 137 builder->path_begun = 0; 138 } 139 140 141 static void 142 cf2_builder_lineTo( CF2_OutlineCallbacks callbacks, 143 const CF2_CallbackParams params ) 144 { 145 FT_Error error; 146 147 /* downcast the object pointer */ 148 CF2_Outline outline = (CF2_Outline)callbacks; 149 CFF_Builder* builder; 150 151 152 FT_ASSERT( outline && outline->decoder ); 153 FT_ASSERT( params->op == CF2_PathOpLineTo ); 154 155 builder = &outline->decoder->builder; 156 157 if ( !builder->path_begun ) 158 { 159 /* record the move before the line; also check points and set */ 160 /* `path_begun' */ 161 error = cff_builder_start_point( builder, 162 params->pt0.x, 163 params->pt0.y ); 164 if ( error ) 165 { 166 if ( !*callbacks->error ) 167 *callbacks->error = error; 168 return; 169 } 170 } 171 172 /* `cff_builder_add_point1' includes a check_points call for one point */ 173 error = cff_builder_add_point1( builder, 174 params->pt1.x, 175 params->pt1.y ); 176 if ( error ) 177 { 178 if ( !*callbacks->error ) 179 *callbacks->error = error; 180 return; 181 } 182 } 183 184 185 static void 186 cf2_builder_cubeTo( CF2_OutlineCallbacks callbacks, 187 const CF2_CallbackParams params ) 188 { 189 FT_Error error; 190 191 /* downcast the object pointer */ 192 CF2_Outline outline = (CF2_Outline)callbacks; 193 CFF_Builder* builder; 194 195 196 FT_ASSERT( outline && outline->decoder ); 197 FT_ASSERT( params->op == CF2_PathOpCubeTo ); 198 199 builder = &outline->decoder->builder; 200 201 if ( !builder->path_begun ) 202 { 203 /* record the move before the line; also check points and set */ 204 /* `path_begun' */ 205 error = cff_builder_start_point( builder, 206 params->pt0.x, 207 params->pt0.y ); 208 if ( error ) 209 { 210 if ( !*callbacks->error ) 211 *callbacks->error = error; 212 return; 213 } 214 } 215 216 /* prepare room for 3 points: 2 off-curve, 1 on-curve */ 217 error = cff_check_points( builder, 3 ); 218 if ( error ) 219 { 220 if ( !*callbacks->error ) 221 *callbacks->error = error; 222 return; 223 } 224 225 cff_builder_add_point( builder, 226 params->pt1.x, 227 params->pt1.y, 0 ); 228 cff_builder_add_point( builder, 229 params->pt2.x, 230 params->pt2.y, 0 ); 231 cff_builder_add_point( builder, 232 params->pt3.x, 233 params->pt3.y, 1 ); 234 } 235 236 237 static void 238 cf2_outline_init( CF2_Outline outline, 239 FT_Memory memory, 240 FT_Error* error ) 241 { 242 FT_MEM_ZERO( outline, sizeof ( CF2_OutlineRec ) ); 243 244 outline->root.memory = memory; 245 outline->root.error = error; 246 247 outline->root.moveTo = cf2_builder_moveTo; 248 outline->root.lineTo = cf2_builder_lineTo; 249 outline->root.cubeTo = cf2_builder_cubeTo; 250 } 251 252 253 /* get scaling and hint flag from GlyphSlot */ 254 static void 255 cf2_getScaleAndHintFlag( CFF_Decoder* decoder, 256 CF2_Fixed* x_scale, 257 CF2_Fixed* y_scale, 258 FT_Bool* hinted, 259 FT_Bool* scaled ) 260 { 261 FT_ASSERT( decoder && decoder->builder.glyph ); 262 263 /* note: FreeType scale includes a factor of 64 */ 264 *hinted = decoder->builder.glyph->hint; 265 *scaled = decoder->builder.glyph->scaled; 266 267 if ( *hinted ) 268 { 269 *x_scale = ( decoder->builder.glyph->x_scale + 32 ) / 64; 270 *y_scale = ( decoder->builder.glyph->y_scale + 32 ) / 64; 271 } 272 else 273 { 274 /* for unhinted outlines, `cff_slot_load' does the scaling, */ 275 /* thus render at `unity' scale */ 276 277 *x_scale = 0x0400; /* 1/64 as 16.16 */ 278 *y_scale = 0x0400; 279 } 280 } 281 282 283 /* get units per em from `FT_Face' */ 284 /* TODO: should handle font matrix concatenation? */ 285 static FT_UShort 286 cf2_getUnitsPerEm( CFF_Decoder* decoder ) 287 { 288 FT_ASSERT( decoder && decoder->builder.face ); 289 FT_ASSERT( decoder->builder.face->root.units_per_EM ); 290 291 return decoder->builder.face->root.units_per_EM; 292 } 293 294 295 /* Main entry point: Render one glyph. */ 296 FT_LOCAL_DEF( FT_Error ) 297 cf2_decoder_parse_charstrings( CFF_Decoder* decoder, 298 FT_Byte* charstring_base, 299 FT_ULong charstring_len ) 300 { 301 FT_Memory memory; 302 FT_Error error = FT_Err_Ok; 303 CF2_Font font; 304 305 306 FT_ASSERT( decoder && decoder->cff ); 307 308 memory = decoder->builder.memory; 309 310 /* CF2 data is saved here across glyphs */ 311 font = (CF2_Font)decoder->cff->cf2_instance.data; 312 313 /* on first glyph, allocate instance structure */ 314 if ( decoder->cff->cf2_instance.data == NULL ) 315 { 316 decoder->cff->cf2_instance.finalizer = 317 (FT_Generic_Finalizer)cf2_free_instance; 318 319 if ( FT_ALLOC( decoder->cff->cf2_instance.data, 320 sizeof ( CF2_FontRec ) ) ) 321 return FT_THROW( Out_Of_Memory ); 322 323 font = (CF2_Font)decoder->cff->cf2_instance.data; 324 325 font->memory = memory; 326 327 /* initialize a client outline, to be shared by each glyph rendered */ 328 cf2_outline_init( &font->outline, font->memory, &font->error ); 329 } 330 331 /* save decoder; it is a stack variable and will be different on each */ 332 /* call */ 333 font->decoder = decoder; 334 font->outline.decoder = decoder; 335 336 { 337 /* build parameters for Adobe engine */ 338 339 CFF_Builder* builder = &decoder->builder; 340 CFF_Driver driver = (CFF_Driver)FT_FACE_DRIVER( builder->face ); 341 342 /* local error */ 343 FT_Error error2 = FT_Err_Ok; 344 CF2_BufferRec buf; 345 CF2_Matrix transform; 346 CF2_F16Dot16 glyphWidth; 347 348 FT_Bool hinted; 349 FT_Bool scaled; 350 351 352 /* FreeType has already looked up the GID; convert to */ 353 /* `RegionBuffer', assuming that the input has been validated */ 354 FT_ASSERT( charstring_base + charstring_len >= charstring_base ); 355 356 FT_ZERO( &buf ); 357 buf.start = 358 buf.ptr = charstring_base; 359 buf.end = charstring_base + charstring_len; 360 361 FT_ZERO( &transform ); 362 363 cf2_getScaleAndHintFlag( decoder, 364 &transform.a, 365 &transform.d, 366 &hinted, 367 &scaled ); 368 369 font->renderingFlags = 0; 370 if ( hinted ) 371 font->renderingFlags |= CF2_FlagsHinted; 372 if ( scaled && !driver->no_stem_darkening ) 373 font->renderingFlags |= CF2_FlagsDarkened; 374 375 font->darkenParams[0] = driver->darken_params[0]; 376 font->darkenParams[1] = driver->darken_params[1]; 377 font->darkenParams[2] = driver->darken_params[2]; 378 font->darkenParams[3] = driver->darken_params[3]; 379 font->darkenParams[4] = driver->darken_params[4]; 380 font->darkenParams[5] = driver->darken_params[5]; 381 font->darkenParams[6] = driver->darken_params[6]; 382 font->darkenParams[7] = driver->darken_params[7]; 383 384 /* now get an outline for this glyph; */ 385 /* also get units per em to validate scale */ 386 font->unitsPerEm = (CF2_Int)cf2_getUnitsPerEm( decoder ); 387 388 if ( scaled ) 389 { 390 error2 = cf2_checkTransform( &transform, font->unitsPerEm ); 391 if ( error2 ) 392 return error2; 393 } 394 395 error2 = cf2_getGlyphOutline( font, &buf, &transform, &glyphWidth ); 396 if ( error2 ) 397 return FT_ERR( Invalid_File_Format ); 398 399 cf2_setGlyphWidth( &font->outline, glyphWidth ); 400 401 return FT_Err_Ok; 402 } 403 } 404 405 406 /* get pointer to current FreeType subfont (based on current glyphID) */ 407 FT_LOCAL_DEF( CFF_SubFont ) 408 cf2_getSubfont( CFF_Decoder* decoder ) 409 { 410 FT_ASSERT( decoder && decoder->current_subfont ); 411 412 return decoder->current_subfont; 413 } 414 415 416 /* get `y_ppem' from `CFF_Size' */ 417 FT_LOCAL_DEF( CF2_Fixed ) 418 cf2_getPpemY( CFF_Decoder* decoder ) 419 { 420 FT_ASSERT( decoder && 421 decoder->builder.face && 422 decoder->builder.face->root.size ); 423 424 /* 425 * Note that `y_ppem' can be zero if there wasn't a call to 426 * `FT_Set_Char_Size' or something similar. However, this isn't a 427 * problem since we come to this place in the code only if 428 * FT_LOAD_NO_SCALE is set (the other case gets caught by 429 * `cf2_checkTransform'). The ppem value is needed to compute the stem 430 * darkening, which is disabled for getting the unscaled outline. 431 * 432 */ 433 return cf2_intToFixed( 434 decoder->builder.face->root.size->metrics.y_ppem ); 435 } 436 437 438 /* get standard stem widths for the current subfont; */ 439 /* FreeType stores these as integer font units */ 440 /* (note: variable names seem swapped) */ 441 FT_LOCAL_DEF( CF2_Fixed ) 442 cf2_getStdVW( CFF_Decoder* decoder ) 443 { 444 FT_ASSERT( decoder && decoder->current_subfont ); 445 446 return cf2_intToFixed( 447 decoder->current_subfont->private_dict.standard_height ); 448 } 449 450 451 FT_LOCAL_DEF( CF2_Fixed ) 452 cf2_getStdHW( CFF_Decoder* decoder ) 453 { 454 FT_ASSERT( decoder && decoder->current_subfont ); 455 456 return cf2_intToFixed( 457 decoder->current_subfont->private_dict.standard_width ); 458 } 459 460 461 /* note: FreeType stores 1000 times the actual value for `BlueScale' */ 462 FT_LOCAL_DEF( void ) 463 cf2_getBlueMetrics( CFF_Decoder* decoder, 464 CF2_Fixed* blueScale, 465 CF2_Fixed* blueShift, 466 CF2_Fixed* blueFuzz ) 467 { 468 FT_ASSERT( decoder && decoder->current_subfont ); 469 470 *blueScale = FT_DivFix( 471 decoder->current_subfont->private_dict.blue_scale, 472 cf2_intToFixed( 1000 ) ); 473 *blueShift = cf2_intToFixed( 474 decoder->current_subfont->private_dict.blue_shift ); 475 *blueFuzz = cf2_intToFixed( 476 decoder->current_subfont->private_dict.blue_fuzz ); 477 } 478 479 480 /* get blue values counts and arrays; the FreeType parser has validated */ 481 /* the counts and verified that each is an even number */ 482 FT_LOCAL_DEF( void ) 483 cf2_getBlueValues( CFF_Decoder* decoder, 484 size_t* count, 485 FT_Pos* *data ) 486 { 487 FT_ASSERT( decoder && decoder->current_subfont ); 488 489 *count = decoder->current_subfont->private_dict.num_blue_values; 490 *data = (FT_Pos*) 491 &decoder->current_subfont->private_dict.blue_values; 492 } 493 494 495 FT_LOCAL_DEF( void ) 496 cf2_getOtherBlues( CFF_Decoder* decoder, 497 size_t* count, 498 FT_Pos* *data ) 499 { 500 FT_ASSERT( decoder && decoder->current_subfont ); 501 502 *count = decoder->current_subfont->private_dict.num_other_blues; 503 *data = (FT_Pos*) 504 &decoder->current_subfont->private_dict.other_blues; 505 } 506 507 508 FT_LOCAL_DEF( void ) 509 cf2_getFamilyBlues( CFF_Decoder* decoder, 510 size_t* count, 511 FT_Pos* *data ) 512 { 513 FT_ASSERT( decoder && decoder->current_subfont ); 514 515 *count = decoder->current_subfont->private_dict.num_family_blues; 516 *data = (FT_Pos*) 517 &decoder->current_subfont->private_dict.family_blues; 518 } 519 520 521 FT_LOCAL_DEF( void ) 522 cf2_getFamilyOtherBlues( CFF_Decoder* decoder, 523 size_t* count, 524 FT_Pos* *data ) 525 { 526 FT_ASSERT( decoder && decoder->current_subfont ); 527 528 *count = decoder->current_subfont->private_dict.num_family_other_blues; 529 *data = (FT_Pos*) 530 &decoder->current_subfont->private_dict.family_other_blues; 531 } 532 533 534 FT_LOCAL_DEF( CF2_Int ) 535 cf2_getLanguageGroup( CFF_Decoder* decoder ) 536 { 537 FT_ASSERT( decoder && decoder->current_subfont ); 538 539 return decoder->current_subfont->private_dict.language_group; 540 } 541 542 543 /* convert unbiased subroutine index to `CF2_Buffer' and */ 544 /* return 0 on success */ 545 FT_LOCAL_DEF( CF2_Int ) 546 cf2_initGlobalRegionBuffer( CFF_Decoder* decoder, 547 CF2_UInt idx, 548 CF2_Buffer buf ) 549 { 550 FT_ASSERT( decoder ); 551 552 FT_ZERO( buf ); 553 554 idx += decoder->globals_bias; 555 if ( idx >= decoder->num_globals ) 556 return TRUE; /* error */ 557 558 FT_ASSERT( decoder->globals ); 559 560 buf->start = 561 buf->ptr = decoder->globals[idx]; 562 buf->end = decoder->globals[idx + 1]; 563 564 return FALSE; /* success */ 565 } 566 567 568 /* convert AdobeStandardEncoding code to CF2_Buffer; */ 569 /* used for seac component */ 570 FT_LOCAL_DEF( FT_Error ) 571 cf2_getSeacComponent( CFF_Decoder* decoder, 572 CF2_UInt code, 573 CF2_Buffer buf ) 574 { 575 CF2_Int gid; 576 FT_Byte* charstring; 577 FT_ULong len; 578 FT_Error error; 579 580 581 FT_ASSERT( decoder ); 582 583 FT_ZERO( buf ); 584 585 gid = cff_lookup_glyph_by_stdcharcode( decoder->cff, code ); 586 if ( gid < 0 ) 587 return FT_THROW( Invalid_Glyph_Format ); 588 589 error = cff_get_glyph_data( decoder->builder.face, 590 gid, 591 &charstring, 592 &len ); 593 /* TODO: for now, just pass the FreeType error through */ 594 if ( error ) 595 return error; 596 597 /* assume input has been validated */ 598 FT_ASSERT( charstring + len >= charstring ); 599 600 buf->start = charstring; 601 buf->end = charstring + len; 602 buf->ptr = buf->start; 603 604 return FT_Err_Ok; 605 } 606 607 608 FT_LOCAL_DEF( void ) 609 cf2_freeSeacComponent( CFF_Decoder* decoder, 610 CF2_Buffer buf ) 611 { 612 FT_ASSERT( decoder ); 613 614 cff_free_glyph_data( decoder->builder.face, 615 (FT_Byte**)&buf->start, 616 (FT_ULong)( buf->end - buf->start ) ); 617 } 618 619 620 FT_LOCAL_DEF( CF2_Int ) 621 cf2_initLocalRegionBuffer( CFF_Decoder* decoder, 622 CF2_UInt idx, 623 CF2_Buffer buf ) 624 { 625 FT_ASSERT( decoder ); 626 627 FT_ZERO( buf ); 628 629 idx += decoder->locals_bias; 630 if ( idx >= decoder->num_locals ) 631 return TRUE; /* error */ 632 633 FT_ASSERT( decoder->locals ); 634 635 buf->start = 636 buf->ptr = decoder->locals[idx]; 637 buf->end = decoder->locals[idx + 1]; 638 639 return FALSE; /* success */ 640 } 641 642 643 FT_LOCAL_DEF( CF2_Fixed ) 644 cf2_getDefaultWidthX( CFF_Decoder* decoder ) 645 { 646 FT_ASSERT( decoder && decoder->current_subfont ); 647 648 return cf2_intToFixed( 649 decoder->current_subfont->private_dict.default_width ); 650 } 651 652 653 FT_LOCAL_DEF( CF2_Fixed ) 654 cf2_getNominalWidthX( CFF_Decoder* decoder ) 655 { 656 FT_ASSERT( decoder && decoder->current_subfont ); 657 658 return cf2_intToFixed( 659 decoder->current_subfont->private_dict.nominal_width ); 660 } 661 662 663 FT_LOCAL_DEF( void ) 664 cf2_outline_reset( CF2_Outline outline ) 665 { 666 CFF_Decoder* decoder = outline->decoder; 667 668 669 FT_ASSERT( decoder ); 670 671 outline->root.windingMomentum = 0; 672 673 FT_GlyphLoader_Rewind( decoder->builder.loader ); 674 } 675 676 677 FT_LOCAL_DEF( void ) 678 cf2_outline_close( CF2_Outline outline ) 679 { 680 CFF_Decoder* decoder = outline->decoder; 681 682 683 FT_ASSERT( decoder ); 684 685 cff_builder_close_contour( &decoder->builder ); 686 687 FT_GlyphLoader_Add( decoder->builder.loader ); 688 } 689 690 691/* END */ 692