| OLD | NEW |
| 1 /***************************************************************************/ | 1 /***************************************************************************/ |
| 2 /* */ | 2 /* */ |
| 3 /* cf2ft.c */ | 3 /* cf2ft.c */ |
| 4 /* */ | 4 /* */ |
| 5 /* FreeType Glue Component to Adobe's Interpreter (body). */ | 5 /* FreeType Glue Component to Adobe's Interpreter (body). */ |
| 6 /* */ | 6 /* */ |
| 7 /* Copyright 2013 Adobe Systems Incorporated. */ | 7 /* Copyright 2013-2014 Adobe Systems Incorporated. */ |
| 8 /* */ | 8 /* */ |
| 9 /* This software, and all works of authorship, whether in source or */ | 9 /* This software, and all works of authorship, whether in source or */ |
| 10 /* object code form as indicated by the copyright notice(s) included */ | 10 /* object code form as indicated by the copyright notice(s) included */ |
| 11 /* herein (collectively, the "Work") is made available, and may only be */ | 11 /* herein (collectively, the "Work") is made available, and may only be */ |
| 12 /* used, modified, and distributed under the FreeType Project License, */ | 12 /* used, modified, and distributed under the FreeType Project License, */ |
| 13 /* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ | 13 /* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ |
| 14 /* FreeType Project License, each contributor to the Work hereby grants */ | 14 /* FreeType Project License, each contributor to the Work hereby grants */ |
| 15 /* to any individual or legal entity exercising permissions granted by */ | 15 /* to any individual or legal entity exercising permissions granted by */ |
| 16 /* the FreeType Project License and this section (hereafter, "You" or */ | 16 /* the FreeType Project License and this section (hereafter, "You" or */ |
| 17 /* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ | 17 /* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ |
| (...skipping 12 matching lines...) Expand all Loading... |
| 30 /* */ | 30 /* */ |
| 31 /* By using, modifying, or distributing the Work you indicate that you */ | 31 /* By using, modifying, or distributing the Work you indicate that you */ |
| 32 /* have read and understood the terms and conditions of the */ | 32 /* have read and understood the terms and conditions of the */ |
| 33 /* FreeType Project License as well as those provided in this section, */ | 33 /* FreeType Project License as well as those provided in this section, */ |
| 34 /* and you accept them fully. */ | 34 /* and you accept them fully. */ |
| 35 /* */ | 35 /* */ |
| 36 /***************************************************************************/ | 36 /***************************************************************************/ |
| 37 | 37 |
| 38 | 38 |
| 39 #include "cf2ft.h" | 39 #include "cf2ft.h" |
| 40 #include "../../include/freetype/internal/ftdebug.h" | 40 #include FT_INTERNAL_DEBUG_H |
| 41 | 41 |
| 42 #include "cf2font.h" | 42 #include "cf2font.h" |
| 43 #include "cf2error.h" | 43 #include "cf2error.h" |
| 44 | 44 |
| 45 | 45 |
| 46 #define CF2_MAX_SIZE cf2_intToFixed( 2000 ) /* max ppem */ | 46 #define CF2_MAX_SIZE cf2_intToFixed( 2000 ) /* max ppem */ |
| 47 | 47 |
| 48 | 48 |
| 49 /* | 49 /* |
| 50 * This check should avoid most internal overflow cases. Clients should | 50 * This check should avoid most internal overflow cases. Clients should |
| 51 * generally respond to `Glyph_Too_Big' by getting a glyph outline | 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. | 52 * at EM size, scaling it and filling it as a graphics operation. |
| 53 * | 53 * |
| 54 */ | 54 */ |
| 55 static FT_Error | 55 static FT_Error |
| 56 cf2_checkTransform( const CF2_Matrix* transform, | 56 cf2_checkTransform( const CF2_Matrix* transform, |
| 57 CF2_Int unitsPerEm ) | 57 CF2_Int unitsPerEm ) |
| 58 { | 58 { |
| 59 CF2_Fixed maxScale; | 59 CF2_Fixed maxScale; |
| 60 | 60 |
| 61 | 61 |
| 62 FT_ASSERT( unitsPerEm > 0 ); | 62 FT_ASSERT( unitsPerEm > 0 ); |
| 63 | 63 |
| 64 FT_ASSERT( transform->a > 0 && transform->d > 0 ); | 64 if ( transform->a <= 0 || transform->d <= 0 ) |
| 65 return FT_THROW( Invalid_Size_Handle ); |
| 66 |
| 65 FT_ASSERT( transform->b == 0 && transform->c == 0 ); | 67 FT_ASSERT( transform->b == 0 && transform->c == 0 ); |
| 66 FT_ASSERT( transform->tx == 0 && transform->ty == 0 ); | 68 FT_ASSERT( transform->tx == 0 && transform->ty == 0 ); |
| 67 | 69 |
| 68 if ( unitsPerEm > 0x7FFF ) | 70 if ( unitsPerEm > 0x7FFF ) |
| 69 return FT_THROW( Glyph_Too_Big ); | 71 return FT_THROW( Glyph_Too_Big ); |
| 70 | 72 |
| 71 maxScale = FT_DivFix( CF2_MAX_SIZE, cf2_intToFixed( unitsPerEm ) ); | 73 maxScale = FT_DivFix( CF2_MAX_SIZE, cf2_intToFixed( unitsPerEm ) ); |
| 72 | 74 |
| 73 if ( transform->a > maxScale || transform->d > maxScale ) | 75 if ( transform->a > maxScale || transform->d > maxScale ) |
| 74 return FT_THROW( Glyph_Too_Big ); | 76 return FT_THROW( Glyph_Too_Big ); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 /* note: two successive moves simply close the contour twice */ | 135 /* note: two successive moves simply close the contour twice */ |
| 134 cff_builder_close_contour( builder ); | 136 cff_builder_close_contour( builder ); |
| 135 builder->path_begun = 0; | 137 builder->path_begun = 0; |
| 136 } | 138 } |
| 137 | 139 |
| 138 | 140 |
| 139 static void | 141 static void |
| 140 cf2_builder_lineTo( CF2_OutlineCallbacks callbacks, | 142 cf2_builder_lineTo( CF2_OutlineCallbacks callbacks, |
| 141 const CF2_CallbackParams params ) | 143 const CF2_CallbackParams params ) |
| 142 { | 144 { |
| 145 FT_Error error; |
| 146 |
| 143 /* downcast the object pointer */ | 147 /* downcast the object pointer */ |
| 144 CF2_Outline outline = (CF2_Outline)callbacks; | 148 CF2_Outline outline = (CF2_Outline)callbacks; |
| 145 CFF_Builder* builder; | 149 CFF_Builder* builder; |
| 146 FT_Error error; | |
| 147 | 150 |
| 148 | 151 |
| 149 FT_ASSERT( outline && outline->decoder ); | 152 FT_ASSERT( outline && outline->decoder ); |
| 150 FT_ASSERT( params->op == CF2_PathOpLineTo ); | 153 FT_ASSERT( params->op == CF2_PathOpLineTo ); |
| 151 | 154 |
| 152 builder = &outline->decoder->builder; | 155 builder = &outline->decoder->builder; |
| 153 | 156 |
| 154 if ( !builder->path_begun ) | 157 if ( !builder->path_begun ) |
| 155 { | 158 { |
| 156 /* record the move before the line; also check points and set */ | 159 /* record the move before the line; also check points and set */ |
| 157 /* `path_begun' */ | 160 /* `path_begun' */ |
| 158 » » error = cff_builder_start_point(builder, | 161 error = cff_builder_start_point( builder, |
| 159 params->pt0.x, | 162 params->pt0.x, |
| 160 params->pt0.y ); | 163 params->pt0.y ); |
| 161 » » if (callbacks && callbacks->error) *callbacks->error = error; | 164 if ( error ) |
| 162 » » if (error) return; | 165 { |
| 166 if ( !*callbacks->error ) |
| 167 *callbacks->error = error; |
| 168 return; |
| 169 } |
| 163 } | 170 } |
| 164 | 171 |
| 165 /* `cff_builder_add_point1' includes a check_points call for one point */ | 172 /* `cff_builder_add_point1' includes a check_points call for one point */ |
| 166 » error = cff_builder_add_point1(builder, | 173 error = cff_builder_add_point1( builder, |
| 167 params->pt1.x, | 174 params->pt1.x, |
| 168 params->pt1.y ); | 175 params->pt1.y ); |
| 169 » if (callbacks && callbacks->error) *callbacks->error = error; | 176 if ( error ) |
| 177 { |
| 178 if ( !*callbacks->error ) |
| 179 *callbacks->error = error; |
| 180 return; |
| 181 } |
| 170 } | 182 } |
| 171 | 183 |
| 172 | 184 |
| 173 static void | 185 static void |
| 174 cf2_builder_cubeTo( CF2_OutlineCallbacks callbacks, | 186 cf2_builder_cubeTo( CF2_OutlineCallbacks callbacks, |
| 175 const CF2_CallbackParams params ) | 187 const CF2_CallbackParams params ) |
| 176 { | 188 { |
| 189 FT_Error error; |
| 190 |
| 177 /* downcast the object pointer */ | 191 /* downcast the object pointer */ |
| 178 CF2_Outline outline = (CF2_Outline)callbacks; | 192 CF2_Outline outline = (CF2_Outline)callbacks; |
| 179 CFF_Builder* builder; | 193 CFF_Builder* builder; |
| 180 FT_Error error; | |
| 181 | 194 |
| 182 | 195 |
| 183 FT_ASSERT( outline && outline->decoder ); | 196 FT_ASSERT( outline && outline->decoder ); |
| 184 FT_ASSERT( params->op == CF2_PathOpCubeTo ); | 197 FT_ASSERT( params->op == CF2_PathOpCubeTo ); |
| 185 | 198 |
| 186 builder = &outline->decoder->builder; | 199 builder = &outline->decoder->builder; |
| 187 | 200 |
| 188 if ( !builder->path_begun ) | 201 if ( !builder->path_begun ) |
| 189 { | 202 { |
| 190 /* record the move before the line; also check points and set */ | 203 /* record the move before the line; also check points and set */ |
| 191 /* `path_begun' */ | 204 /* `path_begun' */ |
| 192 error = cff_builder_start_point( builder, | 205 error = cff_builder_start_point( builder, |
| 193 params->pt0.x, | 206 params->pt0.x, |
| 194 params->pt0.y ); | 207 params->pt0.y ); |
| 195 » if (callbacks && callbacks->error) *callbacks->error = error; | 208 if ( error ) |
| 196 » if (error) return; | 209 { |
| 210 if ( !*callbacks->error ) |
| 211 *callbacks->error = error; |
| 212 return; |
| 213 } |
| 197 } | 214 } |
| 198 | 215 |
| 199 /* prepare room for 3 points: 2 off-curve, 1 on-curve */ | 216 /* prepare room for 3 points: 2 off-curve, 1 on-curve */ |
| 200 error = cff_check_points( builder, 3 ); | 217 error = cff_check_points( builder, 3 ); |
| 201 » if (callbacks && callbacks->error) *callbacks->error = error; | 218 if ( error ) |
| 202 » if (error) return; | 219 { |
| 220 if ( !*callbacks->error ) |
| 221 *callbacks->error = error; |
| 222 return; |
| 223 } |
| 203 | 224 |
| 204 cff_builder_add_point( builder, | 225 cff_builder_add_point( builder, |
| 205 params->pt1.x, | 226 params->pt1.x, |
| 206 params->pt1.y, 0 ); | 227 params->pt1.y, 0 ); |
| 207 cff_builder_add_point( builder, | 228 cff_builder_add_point( builder, |
| 208 params->pt2.x, | 229 params->pt2.x, |
| 209 params->pt2.y, 0 ); | 230 params->pt2.y, 0 ); |
| 210 cff_builder_add_point( builder, | 231 cff_builder_add_point( builder, |
| 211 params->pt3.x, | 232 params->pt3.x, |
| 212 params->pt3.y, 1 ); | 233 params->pt3.y, 1 ); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 238 FT_Bool* scaled ) | 259 FT_Bool* scaled ) |
| 239 { | 260 { |
| 240 FT_ASSERT( decoder && decoder->builder.glyph ); | 261 FT_ASSERT( decoder && decoder->builder.glyph ); |
| 241 | 262 |
| 242 /* note: FreeType scale includes a factor of 64 */ | 263 /* note: FreeType scale includes a factor of 64 */ |
| 243 *hinted = decoder->builder.glyph->hint; | 264 *hinted = decoder->builder.glyph->hint; |
| 244 *scaled = decoder->builder.glyph->scaled; | 265 *scaled = decoder->builder.glyph->scaled; |
| 245 | 266 |
| 246 if ( *hinted ) | 267 if ( *hinted ) |
| 247 { | 268 { |
| 248 *x_scale = FT_DivFix( decoder->builder.glyph->x_scale, | 269 *x_scale = ( decoder->builder.glyph->x_scale + 32 ) / 64; |
| 249 cf2_intToFixed( 64 ) ); | 270 *y_scale = ( decoder->builder.glyph->y_scale + 32 ) / 64; |
| 250 *y_scale = FT_DivFix( decoder->builder.glyph->y_scale, | |
| 251 cf2_intToFixed( 64 ) ); | |
| 252 } | 271 } |
| 253 else | 272 else |
| 254 { | 273 { |
| 255 /* for unhinted outlines, `cff_slot_load' does the scaling, */ | 274 /* for unhinted outlines, `cff_slot_load' does the scaling, */ |
| 256 /* thus render at `unity' scale */ | 275 /* thus render at `unity' scale */ |
| 257 | 276 |
| 258 *x_scale = 0x0400; /* 1/64 as 16.16 */ | 277 *x_scale = 0x0400; /* 1/64 as 16.16 */ |
| 259 *y_scale = 0x0400; | 278 *y_scale = 0x0400; |
| 260 } | 279 } |
| 261 } | 280 } |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 346 &transform.d, | 365 &transform.d, |
| 347 &hinted, | 366 &hinted, |
| 348 &scaled ); | 367 &scaled ); |
| 349 | 368 |
| 350 font->renderingFlags = 0; | 369 font->renderingFlags = 0; |
| 351 if ( hinted ) | 370 if ( hinted ) |
| 352 font->renderingFlags |= CF2_FlagsHinted; | 371 font->renderingFlags |= CF2_FlagsHinted; |
| 353 if ( scaled && !driver->no_stem_darkening ) | 372 if ( scaled && !driver->no_stem_darkening ) |
| 354 font->renderingFlags |= CF2_FlagsDarkened; | 373 font->renderingFlags |= CF2_FlagsDarkened; |
| 355 | 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 |
| 356 /* now get an outline for this glyph; */ | 384 /* now get an outline for this glyph; */ |
| 357 /* also get units per em to validate scale */ | 385 /* also get units per em to validate scale */ |
| 358 font->unitsPerEm = (CF2_Int)cf2_getUnitsPerEm( decoder ); | 386 font->unitsPerEm = (CF2_Int)cf2_getUnitsPerEm( decoder ); |
| 359 | 387 |
| 360 error2 = cf2_checkTransform( &transform, font->unitsPerEm ); | 388 if ( scaled ) |
| 361 if ( error2 ) | 389 { |
| 362 return error2; | 390 error2 = cf2_checkTransform( &transform, font->unitsPerEm ); |
| 391 if ( error2 ) |
| 392 return error2; |
| 393 } |
| 363 | 394 |
| 364 error2 = cf2_getGlyphOutline( font, &buf, &transform, &glyphWidth ); | 395 error2 = cf2_getGlyphOutline( font, &buf, &transform, &glyphWidth ); |
| 365 if ( error2 ) | 396 if ( error2 ) |
| 366 return FT_ERR( Invalid_File_Format ); | 397 return FT_ERR( Invalid_File_Format ); |
| 367 | 398 |
| 368 cf2_setGlyphWidth( &font->outline, glyphWidth ); | 399 cf2_setGlyphWidth( &font->outline, glyphWidth ); |
| 369 | 400 |
| 370 return FT_Err_Ok; | 401 return FT_Err_Ok; |
| 371 } | 402 } |
| 372 } | 403 } |
| 373 | 404 |
| 374 | 405 |
| 375 /* get pointer to current FreeType subfont (based on current glyphID) */ | 406 /* get pointer to current FreeType subfont (based on current glyphID) */ |
| 376 FT_LOCAL_DEF( CFF_SubFont ) | 407 FT_LOCAL_DEF( CFF_SubFont ) |
| 377 cf2_getSubfont( CFF_Decoder* decoder ) | 408 cf2_getSubfont( CFF_Decoder* decoder ) |
| 378 { | 409 { |
| 379 FT_ASSERT( decoder && decoder->current_subfont ); | 410 FT_ASSERT( decoder && decoder->current_subfont ); |
| 380 | 411 |
| 381 return decoder->current_subfont; | 412 return decoder->current_subfont; |
| 382 } | 413 } |
| 383 | 414 |
| 384 | 415 |
| 385 /* get `y_ppem' from `CFF_Size' */ | 416 /* get `y_ppem' from `CFF_Size' */ |
| 386 FT_LOCAL_DEF( CF2_Fixed ) | 417 FT_LOCAL_DEF( CF2_Fixed ) |
| 387 cf2_getPpemY( CFF_Decoder* decoder ) | 418 cf2_getPpemY( CFF_Decoder* decoder ) |
| 388 { | 419 { |
| 389 FT_ASSERT( decoder && | 420 FT_ASSERT( decoder && |
| 390 decoder->builder.face && | 421 decoder->builder.face && |
| 391 decoder->builder.face->root.size ); | 422 decoder->builder.face->root.size ); |
| 392 FT_ASSERT( decoder->builder.face->root.size->metrics.y_ppem ); | |
| 393 | 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 */ |
| 394 return cf2_intToFixed( | 433 return cf2_intToFixed( |
| 395 decoder->builder.face->root.size->metrics.y_ppem ); | 434 decoder->builder.face->root.size->metrics.y_ppem ); |
| 396 } | 435 } |
| 397 | 436 |
| 398 | 437 |
| 399 /* get standard stem widths for the current subfont; */ | 438 /* get standard stem widths for the current subfont; */ |
| 400 /* FreeType stores these as integer font units */ | 439 /* FreeType stores these as integer font units */ |
| 401 /* (note: variable names seem swapped) */ | 440 /* (note: variable names seem swapped) */ |
| 402 FT_LOCAL_DEF( CF2_Fixed ) | 441 FT_LOCAL_DEF( CF2_Fixed ) |
| 403 cf2_getStdVW( CFF_Decoder* decoder ) | 442 cf2_getStdVW( CFF_Decoder* decoder ) |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 501 } | 540 } |
| 502 | 541 |
| 503 | 542 |
| 504 /* convert unbiased subroutine index to `CF2_Buffer' and */ | 543 /* convert unbiased subroutine index to `CF2_Buffer' and */ |
| 505 /* return 0 on success */ | 544 /* return 0 on success */ |
| 506 FT_LOCAL_DEF( CF2_Int ) | 545 FT_LOCAL_DEF( CF2_Int ) |
| 507 cf2_initGlobalRegionBuffer( CFF_Decoder* decoder, | 546 cf2_initGlobalRegionBuffer( CFF_Decoder* decoder, |
| 508 CF2_UInt idx, | 547 CF2_UInt idx, |
| 509 CF2_Buffer buf ) | 548 CF2_Buffer buf ) |
| 510 { | 549 { |
| 511 FT_ASSERT( decoder && decoder->globals ); | 550 FT_ASSERT( decoder ); |
| 512 | 551 |
| 513 FT_ZERO( buf ); | 552 FT_ZERO( buf ); |
| 514 | 553 |
| 515 idx += decoder->globals_bias; | 554 idx += decoder->globals_bias; |
| 516 if ( idx >= decoder->num_globals ) | 555 if ( idx >= decoder->num_globals ) |
| 517 return TRUE; /* error */ | 556 return TRUE; /* error */ |
| 518 | 557 |
| 558 FT_ASSERT( decoder->globals ); |
| 559 |
| 519 buf->start = | 560 buf->start = |
| 520 buf->ptr = decoder->globals[idx]; | 561 buf->ptr = decoder->globals[idx]; |
| 521 buf->end = decoder->globals[idx + 1]; | 562 buf->end = decoder->globals[idx + 1]; |
| 522 | 563 |
| 523 return FALSE; /* success */ | 564 return FALSE; /* success */ |
| 524 } | 565 } |
| 525 | 566 |
| 526 | 567 |
| 527 /* convert AdobeStandardEncoding code to CF2_Buffer; */ | 568 /* convert AdobeStandardEncoding code to CF2_Buffer; */ |
| 528 /* used for seac component */ | 569 /* used for seac component */ |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 574 (FT_Byte**)&buf->start, | 615 (FT_Byte**)&buf->start, |
| 575 (FT_ULong)( buf->end - buf->start ) ); | 616 (FT_ULong)( buf->end - buf->start ) ); |
| 576 } | 617 } |
| 577 | 618 |
| 578 | 619 |
| 579 FT_LOCAL_DEF( CF2_Int ) | 620 FT_LOCAL_DEF( CF2_Int ) |
| 580 cf2_initLocalRegionBuffer( CFF_Decoder* decoder, | 621 cf2_initLocalRegionBuffer( CFF_Decoder* decoder, |
| 581 CF2_UInt idx, | 622 CF2_UInt idx, |
| 582 CF2_Buffer buf ) | 623 CF2_Buffer buf ) |
| 583 { | 624 { |
| 584 FT_ASSERT( decoder && decoder->locals ); | 625 FT_ASSERT( decoder ); |
| 585 | 626 |
| 586 FT_ZERO( buf ); | 627 FT_ZERO( buf ); |
| 587 | 628 |
| 588 idx += decoder->locals_bias; | 629 idx += decoder->locals_bias; |
| 589 if ( idx >= decoder->num_locals ) | 630 if ( idx >= decoder->num_locals ) |
| 590 return TRUE; /* error */ | 631 return TRUE; /* error */ |
| 591 | 632 |
| 633 FT_ASSERT( decoder->locals ); |
| 634 |
| 592 buf->start = | 635 buf->start = |
| 593 buf->ptr = decoder->locals[idx]; | 636 buf->ptr = decoder->locals[idx]; |
| 594 buf->end = decoder->locals[idx + 1]; | 637 buf->end = decoder->locals[idx + 1]; |
| 595 | 638 |
| 596 return FALSE; /* success */ | 639 return FALSE; /* success */ |
| 597 } | 640 } |
| 598 | 641 |
| 599 | 642 |
| 600 FT_LOCAL_DEF( CF2_Fixed ) | 643 FT_LOCAL_DEF( CF2_Fixed ) |
| 601 cf2_getDefaultWidthX( CFF_Decoder* decoder ) | 644 cf2_getDefaultWidthX( CFF_Decoder* decoder ) |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 639 | 682 |
| 640 FT_ASSERT( decoder ); | 683 FT_ASSERT( decoder ); |
| 641 | 684 |
| 642 cff_builder_close_contour( &decoder->builder ); | 685 cff_builder_close_contour( &decoder->builder ); |
| 643 | 686 |
| 644 FT_GlyphLoader_Add( decoder->builder.loader ); | 687 FT_GlyphLoader_Add( decoder->builder.loader ); |
| 645 } | 688 } |
| 646 | 689 |
| 647 | 690 |
| 648 /* END */ | 691 /* END */ |
| OLD | NEW |