1 /**************************************************************************** 2 * 3 * t1gload.c 4 * 5 * Type 1 Glyph Loader (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 "t1gload.h" 21 #include FT_INTERNAL_CALC_H 22 #include FT_INTERNAL_DEBUG_H 23 #include FT_INTERNAL_STREAM_H 24 #include FT_OUTLINE_H 25 #include FT_INTERNAL_POSTSCRIPT_AUX_H 26 #include FT_INTERNAL_CFF_TYPES_H 27 #include FT_DRIVER_H 28 29 #include "t1errors.h" 30 31 32 /************************************************************************** 33 * 34 * The macro FT_COMPONENT is used in trace mode. It is an implicit 35 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log 36 * messages during execution. 37 */ 38 #undef FT_COMPONENT 39 #define FT_COMPONENT t1gload 40 41 42 static FT_Error T1_Parse_Glyph_And_Get_Char_String(T1_Decoder decoder,FT_UInt glyph_index,FT_Data * char_string,FT_Bool * force_scaling)43 T1_Parse_Glyph_And_Get_Char_String( T1_Decoder decoder, 44 FT_UInt glyph_index, 45 FT_Data* char_string, 46 FT_Bool* force_scaling ) 47 { 48 T1_Face face = (T1_Face)decoder->builder.face; 49 T1_Font type1 = &face->type1; 50 FT_Error error = FT_Err_Ok; 51 52 PSAux_Service psaux = (PSAux_Service)face->psaux; 53 const T1_Decoder_Funcs decoder_funcs = psaux->t1_decoder_funcs; 54 PS_Decoder psdecoder; 55 56 #ifdef FT_CONFIG_OPTION_INCREMENTAL 57 FT_Incremental_InterfaceRec *inc = 58 face->root.internal->incremental_interface; 59 #endif 60 61 #ifdef T1_CONFIG_OPTION_OLD_ENGINE 62 PS_Driver driver = (PS_Driver)FT_FACE_DRIVER( face ); 63 #endif 64 65 66 decoder->font_matrix = type1->font_matrix; 67 decoder->font_offset = type1->font_offset; 68 69 #ifdef FT_CONFIG_OPTION_INCREMENTAL 70 71 /* For incremental fonts get the character data using the */ 72 /* callback function. */ 73 if ( inc ) 74 error = inc->funcs->get_glyph_data( inc->object, 75 glyph_index, char_string ); 76 else 77 78 #endif /* FT_CONFIG_OPTION_INCREMENTAL */ 79 80 /* For ordinary fonts get the character data stored in the face record. */ 81 { 82 char_string->pointer = type1->charstrings[glyph_index]; 83 char_string->length = (FT_Int)type1->charstrings_len[glyph_index]; 84 } 85 86 if ( !error ) 87 { 88 /* choose which renderer to use */ 89 #ifdef T1_CONFIG_OPTION_OLD_ENGINE 90 if ( driver->hinting_engine == FT_HINTING_FREETYPE || 91 decoder->builder.metrics_only ) 92 error = decoder_funcs->parse_charstrings_old( 93 decoder, 94 (FT_Byte*)char_string->pointer, 95 (FT_UInt)char_string->length ); 96 #else 97 if ( decoder->builder.metrics_only ) 98 error = decoder_funcs->parse_metrics( 99 decoder, 100 (FT_Byte*)char_string->pointer, 101 (FT_UInt)char_string->length ); 102 #endif 103 else 104 { 105 CFF_SubFontRec subfont; 106 107 108 psaux->ps_decoder_init( &psdecoder, decoder, TRUE ); 109 110 psaux->t1_make_subfont( FT_FACE( face ), 111 &face->type1.private_dict, &subfont ); 112 psdecoder.current_subfont = &subfont; 113 114 error = decoder_funcs->parse_charstrings( 115 &psdecoder, 116 (FT_Byte*)char_string->pointer, 117 (FT_ULong)char_string->length ); 118 119 /* Adobe's engine uses 16.16 numbers everywhere; */ 120 /* as a consequence, glyphs larger than 2000ppem get rejected */ 121 if ( FT_ERR_EQ( error, Glyph_Too_Big ) ) 122 { 123 /* this time, we retry unhinted and scale up the glyph later on */ 124 /* (the engine uses and sets the hardcoded value 0x10000 / 64 = */ 125 /* 0x400 for both `x_scale' and `y_scale' in this case) */ 126 ((T1_GlyphSlot)decoder->builder.glyph)->hint = FALSE; 127 128 *force_scaling = TRUE; 129 130 error = decoder_funcs->parse_charstrings( 131 &psdecoder, 132 (FT_Byte*)char_string->pointer, 133 (FT_ULong)char_string->length ); 134 } 135 } 136 } 137 138 #ifdef FT_CONFIG_OPTION_INCREMENTAL 139 140 /* Incremental fonts can optionally override the metrics. */ 141 if ( !error && inc && inc->funcs->get_glyph_metrics ) 142 { 143 FT_Incremental_MetricsRec metrics; 144 145 146 metrics.bearing_x = FIXED_TO_INT( decoder->builder.left_bearing.x ); 147 metrics.bearing_y = 0; 148 metrics.advance = FIXED_TO_INT( decoder->builder.advance.x ); 149 metrics.advance_v = FIXED_TO_INT( decoder->builder.advance.y ); 150 151 error = inc->funcs->get_glyph_metrics( inc->object, 152 glyph_index, FALSE, &metrics ); 153 154 decoder->builder.left_bearing.x = INT_TO_FIXED( metrics.bearing_x ); 155 decoder->builder.advance.x = INT_TO_FIXED( metrics.advance ); 156 decoder->builder.advance.y = INT_TO_FIXED( metrics.advance_v ); 157 } 158 159 #endif /* FT_CONFIG_OPTION_INCREMENTAL */ 160 161 return error; 162 } 163 164 165 FT_CALLBACK_DEF( FT_Error ) T1_Parse_Glyph(T1_Decoder decoder,FT_UInt glyph_index)166 T1_Parse_Glyph( T1_Decoder decoder, 167 FT_UInt glyph_index ) 168 { 169 FT_Data glyph_data; 170 FT_Bool force_scaling = FALSE; 171 FT_Error error = T1_Parse_Glyph_And_Get_Char_String( 172 decoder, glyph_index, &glyph_data, 173 &force_scaling ); 174 175 176 #ifdef FT_CONFIG_OPTION_INCREMENTAL 177 178 if ( !error ) 179 { 180 T1_Face face = (T1_Face)decoder->builder.face; 181 182 183 if ( face->root.internal->incremental_interface ) 184 face->root.internal->incremental_interface->funcs->free_glyph_data( 185 face->root.internal->incremental_interface->object, 186 &glyph_data ); 187 } 188 189 #endif /* FT_CONFIG_OPTION_INCREMENTAL */ 190 191 return error; 192 } 193 194 195 /*************************************************************************/ 196 /*************************************************************************/ 197 /*************************************************************************/ 198 /********** *********/ 199 /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/ 200 /********** *********/ 201 /********** The following code is in charge of computing *********/ 202 /********** the maximum advance width of the font. It *********/ 203 /********** quickly processes each glyph charstring to *********/ 204 /********** extract the value from either a `sbw' or `seac' *********/ 205 /********** operator. *********/ 206 /********** *********/ 207 /*************************************************************************/ 208 /*************************************************************************/ 209 /*************************************************************************/ 210 211 212 FT_LOCAL_DEF( FT_Error ) T1_Compute_Max_Advance(T1_Face face,FT_Pos * max_advance)213 T1_Compute_Max_Advance( T1_Face face, 214 FT_Pos* max_advance ) 215 { 216 FT_Error error; 217 T1_DecoderRec decoder; 218 FT_Int glyph_index; 219 T1_Font type1 = &face->type1; 220 PSAux_Service psaux = (PSAux_Service)face->psaux; 221 222 223 FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) ); 224 225 *max_advance = 0; 226 227 /* initialize load decoder */ 228 error = psaux->t1_decoder_funcs->init( &decoder, 229 (FT_Face)face, 230 0, /* size */ 231 0, /* glyph slot */ 232 (FT_Byte**)type1->glyph_names, 233 face->blend, 234 0, 235 FT_RENDER_MODE_NORMAL, 236 T1_Parse_Glyph ); 237 if ( error ) 238 return error; 239 240 decoder.builder.metrics_only = 1; 241 decoder.builder.load_points = 0; 242 243 decoder.num_subrs = type1->num_subrs; 244 decoder.subrs = type1->subrs; 245 decoder.subrs_len = type1->subrs_len; 246 decoder.subrs_hash = type1->subrs_hash; 247 248 decoder.buildchar = face->buildchar; 249 decoder.len_buildchar = face->len_buildchar; 250 251 *max_advance = 0; 252 253 FT_TRACE6(( "T1_Compute_Max_Advance:\n" )); 254 255 /* for each glyph, parse the glyph charstring and extract */ 256 /* the advance width */ 257 for ( glyph_index = 0; glyph_index < type1->num_glyphs; glyph_index++ ) 258 { 259 /* now get load the unscaled outline */ 260 (void)T1_Parse_Glyph( &decoder, (FT_UInt)glyph_index ); 261 if ( glyph_index == 0 || decoder.builder.advance.x > *max_advance ) 262 *max_advance = decoder.builder.advance.x; 263 264 /* ignore the error if one occurred - skip to next glyph */ 265 } 266 267 FT_TRACE6(( "T1_Compute_Max_Advance: max advance: %f\n", 268 *max_advance / 65536.0 )); 269 270 psaux->t1_decoder_funcs->done( &decoder ); 271 272 return FT_Err_Ok; 273 } 274 275 276 FT_LOCAL_DEF( FT_Error ) T1_Get_Advances(FT_Face t1face,FT_UInt first,FT_UInt count,FT_Int32 load_flags,FT_Fixed * advances)277 T1_Get_Advances( FT_Face t1face, /* T1_Face */ 278 FT_UInt first, 279 FT_UInt count, 280 FT_Int32 load_flags, 281 FT_Fixed* advances ) 282 { 283 T1_Face face = (T1_Face)t1face; 284 T1_DecoderRec decoder; 285 T1_Font type1 = &face->type1; 286 PSAux_Service psaux = (PSAux_Service)face->psaux; 287 FT_UInt nn; 288 FT_Error error; 289 290 291 FT_TRACE5(( "T1_Get_Advances:\n" )); 292 293 if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) 294 { 295 for ( nn = 0; nn < count; nn++ ) 296 { 297 advances[nn] = 0; 298 299 FT_TRACE5(( " idx %d: advance height 0 font units\n", 300 first + nn )); 301 } 302 303 return FT_Err_Ok; 304 } 305 306 error = psaux->t1_decoder_funcs->init( &decoder, 307 (FT_Face)face, 308 0, /* size */ 309 0, /* glyph slot */ 310 (FT_Byte**)type1->glyph_names, 311 face->blend, 312 0, 313 FT_RENDER_MODE_NORMAL, 314 T1_Parse_Glyph ); 315 if ( error ) 316 return error; 317 318 decoder.builder.metrics_only = 1; 319 decoder.builder.load_points = 0; 320 321 decoder.num_subrs = type1->num_subrs; 322 decoder.subrs = type1->subrs; 323 decoder.subrs_len = type1->subrs_len; 324 decoder.subrs_hash = type1->subrs_hash; 325 326 decoder.buildchar = face->buildchar; 327 decoder.len_buildchar = face->len_buildchar; 328 329 for ( nn = 0; nn < count; nn++ ) 330 { 331 error = T1_Parse_Glyph( &decoder, first + nn ); 332 if ( !error ) 333 advances[nn] = FIXED_TO_INT( decoder.builder.advance.x ); 334 else 335 advances[nn] = 0; 336 337 FT_TRACE5(( " idx %d: advance width %d font unit%s\n", 338 first + nn, 339 advances[nn], 340 advances[nn] == 1 ? "" : "s" )); 341 } 342 343 return FT_Err_Ok; 344 } 345 346 347 FT_LOCAL_DEF( FT_Error ) T1_Load_Glyph(FT_GlyphSlot t1glyph,FT_Size t1size,FT_UInt glyph_index,FT_Int32 load_flags)348 T1_Load_Glyph( FT_GlyphSlot t1glyph, /* T1_GlyphSlot */ 349 FT_Size t1size, /* T1_Size */ 350 FT_UInt glyph_index, 351 FT_Int32 load_flags ) 352 { 353 T1_GlyphSlot glyph = (T1_GlyphSlot)t1glyph; 354 FT_Error error; 355 T1_DecoderRec decoder; 356 T1_Face face = (T1_Face)t1glyph->face; 357 FT_Bool hinting; 358 FT_Bool scaled; 359 FT_Bool force_scaling = FALSE; 360 T1_Font type1 = &face->type1; 361 PSAux_Service psaux = (PSAux_Service)face->psaux; 362 const T1_Decoder_Funcs decoder_funcs = psaux->t1_decoder_funcs; 363 364 FT_Matrix font_matrix; 365 FT_Vector font_offset; 366 FT_Data glyph_data; 367 FT_Bool must_finish_decoder = FALSE; 368 #ifdef FT_CONFIG_OPTION_INCREMENTAL 369 FT_Bool glyph_data_loaded = 0; 370 #endif 371 372 373 #ifdef FT_CONFIG_OPTION_INCREMENTAL 374 if ( glyph_index >= (FT_UInt)face->root.num_glyphs && 375 !face->root.internal->incremental_interface ) 376 #else 377 if ( glyph_index >= (FT_UInt)face->root.num_glyphs ) 378 #endif /* FT_CONFIG_OPTION_INCREMENTAL */ 379 { 380 error = FT_THROW( Invalid_Argument ); 381 goto Exit; 382 } 383 384 FT_TRACE1(( "T1_Load_Glyph: glyph index %d\n", glyph_index )); 385 386 FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) ); 387 388 if ( load_flags & FT_LOAD_NO_RECURSE ) 389 load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; 390 391 if ( t1size ) 392 { 393 glyph->x_scale = t1size->metrics.x_scale; 394 glyph->y_scale = t1size->metrics.y_scale; 395 } 396 else 397 { 398 glyph->x_scale = 0x10000L; 399 glyph->y_scale = 0x10000L; 400 } 401 402 t1glyph->outline.n_points = 0; 403 t1glyph->outline.n_contours = 0; 404 405 hinting = FT_BOOL( !( load_flags & FT_LOAD_NO_SCALE ) && 406 !( load_flags & FT_LOAD_NO_HINTING ) ); 407 scaled = FT_BOOL( !( load_flags & FT_LOAD_NO_SCALE ) ); 408 409 glyph->hint = hinting; 410 glyph->scaled = scaled; 411 t1glyph->format = FT_GLYPH_FORMAT_OUTLINE; 412 413 error = decoder_funcs->init( &decoder, 414 t1glyph->face, 415 t1size, 416 t1glyph, 417 (FT_Byte**)type1->glyph_names, 418 face->blend, 419 hinting, 420 FT_LOAD_TARGET_MODE( load_flags ), 421 T1_Parse_Glyph ); 422 if ( error ) 423 goto Exit; 424 425 must_finish_decoder = TRUE; 426 427 decoder.builder.no_recurse = FT_BOOL( load_flags & FT_LOAD_NO_RECURSE ); 428 429 decoder.num_subrs = type1->num_subrs; 430 decoder.subrs = type1->subrs; 431 decoder.subrs_len = type1->subrs_len; 432 decoder.subrs_hash = type1->subrs_hash; 433 434 decoder.buildchar = face->buildchar; 435 decoder.len_buildchar = face->len_buildchar; 436 437 /* now load the unscaled outline */ 438 error = T1_Parse_Glyph_And_Get_Char_String( &decoder, glyph_index, 439 &glyph_data, 440 &force_scaling ); 441 if ( error ) 442 goto Exit; 443 #ifdef FT_CONFIG_OPTION_INCREMENTAL 444 glyph_data_loaded = 1; 445 #endif 446 447 hinting = glyph->hint; 448 font_matrix = decoder.font_matrix; 449 font_offset = decoder.font_offset; 450 451 /* save new glyph tables */ 452 decoder_funcs->done( &decoder ); 453 454 must_finish_decoder = FALSE; 455 456 /* now, set the metrics -- this is rather simple, as */ 457 /* the left side bearing is the xMin, and the top side */ 458 /* bearing the yMax */ 459 if ( !error ) 460 { 461 t1glyph->outline.flags &= FT_OUTLINE_OWNER; 462 t1glyph->outline.flags |= FT_OUTLINE_REVERSE_FILL; 463 464 /* for composite glyphs, return only left side bearing and */ 465 /* advance width */ 466 if ( load_flags & FT_LOAD_NO_RECURSE ) 467 { 468 FT_Slot_Internal internal = t1glyph->internal; 469 470 471 t1glyph->metrics.horiBearingX = 472 FIXED_TO_INT( decoder.builder.left_bearing.x ); 473 t1glyph->metrics.horiAdvance = 474 FIXED_TO_INT( decoder.builder.advance.x ); 475 476 internal->glyph_matrix = font_matrix; 477 internal->glyph_delta = font_offset; 478 internal->glyph_transformed = 1; 479 } 480 else 481 { 482 FT_BBox cbox; 483 FT_Glyph_Metrics* metrics = &t1glyph->metrics; 484 485 486 /* copy the _unscaled_ advance width */ 487 metrics->horiAdvance = 488 FIXED_TO_INT( decoder.builder.advance.x ); 489 t1glyph->linearHoriAdvance = 490 FIXED_TO_INT( decoder.builder.advance.x ); 491 t1glyph->internal->glyph_transformed = 0; 492 493 if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) 494 { 495 /* make up vertical ones */ 496 metrics->vertAdvance = ( face->type1.font_bbox.yMax - 497 face->type1.font_bbox.yMin ) >> 16; 498 t1glyph->linearVertAdvance = metrics->vertAdvance; 499 } 500 else 501 { 502 metrics->vertAdvance = 503 FIXED_TO_INT( decoder.builder.advance.y ); 504 t1glyph->linearVertAdvance = 505 FIXED_TO_INT( decoder.builder.advance.y ); 506 } 507 508 t1glyph->format = FT_GLYPH_FORMAT_OUTLINE; 509 510 if ( t1size && t1size->metrics.y_ppem < 24 ) 511 t1glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION; 512 513 #if 1 514 /* apply the font matrix, if any */ 515 if ( font_matrix.xx != 0x10000L || font_matrix.yy != 0x10000L || 516 font_matrix.xy != 0 || font_matrix.yx != 0 ) 517 { 518 FT_Outline_Transform( &t1glyph->outline, &font_matrix ); 519 520 metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, 521 font_matrix.xx ); 522 metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, 523 font_matrix.yy ); 524 } 525 526 if ( font_offset.x || font_offset.y ) 527 { 528 FT_Outline_Translate( &t1glyph->outline, 529 font_offset.x, 530 font_offset.y ); 531 532 metrics->horiAdvance += font_offset.x; 533 metrics->vertAdvance += font_offset.y; 534 } 535 #endif 536 537 if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 || force_scaling ) 538 { 539 /* scale the outline and the metrics */ 540 FT_Int n; 541 FT_Outline* cur = decoder.builder.base; 542 FT_Vector* vec = cur->points; 543 FT_Fixed x_scale = glyph->x_scale; 544 FT_Fixed y_scale = glyph->y_scale; 545 546 547 /* First of all, scale the points, if we are not hinting */ 548 if ( !hinting || !decoder.builder.hints_funcs ) 549 for ( n = cur->n_points; n > 0; n--, vec++ ) 550 { 551 vec->x = FT_MulFix( vec->x, x_scale ); 552 vec->y = FT_MulFix( vec->y, y_scale ); 553 } 554 555 /* Then scale the metrics */ 556 metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); 557 metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); 558 } 559 560 /* compute the other metrics */ 561 FT_Outline_Get_CBox( &t1glyph->outline, &cbox ); 562 563 metrics->width = cbox.xMax - cbox.xMin; 564 metrics->height = cbox.yMax - cbox.yMin; 565 566 metrics->horiBearingX = cbox.xMin; 567 metrics->horiBearingY = cbox.yMax; 568 569 if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) 570 { 571 /* make up vertical ones */ 572 ft_synthesize_vertical_metrics( metrics, 573 metrics->vertAdvance ); 574 } 575 } 576 577 /* Set control data to the glyph charstrings. Note that this is */ 578 /* _not_ zero-terminated. */ 579 t1glyph->control_data = (FT_Byte*)glyph_data.pointer; 580 t1glyph->control_len = glyph_data.length; 581 } 582 583 584 Exit: 585 586 #ifdef FT_CONFIG_OPTION_INCREMENTAL 587 if ( glyph_data_loaded && face->root.internal->incremental_interface ) 588 { 589 face->root.internal->incremental_interface->funcs->free_glyph_data( 590 face->root.internal->incremental_interface->object, 591 &glyph_data ); 592 593 /* Set the control data to null - it is no longer available if */ 594 /* loaded incrementally. */ 595 t1glyph->control_data = NULL; 596 t1glyph->control_len = 0; 597 } 598 #endif 599 600 if ( must_finish_decoder ) 601 decoder_funcs->done( &decoder ); 602 603 return error; 604 } 605 606 607 /* END */ 608