1 /***************************************************************************/
5 /* OpenType Glyph Loader (body). */
7 /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 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_CALC_H
22 #include FT_INTERNAL_STREAM_H
23 #include FT_INTERNAL_SFNT_H
25 #include FT_TRUETYPE_TAGS_H
26 #include FT_INTERNAL_POSTSCRIPT_HINTS_H
35 /*************************************************************************/
37 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
38 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
39 /* messages during execution. */
42 #define FT_COMPONENT trace_cffgload
45 typedef enum CFF_Operator_
79 cff_op_dotsection
, /* deprecated, acts as no-op */
113 cff_op_hsbw
, /* Type 1 opcode: invalid but seen in real life */
114 cff_op_closepath
, /* ditto */
122 #define CFF_COUNT_CHECK_WIDTH 0x80
123 #define CFF_COUNT_EXACT 0x40
124 #define CFF_COUNT_CLEAR_STACK 0x20
127 static const FT_Byte cff_argument_counts
[] =
131 2 | CFF_COUNT_CHECK_WIDTH
| CFF_COUNT_EXACT
, /* rmoveto */
132 1 | CFF_COUNT_CHECK_WIDTH
| CFF_COUNT_EXACT
,
133 1 | CFF_COUNT_CHECK_WIDTH
| CFF_COUNT_EXACT
,
135 0 | CFF_COUNT_CLEAR_STACK
, /* rlineto */
136 0 | CFF_COUNT_CLEAR_STACK
,
137 0 | CFF_COUNT_CLEAR_STACK
,
139 0 | CFF_COUNT_CLEAR_STACK
, /* rrcurveto */
140 0 | CFF_COUNT_CLEAR_STACK
,
141 0 | CFF_COUNT_CLEAR_STACK
,
142 0 | CFF_COUNT_CLEAR_STACK
,
143 0 | CFF_COUNT_CLEAR_STACK
,
144 0 | CFF_COUNT_CLEAR_STACK
,
145 0 | CFF_COUNT_CLEAR_STACK
,
152 0 | CFF_COUNT_CHECK_WIDTH
, /* endchar */
154 2 | CFF_COUNT_CHECK_WIDTH
, /* hstem */
155 2 | CFF_COUNT_CHECK_WIDTH
,
156 2 | CFF_COUNT_CHECK_WIDTH
,
157 2 | CFF_COUNT_CHECK_WIDTH
,
159 0 | CFF_COUNT_CHECK_WIDTH
, /* hintmask */
160 0 | CFF_COUNT_CHECK_WIDTH
, /* cntrmask */
200 /*************************************************************************/
201 /*************************************************************************/
202 /*************************************************************************/
203 /********** *********/
204 /********** *********/
205 /********** GENERIC CHARSTRING PARSING *********/
206 /********** *********/
207 /********** *********/
208 /*************************************************************************/
209 /*************************************************************************/
210 /*************************************************************************/
213 /*************************************************************************/
216 /* cff_builder_init */
219 /* Initializes a given glyph builder. */
222 /* builder :: A pointer to the glyph builder to initialize. */
225 /* face :: The current face object. */
227 /* size :: The current size object. */
229 /* glyph :: The current glyph object. */
231 /* hinting :: Whether hinting is active. */
234 cff_builder_init( CFF_Builder
* builder
,
240 builder
->path_begun
= 0;
241 builder
->load_points
= 1;
243 builder
->face
= face
;
244 builder
->glyph
= glyph
;
245 builder
->memory
= face
->root
.memory
;
249 FT_GlyphLoader loader
= glyph
->root
.internal
->loader
;
252 builder
->loader
= loader
;
253 builder
->base
= &loader
->base
.outline
;
254 builder
->current
= &loader
->current
.outline
;
255 FT_GlyphLoader_Rewind( loader
);
257 builder
->hints_globals
= 0;
258 builder
->hints_funcs
= 0;
260 if ( hinting
&& size
)
262 CFF_Internal internal
= (CFF_Internal
)size
->root
.internal
;
265 builder
->hints_globals
= (void *)internal
->topfont
;
266 builder
->hints_funcs
= glyph
->root
.internal
->glyph_hints
;
273 builder
->left_bearing
.x
= 0;
274 builder
->left_bearing
.y
= 0;
275 builder
->advance
.x
= 0;
276 builder
->advance
.y
= 0;
280 /*************************************************************************/
283 /* cff_builder_done */
286 /* Finalizes a given glyph builder. Its contents can still be used */
287 /* after the call, but the function saves important information */
288 /* within the corresponding glyph slot. */
291 /* builder :: A pointer to the glyph builder to finalize. */
294 cff_builder_done( CFF_Builder
* builder
)
296 CFF_GlyphSlot glyph
= builder
->glyph
;
300 glyph
->root
.outline
= *builder
->base
;
304 /*************************************************************************/
307 /* cff_compute_bias */
310 /* Computes the bias value in dependence of the number of glyph */
314 /* num_subrs :: The number of glyph subroutines. */
317 /* The bias value. */
319 cff_compute_bias( FT_UInt num_subrs
)
324 if ( num_subrs
< 1240 )
326 else if ( num_subrs
< 33900U )
335 /*************************************************************************/
338 /* cff_decoder_init */
341 /* Initializes a given glyph decoder. */
344 /* decoder :: A pointer to the glyph builder to initialize. */
347 /* face :: The current face object. */
349 /* size :: The current size object. */
351 /* slot :: The current glyph object. */
353 /* hinting :: Whether hinting is active. */
355 /* hint_mode :: The hinting mode. */
358 cff_decoder_init( CFF_Decoder
* decoder
,
363 FT_Render_Mode hint_mode
)
365 CFF_Font cff
= (CFF_Font
)face
->extra
.data
;
368 /* clear everything */
369 FT_MEM_ZERO( decoder
, sizeof ( *decoder
) );
371 /* initialize builder */
372 cff_builder_init( &decoder
->builder
, face
, size
, slot
, hinting
);
374 /* initialize Type2 decoder */
375 decoder
->num_globals
= cff
->num_global_subrs
;
376 decoder
->globals
= cff
->global_subrs
;
377 decoder
->globals_bias
= cff_compute_bias( decoder
->num_globals
);
379 decoder
->hint_mode
= hint_mode
;
383 /* this function is used to select the subfont */
384 /* and the locals subrs array */
385 FT_LOCAL_DEF( FT_Error
)
386 cff_decoder_prepare( CFF_Decoder
* decoder
,
388 FT_UInt glyph_index
)
390 CFF_Builder
*builder
= &decoder
->builder
;
391 CFF_Font cff
= (CFF_Font
)builder
->face
->extra
.data
;
392 CFF_SubFont sub
= &cff
->top_font
;
393 FT_Error error
= CFF_Err_Ok
;
396 /* manage CID fonts */
397 if ( cff
->num_subfonts
)
399 FT_Byte fd_index
= cff_fd_select_get( &cff
->fd_select
, glyph_index
);
402 if ( fd_index
>= cff
->num_subfonts
)
404 FT_TRACE4(( "cff_decoder_prepare: invalid CID subfont index\n" ));
405 error
= CFF_Err_Invalid_File_Format
;
409 sub
= cff
->subfonts
[fd_index
];
411 if ( builder
->hints_funcs
)
413 CFF_Internal internal
= (CFF_Internal
)size
->root
.internal
;
416 /* for CFFs without subfonts, this value has already been set */
417 builder
->hints_globals
= (void *)internal
->subfonts
[fd_index
];
421 decoder
->num_locals
= sub
->num_local_subrs
;
422 decoder
->locals
= sub
->local_subrs
;
423 decoder
->locals_bias
= cff_compute_bias( decoder
->num_locals
);
425 decoder
->glyph_width
= sub
->private_dict
.default_width
;
426 decoder
->nominal_width
= sub
->private_dict
.nominal_width
;
433 /* check that there is enough space for `count' more points */
435 check_points( CFF_Builder
* builder
,
438 return FT_GLYPHLOADER_CHECK_POINTS( builder
->loader
, count
, 0 );
442 /* add a new point, do not check space */
444 cff_builder_add_point( CFF_Builder
* builder
,
449 FT_Outline
* outline
= builder
->current
;
452 if ( builder
->load_points
)
454 FT_Vector
* point
= outline
->points
+ outline
->n_points
;
455 FT_Byte
* control
= (FT_Byte
*)outline
->tags
+ outline
->n_points
;
460 *control
= (FT_Byte
)( flag
? FT_CURVE_TAG_ON
: FT_CURVE_TAG_CUBIC
);
462 builder
->last
= *point
;
469 /* check space for a new on-curve point, then add it */
471 cff_builder_add_point1( CFF_Builder
* builder
,
478 error
= check_points( builder
, 1 );
480 cff_builder_add_point( builder
, x
, y
, 1 );
486 /* check space for a new contour, then add it */
488 cff_builder_add_contour( CFF_Builder
* builder
)
490 FT_Outline
* outline
= builder
->current
;
494 if ( !builder
->load_points
)
496 outline
->n_contours
++;
500 error
= FT_GLYPHLOADER_CHECK_POINTS( builder
->loader
, 0, 1 );
503 if ( outline
->n_contours
> 0 )
504 outline
->contours
[outline
->n_contours
- 1] =
505 (short)( outline
->n_points
- 1 );
507 outline
->n_contours
++;
514 /* if a path was begun, add its first on-curve point */
516 cff_builder_start_point( CFF_Builder
* builder
,
520 FT_Error error
= CFF_Err_Ok
;
523 /* test whether we are building a new contour */
524 if ( !builder
->path_begun
)
526 builder
->path_begun
= 1;
527 error
= cff_builder_add_contour( builder
);
529 error
= cff_builder_add_point1( builder
, x
, y
);
536 /* close the current contour */
538 cff_builder_close_contour( CFF_Builder
* builder
)
540 FT_Outline
* outline
= builder
->current
;
546 /* XXXX: We must not include the last point in the path if it */
547 /* is located on the first point. */
548 if ( outline
->n_points
> 1 )
551 FT_Vector
* p1
= outline
->points
+ first
;
552 FT_Vector
* p2
= outline
->points
+ outline
->n_points
- 1;
553 FT_Byte
* control
= (FT_Byte
*)outline
->tags
+ outline
->n_points
- 1;
556 if ( outline
->n_contours
> 1 )
558 first
= outline
->contours
[outline
->n_contours
- 2] + 1;
559 p1
= outline
->points
+ first
;
562 /* `delete' last point only if it coincides with the first */
563 /* point and if it is not a control point (which can happen). */
564 if ( p1
->x
== p2
->x
&& p1
->y
== p2
->y
)
565 if ( *control
== FT_CURVE_TAG_ON
)
569 if ( outline
->n_contours
> 0 )
570 outline
->contours
[outline
->n_contours
- 1] =
571 (short)( outline
->n_points
- 1 );
576 cff_lookup_glyph_by_stdcharcode( CFF_Font cff
,
583 /* CID-keyed fonts don't have glyph names */
584 if ( !cff
->charset
.sids
)
587 /* check range of standard char code */
588 if ( charcode
< 0 || charcode
> 255 )
591 /* Get code to SID mapping from `cff_standard_encoding'. */
592 glyph_sid
= cff_get_standard_encoding( (FT_UInt
)charcode
);
594 for ( n
= 0; n
< cff
->num_glyphs
; n
++ )
596 if ( cff
->charset
.sids
[n
] == glyph_sid
)
605 cff_get_glyph_data( TT_Face face
,
610 #ifdef FT_CONFIG_OPTION_INCREMENTAL
611 /* For incremental fonts get the character data using the */
612 /* callback function. */
613 if ( face
->root
.internal
->incremental_interface
)
617 face
->root
.internal
->incremental_interface
->funcs
->get_glyph_data(
618 face
->root
.internal
->incremental_interface
->object
,
619 glyph_index
, &data
);
622 *pointer
= (FT_Byte
*)data
.pointer
;
623 *length
= data
.length
;
628 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
631 CFF_Font cff
= (CFF_Font
)(face
->extra
.data
);
634 return cff_index_access_element( &cff
->charstrings_index
, glyph_index
,
641 cff_free_glyph_data( TT_Face face
,
645 #ifndef FT_CONFIG_OPTION_INCREMENTAL
649 #ifdef FT_CONFIG_OPTION_INCREMENTAL
650 /* For incremental fonts get the character data using the */
651 /* callback function. */
652 if ( face
->root
.internal
->incremental_interface
)
657 data
.pointer
= *pointer
;
658 data
.length
= length
;
660 face
->root
.internal
->incremental_interface
->funcs
->free_glyph_data(
661 face
->root
.internal
->incremental_interface
->object
,&data
);
664 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
667 CFF_Font cff
= (CFF_Font
)(face
->extra
.data
);
670 cff_index_forget_element( &cff
->charstrings_index
, pointer
);
676 cff_operator_seac( CFF_Decoder
* decoder
,
683 CFF_Builder
* builder
= &decoder
->builder
;
684 FT_Int bchar_index
, achar_index
;
685 TT_Face face
= decoder
->builder
.face
;
686 FT_Vector left_bearing
, advance
;
688 FT_ULong charstring_len
;
691 #ifdef FT_CONFIG_OPTION_INCREMENTAL
692 /* Incremental fonts don't necessarily have valid charsets. */
693 /* They use the character code, not the glyph index, in this case. */
694 if ( face
->root
.internal
->incremental_interface
)
700 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
702 CFF_Font cff
= (CFF_Font
)(face
->extra
.data
);
705 bchar_index
= cff_lookup_glyph_by_stdcharcode( cff
, bchar
);
706 achar_index
= cff_lookup_glyph_by_stdcharcode( cff
, achar
);
709 if ( bchar_index
< 0 || achar_index
< 0 )
711 FT_ERROR(( "cff_operator_seac:" ));
712 FT_ERROR(( " invalid seac character code arguments\n" ));
713 return CFF_Err_Syntax_Error
;
716 /* If we are trying to load a composite glyph, do not load the */
717 /* accent character and return the array of subglyphs. */
718 if ( builder
->no_recurse
)
720 FT_GlyphSlot glyph
= (FT_GlyphSlot
)builder
->glyph
;
721 FT_GlyphLoader loader
= glyph
->internal
->loader
;
725 /* reallocate subglyph array if necessary */
726 error
= FT_GlyphLoader_CheckSubGlyphs( loader
, 2 );
730 subg
= loader
->current
.subglyphs
;
732 /* subglyph 0 = base character */
733 subg
->index
= bchar_index
;
734 subg
->flags
= FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES
|
735 FT_SUBGLYPH_FLAG_USE_MY_METRICS
;
740 /* subglyph 1 = accent character */
741 subg
->index
= achar_index
;
742 subg
->flags
= FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES
;
743 subg
->arg1
= (FT_Int
)( adx
>> 16 );
744 subg
->arg2
= (FT_Int
)( ady
>> 16 );
746 /* set up remaining glyph fields */
747 glyph
->num_subglyphs
= 2;
748 glyph
->subglyphs
= loader
->base
.subglyphs
;
749 glyph
->format
= FT_GLYPH_FORMAT_COMPOSITE
;
751 loader
->current
.num_subglyphs
= 2;
754 FT_GlyphLoader_Prepare( builder
->loader
);
756 /* First load `bchar' in builder */
757 error
= cff_get_glyph_data( face
, bchar_index
,
758 &charstring
, &charstring_len
);
761 error
= cff_decoder_parse_charstrings( decoder
, charstring
,
767 cff_free_glyph_data( face
, &charstring
, charstring_len
);
770 /* Save the left bearing and width of the base character */
771 /* as they will be erased by the next load. */
773 left_bearing
= builder
->left_bearing
;
774 advance
= builder
->advance
;
776 builder
->left_bearing
.x
= 0;
777 builder
->left_bearing
.y
= 0;
779 builder
->pos_x
= adx
;
780 builder
->pos_y
= ady
;
782 /* Now load `achar' on top of the base outline. */
783 error
= cff_get_glyph_data( face
, achar_index
,
784 &charstring
, &charstring_len
);
787 error
= cff_decoder_parse_charstrings( decoder
, charstring
,
793 cff_free_glyph_data( face
, &charstring
, charstring_len
);
796 /* Restore the left side bearing and advance width */
797 /* of the base character. */
798 builder
->left_bearing
= left_bearing
;
799 builder
->advance
= advance
;
809 /*************************************************************************/
812 /* cff_decoder_parse_charstrings */
815 /* Parses a given Type 2 charstrings program. */
818 /* decoder :: The current Type 1 decoder. */
821 /* charstring_base :: The base of the charstring stream. */
823 /* charstring_len :: The length in bytes of the charstring stream. */
826 /* FreeType error code. 0 means success. */
828 FT_LOCAL_DEF( FT_Error
)
829 cff_decoder_parse_charstrings( CFF_Decoder
* decoder
,
830 FT_Byte
* charstring_base
,
831 FT_ULong charstring_len
)
834 CFF_Decoder_Zone
* zone
;
837 CFF_Builder
* builder
= &decoder
->builder
;
842 T2_Hints_Funcs hinter
;
845 /* set default width */
846 decoder
->num_hints
= 0;
847 decoder
->read_width
= 1;
849 /* compute random seed from stack address of parameter */
850 seed
= (FT_Fixed
)(char*)&seed
^
851 (FT_Fixed
)(char*)&decoder
^
852 (FT_Fixed
)(char*)&charstring_base
;
853 seed
= ( seed
^ ( seed
>> 10 ) ^ ( seed
>> 20 ) ) & 0xFFFFL
;
857 /* initialize the decoder */
858 decoder
->top
= decoder
->stack
;
859 decoder
->zone
= decoder
->zones
;
860 zone
= decoder
->zones
;
861 stack
= decoder
->top
;
863 hinter
= (T2_Hints_Funcs
)builder
->hints_funcs
;
865 builder
->path_begun
= 0;
867 zone
->base
= charstring_base
;
868 limit
= zone
->limit
= charstring_base
+ charstring_len
;
869 ip
= zone
->cursor
= zone
->base
;
876 /* begin hints recording session, if any */
878 hinter
->open( hinter
->hints
);
880 /* now execute loop */
887 /********************************************************************/
889 /* Decode operator or operand */
892 if ( v
>= 32 || v
== 28 )
898 /* this is an operand, push it on the stack */
901 if ( ip
+ 1 >= limit
)
903 val
= (FT_Short
)( ( (FT_Short
)ip
[0] << 8 ) | ip
[1] );
907 val
= (FT_Long
)v
- 139;
912 val
= ( (FT_Long
)v
- 247 ) * 256 + *ip
++ + 108;
918 val
= -( (FT_Long
)v
- 251 ) * 256 - *ip
++ - 108;
922 if ( ip
+ 3 >= limit
)
924 val
= ( (FT_Int32
)ip
[0] << 24 ) |
925 ( (FT_Int32
)ip
[1] << 16 ) |
926 ( (FT_Int32
)ip
[2] << 8 ) |
931 if ( decoder
->top
- stack
>= CFF_MAX_OPERANDS
)
935 *decoder
->top
++ = val
;
937 #ifdef FT_DEBUG_LEVEL_TRACE
938 if ( !( val
& 0xFFFFL
) )
939 FT_TRACE4(( " %ld", (FT_Int32
)( val
>> 16 ) ));
941 FT_TRACE4(( " %.2f", val
/ 65536.0 ));
947 FT_Fixed
* args
= decoder
->top
;
948 FT_Int num_args
= (FT_Int
)( args
- decoder
->stack
);
976 op
= cff_op_rrcurveto
;
979 op
= cff_op_closepath
;
982 op
= cff_op_callsubr
;
996 op
= cff_op_dotsection
;
1077 /* decrement ip for syntax error message */
1086 op
= cff_op_endchar
;
1092 op
= cff_op_hstemhm
;
1095 op
= cff_op_hintmask
;
1098 op
= cff_op_cntrmask
;
1101 op
= cff_op_rmoveto
;
1104 op
= cff_op_hmoveto
;
1107 op
= cff_op_vstemhm
;
1110 op
= cff_op_rcurveline
;
1113 op
= cff_op_rlinecurve
;
1116 op
= cff_op_vvcurveto
;
1119 op
= cff_op_hhcurveto
;
1122 op
= cff_op_callgsubr
;
1125 op
= cff_op_vhcurveto
;
1128 op
= cff_op_hvcurveto
;
1133 if ( op
== cff_op_unknown
)
1136 /* check arguments */
1137 req_args
= cff_argument_counts
[op
];
1138 if ( req_args
& CFF_COUNT_CHECK_WIDTH
)
1142 if ( num_args
> 0 && decoder
->read_width
)
1144 /* If `nominal_width' is non-zero, the number is really a */
1145 /* difference against `nominal_width'. Else, the number here */
1146 /* is truly a width, not a difference against `nominal_width'. */
1147 /* If the font does not set `nominal_width', then */
1148 /* `nominal_width' defaults to zero, and so we can set */
1149 /* `glyph_width' to `nominal_width' plus number on the stack */
1150 /* -- for either case. */
1152 FT_Int set_width_ok
;
1157 case cff_op_hmoveto
:
1158 case cff_op_vmoveto
:
1159 set_width_ok
= num_args
& 2;
1164 case cff_op_hstemhm
:
1165 case cff_op_vstemhm
:
1166 case cff_op_rmoveto
:
1167 case cff_op_hintmask
:
1168 case cff_op_cntrmask
:
1169 set_width_ok
= num_args
& 1;
1172 case cff_op_endchar
:
1173 /* If there is a width specified for endchar, we either have */
1174 /* 1 argument or 5 arguments. We like to argue. */
1175 set_width_ok
= ( ( num_args
== 5 ) || ( num_args
== 1 ) );
1185 decoder
->glyph_width
= decoder
->nominal_width
+
1188 /* Consumed an argument. */
1194 decoder
->read_width
= 0;
1199 if ( num_args
< req_args
)
1200 goto Stack_Underflow
;
1202 num_args
-= req_args
;
1208 case cff_op_hstemhm
:
1209 case cff_op_vstemhm
:
1210 /* the number of arguments is always even here */
1211 FT_TRACE4(( op
== cff_op_hstem
? " hstem" :
1212 ( op
== cff_op_vstem
? " vstem" :
1213 ( op
== cff_op_hstemhm
? " hstemhm" : " vstemhm" ) ) ));
1216 hinter
->stems( hinter
->hints
,
1217 ( op
== cff_op_hstem
|| op
== cff_op_hstemhm
),
1221 decoder
->num_hints
+= num_args
/ 2;
1225 case cff_op_hintmask
:
1226 case cff_op_cntrmask
:
1227 FT_TRACE4(( op
== cff_op_hintmask
? " hintmask" : " cntrmask" ));
1229 /* implement vstem when needed -- */
1230 /* the specification doesn't say it, but this also works */
1231 /* with the 'cntrmask' operator */
1236 hinter
->stems( hinter
->hints
,
1241 decoder
->num_hints
+= num_args
/ 2;
1246 if ( op
== cff_op_hintmask
)
1247 hinter
->hintmask( hinter
->hints
,
1248 builder
->current
->n_points
,
1252 hinter
->counter( hinter
->hints
,
1257 #ifdef FT_DEBUG_LEVEL_TRACE
1265 maskbyte
< (FT_UInt
)(( decoder
->num_hints
+ 7 ) >> 3);
1267 FT_TRACE4(( "0x%02X", *ip
));
1270 ip
+= ( decoder
->num_hints
+ 7 ) >> 3;
1277 case cff_op_rmoveto
:
1278 FT_TRACE4(( " rmoveto" ));
1280 cff_builder_close_contour( builder
);
1281 builder
->path_begun
= 0;
1287 case cff_op_vmoveto
:
1288 FT_TRACE4(( " vmoveto" ));
1290 cff_builder_close_contour( builder
);
1291 builder
->path_begun
= 0;
1296 case cff_op_hmoveto
:
1297 FT_TRACE4(( " hmoveto" ));
1299 cff_builder_close_contour( builder
);
1300 builder
->path_begun
= 0;
1305 case cff_op_rlineto
:
1306 FT_TRACE4(( " rlineto" ));
1308 if ( cff_builder_start_point ( builder
, x
, y
) ||
1309 check_points( builder
, num_args
/ 2 ) )
1312 if ( num_args
< 2 || num_args
& 1 )
1313 goto Stack_Underflow
;
1316 while ( args
< decoder
->top
)
1320 cff_builder_add_point( builder
, x
, y
, 1 );
1326 case cff_op_hlineto
:
1327 case cff_op_vlineto
:
1329 FT_Int phase
= ( op
== cff_op_hlineto
);
1332 FT_TRACE4(( op
== cff_op_hlineto
? " hlineto"
1335 if ( cff_builder_start_point ( builder
, x
, y
) ||
1336 check_points( builder
, num_args
) )
1340 while ( args
< decoder
->top
)
1347 if ( cff_builder_add_point1( builder
, x
, y
) )
1357 case cff_op_rrcurveto
:
1358 FT_TRACE4(( " rrcurveto" ));
1360 /* check number of arguments; must be a multiple of 6 */
1361 if ( num_args
% 6 != 0 )
1362 goto Stack_Underflow
;
1364 if ( cff_builder_start_point ( builder
, x
, y
) ||
1365 check_points( builder
, num_args
/ 2 ) )
1369 while ( args
< decoder
->top
)
1373 cff_builder_add_point( builder
, x
, y
, 0 );
1376 cff_builder_add_point( builder
, x
, y
, 0 );
1379 cff_builder_add_point( builder
, x
, y
, 1 );
1385 case cff_op_vvcurveto
:
1386 FT_TRACE4(( " vvcurveto" ));
1388 if ( cff_builder_start_point( builder
, x
, y
) )
1399 if ( num_args
% 4 != 0 )
1400 goto Stack_Underflow
;
1402 if ( check_points( builder
, 3 * ( num_args
/ 4 ) ) )
1405 while ( args
< decoder
->top
)
1408 cff_builder_add_point( builder
, x
, y
, 0 );
1411 cff_builder_add_point( builder
, x
, y
, 0 );
1413 cff_builder_add_point( builder
, x
, y
, 1 );
1419 case cff_op_hhcurveto
:
1420 FT_TRACE4(( " hhcurveto" ));
1422 if ( cff_builder_start_point( builder
, x
, y
) )
1433 if ( num_args
% 4 != 0 )
1434 goto Stack_Underflow
;
1436 if ( check_points( builder
, 3 * ( num_args
/ 4 ) ) )
1439 while ( args
< decoder
->top
)
1442 cff_builder_add_point( builder
, x
, y
, 0 );
1445 cff_builder_add_point( builder
, x
, y
, 0 );
1447 cff_builder_add_point( builder
, x
, y
, 1 );
1453 case cff_op_vhcurveto
:
1454 case cff_op_hvcurveto
:
1459 FT_TRACE4(( op
== cff_op_vhcurveto
? " vhcurveto"
1462 if ( cff_builder_start_point( builder
, x
, y
) )
1466 if ( num_args
< 4 || ( num_args
% 4 ) > 1 )
1467 goto Stack_Underflow
;
1469 if ( check_points( builder
, ( num_args
/ 4 ) * 3 ) )
1470 goto Stack_Underflow
;
1472 phase
= ( op
== cff_op_hvcurveto
);
1474 while ( num_args
>= 4 )
1480 cff_builder_add_point( builder
, x
, y
, 0 );
1483 cff_builder_add_point( builder
, x
, y
, 0 );
1485 if ( num_args
== 1 )
1487 cff_builder_add_point( builder
, x
, y
, 1 );
1492 cff_builder_add_point( builder
, x
, y
, 0 );
1495 cff_builder_add_point( builder
, x
, y
, 0 );
1497 if ( num_args
== 1 )
1499 cff_builder_add_point( builder
, x
, y
, 1 );
1508 case cff_op_rlinecurve
:
1510 FT_Int num_lines
= ( num_args
- 6 ) / 2;
1513 FT_TRACE4(( " rlinecurve" ));
1515 if ( num_args
< 8 || ( num_args
- 6 ) & 1 )
1516 goto Stack_Underflow
;
1518 if ( cff_builder_start_point( builder
, x
, y
) ||
1519 check_points( builder
, num_lines
+ 3 ) )
1524 /* first, add the line segments */
1525 while ( num_lines
> 0 )
1529 cff_builder_add_point( builder
, x
, y
, 1 );
1534 /* then the curve */
1537 cff_builder_add_point( builder
, x
, y
, 0 );
1540 cff_builder_add_point( builder
, x
, y
, 0 );
1543 cff_builder_add_point( builder
, x
, y
, 1 );
1548 case cff_op_rcurveline
:
1550 FT_Int num_curves
= ( num_args
- 2 ) / 6;
1553 FT_TRACE4(( " rcurveline" ));
1555 if ( num_args
< 8 || ( num_args
- 2 ) % 6 )
1556 goto Stack_Underflow
;
1558 if ( cff_builder_start_point ( builder
, x
, y
) ||
1559 check_points( builder
, num_curves
*3 + 2 ) )
1564 /* first, add the curves */
1565 while ( num_curves
> 0 )
1569 cff_builder_add_point( builder
, x
, y
, 0 );
1572 cff_builder_add_point( builder
, x
, y
, 0 );
1575 cff_builder_add_point( builder
, x
, y
, 1 );
1580 /* then the final line */
1583 cff_builder_add_point( builder
, x
, y
, 1 );
1593 FT_TRACE4(( " hflex1" ));
1597 /* adding five more points; 4 control points, 1 on-curve point */
1598 /* make sure we have enough space for the start point if it */
1599 /* needs to be added */
1600 if ( cff_builder_start_point( builder
, x
, y
) ||
1601 check_points( builder
, 6 ) )
1604 /* Record the starting point's y position for later use */
1607 /* first control point */
1610 cff_builder_add_point( builder
, x
, y
, 0 );
1612 /* second control point */
1615 cff_builder_add_point( builder
, x
, y
, 0 );
1617 /* join point; on curve, with y-value the same as the last */
1618 /* control point's y-value */
1620 cff_builder_add_point( builder
, x
, y
, 1 );
1622 /* third control point, with y-value the same as the join */
1623 /* point's y-value */
1625 cff_builder_add_point( builder
, x
, y
, 0 );
1627 /* fourth control point */
1630 cff_builder_add_point( builder
, x
, y
, 0 );
1632 /* ending point, with y-value the same as the start */
1635 cff_builder_add_point( builder
, x
, y
, 1 );
1646 FT_TRACE4(( " hflex" ));
1650 /* adding six more points; 4 control points, 2 on-curve points */
1651 if ( cff_builder_start_point( builder
, x
, y
) ||
1652 check_points( builder
, 6 ) )
1655 /* record the starting point's y-position for later use */
1658 /* first control point */
1660 cff_builder_add_point( builder
, x
, y
, 0 );
1662 /* second control point */
1665 cff_builder_add_point( builder
, x
, y
, 0 );
1667 /* join point; on curve, with y-value the same as the last */
1668 /* control point's y-value */
1670 cff_builder_add_point( builder
, x
, y
, 1 );
1672 /* third control point, with y-value the same as the join */
1673 /* point's y-value */
1675 cff_builder_add_point( builder
, x
, y
, 0 );
1677 /* fourth control point */
1680 cff_builder_add_point( builder
, x
, y
, 0 );
1682 /* ending point, with y-value the same as the start point's */
1683 /* y-value -- we don't add this point, though */
1685 cff_builder_add_point( builder
, x
, y
, 1 );
1693 FT_Pos start_x
, start_y
; /* record start x, y values for */
1695 FT_Fixed dx
= 0, dy
= 0; /* used in horizontal/vertical */
1696 /* algorithm below */
1697 FT_Int horizontal
, count
;
1700 FT_TRACE4(( " flex1" ));
1702 /* adding six more points; 4 control points, 2 on-curve points */
1703 if ( cff_builder_start_point( builder
, x
, y
) ||
1704 check_points( builder
, 6 ) )
1707 /* record the starting point's x, y position for later use */
1711 /* XXX: figure out whether this is supposed to be a horizontal */
1712 /* or vertical flex; the Type 2 specification is vague... */
1716 /* grab up to the last argument */
1717 for ( count
= 5; count
> 0; count
-- )
1727 if ( dx
< 0 ) dx
= -dx
;
1728 if ( dy
< 0 ) dy
= -dy
;
1730 /* strange test, but here it is... */
1731 horizontal
= ( dx
> dy
);
1733 for ( count
= 5; count
> 0; count
-- )
1737 cff_builder_add_point( builder
, x
, y
, (FT_Bool
)( count
== 3 ) );
1741 /* is last operand an x- or y-delta? */
1753 cff_builder_add_point( builder
, x
, y
, 1 );
1764 FT_TRACE4(( " flex" ));
1766 if ( cff_builder_start_point( builder
, x
, y
) ||
1767 check_points( builder
, 6 ) )
1771 for ( count
= 6; count
> 0; count
-- )
1775 cff_builder_add_point( builder
, x
, y
,
1776 (FT_Bool
)( count
== 4 || count
== 1 ) );
1784 case cff_op_endchar
:
1785 FT_TRACE4(( " endchar" ));
1787 /* We are going to emulate the seac operator. */
1788 if ( num_args
== 4 )
1790 /* Save glyph width so that the subglyphs don't overwrite it. */
1791 FT_Pos glyph_width
= decoder
->glyph_width
;
1794 error
= cff_operator_seac( decoder
,
1797 (FT_Int
)( args
[2] >> 16 ),
1798 (FT_Int
)( args
[3] >> 16 ) );
1801 decoder
->glyph_width
= glyph_width
;
1808 cff_builder_close_contour( builder
);
1810 /* close hints recording session */
1813 if ( hinter
->close( hinter
->hints
,
1814 builder
->current
->n_points
) )
1817 /* apply hints to the loaded glyph outline now */
1818 hinter
->apply( hinter
->hints
,
1820 (PSH_Globals
)builder
->hints_globals
,
1821 decoder
->hint_mode
);
1824 /* add current outline to the glyph slot */
1825 FT_GlyphLoader_Add( builder
->loader
);
1829 FT_TRACE4(( "\n\n" ));
1833 FT_TRACE4(( " abs" ));
1841 FT_TRACE4(( " add" ));
1848 FT_TRACE4(( " sub" ));
1855 FT_TRACE4(( " div" ));
1857 args
[0] = FT_DivFix( args
[0], args
[1] );
1862 FT_TRACE4(( " neg" ));
1873 FT_TRACE4(( " rand" ));
1876 if ( Rand
>= 0x8000L
)
1880 seed
= FT_MulFix( seed
, 0x10000L
- seed
);
1888 FT_TRACE4(( " mul" ));
1890 args
[0] = FT_MulFix( args
[0], args
[1] );
1895 FT_TRACE4(( " sqrt" ));
1900 FT_Fixed root
= args
[0];
1906 new_root
= ( root
+ FT_DivFix( args
[0], root
) + 1 ) >> 1;
1907 if ( new_root
== root
|| count
<= 0 )
1920 FT_TRACE4(( " drop" ));
1929 FT_TRACE4(( " exch" ));
1940 FT_Int idx
= (FT_Int
)( args
[0] >> 16 );
1943 FT_TRACE4(( " index" ));
1947 else if ( idx
> num_args
- 2 )
1949 args
[0] = args
[-( idx
+ 1 )];
1956 FT_Int count
= (FT_Int
)( args
[0] >> 16 );
1957 FT_Int idx
= (FT_Int
)( args
[1] >> 16 );
1960 FT_TRACE4(( " roll" ));
1967 goto Stack_Underflow
;
1973 FT_Fixed tmp
= args
[count
- 1];
1977 for ( i
= count
- 2; i
>= 0; i
-- )
1978 args
[i
+ 1] = args
[i
];
1987 FT_Fixed tmp
= args
[0];
1991 for ( i
= 0; i
< count
- 1; i
++ )
1992 args
[i
] = args
[i
+ 1];
1993 args
[count
- 1] = tmp
;
2002 FT_TRACE4(( " dup" ));
2010 FT_Fixed val
= args
[0];
2011 FT_Int idx
= (FT_Int
)( args
[1] >> 16 );
2014 FT_TRACE4(( " put" ));
2016 if ( idx
>= 0 && idx
< decoder
->len_buildchar
)
2017 decoder
->buildchar
[idx
] = val
;
2023 FT_Int idx
= (FT_Int
)( args
[0] >> 16 );
2027 FT_TRACE4(( " get" ));
2029 if ( idx
>= 0 && idx
< decoder
->len_buildchar
)
2030 val
= decoder
->buildchar
[idx
];
2038 FT_TRACE4(( " store "));
2043 FT_TRACE4(( " load" ));
2047 case cff_op_dotsection
:
2048 /* this operator is deprecated and ignored by the parser */
2049 FT_TRACE4(( " dotsection" ));
2052 case cff_op_closepath
:
2053 /* this is an invalid Type 2 operator; however, there */
2054 /* exist fonts which are incorrectly converted from probably */
2055 /* Type 1 to CFF, and some parsers seem to accept it */
2057 FT_TRACE4(( " closepath (invalid op)" ));
2063 /* this is an invalid Type 2 operator; however, there */
2064 /* exist fonts which are incorrectly converted from probably */
2065 /* Type 1 to CFF, and some parsers seem to accept it */
2067 FT_TRACE4(( " hsbw (invalid op)" ));
2069 decoder
->glyph_width
= decoder
->nominal_width
+
2078 FT_Fixed cond
= args
[0] && args
[1];
2081 FT_TRACE4(( " and" ));
2083 args
[0] = cond
? 0x10000L
: 0;
2090 FT_Fixed cond
= args
[0] || args
[1];
2093 FT_TRACE4(( " or" ));
2095 args
[0] = cond
? 0x10000L
: 0;
2102 FT_Fixed cond
= !args
[0];
2105 FT_TRACE4(( " eq" ));
2107 args
[0] = cond
? 0x10000L
: 0;
2114 FT_Fixed cond
= ( args
[2] <= args
[3] );
2117 FT_TRACE4(( " ifelse" ));
2125 case cff_op_callsubr
:
2127 FT_UInt idx
= (FT_UInt
)( ( args
[0] >> 16 ) +
2128 decoder
->locals_bias
);
2131 FT_TRACE4(( " callsubr(%d)", idx
));
2133 if ( idx
>= decoder
->num_locals
)
2135 FT_ERROR(( "cff_decoder_parse_charstrings:" ));
2136 FT_ERROR(( " invalid local subr index\n" ));
2140 if ( zone
- decoder
->zones
>= CFF_MAX_SUBRS_CALLS
)
2142 FT_ERROR(( "cff_decoder_parse_charstrings:"
2143 " too many nested subrs\n" ));
2147 zone
->cursor
= ip
; /* save current instruction pointer */
2150 zone
->base
= decoder
->locals
[idx
];
2151 zone
->limit
= decoder
->locals
[idx
+ 1];
2152 zone
->cursor
= zone
->base
;
2154 if ( !zone
->base
|| zone
->limit
== zone
->base
)
2156 FT_ERROR(( "cff_decoder_parse_charstrings:"
2157 " invoking empty subrs!\n" ));
2161 decoder
->zone
= zone
;
2163 limit
= zone
->limit
;
2167 case cff_op_callgsubr
:
2169 FT_UInt idx
= (FT_UInt
)( ( args
[0] >> 16 ) +
2170 decoder
->globals_bias
);
2173 FT_TRACE4(( " callgsubr(%d)", idx
));
2175 if ( idx
>= decoder
->num_globals
)
2177 FT_ERROR(( "cff_decoder_parse_charstrings:" ));
2178 FT_ERROR(( " invalid global subr index\n" ));
2182 if ( zone
- decoder
->zones
>= CFF_MAX_SUBRS_CALLS
)
2184 FT_ERROR(( "cff_decoder_parse_charstrings:"
2185 " too many nested subrs\n" ));
2189 zone
->cursor
= ip
; /* save current instruction pointer */
2192 zone
->base
= decoder
->globals
[idx
];
2193 zone
->limit
= decoder
->globals
[idx
+ 1];
2194 zone
->cursor
= zone
->base
;
2196 if ( !zone
->base
|| zone
->limit
== zone
->base
)
2198 FT_ERROR(( "cff_decoder_parse_charstrings:"
2199 " invoking empty subrs!\n" ));
2203 decoder
->zone
= zone
;
2205 limit
= zone
->limit
;
2210 FT_TRACE4(( " return" ));
2212 if ( decoder
->zone
<= decoder
->zones
)
2214 FT_ERROR(( "cff_decoder_parse_charstrings:"
2215 " unexpected return\n" ));
2220 zone
= decoder
->zone
;
2222 limit
= zone
->limit
;
2227 FT_ERROR(( "Unimplemented opcode: %d", ip
[-1] ));
2230 FT_ERROR(( " %d", ip
[0] ));
2233 return CFF_Err_Unimplemented_Feature
;
2236 decoder
->top
= args
;
2238 } /* general operator processing */
2240 } /* while ip < limit */
2242 FT_TRACE4(( "..end..\n\n" ));
2248 FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error!" ));
2249 return CFF_Err_Invalid_File_Format
;
2252 FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow!" ));
2253 return CFF_Err_Too_Few_Arguments
;
2256 FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow!" ));
2257 return CFF_Err_Stack_Overflow
;
2261 /*************************************************************************/
2262 /*************************************************************************/
2263 /*************************************************************************/
2264 /********** *********/
2265 /********** *********/
2266 /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/
2267 /********** *********/
2268 /********** The following code is in charge of computing *********/
2269 /********** the maximum advance width of the font. It *********/
2270 /********** quickly processes each glyph charstring to *********/
2271 /********** extract the value from either a `sbw' or `seac' *********/
2272 /********** operator. *********/
2273 /********** *********/
2274 /*************************************************************************/
2275 /*************************************************************************/
2276 /*************************************************************************/
2279 #if 0 /* unused until we support pure CFF fonts */
2282 FT_LOCAL_DEF( FT_Error
)
2283 cff_compute_max_advance( TT_Face face
,
2284 FT_Int
* max_advance
)
2286 FT_Error error
= CFF_Err_Ok
;
2287 CFF_Decoder decoder
;
2289 CFF_Font cff
= (CFF_Font
)face
->other
;
2294 /* Initialize load decoder */
2295 cff_decoder_init( &decoder
, face
, 0, 0, 0, 0 );
2297 decoder
.builder
.metrics_only
= 1;
2298 decoder
.builder
.load_points
= 0;
2300 /* For each glyph, parse the glyph charstring and extract */
2301 /* the advance width. */
2302 for ( glyph_index
= 0; glyph_index
< face
->root
.num_glyphs
;
2305 FT_Byte
* charstring
;
2306 FT_ULong charstring_len
;
2309 /* now get load the unscaled outline */
2310 error
= cff_get_glyph_data( face
, glyph_index
,
2311 &charstring
, &charstring_len
);
2314 error
= cff_decoder_prepare( &decoder
, size
, glyph_index
);
2316 error
= cff_decoder_parse_charstrings( &decoder
,
2320 cff_free_glyph_data( face
, &charstring
, &charstring_len
);
2323 /* ignore the error if one has occurred -- skip to next glyph */
2327 *max_advance
= decoder
.builder
.advance
.x
;
2336 FT_LOCAL_DEF( FT_Error
)
2337 cff_slot_load( CFF_GlyphSlot glyph
,
2339 FT_UInt glyph_index
,
2340 FT_Int32 load_flags
)
2343 CFF_Decoder decoder
;
2344 TT_Face face
= (TT_Face
)glyph
->root
.face
;
2345 FT_Bool hinting
, force_scaling
;
2346 CFF_Font cff
= (CFF_Font
)face
->extra
.data
;
2348 FT_Matrix font_matrix
;
2349 FT_Vector font_offset
;
2352 force_scaling
= FALSE
;
2354 /* in a CID-keyed font, consider `glyph_index' as a CID and map */
2355 /* it immediately to the real glyph_index -- if it isn't a */
2356 /* subsetted font, glyph_indices and CIDs are identical, though */
2357 if ( cff
->top_font
.font_dict
.cid_registry
!= 0xFFFFU
&&
2360 glyph_index
= cff_charset_cid_to_gindex( &cff
->charset
, glyph_index
);
2361 if ( glyph_index
== 0 )
2362 return CFF_Err_Invalid_Argument
;
2364 else if ( glyph_index
>= cff
->num_glyphs
)
2365 return CFF_Err_Invalid_Argument
;
2367 if ( load_flags
& FT_LOAD_NO_RECURSE
)
2368 load_flags
|= FT_LOAD_NO_SCALE
| FT_LOAD_NO_HINTING
;
2370 glyph
->x_scale
= 0x10000L
;
2371 glyph
->y_scale
= 0x10000L
;
2374 glyph
->x_scale
= size
->root
.metrics
.x_scale
;
2375 glyph
->y_scale
= size
->root
.metrics
.y_scale
;
2378 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
2380 /* try to load embedded bitmap if any */
2382 /* XXX: The convention should be emphasized in */
2383 /* the documents because it can be confusing. */
2386 CFF_Face cff_face
= (CFF_Face
)size
->root
.face
;
2387 SFNT_Service sfnt
= (SFNT_Service
)cff_face
->sfnt
;
2388 FT_Stream stream
= cff_face
->root
.stream
;
2391 if ( size
->strike_index
!= 0xFFFFFFFFUL
&&
2393 ( load_flags
& FT_LOAD_NO_BITMAP
) == 0 )
2395 TT_SBit_MetricsRec metrics
;
2398 error
= sfnt
->load_sbit_image( face
,
2403 &glyph
->root
.bitmap
,
2408 glyph
->root
.outline
.n_points
= 0;
2409 glyph
->root
.outline
.n_contours
= 0;
2411 glyph
->root
.metrics
.width
= (FT_Pos
)metrics
.width
<< 6;
2412 glyph
->root
.metrics
.height
= (FT_Pos
)metrics
.height
<< 6;
2414 glyph
->root
.metrics
.horiBearingX
= (FT_Pos
)metrics
.horiBearingX
<< 6;
2415 glyph
->root
.metrics
.horiBearingY
= (FT_Pos
)metrics
.horiBearingY
<< 6;
2416 glyph
->root
.metrics
.horiAdvance
= (FT_Pos
)metrics
.horiAdvance
<< 6;
2418 glyph
->root
.metrics
.vertBearingX
= (FT_Pos
)metrics
.vertBearingX
<< 6;
2419 glyph
->root
.metrics
.vertBearingY
= (FT_Pos
)metrics
.vertBearingY
<< 6;
2420 glyph
->root
.metrics
.vertAdvance
= (FT_Pos
)metrics
.vertAdvance
<< 6;
2422 glyph
->root
.format
= FT_GLYPH_FORMAT_BITMAP
;
2424 if ( load_flags
& FT_LOAD_VERTICAL_LAYOUT
)
2426 glyph
->root
.bitmap_left
= metrics
.vertBearingX
;
2427 glyph
->root
.bitmap_top
= metrics
.vertBearingY
;
2431 glyph
->root
.bitmap_left
= metrics
.horiBearingX
;
2432 glyph
->root
.bitmap_top
= metrics
.horiBearingY
;
2439 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
2441 /* return immediately if we only want the embedded bitmaps */
2442 if ( load_flags
& FT_LOAD_SBITS_ONLY
)
2443 return CFF_Err_Invalid_Argument
;
2445 /* if we have a CID subfont, use its matrix (which has already */
2446 /* been multiplied with the root matrix) */
2448 /* this scaling is only relevant if the PS hinter isn't active */
2449 if ( cff
->num_subfonts
)
2451 FT_Byte fd_index
= cff_fd_select_get( &cff
->fd_select
,
2454 FT_Int top_upm
= cff
->top_font
.font_dict
.units_per_em
;
2455 FT_Int sub_upm
= cff
->subfonts
[fd_index
]->font_dict
.units_per_em
;
2458 font_matrix
= cff
->subfonts
[fd_index
]->font_dict
.font_matrix
;
2459 font_offset
= cff
->subfonts
[fd_index
]->font_dict
.font_offset
;
2461 if ( top_upm
!= sub_upm
)
2463 glyph
->x_scale
= FT_MulDiv( glyph
->x_scale
, top_upm
, sub_upm
);
2464 glyph
->y_scale
= FT_MulDiv( glyph
->y_scale
, top_upm
, sub_upm
);
2466 force_scaling
= TRUE
;
2471 font_matrix
= cff
->top_font
.font_dict
.font_matrix
;
2472 font_offset
= cff
->top_font
.font_dict
.font_offset
;
2475 glyph
->root
.outline
.n_points
= 0;
2476 glyph
->root
.outline
.n_contours
= 0;
2478 hinting
= FT_BOOL( ( load_flags
& FT_LOAD_NO_SCALE
) == 0 &&
2479 ( load_flags
& FT_LOAD_NO_HINTING
) == 0 );
2481 glyph
->root
.format
= FT_GLYPH_FORMAT_OUTLINE
; /* by default */
2484 FT_Byte
* charstring
;
2485 FT_ULong charstring_len
;
2488 cff_decoder_init( &decoder
, face
, size
, glyph
, hinting
,
2489 FT_LOAD_TARGET_MODE( load_flags
) );
2491 decoder
.builder
.no_recurse
=
2492 (FT_Bool
)( ( load_flags
& FT_LOAD_NO_RECURSE
) != 0 );
2494 /* now load the unscaled outline */
2495 error
= cff_get_glyph_data( face
, glyph_index
,
2496 &charstring
, &charstring_len
);
2499 error
= cff_decoder_prepare( &decoder
, size
, glyph_index
);
2502 error
= cff_decoder_parse_charstrings( &decoder
,
2506 cff_free_glyph_data( face
, &charstring
, charstring_len
);
2509 #ifdef FT_CONFIG_OPTION_INCREMENTAL
2510 /* Control data and length may not be available for incremental */
2512 if ( face
->root
.internal
->incremental_interface
)
2514 glyph
->root
.control_data
= 0;
2515 glyph
->root
.control_len
= 0;
2518 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
2520 /* We set control_data and control_len if charstrings is loaded. */
2521 /* See how charstring loads at cff_index_access_element() in */
2524 CFF_Index csindex
= &cff
->charstrings_index
;
2527 if ( csindex
->offsets
)
2529 glyph
->root
.control_data
= csindex
->bytes
+
2530 csindex
->offsets
[glyph_index
] - 1;
2531 glyph
->root
.control_len
= charstring_len
;
2537 /* save new glyph tables */
2538 cff_builder_done( &decoder
.builder
);
2541 #ifdef FT_CONFIG_OPTION_INCREMENTAL
2543 /* Incremental fonts can optionally override the metrics. */
2545 face
->root
.internal
->incremental_interface
&&
2546 face
->root
.internal
->incremental_interface
->funcs
->get_glyph_metrics
)
2548 FT_Incremental_MetricsRec metrics
;
2551 metrics
.bearing_x
= decoder
.builder
.left_bearing
.x
;
2552 metrics
.bearing_y
= decoder
.builder
.left_bearing
.y
;
2553 metrics
.advance
= decoder
.builder
.advance
.x
;
2554 error
= face
->root
.internal
->incremental_interface
->funcs
->get_glyph_metrics(
2555 face
->root
.internal
->incremental_interface
->object
,
2556 glyph_index
, FALSE
, &metrics
);
2557 decoder
.builder
.left_bearing
.x
= metrics
.bearing_x
;
2558 decoder
.builder
.left_bearing
.y
= metrics
.bearing_y
;
2559 decoder
.builder
.advance
.x
= metrics
.advance
;
2560 decoder
.builder
.advance
.y
= 0;
2563 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
2567 /* Now, set the metrics -- this is rather simple, as */
2568 /* the left side bearing is the xMin, and the top side */
2569 /* bearing the yMax. */
2571 /* For composite glyphs, return only left side bearing and */
2572 /* advance width. */
2573 if ( load_flags
& FT_LOAD_NO_RECURSE
)
2575 FT_Slot_Internal internal
= glyph
->root
.internal
;
2578 glyph
->root
.metrics
.horiBearingX
= decoder
.builder
.left_bearing
.x
;
2579 glyph
->root
.metrics
.horiAdvance
= decoder
.glyph_width
;
2580 internal
->glyph_matrix
= font_matrix
;
2581 internal
->glyph_delta
= font_offset
;
2582 internal
->glyph_transformed
= 1;
2587 FT_Glyph_Metrics
* metrics
= &glyph
->root
.metrics
;
2589 FT_Bool has_vertical_info
;
2592 /* copy the _unscaled_ advance width */
2593 metrics
->horiAdvance
= decoder
.glyph_width
;
2594 glyph
->root
.linearHoriAdvance
= decoder
.glyph_width
;
2595 glyph
->root
.internal
->glyph_transformed
= 0;
2597 has_vertical_info
= FT_BOOL( face
->vertical_info
&&
2598 face
->vertical
.number_Of_VMetrics
> 0 &&
2599 face
->vertical
.long_metrics
!= 0 );
2601 /* get the vertical metrics from the vtmx table if we have one */
2602 if ( has_vertical_info
)
2604 FT_Short vertBearingY
= 0;
2605 FT_UShort vertAdvance
= 0;
2608 ( (SFNT_Service
)face
->sfnt
)->get_metrics( face
, 1,
2612 metrics
->vertBearingY
= vertBearingY
;
2613 metrics
->vertAdvance
= vertAdvance
;
2617 /* make up vertical ones */
2618 if ( face
->os2
.version
!= 0xFFFFU
)
2619 metrics
->vertAdvance
= (FT_Pos
)( face
->os2
.sTypoAscender
-
2620 face
->os2
.sTypoDescender
);
2622 metrics
->vertAdvance
= (FT_Pos
)( face
->horizontal
.Ascender
-
2623 face
->horizontal
.Descender
);
2626 glyph
->root
.linearVertAdvance
= metrics
->vertAdvance
;
2628 glyph
->root
.format
= FT_GLYPH_FORMAT_OUTLINE
;
2630 glyph
->root
.outline
.flags
= 0;
2631 if ( size
&& size
->root
.metrics
.y_ppem
< 24 )
2632 glyph
->root
.outline
.flags
|= FT_OUTLINE_HIGH_PRECISION
;
2634 glyph
->root
.outline
.flags
|= FT_OUTLINE_REVERSE_FILL
;
2636 /* apply the font matrix -- `xx' has already been normalized */
2637 if ( !( font_matrix
.yy
== 0x10000L
&&
2638 font_matrix
.xy
== 0 &&
2639 font_matrix
.yx
== 0 ) )
2640 FT_Outline_Transform( &glyph
->root
.outline
, &font_matrix
);
2642 if ( !( font_offset
.x
== 0 &&
2643 font_offset
.y
== 0 ) )
2644 FT_Outline_Translate( &glyph
->root
.outline
,
2645 font_offset
.x
, font_offset
.y
);
2647 advance
.x
= metrics
->horiAdvance
;
2649 FT_Vector_Transform( &advance
, &font_matrix
);
2650 metrics
->horiAdvance
= advance
.x
+ font_offset
.x
;
2653 advance
.y
= metrics
->vertAdvance
;
2654 FT_Vector_Transform( &advance
, &font_matrix
);
2655 metrics
->vertAdvance
= advance
.y
+ font_offset
.y
;
2657 if ( ( load_flags
& FT_LOAD_NO_SCALE
) == 0 || force_scaling
)
2659 /* scale the outline and the metrics */
2661 FT_Outline
* cur
= &glyph
->root
.outline
;
2662 FT_Vector
* vec
= cur
->points
;
2663 FT_Fixed x_scale
= glyph
->x_scale
;
2664 FT_Fixed y_scale
= glyph
->y_scale
;
2667 /* First of all, scale the points */
2668 if ( !hinting
|| !decoder
.builder
.hints_funcs
)
2669 for ( n
= cur
->n_points
; n
> 0; n
--, vec
++ )
2671 vec
->x
= FT_MulFix( vec
->x
, x_scale
);
2672 vec
->y
= FT_MulFix( vec
->y
, y_scale
);
2675 /* Then scale the metrics */
2676 metrics
->horiAdvance
= FT_MulFix( metrics
->horiAdvance
, x_scale
);
2677 metrics
->vertAdvance
= FT_MulFix( metrics
->vertAdvance
, y_scale
);
2680 /* compute the other metrics */
2681 FT_Outline_Get_CBox( &glyph
->root
.outline
, &cbox
);
2683 metrics
->width
= cbox
.xMax
- cbox
.xMin
;
2684 metrics
->height
= cbox
.yMax
- cbox
.yMin
;
2686 metrics
->horiBearingX
= cbox
.xMin
;
2687 metrics
->horiBearingY
= cbox
.yMax
;
2689 if ( has_vertical_info
)
2690 metrics
->vertBearingX
= -metrics
->width
/ 2;
2692 ft_synthesize_vertical_metrics( metrics
,
2693 metrics
->vertAdvance
);