1 /***************************************************************************/ |
1 /**************************************************************************** |
2 /* */ |
2 * |
3 /* cffdecode.c */ |
3 * cffdecode.c |
4 /* */ |
4 * |
5 /* PostScript CFF (Type 2) decoding routines (body). */ |
5 * PostScript CFF (Type 2) decoding routines (body). |
6 /* */ |
6 * |
7 /* Copyright 2017-2018 by */ |
7 * Copyright (C) 2017-2019 by |
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
8 * David Turner, Robert Wilhelm, and Werner Lemberg. |
9 /* */ |
9 * |
10 /* This file is part of the FreeType project, and may only be used, */ |
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 */ |
11 * modified, and distributed under the terms of the FreeType project |
12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
12 * license, LICENSE.TXT. By continuing to use, modify, or distribute |
13 /* this file you indicate that you have read the license and */ |
13 * this file you indicate that you have read the license and |
14 /* understand and accept it fully. */ |
14 * understand and accept it fully. |
15 /* */ |
15 * |
16 /***************************************************************************/ |
16 */ |
17 |
17 |
18 |
18 |
19 #include <ft2build.h> |
19 #include <ft2build.h> |
20 #include FT_FREETYPE_H |
20 #include FT_FREETYPE_H |
21 #include FT_INTERNAL_DEBUG_H |
21 #include FT_INTERNAL_DEBUG_H |
26 #include "psobjs.h" |
26 #include "psobjs.h" |
27 |
27 |
28 #include "psauxerr.h" |
28 #include "psauxerr.h" |
29 |
29 |
30 |
30 |
31 /*************************************************************************/ |
31 /************************************************************************** |
32 /* */ |
32 * |
33 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ |
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 */ |
34 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log |
35 /* messages during execution. */ |
35 * messages during execution. |
36 /* */ |
36 */ |
37 #undef FT_COMPONENT |
37 #undef FT_COMPONENT |
38 #define FT_COMPONENT trace_cffdecode |
38 #define FT_COMPONENT cffdecode |
39 |
39 |
40 |
40 |
41 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE |
41 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE |
42 |
42 |
43 typedef enum CFF_Operator_ |
43 typedef enum CFF_Operator_ |
233 { |
233 { |
234 FT_ERROR(( "cff_operator_seac: invalid nested seac\n" )); |
234 FT_ERROR(( "cff_operator_seac: invalid nested seac\n" )); |
235 return FT_THROW( Syntax_Error ); |
235 return FT_THROW( Syntax_Error ); |
236 } |
236 } |
237 |
237 |
238 adx += decoder->builder.left_bearing.x; |
238 adx = ADD_LONG( adx, decoder->builder.left_bearing.x ); |
239 ady += decoder->builder.left_bearing.y; |
239 ady = ADD_LONG( ady, decoder->builder.left_bearing.y ); |
240 |
240 |
241 #ifdef FT_CONFIG_OPTION_INCREMENTAL |
241 #ifdef FT_CONFIG_OPTION_INCREMENTAL |
242 /* Incremental fonts don't necessarily have valid charsets. */ |
242 /* Incremental fonts don't necessarily have valid charsets. */ |
243 /* They use the character code, not the glyph index, in this case. */ |
243 /* They use the character code, not the glyph index, in this case. */ |
244 if ( face->root.internal->incremental_interface ) |
244 if ( face->root.internal->incremental_interface ) |
376 /********** *********/ |
376 /********** *********/ |
377 /*************************************************************************/ |
377 /*************************************************************************/ |
378 /*************************************************************************/ |
378 /*************************************************************************/ |
379 /*************************************************************************/ |
379 /*************************************************************************/ |
380 |
380 |
381 /*************************************************************************/ |
381 /************************************************************************** |
382 /* */ |
382 * |
383 /* <Function> */ |
383 * @Function: |
384 /* cff_compute_bias */ |
384 * cff_compute_bias |
385 /* */ |
385 * |
386 /* <Description> */ |
386 * @Description: |
387 /* Computes the bias value in dependence of the number of glyph */ |
387 * Computes the bias value in dependence of the number of glyph |
388 /* subroutines. */ |
388 * subroutines. |
389 /* */ |
389 * |
390 /* <Input> */ |
390 * @Input: |
391 /* in_charstring_type :: The `CharstringType' value of the top DICT */ |
391 * in_charstring_type :: |
392 /* dictionary. */ |
392 * The `CharstringType' value of the top DICT |
393 /* */ |
393 * dictionary. |
394 /* num_subrs :: The number of glyph subroutines. */ |
394 * |
395 /* */ |
395 * num_subrs :: |
396 /* <Return> */ |
396 * The number of glyph subroutines. |
397 /* The bias value. */ |
397 * |
|
398 * @Return: |
|
399 * The bias value. |
|
400 */ |
398 static FT_Int |
401 static FT_Int |
399 cff_compute_bias( FT_Int in_charstring_type, |
402 cff_compute_bias( FT_Int in_charstring_type, |
400 FT_UInt num_subrs ) |
403 FT_UInt num_subrs ) |
401 { |
404 { |
402 FT_Int result; |
405 FT_Int result; |
462 } |
465 } |
463 |
466 |
464 |
467 |
465 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE |
468 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE |
466 |
469 |
467 /*************************************************************************/ |
470 /************************************************************************** |
468 /* */ |
471 * |
469 /* <Function> */ |
472 * @Function: |
470 /* cff_decoder_parse_charstrings */ |
473 * cff_decoder_parse_charstrings |
471 /* */ |
474 * |
472 /* <Description> */ |
475 * @Description: |
473 /* Parses a given Type 2 charstrings program. */ |
476 * Parses a given Type 2 charstrings program. |
474 /* */ |
477 * |
475 /* <InOut> */ |
478 * @InOut: |
476 /* decoder :: The current Type 1 decoder. */ |
479 * decoder :: |
477 /* */ |
480 * The current Type 1 decoder. |
478 /* <Input> */ |
481 * |
479 /* charstring_base :: The base of the charstring stream. */ |
482 * @Input: |
480 /* */ |
483 * charstring_base :: |
481 /* charstring_len :: The length in bytes of the charstring stream. */ |
484 * The base of the charstring stream. |
482 /* */ |
485 * |
483 /* in_dict :: Set to 1 if function is called from top or */ |
486 * charstring_len :: |
484 /* private DICT (needed for Multiple Master CFFs). */ |
487 * The length in bytes of the charstring stream. |
485 /* */ |
488 * |
486 /* <Return> */ |
489 * in_dict :: |
487 /* FreeType error code. 0 means success. */ |
490 * Set to 1 if function is called from top or |
488 /* */ |
491 * private DICT (needed for Multiple Master CFFs). |
|
492 * |
|
493 * @Return: |
|
494 * FreeType error code. 0 means success. |
|
495 */ |
489 FT_LOCAL_DEF( FT_Error ) |
496 FT_LOCAL_DEF( FT_Error ) |
490 cff_decoder_parse_charstrings( CFF_Decoder* decoder, |
497 cff_decoder_parse_charstrings( CFF_Decoder* decoder, |
491 FT_Byte* charstring_base, |
498 FT_Byte* charstring_base, |
492 FT_ULong charstring_len, |
499 FT_ULong charstring_len, |
493 FT_Bool in_dict ) |
500 FT_Bool in_dict ) |
946 case cff_op_hstem: |
962 case cff_op_hstem: |
947 case cff_op_vstem: |
963 case cff_op_vstem: |
948 case cff_op_hstemhm: |
964 case cff_op_hstemhm: |
949 case cff_op_vstemhm: |
965 case cff_op_vstemhm: |
950 /* the number of arguments is always even here */ |
966 /* the number of arguments is always even here */ |
951 FT_TRACE4(( |
967 FT_TRACE4(( "%s\n", |
952 op == cff_op_hstem ? " hstem\n" : |
968 op == cff_op_hstem ? " hstem" : |
953 ( op == cff_op_vstem ? " vstem\n" : |
969 ( op == cff_op_vstem ? " vstem" : |
954 ( op == cff_op_hstemhm ? " hstemhm\n" : " vstemhm\n" ) ) )); |
970 ( op == cff_op_hstemhm ? " hstemhm" : " vstemhm" ) ) )); |
955 |
971 |
956 if ( hinter ) |
972 if ( hinter ) |
957 hinter->stems( hinter->hints, |
973 hinter->stems( hinter->hints, |
958 ( op == cff_op_hstem || op == cff_op_hstemhm ), |
974 ( op == cff_op_hstem || op == cff_op_hstemhm ), |
959 num_args / 2, |
975 num_args / 2, |
963 args = stack; |
979 args = stack; |
964 break; |
980 break; |
965 |
981 |
966 case cff_op_hintmask: |
982 case cff_op_hintmask: |
967 case cff_op_cntrmask: |
983 case cff_op_cntrmask: |
968 FT_TRACE4(( op == cff_op_hintmask ? " hintmask" : " cntrmask" )); |
984 FT_TRACE4(( "%s", op == cff_op_hintmask ? " hintmask" |
|
985 : " cntrmask" )); |
969 |
986 |
970 /* implement vstem when needed -- */ |
987 /* implement vstem when needed -- */ |
971 /* the specification doesn't say it, but this also works */ |
988 /* the specification doesn't say it, but this also works */ |
972 /* with the 'cntrmask' operator */ |
989 /* with the 'cntrmask' operator */ |
973 /* */ |
990 /* */ |
1076 case cff_op_vlineto: |
1093 case cff_op_vlineto: |
1077 { |
1094 { |
1078 FT_Int phase = ( op == cff_op_hlineto ); |
1095 FT_Int phase = ( op == cff_op_hlineto ); |
1079 |
1096 |
1080 |
1097 |
1081 FT_TRACE4(( op == cff_op_hlineto ? " hlineto\n" |
1098 FT_TRACE4(( "%s\n", op == cff_op_hlineto ? " hlineto" |
1082 : " vlineto\n" )); |
1099 : " vlineto" )); |
1083 |
1100 |
1084 if ( num_args < 0 ) |
1101 if ( num_args < 0 ) |
1085 goto Stack_Underflow; |
1102 goto Stack_Underflow; |
1086 |
1103 |
1087 /* there exist subsetted fonts (found in PDFs) */ |
1104 /* there exist subsetted fonts (found in PDFs) */ |
1537 dy = ADD_LONG( dy, temp[1] ); |
1554 dy = ADD_LONG( dy, temp[1] ); |
1538 temp += 2; |
1555 temp += 2; |
1539 } |
1556 } |
1540 |
1557 |
1541 if ( dx < 0 ) |
1558 if ( dx < 0 ) |
1542 dx = -dx; |
1559 dx = NEG_LONG( dx ); |
1543 if ( dy < 0 ) |
1560 if ( dy < 0 ) |
1544 dy = -dy; |
1561 dy = NEG_LONG( dy ); |
1545 |
1562 |
1546 /* strange test, but here it is... */ |
1563 /* strange test, but here it is... */ |
1547 horizontal = ( dx > dy ); |
1564 horizontal = ( dx > dy ); |
1548 |
1565 |
1549 for ( count = 5; count > 0; count-- ) |
1566 for ( count = 5; count > 0; count-- ) |
1550 { |
1567 { |
1551 x = ADD_LONG( x, args[0] ); |
1568 x = ADD_LONG( x, args[0] ); |
1552 y = ADD_LONG( y, args[1] ); |
1569 y = ADD_LONG( y, args[1] ); |
1553 cff_builder_add_point( builder, x, y, |
1570 cff_builder_add_point( builder, x, y, |
1554 (FT_Bool)( count == 3 ) ); |
1571 FT_BOOL( count == 3 ) ); |
1555 args += 2; |
1572 args += 2; |
1556 } |
1573 } |
1557 |
1574 |
1558 /* is last operand an x- or y-delta? */ |
1575 /* is last operand an x- or y-delta? */ |
1559 if ( horizontal ) |
1576 if ( horizontal ) |
1587 for ( count = 6; count > 0; count-- ) |
1604 for ( count = 6; count > 0; count-- ) |
1588 { |
1605 { |
1589 x = ADD_LONG( x, args[0] ); |
1606 x = ADD_LONG( x, args[0] ); |
1590 y = ADD_LONG( y, args[1] ); |
1607 y = ADD_LONG( y, args[1] ); |
1591 cff_builder_add_point( builder, x, y, |
1608 cff_builder_add_point( builder, x, y, |
1592 (FT_Bool)( count == 4 || count == 1 ) ); |
1609 FT_BOOL( count == 4 || count == 1 ) ); |
1593 args += 2; |
1610 args += 2; |
1594 } |
1611 } |
1595 |
1612 |
1596 args = stack; |
1613 args = stack; |
1597 } |
1614 } |
1703 args[0] = -args[0]; |
1720 args[0] = -args[0]; |
1704 args++; |
1721 args++; |
1705 break; |
1722 break; |
1706 |
1723 |
1707 case cff_op_random: |
1724 case cff_op_random: |
1708 FT_TRACE4(( " random\n" )); |
1725 { |
1709 |
1726 FT_UInt32* randval = in_dict ? &decoder->cff->top_font.random |
1710 /* only use the lower 16 bits of `random' */ |
1727 : &decoder->current_subfont->random; |
1711 /* to generate a number in the range (0;1] */ |
1728 |
1712 args[0] = (FT_Fixed) |
1729 |
1713 ( ( decoder->current_subfont->random & 0xFFFF ) + 1 ); |
1730 FT_TRACE4(( " random\n" )); |
1714 args++; |
1731 |
1715 |
1732 /* only use the lower 16 bits of `random' */ |
1716 decoder->current_subfont->random = |
1733 /* to generate a number in the range (0;1] */ |
1717 cff_random( decoder->current_subfont->random ); |
1734 args[0] = (FT_Fixed)( ( *randval & 0xFFFF ) + 1 ); |
|
1735 args++; |
|
1736 |
|
1737 *randval = cff_random( *randval ); |
|
1738 } |
1718 break; |
1739 break; |
1719 |
1740 |
1720 case cff_op_mul: |
1741 case cff_op_mul: |
1721 FT_TRACE4(( " mul\n" )); |
1742 FT_TRACE4(( " mul\n" )); |
1722 |
1743 |
1912 break; |
1941 break; |
1913 |
1942 |
1914 case cff_op_blend: |
1943 case cff_op_blend: |
1915 /* this operator was removed from the Type2 specification */ |
1944 /* this operator was removed from the Type2 specification */ |
1916 /* in version 16-March-2000 */ |
1945 /* in version 16-March-2000 */ |
|
1946 if ( num_designs ) |
1917 { |
1947 { |
1918 FT_Int num_results = (FT_Int)( args[0] >> 16 ); |
1948 FT_Int num_results = (FT_Int)( args[0] >> 16 ); |
1919 |
1949 |
1920 |
1950 |
1921 FT_TRACE4(( " blend\n" )); |
1951 FT_TRACE4(( " blend\n" )); |
1922 |
1952 |
1923 if ( num_results < 0 ) |
1953 if ( num_results < 0 ) |
1924 goto Syntax_Error; |
1954 goto Syntax_Error; |
1925 |
1955 |
1926 if ( num_results * (FT_Int)num_designs > num_args ) |
1956 if ( num_results > num_args || |
|
1957 num_results * (FT_Int)num_designs > num_args ) |
1927 goto Stack_Underflow; |
1958 goto Stack_Underflow; |
1928 |
1959 |
1929 /* since we currently don't handle interpolation of multiple */ |
1960 /* since we currently don't handle interpolation of multiple */ |
1930 /* master fonts, return the `num_results' values of the */ |
1961 /* master fonts, return the `num_results' values of the */ |
1931 /* first master */ |
1962 /* first master */ |
1932 args -= num_results * ( num_designs - 1 ); |
1963 args -= num_results * ( num_designs - 1 ); |
1933 num_args -= num_results * ( num_designs - 1 ); |
1964 num_args -= num_results * ( num_designs - 1 ); |
1934 } |
1965 } |
|
1966 else |
|
1967 goto Syntax_Error; |
1935 break; |
1968 break; |
1936 |
1969 |
1937 case cff_op_dotsection: |
1970 case cff_op_dotsection: |
1938 /* this operator is deprecated and ignored by the parser */ |
1971 /* this operator is deprecated and ignored by the parser */ |
1939 FT_TRACE4(( " dotsection\n" )); |
1972 FT_TRACE4(( " dotsection\n" )); |
1996 y = ADD_LONG( decoder->builder.pos_y, args[1] ); |
2029 y = ADD_LONG( decoder->builder.pos_y, args[1] ); |
1997 args = stack; |
2030 args = stack; |
1998 break; |
2031 break; |
1999 |
2032 |
2000 case cff_op_callothersubr: |
2033 case cff_op_callothersubr: |
2001 /* this is an invalid Type 2 operator; however, there */ |
2034 { |
2002 /* exist fonts which are incorrectly converted from probably */ |
2035 FT_Fixed arg; |
2003 /* Type 1 to CFF, and some parsers seem to accept it */ |
2036 |
2004 |
2037 |
2005 FT_TRACE4(( " callothersubr (invalid op)\n" )); |
2038 /* this is an invalid Type 2 operator; however, there */ |
2006 |
2039 /* exist fonts which are incorrectly converted from */ |
2007 /* subsequent `pop' operands should add the arguments, */ |
2040 /* probably Type 1 to CFF, and some parsers seem to accept */ |
2008 /* this is the implementation described for `unknown' other */ |
2041 /* it */ |
2009 /* subroutines in the Type1 spec. */ |
2042 |
2010 /* */ |
2043 FT_TRACE4(( " callothersubr (invalid op)\n" )); |
2011 /* XXX Fix return arguments (see discussion below). */ |
2044 |
2012 args -= 2 + ( args[-2] >> 16 ); |
2045 /* subsequent `pop' operands should add the arguments, */ |
2013 if ( args < stack ) |
2046 /* this is the implementation described for `unknown' */ |
2014 goto Stack_Underflow; |
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 } |
2015 break; |
2059 break; |
2016 |
2060 |
2017 case cff_op_pop: |
2061 case cff_op_pop: |
2018 /* this is an invalid Type 2 operator; however, there */ |
2062 /* this is an invalid Type 2 operator; however, there */ |
2019 /* exist fonts which are incorrectly converted from probably */ |
2063 /* exist fonts which are incorrectly converted from probably */ |
2249 } |
2293 } |
2250 |
2294 |
2251 #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */ |
2295 #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */ |
2252 |
2296 |
2253 |
2297 |
2254 /*************************************************************************/ |
2298 /************************************************************************** |
2255 /* */ |
2299 * |
2256 /* <Function> */ |
2300 * @Function: |
2257 /* cff_decoder_init */ |
2301 * cff_decoder_init |
2258 /* */ |
2302 * |
2259 /* <Description> */ |
2303 * @Description: |
2260 /* Initializes a given glyph decoder. */ |
2304 * Initializes a given glyph decoder. |
2261 /* */ |
2305 * |
2262 /* <InOut> */ |
2306 * @InOut: |
2263 /* decoder :: A pointer to the glyph builder to initialize. */ |
2307 * decoder :: |
2264 /* */ |
2308 * A pointer to the glyph builder to initialize. |
2265 /* <Input> */ |
2309 * |
2266 /* face :: The current face object. */ |
2310 * @Input: |
2267 /* */ |
2311 * face :: |
2268 /* size :: The current size object. */ |
2312 * The current face object. |
2269 /* */ |
2313 * |
2270 /* slot :: The current glyph object. */ |
2314 * size :: |
2271 /* */ |
2315 * The current size object. |
2272 /* hinting :: Whether hinting is active. */ |
2316 * |
2273 /* */ |
2317 * slot :: |
2274 /* hint_mode :: The hinting mode. */ |
2318 * The current glyph object. |
2275 /* */ |
2319 * |
|
2320 * hinting :: |
|
2321 * Whether hinting is active. |
|
2322 * |
|
2323 * hint_mode :: |
|
2324 * The hinting mode. |
|
2325 */ |
2276 FT_LOCAL_DEF( void ) |
2326 FT_LOCAL_DEF( void ) |
2277 cff_decoder_init( CFF_Decoder* decoder, |
2327 cff_decoder_init( CFF_Decoder* decoder, |
2278 TT_Face face, |
2328 TT_Face face, |
2279 CFF_Size size, |
2329 CFF_Size size, |
2280 CFF_GlyphSlot slot, |
2330 CFF_GlyphSlot slot, |