1 /***************************************************************************/
5 /* FreeType Glue Component to Adobe's Interpreter (body). */
7 /* Copyright 2013-2014 Adobe Systems Incorporated. */
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. */
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. */
36 /***************************************************************************/
40 #include FT_INTERNAL_DEBUG_H
45 #include "cffdecode.h"
47 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
48 #include FT_MULTIPLE_MASTERS_H
49 #include FT_SERVICE_MULTIPLE_MASTERS_H
52 #include FT_SERVICE_CFF_TABLE_LOAD_H
55 #define CF2_MAX_SIZE cf2_intToFixed( 2000 ) /* max ppem */
59 * This check should avoid most internal overflow cases. Clients should
60 * generally respond to `Glyph_Too_Big' by getting a glyph outline
61 * at EM size, scaling it and filling it as a graphics operation.
65 cf2_checkTransform( const CF2_Matrix
* transform
,
71 FT_ASSERT( unitsPerEm
> 0 );
73 if ( transform
->a
<= 0 || transform
->d
<= 0 )
74 return FT_THROW( Invalid_Size_Handle
);
76 FT_ASSERT( transform
->b
== 0 && transform
->c
== 0 );
77 FT_ASSERT( transform
->tx
== 0 && transform
->ty
== 0 );
79 if ( unitsPerEm
> 0x7FFF )
80 return FT_THROW( Glyph_Too_Big
);
82 maxScale
= FT_DivFix( CF2_MAX_SIZE
, cf2_intToFixed( unitsPerEm
) );
84 if ( transform
->a
> maxScale
|| transform
->d
> maxScale
)
85 return FT_THROW( Glyph_Too_Big
);
92 cf2_setGlyphWidth( CF2_Outline outline
,
95 PS_Decoder
* decoder
= outline
->decoder
;
100 if ( !decoder
->builder
.is_t1
)
101 *decoder
->glyph_width
= cf2_fixedToInt( width
);
105 /* Clean up font instance. */
107 cf2_free_instance( void* ptr
)
109 CF2_Font font
= (CF2_Font
)ptr
;
114 FT_Memory memory
= font
->memory
;
117 FT_FREE( font
->blend
.lastNDV
);
118 FT_FREE( font
->blend
.BV
);
123 /********************************************/
125 /* functions for handling client outline; */
126 /* FreeType uses coordinates in 26.6 format */
128 /********************************************/
131 cf2_builder_moveTo( CF2_OutlineCallbacks callbacks
,
132 const CF2_CallbackParams params
)
134 /* downcast the object pointer */
135 CF2_Outline outline
= (CF2_Outline
)callbacks
;
138 (void)params
; /* only used in debug mode */
141 FT_ASSERT( outline
&& outline
->decoder
);
142 FT_ASSERT( params
->op
== CF2_PathOpMoveTo
);
144 builder
= &outline
->decoder
->builder
;
146 /* note: two successive moves simply close the contour twice */
147 ps_builder_close_contour( builder
);
148 builder
->path_begun
= 0;
153 cf2_builder_lineTo( CF2_OutlineCallbacks callbacks
,
154 const CF2_CallbackParams params
)
158 /* downcast the object pointer */
159 CF2_Outline outline
= (CF2_Outline
)callbacks
;
163 FT_ASSERT( outline
&& outline
->decoder
);
164 FT_ASSERT( params
->op
== CF2_PathOpLineTo
);
166 builder
= &outline
->decoder
->builder
;
168 if ( !builder
->path_begun
)
170 /* record the move before the line; also check points and set */
172 error
= ps_builder_start_point( builder
,
177 if ( !*callbacks
->error
)
178 *callbacks
->error
= error
;
183 /* `ps_builder_add_point1' includes a check_points call for one point */
184 error
= ps_builder_add_point1( builder
,
189 if ( !*callbacks
->error
)
190 *callbacks
->error
= error
;
197 cf2_builder_cubeTo( CF2_OutlineCallbacks callbacks
,
198 const CF2_CallbackParams params
)
202 /* downcast the object pointer */
203 CF2_Outline outline
= (CF2_Outline
)callbacks
;
207 FT_ASSERT( outline
&& outline
->decoder
);
208 FT_ASSERT( params
->op
== CF2_PathOpCubeTo
);
210 builder
= &outline
->decoder
->builder
;
212 if ( !builder
->path_begun
)
214 /* record the move before the line; also check points and set */
216 error
= ps_builder_start_point( builder
,
221 if ( !*callbacks
->error
)
222 *callbacks
->error
= error
;
227 /* prepare room for 3 points: 2 off-curve, 1 on-curve */
228 error
= ps_builder_check_points( builder
, 3 );
231 if ( !*callbacks
->error
)
232 *callbacks
->error
= error
;
236 ps_builder_add_point( builder
,
239 ps_builder_add_point( builder
,
242 ps_builder_add_point( builder
,
249 cf2_outline_init( CF2_Outline outline
,
255 outline
->root
.memory
= memory
;
256 outline
->root
.error
= error
;
258 outline
->root
.moveTo
= cf2_builder_moveTo
;
259 outline
->root
.lineTo
= cf2_builder_lineTo
;
260 outline
->root
.cubeTo
= cf2_builder_cubeTo
;
264 /* get scaling and hint flag from GlyphSlot */
266 cf2_getScaleAndHintFlag( PS_Decoder
* decoder
,
272 FT_ASSERT( decoder
&& decoder
->builder
.glyph
);
274 /* note: FreeType scale includes a factor of 64 */
275 *hinted
= decoder
->builder
.glyph
->hint
;
276 *scaled
= decoder
->builder
.glyph
->scaled
;
280 *x_scale
= ADD_INT32( decoder
->builder
.glyph
->x_scale
, 32 ) / 64;
281 *y_scale
= ADD_INT32( decoder
->builder
.glyph
->y_scale
, 32 ) / 64;
285 /* for unhinted outlines, `cff_slot_load' does the scaling, */
286 /* thus render at `unity' scale */
288 *x_scale
= 0x0400; /* 1/64 as 16.16 */
294 /* get units per em from `FT_Face' */
295 /* TODO: should handle font matrix concatenation? */
297 cf2_getUnitsPerEm( PS_Decoder
* decoder
)
299 FT_ASSERT( decoder
&& decoder
->builder
.face
);
300 FT_ASSERT( decoder
->builder
.face
->units_per_EM
);
302 return decoder
->builder
.face
->units_per_EM
;
306 /* Main entry point: Render one glyph. */
307 FT_LOCAL_DEF( FT_Error
)
308 cf2_decoder_parse_charstrings( PS_Decoder
* decoder
,
309 FT_Byte
* charstring_base
,
310 FT_ULong charstring_len
)
313 FT_Error error
= FT_Err_Ok
;
316 FT_Bool is_t1
= decoder
->builder
.is_t1
;
319 FT_ASSERT( decoder
&&
320 ( is_t1
|| decoder
->cff
) );
322 if ( is_t1
&& !decoder
->current_subfont
)
324 FT_ERROR(( "cf2_decoder_parse_charstrings (Type 1): "
325 "SubFont missing. Use `t1_make_subfont' first\n" ));
326 return FT_THROW( Invalid_Table
);
329 memory
= decoder
->builder
.memory
;
331 /* CF2 data is saved here across glyphs */
332 font
= (CF2_Font
)decoder
->cf2_instance
->data
;
334 /* on first glyph, allocate instance structure */
335 if ( !decoder
->cf2_instance
->data
)
337 decoder
->cf2_instance
->finalizer
=
338 (FT_Generic_Finalizer
)cf2_free_instance
;
340 if ( FT_ALLOC( decoder
->cf2_instance
->data
,
341 sizeof ( CF2_FontRec
) ) )
342 return FT_THROW( Out_Of_Memory
);
344 font
= (CF2_Font
)decoder
->cf2_instance
->data
;
346 font
->memory
= memory
;
349 font
->cffload
= (FT_Service_CFFLoad
)decoder
->cff
->cffload
;
351 /* initialize a client outline, to be shared by each glyph rendered */
352 cf2_outline_init( &font
->outline
, font
->memory
, &font
->error
);
355 /* save decoder; it is a stack variable and will be different on each */
357 font
->decoder
= decoder
;
358 font
->outline
.decoder
= decoder
;
361 /* build parameters for Adobe engine */
363 PS_Builder
* builder
= &decoder
->builder
;
364 PS_Driver driver
= (PS_Driver
)FT_FACE_DRIVER( builder
->face
);
366 FT_Bool no_stem_darkening_driver
=
367 driver
->no_stem_darkening
;
368 FT_Char no_stem_darkening_font
=
369 builder
->face
->internal
->no_stem_darkening
;
372 FT_Error error2
= FT_Err_Ok
;
374 CF2_Matrix transform
;
375 CF2_F16Dot16 glyphWidth
;
381 /* FreeType has already looked up the GID; convert to */
382 /* `RegionBuffer', assuming that the input has been validated */
383 FT_ASSERT( charstring_base
+ charstring_len
>= charstring_base
);
387 buf
.ptr
= charstring_base
;
388 buf
.end
= charstring_base
+ charstring_len
;
390 FT_ZERO( &transform
);
392 cf2_getScaleAndHintFlag( decoder
,
399 font
->isCFF2
= FALSE
;
402 /* copy isCFF2 boolean from TT_Face to CF2_Font */
403 font
->isCFF2
= ((TT_Face
)builder
->face
)->is_cff2
;
407 font
->renderingFlags
= 0;
409 font
->renderingFlags
|= CF2_FlagsHinted
;
410 if ( scaled
&& ( !no_stem_darkening_font
||
411 ( no_stem_darkening_font
< 0 &&
412 !no_stem_darkening_driver
) ) )
413 font
->renderingFlags
|= CF2_FlagsDarkened
;
415 font
->darkenParams
[0] = driver
->darken_params
[0];
416 font
->darkenParams
[1] = driver
->darken_params
[1];
417 font
->darkenParams
[2] = driver
->darken_params
[2];
418 font
->darkenParams
[3] = driver
->darken_params
[3];
419 font
->darkenParams
[4] = driver
->darken_params
[4];
420 font
->darkenParams
[5] = driver
->darken_params
[5];
421 font
->darkenParams
[6] = driver
->darken_params
[6];
422 font
->darkenParams
[7] = driver
->darken_params
[7];
424 /* now get an outline for this glyph; */
425 /* also get units per em to validate scale */
426 font
->unitsPerEm
= (CF2_Int
)cf2_getUnitsPerEm( decoder
);
430 error2
= cf2_checkTransform( &transform
, font
->unitsPerEm
);
435 error2
= cf2_getGlyphOutline( font
, &buf
, &transform
, &glyphWidth
);
437 return FT_ERR( Invalid_File_Format
);
439 cf2_setGlyphWidth( &font
->outline
, glyphWidth
);
446 /* get pointer to current FreeType subfont (based on current glyphID) */
447 FT_LOCAL_DEF( CFF_SubFont
)
448 cf2_getSubfont( PS_Decoder
* decoder
)
450 FT_ASSERT( decoder
&& decoder
->current_subfont
);
452 return decoder
->current_subfont
;
456 /* get pointer to VStore structure */
457 FT_LOCAL_DEF( CFF_VStore
)
458 cf2_getVStore( PS_Decoder
* decoder
)
460 FT_ASSERT( decoder
&& decoder
->cff
);
462 return &decoder
->cff
->vstore
;
466 /* get maxstack value from CFF2 Top DICT */
467 FT_LOCAL_DEF( FT_UInt
)
468 cf2_getMaxstack( PS_Decoder
* decoder
)
470 FT_ASSERT( decoder
&& decoder
->cff
);
472 return decoder
->cff
->top_font
.font_dict
.maxstack
;
476 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
477 /* Get normalized design vector for current render request; */
478 /* return pointer and length. */
480 /* Note: Uses FT_Fixed not CF2_Fixed for the vector. */
481 FT_LOCAL_DEF( FT_Error
)
482 cf2_getNormalizedVector( PS_Decoder
* decoder
,
487 FT_Service_MultiMasters mm
;
490 FT_ASSERT( decoder
&& decoder
->builder
.face
);
491 FT_ASSERT( vec
&& len
);
492 FT_ASSERT( !decoder
->builder
.is_t1
);
494 face
= (TT_Face
)decoder
->builder
.face
;
495 mm
= (FT_Service_MultiMasters
)face
->mm
;
497 return mm
->get_var_blend( FT_FACE( face
), len
, NULL
, vec
, NULL
);
502 /* get `y_ppem' from `CFF_Size' */
503 FT_LOCAL_DEF( CF2_Fixed
)
504 cf2_getPpemY( PS_Decoder
* decoder
)
506 FT_ASSERT( decoder
&&
507 decoder
->builder
.face
&&
508 decoder
->builder
.face
->size
);
511 * Note that `y_ppem' can be zero if there wasn't a call to
512 * `FT_Set_Char_Size' or something similar. However, this isn't a
513 * problem since we come to this place in the code only if
514 * FT_LOAD_NO_SCALE is set (the other case gets caught by
515 * `cf2_checkTransform'). The ppem value is needed to compute the stem
516 * darkening, which is disabled for getting the unscaled outline.
519 return cf2_intToFixed(
520 decoder
->builder
.face
->size
->metrics
.y_ppem
);
524 /* get standard stem widths for the current subfont; */
525 /* FreeType stores these as integer font units */
526 /* (note: variable names seem swapped) */
527 FT_LOCAL_DEF( CF2_Fixed
)
528 cf2_getStdVW( PS_Decoder
* decoder
)
530 FT_ASSERT( decoder
&& decoder
->current_subfont
);
532 return cf2_intToFixed(
533 decoder
->current_subfont
->private_dict
.standard_height
);
537 FT_LOCAL_DEF( CF2_Fixed
)
538 cf2_getStdHW( PS_Decoder
* decoder
)
540 FT_ASSERT( decoder
&& decoder
->current_subfont
);
542 return cf2_intToFixed(
543 decoder
->current_subfont
->private_dict
.standard_width
);
547 /* note: FreeType stores 1000 times the actual value for `BlueScale' */
549 cf2_getBlueMetrics( PS_Decoder
* decoder
,
550 CF2_Fixed
* blueScale
,
551 CF2_Fixed
* blueShift
,
552 CF2_Fixed
* blueFuzz
)
554 FT_ASSERT( decoder
&& decoder
->current_subfont
);
556 *blueScale
= FT_DivFix(
557 decoder
->current_subfont
->private_dict
.blue_scale
,
558 cf2_intToFixed( 1000 ) );
559 *blueShift
= cf2_intToFixed(
560 decoder
->current_subfont
->private_dict
.blue_shift
);
561 *blueFuzz
= cf2_intToFixed(
562 decoder
->current_subfont
->private_dict
.blue_fuzz
);
566 /* get blue values counts and arrays; the FreeType parser has validated */
567 /* the counts and verified that each is an even number */
569 cf2_getBlueValues( PS_Decoder
* decoder
,
573 FT_ASSERT( decoder
&& decoder
->current_subfont
);
575 *count
= decoder
->current_subfont
->private_dict
.num_blue_values
;
577 &decoder
->current_subfont
->private_dict
.blue_values
;
582 cf2_getOtherBlues( PS_Decoder
* decoder
,
586 FT_ASSERT( decoder
&& decoder
->current_subfont
);
588 *count
= decoder
->current_subfont
->private_dict
.num_other_blues
;
590 &decoder
->current_subfont
->private_dict
.other_blues
;
595 cf2_getFamilyBlues( PS_Decoder
* decoder
,
599 FT_ASSERT( decoder
&& decoder
->current_subfont
);
601 *count
= decoder
->current_subfont
->private_dict
.num_family_blues
;
603 &decoder
->current_subfont
->private_dict
.family_blues
;
608 cf2_getFamilyOtherBlues( PS_Decoder
* decoder
,
612 FT_ASSERT( decoder
&& decoder
->current_subfont
);
614 *count
= decoder
->current_subfont
->private_dict
.num_family_other_blues
;
616 &decoder
->current_subfont
->private_dict
.family_other_blues
;
620 FT_LOCAL_DEF( CF2_Int
)
621 cf2_getLanguageGroup( PS_Decoder
* decoder
)
623 FT_ASSERT( decoder
&& decoder
->current_subfont
);
625 return decoder
->current_subfont
->private_dict
.language_group
;
629 /* convert unbiased subroutine index to `CF2_Buffer' and */
630 /* return 0 on success */
631 FT_LOCAL_DEF( CF2_Int
)
632 cf2_initGlobalRegionBuffer( PS_Decoder
* decoder
,
639 FT_ASSERT( decoder
);
643 idx
= (CF2_UInt
)( subrNum
+ decoder
->globals_bias
);
644 if ( idx
>= decoder
->num_globals
)
645 return TRUE
; /* error */
647 FT_ASSERT( decoder
->globals
);
650 buf
->ptr
= decoder
->globals
[idx
];
651 buf
->end
= decoder
->globals
[idx
+ 1];
653 return FALSE
; /* success */
657 /* convert AdobeStandardEncoding code to CF2_Buffer; */
658 /* used for seac component */
659 FT_LOCAL_DEF( FT_Error
)
660 cf2_getSeacComponent( PS_Decoder
* decoder
,
670 FT_ASSERT( decoder
);
671 FT_ASSERT( !decoder
->builder
.is_t1
);
675 #ifdef FT_CONFIG_OPTION_INCREMENTAL
676 /* Incremental fonts don't necessarily have valid charsets. */
677 /* They use the character code, not the glyph index, in this case. */
678 if ( decoder
->builder
.face
->internal
->incremental_interface
)
681 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
683 gid
= cff_lookup_glyph_by_stdcharcode( decoder
->cff
, code
);
685 return FT_THROW( Invalid_Glyph_Format
);
688 error
= decoder
->get_glyph_callback( (TT_Face
)decoder
->builder
.face
,
692 /* TODO: for now, just pass the FreeType error through */
696 /* assume input has been validated */
697 FT_ASSERT( charstring
+ len
>= charstring
);
699 buf
->start
= charstring
;
700 buf
->end
= charstring
+ len
;
701 buf
->ptr
= buf
->start
;
708 cf2_freeSeacComponent( PS_Decoder
* decoder
,
711 FT_ASSERT( decoder
);
712 FT_ASSERT( !decoder
->builder
.is_t1
);
714 decoder
->free_glyph_callback( (TT_Face
)decoder
->builder
.face
,
715 (FT_Byte
**)&buf
->start
,
716 (FT_ULong
)( buf
->end
- buf
->start
) );
720 FT_LOCAL_DEF( FT_Error
)
721 cf2_getT1SeacComponent( PS_Decoder
* decoder
,
726 FT_Error error
= FT_Err_Ok
;
727 T1_Face face
= (T1_Face
)decoder
->builder
.face
;
728 T1_Font type1
= &face
->type1
;
730 #ifdef FT_CONFIG_OPTION_INCREMENTAL
731 FT_Incremental_InterfaceRec
*inc
=
732 face
->root
.internal
->incremental_interface
;
735 /* For incremental fonts get the character data using the */
736 /* callback function. */
738 error
= inc
->funcs
->get_glyph_data( inc
->object
,
739 glyph_index
, &glyph_data
);
742 /* For ordinary fonts get the character data stored in the face record. */
744 glyph_data
.pointer
= type1
->charstrings
[glyph_index
];
745 glyph_data
.length
= (FT_Int
)type1
->charstrings_len
[glyph_index
];
750 FT_Byte
* charstring_base
= (FT_Byte
*)glyph_data
.pointer
;
751 FT_ULong charstring_len
= (FT_ULong
)glyph_data
.length
;
754 FT_ASSERT( charstring_base
+ charstring_len
>= charstring_base
);
758 buf
->ptr
= charstring_base
;
759 buf
->end
= charstring_base
+ charstring_len
;
767 cf2_freeT1SeacComponent( PS_Decoder
* decoder
,
774 FT_ASSERT( decoder
);
776 #ifdef FT_CONFIG_OPTION_INCREMENTAL
777 face
= (T1_Face
)decoder
->builder
.face
;
779 data
.pointer
= buf
->start
;
780 data
.length
= (FT_Int
)( buf
->end
- buf
->start
);
782 if ( face
->root
.internal
->incremental_interface
)
783 face
->root
.internal
->incremental_interface
->funcs
->free_glyph_data(
784 face
->root
.internal
->incremental_interface
->object
,
786 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
790 FT_LOCAL_DEF( CF2_Int
)
791 cf2_initLocalRegionBuffer( PS_Decoder
* decoder
,
798 FT_ASSERT( decoder
);
802 idx
= (CF2_UInt
)( subrNum
+ decoder
->locals_bias
);
803 if ( idx
>= decoder
->num_locals
)
804 return TRUE
; /* error */
806 FT_ASSERT( decoder
->locals
);
808 buf
->start
= decoder
->locals
[idx
];
810 if ( decoder
->builder
.is_t1
)
812 /* The Type 1 driver stores subroutines without the seed bytes. */
813 /* The CID driver stores subroutines with seed bytes. This */
814 /* case is taken care of when decoder->subrs_len == 0. */
815 if ( decoder
->locals_len
)
816 buf
->end
= buf
->start
+ decoder
->locals_len
[idx
];
819 /* We are using subroutines from a CID font. We must adjust */
820 /* for the seed bytes. */
821 buf
->start
+= ( decoder
->lenIV
>= 0 ? decoder
->lenIV
: 0 );
822 buf
->end
= decoder
->locals
[idx
+ 1];
827 FT_ERROR(( "cf2_initLocalRegionBuffer (Type 1 mode):"
828 " invoking empty subrs\n" ));
833 buf
->end
= decoder
->locals
[idx
+ 1];
836 buf
->ptr
= buf
->start
;
838 return FALSE
; /* success */
842 FT_LOCAL_DEF( CF2_Fixed
)
843 cf2_getDefaultWidthX( PS_Decoder
* decoder
)
845 FT_ASSERT( decoder
&& decoder
->current_subfont
);
847 return cf2_intToFixed(
848 decoder
->current_subfont
->private_dict
.default_width
);
852 FT_LOCAL_DEF( CF2_Fixed
)
853 cf2_getNominalWidthX( PS_Decoder
* decoder
)
855 FT_ASSERT( decoder
&& decoder
->current_subfont
);
857 return cf2_intToFixed(
858 decoder
->current_subfont
->private_dict
.nominal_width
);
863 cf2_outline_reset( CF2_Outline outline
)
865 PS_Decoder
* decoder
= outline
->decoder
;
868 FT_ASSERT( decoder
);
870 outline
->root
.windingMomentum
= 0;
872 FT_GlyphLoader_Rewind( decoder
->builder
.loader
);
877 cf2_outline_close( CF2_Outline outline
)
879 PS_Decoder
* decoder
= outline
->decoder
;
882 FT_ASSERT( decoder
);
884 ps_builder_close_contour( &decoder
->builder
);
886 FT_GlyphLoader_Add( decoder
->builder
.loader
);