63#define FT_COMPONENT cf2interp
67 cf2_hintmask_init( CF2_HintMask hintmask,
72 hintmask->error = error;
76 FT_LOCAL_DEF( FT_Bool )
77 cf2_hintmask_isValid(
const CF2_HintMask hintmask )
79 return hintmask->isValid;
83 FT_LOCAL_DEF( FT_Bool )
84 cf2_hintmask_isNew(
const CF2_HintMask hintmask )
86 return hintmask->isNew;
91 cf2_hintmask_setNew( CF2_HintMask hintmask,
94 hintmask->isNew = val;
101 FT_LOCAL_DEF( FT_Byte* )
102 cf2_hintmask_getMaskPtr( CF2_HintMask hintmask )
104 return hintmask->mask;
109 cf2_hintmask_setCounts( CF2_HintMask hintmask,
112 if ( bitCount > CF2_MAX_HINTS )
115 CF2_SET_ERROR( hintmask->error, Invalid_Glyph_Format );
119 hintmask->bitCount = bitCount;
120 hintmask->byteCount = ( hintmask->bitCount + 7 ) / 8;
122 hintmask->isValid = TRUE;
123 hintmask->isNew = TRUE;
132 cf2_hintmask_read( CF2_HintMask hintmask,
133 CF2_Buffer charstring,
142 CF2_UInt mask = ( 1 << ( -(CF2_Int)bitCount & 7 ) ) - 1;
147 if ( cf2_hintmask_setCounts( hintmask, bitCount ) == 0 )
150 FT_ASSERT( hintmask->byteCount > 0 );
152 FT_TRACE4((
" (maskbytes:" ));
155 for ( i = 0; i < hintmask->byteCount; i++ )
157 hintmask->mask[i] = (FT_Byte)cf2_buf_readByte( charstring );
158 FT_TRACE4((
" 0x%02X", hintmask->mask[i] ));
161 FT_TRACE4((
")\n" ));
167 FT_ASSERT( ( hintmask->mask[hintmask->byteCount - 1] & mask ) == 0 ||
174 cf2_hintmask_setAll( CF2_HintMask hintmask,
178 CF2_UInt mask = ( 1 << ( -(CF2_Int)bitCount & 7 ) ) - 1;
182 if ( cf2_hintmask_setCounts( hintmask, bitCount ) == 0 )
185 FT_ASSERT( hintmask->byteCount > 0 );
186 FT_ASSERT( hintmask->byteCount <=
187 sizeof ( hintmask->mask ) / sizeof ( hintmask->mask[0] ) );
190 for ( i = 0; i < hintmask->byteCount; i++ )
191 hintmask->mask[i] = 0xFF;
195 hintmask->mask[hintmask->byteCount - 1] &= ~mask;
254 cf2_escCALLOTHERSUBR,
282 cf2_doStems(
const CF2_Font font,
284 CF2_ArrStack stemHintArray,
287 CF2_Fixed hintOffset )
290 CF2_UInt count = cf2_stack_count( opStack );
291 FT_Bool hasWidthArg = FT_BOOL( count & 1 );
294 CF2_Fixed position = hintOffset;
296 if ( font->isT1 && !font->decoder->flex_state && !*haveWidth )
297 FT_ERROR((
"cf2_doStems (Type 1 mode):"
298 " No width. Use hsbw/sbw as first op\n" ));
300 if ( !font->isT1 && hasWidthArg && !*haveWidth )
301 *width = ADD_INT32( cf2_stack_getReal( opStack, 0 ),
302 cf2_getNominalWidthX( font->decoder ) );
304 if ( font->decoder->width_only )
307 for ( i = hasWidthArg ? 1 : 0; i < count; i += 2 )
310 CF2_StemHintRec stemhint;
314 position = ADD_INT32( position,
315 cf2_stack_getReal( opStack, i ) );
317 position = ADD_INT32( position,
318 cf2_stack_getReal( opStack, i + 1 ) );
320 stemhint.used = FALSE;
324 cf2_arrstack_push( stemHintArray, &stemhint );
327 cf2_stack_clear( opStack );
336 cf2_doFlex( CF2_Stack opStack,
339 CF2_GlyphPath glyphPath,
340 const FT_Bool* readFromStack,
341 FT_Bool doConditionalLastRead )
352 isHFlex = FT_BOOL( readFromStack[9] == FALSE );
353 top = isHFlex ? 9 : 10;
355 for ( i = 0; i < top; i++ )
357 vals[i + 2] = vals[i];
358 if ( readFromStack[i] )
359 vals[i + 2] = ADD_INT32( vals[i + 2], cf2_stack_getReal( opStack,
366 if ( doConditionalLastRead )
368 FT_Bool lastIsX = FT_BOOL(
369 cf2_fixedAbs( SUB_INT32( vals[10], *curX ) ) >
370 cf2_fixedAbs( SUB_INT32( vals[11], *curY ) ) );
371 CF2_Fixed lastVal = cf2_stack_getReal( opStack, idx );
376 vals[12] = ADD_INT32( vals[10], lastVal );
382 vals[13] = ADD_INT32( vals[11], lastVal );
387 if ( readFromStack[10] )
388 vals[12] = ADD_INT32( vals[10],
389 cf2_stack_getReal( opStack, idx++ ) );
393 if ( readFromStack[11] )
394 vals[13] = ADD_INT32( vals[11],
395 cf2_stack_getReal( opStack, idx ) );
400 for ( j = 0; j < 2; j++ )
401 cf2_glyphpath_curveTo( glyphPath, vals[j * 6 + 2],
408 cf2_stack_clear( opStack );
419 cf2_doBlend(
const CFF_Blend blend,
426 CF2_UInt numOperands = (CF2_UInt)( numBlends * blend->lenBV );
429 base = cf2_stack_count( opStack ) - numOperands;
430 delta = base + numBlends;
434 for ( i = 0; i < numBlends; i++ )
436 const CF2_Fixed* weight = &blend->BV[1];
439 CF2_Fixed sum = cf2_stack_getReal( opStack, i + base );
442 for ( j = 1; j < blend->lenBV; j++ )
443 sum = ADD_INT32( sum,
444 FT_MulFix( *weight++,
445 cf2_stack_getReal( opStack,
448 FT_TRACE6((
"%f ", (
double)sum / 65536 ));
451 cf2_stack_setReal( opStack, i + base, sum );
454 FT_TRACE6((
"blended)\n" ));
457 cf2_stack_pop( opStack, numOperands - numBlends );
478 cf2_interpT2CharString( CF2_Font font,
479 const CF2_Buffer buf,
480 CF2_OutlineCallbacks callbacks,
481 const FT_Vector* translation,
488 FT_Error lastError = FT_Err_Ok;
491 PS_Decoder* decoder = font->decoder;
493 FT_Error* error = &font->error;
494 FT_Memory memory = font->memory;
496 CF2_Fixed scaleY = font->innerTransform.d;
497 CF2_Fixed nominalWidthX = cf2_getNominalWidthX( decoder );
500 FT_Int known_othersubr_result_cnt = 0;
501 FT_Bool large_int = FALSE;
502 FT_Bool initial_map_ready = FALSE;
504#define PS_STORAGE_SIZE 3
505 CF2_F16Dot16 results[PS_STORAGE_SIZE];
506 FT_Int result_cnt = 0;
509 CF2_Fixed hintOriginY = curY;
511 CF2_Stack opStack = NULL;
515 CF2_F16Dot16 storage[CF2_STORAGE_SIZE];
516 CF2_F16Dot16 flexStore[6];
519 FT_UInt32 instructionLimit = 20000000UL;
521 CF2_ArrStackRec subrStack;
524 CF2_Buffer charstring = NULL;
526 CF2_Int charstringIndex = -1;
531 CF2_ArrStackRec hStemHintArray;
532 CF2_ArrStackRec vStemHintArray;
534 CF2_HintMaskRec hintMask;
535 CF2_GlyphPathRec glyphPath;
540 FT_ZERO( &flexStore );
543 cf2_arrstack_init( &subrStack,
546 sizeof ( CF2_BufferRec ) );
547 cf2_arrstack_init( &hStemHintArray,
550 sizeof ( CF2_StemHintRec ) );
551 cf2_arrstack_init( &vStemHintArray,
554 sizeof ( CF2_StemHintRec ) );
557 cf2_hintmask_init( &hintMask, error );
564 cf2_glyphpath_init( &glyphPath,
594 haveWidth = font->isCFF2 ? TRUE : FALSE;
595 *width = cf2_getDefaultWidthX( decoder );
605 stackSize = font->isCFF2 ? cf2_getMaxstack( decoder )
606 : CF2_OPERAND_STACK_SIZE;
607 opStack = cf2_stack_init( memory, error, stackSize );
611 lastError = FT_THROW( Out_Of_Memory );
619 cf2_arrstack_setCount( &subrStack, CF2_MAX_SUBR + 1 );
621 charstring = (CF2_Buffer)cf2_arrstack_getBuffer( &subrStack );
634 FT_ASSERT( known_othersubr_result_cnt == 0 ||
637 if ( cf2_buf_isEnd( charstring ) )
642 if ( charstringIndex )
645 op1 = cf2_cmdENDCHAR;
649 op1 = (FT_Byte)cf2_buf_readByte( charstring );
653 if ( ( op1 == cf2_cmdRETURN || op1 == cf2_cmdENDCHAR ) &&
655 op1 = cf2_cmdRESERVED_0;
660 if ( !initial_map_ready &&
661 !( op1 == cf2_cmdHSTEM ||
662 op1 == cf2_cmdVSTEM ||
663 op1 == cf2_cmdHSBW ||
664 op1 == cf2_cmdCALLSUBR ||
665 op1 == cf2_cmdRETURN ||
667 op1 == cf2_cmdENDCHAR ||
673 FT_TRACE4((
" <outline command skipped>\n" ));
674 cf2_stack_clear( opStack );
678 if ( result_cnt > 0 &&
679 !( op1 == cf2_cmdCALLSUBR ||
680 op1 == cf2_cmdRETURN ||
688 if ( large_int && !( op1 >= 32 || op1 == cf2_escDIV ) )
690 FT_ERROR((
"cf2_interpT2CharString (Type 1 mode):"
691 " no `div' after large integer\n" ));
702 if ( instructionLimit == 0 )
704 lastError = FT_THROW( Invalid_Glyph_Format );
710 case cf2_cmdRESERVED_0:
711 case cf2_cmdRESERVED_2:
712 case cf2_cmdRESERVED_17:
714 FT_TRACE4((
" unknown op (%d)\n", op1 ));
718 FT_TRACE4((
" vsindex\n" ));
723 if ( font->blend.usedBV )
726 lastError = FT_THROW( Invalid_Glyph_Format );
731 FT_Int temp = cf2_stack_popInt( opStack );
735 font->vsindex = (FT_UInt)temp;
744 FT_TRACE4((
" blend" ));
750 if ( !font->blend.font )
752 lastError = FT_THROW( Invalid_Glyph_Format );
757 if ( font->cffload->blend_check_vector( &font->blend,
762 lastError = font->cffload->blend_build_vector( &font->blend,
771 numBlends = (FT_UInt)cf2_stack_popInt( opStack );
772 if ( numBlends > stackSize )
774 lastError = FT_THROW( Invalid_Glyph_Format );
778 cf2_doBlend( &font->blend, opStack, numBlends );
780 font->blend.usedBV = TRUE;
786 FT_TRACE4((
"%s\n", op1 == cf2_cmdHSTEMHM ?
" hstemhm"
793 if ( cf2_hintmask_isValid( &hintMask ) )
795 FT_TRACE4((
"cf2_interpT2CharString:"
796 " invalid horizontal hint mask\n" ));
807 font->isT1 ? decoder->builder.left_bearing->y
810 if ( decoder->width_only )
817 FT_TRACE4((
"%s\n", op1 == cf2_cmdVSTEMHM ?
" vstemhm"
824 if ( cf2_hintmask_isValid( &hintMask ) )
826 FT_TRACE4((
"cf2_interpT2CharString:"
827 " invalid vertical hint mask\n" ));
838 font->isT1 ? decoder->builder.left_bearing->x
841 if ( decoder->width_only )
847 FT_TRACE4((
" vmoveto\n" ));
849 if ( font->isT1 && !decoder->flex_state && !haveWidth )
850 FT_ERROR((
"cf2_interpT2CharString (Type 1 mode):"
851 " No width. Use hsbw/sbw as first op\n" ));
853 if ( cf2_stack_count( opStack ) > 1 && !haveWidth )
854 *width = ADD_INT32( cf2_stack_getReal( opStack, 0 ),
860 if ( decoder->width_only )
863 curY = ADD_INT32( curY, cf2_stack_popFixed( opStack ) );
865 if ( !decoder->flex_state )
866 cf2_glyphpath_moveTo( &glyphPath, curX, curY );
873 CF2_UInt count = cf2_stack_count( opStack );
876 FT_TRACE4((
" rlineto\n" ));
878 for ( idx = 0; idx < count; idx += 2 )
880 curX = ADD_INT32( curX, cf2_stack_getReal( opStack,
882 curY = ADD_INT32( curY, cf2_stack_getReal( opStack,
885 cf2_glyphpath_lineTo( &glyphPath, curX, curY );
888 cf2_stack_clear( opStack );
896 CF2_UInt count = cf2_stack_count( opStack );
898 FT_Bool isX = FT_BOOL( op1 == cf2_cmdHLINETO );
901 FT_TRACE4((
"%s\n", isX ?
" hlineto" :
" vlineto" ));
903 for ( idx = 0; idx < count; idx++ )
905 CF2_Fixed v = cf2_stack_getReal( opStack, idx );
909 curX = ADD_INT32( curX, v );
911 curY = ADD_INT32( curY, v );
915 cf2_glyphpath_lineTo( &glyphPath, curX, curY );
918 cf2_stack_clear( opStack );
922 case cf2_cmdRCURVELINE:
923 case cf2_cmdRRCURVETO:
925 CF2_UInt count = cf2_stack_count( opStack );
929 FT_TRACE4((
"%s\n", op1 == cf2_cmdRCURVELINE ?
" rcurveline"
932 while ( idx + 6 <= count )
934 CF2_Fixed x1, y1, x2, y2, x3, y3;
937 x1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ), curX );
938 y1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ), curY );
939 x2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ), x1 );
940 y2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ), y1 );
941 x3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 4 ), x2 );
942 y3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 5 ), y2 );
944 cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 );
951 if ( op1 == cf2_cmdRCURVELINE )
953 curX = ADD_INT32( curX, cf2_stack_getReal( opStack,
955 curY = ADD_INT32( curY, cf2_stack_getReal( opStack,
958 cf2_glyphpath_lineTo( &glyphPath, curX, curY );
961 cf2_stack_clear( opStack );
965 case cf2_cmdCLOSEPATH:
967 FT_TRACE4((
" unknown op (%d)\n", op1 ));
970 FT_TRACE4((
" closepath\n" ));
973 cf2_glyphpath_closeOpenPath( &glyphPath );
979 case cf2_cmdCALLGSUBR:
980 case cf2_cmdCALLSUBR:
985 FT_TRACE4((
"%s", op1 == cf2_cmdCALLGSUBR ?
" callgsubr"
988 if ( ( !font->isT1 && charstringIndex > CF2_MAX_SUBR ) ||
989 ( font->isT1 && charstringIndex > T1_MAX_SUBRS_CALLS ) )
992 lastError = FT_THROW( Invalid_Glyph_Format );
997 charstring = (CF2_Buffer)
998 cf2_arrstack_getPointer(
1000 (
size_t)charstringIndex + 1 );
1003 subrNum = cf2_stack_popInt( opStack );
1005 if ( font->isT1 && decoder->locals_hash )
1007 size_t* val = ft_hash_num_lookup( subrNum,
1008 decoder->locals_hash );
1019 case cf2_cmdCALLGSUBR:
1020 FT_TRACE4((
" (idx %d, entering level %d)\n",
1021 subrNum + decoder->globals_bias,
1022 charstringIndex + 1 ));
1024 if ( cf2_initGlobalRegionBuffer( decoder,
1028 lastError = FT_THROW( Invalid_Glyph_Format );
1035 FT_TRACE4((
" (idx %d, entering level %d)\n",
1036 subrNum + decoder->locals_bias,
1037 charstringIndex + 1 ));
1039 if ( cf2_initLocalRegionBuffer( decoder,
1043 lastError = FT_THROW( Invalid_Glyph_Format );
1048 charstringIndex += 1;
1053 FT_TRACE4((
" return (leaving level %d)\n", charstringIndex ));
1055 if ( charstringIndex < 1 )
1058 lastError = FT_THROW( Invalid_Glyph_Format );
1063 charstring = (CF2_Buffer)
1064 cf2_arrstack_getPointer(
1066 (CF2_UInt)--charstringIndex );
1071 FT_Byte op2 = (FT_Byte)cf2_buf_readByte( charstring );
1080 static const FT_Bool readFromStack[12] =
1091 FT_TRACE4((
" hflex\n" ));
1093 cf2_doFlex( opStack,
1104 static const FT_Bool readFromStack[12] =
1115 FT_TRACE4((
" flex\n" ));
1117 cf2_doFlex( opStack,
1128 static const FT_Bool readFromStack[12] =
1139 FT_TRACE4((
" hflex1\n" ));
1141 cf2_doFlex( opStack,
1152 static const FT_Bool readFromStack[12] =
1163 FT_TRACE4((
" flex1\n" ));
1165 cf2_doFlex( opStack,
1175 case cf2_escRESERVED_8:
1176 case cf2_escRESERVED_13:
1177 case cf2_escRESERVED_19:
1178 case cf2_escRESERVED_25:
1179 case cf2_escRESERVED_31:
1180 case cf2_escRESERVED_32:
1181 FT_TRACE4((
" unknown op (12, %d)\n", op2 ));
1186 if ( font->isCFF2 || op2 >= cf2_escRESERVED_38 )
1187 FT_TRACE4((
" unknown op (12, %d)\n", op2 ));
1188 else if ( font->isT1 && result_cnt > 0 && op2 != cf2_escPOP )
1200 case cf2_escDOTSECTION:
1202 FT_TRACE4((
" dotsection\n" ));
1217 FT_TRACE4((
" unknown op (12, %d)\n", op2 ));
1220 CF2_F16Dot16 v0, v1, v2;
1222 FT_Bool isV = FT_BOOL( op2 == cf2_escVSTEM3 );
1225 FT_TRACE4((
"%s\n", isV ?
" vstem3"
1228 FT_ASSERT( cf2_stack_count( opStack ) == 6 );
1230 v0 = cf2_stack_getReal( opStack, 0 );
1231 v1 = cf2_stack_getReal( opStack, 2 );
1232 v2 = cf2_stack_getReal( opStack, 4 );
1236 SUB_INT32( SUB_INT32( v1, v0 ),
1237 cf2_stack_getReal( opStack, 1 ) ) );
1240 SUB_INT32( SUB_INT32( v2, v1 ),
1241 cf2_stack_getReal( opStack, 3 ) ) );
1246 isV ? &vStemHintArray : &hStemHintArray,
1249 isV ? decoder->builder.left_bearing->x
1250 : decoder->builder.left_bearing->y );
1252 if ( decoder->width_only )
1264 FT_TRACE4((
" and\n" ));
1266 arg2 = cf2_stack_popFixed( opStack );
1267 arg1 = cf2_stack_popFixed( opStack );
1269 cf2_stack_pushInt( opStack, arg1 && arg2 );
1279 FT_TRACE4((
" or\n" ));
1281 arg2 = cf2_stack_popFixed( opStack );
1282 arg1 = cf2_stack_popFixed( opStack );
1284 cf2_stack_pushInt( opStack, arg1 || arg2 );
1293 FT_TRACE4((
" not\n" ));
1295 arg = cf2_stack_popFixed( opStack );
1297 cf2_stack_pushInt( opStack, !arg );
1303 FT_TRACE4((
" unknown op (12, %d)\n", op2 ));
1307 CF2_Int bchar_index, achar_index;
1308 FT_Vector left_bearing, advance;
1310#ifdef FT_CONFIG_OPTION_INCREMENTAL
1311 T1_Face face = (T1_Face)decoder->builder.face;
1313 CF2_BufferRec component;
1314 CF2_Fixed dummyWidth;
1316 CF2_Int achar = cf2_stack_popInt( opStack );
1317 CF2_Int bchar = cf2_stack_popInt( opStack );
1319 FT_Pos ady = cf2_stack_popFixed ( opStack );
1320 FT_Pos adx = cf2_stack_popFixed ( opStack );
1321 FT_Pos asb = cf2_stack_popFixed ( opStack );
1324 FT_TRACE4((
" seac\n" ));
1328 FT_ERROR((
" nested seac\n" ));
1329 lastError = FT_THROW( Invalid_Glyph_Format );
1333 if ( decoder->builder.metrics_only )
1335 FT_ERROR((
" unexpected seac\n" ));
1336 lastError = FT_THROW( Invalid_Glyph_Format );
1343#ifdef FT_CONFIG_OPTION_INCREMENTAL
1344 if ( decoder->glyph_names == 0 &&
1345 !face->root.internal->incremental_interface )
1347 if ( decoder->glyph_names == 0 )
1350 FT_ERROR((
"cf2_interpT2CharString:\n" ));
1351 FT_ERROR((
" (Type 1 seac) glyph names table"
1352 " not available in this font\n" ));
1353 lastError = FT_THROW( Invalid_Glyph_Format );
1358 adx += decoder->builder.left_bearing->x;
1360#ifdef FT_CONFIG_OPTION_INCREMENTAL
1361 if ( face->root.internal->incremental_interface )
1364 bchar_index = bchar;
1365 achar_index = achar;
1370 bchar_index = t1_lookup_glyph_by_stdcharcode_ps(
1372 achar_index = t1_lookup_glyph_by_stdcharcode_ps(
1376 if ( bchar_index < 0 || achar_index < 0 )
1378 FT_ERROR((
"cf2_interpT2CharString:\n" ));
1379 FT_ERROR((
" (Type 1 seac) invalid"
1380 " seac character code arguments\n" ));
1381 lastError = FT_THROW( Invalid_Glyph_Format );
1388 if ( decoder->builder.no_recurse )
1390 FT_GlyphSlot glyph = (FT_GlyphSlot)decoder->builder.glyph;
1391 FT_GlyphLoader loader = glyph->internal->loader;
1396 error2 = FT_GlyphLoader_CheckSubGlyphs( loader, 2 );
1403 subg = loader->current.subglyphs;
1406 subg->index = bchar_index;
1407 subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES |
1408 FT_SUBGLYPH_FLAG_USE_MY_METRICS;
1414 subg->index = achar_index;
1415 subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES;
1416 subg->arg1 = (FT_Int)FIXED_TO_INT( adx - asb );
1417 subg->arg2 = (FT_Int)FIXED_TO_INT( ady );
1420 glyph->num_subglyphs = 2;
1421 glyph->subglyphs = loader->base.subglyphs;
1422 glyph->format = FT_GLYPH_FORMAT_COMPOSITE;
1424 loader->current.num_subglyphs = 2;
1433 FT_GlyphLoader_Prepare( decoder->builder.loader );
1435 error2 = cf2_getT1SeacComponent( decoder,
1436 (FT_UInt)bchar_index,
1447 left_bearing = *decoder->builder.left_bearing;
1448 advance = *decoder->builder.advance;
1450 cf2_interpT2CharString( font,
1458 cf2_freeT1SeacComponent( decoder, &component );
1465 left_bearing = *decoder->builder.left_bearing;
1466 advance = *decoder->builder.advance;
1469 decoder->builder.left_bearing->x = 0;
1470 decoder->builder.left_bearing->y = 0;
1475 error2 = cf2_getT1SeacComponent( decoder,
1476 (FT_UInt)achar_index,
1483 cf2_interpT2CharString( font,
1491 cf2_freeT1SeacComponent( decoder, &component );
1496 *decoder->builder.left_bearing = left_bearing;
1497 *decoder->builder.advance = advance;
1505 FT_TRACE4((
" unknown op (12, %d)\n", op2 ));
1508 CF2_Fixed lsb_x, lsb_y;
1509 PS_Builder* builder;
1512 FT_TRACE4((
" sbw" ));
1514 builder = &decoder->builder;
1516 builder->advance->y = cf2_stack_popFixed( opStack );
1517 builder->advance->x = cf2_stack_popFixed( opStack );
1519 lsb_y = cf2_stack_popFixed( opStack );
1520 lsb_x = cf2_stack_popFixed( opStack );
1522 builder->left_bearing->x =
1523 ADD_INT32( builder->left_bearing->x, lsb_x );
1524 builder->left_bearing->y =
1525 ADD_INT32( builder->left_bearing->y, lsb_y );
1533 if ( builder->metrics_only )
1536 if ( initial_map_ready )
1538 curX = ADD_INT32( curX, lsb_x );
1539 curY = ADD_INT32( curY, lsb_y );
1549 FT_TRACE4((
" abs\n" ));
1551 arg = cf2_stack_popFixed( opStack );
1553 if ( arg < -CF2_FIXED_MAX )
1554 cf2_stack_pushFixed( opStack, CF2_FIXED_MAX );
1556 cf2_stack_pushFixed( opStack, FT_ABS( arg ) );
1562 CF2_F16Dot16 summand1;
1563 CF2_F16Dot16 summand2;
1566 FT_TRACE4((
" add\n" ));
1568 summand2 = cf2_stack_popFixed( opStack );
1569 summand1 = cf2_stack_popFixed( opStack );
1571 cf2_stack_pushFixed( opStack,
1572 ADD_INT32( summand1,
1579 CF2_F16Dot16 minuend;
1580 CF2_F16Dot16 subtrahend;
1583 FT_TRACE4((
" sub\n" ));
1585 subtrahend = cf2_stack_popFixed( opStack );
1586 minuend = cf2_stack_popFixed( opStack );
1588 cf2_stack_pushFixed( opStack,
1589 SUB_INT32( minuend, subtrahend ) );
1595 CF2_F16Dot16 dividend;
1596 CF2_F16Dot16 divisor;
1599 FT_TRACE4((
" div\n" ));
1601 if ( font->isT1 && large_int )
1603 divisor = (CF2_F16Dot16)cf2_stack_popInt( opStack );
1604 dividend = (CF2_F16Dot16)cf2_stack_popInt( opStack );
1610 divisor = cf2_stack_popFixed( opStack );
1611 dividend = cf2_stack_popFixed( opStack );
1614 cf2_stack_pushFixed( opStack,
1615 FT_DivFix( dividend, divisor ) );
1625 FT_TRACE4((
" neg\n" ));
1627 arg = cf2_stack_popFixed( opStack );
1629 if ( arg < -CF2_FIXED_MAX )
1630 cf2_stack_pushFixed( opStack, CF2_FIXED_MAX );
1632 cf2_stack_pushFixed( opStack, -arg );
1642 FT_TRACE4((
" eq\n" ));
1644 arg2 = cf2_stack_popFixed( opStack );
1645 arg1 = cf2_stack_popFixed( opStack );
1647 cf2_stack_pushInt( opStack, arg1 == arg2 );
1651 case cf2_escCALLOTHERSUBR:
1653 FT_TRACE4((
" unknown op (12, %d)\n", op2 ));
1662 FT_TRACE4((
" callothersubr\n" ));
1664 subr_no = cf2_stack_popInt( opStack );
1665 arg_cnt = cf2_stack_popInt( opStack );
1679 count = cf2_stack_count( opStack );
1680 if ( (CF2_UInt)arg_cnt > count )
1682 FT_ERROR((
"cf2_interpT2CharString (Type 1 mode):"
1683 " stack underflow\n" ));
1684 lastError = FT_THROW( Invalid_Glyph_Format );
1688 opIdx += count - (CF2_UInt)arg_cnt;
1690 known_othersubr_result_cnt = 0;
1715 goto Unexpected_OtherSubr;
1717 if ( initial_map_ready &&
1718 ( !decoder->flex_state ||
1719 decoder->num_flex_vectors != 7 ) )
1721 FT_ERROR((
"cf2_interpT2CharString (Type 1 mode):"
1722 " unexpected flex end\n" ));
1723 lastError = FT_THROW( Invalid_Glyph_Format );
1729 cf2_stack_pushFixed( opStack, curX );
1730 cf2_stack_pushFixed( opStack, curY );
1731 known_othersubr_result_cnt = 2;
1736 goto Unexpected_OtherSubr;
1738 if ( !initial_map_ready )
1741 if ( ps_builder_check_points( &decoder->builder, 6 ) )
1744 decoder->flex_state = 1;
1745 decoder->num_flex_vectors = 0;
1755 goto Unexpected_OtherSubr;
1757 if ( !initial_map_ready )
1760 if ( !decoder->flex_state )
1762 FT_ERROR((
"cf2_interpT2CharString (Type 1 mode):"
1763 " missing flex start\n" ));
1764 lastError = FT_THROW( Invalid_Glyph_Format );
1772 idx = decoder->num_flex_vectors++;
1773 if ( idx > 0 && idx < 7 )
1780 if ( ps_builder_check_points( &decoder->builder,
1783 lastError = FT_THROW( Invalid_Glyph_Format );
1788 idx2 = ( idx > 3 ? idx - 3 : idx ) * 2;
1790 flexStore[idx2 - 2] = curX;
1791 flexStore[idx2 - 1] = curY;
1793 if ( idx == 3 || idx == 6 )
1794 cf2_glyphpath_curveTo( &glyphPath,
1807 goto Unexpected_OtherSubr;
1809 if ( initial_map_ready )
1813 cf2_arrstack_clear( &vStemHintArray );
1814 cf2_arrstack_clear( &hStemHintArray );
1816 cf2_hintmask_init( &hintMask, error );
1817 hintMask.isValid = FALSE;
1818 hintMask.isNew = TRUE;
1821 known_othersubr_result_cnt = 1;
1827 cf2_stack_clear( opStack );
1836 PS_Blend blend = decoder->blend;
1837 FT_UInt num_points, nn, mm;
1845 "cf2_interpT2CharString:"
1846 " unexpected multiple masters operator\n" ));
1847 lastError = FT_THROW( Invalid_Glyph_Format );
1851 num_points = (FT_UInt)subr_no - 13 +
1853 if ( arg_cnt != (FT_Int)( num_points *
1854 blend->num_designs ) )
1857 "cf2_interpT2CharString:"
1858 " incorrect number of multiple masters arguments\n" ));
1859 lastError = FT_THROW( Invalid_Glyph_Format );
1879 delta = opIdx + num_points;
1881 for ( nn = 0; nn < num_points; nn++ )
1883 CF2_Fixed tmp = cf2_stack_getReal( opStack,
1887 for ( mm = 1; mm < blend->num_designs; mm++ )
1888 tmp = ADD_INT32( tmp,
1890 cf2_stack_getReal( opStack,
1892 blend->weight_vector[mm] ) );
1894 cf2_stack_setReal( opStack, values++, tmp );
1896 cf2_stack_pop( opStack,
1897 (CF2_UInt)arg_cnt - num_points );
1899 known_othersubr_result_cnt = (FT_Int)num_points;
1910 PS_Blend blend = decoder->blend;
1911 FT_UInt len_buildchar = decoder->len_buildchar;
1914 if ( arg_cnt != 1 || !blend )
1915 goto Unexpected_OtherSubr;
1917 idx = (FT_UInt)cf2_stack_popInt( opStack );
1919 if ( len_buildchar < blend->num_designs ||
1920 len_buildchar - blend->num_designs < idx )
1921 goto Unexpected_OtherSubr;
1923 if ( decoder->buildchar && blend->weight_vector )
1924 ft_memcpy( &decoder->buildchar[idx],
1925 blend->weight_vector,
1926 blend->num_designs *
1927 sizeof ( blend->weight_vector[0] ) );
1935 CF2_F16Dot16 summand1;
1936 CF2_F16Dot16 summand2;
1940 goto Unexpected_OtherSubr;
1942 summand2 = cf2_stack_popFixed( opStack );
1943 summand1 = cf2_stack_popFixed( opStack );
1945 cf2_stack_pushFixed( opStack,
1946 ADD_INT32( summand1,
1948 known_othersubr_result_cnt = 1;
1956 CF2_F16Dot16 minuend;
1957 CF2_F16Dot16 subtrahend;
1961 goto Unexpected_OtherSubr;
1963 subtrahend = cf2_stack_popFixed( opStack );
1964 minuend = cf2_stack_popFixed( opStack );
1966 cf2_stack_pushFixed( opStack,
1969 known_othersubr_result_cnt = 1;
1977 CF2_F16Dot16 factor1;
1978 CF2_F16Dot16 factor2;
1982 goto Unexpected_OtherSubr;
1984 factor2 = cf2_stack_popFixed( opStack );
1985 factor1 = cf2_stack_popFixed( opStack );
1987 cf2_stack_pushFixed( opStack,
1988 FT_MulFix( factor1, factor2 ) );
1989 known_othersubr_result_cnt = 1;
1997 CF2_F16Dot16 dividend;
1998 CF2_F16Dot16 divisor;
2002 goto Unexpected_OtherSubr;
2004 divisor = cf2_stack_popFixed( opStack );
2005 dividend = cf2_stack_popFixed( opStack );
2008 goto Unexpected_OtherSubr;
2010 cf2_stack_pushFixed( opStack,
2011 FT_DivFix( dividend,
2013 known_othersubr_result_cnt = 1;
2022 PS_Blend blend = decoder->blend;
2025 if ( arg_cnt != 2 || !blend )
2026 goto Unexpected_OtherSubr;
2028 idx = (CF2_UInt)cf2_stack_popInt( opStack );
2030 if ( idx >= decoder->len_buildchar )
2031 goto Unexpected_OtherSubr;
2033 decoder->buildchar[idx] =
2034 cf2_stack_popFixed( opStack );
2044 PS_Blend blend = decoder->blend;
2047 if ( arg_cnt != 1 || !blend )
2048 goto Unexpected_OtherSubr;
2050 idx = (CF2_UInt)cf2_stack_popInt( opStack );
2052 if ( idx >= decoder->len_buildchar )
2053 goto Unexpected_OtherSubr;
2055 cf2_stack_pushFixed( opStack,
2056 decoder->buildchar[idx] );
2057 known_othersubr_result_cnt = 1;
2068 XXX which routine has left its mark on the
2069 XXX (PostScript) stack?;
2085 goto Unexpected_OtherSubr;
2087 cond2 = cf2_stack_popFixed( opStack );
2088 cond1 = cf2_stack_popFixed( opStack );
2089 arg2 = cf2_stack_popFixed( opStack );
2090 arg1 = cf2_stack_popFixed( opStack );
2092 cf2_stack_pushFixed( opStack,
2093 cond1 <= cond2 ? arg1 : arg2 );
2094 known_othersubr_result_cnt = 1;
2107 goto Unexpected_OtherSubr;
2112 ( ( decoder->current_subfont->random & 0xFFFF ) + 1 );
2114 decoder->current_subfont->random =
2115 cff_random( decoder->current_subfont->random );
2117 cf2_stack_pushFixed( opStack, r );
2118 known_othersubr_result_cnt = 1;
2123 if ( arg_cnt >= 0 && subr_no >= 0 )
2129 "cf2_interpT2CharString (Type 1 mode):"
2130 " unknown othersubr [%d %d], wish me luck\n",
2131 arg_cnt, subr_no ));
2136 if ( arg_cnt > PS_STORAGE_SIZE )
2137 arg_cnt = PS_STORAGE_SIZE;
2138 result_cnt = arg_cnt;
2140 for ( i = 1; i <= arg_cnt; i++ )
2141 results[result_cnt - i] =
2142 cf2_stack_popFixed( opStack );
2148 Unexpected_OtherSubr:
2149 FT_ERROR((
"cf2_interpT2CharString (Type 1 mode):"
2150 " invalid othersubr [%d %d]\n",
2151 arg_cnt, subr_no ));
2152 lastError = FT_THROW( Invalid_Glyph_Format );
2160 FT_TRACE4((
" unknown op (12, %d)\n", op2 ));
2163 FT_TRACE4((
" pop" ));
2165 if ( known_othersubr_result_cnt > 0 )
2167 known_othersubr_result_cnt--;
2172 if ( result_cnt == 0 )
2174 FT_ERROR((
"cf2_interpT2CharString (Type 1 mode):"
2175 " no more operands for othersubr\n" ));
2176 lastError = FT_THROW( Invalid_Glyph_Format );
2181 cf2_stack_pushFixed( opStack, results[result_cnt] );
2186 FT_TRACE4((
" drop\n" ));
2188 (void)cf2_stack_popFixed( opStack );
2197 FT_TRACE4((
" put\n" ));
2199 idx = (CF2_UInt)cf2_stack_popInt( opStack );
2200 val = cf2_stack_popFixed( opStack );
2202 if ( idx < CF2_STORAGE_SIZE )
2212 FT_TRACE4((
" get\n" ));
2214 idx = (CF2_UInt)cf2_stack_popInt( opStack );
2216 if ( idx < CF2_STORAGE_SIZE )
2217 cf2_stack_pushFixed( opStack, storage[idx] );
2229 FT_TRACE4((
" ifelse\n" ));
2231 cond2 = cf2_stack_popFixed( opStack );
2232 cond1 = cf2_stack_popFixed( opStack );
2233 arg2 = cf2_stack_popFixed( opStack );
2234 arg1 = cf2_stack_popFixed( opStack );
2236 cf2_stack_pushFixed( opStack,
2237 cond1 <= cond2 ? arg1 : arg2 );
2246 FT_TRACE4((
" random\n" ));
2251 ( ( decoder->current_subfont->random & 0xFFFF ) + 1 );
2253 decoder->current_subfont->random =
2254 cff_random( decoder->current_subfont->random );
2256 cf2_stack_pushFixed( opStack, r );
2262 CF2_F16Dot16 factor1;
2263 CF2_F16Dot16 factor2;
2266 FT_TRACE4((
" mul\n" ));
2268 factor2 = cf2_stack_popFixed( opStack );
2269 factor1 = cf2_stack_popFixed( opStack );
2271 cf2_stack_pushFixed( opStack,
2272 FT_MulFix( factor1, factor2 ) );
2281 FT_TRACE4((
" sqrt\n" ));
2283 arg = cf2_stack_popFixed( opStack );
2285 arg = (CF2_F16Dot16)FT_SqrtFixed( (FT_UInt32)arg );
2289 cf2_stack_pushFixed( opStack, arg );
2298 FT_TRACE4((
" dup\n" ));
2300 arg = cf2_stack_popFixed( opStack );
2302 cf2_stack_pushFixed( opStack, arg );
2303 cf2_stack_pushFixed( opStack, arg );
2313 FT_TRACE4((
" exch\n" ));
2315 arg2 = cf2_stack_popFixed( opStack );
2316 arg1 = cf2_stack_popFixed( opStack );
2318 cf2_stack_pushFixed( opStack, arg2 );
2319 cf2_stack_pushFixed( opStack, arg1 );
2329 FT_TRACE4((
" index\n" ));
2331 idx = cf2_stack_popInt( opStack );
2332 size = cf2_stack_count( opStack );
2343 else if ( (CF2_UInt)idx >= size )
2346 gr_idx = size - 1 - (CF2_UInt)idx;
2348 cf2_stack_pushFixed( opStack,
2349 cf2_stack_getReal( opStack,
2361 FT_TRACE4((
" roll\n" ));
2363 idx = cf2_stack_popInt( opStack );
2364 count = cf2_stack_popInt( opStack );
2366 cf2_stack_roll( opStack, count, idx );
2370 case cf2_escSETCURRENTPT:
2372 FT_TRACE4((
" unknown op (12, %d)\n", op2 ));
2375 FT_TRACE4((
" setcurrentpoint" ));
2377 if ( !initial_map_ready )
2395 if ( decoder->flex_state != 1 )
2397 FT_ERROR((
"cf2_interpT2CharString:"
2398 " unexpected `setcurrentpoint'\n" ));
2405 curY = cf2_stack_popFixed( opStack );
2406 curX = cf2_stack_popFixed( opStack );
2408 decoder->flex_state = 0;
2422 FT_TRACE4((
" unknown op (%d)\n", op1 ));
2426 PS_Builder* builder;
2429 FT_TRACE4((
" hsbw\n" ));
2431 builder = &decoder->builder;
2433 builder->advance->x = cf2_stack_popFixed( opStack );
2434 builder->advance->y = 0;
2436 lsb_x = cf2_stack_popFixed( opStack );
2438 builder->left_bearing->x = ADD_INT32( builder->left_bearing->x,
2446 if ( builder->metrics_only )
2449 if ( initial_map_ready )
2450 curX = ADD_INT32( curX, lsb_x );
2454 case cf2_cmdENDCHAR:
2455 FT_TRACE4((
" endchar\n" ));
2457 if ( font->isT1 && !initial_map_ready )
2459 FT_TRACE5((
"cf2_interpT2CharString (Type 1 mode): "
2460 "Build initial hintmap, rewinding...\n" ));
2463 cf2_glyphpath_moveTo( &glyphPath, curX, curY );
2465 initial_map_ready = TRUE;
2468 cf2_arrstack_clear( &vStemHintArray );
2469 cf2_arrstack_clear( &hStemHintArray );
2471 cf2_hintmask_init( &hintMask, error );
2472 hintMask.isValid = FALSE;
2473 hintMask.isNew = TRUE;
2479 while ( charstringIndex > 0 )
2481 FT_TRACE4((
" return (leaving level %d)\n", charstringIndex ));
2484 charstring = (CF2_Buffer)
2485 cf2_arrstack_getPointer(
2487 (CF2_UInt)--charstringIndex );
2489 charstring->ptr = charstring->start;
2494 if ( cf2_stack_count( opStack ) == 1 ||
2495 cf2_stack_count( opStack ) == 5 )
2498 *width = ADD_INT32( cf2_stack_getReal( opStack, 0 ),
2505 if ( decoder->width_only )
2509 cf2_glyphpath_closeOpenPath( &glyphPath );
2513 if ( !font->isCFF2 && !font->isT1 && cf2_stack_count( opStack ) > 1 )
2520 CF2_BufferRec component;
2521 CF2_Fixed dummyWidth;
2527 lastError = FT_THROW( Invalid_Glyph_Format );
2531 achar = cf2_stack_popInt( opStack );
2532 bchar = cf2_stack_popInt( opStack );
2534 curY = cf2_stack_popFixed( opStack );
2535 curX = cf2_stack_popFixed( opStack );
2537 error2 = cf2_getSeacComponent( decoder, achar, &component );
2543 cf2_interpT2CharString( font,
2551 cf2_freeSeacComponent( decoder, &component );
2553 error2 = cf2_getSeacComponent( decoder, bchar, &component );
2559 cf2_interpT2CharString( font,
2567 cf2_freeSeacComponent( decoder, &component );
2571 case cf2_cmdCNTRMASK:
2572 case cf2_cmdHINTMASK:
2575 FT_TRACE4((
"%s", op1 == cf2_cmdCNTRMASK ?
" cntrmask" :
" hintmask" ));
2578 if ( cf2_stack_count( opStack ) > 1 &&
2579 cf2_hintmask_isValid( &hintMask ) )
2581 FT_TRACE4((
"cf2_interpT2CharString: invalid hint mask\n" ));
2594 if ( decoder->width_only )
2597 if ( op1 == cf2_cmdHINTMASK )
2600 cf2_hintmask_read( &hintMask,
2602 cf2_arrstack_size( &hStemHintArray ) +
2603 cf2_arrstack_size( &vStemHintArray ) );
2620 CF2_HintMapRec counterHintMap;
2621 CF2_HintMaskRec counterMask;
2624 cf2_hintmap_init( &counterHintMap,
2626 &glyphPath.initialHintMap,
2627 &glyphPath.hintMoves,
2629 cf2_hintmask_init( &counterMask, error );
2631 cf2_hintmask_read( &counterMask,
2633 cf2_arrstack_size( &hStemHintArray ) +
2634 cf2_arrstack_size( &vStemHintArray ) );
2635 cf2_hintmap_build( &counterHintMap,
2644 case cf2_cmdRMOVETO:
2645 FT_TRACE4((
" rmoveto\n" ));
2647 if ( font->isT1 && !decoder->flex_state && !haveWidth )
2648 FT_ERROR((
"cf2_interpT2CharString (Type 1 mode):"
2649 " No width. Use hsbw/sbw as first op\n" ));
2651 if ( cf2_stack_count( opStack ) > 2 && !haveWidth )
2652 *width = ADD_INT32( cf2_stack_getReal( opStack, 0 ),
2658 if ( decoder->width_only )
2661 curY = ADD_INT32( curY, cf2_stack_popFixed( opStack ) );
2662 curX = ADD_INT32( curX, cf2_stack_popFixed( opStack ) );
2664 if ( !decoder->flex_state )
2665 cf2_glyphpath_moveTo( &glyphPath, curX, curY );
2669 case cf2_cmdHMOVETO:
2670 FT_TRACE4((
" hmoveto\n" ));
2672 if ( font->isT1 && !decoder->flex_state && !haveWidth )
2673 FT_ERROR((
"cf2_interpT2CharString (Type 1 mode):"
2674 " No width. Use hsbw/sbw as first op\n" ));
2676 if ( cf2_stack_count( opStack ) > 1 && !haveWidth )
2677 *width = ADD_INT32( cf2_stack_getReal( opStack, 0 ),
2683 if ( decoder->width_only )
2686 curX = ADD_INT32( curX, cf2_stack_popFixed( opStack ) );
2688 if ( !decoder->flex_state )
2689 cf2_glyphpath_moveTo( &glyphPath, curX, curY );
2693 case cf2_cmdRLINECURVE:
2695 CF2_UInt count = cf2_stack_count( opStack );
2699 FT_TRACE4((
" rlinecurve\n" ));
2701 while ( idx + 6 < count )
2703 curX = ADD_INT32( curX, cf2_stack_getReal( opStack,
2705 curY = ADD_INT32( curY, cf2_stack_getReal( opStack,
2708 cf2_glyphpath_lineTo( &glyphPath, curX, curY );
2712 while ( idx < count )
2714 CF2_Fixed x1, y1, x2, y2, x3, y3;
2717 x1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ), curX );
2718 y1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ), curY );
2719 x2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ), x1 );
2720 y2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ), y1 );
2721 x3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 4 ), x2 );
2722 y3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 5 ), y2 );
2724 cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 );
2731 cf2_stack_clear( opStack );
2735 case cf2_cmdVVCURVETO:
2737 CF2_UInt count, count1 = cf2_stack_count( opStack );
2744 count = count1 & ~2U;
2745 idx += count1 - count;
2747 FT_TRACE4((
" vvcurveto\n" ));
2749 while ( idx < count )
2751 CF2_Fixed x1, y1, x2, y2, x3, y3;
2754 if ( ( count - idx ) & 1 )
2756 x1 = ADD_INT32( cf2_stack_getReal( opStack, idx ), curX );
2763 y1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ), curY );
2764 x2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ), x1 );
2765 y2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ), y1 );
2767 y3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ), y2 );
2769 cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 );
2776 cf2_stack_clear( opStack );
2780 case cf2_cmdHHCURVETO:
2782 CF2_UInt count, count1 = cf2_stack_count( opStack );
2789 count = count1 & ~2U;
2790 idx += count1 - count;
2792 FT_TRACE4((
" hhcurveto\n" ));
2794 while ( idx < count )
2796 CF2_Fixed x1, y1, x2, y2, x3, y3;
2799 if ( ( count - idx ) & 1 )
2801 y1 = ADD_INT32( cf2_stack_getReal( opStack, idx ), curY );
2808 x1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ), curX );
2809 x2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ), x1 );
2810 y2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ), y1 );
2811 x3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ), x2 );
2814 cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 );
2821 cf2_stack_clear( opStack );
2825 case cf2_cmdVHCURVETO:
2826 case cf2_cmdHVCURVETO:
2828 CF2_UInt count, count1 = cf2_stack_count( opStack );
2831 FT_Bool alternate = FT_BOOL( op1 == cf2_cmdHVCURVETO );
2838 count = count1 & ~2U;
2839 idx += count1 - count;
2841 FT_TRACE4((
"%s\n", alternate ?
" hvcurveto" :
" vhcurveto" ));
2843 while ( idx < count )
2845 CF2_Fixed x1, x2, x3, y1, y2, y3;
2850 x1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ), curX );
2852 x2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ), x1 );
2853 y2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ), y1 );
2854 y3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ), y2 );
2856 if ( count - idx == 5 )
2858 x3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 4 ), x2 );
2870 y1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ), curY );
2871 x2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ), x1 );
2872 y2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ), y1 );
2873 x3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ), x2 );
2875 if ( count - idx == 5 )
2877 y3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 4 ), y2 );
2887 cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 );
2894 cf2_stack_clear( opStack );
2898 case cf2_cmdEXTENDEDNMBR:
2902 CF2_Int byte1 = cf2_buf_readByte( charstring );
2903 CF2_Int byte2 = cf2_buf_readByte( charstring );
2906 v = (FT_Short)( ( byte1 << 8 ) |
2909 FT_TRACE4((
" %d", v ));
2911 cf2_stack_pushInt( opStack, v );
2925 FT_TRACE4((
" %d", v ));
2928 cf2_stack_pushInt( opStack, v );
2931 else if ( op1 <= 250 )
2939 v += cf2_buf_readByte( charstring );
2942 FT_TRACE4((
" %d", v ));
2945 cf2_stack_pushInt( opStack, v );
2948 else if ( op1 <= 254 )
2956 v += cf2_buf_readByte( charstring );
2959 FT_TRACE4((
" %d", v ));
2962 cf2_stack_pushInt( opStack, v );
2969 FT_UInt32 byte1 = (FT_UInt32)cf2_buf_readByte( charstring );
2970 FT_UInt32 byte2 = (FT_UInt32)cf2_buf_readByte( charstring );
2971 FT_UInt32 byte3 = (FT_UInt32)cf2_buf_readByte( charstring );
2972 FT_UInt32 byte4 = (FT_UInt32)cf2_buf_readByte( charstring );
2975 v = (CF2_Fixed)( ( byte1 << 24 ) |
2997 if ( v > 32000 || v < -32000 )
3000 FT_ERROR((
"cf2_interpT2CharString (Type 1 mode):"
3001 " no `div' after large integer\n" ));
3006 FT_TRACE4((
" %d", v ));
3008 cf2_stack_pushInt( opStack, (CF2_Int)v );
3012 FT_TRACE4((
" %.5fF", v / 65536.0 ));
3014 cf2_stack_pushFixed( opStack, v );
3022 cf2_stack_clear( opStack );
3027 FT_TRACE4((
"cf2_interpT2CharString:"
3028 " charstring ends without ENDCHAR\n" ));
3032 cf2_setError( error, lastError );
3035 FT_TRACE4((
"charstring error %d\n", *error ));
3038 cf2_glyphpath_finalize( &glyphPath );
3039 cf2_arrstack_finalize( &vStemHintArray );
3040 cf2_arrstack_finalize( &hStemHintArray );
3041 cf2_arrstack_finalize( &subrStack );
3042 cf2_stack_free( opStack );
3044 FT_TRACE4((
"\n" ));