1 /***************************************************************************/
5 /* OpenType Glyph Loader (body). */
7 /* Copyright 1996-2012 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
32 /*************************************************************************/
34 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
35 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
36 /* messages during execution. */
39 #define FT_COMPONENT trace_cffgload
42 typedef enum CFF_Operator_
76 cff_op_dotsection, /* deprecated, acts as no-op */
110 /* Type 1 opcodes: invalid but seen in real life */
113 cff_op_callothersubr,
117 cff_op_setcurrentpoint,
125 #define CFF_COUNT_CHECK_WIDTH 0x80
126 #define CFF_COUNT_EXACT 0x40
127 #define CFF_COUNT_CLEAR_STACK 0x20
129 /* count values which have the `CFF_COUNT_CHECK_WIDTH' flag set are */
130 /* used for checking the width and requested numbers of arguments */
131 /* only; they are set to zero afterwards */
133 /* the other two flags are informative only and unused currently */
135 static const FT_Byte cff_argument_counts[] =
139 2 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, /* rmoveto */
140 1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT,
141 1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT,
143 0 | CFF_COUNT_CLEAR_STACK, /* rlineto */
144 0 | CFF_COUNT_CLEAR_STACK,
145 0 | CFF_COUNT_CLEAR_STACK,
147 0 | CFF_COUNT_CLEAR_STACK, /* rrcurveto */
148 0 | CFF_COUNT_CLEAR_STACK,
149 0 | CFF_COUNT_CLEAR_STACK,
150 0 | CFF_COUNT_CLEAR_STACK,
151 0 | CFF_COUNT_CLEAR_STACK,
152 0 | CFF_COUNT_CLEAR_STACK,
153 0 | CFF_COUNT_CLEAR_STACK,
160 0 | CFF_COUNT_CHECK_WIDTH, /* endchar */
162 2 | CFF_COUNT_CHECK_WIDTH, /* hstem */
163 2 | CFF_COUNT_CHECK_WIDTH,
164 2 | CFF_COUNT_CHECK_WIDTH,
165 2 | CFF_COUNT_CHECK_WIDTH,
167 0 | CFF_COUNT_CHECK_WIDTH, /* hintmask */
168 0 | CFF_COUNT_CHECK_WIDTH, /* cntrmask */
209 2 /* setcurrentpoint */
213 /*************************************************************************/
214 /*************************************************************************/
215 /*************************************************************************/
216 /********** *********/
217 /********** *********/
218 /********** GENERIC CHARSTRING PARSING *********/
219 /********** *********/
220 /********** *********/
221 /*************************************************************************/
222 /*************************************************************************/
223 /*************************************************************************/
226 /*************************************************************************/
229 /* cff_builder_init */
232 /* Initializes a given glyph builder. */
235 /* builder :: A pointer to the glyph builder to initialize. */
238 /* face :: The current face object. */
240 /* size :: The current size object. */
242 /* glyph :: The current glyph object. */
244 /* hinting :: Whether hinting is active. */
247 cff_builder_init( CFF_Builder* builder,
253 builder->path_begun = 0;
254 builder->load_points = 1;
256 builder->face = face;
257 builder->glyph = glyph;
258 builder->memory = face->root.memory;
262 FT_GlyphLoader loader = glyph->root.internal->loader;
265 builder->loader = loader;
266 builder->base = &loader->base.outline;
267 builder->current = &loader->current.outline;
268 FT_GlyphLoader_Rewind( loader );
270 builder->hints_globals = 0;
271 builder->hints_funcs = 0;
273 if ( hinting && size )
275 CFF_Internal internal = (CFF_Internal)size->root.internal;
278 builder->hints_globals = (void *)internal->topfont;
279 builder->hints_funcs = glyph->root.internal->glyph_hints;
286 builder->left_bearing.x = 0;
287 builder->left_bearing.y = 0;
288 builder->advance.x = 0;
289 builder->advance.y = 0;
293 /*************************************************************************/
296 /* cff_builder_done */
299 /* Finalizes a given glyph builder. Its contents can still be used */
300 /* after the call, but the function saves important information */
301 /* within the corresponding glyph slot. */
304 /* builder :: A pointer to the glyph builder to finalize. */
307 cff_builder_done( CFF_Builder* builder )
309 CFF_GlyphSlot glyph = builder->glyph;
313 glyph->root.outline = *builder->base;
317 /*************************************************************************/
320 /* cff_compute_bias */
323 /* Computes the bias value in dependence of the number of glyph */
327 /* in_charstring_type :: The `CharstringType' value of the top DICT */
330 /* num_subrs :: The number of glyph subroutines. */
333 /* The bias value. */
335 cff_compute_bias( FT_Int in_charstring_type,
341 if ( in_charstring_type == 1 )
343 else if ( num_subrs < 1240 )
345 else if ( num_subrs < 33900U )
354 /*************************************************************************/
357 /* cff_decoder_init */
360 /* Initializes a given glyph decoder. */
363 /* decoder :: A pointer to the glyph builder to initialize. */
366 /* face :: The current face object. */
368 /* size :: The current size object. */
370 /* slot :: The current glyph object. */
372 /* hinting :: Whether hinting is active. */
374 /* hint_mode :: The hinting mode. */
377 cff_decoder_init( CFF_Decoder* decoder,
382 FT_Render_Mode hint_mode )
384 CFF_Font cff = (CFF_Font)face->extra.data;
387 /* clear everything */
388 FT_MEM_ZERO( decoder, sizeof ( *decoder ) );
390 /* initialize builder */
391 cff_builder_init( &decoder->builder, face, size, slot, hinting );
393 /* initialize Type2 decoder */
395 decoder->num_globals = cff->global_subrs_index.count;
396 decoder->globals = cff->global_subrs;
397 decoder->globals_bias = cff_compute_bias(
398 cff->top_font.font_dict.charstring_type,
399 decoder->num_globals );
401 decoder->hint_mode = hint_mode;
405 /* this function is used to select the subfont */
406 /* and the locals subrs array */
407 FT_LOCAL_DEF( FT_Error )
408 cff_decoder_prepare( CFF_Decoder* decoder,
410 FT_UInt glyph_index )
412 CFF_Builder *builder = &decoder->builder;
413 CFF_Font cff = (CFF_Font)builder->face->extra.data;
414 CFF_SubFont sub = &cff->top_font;
415 FT_Error error = CFF_Err_Ok;
418 /* manage CID fonts */
419 if ( cff->num_subfonts )
421 FT_Byte fd_index = cff_fd_select_get( &cff->fd_select, glyph_index );
424 if ( fd_index >= cff->num_subfonts )
426 FT_TRACE4(( "cff_decoder_prepare: invalid CID subfont index\n" ));
427 error = CFF_Err_Invalid_File_Format;
431 FT_TRACE3(( "glyph index %d (subfont %d):\n", glyph_index, fd_index ));
433 sub = cff->subfonts[fd_index];
435 if ( builder->hints_funcs && size )
437 CFF_Internal internal = (CFF_Internal)size->root.internal;
440 /* for CFFs without subfonts, this value has already been set */
441 builder->hints_globals = (void *)internal->subfonts[fd_index];
444 #ifdef FT_DEBUG_LEVEL_TRACE
446 FT_TRACE3(( "glyph index %d:\n", glyph_index ));
449 decoder->num_locals = sub->local_subrs_index.count;
450 decoder->locals = sub->local_subrs;
451 decoder->locals_bias = cff_compute_bias(
452 decoder->cff->top_font.font_dict.charstring_type,
453 decoder->num_locals );
455 decoder->glyph_width = sub->private_dict.default_width;
456 decoder->nominal_width = sub->private_dict.nominal_width;
463 /* check that there is enough space for `count' more points */
465 check_points( CFF_Builder* builder,
468 return FT_GLYPHLOADER_CHECK_POINTS( builder->loader, count, 0 );
472 /* add a new point, do not check space */
474 cff_builder_add_point( CFF_Builder* builder,
479 FT_Outline* outline = builder->current;
482 if ( builder->load_points )
484 FT_Vector* point = outline->points + outline->n_points;
485 FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points;
490 *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC );
497 /* check space for a new on-curve point, then add it */
499 cff_builder_add_point1( CFF_Builder* builder,
506 error = check_points( builder, 1 );
508 cff_builder_add_point( builder, x, y, 1 );
514 /* check space for a new contour, then add it */
516 cff_builder_add_contour( CFF_Builder* builder )
518 FT_Outline* outline = builder->current;
522 if ( !builder->load_points )
524 outline->n_contours++;
528 error = FT_GLYPHLOADER_CHECK_POINTS( builder->loader, 0, 1 );
531 if ( outline->n_contours > 0 )
532 outline->contours[outline->n_contours - 1] =
533 (short)( outline->n_points - 1 );
535 outline->n_contours++;
542 /* if a path was begun, add its first on-curve point */
544 cff_builder_start_point( CFF_Builder* builder,
548 FT_Error error = CFF_Err_Ok;
551 /* test whether we are building a new contour */
552 if ( !builder->path_begun )
554 builder->path_begun = 1;
555 error = cff_builder_add_contour( builder );
557 error = cff_builder_add_point1( builder, x, y );
564 /* close the current contour */
566 cff_builder_close_contour( CFF_Builder* builder )
568 FT_Outline* outline = builder->current;
575 first = outline->n_contours <= 1
576 ? 0 : outline->contours[outline->n_contours - 2] + 1;
578 /* We must not include the last point in the path if it */
579 /* is located on the first point. */
580 if ( outline->n_points > 1 )
582 FT_Vector* p1 = outline->points + first;
583 FT_Vector* p2 = outline->points + outline->n_points - 1;
584 FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1;
587 /* `delete' last point only if it coincides with the first */
588 /* point and if it is not a control point (which can happen). */
589 if ( p1->x == p2->x && p1->y == p2->y )
590 if ( *control == FT_CURVE_TAG_ON )
594 if ( outline->n_contours > 0 )
596 /* Don't add contours only consisting of one point, i.e., */
597 /* check whether begin point and last point are the same. */
598 if ( first == outline->n_points - 1 )
600 outline->n_contours--;
604 outline->contours[outline->n_contours - 1] =
605 (short)( outline->n_points - 1 );
611 cff_lookup_glyph_by_stdcharcode( CFF_Font cff,
618 /* CID-keyed fonts don't have glyph names */
619 if ( !cff->charset.sids )
622 /* check range of standard char code */
623 if ( charcode < 0 || charcode > 255 )
626 /* Get code to SID mapping from `cff_standard_encoding'. */
627 glyph_sid = cff_get_standard_encoding( (FT_UInt)charcode );
629 for ( n = 0; n < cff->num_glyphs; n++ )
631 if ( cff->charset.sids[n] == glyph_sid )
640 cff_get_glyph_data( TT_Face face,
645 #ifdef FT_CONFIG_OPTION_INCREMENTAL
646 /* For incremental fonts get the character data using the */
647 /* callback function. */
648 if ( face->root.internal->incremental_interface )
652 face->root.internal->incremental_interface->funcs->get_glyph_data(
653 face->root.internal->incremental_interface->object,
654 glyph_index, &data );
657 *pointer = (FT_Byte*)data.pointer;
658 *length = data.length;
663 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
666 CFF_Font cff = (CFF_Font)(face->extra.data);
669 return cff_index_access_element( &cff->charstrings_index, glyph_index,
676 cff_free_glyph_data( TT_Face face,
680 #ifndef FT_CONFIG_OPTION_INCREMENTAL
684 #ifdef FT_CONFIG_OPTION_INCREMENTAL
685 /* For incremental fonts get the character data using the */
686 /* callback function. */
687 if ( face->root.internal->incremental_interface )
692 data.pointer = *pointer;
693 data.length = length;
695 face->root.internal->incremental_interface->funcs->free_glyph_data(
696 face->root.internal->incremental_interface->object, &data );
699 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
702 CFF_Font cff = (CFF_Font)(face->extra.data);
705 cff_index_forget_element( &cff->charstrings_index, pointer );
711 cff_operator_seac( CFF_Decoder* decoder,
719 CFF_Builder* builder = &decoder->builder;
720 FT_Int bchar_index, achar_index;
721 TT_Face face = decoder->builder.face;
722 FT_Vector left_bearing, advance;
724 FT_ULong charstring_len;
730 FT_ERROR(( "cff_operator_seac: invalid nested seac\n" ));
731 return CFF_Err_Syntax_Error;
734 adx += decoder->builder.left_bearing.x;
735 ady += decoder->builder.left_bearing.y;
737 #ifdef FT_CONFIG_OPTION_INCREMENTAL
738 /* Incremental fonts don't necessarily have valid charsets. */
739 /* They use the character code, not the glyph index, in this case. */
740 if ( face->root.internal->incremental_interface )
746 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
748 CFF_Font cff = (CFF_Font)(face->extra.data);
751 bchar_index = cff_lookup_glyph_by_stdcharcode( cff, bchar );
752 achar_index = cff_lookup_glyph_by_stdcharcode( cff, achar );
755 if ( bchar_index < 0 || achar_index < 0 )
757 FT_ERROR(( "cff_operator_seac:"
758 " invalid seac character code arguments\n" ));
759 return CFF_Err_Syntax_Error;
762 /* If we are trying to load a composite glyph, do not load the */
763 /* accent character and return the array of subglyphs. */
764 if ( builder->no_recurse )
766 FT_GlyphSlot glyph = (FT_GlyphSlot)builder->glyph;
767 FT_GlyphLoader loader = glyph->internal->loader;
771 /* reallocate subglyph array if necessary */
772 error = FT_GlyphLoader_CheckSubGlyphs( loader, 2 );
776 subg = loader->current.subglyphs;
778 /* subglyph 0 = base character */
779 subg->index = bchar_index;
780 subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES |
781 FT_SUBGLYPH_FLAG_USE_MY_METRICS;
786 /* subglyph 1 = accent character */
787 subg->index = achar_index;
788 subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES;
789 subg->arg1 = (FT_Int)( adx >> 16 );
790 subg->arg2 = (FT_Int)( ady >> 16 );
792 /* set up remaining glyph fields */
793 glyph->num_subglyphs = 2;
794 glyph->subglyphs = loader->base.subglyphs;
795 glyph->format = FT_GLYPH_FORMAT_COMPOSITE;
797 loader->current.num_subglyphs = 2;
800 FT_GlyphLoader_Prepare( builder->loader );
802 /* First load `bchar' in builder */
803 error = cff_get_glyph_data( face, bchar_index,
804 &charstring, &charstring_len );
807 /* the seac operator must not be nested */
808 decoder->seac = TRUE;
809 error = cff_decoder_parse_charstrings( decoder, charstring,
811 decoder->seac = FALSE;
813 cff_free_glyph_data( face, &charstring, charstring_len );
819 /* Save the left bearing, advance and glyph width of the base */
820 /* character as they will be erased by the next load. */
822 left_bearing = builder->left_bearing;
823 advance = builder->advance;
824 glyph_width = decoder->glyph_width;
826 builder->left_bearing.x = 0;
827 builder->left_bearing.y = 0;
829 builder->pos_x = adx - asb;
830 builder->pos_y = ady;
832 /* Now load `achar' on top of the base outline. */
833 error = cff_get_glyph_data( face, achar_index,
834 &charstring, &charstring_len );
837 /* the seac operator must not be nested */
838 decoder->seac = TRUE;
839 error = cff_decoder_parse_charstrings( decoder, charstring,
841 decoder->seac = FALSE;
843 cff_free_glyph_data( face, &charstring, charstring_len );
849 /* Restore the left side bearing, advance and glyph width */
850 /* of the base character. */
851 builder->left_bearing = left_bearing;
852 builder->advance = advance;
853 decoder->glyph_width = glyph_width;
863 /*************************************************************************/
866 /* cff_decoder_parse_charstrings */
869 /* Parses a given Type 2 charstrings program. */
872 /* decoder :: The current Type 1 decoder. */
875 /* charstring_base :: The base of the charstring stream. */
877 /* charstring_len :: The length in bytes of the charstring stream. */
880 /* FreeType error code. 0 means success. */
882 FT_LOCAL_DEF( FT_Error )
883 cff_decoder_parse_charstrings( CFF_Decoder* decoder,
884 FT_Byte* charstring_base,
885 FT_ULong charstring_len )
888 CFF_Decoder_Zone* zone;
891 CFF_Builder* builder = &decoder->builder;
895 FT_Int charstring_type =
896 decoder->cff->top_font.font_dict.charstring_type;
898 T2_Hints_Funcs hinter;
901 /* set default width */
902 decoder->num_hints = 0;
903 decoder->read_width = 1;
905 /* compute random seed from stack address of parameter */
906 seed = (FT_Fixed)( ( (FT_PtrDist)(char*)&seed ^
907 (FT_PtrDist)(char*)&decoder ^
908 (FT_PtrDist)(char*)&charstring_base ) &
910 seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL;
914 /* initialize the decoder */
915 decoder->top = decoder->stack;
916 decoder->zone = decoder->zones;
917 zone = decoder->zones;
918 stack = decoder->top;
920 hinter = (T2_Hints_Funcs)builder->hints_funcs;
922 builder->path_begun = 0;
924 zone->base = charstring_base;
925 limit = zone->limit = charstring_base + charstring_len;
926 ip = zone->cursor = zone->base;
933 /* begin hints recording session, if any */
935 hinter->open( hinter->hints );
937 /* now execute loop */
944 /********************************************************************/
946 /* Decode operator or operand */
949 if ( v >= 32 || v == 28 )
955 /* this is an operand, push it on the stack */
958 if ( ip + 1 >= limit )
960 val = (FT_Short)( ( (FT_Short)ip[0] << 8 ) | ip[1] );
964 val = (FT_Int32)v - 139;
969 val = ( (FT_Int32)v - 247 ) * 256 + *ip++ + 108;
975 val = -( (FT_Int32)v - 251 ) * 256 - *ip++ - 108;
979 if ( ip + 3 >= limit )
981 val = ( (FT_Int32)ip[0] << 24 ) |
982 ( (FT_Int32)ip[1] << 16 ) |
983 ( (FT_Int32)ip[2] << 8 ) |
986 if ( charstring_type == 2 )
989 if ( decoder->top - stack >= CFF_MAX_OPERANDS )
993 *decoder->top++ = val;
995 #ifdef FT_DEBUG_LEVEL_TRACE
996 if ( !( val & 0xFFFFL ) )
997 FT_TRACE4(( " %ld", (FT_Int32)( val >> 16 ) ));
999 FT_TRACE4(( " %.2f", val / 65536.0 ));
1005 /* The specification says that normally arguments are to be taken */
1006 /* from the bottom of the stack. However, this seems not to be */
1007 /* correct, at least for Acroread 7.0.8 on GNU/Linux: It pops the */
1008 /* arguments similar to a PS interpreter. */
1010 FT_Fixed* args = decoder->top;
1011 FT_Int num_args = (FT_Int)( args - decoder->stack );
1016 op = cff_op_unknown;
1027 op = cff_op_vmoveto;
1030 op = cff_op_rlineto;
1033 op = cff_op_hlineto;
1036 op = cff_op_vlineto;
1039 op = cff_op_rrcurveto;
1042 op = cff_op_closepath;
1045 op = cff_op_callsubr;
1059 op = cff_op_dotsection;
1061 case 1: /* this is actually the Type1 vstem3 operator */
1064 case 2: /* this is actually the Type1 hstem3 operator */
1107 op = cff_op_callothersubr;
1146 op = cff_op_setcurrentpoint;
1161 FT_TRACE4(( " unknown op (12, %d)\n", v ));
1170 op = cff_op_endchar;
1176 op = cff_op_hstemhm;
1179 op = cff_op_hintmask;
1182 op = cff_op_cntrmask;
1185 op = cff_op_rmoveto;
1188 op = cff_op_hmoveto;
1191 op = cff_op_vstemhm;
1194 op = cff_op_rcurveline;
1197 op = cff_op_rlinecurve;
1200 op = cff_op_vvcurveto;
1203 op = cff_op_hhcurveto;
1206 op = cff_op_callgsubr;
1209 op = cff_op_vhcurveto;
1212 op = cff_op_hvcurveto;
1215 FT_TRACE4(( " unknown op (%d)\n", v ));
1219 if ( op == cff_op_unknown )
1222 /* check arguments */
1223 req_args = cff_argument_counts[op];
1224 if ( req_args & CFF_COUNT_CHECK_WIDTH )
1226 if ( num_args > 0 && decoder->read_width )
1228 /* If `nominal_width' is non-zero, the number is really a */
1229 /* difference against `nominal_width'. Else, the number here */
1230 /* is truly a width, not a difference against `nominal_width'. */
1231 /* If the font does not set `nominal_width', then */
1232 /* `nominal_width' defaults to zero, and so we can set */
1233 /* `glyph_width' to `nominal_width' plus number on the stack */
1234 /* -- for either case. */
1236 FT_Int set_width_ok;
1241 case cff_op_hmoveto:
1242 case cff_op_vmoveto:
1243 set_width_ok = num_args & 2;
1248 case cff_op_hstemhm:
1249 case cff_op_vstemhm:
1250 case cff_op_rmoveto:
1251 case cff_op_hintmask:
1252 case cff_op_cntrmask:
1253 set_width_ok = num_args & 1;
1256 case cff_op_endchar:
1257 /* If there is a width specified for endchar, we either have */
1258 /* 1 argument or 5 arguments. We like to argue. */
1259 set_width_ok = ( num_args == 5 ) || ( num_args == 1 );
1269 decoder->glyph_width = decoder->nominal_width +
1272 if ( decoder->width_only )
1274 /* we only want the advance width; stop here */
1278 /* Consumed an argument. */
1283 decoder->read_width = 0;
1288 if ( num_args < req_args )
1289 goto Stack_Underflow;
1291 num_args -= req_args;
1293 /* At this point, `args' points to the first argument of the */
1294 /* operand in case `req_args' isn't zero. Otherwise, we have */
1295 /* to adjust `args' manually. */
1297 /* Note that we only pop arguments from the stack which we */
1298 /* really need and can digest so that we can continue in case */
1299 /* of superfluous stack elements. */
1305 case cff_op_hstemhm:
1306 case cff_op_vstemhm:
1307 /* the number of arguments is always even here */
1309 op == cff_op_hstem ? " hstem\n" :
1310 ( op == cff_op_vstem ? " vstem\n" :
1311 ( op == cff_op_hstemhm ? " hstemhm\n" : " vstemhm\n" ) ) ));
1314 hinter->stems( hinter->hints,
1315 ( op == cff_op_hstem || op == cff_op_hstemhm ),
1317 args - ( num_args & ~1 ) );
1319 decoder->num_hints += num_args / 2;
1323 case cff_op_hintmask:
1324 case cff_op_cntrmask:
1325 FT_TRACE4(( op == cff_op_hintmask ? " hintmask" : " cntrmask" ));
1327 /* implement vstem when needed -- */
1328 /* the specification doesn't say it, but this also works */
1329 /* with the 'cntrmask' operator */
1334 hinter->stems( hinter->hints,
1337 args - ( num_args & ~1 ) );
1339 decoder->num_hints += num_args / 2;
1342 /* In a valid charstring there must be at least one byte */
1343 /* after `hintmask' or `cntrmask' (e.g., for a `return' */
1344 /* instruction). Additionally, there must be space for */
1345 /* `num_hints' bits. */
1347 if ( ( ip + ( ( decoder->num_hints + 7 ) >> 3 ) ) >= limit )
1352 if ( op == cff_op_hintmask )
1353 hinter->hintmask( hinter->hints,
1354 builder->current->n_points,
1358 hinter->counter( hinter->hints,
1363 #ifdef FT_DEBUG_LEVEL_TRACE
1368 FT_TRACE4(( " (maskbytes:" ));
1371 maskbyte < (FT_UInt)( ( decoder->num_hints + 7 ) >> 3 );
1373 FT_TRACE4(( " 0x%02X", *ip ));
1375 FT_TRACE4(( ")\n" ));
1378 ip += ( decoder->num_hints + 7 ) >> 3;
1383 case cff_op_rmoveto:
1384 FT_TRACE4(( " rmoveto\n" ));
1386 cff_builder_close_contour( builder );
1387 builder->path_begun = 0;
1393 case cff_op_vmoveto:
1394 FT_TRACE4(( " vmoveto\n" ));
1396 cff_builder_close_contour( builder );
1397 builder->path_begun = 0;
1402 case cff_op_hmoveto:
1403 FT_TRACE4(( " hmoveto\n" ));
1405 cff_builder_close_contour( builder );
1406 builder->path_begun = 0;
1411 case cff_op_rlineto:
1412 FT_TRACE4(( " rlineto\n" ));
1414 if ( cff_builder_start_point ( builder, x, y ) ||
1415 check_points( builder, num_args / 2 ) )
1419 goto Stack_Underflow;
1421 args -= num_args & ~1;
1422 while ( args < decoder->top )
1426 cff_builder_add_point( builder, x, y, 1 );
1432 case cff_op_hlineto:
1433 case cff_op_vlineto:
1435 FT_Int phase = ( op == cff_op_hlineto );
1438 FT_TRACE4(( op == cff_op_hlineto ? " hlineto\n"
1442 goto Stack_Underflow;
1444 /* there exist subsetted fonts (found in PDFs) */
1445 /* which call `hlineto' without arguments */
1446 if ( num_args == 0 )
1449 if ( cff_builder_start_point ( builder, x, y ) ||
1450 check_points( builder, num_args ) )
1454 while ( args < decoder->top )
1461 if ( cff_builder_add_point1( builder, x, y ) )
1471 case cff_op_rrcurveto:
1476 FT_TRACE4(( " rrcurveto\n" ));
1479 goto Stack_Underflow;
1481 nargs = num_args - num_args % 6;
1483 if ( cff_builder_start_point ( builder, x, y ) ||
1484 check_points( builder, nargs / 2 ) )
1488 while ( args < decoder->top )
1492 cff_builder_add_point( builder, x, y, 0 );
1495 cff_builder_add_point( builder, x, y, 0 );
1498 cff_builder_add_point( builder, x, y, 1 );
1505 case cff_op_vvcurveto:
1510 FT_TRACE4(( " vvcurveto\n" ));
1513 goto Stack_Underflow;
1515 /* if num_args isn't of the form 4n or 4n+1, */
1516 /* we enforce it by clearing the second bit */
1518 nargs = num_args & ~2;
1520 if ( cff_builder_start_point( builder, x, y ) )
1532 if ( check_points( builder, 3 * ( nargs / 4 ) ) )
1535 while ( args < decoder->top )
1538 cff_builder_add_point( builder, x, y, 0 );
1541 cff_builder_add_point( builder, x, y, 0 );
1543 cff_builder_add_point( builder, x, y, 1 );
1550 case cff_op_hhcurveto:
1555 FT_TRACE4(( " hhcurveto\n" ));
1558 goto Stack_Underflow;
1560 /* if num_args isn't of the form 4n or 4n+1, */
1561 /* we enforce it by clearing the second bit */
1563 nargs = num_args & ~2;
1565 if ( cff_builder_start_point( builder, x, y ) )
1576 if ( check_points( builder, 3 * ( nargs / 4 ) ) )
1579 while ( args < decoder->top )
1582 cff_builder_add_point( builder, x, y, 0 );
1585 cff_builder_add_point( builder, x, y, 0 );
1587 cff_builder_add_point( builder, x, y, 1 );
1594 case cff_op_vhcurveto:
1595 case cff_op_hvcurveto:
1601 FT_TRACE4(( op == cff_op_vhcurveto ? " vhcurveto\n"
1602 : " hvcurveto\n" ));
1604 if ( cff_builder_start_point( builder, x, y ) )
1608 goto Stack_Underflow;
1610 /* if num_args isn't of the form 8n, 8n+1, 8n+4, or 8n+5, */
1611 /* we enforce it by clearing the second bit */
1613 nargs = num_args & ~2;
1616 if ( check_points( builder, ( nargs / 4 ) * 3 ) )
1617 goto Stack_Underflow;
1619 phase = ( op == cff_op_hvcurveto );
1621 while ( nargs >= 4 )
1627 cff_builder_add_point( builder, x, y, 0 );
1630 cff_builder_add_point( builder, x, y, 0 );
1634 cff_builder_add_point( builder, x, y, 1 );
1639 cff_builder_add_point( builder, x, y, 0 );
1642 cff_builder_add_point( builder, x, y, 0 );
1646 cff_builder_add_point( builder, x, y, 1 );
1655 case cff_op_rlinecurve:
1661 FT_TRACE4(( " rlinecurve\n" ));
1664 goto Stack_Underflow;
1666 nargs = num_args & ~1;
1667 num_lines = ( nargs - 6 ) / 2;
1669 if ( cff_builder_start_point( builder, x, y ) ||
1670 check_points( builder, num_lines + 3 ) )
1675 /* first, add the line segments */
1676 while ( num_lines > 0 )
1680 cff_builder_add_point( builder, x, y, 1 );
1685 /* then the curve */
1688 cff_builder_add_point( builder, x, y, 0 );
1691 cff_builder_add_point( builder, x, y, 0 );
1694 cff_builder_add_point( builder, x, y, 1 );
1699 case cff_op_rcurveline:
1705 FT_TRACE4(( " rcurveline\n" ));
1708 goto Stack_Underflow;
1710 nargs = num_args - 2;
1711 nargs = nargs - nargs % 6 + 2;
1712 num_curves = ( nargs - 2 ) / 6;
1714 if ( cff_builder_start_point ( builder, x, y ) ||
1715 check_points( builder, num_curves * 3 + 2 ) )
1720 /* first, add the curves */
1721 while ( num_curves > 0 )
1725 cff_builder_add_point( builder, x, y, 0 );
1728 cff_builder_add_point( builder, x, y, 0 );
1731 cff_builder_add_point( builder, x, y, 1 );
1736 /* then the final line */
1739 cff_builder_add_point( builder, x, y, 1 );
1749 FT_TRACE4(( " hflex1\n" ));
1751 /* adding five more points: 4 control points, 1 on-curve point */
1752 /* -- make sure we have enough space for the start point if it */
1753 /* needs to be added */
1754 if ( cff_builder_start_point( builder, x, y ) ||
1755 check_points( builder, 6 ) )
1758 /* record the starting point's y position for later use */
1761 /* first control point */
1764 cff_builder_add_point( builder, x, y, 0 );
1766 /* second control point */
1769 cff_builder_add_point( builder, x, y, 0 );
1771 /* join point; on curve, with y-value the same as the last */
1772 /* control point's y-value */
1774 cff_builder_add_point( builder, x, y, 1 );
1776 /* third control point, with y-value the same as the join */
1777 /* point's y-value */
1779 cff_builder_add_point( builder, x, y, 0 );
1781 /* fourth control point */
1784 cff_builder_add_point( builder, x, y, 0 );
1786 /* ending point, with y-value the same as the start */
1789 cff_builder_add_point( builder, x, y, 1 );
1800 FT_TRACE4(( " hflex\n" ));
1802 /* adding six more points; 4 control points, 2 on-curve points */
1803 if ( cff_builder_start_point( builder, x, y ) ||
1804 check_points( builder, 6 ) )
1807 /* record the starting point's y-position for later use */
1810 /* first control point */
1812 cff_builder_add_point( builder, x, y, 0 );
1814 /* second control point */
1817 cff_builder_add_point( builder, x, y, 0 );
1819 /* join point; on curve, with y-value the same as the last */
1820 /* control point's y-value */
1822 cff_builder_add_point( builder, x, y, 1 );
1824 /* third control point, with y-value the same as the join */
1825 /* point's y-value */
1827 cff_builder_add_point( builder, x, y, 0 );
1829 /* fourth control point */
1832 cff_builder_add_point( builder, x, y, 0 );
1834 /* ending point, with y-value the same as the start point's */
1835 /* y-value -- we don't add this point, though */
1837 cff_builder_add_point( builder, x, y, 1 );
1845 FT_Pos start_x, start_y; /* record start x, y values for */
1847 FT_Fixed dx = 0, dy = 0; /* used in horizontal/vertical */
1848 /* algorithm below */
1849 FT_Int horizontal, count;
1853 FT_TRACE4(( " flex1\n" ));
1855 /* adding six more points; 4 control points, 2 on-curve points */
1856 if ( cff_builder_start_point( builder, x, y ) ||
1857 check_points( builder, 6 ) )
1860 /* record the starting point's x, y position for later use */
1864 /* XXX: figure out whether this is supposed to be a horizontal */
1865 /* or vertical flex; the Type 2 specification is vague... */
1869 /* grab up to the last argument */
1870 for ( count = 5; count > 0; count-- )
1882 /* strange test, but here it is... */
1883 horizontal = ( dx > dy );
1885 for ( count = 5; count > 0; count-- )
1889 cff_builder_add_point( builder, x, y,
1890 (FT_Bool)( count == 3 ) );
1894 /* is last operand an x- or y-delta? */
1906 cff_builder_add_point( builder, x, y, 1 );
1917 FT_TRACE4(( " flex\n" ));
1919 if ( cff_builder_start_point( builder, x, y ) ||
1920 check_points( builder, 6 ) )
1923 for ( count = 6; count > 0; count-- )
1927 cff_builder_add_point( builder, x, y,
1928 (FT_Bool)( count == 4 || count == 1 ) );
1937 FT_TRACE4(( " seac\n" ));
1939 error = cff_operator_seac( decoder,
1940 args[0], args[1], args[2],
1941 (FT_Int)( args[3] >> 16 ),
1942 (FT_Int)( args[4] >> 16 ) );
1944 /* add current outline to the glyph slot */
1945 FT_GlyphLoader_Add( builder->loader );
1948 FT_TRACE4(( "\n" ));
1951 case cff_op_endchar:
1952 FT_TRACE4(( " endchar\n" ));
1954 /* We are going to emulate the seac operator. */
1955 if ( num_args >= 4 )
1957 /* Save glyph width so that the subglyphs don't overwrite it. */
1958 FT_Pos glyph_width = decoder->glyph_width;
1961 error = cff_operator_seac( decoder,
1962 0L, args[-4], args[-3],
1963 (FT_Int)( args[-2] >> 16 ),
1964 (FT_Int)( args[-1] >> 16 ) );
1966 decoder->glyph_width = glyph_width;
1973 cff_builder_close_contour( builder );
1975 /* close hints recording session */
1978 if ( hinter->close( hinter->hints,
1979 builder->current->n_points ) )
1982 /* apply hints to the loaded glyph outline now */
1983 hinter->apply( hinter->hints,
1985 (PSH_Globals)builder->hints_globals,
1986 decoder->hint_mode );
1989 /* add current outline to the glyph slot */
1990 FT_GlyphLoader_Add( builder->loader );
1994 FT_TRACE4(( "\n" ));
1998 FT_TRACE4(( " abs\n" ));
2006 FT_TRACE4(( " add\n" ));
2013 FT_TRACE4(( " sub\n" ));
2020 FT_TRACE4(( " div\n" ));
2022 args[0] = FT_DivFix( args[0], args[1] );
2027 FT_TRACE4(( " neg\n" ));
2038 FT_TRACE4(( " rand\n" ));
2041 if ( Rand >= 0x8000L )
2045 seed = FT_MulFix( seed, 0x10000L - seed );
2053 FT_TRACE4(( " mul\n" ));
2055 args[0] = FT_MulFix( args[0], args[1] );
2060 FT_TRACE4(( " sqrt\n" ));
2065 FT_Fixed root = args[0];
2071 new_root = ( root + FT_DivFix( args[0], root ) + 1 ) >> 1;
2072 if ( new_root == root || count <= 0 )
2085 FT_TRACE4(( " drop\n" ));
2094 FT_TRACE4(( " exch\n" ));
2105 FT_Int idx = (FT_Int)( args[0] >> 16 );
2108 FT_TRACE4(( " index\n" ));
2112 else if ( idx > num_args - 2 )
2114 args[0] = args[-( idx + 1 )];
2121 FT_Int count = (FT_Int)( args[0] >> 16 );
2122 FT_Int idx = (FT_Int)( args[1] >> 16 );
2125 FT_TRACE4(( " roll\n" ));
2132 goto Stack_Underflow;
2138 FT_Fixed tmp = args[count - 1];
2142 for ( i = count - 2; i >= 0; i-- )
2143 args[i + 1] = args[i];
2152 FT_Fixed tmp = args[0];
2156 for ( i = 0; i < count - 1; i++ )
2157 args[i] = args[i + 1];
2158 args[count - 1] = tmp;
2167 FT_TRACE4(( " dup\n" ));
2175 FT_Fixed val = args[0];
2176 FT_Int idx = (FT_Int)( args[1] >> 16 );
2179 FT_TRACE4(( " put\n" ));
2181 if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS )
2182 decoder->buildchar[idx] = val;
2188 FT_Int idx = (FT_Int)( args[0] >> 16 );
2192 FT_TRACE4(( " get\n" ));
2194 if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS )
2195 val = decoder->buildchar[idx];
2203 FT_TRACE4(( " store\n"));
2208 FT_TRACE4(( " load\n" ));
2212 case cff_op_dotsection:
2213 /* this operator is deprecated and ignored by the parser */
2214 FT_TRACE4(( " dotsection\n" ));
2217 case cff_op_closepath:
2218 /* this is an invalid Type 2 operator; however, there */
2219 /* exist fonts which are incorrectly converted from probably */
2220 /* Type 1 to CFF, and some parsers seem to accept it */
2222 FT_TRACE4(( " closepath (invalid op)\n" ));
2228 /* this is an invalid Type 2 operator; however, there */
2229 /* exist fonts which are incorrectly converted from probably */
2230 /* Type 1 to CFF, and some parsers seem to accept it */
2232 FT_TRACE4(( " hsbw (invalid op)\n" ));
2234 decoder->glyph_width = decoder->nominal_width + ( args[1] >> 16 );
2236 decoder->builder.left_bearing.x = args[0];
2237 decoder->builder.left_bearing.y = 0;
2239 x = decoder->builder.pos_x + args[0];
2240 y = decoder->builder.pos_y;
2245 /* this is an invalid Type 2 operator; however, there */
2246 /* exist fonts which are incorrectly converted from probably */
2247 /* Type 1 to CFF, and some parsers seem to accept it */
2249 FT_TRACE4(( " sbw (invalid op)\n" ));
2251 decoder->glyph_width = decoder->nominal_width + ( args[2] >> 16 );
2253 decoder->builder.left_bearing.x = args[0];
2254 decoder->builder.left_bearing.y = args[1];
2256 x = decoder->builder.pos_x + args[0];
2257 y = decoder->builder.pos_y + args[1];
2261 case cff_op_setcurrentpoint:
2262 /* this is an invalid Type 2 operator; however, there */
2263 /* exist fonts which are incorrectly converted from probably */
2264 /* Type 1 to CFF, and some parsers seem to accept it */
2266 FT_TRACE4(( " setcurrentpoint (invalid op)\n" ));
2268 x = decoder->builder.pos_x + args[0];
2269 y = decoder->builder.pos_y + args[1];
2273 case cff_op_callothersubr:
2274 /* this is an invalid Type 2 operator; however, there */
2275 /* exist fonts which are incorrectly converted from probably */
2276 /* Type 1 to CFF, and some parsers seem to accept it */
2278 FT_TRACE4(( " callothersubr (invalid op)\n" ));
2280 /* subsequent `pop' operands should add the arguments, */
2281 /* this is the implementation described for `unknown' other */
2282 /* subroutines in the Type1 spec. */
2284 /* XXX Fix return arguments (see discussion below). */
2285 args -= 2 + ( args[-2] >> 16 );
2287 goto Stack_Underflow;
2291 /* this is an invalid Type 2 operator; however, there */
2292 /* exist fonts which are incorrectly converted from probably */
2293 /* Type 1 to CFF, and some parsers seem to accept it */
2295 FT_TRACE4(( " pop (invalid op)\n" ));
2297 /* XXX Increasing `args' is wrong: After a certain number of */
2298 /* `pop's we get a stack overflow. Reason for doing it is */
2299 /* code like this (actually found in a CFF font): */
2301 /* 17 1 3 callothersubr */
2305 /* Since we handle `callothersubr' as a no-op, and */
2306 /* `callsubr' needs at least one argument, `pop' can't be a */
2307 /* no-op too as it basically should be. */
2309 /* The right solution would be to provide real support for */
2310 /* `callothersubr' as done in `t1decode.c', however, given */
2311 /* the fact that CFF fonts with `pop' are invalid, it is */
2312 /* questionable whether it is worth the time. */
2318 FT_Fixed cond = args[0] && args[1];
2321 FT_TRACE4(( " and\n" ));
2323 args[0] = cond ? 0x10000L : 0;
2330 FT_Fixed cond = args[0] || args[1];
2333 FT_TRACE4(( " or\n" ));
2335 args[0] = cond ? 0x10000L : 0;
2342 FT_Fixed cond = !args[0];
2345 FT_TRACE4(( " eq\n" ));
2347 args[0] = cond ? 0x10000L : 0;
2354 FT_Fixed cond = ( args[2] <= args[3] );
2357 FT_TRACE4(( " ifelse\n" ));
2365 case cff_op_callsubr:
2367 FT_UInt idx = (FT_UInt)( ( args[0] >> 16 ) +
2368 decoder->locals_bias );
2371 FT_TRACE4(( " callsubr(%d)\n", idx ));
2373 if ( idx >= decoder->num_locals )
2375 FT_ERROR(( "cff_decoder_parse_charstrings:"
2376 " invalid local subr index\n" ));
2380 if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS )
2382 FT_ERROR(( "cff_decoder_parse_charstrings:"
2383 " too many nested subrs\n" ));
2387 zone->cursor = ip; /* save current instruction pointer */
2390 zone->base = decoder->locals[idx];
2391 zone->limit = decoder->locals[idx + 1];
2392 zone->cursor = zone->base;
2394 if ( !zone->base || zone->limit == zone->base )
2396 FT_ERROR(( "cff_decoder_parse_charstrings:"
2397 " invoking empty subrs\n" ));
2401 decoder->zone = zone;
2403 limit = zone->limit;
2407 case cff_op_callgsubr:
2409 FT_UInt idx = (FT_UInt)( ( args[0] >> 16 ) +
2410 decoder->globals_bias );
2413 FT_TRACE4(( " callgsubr(%d)\n", idx ));
2415 if ( idx >= decoder->num_globals )
2417 FT_ERROR(( "cff_decoder_parse_charstrings:"
2418 " invalid global subr index\n" ));
2422 if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS )
2424 FT_ERROR(( "cff_decoder_parse_charstrings:"
2425 " too many nested subrs\n" ));
2429 zone->cursor = ip; /* save current instruction pointer */
2432 zone->base = decoder->globals[idx];
2433 zone->limit = decoder->globals[idx + 1];
2434 zone->cursor = zone->base;
2436 if ( !zone->base || zone->limit == zone->base )
2438 FT_ERROR(( "cff_decoder_parse_charstrings:"
2439 " invoking empty subrs\n" ));
2443 decoder->zone = zone;
2445 limit = zone->limit;
2450 FT_TRACE4(( " return\n" ));
2452 if ( decoder->zone <= decoder->zones )
2454 FT_ERROR(( "cff_decoder_parse_charstrings:"
2455 " unexpected return\n" ));
2460 zone = decoder->zone;
2462 limit = zone->limit;
2467 FT_ERROR(( "Unimplemented opcode: %d", ip[-1] ));
2470 FT_ERROR(( " %d", ip[0] ));
2473 return CFF_Err_Unimplemented_Feature;
2476 decoder->top = args;
2478 if ( decoder->top - stack >= CFF_MAX_OPERANDS )
2479 goto Stack_Overflow;
2481 } /* general operator processing */
2483 } /* while ip < limit */
2485 FT_TRACE4(( "..end..\n\n" ));
2491 FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" ));
2492 return CFF_Err_Invalid_File_Format;
2495 FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" ));
2496 return CFF_Err_Too_Few_Arguments;
2499 FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" ));
2500 return CFF_Err_Stack_Overflow;
2504 /*************************************************************************/
2505 /*************************************************************************/
2506 /*************************************************************************/
2507 /********** *********/
2508 /********** *********/
2509 /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/
2510 /********** *********/
2511 /********** The following code is in charge of computing *********/
2512 /********** the maximum advance width of the font. It *********/
2513 /********** quickly processes each glyph charstring to *********/
2514 /********** extract the value from either a `sbw' or `seac' *********/
2515 /********** operator. *********/
2516 /********** *********/
2517 /*************************************************************************/
2518 /*************************************************************************/
2519 /*************************************************************************/
2522 #if 0 /* unused until we support pure CFF fonts */
2525 FT_LOCAL_DEF( FT_Error )
2526 cff_compute_max_advance( TT_Face face,
2527 FT_Int* max_advance )
2529 FT_Error error = CFF_Err_Ok;
2530 CFF_Decoder decoder;
2532 CFF_Font cff = (CFF_Font)face->other;
2537 /* Initialize load decoder */
2538 cff_decoder_init( &decoder, face, 0, 0, 0, 0 );
2540 decoder.builder.metrics_only = 1;
2541 decoder.builder.load_points = 0;
2543 /* For each glyph, parse the glyph charstring and extract */
2544 /* the advance width. */
2545 for ( glyph_index = 0; glyph_index < face->root.num_glyphs;
2548 FT_Byte* charstring;
2549 FT_ULong charstring_len;
2552 /* now get load the unscaled outline */
2553 error = cff_get_glyph_data( face, glyph_index,
2554 &charstring, &charstring_len );
2557 error = cff_decoder_prepare( &decoder, size, glyph_index );
2559 error = cff_decoder_parse_charstrings( &decoder,
2563 cff_free_glyph_data( face, &charstring, &charstring_len );
2566 /* ignore the error if one has occurred -- skip to next glyph */
2570 *max_advance = decoder.builder.advance.x;
2579 FT_LOCAL_DEF( FT_Error )
2580 cff_slot_load( CFF_GlyphSlot glyph,
2582 FT_UInt glyph_index,
2583 FT_Int32 load_flags )
2586 CFF_Decoder decoder;
2587 TT_Face face = (TT_Face)glyph->root.face;
2588 FT_Bool hinting, force_scaling;
2589 CFF_Font cff = (CFF_Font)face->extra.data;
2591 FT_Matrix font_matrix;
2592 FT_Vector font_offset;
2595 force_scaling = FALSE;
2597 /* in a CID-keyed font, consider `glyph_index' as a CID and map */
2598 /* it immediately to the real glyph_index -- if it isn't a */
2599 /* subsetted font, glyph_indices and CIDs are identical, though */
2600 if ( cff->top_font.font_dict.cid_registry != 0xFFFFU &&
2603 /* don't handle CID 0 (.notdef) which is directly mapped to GID 0 */
2604 if ( glyph_index != 0 )
2606 glyph_index = cff_charset_cid_to_gindex( &cff->charset,
2608 if ( glyph_index == 0 )
2609 return CFF_Err_Invalid_Argument;
2612 else if ( glyph_index >= cff->num_glyphs )
2613 return CFF_Err_Invalid_Argument;
2615 if ( load_flags & FT_LOAD_NO_RECURSE )
2616 load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
2618 glyph->x_scale = 0x10000L;
2619 glyph->y_scale = 0x10000L;
2622 glyph->x_scale = size->root.metrics.x_scale;
2623 glyph->y_scale = size->root.metrics.y_scale;
2626 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
2628 /* try to load embedded bitmap if any */
2630 /* XXX: The convention should be emphasized in */
2631 /* the documents because it can be confusing. */
2634 CFF_Face cff_face = (CFF_Face)size->root.face;
2635 SFNT_Service sfnt = (SFNT_Service)cff_face->sfnt;
2636 FT_Stream stream = cff_face->root.stream;
2639 if ( size->strike_index != 0xFFFFFFFFUL &&
2641 ( load_flags & FT_LOAD_NO_BITMAP ) == 0 )
2643 TT_SBit_MetricsRec metrics;
2646 error = sfnt->load_sbit_image( face,
2651 &glyph->root.bitmap,
2656 glyph->root.outline.n_points = 0;
2657 glyph->root.outline.n_contours = 0;
2659 glyph->root.metrics.width = (FT_Pos)metrics.width << 6;
2660 glyph->root.metrics.height = (FT_Pos)metrics.height << 6;
2662 glyph->root.metrics.horiBearingX = (FT_Pos)metrics.horiBearingX << 6;
2663 glyph->root.metrics.horiBearingY = (FT_Pos)metrics.horiBearingY << 6;
2664 glyph->root.metrics.horiAdvance = (FT_Pos)metrics.horiAdvance << 6;
2666 glyph->root.metrics.vertBearingX = (FT_Pos)metrics.vertBearingX << 6;
2667 glyph->root.metrics.vertBearingY = (FT_Pos)metrics.vertBearingY << 6;
2668 glyph->root.metrics.vertAdvance = (FT_Pos)metrics.vertAdvance << 6;
2670 glyph->root.format = FT_GLYPH_FORMAT_BITMAP;
2672 if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
2674 glyph->root.bitmap_left = metrics.vertBearingX;
2675 glyph->root.bitmap_top = metrics.vertBearingY;
2679 glyph->root.bitmap_left = metrics.horiBearingX;
2680 glyph->root.bitmap_top = metrics.horiBearingY;
2687 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
2689 /* return immediately if we only want the embedded bitmaps */
2690 if ( load_flags & FT_LOAD_SBITS_ONLY )
2691 return CFF_Err_Invalid_Argument;
2693 /* if we have a CID subfont, use its matrix (which has already */
2694 /* been multiplied with the root matrix) */
2696 /* this scaling is only relevant if the PS hinter isn't active */
2697 if ( cff->num_subfonts )
2699 FT_ULong top_upm, sub_upm;
2700 FT_Byte fd_index = cff_fd_select_get( &cff->fd_select,
2703 if ( fd_index >= cff->num_subfonts )
2704 fd_index = (FT_Byte)( cff->num_subfonts - 1 );
2706 top_upm = cff->top_font.font_dict.units_per_em;
2707 sub_upm = cff->subfonts[fd_index]->font_dict.units_per_em;
2710 font_matrix = cff->subfonts[fd_index]->font_dict.font_matrix;
2711 font_offset = cff->subfonts[fd_index]->font_dict.font_offset;
2713 if ( top_upm != sub_upm )
2715 glyph->x_scale = FT_MulDiv( glyph->x_scale, top_upm, sub_upm );
2716 glyph->y_scale = FT_MulDiv( glyph->y_scale, top_upm, sub_upm );
2718 force_scaling = TRUE;
2723 font_matrix = cff->top_font.font_dict.font_matrix;
2724 font_offset = cff->top_font.font_dict.font_offset;
2727 glyph->root.outline.n_points = 0;
2728 glyph->root.outline.n_contours = 0;
2730 hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 &&
2731 ( load_flags & FT_LOAD_NO_HINTING ) == 0 );
2733 glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; /* by default */
2736 FT_Byte* charstring;
2737 FT_ULong charstring_len;
2740 cff_decoder_init( &decoder, face, size, glyph, hinting,
2741 FT_LOAD_TARGET_MODE( load_flags ) );
2743 if ( load_flags & FT_LOAD_ADVANCE_ONLY )
2744 decoder.width_only = TRUE;
2746 decoder.builder.no_recurse =
2747 (FT_Bool)( load_flags & FT_LOAD_NO_RECURSE );
2749 /* now load the unscaled outline */
2750 error = cff_get_glyph_data( face, glyph_index,
2751 &charstring, &charstring_len );
2753 goto Glyph_Build_Finished;
2755 error = cff_decoder_prepare( &decoder, size, glyph_index );
2757 goto Glyph_Build_Finished;
2759 error = cff_decoder_parse_charstrings( &decoder,
2763 cff_free_glyph_data( face, &charstring, charstring_len );
2766 goto Glyph_Build_Finished;
2768 #ifdef FT_CONFIG_OPTION_INCREMENTAL
2769 /* Control data and length may not be available for incremental */
2771 if ( face->root.internal->incremental_interface )
2773 glyph->root.control_data = 0;
2774 glyph->root.control_len = 0;
2777 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
2779 /* We set control_data and control_len if charstrings is loaded. */
2780 /* See how charstring loads at cff_index_access_element() in */
2783 CFF_Index csindex = &cff->charstrings_index;
2786 if ( csindex->offsets )
2788 glyph->root.control_data = csindex->bytes +
2789 csindex->offsets[glyph_index] - 1;
2790 glyph->root.control_len = charstring_len;
2794 Glyph_Build_Finished:
2795 /* save new glyph tables, if no error */
2797 cff_builder_done( &decoder.builder );
2798 /* XXX: anything to do for broken glyph entry? */
2801 #ifdef FT_CONFIG_OPTION_INCREMENTAL
2803 /* Incremental fonts can optionally override the metrics. */
2805 face->root.internal->incremental_interface &&
2806 face->root.internal->incremental_interface->funcs->get_glyph_metrics )
2808 FT_Incremental_MetricsRec metrics;
2811 metrics.bearing_x = decoder.builder.left_bearing.x;
2812 metrics.bearing_y = 0;
2813 metrics.advance = decoder.builder.advance.x;
2814 metrics.advance_v = decoder.builder.advance.y;
2816 error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
2817 face->root.internal->incremental_interface->object,
2818 glyph_index, FALSE, &metrics );
2820 decoder.builder.left_bearing.x = metrics.bearing_x;
2821 decoder.builder.advance.x = metrics.advance;
2822 decoder.builder.advance.y = metrics.advance_v;
2825 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
2829 /* Now, set the metrics -- this is rather simple, as */
2830 /* the left side bearing is the xMin, and the top side */
2831 /* bearing the yMax. */
2833 /* For composite glyphs, return only left side bearing and */
2834 /* advance width. */
2835 if ( load_flags & FT_LOAD_NO_RECURSE )
2837 FT_Slot_Internal internal = glyph->root.internal;
2840 glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x;
2841 glyph->root.metrics.horiAdvance = decoder.glyph_width;
2842 internal->glyph_matrix = font_matrix;
2843 internal->glyph_delta = font_offset;
2844 internal->glyph_transformed = 1;
2849 FT_Glyph_Metrics* metrics = &glyph->root.metrics;
2851 FT_Bool has_vertical_info;
2854 /* copy the _unscaled_ advance width */
2855 metrics->horiAdvance = decoder.glyph_width;
2856 glyph->root.linearHoriAdvance = decoder.glyph_width;
2857 glyph->root.internal->glyph_transformed = 0;
2859 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
2860 has_vertical_info = FT_BOOL( face->vertical_info &&
2861 face->vertical.number_Of_VMetrics > 0 &&
2862 face->vertical.long_metrics );
2864 has_vertical_info = FT_BOOL( face->vertical_info &&
2865 face->vertical.number_Of_VMetrics > 0 );
2868 /* get the vertical metrics from the vtmx table if we have one */
2869 if ( has_vertical_info )
2871 FT_Short vertBearingY = 0;
2872 FT_UShort vertAdvance = 0;
2875 ( (SFNT_Service)face->sfnt )->get_metrics( face, 1,
2879 metrics->vertBearingY = vertBearingY;
2880 metrics->vertAdvance = vertAdvance;
2884 /* make up vertical ones */
2885 if ( face->os2.version != 0xFFFFU )
2886 metrics->vertAdvance = (FT_Pos)( face->os2.sTypoAscender -
2887 face->os2.sTypoDescender );
2889 metrics->vertAdvance = (FT_Pos)( face->horizontal.Ascender -
2890 face->horizontal.Descender );
2893 glyph->root.linearVertAdvance = metrics->vertAdvance;
2895 glyph->root.format = FT_GLYPH_FORMAT_OUTLINE;
2897 glyph->root.outline.flags = 0;
2898 if ( size && size->root.metrics.y_ppem < 24 )
2899 glyph->root.outline.flags |= FT_OUTLINE_HIGH_PRECISION;
2901 glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL;
2903 if ( !( font_matrix.xx == 0x10000L &&
2904 font_matrix.yy == 0x10000L &&
2905 font_matrix.xy == 0 &&
2906 font_matrix.yx == 0 ) )
2907 FT_Outline_Transform( &glyph->root.outline, &font_matrix );
2909 if ( !( font_offset.x == 0 &&
2910 font_offset.y == 0 ) )
2911 FT_Outline_Translate( &glyph->root.outline,
2912 font_offset.x, font_offset.y );
2914 advance.x = metrics->horiAdvance;
2916 FT_Vector_Transform( &advance, &font_matrix );
2917 metrics->horiAdvance = advance.x + font_offset.x;
2920 advance.y = metrics->vertAdvance;
2921 FT_Vector_Transform( &advance, &font_matrix );
2922 metrics->vertAdvance = advance.y + font_offset.y;
2924 if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 || force_scaling )
2926 /* scale the outline and the metrics */
2928 FT_Outline* cur = &glyph->root.outline;
2929 FT_Vector* vec = cur->points;
2930 FT_Fixed x_scale = glyph->x_scale;
2931 FT_Fixed y_scale = glyph->y_scale;
2934 /* First of all, scale the points */
2935 if ( !hinting || !decoder.builder.hints_funcs )
2936 for ( n = cur->n_points; n > 0; n--, vec++ )
2938 vec->x = FT_MulFix( vec->x, x_scale );
2939 vec->y = FT_MulFix( vec->y, y_scale );
2942 /* Then scale the metrics */
2943 metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
2944 metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );
2947 /* compute the other metrics */
2948 FT_Outline_Get_CBox( &glyph->root.outline, &cbox );
2950 metrics->width = cbox.xMax - cbox.xMin;
2951 metrics->height = cbox.yMax - cbox.yMin;
2953 metrics->horiBearingX = cbox.xMin;
2954 metrics->horiBearingY = cbox.yMax;
2956 if ( has_vertical_info )
2957 metrics->vertBearingX = metrics->horiBearingX -
2958 metrics->horiAdvance / 2;
2961 if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
2962 ft_synthesize_vertical_metrics( metrics,
2963 metrics->vertAdvance );