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