1 /***************************************************************************/
2 /* */
3 /* cffdecode.c */
4 /* */
5 /* PostScript CFF (Type 2) decoding routines (body). */
6 /* */
7 /* Copyright 2017-2018 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
9 /* */
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. */
15 /* */
16 /***************************************************************************/
17
18
19 #include <ft2build.h>
20 #include FT_FREETYPE_H
21 #include FT_INTERNAL_DEBUG_H
22 #include FT_INTERNAL_SERVICE_H
23 #include FT_SERVICE_CFF_TABLE_LOAD_H
24
25 #include "cffdecode.h"
26 #include "psobjs.h"
27
28 #include "psauxerr.h"
29
30
31 /*************************************************************************/
32 /* */
33 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
34 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
35 /* messages during execution. */
36 /* */
37 #undef FT_COMPONENT
38 #define FT_COMPONENT trace_cffdecode
39
40
41 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
42
43 typedef enum CFF_Operator_
44 {
45 cff_op_unknown = 0,
46
47 cff_op_rmoveto,
48 cff_op_hmoveto,
49 cff_op_vmoveto,
50
51 cff_op_rlineto,
52 cff_op_hlineto,
53 cff_op_vlineto,
54
55 cff_op_rrcurveto,
56 cff_op_hhcurveto,
57 cff_op_hvcurveto,
58 cff_op_rcurveline,
218 FT_Pos ady,
219 FT_Int bchar,
220 FT_Int achar )
221 {
222 FT_Error error;
223 CFF_Builder* builder = &decoder->builder;
224 FT_Int bchar_index, achar_index;
225 TT_Face face = decoder->builder.face;
226 FT_Vector left_bearing, advance;
227 FT_Byte* charstring;
228 FT_ULong charstring_len;
229 FT_Pos glyph_width;
230
231
232 if ( decoder->seac )
233 {
234 FT_ERROR(( "cff_operator_seac: invalid nested seac\n" ));
235 return FT_THROW( Syntax_Error );
236 }
237
238 adx += decoder->builder.left_bearing.x;
239 ady += decoder->builder.left_bearing.y;
240
241 #ifdef FT_CONFIG_OPTION_INCREMENTAL
242 /* Incremental fonts don't necessarily have valid charsets. */
243 /* They use the character code, not the glyph index, in this case. */
244 if ( face->root.internal->incremental_interface )
245 {
246 bchar_index = bchar;
247 achar_index = achar;
248 }
249 else
250 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
251 {
252 CFF_Font cff = (CFF_Font)(face->extra.data);
253
254
255 bchar_index = cff_lookup_glyph_by_stdcharcode( cff, bchar );
256 achar_index = cff_lookup_glyph_by_stdcharcode( cff, achar );
257 }
258
259 if ( bchar_index < 0 || achar_index < 0 )
361
362 Exit:
363 return error;
364 }
365
366 #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
367
368
369 /*************************************************************************/
370 /*************************************************************************/
371 /*************************************************************************/
372 /********** *********/
373 /********** *********/
374 /********** GENERIC CHARSTRING PARSING *********/
375 /********** *********/
376 /********** *********/
377 /*************************************************************************/
378 /*************************************************************************/
379 /*************************************************************************/
380
381 /*************************************************************************/
382 /* */
383 /* <Function> */
384 /* cff_compute_bias */
385 /* */
386 /* <Description> */
387 /* Computes the bias value in dependence of the number of glyph */
388 /* subroutines. */
389 /* */
390 /* <Input> */
391 /* in_charstring_type :: The `CharstringType' value of the top DICT */
392 /* dictionary. */
393 /* */
394 /* num_subrs :: The number of glyph subroutines. */
395 /* */
396 /* <Return> */
397 /* The bias value. */
398 static FT_Int
399 cff_compute_bias( FT_Int in_charstring_type,
400 FT_UInt num_subrs )
401 {
402 FT_Int result;
403
404
405 if ( in_charstring_type == 1 )
406 result = 0;
407 else if ( num_subrs < 1240 )
408 result = 107;
409 else if ( num_subrs < 33900U )
410 result = 1131;
411 else
412 result = 32768U;
413
414 return result;
415 }
416
417
447 }
448 #endif
449
450 cffload = (FT_Service_CFFLoad)cff->cffload;
451
452 /* Get code to SID mapping from `cff_standard_encoding'. */
453 glyph_sid = cffload->get_standard_encoding( (FT_UInt)charcode );
454
455 for ( n = 0; n < cff->num_glyphs; n++ )
456 {
457 if ( cff->charset.sids[n] == glyph_sid )
458 return (FT_Int)n;
459 }
460
461 return -1;
462 }
463
464
465 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
466
467 /*************************************************************************/
468 /* */
469 /* <Function> */
470 /* cff_decoder_parse_charstrings */
471 /* */
472 /* <Description> */
473 /* Parses a given Type 2 charstrings program. */
474 /* */
475 /* <InOut> */
476 /* decoder :: The current Type 1 decoder. */
477 /* */
478 /* <Input> */
479 /* charstring_base :: The base of the charstring stream. */
480 /* */
481 /* charstring_len :: The length in bytes of the charstring stream. */
482 /* */
483 /* in_dict :: Set to 1 if function is called from top or */
484 /* private DICT (needed for Multiple Master CFFs). */
485 /* */
486 /* <Return> */
487 /* FreeType error code. 0 means success. */
488 /* */
489 FT_LOCAL_DEF( FT_Error )
490 cff_decoder_parse_charstrings( CFF_Decoder* decoder,
491 FT_Byte* charstring_base,
492 FT_ULong charstring_len,
493 FT_Bool in_dict )
494 {
495 FT_Error error;
496 CFF_Decoder_Zone* zone;
497 FT_Byte* ip;
498 FT_Byte* limit;
499 CFF_Builder* builder = &decoder->builder;
500 FT_Pos x, y;
501 FT_Fixed* stack;
502 FT_Int charstring_type =
503 decoder->cff->top_font.font_dict.charstring_type;
504 FT_UShort num_designs =
505 decoder->cff->top_font.font_dict.num_designs;
506 FT_UShort num_axes =
507 decoder->cff->top_font.font_dict.num_axes;
508
526 zone->base = charstring_base;
527 limit = zone->limit = charstring_base + charstring_len;
528 ip = zone->cursor = zone->base;
529
530 error = FT_Err_Ok;
531
532 x = builder->pos_x;
533 y = builder->pos_y;
534
535 /* begin hints recording session, if any */
536 if ( hinter )
537 hinter->open( hinter->hints );
538
539 /* now execute loop */
540 while ( ip < limit )
541 {
542 CFF_Operator op;
543 FT_Byte v;
544
545
546 /********************************************************************/
547 /* */
548 /* Decode operator or operand */
549 /* */
550 v = *ip++;
551 if ( v >= 32 || v == 28 )
552 {
553 FT_Int shift = 16;
554 FT_Int32 val;
555
556
557 /* this is an operand, push it on the stack */
558
559 /* if we use shifts, all computations are done with unsigned */
560 /* values; the conversion to a signed value is the last step */
561 if ( v == 28 )
562 {
563 if ( ip + 1 >= limit )
564 goto Syntax_Error;
565 val = (FT_Short)( ( (FT_UShort)ip[0] << 8 ) | ip[1] );
566 ip += 2;
567 }
568 else if ( v < 247 )
569 val = (FT_Int32)v - 139;
836 case cff_op_vlineto:
837 case cff_op_rrcurveto:
838 case cff_op_hstemhm:
839 case cff_op_hintmask:
840 case cff_op_cntrmask:
841 case cff_op_rmoveto:
842 case cff_op_hmoveto:
843 case cff_op_vstemhm:
844 case cff_op_rcurveline:
845 case cff_op_rlinecurve:
846 case cff_op_vvcurveto:
847 case cff_op_hhcurveto:
848 case cff_op_vhcurveto:
849 case cff_op_hvcurveto:
850 case cff_op_hflex:
851 case cff_op_flex:
852 case cff_op_hflex1:
853 case cff_op_flex1:
854 case cff_op_callsubr:
855 case cff_op_callgsubr:
856 goto MM_Error;
857
858 default:
859 break;
860 }
861 }
862
863 /* check arguments */
864 req_args = cff_argument_counts[op];
865 if ( req_args & CFF_COUNT_CHECK_WIDTH )
866 {
867 if ( num_args > 0 && decoder->read_width )
868 {
869 /* If `nominal_width' is non-zero, the number is really a */
870 /* difference against `nominal_width'. Else, the number here */
871 /* is truly a width, not a difference against `nominal_width'. */
872 /* If the font does not set `nominal_width', then */
873 /* `nominal_width' defaults to zero, and so we can set */
874 /* `glyph_width' to `nominal_width' plus number on the stack */
875 /* -- for either case. */
931 if ( num_args < req_args )
932 goto Stack_Underflow;
933 args -= req_args;
934 num_args -= req_args;
935
936 /* At this point, `args' points to the first argument of the */
937 /* operand in case `req_args' isn't zero. Otherwise, we have */
938 /* to adjust `args' manually. */
939
940 /* Note that we only pop arguments from the stack which we */
941 /* really need and can digest so that we can continue in case */
942 /* of superfluous stack elements. */
943
944 switch ( op )
945 {
946 case cff_op_hstem:
947 case cff_op_vstem:
948 case cff_op_hstemhm:
949 case cff_op_vstemhm:
950 /* the number of arguments is always even here */
951 FT_TRACE4((
952 op == cff_op_hstem ? " hstem\n" :
953 ( op == cff_op_vstem ? " vstem\n" :
954 ( op == cff_op_hstemhm ? " hstemhm\n" : " vstemhm\n" ) ) ));
955
956 if ( hinter )
957 hinter->stems( hinter->hints,
958 ( op == cff_op_hstem || op == cff_op_hstemhm ),
959 num_args / 2,
960 args - ( num_args & ~1 ) );
961
962 decoder->num_hints += num_args / 2;
963 args = stack;
964 break;
965
966 case cff_op_hintmask:
967 case cff_op_cntrmask:
968 FT_TRACE4(( op == cff_op_hintmask ? " hintmask" : " cntrmask" ));
969
970 /* implement vstem when needed -- */
971 /* the specification doesn't say it, but this also works */
972 /* with the 'cntrmask' operator */
973 /* */
974 if ( num_args > 0 )
975 {
976 if ( hinter )
977 hinter->stems( hinter->hints,
978 0,
979 num_args / 2,
980 args - ( num_args & ~1 ) );
981
982 decoder->num_hints += num_args / 2;
983 }
984
985 /* In a valid charstring there must be at least one byte */
986 /* after `hintmask' or `cntrmask' (e.g., for a `return' */
987 /* instruction). Additionally, there must be space for */
988 /* `num_hints' bits. */
1061 if ( num_args < 2 )
1062 goto Stack_Underflow;
1063
1064 args -= num_args & ~1;
1065 while ( args < decoder->top )
1066 {
1067 x = ADD_LONG( x, args[0] );
1068 y = ADD_LONG( y, args[1] );
1069 cff_builder_add_point( builder, x, y, 1 );
1070 args += 2;
1071 }
1072 args = stack;
1073 break;
1074
1075 case cff_op_hlineto:
1076 case cff_op_vlineto:
1077 {
1078 FT_Int phase = ( op == cff_op_hlineto );
1079
1080
1081 FT_TRACE4(( op == cff_op_hlineto ? " hlineto\n"
1082 : " vlineto\n" ));
1083
1084 if ( num_args < 0 )
1085 goto Stack_Underflow;
1086
1087 /* there exist subsetted fonts (found in PDFs) */
1088 /* which call `hlineto' without arguments */
1089 if ( num_args == 0 )
1090 break;
1091
1092 if ( cff_builder_start_point( builder, x, y ) ||
1093 cff_check_points( builder, num_args ) )
1094 goto Fail;
1095
1096 args = stack;
1097 while ( args < decoder->top )
1098 {
1099 if ( phase )
1100 x = ADD_LONG( x, args[0] );
1101 else
1102 y = ADD_LONG( y, args[0] );
1233 x = ADD_LONG( x, args[1] );
1234 y = ADD_LONG( y, args[2] );
1235 cff_builder_add_point( builder, x, y, 0 );
1236
1237 x = ADD_LONG( x, args[3] );
1238 cff_builder_add_point( builder, x, y, 1 );
1239
1240 args += 4;
1241 }
1242 args = stack;
1243 }
1244 break;
1245
1246 case cff_op_vhcurveto:
1247 case cff_op_hvcurveto:
1248 {
1249 FT_Int phase;
1250 FT_Int nargs;
1251
1252
1253 FT_TRACE4(( op == cff_op_vhcurveto ? " vhcurveto\n"
1254 : " hvcurveto\n" ));
1255
1256 if ( cff_builder_start_point( builder, x, y ) )
1257 goto Fail;
1258
1259 if ( num_args < 4 )
1260 goto Stack_Underflow;
1261
1262 /* if num_args isn't of the form 8n, 8n+1, 8n+4, or 8n+5, */
1263 /* we enforce it by clearing the second bit */
1264
1265 nargs = num_args & ~2;
1266
1267 args -= nargs;
1268 if ( cff_check_points( builder, ( nargs / 4 ) * 3 ) )
1269 goto Stack_Underflow;
1270
1271 phase = ( op == cff_op_hvcurveto );
1272
1273 while ( nargs >= 4 )
1274 {
1522 goto Fail;
1523
1524 /* record the starting point's x, y position for later use */
1525 start_x = x;
1526 start_y = y;
1527
1528 /* XXX: figure out whether this is supposed to be a horizontal */
1529 /* or vertical flex; the Type 2 specification is vague... */
1530
1531 temp = args;
1532
1533 /* grab up to the last argument */
1534 for ( count = 5; count > 0; count-- )
1535 {
1536 dx = ADD_LONG( dx, temp[0] );
1537 dy = ADD_LONG( dy, temp[1] );
1538 temp += 2;
1539 }
1540
1541 if ( dx < 0 )
1542 dx = -dx;
1543 if ( dy < 0 )
1544 dy = -dy;
1545
1546 /* strange test, but here it is... */
1547 horizontal = ( dx > dy );
1548
1549 for ( count = 5; count > 0; count-- )
1550 {
1551 x = ADD_LONG( x, args[0] );
1552 y = ADD_LONG( y, args[1] );
1553 cff_builder_add_point( builder, x, y,
1554 (FT_Bool)( count == 3 ) );
1555 args += 2;
1556 }
1557
1558 /* is last operand an x- or y-delta? */
1559 if ( horizontal )
1560 {
1561 x = ADD_LONG( x, args[0] );
1562 y = start_y;
1563 }
1564 else
1565 {
1566 x = start_x;
1567 y = ADD_LONG( y, args[0] );
1568 }
1569
1570 cff_builder_add_point( builder, x, y, 1 );
1571
1572 args = stack;
1573 break;
1574 }
1575
1576 case cff_op_flex:
1577 {
1578 FT_UInt count;
1579
1580
1581 FT_TRACE4(( " flex\n" ));
1582
1583 if ( cff_builder_start_point( builder, x, y ) ||
1584 cff_check_points( builder, 6 ) )
1585 goto Fail;
1586
1587 for ( count = 6; count > 0; count-- )
1588 {
1589 x = ADD_LONG( x, args[0] );
1590 y = ADD_LONG( y, args[1] );
1591 cff_builder_add_point( builder, x, y,
1592 (FT_Bool)( count == 4 || count == 1 ) );
1593 args += 2;
1594 }
1595
1596 args = stack;
1597 }
1598 break;
1599
1600 case cff_op_seac:
1601 FT_TRACE4(( " seac\n" ));
1602
1603 error = cff_operator_seac( decoder,
1604 args[0], args[1], args[2],
1605 (FT_Int)( args[3] >> 16 ),
1606 (FT_Int)( args[4] >> 16 ) );
1607
1608 /* add current outline to the glyph slot */
1609 FT_GlyphLoader_Add( builder->loader );
1610
1611 /* return now! */
1612 FT_TRACE4(( "\n" ));
1688 args++;
1689 break;
1690
1691 case cff_op_div:
1692 FT_TRACE4(( " div\n" ));
1693
1694 args[0] = FT_DivFix( args[0], args[1] );
1695 args++;
1696 break;
1697
1698 case cff_op_neg:
1699 FT_TRACE4(( " neg\n" ));
1700
1701 if ( args[0] == FT_LONG_MIN )
1702 args[0] = FT_LONG_MAX;
1703 args[0] = -args[0];
1704 args++;
1705 break;
1706
1707 case cff_op_random:
1708 FT_TRACE4(( " random\n" ));
1709
1710 /* only use the lower 16 bits of `random' */
1711 /* to generate a number in the range (0;1] */
1712 args[0] = (FT_Fixed)
1713 ( ( decoder->current_subfont->random & 0xFFFF ) + 1 );
1714 args++;
1715
1716 decoder->current_subfont->random =
1717 cff_random( decoder->current_subfont->random );
1718 break;
1719
1720 case cff_op_mul:
1721 FT_TRACE4(( " mul\n" ));
1722
1723 args[0] = FT_MulFix( args[0], args[1] );
1724 args++;
1725 break;
1726
1727 case cff_op_sqrt:
1728 FT_TRACE4(( " sqrt\n" ));
1729
1730 if ( args[0] > 0 )
1731 {
1732 FT_Fixed root = args[0];
1733 FT_Fixed new_root;
1734
1735
1736 for (;;)
1737 {
1738 new_root = ( root + FT_DivFix( args[0], root ) + 1 ) >> 1;
1739 if ( new_root == root )
1740 break;
1741 root = new_root;
1742 }
1743 args[0] = new_root;
1744 }
1745 else
1746 args[0] = 0;
1747 args++;
1748 break;
1749
1750 case cff_op_drop:
1783 }
1784 break;
1785
1786 case cff_op_roll:
1787 {
1788 FT_Int count = (FT_Int)( args[0] >> 16 );
1789 FT_Int idx = (FT_Int)( args[1] >> 16 );
1790
1791
1792 FT_TRACE4(( " roll\n" ));
1793
1794 if ( count <= 0 )
1795 count = 1;
1796
1797 args -= count;
1798 if ( args < stack )
1799 goto Stack_Underflow;
1800
1801 if ( idx >= 0 )
1802 {
1803 while ( idx > 0 )
1804 {
1805 FT_Fixed tmp = args[count - 1];
1806 FT_Int i;
1807
1808
1809 for ( i = count - 2; i >= 0; i-- )
1810 args[i + 1] = args[i];
1811 args[0] = tmp;
1812 idx--;
1813 }
1814 }
1815 else
1816 {
1817 while ( idx < 0 )
1818 {
1819 FT_Fixed tmp = args[0];
1820 FT_Int i;
1821
1822
1823 for ( i = 0; i < count - 1; i++ )
1824 args[i] = args[i + 1];
1825 args[count - 1] = tmp;
1826 idx++;
1827 }
1828 }
1829 args += count;
1830 }
1831 break;
1832
1833 case cff_op_dup:
1834 FT_TRACE4(( " dup\n" ));
1835
1836 args[1] = args[0];
1897 idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS &&
1898 count >= 0 && count <= num_axes )
1899 {
1900 FT_Int end, i;
1901
1902
1903 end = FT_MIN( idx + count, CFF_MAX_TRANS_ELEMENTS );
1904
1905 if ( idx < end )
1906 decoder->buildchar[idx] = 1 << 16;
1907
1908 for ( i = idx + 1; i < end; i++ )
1909 decoder->buildchar[i] = 0;
1910 }
1911 }
1912 break;
1913
1914 case cff_op_blend:
1915 /* this operator was removed from the Type2 specification */
1916 /* in version 16-March-2000 */
1917 {
1918 FT_Int num_results = (FT_Int)( args[0] >> 16 );
1919
1920
1921 FT_TRACE4(( " blend\n" ));
1922
1923 if ( num_results < 0 )
1924 goto Syntax_Error;
1925
1926 if ( num_results * (FT_Int)num_designs > num_args )
1927 goto Stack_Underflow;
1928
1929 /* since we currently don't handle interpolation of multiple */
1930 /* master fonts, return the `num_results' values of the */
1931 /* first master */
1932 args -= num_results * ( num_designs - 1 );
1933 num_args -= num_results * ( num_designs - 1 );
1934 }
1935 break;
1936
1937 case cff_op_dotsection:
1938 /* this operator is deprecated and ignored by the parser */
1939 FT_TRACE4(( " dotsection\n" ));
1940 break;
1941
1942 case cff_op_closepath:
1943 /* this is an invalid Type 2 operator; however, there */
1944 /* exist fonts which are incorrectly converted from probably */
1945 /* Type 1 to CFF, and some parsers seem to accept it */
1946
1947 FT_TRACE4(( " closepath (invalid op)\n" ));
1948
1949 args = stack;
1950 break;
1951
1952 case cff_op_hsbw:
1953 /* this is an invalid Type 2 operator; however, there */
1954 /* exist fonts which are incorrectly converted from probably */
1981 decoder->builder.left_bearing.y = args[1];
1982
1983 x = ADD_LONG( decoder->builder.pos_x, args[0] );
1984 y = ADD_LONG( decoder->builder.pos_y, args[1] );
1985 args = stack;
1986 break;
1987
1988 case cff_op_setcurrentpoint:
1989 /* this is an invalid Type 2 operator; however, there */
1990 /* exist fonts which are incorrectly converted from probably */
1991 /* Type 1 to CFF, and some parsers seem to accept it */
1992
1993 FT_TRACE4(( " setcurrentpoint (invalid op)\n" ));
1994
1995 x = ADD_LONG( decoder->builder.pos_x, args[0] );
1996 y = ADD_LONG( decoder->builder.pos_y, args[1] );
1997 args = stack;
1998 break;
1999
2000 case cff_op_callothersubr:
2001 /* this is an invalid Type 2 operator; however, there */
2002 /* exist fonts which are incorrectly converted from probably */
2003 /* Type 1 to CFF, and some parsers seem to accept it */
2004
2005 FT_TRACE4(( " callothersubr (invalid op)\n" ));
2006
2007 /* subsequent `pop' operands should add the arguments, */
2008 /* this is the implementation described for `unknown' other */
2009 /* subroutines in the Type1 spec. */
2010 /* */
2011 /* XXX Fix return arguments (see discussion below). */
2012 args -= 2 + ( args[-2] >> 16 );
2013 if ( args < stack )
2014 goto Stack_Underflow;
2015 break;
2016
2017 case cff_op_pop:
2018 /* this is an invalid Type 2 operator; however, there */
2019 /* exist fonts which are incorrectly converted from probably */
2020 /* Type 1 to CFF, and some parsers seem to accept it */
2021
2022 FT_TRACE4(( " pop (invalid op)\n" ));
2023
2024 /* XXX Increasing `args' is wrong: After a certain number of */
2025 /* `pop's we get a stack overflow. Reason for doing it is */
2026 /* code like this (actually found in a CFF font): */
2027 /* */
2028 /* 17 1 3 callothersubr */
2029 /* pop */
2030 /* callsubr */
2031 /* */
2032 /* Since we handle `callothersubr' as a no-op, and */
2033 /* `callsubr' needs at least one argument, `pop' can't be a */
2034 /* no-op too as it basically should be. */
2234 FT_TRACE4(( "cff_decoder_parse_charstrings:"
2235 " invalid opcode found in top DICT charstring\n"));
2236 return FT_THROW( Invalid_File_Format );
2237
2238 Syntax_Error:
2239 FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" ));
2240 return FT_THROW( Invalid_File_Format );
2241
2242 Stack_Underflow:
2243 FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" ));
2244 return FT_THROW( Too_Few_Arguments );
2245
2246 Stack_Overflow:
2247 FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" ));
2248 return FT_THROW( Stack_Overflow );
2249 }
2250
2251 #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
2252
2253
2254 /*************************************************************************/
2255 /* */
2256 /* <Function> */
2257 /* cff_decoder_init */
2258 /* */
2259 /* <Description> */
2260 /* Initializes a given glyph decoder. */
2261 /* */
2262 /* <InOut> */
2263 /* decoder :: A pointer to the glyph builder to initialize. */
2264 /* */
2265 /* <Input> */
2266 /* face :: The current face object. */
2267 /* */
2268 /* size :: The current size object. */
2269 /* */
2270 /* slot :: The current glyph object. */
2271 /* */
2272 /* hinting :: Whether hinting is active. */
2273 /* */
2274 /* hint_mode :: The hinting mode. */
2275 /* */
2276 FT_LOCAL_DEF( void )
2277 cff_decoder_init( CFF_Decoder* decoder,
2278 TT_Face face,
2279 CFF_Size size,
2280 CFF_GlyphSlot slot,
2281 FT_Bool hinting,
2282 FT_Render_Mode hint_mode,
2283 CFF_Decoder_Get_Glyph_Callback get_callback,
2284 CFF_Decoder_Free_Glyph_Callback free_callback )
2285 {
2286 CFF_Font cff = (CFF_Font)face->extra.data;
2287
2288
2289 /* clear everything */
2290 FT_ZERO( decoder );
2291
2292 /* initialize builder */
2293 cff_builder_init( &decoder->builder, face, size, slot, hinting );
2294
2295 /* initialize Type2 decoder */
|
1 /****************************************************************************
2 *
3 * cffdecode.c
4 *
5 * PostScript CFF (Type 2) decoding routines (body).
6 *
7 * Copyright (C) 2017-2019 by
8 * David Turner, Robert Wilhelm, and Werner Lemberg.
9 *
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.
15 *
16 */
17
18
19 #include <ft2build.h>
20 #include FT_FREETYPE_H
21 #include FT_INTERNAL_DEBUG_H
22 #include FT_INTERNAL_SERVICE_H
23 #include FT_SERVICE_CFF_TABLE_LOAD_H
24
25 #include "cffdecode.h"
26 #include "psobjs.h"
27
28 #include "psauxerr.h"
29
30
31 /**************************************************************************
32 *
33 * The macro FT_COMPONENT is used in trace mode. It is an implicit
34 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
35 * messages during execution.
36 */
37 #undef FT_COMPONENT
38 #define FT_COMPONENT cffdecode
39
40
41 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
42
43 typedef enum CFF_Operator_
44 {
45 cff_op_unknown = 0,
46
47 cff_op_rmoveto,
48 cff_op_hmoveto,
49 cff_op_vmoveto,
50
51 cff_op_rlineto,
52 cff_op_hlineto,
53 cff_op_vlineto,
54
55 cff_op_rrcurveto,
56 cff_op_hhcurveto,
57 cff_op_hvcurveto,
58 cff_op_rcurveline,
218 FT_Pos ady,
219 FT_Int bchar,
220 FT_Int achar )
221 {
222 FT_Error error;
223 CFF_Builder* builder = &decoder->builder;
224 FT_Int bchar_index, achar_index;
225 TT_Face face = decoder->builder.face;
226 FT_Vector left_bearing, advance;
227 FT_Byte* charstring;
228 FT_ULong charstring_len;
229 FT_Pos glyph_width;
230
231
232 if ( decoder->seac )
233 {
234 FT_ERROR(( "cff_operator_seac: invalid nested seac\n" ));
235 return FT_THROW( Syntax_Error );
236 }
237
238 adx = ADD_LONG( adx, decoder->builder.left_bearing.x );
239 ady = ADD_LONG( ady, decoder->builder.left_bearing.y );
240
241 #ifdef FT_CONFIG_OPTION_INCREMENTAL
242 /* Incremental fonts don't necessarily have valid charsets. */
243 /* They use the character code, not the glyph index, in this case. */
244 if ( face->root.internal->incremental_interface )
245 {
246 bchar_index = bchar;
247 achar_index = achar;
248 }
249 else
250 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
251 {
252 CFF_Font cff = (CFF_Font)(face->extra.data);
253
254
255 bchar_index = cff_lookup_glyph_by_stdcharcode( cff, bchar );
256 achar_index = cff_lookup_glyph_by_stdcharcode( cff, achar );
257 }
258
259 if ( bchar_index < 0 || achar_index < 0 )
361
362 Exit:
363 return error;
364 }
365
366 #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
367
368
369 /*************************************************************************/
370 /*************************************************************************/
371 /*************************************************************************/
372 /********** *********/
373 /********** *********/
374 /********** GENERIC CHARSTRING PARSING *********/
375 /********** *********/
376 /********** *********/
377 /*************************************************************************/
378 /*************************************************************************/
379 /*************************************************************************/
380
381 /**************************************************************************
382 *
383 * @Function:
384 * cff_compute_bias
385 *
386 * @Description:
387 * Computes the bias value in dependence of the number of glyph
388 * subroutines.
389 *
390 * @Input:
391 * in_charstring_type ::
392 * The `CharstringType' value of the top DICT
393 * dictionary.
394 *
395 * num_subrs ::
396 * The number of glyph subroutines.
397 *
398 * @Return:
399 * The bias value.
400 */
401 static FT_Int
402 cff_compute_bias( FT_Int in_charstring_type,
403 FT_UInt num_subrs )
404 {
405 FT_Int result;
406
407
408 if ( in_charstring_type == 1 )
409 result = 0;
410 else if ( num_subrs < 1240 )
411 result = 107;
412 else if ( num_subrs < 33900U )
413 result = 1131;
414 else
415 result = 32768U;
416
417 return result;
418 }
419
420
450 }
451 #endif
452
453 cffload = (FT_Service_CFFLoad)cff->cffload;
454
455 /* Get code to SID mapping from `cff_standard_encoding'. */
456 glyph_sid = cffload->get_standard_encoding( (FT_UInt)charcode );
457
458 for ( n = 0; n < cff->num_glyphs; n++ )
459 {
460 if ( cff->charset.sids[n] == glyph_sid )
461 return (FT_Int)n;
462 }
463
464 return -1;
465 }
466
467
468 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
469
470 /**************************************************************************
471 *
472 * @Function:
473 * cff_decoder_parse_charstrings
474 *
475 * @Description:
476 * Parses a given Type 2 charstrings program.
477 *
478 * @InOut:
479 * decoder ::
480 * The current Type 1 decoder.
481 *
482 * @Input:
483 * charstring_base ::
484 * The base of the charstring stream.
485 *
486 * charstring_len ::
487 * The length in bytes of the charstring stream.
488 *
489 * in_dict ::
490 * Set to 1 if function is called from top or
491 * private DICT (needed for Multiple Master CFFs).
492 *
493 * @Return:
494 * FreeType error code. 0 means success.
495 */
496 FT_LOCAL_DEF( FT_Error )
497 cff_decoder_parse_charstrings( CFF_Decoder* decoder,
498 FT_Byte* charstring_base,
499 FT_ULong charstring_len,
500 FT_Bool in_dict )
501 {
502 FT_Error error;
503 CFF_Decoder_Zone* zone;
504 FT_Byte* ip;
505 FT_Byte* limit;
506 CFF_Builder* builder = &decoder->builder;
507 FT_Pos x, y;
508 FT_Fixed* stack;
509 FT_Int charstring_type =
510 decoder->cff->top_font.font_dict.charstring_type;
511 FT_UShort num_designs =
512 decoder->cff->top_font.font_dict.num_designs;
513 FT_UShort num_axes =
514 decoder->cff->top_font.font_dict.num_axes;
515
533 zone->base = charstring_base;
534 limit = zone->limit = charstring_base + charstring_len;
535 ip = zone->cursor = zone->base;
536
537 error = FT_Err_Ok;
538
539 x = builder->pos_x;
540 y = builder->pos_y;
541
542 /* begin hints recording session, if any */
543 if ( hinter )
544 hinter->open( hinter->hints );
545
546 /* now execute loop */
547 while ( ip < limit )
548 {
549 CFF_Operator op;
550 FT_Byte v;
551
552
553 /*********************************************************************
554 *
555 * Decode operator or operand
556 */
557 v = *ip++;
558 if ( v >= 32 || v == 28 )
559 {
560 FT_Int shift = 16;
561 FT_Int32 val;
562
563
564 /* this is an operand, push it on the stack */
565
566 /* if we use shifts, all computations are done with unsigned */
567 /* values; the conversion to a signed value is the last step */
568 if ( v == 28 )
569 {
570 if ( ip + 1 >= limit )
571 goto Syntax_Error;
572 val = (FT_Short)( ( (FT_UShort)ip[0] << 8 ) | ip[1] );
573 ip += 2;
574 }
575 else if ( v < 247 )
576 val = (FT_Int32)v - 139;
843 case cff_op_vlineto:
844 case cff_op_rrcurveto:
845 case cff_op_hstemhm:
846 case cff_op_hintmask:
847 case cff_op_cntrmask:
848 case cff_op_rmoveto:
849 case cff_op_hmoveto:
850 case cff_op_vstemhm:
851 case cff_op_rcurveline:
852 case cff_op_rlinecurve:
853 case cff_op_vvcurveto:
854 case cff_op_hhcurveto:
855 case cff_op_vhcurveto:
856 case cff_op_hvcurveto:
857 case cff_op_hflex:
858 case cff_op_flex:
859 case cff_op_hflex1:
860 case cff_op_flex1:
861 case cff_op_callsubr:
862 case cff_op_callgsubr:
863 /* deprecated opcodes */
864 case cff_op_dotsection:
865 /* invalid Type 1 opcodes */
866 case cff_op_hsbw:
867 case cff_op_closepath:
868 case cff_op_callothersubr:
869 case cff_op_seac:
870 case cff_op_sbw:
871 case cff_op_setcurrentpoint:
872 goto MM_Error;
873
874 default:
875 break;
876 }
877 }
878
879 /* check arguments */
880 req_args = cff_argument_counts[op];
881 if ( req_args & CFF_COUNT_CHECK_WIDTH )
882 {
883 if ( num_args > 0 && decoder->read_width )
884 {
885 /* If `nominal_width' is non-zero, the number is really a */
886 /* difference against `nominal_width'. Else, the number here */
887 /* is truly a width, not a difference against `nominal_width'. */
888 /* If the font does not set `nominal_width', then */
889 /* `nominal_width' defaults to zero, and so we can set */
890 /* `glyph_width' to `nominal_width' plus number on the stack */
891 /* -- for either case. */
947 if ( num_args < req_args )
948 goto Stack_Underflow;
949 args -= req_args;
950 num_args -= req_args;
951
952 /* At this point, `args' points to the first argument of the */
953 /* operand in case `req_args' isn't zero. Otherwise, we have */
954 /* to adjust `args' manually. */
955
956 /* Note that we only pop arguments from the stack which we */
957 /* really need and can digest so that we can continue in case */
958 /* of superfluous stack elements. */
959
960 switch ( op )
961 {
962 case cff_op_hstem:
963 case cff_op_vstem:
964 case cff_op_hstemhm:
965 case cff_op_vstemhm:
966 /* the number of arguments is always even here */
967 FT_TRACE4(( "%s\n",
968 op == cff_op_hstem ? " hstem" :
969 ( op == cff_op_vstem ? " vstem" :
970 ( op == cff_op_hstemhm ? " hstemhm" : " vstemhm" ) ) ));
971
972 if ( hinter )
973 hinter->stems( hinter->hints,
974 ( op == cff_op_hstem || op == cff_op_hstemhm ),
975 num_args / 2,
976 args - ( num_args & ~1 ) );
977
978 decoder->num_hints += num_args / 2;
979 args = stack;
980 break;
981
982 case cff_op_hintmask:
983 case cff_op_cntrmask:
984 FT_TRACE4(( "%s", op == cff_op_hintmask ? " hintmask"
985 : " cntrmask" ));
986
987 /* implement vstem when needed -- */
988 /* the specification doesn't say it, but this also works */
989 /* with the 'cntrmask' operator */
990 /* */
991 if ( num_args > 0 )
992 {
993 if ( hinter )
994 hinter->stems( hinter->hints,
995 0,
996 num_args / 2,
997 args - ( num_args & ~1 ) );
998
999 decoder->num_hints += num_args / 2;
1000 }
1001
1002 /* In a valid charstring there must be at least one byte */
1003 /* after `hintmask' or `cntrmask' (e.g., for a `return' */
1004 /* instruction). Additionally, there must be space for */
1005 /* `num_hints' bits. */
1078 if ( num_args < 2 )
1079 goto Stack_Underflow;
1080
1081 args -= num_args & ~1;
1082 while ( args < decoder->top )
1083 {
1084 x = ADD_LONG( x, args[0] );
1085 y = ADD_LONG( y, args[1] );
1086 cff_builder_add_point( builder, x, y, 1 );
1087 args += 2;
1088 }
1089 args = stack;
1090 break;
1091
1092 case cff_op_hlineto:
1093 case cff_op_vlineto:
1094 {
1095 FT_Int phase = ( op == cff_op_hlineto );
1096
1097
1098 FT_TRACE4(( "%s\n", op == cff_op_hlineto ? " hlineto"
1099 : " vlineto" ));
1100
1101 if ( num_args < 0 )
1102 goto Stack_Underflow;
1103
1104 /* there exist subsetted fonts (found in PDFs) */
1105 /* which call `hlineto' without arguments */
1106 if ( num_args == 0 )
1107 break;
1108
1109 if ( cff_builder_start_point( builder, x, y ) ||
1110 cff_check_points( builder, num_args ) )
1111 goto Fail;
1112
1113 args = stack;
1114 while ( args < decoder->top )
1115 {
1116 if ( phase )
1117 x = ADD_LONG( x, args[0] );
1118 else
1119 y = ADD_LONG( y, args[0] );
1250 x = ADD_LONG( x, args[1] );
1251 y = ADD_LONG( y, args[2] );
1252 cff_builder_add_point( builder, x, y, 0 );
1253
1254 x = ADD_LONG( x, args[3] );
1255 cff_builder_add_point( builder, x, y, 1 );
1256
1257 args += 4;
1258 }
1259 args = stack;
1260 }
1261 break;
1262
1263 case cff_op_vhcurveto:
1264 case cff_op_hvcurveto:
1265 {
1266 FT_Int phase;
1267 FT_Int nargs;
1268
1269
1270 FT_TRACE4(( "%s\n", op == cff_op_vhcurveto ? " vhcurveto"
1271 : " hvcurveto" ));
1272
1273 if ( cff_builder_start_point( builder, x, y ) )
1274 goto Fail;
1275
1276 if ( num_args < 4 )
1277 goto Stack_Underflow;
1278
1279 /* if num_args isn't of the form 8n, 8n+1, 8n+4, or 8n+5, */
1280 /* we enforce it by clearing the second bit */
1281
1282 nargs = num_args & ~2;
1283
1284 args -= nargs;
1285 if ( cff_check_points( builder, ( nargs / 4 ) * 3 ) )
1286 goto Stack_Underflow;
1287
1288 phase = ( op == cff_op_hvcurveto );
1289
1290 while ( nargs >= 4 )
1291 {
1539 goto Fail;
1540
1541 /* record the starting point's x, y position for later use */
1542 start_x = x;
1543 start_y = y;
1544
1545 /* XXX: figure out whether this is supposed to be a horizontal */
1546 /* or vertical flex; the Type 2 specification is vague... */
1547
1548 temp = args;
1549
1550 /* grab up to the last argument */
1551 for ( count = 5; count > 0; count-- )
1552 {
1553 dx = ADD_LONG( dx, temp[0] );
1554 dy = ADD_LONG( dy, temp[1] );
1555 temp += 2;
1556 }
1557
1558 if ( dx < 0 )
1559 dx = NEG_LONG( dx );
1560 if ( dy < 0 )
1561 dy = NEG_LONG( dy );
1562
1563 /* strange test, but here it is... */
1564 horizontal = ( dx > dy );
1565
1566 for ( count = 5; count > 0; count-- )
1567 {
1568 x = ADD_LONG( x, args[0] );
1569 y = ADD_LONG( y, args[1] );
1570 cff_builder_add_point( builder, x, y,
1571 FT_BOOL( count == 3 ) );
1572 args += 2;
1573 }
1574
1575 /* is last operand an x- or y-delta? */
1576 if ( horizontal )
1577 {
1578 x = ADD_LONG( x, args[0] );
1579 y = start_y;
1580 }
1581 else
1582 {
1583 x = start_x;
1584 y = ADD_LONG( y, args[0] );
1585 }
1586
1587 cff_builder_add_point( builder, x, y, 1 );
1588
1589 args = stack;
1590 break;
1591 }
1592
1593 case cff_op_flex:
1594 {
1595 FT_UInt count;
1596
1597
1598 FT_TRACE4(( " flex\n" ));
1599
1600 if ( cff_builder_start_point( builder, x, y ) ||
1601 cff_check_points( builder, 6 ) )
1602 goto Fail;
1603
1604 for ( count = 6; count > 0; count-- )
1605 {
1606 x = ADD_LONG( x, args[0] );
1607 y = ADD_LONG( y, args[1] );
1608 cff_builder_add_point( builder, x, y,
1609 FT_BOOL( count == 4 || count == 1 ) );
1610 args += 2;
1611 }
1612
1613 args = stack;
1614 }
1615 break;
1616
1617 case cff_op_seac:
1618 FT_TRACE4(( " seac\n" ));
1619
1620 error = cff_operator_seac( decoder,
1621 args[0], args[1], args[2],
1622 (FT_Int)( args[3] >> 16 ),
1623 (FT_Int)( args[4] >> 16 ) );
1624
1625 /* add current outline to the glyph slot */
1626 FT_GlyphLoader_Add( builder->loader );
1627
1628 /* return now! */
1629 FT_TRACE4(( "\n" ));
1705 args++;
1706 break;
1707
1708 case cff_op_div:
1709 FT_TRACE4(( " div\n" ));
1710
1711 args[0] = FT_DivFix( args[0], args[1] );
1712 args++;
1713 break;
1714
1715 case cff_op_neg:
1716 FT_TRACE4(( " neg\n" ));
1717
1718 if ( args[0] == FT_LONG_MIN )
1719 args[0] = FT_LONG_MAX;
1720 args[0] = -args[0];
1721 args++;
1722 break;
1723
1724 case cff_op_random:
1725 {
1726 FT_UInt32* randval = in_dict ? &decoder->cff->top_font.random
1727 : &decoder->current_subfont->random;
1728
1729
1730 FT_TRACE4(( " random\n" ));
1731
1732 /* only use the lower 16 bits of `random' */
1733 /* to generate a number in the range (0;1] */
1734 args[0] = (FT_Fixed)( ( *randval & 0xFFFF ) + 1 );
1735 args++;
1736
1737 *randval = cff_random( *randval );
1738 }
1739 break;
1740
1741 case cff_op_mul:
1742 FT_TRACE4(( " mul\n" ));
1743
1744 args[0] = FT_MulFix( args[0], args[1] );
1745 args++;
1746 break;
1747
1748 case cff_op_sqrt:
1749 FT_TRACE4(( " sqrt\n" ));
1750
1751 /* without upper limit the loop below might not finish */
1752 if ( args[0] > 0x7FFFFFFFL )
1753 args[0] = 46341;
1754 else if ( args[0] > 0 )
1755 {
1756 FT_Fixed root = args[0];
1757 FT_Fixed new_root;
1758
1759
1760 for (;;)
1761 {
1762 new_root = ( root + FT_DivFix( args[0], root ) + 1 ) >> 1;
1763 if ( new_root == root )
1764 break;
1765 root = new_root;
1766 }
1767 args[0] = new_root;
1768 }
1769 else
1770 args[0] = 0;
1771 args++;
1772 break;
1773
1774 case cff_op_drop:
1807 }
1808 break;
1809
1810 case cff_op_roll:
1811 {
1812 FT_Int count = (FT_Int)( args[0] >> 16 );
1813 FT_Int idx = (FT_Int)( args[1] >> 16 );
1814
1815
1816 FT_TRACE4(( " roll\n" ));
1817
1818 if ( count <= 0 )
1819 count = 1;
1820
1821 args -= count;
1822 if ( args < stack )
1823 goto Stack_Underflow;
1824
1825 if ( idx >= 0 )
1826 {
1827 idx = idx % count;
1828 while ( idx > 0 )
1829 {
1830 FT_Fixed tmp = args[count - 1];
1831 FT_Int i;
1832
1833
1834 for ( i = count - 2; i >= 0; i-- )
1835 args[i + 1] = args[i];
1836 args[0] = tmp;
1837 idx--;
1838 }
1839 }
1840 else
1841 {
1842 /* before C99 it is implementation-defined whether */
1843 /* the result of `%' is negative if the first operand */
1844 /* is negative */
1845 idx = -( NEG_INT( idx ) % count );
1846 while ( idx < 0 )
1847 {
1848 FT_Fixed tmp = args[0];
1849 FT_Int i;
1850
1851
1852 for ( i = 0; i < count - 1; i++ )
1853 args[i] = args[i + 1];
1854 args[count - 1] = tmp;
1855 idx++;
1856 }
1857 }
1858 args += count;
1859 }
1860 break;
1861
1862 case cff_op_dup:
1863 FT_TRACE4(( " dup\n" ));
1864
1865 args[1] = args[0];
1926 idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS &&
1927 count >= 0 && count <= num_axes )
1928 {
1929 FT_Int end, i;
1930
1931
1932 end = FT_MIN( idx + count, CFF_MAX_TRANS_ELEMENTS );
1933
1934 if ( idx < end )
1935 decoder->buildchar[idx] = 1 << 16;
1936
1937 for ( i = idx + 1; i < end; i++ )
1938 decoder->buildchar[i] = 0;
1939 }
1940 }
1941 break;
1942
1943 case cff_op_blend:
1944 /* this operator was removed from the Type2 specification */
1945 /* in version 16-March-2000 */
1946 if ( num_designs )
1947 {
1948 FT_Int num_results = (FT_Int)( args[0] >> 16 );
1949
1950
1951 FT_TRACE4(( " blend\n" ));
1952
1953 if ( num_results < 0 )
1954 goto Syntax_Error;
1955
1956 if ( num_results > num_args ||
1957 num_results * (FT_Int)num_designs > num_args )
1958 goto Stack_Underflow;
1959
1960 /* since we currently don't handle interpolation of multiple */
1961 /* master fonts, return the `num_results' values of the */
1962 /* first master */
1963 args -= num_results * ( num_designs - 1 );
1964 num_args -= num_results * ( num_designs - 1 );
1965 }
1966 else
1967 goto Syntax_Error;
1968 break;
1969
1970 case cff_op_dotsection:
1971 /* this operator is deprecated and ignored by the parser */
1972 FT_TRACE4(( " dotsection\n" ));
1973 break;
1974
1975 case cff_op_closepath:
1976 /* this is an invalid Type 2 operator; however, there */
1977 /* exist fonts which are incorrectly converted from probably */
1978 /* Type 1 to CFF, and some parsers seem to accept it */
1979
1980 FT_TRACE4(( " closepath (invalid op)\n" ));
1981
1982 args = stack;
1983 break;
1984
1985 case cff_op_hsbw:
1986 /* this is an invalid Type 2 operator; however, there */
1987 /* exist fonts which are incorrectly converted from probably */
2014 decoder->builder.left_bearing.y = args[1];
2015
2016 x = ADD_LONG( decoder->builder.pos_x, args[0] );
2017 y = ADD_LONG( decoder->builder.pos_y, args[1] );
2018 args = stack;
2019 break;
2020
2021 case cff_op_setcurrentpoint:
2022 /* this is an invalid Type 2 operator; however, there */
2023 /* exist fonts which are incorrectly converted from probably */
2024 /* Type 1 to CFF, and some parsers seem to accept it */
2025
2026 FT_TRACE4(( " setcurrentpoint (invalid op)\n" ));
2027
2028 x = ADD_LONG( decoder->builder.pos_x, args[0] );
2029 y = ADD_LONG( decoder->builder.pos_y, args[1] );
2030 args = stack;
2031 break;
2032
2033 case cff_op_callothersubr:
2034 {
2035 FT_Fixed arg;
2036
2037
2038 /* this is an invalid Type 2 operator; however, there */
2039 /* exist fonts which are incorrectly converted from */
2040 /* probably Type 1 to CFF, and some parsers seem to accept */
2041 /* it */
2042
2043 FT_TRACE4(( " callothersubr (invalid op)\n" ));
2044
2045 /* subsequent `pop' operands should add the arguments, */
2046 /* this is the implementation described for `unknown' */
2047 /* other subroutines in the Type1 spec. */
2048 /* */
2049 /* XXX Fix return arguments (see discussion below). */
2050
2051 arg = 2 + ( args[-2] >> 16 );
2052 if ( arg >= CFF_MAX_OPERANDS )
2053 goto Stack_Underflow;
2054
2055 args -= arg;
2056 if ( args < stack )
2057 goto Stack_Underflow;
2058 }
2059 break;
2060
2061 case cff_op_pop:
2062 /* this is an invalid Type 2 operator; however, there */
2063 /* exist fonts which are incorrectly converted from probably */
2064 /* Type 1 to CFF, and some parsers seem to accept it */
2065
2066 FT_TRACE4(( " pop (invalid op)\n" ));
2067
2068 /* XXX Increasing `args' is wrong: After a certain number of */
2069 /* `pop's we get a stack overflow. Reason for doing it is */
2070 /* code like this (actually found in a CFF font): */
2071 /* */
2072 /* 17 1 3 callothersubr */
2073 /* pop */
2074 /* callsubr */
2075 /* */
2076 /* Since we handle `callothersubr' as a no-op, and */
2077 /* `callsubr' needs at least one argument, `pop' can't be a */
2078 /* no-op too as it basically should be. */
2278 FT_TRACE4(( "cff_decoder_parse_charstrings:"
2279 " invalid opcode found in top DICT charstring\n"));
2280 return FT_THROW( Invalid_File_Format );
2281
2282 Syntax_Error:
2283 FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" ));
2284 return FT_THROW( Invalid_File_Format );
2285
2286 Stack_Underflow:
2287 FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" ));
2288 return FT_THROW( Too_Few_Arguments );
2289
2290 Stack_Overflow:
2291 FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" ));
2292 return FT_THROW( Stack_Overflow );
2293 }
2294
2295 #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
2296
2297
2298 /**************************************************************************
2299 *
2300 * @Function:
2301 * cff_decoder_init
2302 *
2303 * @Description:
2304 * Initializes a given glyph decoder.
2305 *
2306 * @InOut:
2307 * decoder ::
2308 * A pointer to the glyph builder to initialize.
2309 *
2310 * @Input:
2311 * face ::
2312 * The current face object.
2313 *
2314 * size ::
2315 * The current size object.
2316 *
2317 * slot ::
2318 * The current glyph object.
2319 *
2320 * hinting ::
2321 * Whether hinting is active.
2322 *
2323 * hint_mode ::
2324 * The hinting mode.
2325 */
2326 FT_LOCAL_DEF( void )
2327 cff_decoder_init( CFF_Decoder* decoder,
2328 TT_Face face,
2329 CFF_Size size,
2330 CFF_GlyphSlot slot,
2331 FT_Bool hinting,
2332 FT_Render_Mode hint_mode,
2333 CFF_Decoder_Get_Glyph_Callback get_callback,
2334 CFF_Decoder_Free_Glyph_Callback free_callback )
2335 {
2336 CFF_Font cff = (CFF_Font)face->extra.data;
2337
2338
2339 /* clear everything */
2340 FT_ZERO( decoder );
2341
2342 /* initialize builder */
2343 cff_builder_init( &decoder->builder, face, size, slot, hinting );
2344
2345 /* initialize Type2 decoder */
|