1 /***************************************************************************/
5 /* OpenType Glyph Loader (body). */
7 /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
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. */
16 /***************************************************************************/
20 #include FT_INTERNAL_DEBUG_H
21 #include FT_INTERNAL_STREAM_H
22 #include FT_INTERNAL_SFNT_H
24 #include FT_INTERNAL_POSTSCRIPT_HINTS_H
33 /*************************************************************************/
35 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
36 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
37 /* messages during execution. */
40 #define FT_COMPONENT trace_cffgload
43 typedef enum CFF_Operator_
77 cff_op_dotsection
, /* deprecated, acts as no-op */
111 /* Type 1 opcodes: invalid but seen in real life */
114 cff_op_callothersubr
,
123 #define CFF_COUNT_CHECK_WIDTH 0x80
124 #define CFF_COUNT_EXACT 0x40
125 #define CFF_COUNT_CLEAR_STACK 0x20
127 /* count values which have the `CFF_COUNT_CHECK_WIDTH' flag set are */
128 /* used for checking the width and requested numbers of arguments */
129 /* only; they are set to zero afterwards */
131 /* the other two flags are informative only and unused currently */
133 static const FT_Byte cff_argument_counts
[] =
137 2 | CFF_COUNT_CHECK_WIDTH
| CFF_COUNT_EXACT
, /* rmoveto */
138 1 | CFF_COUNT_CHECK_WIDTH
| CFF_COUNT_EXACT
,
139 1 | CFF_COUNT_CHECK_WIDTH
| CFF_COUNT_EXACT
,
141 0 | CFF_COUNT_CLEAR_STACK
, /* rlineto */
142 0 | CFF_COUNT_CLEAR_STACK
,
143 0 | CFF_COUNT_CLEAR_STACK
,
145 0 | CFF_COUNT_CLEAR_STACK
, /* rrcurveto */
146 0 | CFF_COUNT_CLEAR_STACK
,
147 0 | CFF_COUNT_CLEAR_STACK
,
148 0 | CFF_COUNT_CLEAR_STACK
,
149 0 | CFF_COUNT_CLEAR_STACK
,
150 0 | CFF_COUNT_CLEAR_STACK
,
151 0 | CFF_COUNT_CLEAR_STACK
,
158 0 | CFF_COUNT_CHECK_WIDTH
, /* endchar */
160 2 | CFF_COUNT_CHECK_WIDTH
, /* hstem */
161 2 | CFF_COUNT_CHECK_WIDTH
,
162 2 | CFF_COUNT_CHECK_WIDTH
,
163 2 | CFF_COUNT_CHECK_WIDTH
,
165 0 | CFF_COUNT_CHECK_WIDTH
, /* hintmask */
166 0 | CFF_COUNT_CHECK_WIDTH
, /* cntrmask */
208 /*************************************************************************/
209 /*************************************************************************/
210 /*************************************************************************/
211 /********** *********/
212 /********** *********/
213 /********** GENERIC CHARSTRING PARSING *********/
214 /********** *********/
215 /********** *********/
216 /*************************************************************************/
217 /*************************************************************************/
218 /*************************************************************************/
221 /*************************************************************************/
224 /* cff_builder_init */
227 /* Initializes a given glyph builder. */
230 /* builder :: A pointer to the glyph builder to initialize. */
233 /* face :: The current face object. */
235 /* size :: The current size object. */
237 /* glyph :: The current glyph object. */
239 /* hinting :: Whether hinting is active. */
242 cff_builder_init( CFF_Builder
* builder
,
248 builder
->path_begun
= 0;
249 builder
->load_points
= 1;
251 builder
->face
= face
;
252 builder
->glyph
= glyph
;
253 builder
->memory
= face
->root
.memory
;
257 FT_GlyphLoader loader
= glyph
->root
.internal
->loader
;
260 builder
->loader
= loader
;
261 builder
->base
= &loader
->base
.outline
;
262 builder
->current
= &loader
->current
.outline
;
263 FT_GlyphLoader_Rewind( loader
);
265 builder
->hints_globals
= 0;
266 builder
->hints_funcs
= 0;
268 if ( hinting
&& size
)
270 CFF_Internal internal
= (CFF_Internal
)size
->root
.internal
;
273 builder
->hints_globals
= (void *)internal
->topfont
;
274 builder
->hints_funcs
= glyph
->root
.internal
->glyph_hints
;
281 builder
->left_bearing
.x
= 0;
282 builder
->left_bearing
.y
= 0;
283 builder
->advance
.x
= 0;
284 builder
->advance
.y
= 0;
288 /*************************************************************************/
291 /* cff_builder_done */
294 /* Finalizes a given glyph builder. Its contents can still be used */
295 /* after the call, but the function saves important information */
296 /* within the corresponding glyph slot. */
299 /* builder :: A pointer to the glyph builder to finalize. */
302 cff_builder_done( CFF_Builder
* builder
)
304 CFF_GlyphSlot glyph
= builder
->glyph
;
308 glyph
->root
.outline
= *builder
->base
;
312 /*************************************************************************/
315 /* cff_compute_bias */
318 /* Computes the bias value in dependence of the number of glyph */
322 /* num_subrs :: The number of glyph subroutines. */
325 /* The bias value. */
327 cff_compute_bias( FT_UInt num_subrs
)
332 if ( num_subrs
< 1240 )
334 else if ( num_subrs
< 33900U )
343 /*************************************************************************/
346 /* cff_decoder_init */
349 /* Initializes a given glyph decoder. */
352 /* decoder :: A pointer to the glyph builder to initialize. */
355 /* face :: The current face object. */
357 /* size :: The current size object. */
359 /* slot :: The current glyph object. */
361 /* hinting :: Whether hinting is active. */
363 /* hint_mode :: The hinting mode. */
366 cff_decoder_init( CFF_Decoder
* decoder
,
371 FT_Render_Mode hint_mode
)
373 CFF_Font cff
= (CFF_Font
)face
->extra
.data
;
376 /* clear everything */
377 FT_MEM_ZERO( decoder
, sizeof ( *decoder
) );
379 /* initialize builder */
380 cff_builder_init( &decoder
->builder
, face
, size
, slot
, hinting
);
382 /* initialize Type2 decoder */
383 decoder
->num_globals
= cff
->num_global_subrs
;
384 decoder
->globals
= cff
->global_subrs
;
385 decoder
->globals_bias
= cff_compute_bias( decoder
->num_globals
);
387 decoder
->hint_mode
= hint_mode
;
391 /* this function is used to select the subfont */
392 /* and the locals subrs array */
393 FT_LOCAL_DEF( FT_Error
)
394 cff_decoder_prepare( CFF_Decoder
* decoder
,
396 FT_UInt glyph_index
)
398 CFF_Builder
*builder
= &decoder
->builder
;
399 CFF_Font cff
= (CFF_Font
)builder
->face
->extra
.data
;
400 CFF_SubFont sub
= &cff
->top_font
;
401 FT_Error error
= CFF_Err_Ok
;
404 /* manage CID fonts */
405 if ( cff
->num_subfonts
)
407 FT_Byte fd_index
= cff_fd_select_get( &cff
->fd_select
, glyph_index
);
410 if ( fd_index
>= cff
->num_subfonts
)
412 FT_TRACE4(( "cff_decoder_prepare: invalid CID subfont index\n" ));
413 error
= CFF_Err_Invalid_File_Format
;
417 FT_TRACE4(( "glyph index %d (subfont %d):\n", glyph_index
, fd_index
));
419 sub
= cff
->subfonts
[fd_index
];
421 if ( builder
->hints_funcs
&& size
)
423 CFF_Internal internal
= (CFF_Internal
)size
->root
.internal
;
426 /* for CFFs without subfonts, this value has already been set */
427 builder
->hints_globals
= (void *)internal
->subfonts
[fd_index
];
430 #ifdef FT_DEBUG_LEVEL_TRACE
432 FT_TRACE4(( "glyph index %d:\n", glyph_index
));
435 decoder
->num_locals
= sub
->num_local_subrs
;
436 decoder
->locals
= sub
->local_subrs
;
437 decoder
->locals_bias
= cff_compute_bias( decoder
->num_locals
);
439 decoder
->glyph_width
= sub
->private_dict
.default_width
;
440 decoder
->nominal_width
= sub
->private_dict
.nominal_width
;
447 /* check that there is enough space for `count' more points */
449 check_points( CFF_Builder
* builder
,
452 return FT_GLYPHLOADER_CHECK_POINTS( builder
->loader
, count
, 0 );
456 /* add a new point, do not check space */
458 cff_builder_add_point( CFF_Builder
* builder
,
463 FT_Outline
* outline
= builder
->current
;
466 if ( builder
->load_points
)
468 FT_Vector
* point
= outline
->points
+ outline
->n_points
;
469 FT_Byte
* control
= (FT_Byte
*)outline
->tags
+ outline
->n_points
;
474 *control
= (FT_Byte
)( flag
? FT_CURVE_TAG_ON
: FT_CURVE_TAG_CUBIC
);
481 /* check space for a new on-curve point, then add it */
483 cff_builder_add_point1( CFF_Builder
* builder
,
490 error
= check_points( builder
, 1 );
492 cff_builder_add_point( builder
, x
, y
, 1 );
498 /* check space for a new contour, then add it */
500 cff_builder_add_contour( CFF_Builder
* builder
)
502 FT_Outline
* outline
= builder
->current
;
506 if ( !builder
->load_points
)
508 outline
->n_contours
++;
512 error
= FT_GLYPHLOADER_CHECK_POINTS( builder
->loader
, 0, 1 );
515 if ( outline
->n_contours
> 0 )
516 outline
->contours
[outline
->n_contours
- 1] =
517 (short)( outline
->n_points
- 1 );
519 outline
->n_contours
++;
526 /* if a path was begun, add its first on-curve point */
528 cff_builder_start_point( CFF_Builder
* builder
,
532 FT_Error error
= CFF_Err_Ok
;
535 /* test whether we are building a new contour */
536 if ( !builder
->path_begun
)
538 builder
->path_begun
= 1;
539 error
= cff_builder_add_contour( builder
);
541 error
= cff_builder_add_point1( builder
, x
, y
);
548 /* close the current contour */
550 cff_builder_close_contour( CFF_Builder
* builder
)
552 FT_Outline
* outline
= builder
->current
;
559 first
= outline
->n_contours
<= 1
560 ? 0 : outline
->contours
[outline
->n_contours
- 2] + 1;
562 /* We must not include the last point in the path if it */
563 /* is located on the first point. */
564 if ( outline
->n_points
> 1 )
566 FT_Vector
* p1
= outline
->points
+ first
;
567 FT_Vector
* p2
= outline
->points
+ outline
->n_points
- 1;
568 FT_Byte
* control
= (FT_Byte
*)outline
->tags
+ outline
->n_points
- 1;
571 /* `delete' last point only if it coincides with the first */
572 /* point and if it is not a control point (which can happen). */
573 if ( p1
->x
== p2
->x
&& p1
->y
== p2
->y
)
574 if ( *control
== FT_CURVE_TAG_ON
)
578 if ( outline
->n_contours
> 0 )
580 /* Don't add contours only consisting of one point, i.e., */
581 /* check whether begin point and last point are the same. */
582 if ( first
== outline
->n_points
- 1 )
584 outline
->n_contours
--;
588 outline
->contours
[outline
->n_contours
- 1] =
589 (short)( outline
->n_points
- 1 );
595 cff_lookup_glyph_by_stdcharcode( CFF_Font cff
,
602 /* CID-keyed fonts don't have glyph names */
603 if ( !cff
->charset
.sids
)
606 /* check range of standard char code */
607 if ( charcode
< 0 || charcode
> 255 )
610 /* Get code to SID mapping from `cff_standard_encoding'. */
611 glyph_sid
= cff_get_standard_encoding( (FT_UInt
)charcode
);
613 for ( n
= 0; n
< cff
->num_glyphs
; n
++ )
615 if ( cff
->charset
.sids
[n
] == glyph_sid
)
624 cff_get_glyph_data( TT_Face face
,
629 #ifdef FT_CONFIG_OPTION_INCREMENTAL
630 /* For incremental fonts get the character data using the */
631 /* callback function. */
632 if ( face
->root
.internal
->incremental_interface
)
636 face
->root
.internal
->incremental_interface
->funcs
->get_glyph_data(
637 face
->root
.internal
->incremental_interface
->object
,
638 glyph_index
, &data
);
641 *pointer
= (FT_Byte
*)data
.pointer
;
642 *length
= data
.length
;
647 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
650 CFF_Font cff
= (CFF_Font
)(face
->extra
.data
);
653 return cff_index_access_element( &cff
->charstrings_index
, glyph_index
,
660 cff_free_glyph_data( TT_Face face
,
664 #ifndef FT_CONFIG_OPTION_INCREMENTAL
668 #ifdef FT_CONFIG_OPTION_INCREMENTAL
669 /* For incremental fonts get the character data using the */
670 /* callback function. */
671 if ( face
->root
.internal
->incremental_interface
)
676 data
.pointer
= *pointer
;
677 data
.length
= length
;
679 face
->root
.internal
->incremental_interface
->funcs
->free_glyph_data(
680 face
->root
.internal
->incremental_interface
->object
,&data
);
683 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
686 CFF_Font cff
= (CFF_Font
)(face
->extra
.data
);
689 cff_index_forget_element( &cff
->charstrings_index
, pointer
);
695 cff_operator_seac( CFF_Decoder
* decoder
,
702 CFF_Builder
* builder
= &decoder
->builder
;
703 FT_Int bchar_index
, achar_index
;
704 TT_Face face
= decoder
->builder
.face
;
705 FT_Vector left_bearing
, advance
;
707 FT_ULong charstring_len
;
712 FT_ERROR(( "cff_operator_seac: invalid nested seac\n" ));
713 return CFF_Err_Syntax_Error
;
716 #ifdef FT_CONFIG_OPTION_INCREMENTAL
717 /* Incremental fonts don't necessarily have valid charsets. */
718 /* They use the character code, not the glyph index, in this case. */
719 if ( face
->root
.internal
->incremental_interface
)
725 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
727 CFF_Font cff
= (CFF_Font
)(face
->extra
.data
);
730 bchar_index
= cff_lookup_glyph_by_stdcharcode( cff
, bchar
);
731 achar_index
= cff_lookup_glyph_by_stdcharcode( cff
, achar
);
734 if ( bchar_index
< 0 || achar_index
< 0 )
736 FT_ERROR(( "cff_operator_seac:"
737 " invalid seac character code arguments\n" ));
738 return CFF_Err_Syntax_Error
;
741 /* If we are trying to load a composite glyph, do not load the */
742 /* accent character and return the array of subglyphs. */
743 if ( builder
->no_recurse
)
745 FT_GlyphSlot glyph
= (FT_GlyphSlot
)builder
->glyph
;
746 FT_GlyphLoader loader
= glyph
->internal
->loader
;
750 /* reallocate subglyph array if necessary */
751 error
= FT_GlyphLoader_CheckSubGlyphs( loader
, 2 );
755 subg
= loader
->current
.subglyphs
;
757 /* subglyph 0 = base character */
758 subg
->index
= bchar_index
;
759 subg
->flags
= FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES
|
760 FT_SUBGLYPH_FLAG_USE_MY_METRICS
;
765 /* subglyph 1 = accent character */
766 subg
->index
= achar_index
;
767 subg
->flags
= FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES
;
768 subg
->arg1
= (FT_Int
)( adx
>> 16 );
769 subg
->arg2
= (FT_Int
)( ady
>> 16 );
771 /* set up remaining glyph fields */
772 glyph
->num_subglyphs
= 2;
773 glyph
->subglyphs
= loader
->base
.subglyphs
;
774 glyph
->format
= FT_GLYPH_FORMAT_COMPOSITE
;
776 loader
->current
.num_subglyphs
= 2;
779 FT_GlyphLoader_Prepare( builder
->loader
);
781 /* First load `bchar' in builder */
782 error
= cff_get_glyph_data( face
, bchar_index
,
783 &charstring
, &charstring_len
);
786 /* the seac operator must not be nested */
787 decoder
->seac
= TRUE
;
788 error
= cff_decoder_parse_charstrings( decoder
, charstring
,
790 decoder
->seac
= FALSE
;
795 cff_free_glyph_data( face
, &charstring
, charstring_len
);
798 /* Save the left bearing and width of the base character */
799 /* as they will be erased by the next load. */
801 left_bearing
= builder
->left_bearing
;
802 advance
= builder
->advance
;
804 builder
->left_bearing
.x
= 0;
805 builder
->left_bearing
.y
= 0;
807 builder
->pos_x
= adx
;
808 builder
->pos_y
= ady
;
810 /* Now load `achar' on top of the base outline. */
811 error
= cff_get_glyph_data( face
, achar_index
,
812 &charstring
, &charstring_len
);
815 /* the seac operator must not be nested */
816 decoder
->seac
= TRUE
;
817 error
= cff_decoder_parse_charstrings( decoder
, charstring
,
819 decoder
->seac
= FALSE
;
824 cff_free_glyph_data( face
, &charstring
, charstring_len
);
827 /* Restore the left side bearing and advance width */
828 /* of the base character. */
829 builder
->left_bearing
= left_bearing
;
830 builder
->advance
= advance
;
840 /*************************************************************************/
843 /* cff_decoder_parse_charstrings */
846 /* Parses a given Type 2 charstrings program. */
849 /* decoder :: The current Type 1 decoder. */
852 /* charstring_base :: The base of the charstring stream. */
854 /* charstring_len :: The length in bytes of the charstring stream. */
857 /* FreeType error code. 0 means success. */
859 FT_LOCAL_DEF( FT_Error
)
860 cff_decoder_parse_charstrings( CFF_Decoder
* decoder
,
861 FT_Byte
* charstring_base
,
862 FT_ULong charstring_len
)
865 CFF_Decoder_Zone
* zone
;
868 CFF_Builder
* builder
= &decoder
->builder
;
873 T2_Hints_Funcs hinter
;
876 /* set default width */
877 decoder
->num_hints
= 0;
878 decoder
->read_width
= 1;
880 /* compute random seed from stack address of parameter */
881 seed
= (FT_Fixed
)( ( (FT_PtrDist
)(char*)&seed
^
882 (FT_PtrDist
)(char*)&decoder
^
883 (FT_PtrDist
)(char*)&charstring_base
) &
885 seed
= ( seed
^ ( seed
>> 10 ) ^ ( seed
>> 20 ) ) & 0xFFFFL
;
889 /* initialize the decoder */
890 decoder
->top
= decoder
->stack
;
891 decoder
->zone
= decoder
->zones
;
892 zone
= decoder
->zones
;
893 stack
= decoder
->top
;
895 hinter
= (T2_Hints_Funcs
)builder
->hints_funcs
;
897 builder
->path_begun
= 0;
899 zone
->base
= charstring_base
;
900 limit
= zone
->limit
= charstring_base
+ charstring_len
;
901 ip
= zone
->cursor
= zone
->base
;
908 /* begin hints recording session, if any */
910 hinter
->open( hinter
->hints
);
912 /* now execute loop */
919 /********************************************************************/
921 /* Decode operator or operand */
924 if ( v
>= 32 || v
== 28 )
930 /* this is an operand, push it on the stack */
933 if ( ip
+ 1 >= limit
)
935 val
= (FT_Short
)( ( (FT_Short
)ip
[0] << 8 ) | ip
[1] );
939 val
= (FT_Int32
)v
- 139;
944 val
= ( (FT_Int32
)v
- 247 ) * 256 + *ip
++ + 108;
950 val
= -( (FT_Int32
)v
- 251 ) * 256 - *ip
++ - 108;
954 if ( ip
+ 3 >= limit
)
956 val
= ( (FT_Int32
)ip
[0] << 24 ) |
957 ( (FT_Int32
)ip
[1] << 16 ) |
958 ( (FT_Int32
)ip
[2] << 8 ) |
963 if ( decoder
->top
- stack
>= CFF_MAX_OPERANDS
)
967 *decoder
->top
++ = val
;
969 #ifdef FT_DEBUG_LEVEL_TRACE
970 if ( !( val
& 0xFFFFL
) )
971 FT_TRACE4(( " %ld", (FT_Int32
)( val
>> 16 ) ));
973 FT_TRACE4(( " %.2f", val
/ 65536.0 ));
979 /* The specification says that normally arguments are to be taken */
980 /* from the bottom of the stack. However, this seems not to be */
981 /* correct, at least for Acroread 7.0.8 on GNU/Linux: It pops the */
982 /* arguments similar to a PS interpreter. */
984 FT_Fixed
* args
= decoder
->top
;
985 FT_Int num_args
= (FT_Int
)( args
- decoder
->stack
);
1001 op
= cff_op_vmoveto
;
1004 op
= cff_op_rlineto
;
1007 op
= cff_op_hlineto
;
1010 op
= cff_op_vlineto
;
1013 op
= cff_op_rrcurveto
;
1016 op
= cff_op_closepath
;
1019 op
= cff_op_callsubr
;
1033 op
= cff_op_dotsection
;
1069 op
= cff_op_callothersubr
;
1120 /* decrement ip for syntax error message */
1129 op
= cff_op_endchar
;
1135 op
= cff_op_hstemhm
;
1138 op
= cff_op_hintmask
;
1141 op
= cff_op_cntrmask
;
1144 op
= cff_op_rmoveto
;
1147 op
= cff_op_hmoveto
;
1150 op
= cff_op_vstemhm
;
1153 op
= cff_op_rcurveline
;
1156 op
= cff_op_rlinecurve
;
1159 op
= cff_op_vvcurveto
;
1162 op
= cff_op_hhcurveto
;
1165 op
= cff_op_callgsubr
;
1168 op
= cff_op_vhcurveto
;
1171 op
= cff_op_hvcurveto
;
1177 if ( op
== cff_op_unknown
)
1180 /* check arguments */
1181 req_args
= cff_argument_counts
[op
];
1182 if ( req_args
& CFF_COUNT_CHECK_WIDTH
)
1184 if ( num_args
> 0 && decoder
->read_width
)
1186 /* If `nominal_width' is non-zero, the number is really a */
1187 /* difference against `nominal_width'. Else, the number here */
1188 /* is truly a width, not a difference against `nominal_width'. */
1189 /* If the font does not set `nominal_width', then */
1190 /* `nominal_width' defaults to zero, and so we can set */
1191 /* `glyph_width' to `nominal_width' plus number on the stack */
1192 /* -- for either case. */
1194 FT_Int set_width_ok
;
1199 case cff_op_hmoveto
:
1200 case cff_op_vmoveto
:
1201 set_width_ok
= num_args
& 2;
1206 case cff_op_hstemhm
:
1207 case cff_op_vstemhm
:
1208 case cff_op_rmoveto
:
1209 case cff_op_hintmask
:
1210 case cff_op_cntrmask
:
1211 set_width_ok
= num_args
& 1;
1214 case cff_op_endchar
:
1215 /* If there is a width specified for endchar, we either have */
1216 /* 1 argument or 5 arguments. We like to argue. */
1217 set_width_ok
= ( num_args
== 5 ) || ( num_args
== 1 );
1227 decoder
->glyph_width
= decoder
->nominal_width
+
1230 if ( decoder
->width_only
)
1232 /* we only want the advance width; stop here */
1236 /* Consumed an argument. */
1241 decoder
->read_width
= 0;
1246 if ( num_args
< req_args
)
1247 goto Stack_Underflow
;
1249 num_args
-= req_args
;
1251 /* At this point, `args' points to the first argument of the */
1252 /* operand in case `req_args' isn't zero. Otherwise, we have */
1253 /* to adjust `args' manually. */
1255 /* Note that we only pop arguments from the stack which we */
1256 /* really need and can digest so that we can continue in case */
1257 /* of superfluous stack elements. */
1263 case cff_op_hstemhm
:
1264 case cff_op_vstemhm
:
1265 /* the number of arguments is always even here */
1267 op
== cff_op_hstem
? " hstem\n" :
1268 ( op
== cff_op_vstem
? " vstem\n" :
1269 ( op
== cff_op_hstemhm
? " hstemhm\n" : " vstemhm\n" ) ) ));
1272 hinter
->stems( hinter
->hints
,
1273 ( op
== cff_op_hstem
|| op
== cff_op_hstemhm
),
1275 args
- ( num_args
& ~1 ) );
1277 decoder
->num_hints
+= num_args
/ 2;
1281 case cff_op_hintmask
:
1282 case cff_op_cntrmask
:
1283 FT_TRACE4(( op
== cff_op_hintmask
? " hintmask" : " cntrmask" ));
1285 /* implement vstem when needed -- */
1286 /* the specification doesn't say it, but this also works */
1287 /* with the 'cntrmask' operator */
1292 hinter
->stems( hinter
->hints
,
1295 args
- ( num_args
& ~1 ) );
1297 decoder
->num_hints
+= num_args
/ 2;
1302 if ( op
== cff_op_hintmask
)
1303 hinter
->hintmask( hinter
->hints
,
1304 builder
->current
->n_points
,
1308 hinter
->counter( hinter
->hints
,
1313 #ifdef FT_DEBUG_LEVEL_TRACE
1318 FT_TRACE4(( " (maskbytes: " ));
1321 maskbyte
< (FT_UInt
)(( decoder
->num_hints
+ 7 ) >> 3);
1323 FT_TRACE4(( "0x%02X", *ip
));
1325 FT_TRACE4(( ")\n" ));
1328 ip
+= ( decoder
->num_hints
+ 7 ) >> 3;
1335 case cff_op_rmoveto
:
1336 FT_TRACE4(( " rmoveto\n" ));
1338 cff_builder_close_contour( builder
);
1339 builder
->path_begun
= 0;
1345 case cff_op_vmoveto
:
1346 FT_TRACE4(( " vmoveto\n" ));
1348 cff_builder_close_contour( builder
);
1349 builder
->path_begun
= 0;
1354 case cff_op_hmoveto
:
1355 FT_TRACE4(( " hmoveto\n" ));
1357 cff_builder_close_contour( builder
);
1358 builder
->path_begun
= 0;
1363 case cff_op_rlineto
:
1364 FT_TRACE4(( " rlineto\n" ));
1366 if ( cff_builder_start_point ( builder
, x
, y
) ||
1367 check_points( builder
, num_args
/ 2 ) )
1371 goto Stack_Underflow
;
1373 args
-= num_args
& ~1;
1374 while ( args
< decoder
->top
)
1378 cff_builder_add_point( builder
, x
, y
, 1 );
1384 case cff_op_hlineto
:
1385 case cff_op_vlineto
:
1387 FT_Int phase
= ( op
== cff_op_hlineto
);
1390 FT_TRACE4(( op
== cff_op_hlineto
? " hlineto\n"
1394 goto Stack_Underflow
;
1396 if ( cff_builder_start_point ( builder
, x
, y
) ||
1397 check_points( builder
, num_args
) )
1401 while ( args
< decoder
->top
)
1408 if ( cff_builder_add_point1( builder
, x
, y
) )
1418 case cff_op_rrcurveto
:
1423 FT_TRACE4(( " rrcurveto\n" ));
1426 goto Stack_Underflow
;
1428 nargs
= num_args
- num_args
% 6;
1430 if ( cff_builder_start_point ( builder
, x
, y
) ||
1431 check_points( builder
, nargs
/ 2 ) )
1435 while ( args
< decoder
->top
)
1439 cff_builder_add_point( builder
, x
, y
, 0 );
1442 cff_builder_add_point( builder
, x
, y
, 0 );
1445 cff_builder_add_point( builder
, x
, y
, 1 );
1452 case cff_op_vvcurveto
:
1457 FT_TRACE4(( " vvcurveto\n" ));
1460 goto Stack_Underflow
;
1462 /* if num_args isn't of the form 4n or 4n+1, */
1463 /* we reduce it to 4n+1 */
1465 nargs
= num_args
- num_args
% 4;
1466 if ( num_args
- nargs
> 0 )
1469 if ( cff_builder_start_point( builder
, x
, y
) )
1481 if ( check_points( builder
, 3 * ( nargs
/ 4 ) ) )
1484 while ( args
< decoder
->top
)
1487 cff_builder_add_point( builder
, x
, y
, 0 );
1490 cff_builder_add_point( builder
, x
, y
, 0 );
1492 cff_builder_add_point( builder
, x
, y
, 1 );
1499 case cff_op_hhcurveto
:
1504 FT_TRACE4(( " hhcurveto\n" ));
1507 goto Stack_Underflow
;
1509 /* if num_args isn't of the form 4n or 4n+1, */
1510 /* we reduce it to 4n+1 */
1512 nargs
= num_args
- num_args
% 4;
1513 if ( num_args
- nargs
> 0 )
1516 if ( cff_builder_start_point( builder
, x
, y
) )
1527 if ( check_points( builder
, 3 * ( nargs
/ 4 ) ) )
1530 while ( args
< decoder
->top
)
1533 cff_builder_add_point( builder
, x
, y
, 0 );
1536 cff_builder_add_point( builder
, x
, y
, 0 );
1538 cff_builder_add_point( builder
, x
, y
, 1 );
1545 case cff_op_vhcurveto
:
1546 case cff_op_hvcurveto
:
1552 FT_TRACE4(( op
== cff_op_vhcurveto
? " vhcurveto\n"
1553 : " hvcurveto\n" ));
1555 if ( cff_builder_start_point( builder
, x
, y
) )
1559 goto Stack_Underflow
;
1561 /* if num_args isn't of the form 8n, 8n+1, 8n+4, or 8n+5, */
1562 /* we reduce it to the largest one which fits */
1564 nargs
= num_args
- num_args
% 4;
1565 if ( num_args
- nargs
> 0 )
1569 if ( check_points( builder
, ( nargs
/ 4 ) * 3 ) )
1570 goto Stack_Underflow
;
1572 phase
= ( op
== cff_op_hvcurveto
);
1574 while ( nargs
>= 4 )
1580 cff_builder_add_point( builder
, x
, y
, 0 );
1583 cff_builder_add_point( builder
, x
, y
, 0 );
1587 cff_builder_add_point( builder
, x
, y
, 1 );
1592 cff_builder_add_point( builder
, x
, y
, 0 );
1595 cff_builder_add_point( builder
, x
, y
, 0 );
1599 cff_builder_add_point( builder
, x
, y
, 1 );
1608 case cff_op_rlinecurve
:
1614 FT_TRACE4(( " rlinecurve\n" ));
1617 goto Stack_Underflow
;
1619 nargs
= num_args
& ~1;
1620 num_lines
= ( nargs
- 6 ) / 2;
1622 if ( cff_builder_start_point( builder
, x
, y
) ||
1623 check_points( builder
, num_lines
+ 3 ) )
1628 /* first, add the line segments */
1629 while ( num_lines
> 0 )
1633 cff_builder_add_point( builder
, x
, y
, 1 );
1638 /* then the curve */
1641 cff_builder_add_point( builder
, x
, y
, 0 );
1644 cff_builder_add_point( builder
, x
, y
, 0 );
1647 cff_builder_add_point( builder
, x
, y
, 1 );
1652 case cff_op_rcurveline
:
1658 FT_TRACE4(( " rcurveline\n" ));
1661 goto Stack_Underflow
;
1663 nargs
= num_args
- 2;
1664 nargs
= nargs
- nargs
% 6 + 2;
1665 num_curves
= ( nargs
- 2 ) / 6;
1667 if ( cff_builder_start_point ( builder
, x
, y
) ||
1668 check_points( builder
, num_curves
* 3 + 2 ) )
1673 /* first, add the curves */
1674 while ( num_curves
> 0 )
1678 cff_builder_add_point( builder
, x
, y
, 0 );
1681 cff_builder_add_point( builder
, x
, y
, 0 );
1684 cff_builder_add_point( builder
, x
, y
, 1 );
1689 /* then the final line */
1692 cff_builder_add_point( builder
, x
, y
, 1 );
1702 FT_TRACE4(( " hflex1\n" ));
1704 /* adding five more points: 4 control points, 1 on-curve point */
1705 /* -- make sure we have enough space for the start point if it */
1706 /* needs to be added */
1707 if ( cff_builder_start_point( builder
, x
, y
) ||
1708 check_points( builder
, 6 ) )
1711 /* record the starting point's y position for later use */
1714 /* first control point */
1717 cff_builder_add_point( builder
, x
, y
, 0 );
1719 /* second control point */
1722 cff_builder_add_point( builder
, x
, y
, 0 );
1724 /* join point; on curve, with y-value the same as the last */
1725 /* control point's y-value */
1727 cff_builder_add_point( builder
, x
, y
, 1 );
1729 /* third control point, with y-value the same as the join */
1730 /* point's y-value */
1732 cff_builder_add_point( builder
, x
, y
, 0 );
1734 /* fourth control point */
1737 cff_builder_add_point( builder
, x
, y
, 0 );
1739 /* ending point, with y-value the same as the start */
1742 cff_builder_add_point( builder
, x
, y
, 1 );
1753 FT_TRACE4(( " hflex\n" ));
1755 /* adding six more points; 4 control points, 2 on-curve points */
1756 if ( cff_builder_start_point( builder
, x
, y
) ||
1757 check_points( builder
, 6 ) )
1760 /* record the starting point's y-position for later use */
1763 /* first control point */
1765 cff_builder_add_point( builder
, x
, y
, 0 );
1767 /* second control point */
1770 cff_builder_add_point( builder
, x
, y
, 0 );
1772 /* join point; on curve, with y-value the same as the last */
1773 /* control point's y-value */
1775 cff_builder_add_point( builder
, x
, y
, 1 );
1777 /* third control point, with y-value the same as the join */
1778 /* point's y-value */
1780 cff_builder_add_point( builder
, x
, y
, 0 );
1782 /* fourth control point */
1785 cff_builder_add_point( builder
, x
, y
, 0 );
1787 /* ending point, with y-value the same as the start point's */
1788 /* y-value -- we don't add this point, though */
1790 cff_builder_add_point( builder
, x
, y
, 1 );
1798 FT_Pos start_x
, start_y
; /* record start x, y values for */
1800 FT_Fixed dx
= 0, dy
= 0; /* used in horizontal/vertical */
1801 /* algorithm below */
1802 FT_Int horizontal
, count
;
1806 FT_TRACE4(( " flex1\n" ));
1808 /* adding six more points; 4 control points, 2 on-curve points */
1809 if ( cff_builder_start_point( builder
, x
, y
) ||
1810 check_points( builder
, 6 ) )
1813 /* record the starting point's x, y position for later use */
1817 /* XXX: figure out whether this is supposed to be a horizontal */
1818 /* or vertical flex; the Type 2 specification is vague... */
1822 /* grab up to the last argument */
1823 for ( count
= 5; count
> 0; count
-- )
1835 /* strange test, but here it is... */
1836 horizontal
= ( dx
> dy
);
1838 for ( count
= 5; count
> 0; count
-- )
1842 cff_builder_add_point( builder
, x
, y
,
1843 (FT_Bool
)( count
== 3 ) );
1847 /* is last operand an x- or y-delta? */
1859 cff_builder_add_point( builder
, x
, y
, 1 );
1870 FT_TRACE4(( " flex\n" ));
1872 if ( cff_builder_start_point( builder
, x
, y
) ||
1873 check_points( builder
, 6 ) )
1876 for ( count
= 6; count
> 0; count
-- )
1880 cff_builder_add_point( builder
, x
, y
,
1881 (FT_Bool
)( count
== 4 || count
== 1 ) );
1889 case cff_op_endchar
:
1890 FT_TRACE4(( " endchar\n" ));
1892 /* We are going to emulate the seac operator. */
1893 if ( num_args
>= 4 )
1895 /* Save glyph width so that the subglyphs don't overwrite it. */
1896 FT_Pos glyph_width
= decoder
->glyph_width
;
1899 error
= cff_operator_seac( decoder
,
1902 (FT_Int
)( args
[-2] >> 16 ),
1903 (FT_Int
)( args
[-1] >> 16 ) );
1905 decoder
->glyph_width
= glyph_width
;
1912 cff_builder_close_contour( builder
);
1914 /* close hints recording session */
1917 if ( hinter
->close( hinter
->hints
,
1918 builder
->current
->n_points
) )
1921 /* apply hints to the loaded glyph outline now */
1922 hinter
->apply( hinter
->hints
,
1924 (PSH_Globals
)builder
->hints_globals
,
1925 decoder
->hint_mode
);
1928 /* add current outline to the glyph slot */
1929 FT_GlyphLoader_Add( builder
->loader
);
1933 FT_TRACE4(( "\n" ));
1937 FT_TRACE4(( " abs\n" ));
1945 FT_TRACE4(( " add\n" ));
1952 FT_TRACE4(( " sub\n" ));
1959 FT_TRACE4(( " div\n" ));
1961 args
[0] = FT_DivFix( args
[0], args
[1] );
1966 FT_TRACE4(( " neg\n" ));
1977 FT_TRACE4(( " rand\n" ));
1980 if ( Rand
>= 0x8000L
)
1984 seed
= FT_MulFix( seed
, 0x10000L
- seed
);
1992 FT_TRACE4(( " mul\n" ));
1994 args
[0] = FT_MulFix( args
[0], args
[1] );
1999 FT_TRACE4(( " sqrt\n" ));
2004 FT_Fixed root
= args
[0];
2010 new_root
= ( root
+ FT_DivFix( args
[0], root
) + 1 ) >> 1;
2011 if ( new_root
== root
|| count
<= 0 )
2024 FT_TRACE4(( " drop\n" ));
2033 FT_TRACE4(( " exch\n" ));
2044 FT_Int idx
= (FT_Int
)( args
[0] >> 16 );
2047 FT_TRACE4(( " index\n" ));
2051 else if ( idx
> num_args
- 2 )
2053 args
[0] = args
[-( idx
+ 1 )];
2060 FT_Int count
= (FT_Int
)( args
[0] >> 16 );
2061 FT_Int idx
= (FT_Int
)( args
[1] >> 16 );
2064 FT_TRACE4(( " roll\n" ));
2071 goto Stack_Underflow
;
2077 FT_Fixed tmp
= args
[count
- 1];
2081 for ( i
= count
- 2; i
>= 0; i
-- )
2082 args
[i
+ 1] = args
[i
];
2091 FT_Fixed tmp
= args
[0];
2095 for ( i
= 0; i
< count
- 1; i
++ )
2096 args
[i
] = args
[i
+ 1];
2097 args
[count
- 1] = tmp
;
2106 FT_TRACE4(( " dup\n" ));
2114 FT_Fixed val
= args
[0];
2115 FT_Int idx
= (FT_Int
)( args
[1] >> 16 );
2118 FT_TRACE4(( " put\n" ));
2120 if ( idx
>= 0 && idx
< decoder
->len_buildchar
)
2121 decoder
->buildchar
[idx
] = val
;
2127 FT_Int idx
= (FT_Int
)( args
[0] >> 16 );
2131 FT_TRACE4(( " get\n" ));
2133 if ( idx
>= 0 && idx
< decoder
->len_buildchar
)
2134 val
= decoder
->buildchar
[idx
];
2142 FT_TRACE4(( " store\n"));
2147 FT_TRACE4(( " load\n" ));
2151 case cff_op_dotsection
:
2152 /* this operator is deprecated and ignored by the parser */
2153 FT_TRACE4(( " dotsection\n" ));
2156 case cff_op_closepath
:
2157 /* this is an invalid Type 2 operator; however, there */
2158 /* exist fonts which are incorrectly converted from probably */
2159 /* Type 1 to CFF, and some parsers seem to accept it */
2161 FT_TRACE4(( " closepath (invalid op)\n" ));
2167 /* this is an invalid Type 2 operator; however, there */
2168 /* exist fonts which are incorrectly converted from probably */
2169 /* Type 1 to CFF, and some parsers seem to accept it */
2171 FT_TRACE4(( " hsbw (invalid op)\n" ));
2173 decoder
->glyph_width
= decoder
->nominal_width
+
2180 case cff_op_callothersubr
:
2181 /* this is an invalid Type 2 operator; however, there */
2182 /* exist fonts which are incorrectly converted from probably */
2183 /* Type 1 to CFF, and some parsers seem to accept it */
2185 FT_TRACE4(( " callothersubr (invalid op)\n" ));
2187 /* don't modify stack; handle the subr as `unknown' so that */
2188 /* following `pop' operands use the arguments on stack */
2192 /* this is an invalid Type 2 operator; however, there */
2193 /* exist fonts which are incorrectly converted from probably */
2194 /* Type 1 to CFF, and some parsers seem to accept it */
2196 FT_TRACE4(( " pop (invalid op)\n" ));
2203 FT_Fixed cond
= args
[0] && args
[1];
2206 FT_TRACE4(( " and\n" ));
2208 args
[0] = cond
? 0x10000L
: 0;
2215 FT_Fixed cond
= args
[0] || args
[1];
2218 FT_TRACE4(( " or\n" ));
2220 args
[0] = cond
? 0x10000L
: 0;
2227 FT_Fixed cond
= !args
[0];
2230 FT_TRACE4(( " eq\n" ));
2232 args
[0] = cond
? 0x10000L
: 0;
2239 FT_Fixed cond
= ( args
[2] <= args
[3] );
2242 FT_TRACE4(( " ifelse\n" ));
2250 case cff_op_callsubr
:
2252 FT_UInt idx
= (FT_UInt
)( ( args
[0] >> 16 ) +
2253 decoder
->locals_bias
);
2256 FT_TRACE4(( " callsubr(%d)\n", idx
));
2258 if ( idx
>= decoder
->num_locals
)
2260 FT_ERROR(( "cff_decoder_parse_charstrings:"
2261 " invalid local subr index\n" ));
2265 if ( zone
- decoder
->zones
>= CFF_MAX_SUBRS_CALLS
)
2267 FT_ERROR(( "cff_decoder_parse_charstrings:"
2268 " too many nested subrs\n" ));
2272 zone
->cursor
= ip
; /* save current instruction pointer */
2275 zone
->base
= decoder
->locals
[idx
];
2276 zone
->limit
= decoder
->locals
[idx
+ 1];
2277 zone
->cursor
= zone
->base
;
2279 if ( !zone
->base
|| zone
->limit
== zone
->base
)
2281 FT_ERROR(( "cff_decoder_parse_charstrings:"
2282 " invoking empty subrs\n" ));
2286 decoder
->zone
= zone
;
2288 limit
= zone
->limit
;
2292 case cff_op_callgsubr
:
2294 FT_UInt idx
= (FT_UInt
)( ( args
[0] >> 16 ) +
2295 decoder
->globals_bias
);
2298 FT_TRACE4(( " callgsubr(%d)\n", idx
));
2300 if ( idx
>= decoder
->num_globals
)
2302 FT_ERROR(( "cff_decoder_parse_charstrings:"
2303 " invalid global subr index\n" ));
2307 if ( zone
- decoder
->zones
>= CFF_MAX_SUBRS_CALLS
)
2309 FT_ERROR(( "cff_decoder_parse_charstrings:"
2310 " too many nested subrs\n" ));
2314 zone
->cursor
= ip
; /* save current instruction pointer */
2317 zone
->base
= decoder
->globals
[idx
];
2318 zone
->limit
= decoder
->globals
[idx
+ 1];
2319 zone
->cursor
= zone
->base
;
2321 if ( !zone
->base
|| zone
->limit
== zone
->base
)
2323 FT_ERROR(( "cff_decoder_parse_charstrings:"
2324 " invoking empty subrs\n" ));
2328 decoder
->zone
= zone
;
2330 limit
= zone
->limit
;
2335 FT_TRACE4(( " return\n" ));
2337 if ( decoder
->zone
<= decoder
->zones
)
2339 FT_ERROR(( "cff_decoder_parse_charstrings:"
2340 " unexpected return\n" ));
2345 zone
= decoder
->zone
;
2347 limit
= zone
->limit
;
2352 FT_ERROR(( "Unimplemented opcode: %d", ip
[-1] ));
2355 FT_ERROR(( " %d", ip
[0] ));
2358 return CFF_Err_Unimplemented_Feature
;
2361 decoder
->top
= args
;
2363 } /* general operator processing */
2365 } /* while ip < limit */
2367 FT_TRACE4(( "..end..\n\n" ));
2373 FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" ));
2374 return CFF_Err_Invalid_File_Format
;
2377 FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" ));
2378 return CFF_Err_Too_Few_Arguments
;
2381 FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" ));
2382 return CFF_Err_Stack_Overflow
;
2386 /*************************************************************************/
2387 /*************************************************************************/
2388 /*************************************************************************/
2389 /********** *********/
2390 /********** *********/
2391 /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/
2392 /********** *********/
2393 /********** The following code is in charge of computing *********/
2394 /********** the maximum advance width of the font. It *********/
2395 /********** quickly processes each glyph charstring to *********/
2396 /********** extract the value from either a `sbw' or `seac' *********/
2397 /********** operator. *********/
2398 /********** *********/
2399 /*************************************************************************/
2400 /*************************************************************************/
2401 /*************************************************************************/
2404 #if 0 /* unused until we support pure CFF fonts */
2407 FT_LOCAL_DEF( FT_Error
)
2408 cff_compute_max_advance( TT_Face face
,
2409 FT_Int
* max_advance
)
2411 FT_Error error
= CFF_Err_Ok
;
2412 CFF_Decoder decoder
;
2414 CFF_Font cff
= (CFF_Font
)face
->other
;
2419 /* Initialize load decoder */
2420 cff_decoder_init( &decoder
, face
, 0, 0, 0, 0 );
2422 decoder
.builder
.metrics_only
= 1;
2423 decoder
.builder
.load_points
= 0;
2425 /* For each glyph, parse the glyph charstring and extract */
2426 /* the advance width. */
2427 for ( glyph_index
= 0; glyph_index
< face
->root
.num_glyphs
;
2430 FT_Byte
* charstring
;
2431 FT_ULong charstring_len
;
2434 /* now get load the unscaled outline */
2435 error
= cff_get_glyph_data( face
, glyph_index
,
2436 &charstring
, &charstring_len
);
2439 error
= cff_decoder_prepare( &decoder
, size
, glyph_index
);
2441 error
= cff_decoder_parse_charstrings( &decoder
,
2445 cff_free_glyph_data( face
, &charstring
, &charstring_len
);
2448 /* ignore the error if one has occurred -- skip to next glyph */
2452 *max_advance
= decoder
.builder
.advance
.x
;
2461 FT_LOCAL_DEF( FT_Error
)
2462 cff_slot_load( CFF_GlyphSlot glyph
,
2464 FT_UInt glyph_index
,
2465 FT_Int32 load_flags
)
2468 CFF_Decoder decoder
;
2469 TT_Face face
= (TT_Face
)glyph
->root
.face
;
2470 FT_Bool hinting
, force_scaling
;
2471 CFF_Font cff
= (CFF_Font
)face
->extra
.data
;
2473 FT_Matrix font_matrix
;
2474 FT_Vector font_offset
;
2477 force_scaling
= FALSE
;
2479 /* in a CID-keyed font, consider `glyph_index' as a CID and map */
2480 /* it immediately to the real glyph_index -- if it isn't a */
2481 /* subsetted font, glyph_indices and CIDs are identical, though */
2482 if ( cff
->top_font
.font_dict
.cid_registry
!= 0xFFFFU
&&
2485 /* don't handle CID 0 (.notdef) which is directly mapped to GID 0 */
2486 if ( glyph_index
!= 0 )
2488 glyph_index
= cff_charset_cid_to_gindex( &cff
->charset
,
2490 if ( glyph_index
== 0 )
2491 return CFF_Err_Invalid_Argument
;
2494 else if ( glyph_index
>= cff
->num_glyphs
)
2495 return CFF_Err_Invalid_Argument
;
2497 if ( load_flags
& FT_LOAD_NO_RECURSE
)
2498 load_flags
|= FT_LOAD_NO_SCALE
| FT_LOAD_NO_HINTING
;
2500 glyph
->x_scale
= 0x10000L
;
2501 glyph
->y_scale
= 0x10000L
;
2504 glyph
->x_scale
= size
->root
.metrics
.x_scale
;
2505 glyph
->y_scale
= size
->root
.metrics
.y_scale
;
2508 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
2510 /* try to load embedded bitmap if any */
2512 /* XXX: The convention should be emphasized in */
2513 /* the documents because it can be confusing. */
2516 CFF_Face cff_face
= (CFF_Face
)size
->root
.face
;
2517 SFNT_Service sfnt
= (SFNT_Service
)cff_face
->sfnt
;
2518 FT_Stream stream
= cff_face
->root
.stream
;
2521 if ( size
->strike_index
!= 0xFFFFFFFFUL
&&
2523 ( load_flags
& FT_LOAD_NO_BITMAP
) == 0 )
2525 TT_SBit_MetricsRec metrics
;
2528 error
= sfnt
->load_sbit_image( face
,
2533 &glyph
->root
.bitmap
,
2538 glyph
->root
.outline
.n_points
= 0;
2539 glyph
->root
.outline
.n_contours
= 0;
2541 glyph
->root
.metrics
.width
= (FT_Pos
)metrics
.width
<< 6;
2542 glyph
->root
.metrics
.height
= (FT_Pos
)metrics
.height
<< 6;
2544 glyph
->root
.metrics
.horiBearingX
= (FT_Pos
)metrics
.horiBearingX
<< 6;
2545 glyph
->root
.metrics
.horiBearingY
= (FT_Pos
)metrics
.horiBearingY
<< 6;
2546 glyph
->root
.metrics
.horiAdvance
= (FT_Pos
)metrics
.horiAdvance
<< 6;
2548 glyph
->root
.metrics
.vertBearingX
= (FT_Pos
)metrics
.vertBearingX
<< 6;
2549 glyph
->root
.metrics
.vertBearingY
= (FT_Pos
)metrics
.vertBearingY
<< 6;
2550 glyph
->root
.metrics
.vertAdvance
= (FT_Pos
)metrics
.vertAdvance
<< 6;
2552 glyph
->root
.format
= FT_GLYPH_FORMAT_BITMAP
;
2554 if ( load_flags
& FT_LOAD_VERTICAL_LAYOUT
)
2556 glyph
->root
.bitmap_left
= metrics
.vertBearingX
;
2557 glyph
->root
.bitmap_top
= metrics
.vertBearingY
;
2561 glyph
->root
.bitmap_left
= metrics
.horiBearingX
;
2562 glyph
->root
.bitmap_top
= metrics
.horiBearingY
;
2569 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
2571 /* return immediately if we only want the embedded bitmaps */
2572 if ( load_flags
& FT_LOAD_SBITS_ONLY
)
2573 return CFF_Err_Invalid_Argument
;
2575 /* if we have a CID subfont, use its matrix (which has already */
2576 /* been multiplied with the root matrix) */
2578 /* this scaling is only relevant if the PS hinter isn't active */
2579 if ( cff
->num_subfonts
)
2581 FT_Byte fd_index
= cff_fd_select_get( &cff
->fd_select
,
2584 FT_ULong top_upm
= cff
->top_font
.font_dict
.units_per_em
;
2585 FT_ULong sub_upm
= cff
->subfonts
[fd_index
]->font_dict
.units_per_em
;
2588 font_matrix
= cff
->subfonts
[fd_index
]->font_dict
.font_matrix
;
2589 font_offset
= cff
->subfonts
[fd_index
]->font_dict
.font_offset
;
2591 if ( top_upm
!= sub_upm
)
2593 glyph
->x_scale
= FT_MulDiv( glyph
->x_scale
, top_upm
, sub_upm
);
2594 glyph
->y_scale
= FT_MulDiv( glyph
->y_scale
, top_upm
, sub_upm
);
2596 force_scaling
= TRUE
;
2601 font_matrix
= cff
->top_font
.font_dict
.font_matrix
;
2602 font_offset
= cff
->top_font
.font_dict
.font_offset
;
2605 glyph
->root
.outline
.n_points
= 0;
2606 glyph
->root
.outline
.n_contours
= 0;
2608 hinting
= FT_BOOL( ( load_flags
& FT_LOAD_NO_SCALE
) == 0 &&
2609 ( load_flags
& FT_LOAD_NO_HINTING
) == 0 );
2611 glyph
->root
.format
= FT_GLYPH_FORMAT_OUTLINE
; /* by default */
2614 FT_Byte
* charstring
;
2615 FT_ULong charstring_len
;
2618 cff_decoder_init( &decoder
, face
, size
, glyph
, hinting
,
2619 FT_LOAD_TARGET_MODE( load_flags
) );
2621 if ( load_flags
& FT_LOAD_ADVANCE_ONLY
)
2622 decoder
.width_only
= TRUE
;
2624 decoder
.builder
.no_recurse
=
2625 (FT_Bool
)( load_flags
& FT_LOAD_NO_RECURSE
);
2627 /* now load the unscaled outline */
2628 error
= cff_get_glyph_data( face
, glyph_index
,
2629 &charstring
, &charstring_len
);
2632 error
= cff_decoder_prepare( &decoder
, size
, glyph_index
);
2635 error
= cff_decoder_parse_charstrings( &decoder
,
2639 cff_free_glyph_data( face
, &charstring
, charstring_len
);
2642 #ifdef FT_CONFIG_OPTION_INCREMENTAL
2643 /* Control data and length may not be available for incremental */
2645 if ( face
->root
.internal
->incremental_interface
)
2647 glyph
->root
.control_data
= 0;
2648 glyph
->root
.control_len
= 0;
2651 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
2653 /* We set control_data and control_len if charstrings is loaded. */
2654 /* See how charstring loads at cff_index_access_element() in */
2657 CFF_Index csindex
= &cff
->charstrings_index
;
2660 if ( csindex
->offsets
)
2662 glyph
->root
.control_data
= csindex
->bytes
+
2663 csindex
->offsets
[glyph_index
] - 1;
2664 glyph
->root
.control_len
= charstring_len
;
2670 /* save new glyph tables */
2671 cff_builder_done( &decoder
.builder
);
2674 #ifdef FT_CONFIG_OPTION_INCREMENTAL
2676 /* Incremental fonts can optionally override the metrics. */
2678 face
->root
.internal
->incremental_interface
&&
2679 face
->root
.internal
->incremental_interface
->funcs
->get_glyph_metrics
)
2681 FT_Incremental_MetricsRec metrics
;
2684 metrics
.bearing_x
= decoder
.builder
.left_bearing
.x
;
2685 metrics
.bearing_y
= decoder
.builder
.left_bearing
.y
;
2686 metrics
.advance
= decoder
.builder
.advance
.x
;
2687 error
= face
->root
.internal
->incremental_interface
->funcs
->get_glyph_metrics(
2688 face
->root
.internal
->incremental_interface
->object
,
2689 glyph_index
, FALSE
, &metrics
);
2690 decoder
.builder
.left_bearing
.x
= metrics
.bearing_x
;
2691 decoder
.builder
.left_bearing
.y
= metrics
.bearing_y
;
2692 decoder
.builder
.advance
.x
= metrics
.advance
;
2693 decoder
.builder
.advance
.y
= 0;
2696 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
2700 /* Now, set the metrics -- this is rather simple, as */
2701 /* the left side bearing is the xMin, and the top side */
2702 /* bearing the yMax. */
2704 /* For composite glyphs, return only left side bearing and */
2705 /* advance width. */
2706 if ( load_flags
& FT_LOAD_NO_RECURSE
)
2708 FT_Slot_Internal internal
= glyph
->root
.internal
;
2711 glyph
->root
.metrics
.horiBearingX
= decoder
.builder
.left_bearing
.x
;
2712 glyph
->root
.metrics
.horiAdvance
= decoder
.glyph_width
;
2713 internal
->glyph_matrix
= font_matrix
;
2714 internal
->glyph_delta
= font_offset
;
2715 internal
->glyph_transformed
= 1;
2720 FT_Glyph_Metrics
* metrics
= &glyph
->root
.metrics
;
2722 FT_Bool has_vertical_info
;
2725 /* copy the _unscaled_ advance width */
2726 metrics
->horiAdvance
= decoder
.glyph_width
;
2727 glyph
->root
.linearHoriAdvance
= decoder
.glyph_width
;
2728 glyph
->root
.internal
->glyph_transformed
= 0;
2730 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
2731 has_vertical_info
= FT_BOOL( face
->vertical_info
&&
2732 face
->vertical
.number_Of_VMetrics
> 0 &&
2733 face
->vertical
.long_metrics
);
2735 has_vertical_info
= FT_BOOL( face
->vertical_info
&&
2736 face
->vertical
.number_Of_VMetrics
> 0 );
2739 /* get the vertical metrics from the vtmx table if we have one */
2740 if ( has_vertical_info
)
2742 FT_Short vertBearingY
= 0;
2743 FT_UShort vertAdvance
= 0;
2746 ( (SFNT_Service
)face
->sfnt
)->get_metrics( face
, 1,
2750 metrics
->vertBearingY
= vertBearingY
;
2751 metrics
->vertAdvance
= vertAdvance
;
2755 /* make up vertical ones */
2756 if ( face
->os2
.version
!= 0xFFFFU
)
2757 metrics
->vertAdvance
= (FT_Pos
)( face
->os2
.sTypoAscender
-
2758 face
->os2
.sTypoDescender
);
2760 metrics
->vertAdvance
= (FT_Pos
)( face
->horizontal
.Ascender
-
2761 face
->horizontal
.Descender
);
2764 glyph
->root
.linearVertAdvance
= metrics
->vertAdvance
;
2766 glyph
->root
.format
= FT_GLYPH_FORMAT_OUTLINE
;
2768 glyph
->root
.outline
.flags
= 0;
2769 if ( size
&& size
->root
.metrics
.y_ppem
< 24 )
2770 glyph
->root
.outline
.flags
|= FT_OUTLINE_HIGH_PRECISION
;
2772 glyph
->root
.outline
.flags
|= FT_OUTLINE_REVERSE_FILL
;
2774 if ( !( font_matrix
.xx
== 0x10000L
&&
2775 font_matrix
.yy
== 0x10000L
&&
2776 font_matrix
.xy
== 0 &&
2777 font_matrix
.yx
== 0 ) )
2778 FT_Outline_Transform( &glyph
->root
.outline
, &font_matrix
);
2780 if ( !( font_offset
.x
== 0 &&
2781 font_offset
.y
== 0 ) )
2782 FT_Outline_Translate( &glyph
->root
.outline
,
2783 font_offset
.x
, font_offset
.y
);
2785 advance
.x
= metrics
->horiAdvance
;
2787 FT_Vector_Transform( &advance
, &font_matrix
);
2788 metrics
->horiAdvance
= advance
.x
+ font_offset
.x
;
2791 advance
.y
= metrics
->vertAdvance
;
2792 FT_Vector_Transform( &advance
, &font_matrix
);
2793 metrics
->vertAdvance
= advance
.y
+ font_offset
.y
;
2795 if ( ( load_flags
& FT_LOAD_NO_SCALE
) == 0 || force_scaling
)
2797 /* scale the outline and the metrics */
2799 FT_Outline
* cur
= &glyph
->root
.outline
;
2800 FT_Vector
* vec
= cur
->points
;
2801 FT_Fixed x_scale
= glyph
->x_scale
;
2802 FT_Fixed y_scale
= glyph
->y_scale
;
2805 /* First of all, scale the points */
2806 if ( !hinting
|| !decoder
.builder
.hints_funcs
)
2807 for ( n
= cur
->n_points
; n
> 0; n
--, vec
++ )
2809 vec
->x
= FT_MulFix( vec
->x
, x_scale
);
2810 vec
->y
= FT_MulFix( vec
->y
, y_scale
);
2813 /* Then scale the metrics */
2814 metrics
->horiAdvance
= FT_MulFix( metrics
->horiAdvance
, x_scale
);
2815 metrics
->vertAdvance
= FT_MulFix( metrics
->vertAdvance
, y_scale
);
2818 /* compute the other metrics */
2819 FT_Outline_Get_CBox( &glyph
->root
.outline
, &cbox
);
2821 metrics
->width
= cbox
.xMax
- cbox
.xMin
;
2822 metrics
->height
= cbox
.yMax
- cbox
.yMin
;
2824 metrics
->horiBearingX
= cbox
.xMin
;
2825 metrics
->horiBearingY
= cbox
.yMax
;
2827 if ( has_vertical_info
)
2828 metrics
->vertBearingX
= metrics
->horiBearingX
-
2829 metrics
->horiAdvance
/ 2;
2831 ft_synthesize_vertical_metrics( metrics
,
2832 metrics
->vertAdvance
);