1 /***************************************************************************/ 2 /* */ 3 /* cffgload.c */ 4 /* */ 5 /* OpenType Glyph Loader (body). */ 6 /* */ 7 /* Copyright 1996-2018 by */ 8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9 /* */ 10 /* This file is part of the FreeType project, and may only be used, */ 11 /* modified, and distributed under the terms of the FreeType project */ 12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13 /* this file you indicate that you have read the license and */ 14 /* understand and accept it fully. */ 15 /* */ 16 /***************************************************************************/ 17 18 19 #include <ft2build.h> 20 #include FT_INTERNAL_DEBUG_H 21 #include FT_INTERNAL_STREAM_H 22 #include FT_INTERNAL_SFNT_H 23 #include FT_INTERNAL_CALC_H 24 #include FT_INTERNAL_POSTSCRIPT_AUX_H 25 #include FT_OUTLINE_H 26 #include FT_DRIVER_H 27 28 #include "cffload.h" 29 #include "cffgload.h" 30 31 #include "cfferrs.h" 32 33 34 /*************************************************************************/ 35 /* */ 36 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 37 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 38 /* messages during execution. */ 39 /* */ 40 #undef FT_COMPONENT 41 #define FT_COMPONENT trace_cffgload 42 43 44 FT_LOCAL_DEF( FT_Error ) cff_get_glyph_data(TT_Face face,FT_UInt glyph_index,FT_Byte ** pointer,FT_ULong * length)45 cff_get_glyph_data( TT_Face face, 46 FT_UInt glyph_index, 47 FT_Byte** pointer, 48 FT_ULong* length ) 49 { 50 #ifdef FT_CONFIG_OPTION_INCREMENTAL 51 /* For incremental fonts get the character data using the */ 52 /* callback function. */ 53 if ( face->root.internal->incremental_interface ) 54 { 55 FT_Data data; 56 FT_Error error = 57 face->root.internal->incremental_interface->funcs->get_glyph_data( 58 face->root.internal->incremental_interface->object, 59 glyph_index, &data ); 60 61 62 *pointer = (FT_Byte*)data.pointer; 63 *length = (FT_ULong)data.length; 64 65 return error; 66 } 67 else 68 #endif /* FT_CONFIG_OPTION_INCREMENTAL */ 69 70 { 71 CFF_Font cff = (CFF_Font)(face->extra.data); 72 73 74 return cff_index_access_element( &cff->charstrings_index, glyph_index, 75 pointer, length ); 76 } 77 } 78 79 80 FT_LOCAL_DEF( void ) cff_free_glyph_data(TT_Face face,FT_Byte ** pointer,FT_ULong length)81 cff_free_glyph_data( TT_Face face, 82 FT_Byte** pointer, 83 FT_ULong length ) 84 { 85 #ifndef FT_CONFIG_OPTION_INCREMENTAL 86 FT_UNUSED( length ); 87 #endif 88 89 #ifdef FT_CONFIG_OPTION_INCREMENTAL 90 /* For incremental fonts get the character data using the */ 91 /* callback function. */ 92 if ( face->root.internal->incremental_interface ) 93 { 94 FT_Data data; 95 96 97 data.pointer = *pointer; 98 data.length = (FT_Int)length; 99 100 face->root.internal->incremental_interface->funcs->free_glyph_data( 101 face->root.internal->incremental_interface->object, &data ); 102 } 103 else 104 #endif /* FT_CONFIG_OPTION_INCREMENTAL */ 105 106 { 107 CFF_Font cff = (CFF_Font)(face->extra.data); 108 109 110 cff_index_forget_element( &cff->charstrings_index, pointer ); 111 } 112 } 113 114 115 /*************************************************************************/ 116 /*************************************************************************/ 117 /*************************************************************************/ 118 /********** *********/ 119 /********** *********/ 120 /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/ 121 /********** *********/ 122 /********** The following code is in charge of computing *********/ 123 /********** the maximum advance width of the font. It *********/ 124 /********** quickly processes each glyph charstring to *********/ 125 /********** extract the value from either a `sbw' or `seac' *********/ 126 /********** operator. *********/ 127 /********** *********/ 128 /*************************************************************************/ 129 /*************************************************************************/ 130 /*************************************************************************/ 131 132 133 #if 0 /* unused until we support pure CFF fonts */ 134 135 136 FT_LOCAL_DEF( FT_Error ) 137 cff_compute_max_advance( TT_Face face, 138 FT_Int* max_advance ) 139 { 140 FT_Error error = FT_Err_Ok; 141 CFF_Decoder decoder; 142 FT_Int glyph_index; 143 CFF_Font cff = (CFF_Font)face->other; 144 145 PSAux_Service psaux = (PSAux_Service)face->psaux; 146 const CFF_Decoder_Funcs decoder_funcs = psaux->cff_decoder_funcs; 147 148 149 *max_advance = 0; 150 151 /* Initialize load decoder */ 152 decoder_funcs->init( &decoder, face, 0, 0, 0, 0, 0, 0 ); 153 154 decoder.builder.metrics_only = 1; 155 decoder.builder.load_points = 0; 156 157 /* For each glyph, parse the glyph charstring and extract */ 158 /* the advance width. */ 159 for ( glyph_index = 0; glyph_index < face->root.num_glyphs; 160 glyph_index++ ) 161 { 162 FT_Byte* charstring; 163 FT_ULong charstring_len; 164 165 166 /* now get load the unscaled outline */ 167 error = cff_get_glyph_data( face, glyph_index, 168 &charstring, &charstring_len ); 169 if ( !error ) 170 { 171 error = decoder_funcs->prepare( &decoder, size, glyph_index ); 172 if ( !error ) 173 error = decoder_funcs->parse_charstrings_old( &decoder, 174 charstring, 175 charstring_len, 176 0 ); 177 178 cff_free_glyph_data( face, &charstring, &charstring_len ); 179 } 180 181 /* ignore the error if one has occurred -- skip to next glyph */ 182 error = FT_Err_Ok; 183 } 184 185 *max_advance = decoder.builder.advance.x; 186 187 return FT_Err_Ok; 188 } 189 190 191 #endif /* 0 */ 192 193 194 FT_LOCAL_DEF( FT_Error ) cff_slot_load(CFF_GlyphSlot glyph,CFF_Size size,FT_UInt glyph_index,FT_Int32 load_flags)195 cff_slot_load( CFF_GlyphSlot glyph, 196 CFF_Size size, 197 FT_UInt glyph_index, 198 FT_Int32 load_flags ) 199 { 200 FT_Error error; 201 CFF_Decoder decoder; 202 PS_Decoder psdecoder; 203 TT_Face face = (TT_Face)glyph->root.face; 204 FT_Bool hinting, scaled, force_scaling; 205 CFF_Font cff = (CFF_Font)face->extra.data; 206 207 PSAux_Service psaux = (PSAux_Service)face->psaux; 208 const CFF_Decoder_Funcs decoder_funcs = psaux->cff_decoder_funcs; 209 210 FT_Matrix font_matrix; 211 FT_Vector font_offset; 212 213 214 force_scaling = FALSE; 215 216 /* in a CID-keyed font, consider `glyph_index' as a CID and map */ 217 /* it immediately to the real glyph_index -- if it isn't a */ 218 /* subsetted font, glyph_indices and CIDs are identical, though */ 219 if ( cff->top_font.font_dict.cid_registry != 0xFFFFU && 220 cff->charset.cids ) 221 { 222 /* don't handle CID 0 (.notdef) which is directly mapped to GID 0 */ 223 if ( glyph_index != 0 ) 224 { 225 glyph_index = cff_charset_cid_to_gindex( &cff->charset, 226 glyph_index ); 227 if ( glyph_index == 0 ) 228 return FT_THROW( Invalid_Argument ); 229 } 230 } 231 else if ( glyph_index >= cff->num_glyphs ) 232 return FT_THROW( Invalid_Argument ); 233 234 if ( load_flags & FT_LOAD_NO_RECURSE ) 235 load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; 236 237 glyph->x_scale = 0x10000L; 238 glyph->y_scale = 0x10000L; 239 if ( size ) 240 { 241 glyph->x_scale = size->root.metrics.x_scale; 242 glyph->y_scale = size->root.metrics.y_scale; 243 } 244 245 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS 246 247 /* try to load embedded bitmap if any */ 248 /* */ 249 /* XXX: The convention should be emphasized in */ 250 /* the documents because it can be confusing. */ 251 if ( size ) 252 { 253 CFF_Face cff_face = (CFF_Face)size->root.face; 254 SFNT_Service sfnt = (SFNT_Service)cff_face->sfnt; 255 FT_Stream stream = cff_face->root.stream; 256 257 258 if ( size->strike_index != 0xFFFFFFFFUL && 259 sfnt->load_eblc && 260 ( load_flags & FT_LOAD_NO_BITMAP ) == 0 ) 261 { 262 TT_SBit_MetricsRec metrics; 263 264 265 error = sfnt->load_sbit_image( face, 266 size->strike_index, 267 glyph_index, 268 (FT_UInt)load_flags, 269 stream, 270 &glyph->root.bitmap, 271 &metrics ); 272 273 if ( !error ) 274 { 275 FT_Bool has_vertical_info; 276 FT_UShort advance; 277 FT_Short dummy; 278 279 280 glyph->root.outline.n_points = 0; 281 glyph->root.outline.n_contours = 0; 282 283 glyph->root.metrics.width = (FT_Pos)metrics.width << 6; 284 glyph->root.metrics.height = (FT_Pos)metrics.height << 6; 285 286 glyph->root.metrics.horiBearingX = (FT_Pos)metrics.horiBearingX << 6; 287 glyph->root.metrics.horiBearingY = (FT_Pos)metrics.horiBearingY << 6; 288 glyph->root.metrics.horiAdvance = (FT_Pos)metrics.horiAdvance << 6; 289 290 glyph->root.metrics.vertBearingX = (FT_Pos)metrics.vertBearingX << 6; 291 glyph->root.metrics.vertBearingY = (FT_Pos)metrics.vertBearingY << 6; 292 glyph->root.metrics.vertAdvance = (FT_Pos)metrics.vertAdvance << 6; 293 294 glyph->root.format = FT_GLYPH_FORMAT_BITMAP; 295 296 if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) 297 { 298 glyph->root.bitmap_left = metrics.vertBearingX; 299 glyph->root.bitmap_top = metrics.vertBearingY; 300 } 301 else 302 { 303 glyph->root.bitmap_left = metrics.horiBearingX; 304 glyph->root.bitmap_top = metrics.horiBearingY; 305 } 306 307 /* compute linear advance widths */ 308 309 (void)( (SFNT_Service)face->sfnt )->get_metrics( face, 0, 310 glyph_index, 311 &dummy, 312 &advance ); 313 glyph->root.linearHoriAdvance = advance; 314 315 has_vertical_info = FT_BOOL( 316 face->vertical_info && 317 face->vertical.number_Of_VMetrics > 0 ); 318 319 /* get the vertical metrics from the vmtx table if we have one */ 320 if ( has_vertical_info ) 321 { 322 (void)( (SFNT_Service)face->sfnt )->get_metrics( face, 1, 323 glyph_index, 324 &dummy, 325 &advance ); 326 glyph->root.linearVertAdvance = advance; 327 } 328 else 329 { 330 /* make up vertical ones */ 331 if ( face->os2.version != 0xFFFFU ) 332 glyph->root.linearVertAdvance = (FT_Pos) 333 ( face->os2.sTypoAscender - face->os2.sTypoDescender ); 334 else 335 glyph->root.linearVertAdvance = (FT_Pos) 336 ( face->horizontal.Ascender - face->horizontal.Descender ); 337 } 338 339 return error; 340 } 341 } 342 } 343 344 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ 345 346 /* return immediately if we only want the embedded bitmaps */ 347 if ( load_flags & FT_LOAD_SBITS_ONLY ) 348 return FT_THROW( Invalid_Argument ); 349 350 /* if we have a CID subfont, use its matrix (which has already */ 351 /* been multiplied with the root matrix) */ 352 353 /* this scaling is only relevant if the PS hinter isn't active */ 354 if ( cff->num_subfonts ) 355 { 356 FT_Long top_upm, sub_upm; 357 FT_Byte fd_index = cff_fd_select_get( &cff->fd_select, 358 glyph_index ); 359 360 361 if ( fd_index >= cff->num_subfonts ) 362 fd_index = (FT_Byte)( cff->num_subfonts - 1 ); 363 364 top_upm = (FT_Long)cff->top_font.font_dict.units_per_em; 365 sub_upm = (FT_Long)cff->subfonts[fd_index]->font_dict.units_per_em; 366 367 368 font_matrix = cff->subfonts[fd_index]->font_dict.font_matrix; 369 font_offset = cff->subfonts[fd_index]->font_dict.font_offset; 370 371 if ( top_upm != sub_upm ) 372 { 373 glyph->x_scale = FT_MulDiv( glyph->x_scale, top_upm, sub_upm ); 374 glyph->y_scale = FT_MulDiv( glyph->y_scale, top_upm, sub_upm ); 375 376 force_scaling = TRUE; 377 } 378 } 379 else 380 { 381 font_matrix = cff->top_font.font_dict.font_matrix; 382 font_offset = cff->top_font.font_dict.font_offset; 383 } 384 385 glyph->root.outline.n_points = 0; 386 glyph->root.outline.n_contours = 0; 387 388 /* top-level code ensures that FT_LOAD_NO_HINTING is set */ 389 /* if FT_LOAD_NO_SCALE is active */ 390 hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_HINTING ) == 0 ); 391 scaled = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ); 392 393 glyph->hint = hinting; 394 glyph->scaled = scaled; 395 glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; /* by default */ 396 397 { 398 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE 399 PS_Driver driver = (PS_Driver)FT_FACE_DRIVER( face ); 400 #endif 401 402 403 FT_Byte* charstring; 404 FT_ULong charstring_len; 405 406 407 decoder_funcs->init( &decoder, face, size, glyph, hinting, 408 FT_LOAD_TARGET_MODE( load_flags ), 409 cff_get_glyph_data, 410 cff_free_glyph_data ); 411 412 /* this is for pure CFFs */ 413 if ( load_flags & FT_LOAD_ADVANCE_ONLY ) 414 decoder.width_only = TRUE; 415 416 decoder.builder.no_recurse = 417 (FT_Bool)( load_flags & FT_LOAD_NO_RECURSE ); 418 419 /* now load the unscaled outline */ 420 error = cff_get_glyph_data( face, glyph_index, 421 &charstring, &charstring_len ); 422 if ( error ) 423 goto Glyph_Build_Finished; 424 425 error = decoder_funcs->prepare( &decoder, size, glyph_index ); 426 if ( error ) 427 goto Glyph_Build_Finished; 428 429 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE 430 /* choose which CFF renderer to use */ 431 if ( driver->hinting_engine == FT_HINTING_FREETYPE ) 432 error = decoder_funcs->parse_charstrings_old( &decoder, 433 charstring, 434 charstring_len, 435 0 ); 436 else 437 #endif 438 { 439 psaux->ps_decoder_init( &psdecoder, &decoder, FALSE ); 440 441 error = decoder_funcs->parse_charstrings( &psdecoder, 442 charstring, 443 charstring_len ); 444 445 /* Adobe's engine uses 16.16 numbers everywhere; */ 446 /* as a consequence, glyphs larger than 2000ppem get rejected */ 447 if ( FT_ERR_EQ( error, Glyph_Too_Big ) ) 448 { 449 /* this time, we retry unhinted and scale up the glyph later on */ 450 /* (the engine uses and sets the hardcoded value 0x10000 / 64 = */ 451 /* 0x400 for both `x_scale' and `y_scale' in this case) */ 452 hinting = FALSE; 453 force_scaling = TRUE; 454 glyph->hint = hinting; 455 456 error = decoder_funcs->parse_charstrings( &psdecoder, 457 charstring, 458 charstring_len ); 459 } 460 } 461 462 cff_free_glyph_data( face, &charstring, charstring_len ); 463 464 if ( error ) 465 goto Glyph_Build_Finished; 466 467 #ifdef FT_CONFIG_OPTION_INCREMENTAL 468 /* Control data and length may not be available for incremental */ 469 /* fonts. */ 470 if ( face->root.internal->incremental_interface ) 471 { 472 glyph->root.control_data = NULL; 473 glyph->root.control_len = 0; 474 } 475 else 476 #endif /* FT_CONFIG_OPTION_INCREMENTAL */ 477 478 /* We set control_data and control_len if charstrings is loaded. */ 479 /* See how charstring loads at cff_index_access_element() in */ 480 /* cffload.c. */ 481 { 482 CFF_Index csindex = &cff->charstrings_index; 483 484 485 if ( csindex->offsets ) 486 { 487 glyph->root.control_data = csindex->bytes + 488 csindex->offsets[glyph_index] - 1; 489 glyph->root.control_len = (FT_Long)charstring_len; 490 } 491 } 492 493 Glyph_Build_Finished: 494 /* save new glyph tables, if no error */ 495 if ( !error ) 496 decoder.builder.funcs.done( &decoder.builder ); 497 /* XXX: anything to do for broken glyph entry? */ 498 } 499 500 #ifdef FT_CONFIG_OPTION_INCREMENTAL 501 502 /* Incremental fonts can optionally override the metrics. */ 503 if ( !error && 504 face->root.internal->incremental_interface && 505 face->root.internal->incremental_interface->funcs->get_glyph_metrics ) 506 { 507 FT_Incremental_MetricsRec metrics; 508 509 510 metrics.bearing_x = decoder.builder.left_bearing.x; 511 metrics.bearing_y = 0; 512 metrics.advance = decoder.builder.advance.x; 513 metrics.advance_v = decoder.builder.advance.y; 514 515 error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( 516 face->root.internal->incremental_interface->object, 517 glyph_index, FALSE, &metrics ); 518 519 decoder.builder.left_bearing.x = metrics.bearing_x; 520 decoder.builder.advance.x = metrics.advance; 521 decoder.builder.advance.y = metrics.advance_v; 522 } 523 524 #endif /* FT_CONFIG_OPTION_INCREMENTAL */ 525 526 if ( !error ) 527 { 528 /* Now, set the metrics -- this is rather simple, as */ 529 /* the left side bearing is the xMin, and the top side */ 530 /* bearing the yMax. */ 531 532 /* For composite glyphs, return only left side bearing and */ 533 /* advance width. */ 534 if ( load_flags & FT_LOAD_NO_RECURSE ) 535 { 536 FT_Slot_Internal internal = glyph->root.internal; 537 538 539 glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x; 540 glyph->root.metrics.horiAdvance = decoder.glyph_width; 541 internal->glyph_matrix = font_matrix; 542 internal->glyph_delta = font_offset; 543 internal->glyph_transformed = 1; 544 } 545 else 546 { 547 FT_BBox cbox; 548 FT_Glyph_Metrics* metrics = &glyph->root.metrics; 549 FT_Bool has_vertical_info; 550 551 552 if ( face->horizontal.number_Of_HMetrics ) 553 { 554 FT_Short horiBearingX = 0; 555 FT_UShort horiAdvance = 0; 556 557 558 ( (SFNT_Service)face->sfnt )->get_metrics( face, 0, 559 glyph_index, 560 &horiBearingX, 561 &horiAdvance ); 562 metrics->horiAdvance = horiAdvance; 563 metrics->horiBearingX = horiBearingX; 564 glyph->root.linearHoriAdvance = horiAdvance; 565 } 566 else 567 { 568 /* copy the _unscaled_ advance width */ 569 metrics->horiAdvance = decoder.glyph_width; 570 glyph->root.linearHoriAdvance = decoder.glyph_width; 571 } 572 573 glyph->root.internal->glyph_transformed = 0; 574 575 has_vertical_info = FT_BOOL( face->vertical_info && 576 face->vertical.number_Of_VMetrics > 0 ); 577 578 /* get the vertical metrics from the vmtx table if we have one */ 579 if ( has_vertical_info ) 580 { 581 FT_Short vertBearingY = 0; 582 FT_UShort vertAdvance = 0; 583 584 585 ( (SFNT_Service)face->sfnt )->get_metrics( face, 1, 586 glyph_index, 587 &vertBearingY, 588 &vertAdvance ); 589 metrics->vertBearingY = vertBearingY; 590 metrics->vertAdvance = vertAdvance; 591 } 592 else 593 { 594 /* make up vertical ones */ 595 if ( face->os2.version != 0xFFFFU ) 596 metrics->vertAdvance = (FT_Pos)( face->os2.sTypoAscender - 597 face->os2.sTypoDescender ); 598 else 599 metrics->vertAdvance = (FT_Pos)( face->horizontal.Ascender - 600 face->horizontal.Descender ); 601 } 602 603 glyph->root.linearVertAdvance = metrics->vertAdvance; 604 605 glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; 606 607 glyph->root.outline.flags = 0; 608 if ( size && size->root.metrics.y_ppem < 24 ) 609 glyph->root.outline.flags |= FT_OUTLINE_HIGH_PRECISION; 610 611 glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL; 612 613 /* apply the font matrix, if any */ 614 if ( font_matrix.xx != 0x10000L || font_matrix.yy != 0x10000L || 615 font_matrix.xy != 0 || font_matrix.yx != 0 ) 616 { 617 FT_Outline_Transform( &glyph->root.outline, &font_matrix ); 618 619 metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, 620 font_matrix.xx ); 621 metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, 622 font_matrix.yy ); 623 } 624 625 if ( font_offset.x || font_offset.y ) 626 { 627 FT_Outline_Translate( &glyph->root.outline, 628 font_offset.x, 629 font_offset.y ); 630 631 metrics->horiAdvance += font_offset.x; 632 metrics->vertAdvance += font_offset.y; 633 } 634 635 if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 || force_scaling ) 636 { 637 /* scale the outline and the metrics */ 638 FT_Int n; 639 FT_Outline* cur = &glyph->root.outline; 640 FT_Vector* vec = cur->points; 641 FT_Fixed x_scale = glyph->x_scale; 642 FT_Fixed y_scale = glyph->y_scale; 643 644 645 /* First of all, scale the points */ 646 if ( !hinting || !decoder.builder.hints_funcs ) 647 for ( n = cur->n_points; n > 0; n--, vec++ ) 648 { 649 vec->x = FT_MulFix( vec->x, x_scale ); 650 vec->y = FT_MulFix( vec->y, y_scale ); 651 } 652 653 /* Then scale the metrics */ 654 metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); 655 metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); 656 } 657 658 /* compute the other metrics */ 659 FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); 660 661 metrics->width = cbox.xMax - cbox.xMin; 662 metrics->height = cbox.yMax - cbox.yMin; 663 664 metrics->horiBearingX = cbox.xMin; 665 metrics->horiBearingY = cbox.yMax; 666 667 if ( has_vertical_info ) 668 metrics->vertBearingX = metrics->horiBearingX - 669 metrics->horiAdvance / 2; 670 else 671 { 672 if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) 673 ft_synthesize_vertical_metrics( metrics, 674 metrics->vertAdvance ); 675 } 676 } 677 } 678 679 return error; 680 } 681 682 683 /* END */ 684