1 /***************************************************************************/ 2 /* */ 3 /* t1decode.c */ 4 /* */ 5 /* PostScript Type 1 decoding routines (body). */ 6 /* */ 7 /* Copyright 2000-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_INTERNAL_CALC_H 21 #include FT_INTERNAL_DEBUG_H 22 #include FT_INTERNAL_POSTSCRIPT_HINTS_H 23 #include FT_INTERNAL_HASH_H 24 #include FT_OUTLINE_H 25 26 #include "t1decode.h" 27 #include "psobjs.h" 28 29 #include "psauxerr.h" 30 31 /* ensure proper sign extension */ 32 #define Fix2Int( f ) ( (FT_Int)(FT_Short)( (f) >> 16 ) ) 33 34 /*************************************************************************/ 35 /* */ 36 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 37 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 38 /* messages during execution. */ 39 /* */ 40 #undef FT_COMPONENT 41 #define FT_COMPONENT trace_t1decode 42 43 44 typedef enum T1_Operator_ 45 { 46 op_none = 0, 47 op_endchar, 48 op_hsbw, 49 op_seac, 50 op_sbw, 51 op_closepath, 52 op_hlineto, 53 op_hmoveto, 54 op_hvcurveto, 55 op_rlineto, 56 op_rmoveto, 57 op_rrcurveto, 58 op_vhcurveto, 59 op_vlineto, 60 op_vmoveto, 61 op_dotsection, 92 2, /* rmoveto */ 93 6, /* rrcurveto */ 94 4, /* vhcurveto */ 95 1, /* vlineto */ 96 1, /* vmoveto */ 97 0, /* dotsection */ 98 2, /* hstem */ 99 6, /* hstem3 */ 100 2, /* vstem */ 101 6, /* vstem3 */ 102 2, /* div */ 103 -1, /* callothersubr */ 104 1, /* callsubr */ 105 0, /* pop */ 106 0, /* return */ 107 2, /* setcurrentpoint */ 108 2 /* opcode 15 (undocumented and obsolete) */ 109 }; 110 111 112 /*************************************************************************/ 113 /* */ 114 /* <Function> */ 115 /* t1_lookup_glyph_by_stdcharcode_ps */ 116 /* */ 117 /* <Description> */ 118 /* Looks up a given glyph by its StandardEncoding charcode. Used to */ 119 /* implement the SEAC Type 1 operator in the Adobe engine */ 120 /* */ 121 /* <Input> */ 122 /* face :: The current face object. */ 123 /* */ 124 /* charcode :: The character code to look for. */ 125 /* */ 126 /* <Return> */ 127 /* A glyph index in the font face. Returns -1 if the corresponding */ 128 /* glyph wasn't found. */ 129 /* */ 130 FT_LOCAL_DEF( FT_Int ) 131 t1_lookup_glyph_by_stdcharcode_ps( PS_Decoder* decoder, 132 FT_Int charcode ) 133 { 134 FT_UInt n; 135 const FT_String* glyph_name; 136 FT_Service_PsCMaps psnames = decoder->psnames; 137 138 139 /* check range of standard char code */ 140 if ( charcode < 0 || charcode > 255 ) 141 return -1; 142 143 glyph_name = psnames->adobe_std_strings( 144 psnames->adobe_std_encoding[charcode]); 145 146 for ( n = 0; n < decoder->num_glyphs; n++ ) 147 { 148 FT_String* name = (FT_String*)decoder->glyph_names[n]; 149 150 151 if ( name && 152 name[0] == glyph_name[0] && 153 ft_strcmp( name, glyph_name ) == 0 ) 154 return (FT_Int)n; 155 } 156 157 return -1; 158 } 159 160 161 #ifdef T1_CONFIG_OPTION_OLD_ENGINE 162 /*************************************************************************/ 163 /* */ 164 /* <Function> */ 165 /* t1_lookup_glyph_by_stdcharcode */ 166 /* */ 167 /* <Description> */ 168 /* Looks up a given glyph by its StandardEncoding charcode. Used to */ 169 /* implement the SEAC Type 1 operator. */ 170 /* */ 171 /* <Input> */ 172 /* face :: The current face object. */ 173 /* */ 174 /* charcode :: The character code to look for. */ 175 /* */ 176 /* <Return> */ 177 /* A glyph index in the font face. Returns -1 if the corresponding */ 178 /* glyph wasn't found. */ 179 /* */ 180 static FT_Int 181 t1_lookup_glyph_by_stdcharcode( T1_Decoder decoder, 182 FT_Int charcode ) 183 { 184 FT_UInt n; 185 const FT_String* glyph_name; 186 FT_Service_PsCMaps psnames = decoder->psnames; 187 188 189 /* check range of standard char code */ 190 if ( charcode < 0 || charcode > 255 ) 191 return -1; 192 193 glyph_name = psnames->adobe_std_strings( 194 psnames->adobe_std_encoding[charcode]); 195 196 for ( n = 0; n < decoder->num_glyphs; n++ ) 197 { 198 FT_String* name = (FT_String*)decoder->glyph_names[n]; 199 200 201 if ( name && 202 name[0] == glyph_name[0] && 203 ft_strcmp( name, glyph_name ) == 0 ) 204 return (FT_Int)n; 205 } 206 207 return -1; 208 } 209 210 211 /* parse a single Type 1 glyph */ 212 FT_LOCAL_DEF( FT_Error ) 213 t1_decoder_parse_glyph( T1_Decoder decoder, 214 FT_UInt glyph ) 215 { 216 return decoder->parse_callback( decoder, glyph ); 217 } 218 219 220 /*************************************************************************/ 221 /* */ 222 /* <Function> */ 223 /* t1operator_seac */ 224 /* */ 225 /* <Description> */ 226 /* Implements the `seac' Type 1 operator for a Type 1 decoder. */ 227 /* */ 228 /* <Input> */ 229 /* decoder :: The current CID decoder. */ 230 /* */ 231 /* asb :: The accent's side bearing. */ 232 /* */ 233 /* adx :: The horizontal offset of the accent. */ 234 /* */ 235 /* ady :: The vertical offset of the accent. */ 236 /* */ 237 /* bchar :: The base character's StandardEncoding charcode. */ 238 /* */ 239 /* achar :: The accent character's StandardEncoding charcode. */ 240 /* */ 241 /* <Return> */ 242 /* FreeType error code. 0 means success. */ 243 /* */ 244 static FT_Error 245 t1operator_seac( T1_Decoder decoder, 246 FT_Pos asb, 247 FT_Pos adx, 248 FT_Pos ady, 249 FT_Int bchar, 250 FT_Int achar ) 251 { 252 FT_Error error; 253 FT_Int bchar_index, achar_index; 254 #if 0 255 FT_Int n_base_points; 256 FT_Outline* base = decoder->builder.base; 257 #endif 258 FT_Vector left_bearing, advance; 259 260 #ifdef FT_CONFIG_OPTION_INCREMENTAL 261 T1_Face face = (T1_Face)decoder->builder.face; 262 #endif 263 382 decoder->seac = TRUE; 383 error = t1_decoder_parse_glyph( decoder, (FT_UInt)achar_index ); 384 decoder->seac = FALSE; 385 if ( error ) 386 goto Exit; 387 388 /* restore the left side bearing and */ 389 /* advance width of the base character */ 390 391 decoder->builder.left_bearing = left_bearing; 392 decoder->builder.advance = advance; 393 394 decoder->builder.pos_x = 0; 395 decoder->builder.pos_y = 0; 396 397 Exit: 398 return error; 399 } 400 401 402 /*************************************************************************/ 403 /* */ 404 /* <Function> */ 405 /* t1_decoder_parse_charstrings */ 406 /* */ 407 /* <Description> */ 408 /* Parses a given Type 1 charstrings program. */ 409 /* */ 410 /* <Input> */ 411 /* decoder :: The current Type 1 decoder. */ 412 /* */ 413 /* charstring_base :: The base address of the charstring stream. */ 414 /* */ 415 /* charstring_len :: The length in bytes of the charstring stream. */ 416 /* */ 417 /* <Return> */ 418 /* FreeType error code. 0 means success. */ 419 /* */ 420 FT_LOCAL_DEF( FT_Error ) 421 t1_decoder_parse_charstrings( T1_Decoder decoder, 422 FT_Byte* charstring_base, 423 FT_UInt charstring_len ) 424 { 425 FT_Error error; 426 T1_Decoder_Zone zone; 427 FT_Byte* ip; 428 FT_Byte* limit; 429 T1_Builder builder = &decoder->builder; 430 FT_Pos x, y, orig_x, orig_y; 431 FT_Int known_othersubr_result_cnt = 0; 432 FT_Int unknown_othersubr_result_cnt = 0; 433 FT_Bool large_int; 434 FT_Fixed seed; 435 436 T1_Hints_Funcs hinter; 437 438 #ifdef FT_DEBUG_LEVEL_TRACE 439 FT_Bool bol = TRUE; 449 if ( seed == 0 ) 450 seed = 0x7384; 451 452 /* First of all, initialize the decoder */ 453 decoder->top = decoder->stack; 454 decoder->zone = decoder->zones; 455 zone = decoder->zones; 456 457 builder->parse_state = T1_Parse_Start; 458 459 hinter = (T1_Hints_Funcs)builder->hints_funcs; 460 461 /* a font that reads BuildCharArray without setting */ 462 /* its values first is buggy, but ... */ 463 FT_ASSERT( ( decoder->len_buildchar == 0 ) == 464 ( decoder->buildchar == NULL ) ); 465 466 if ( decoder->buildchar && decoder->len_buildchar > 0 ) 467 FT_ARRAY_ZERO( decoder->buildchar, decoder->len_buildchar ); 468 469 FT_TRACE4(( "\n" 470 "Start charstring\n" )); 471 472 zone->base = charstring_base; 473 limit = zone->limit = charstring_base + charstring_len; 474 ip = zone->cursor = zone->base; 475 476 error = FT_Err_Ok; 477 478 x = orig_x = builder->pos_x; 479 y = orig_y = builder->pos_y; 480 481 /* begin hints recording session, if any */ 482 if ( hinter ) 483 hinter->open( hinter->hints ); 484 485 large_int = FALSE; 486 487 /* now, execute loop */ 488 while ( ip < limit ) 489 { 490 FT_Long* top = decoder->top; 491 T1_Operator op = op_none; 492 FT_Int32 value = 0; 493 494 495 FT_ASSERT( known_othersubr_result_cnt == 0 || 496 unknown_othersubr_result_cnt == 0 ); 497 498 #ifdef FT_DEBUG_LEVEL_TRACE 499 if ( bol ) 500 { 501 FT_TRACE5(( " (%d)", decoder->top - decoder->stack )); 502 bol = FALSE; 503 } 504 #endif 505 506 /*********************************************************************/ 507 /* */ 508 /* Decode operator or operand */ 509 /* */ 510 /* */ 511 512 /* first of all, decompress operator or value */ 513 switch ( *ip++ ) 514 { 515 case 1: 516 op = op_hstem; 517 break; 518 519 case 3: 520 op = op_vstem; 521 break; 522 case 4: 523 op = op_vmoveto; 524 break; 525 case 5: 526 op = op_rlineto; 527 break; 528 case 6: 529 op = op_hlineto; 530 break; 693 case op_return: 694 case op_none: 695 case op_pop: 696 break; 697 698 default: 699 /* all operands have been transferred by previous pops */ 700 unknown_othersubr_result_cnt = 0; 701 break; 702 } 703 } 704 705 if ( large_int && !( op == op_none || op == op_div ) ) 706 { 707 FT_ERROR(( "t1_decoder_parse_charstrings:" 708 " no `div' after large integer\n" )); 709 710 large_int = FALSE; 711 } 712 713 /*********************************************************************/ 714 /* */ 715 /* Push value on stack, or process operator */ 716 /* */ 717 /* */ 718 if ( op == op_none ) 719 { 720 if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS ) 721 { 722 FT_ERROR(( "t1_decoder_parse_charstrings: stack overflow\n" )); 723 goto Syntax_Error; 724 } 725 726 #ifdef FT_DEBUG_LEVEL_TRACE 727 if ( large_int ) 728 FT_TRACE4(( " %d", value )); 729 else 730 FT_TRACE4(( " %d", value / 65536 )); 731 #endif 732 733 *top++ = value; 734 decoder->top = top; 735 } 736 else if ( op == op_callothersubr ) /* callothersubr */ 737 { 738 FT_Int subr_no; 739 FT_Int arg_cnt; 740 741 742 #ifdef FT_DEBUG_LEVEL_TRACE 743 FT_TRACE4(( " callothersubr\n" )); 744 bol = TRUE; 745 #endif 746 747 if ( top - decoder->stack < 2 ) 748 goto Stack_Underflow; 749 750 top -= 2; 751 752 subr_no = Fix2Int( top[1] ); 753 arg_cnt = Fix2Int( top[0] ); 754 755 /***********************************************************/ 756 /* */ 757 /* remove all operands to callothersubr from the stack */ 758 /* */ 759 /* for handled othersubrs, where we know the number of */ 760 /* arguments, we increase the stack by the value of */ 761 /* known_othersubr_result_cnt */ 762 /* */ 763 /* for unhandled othersubrs the following pops adjust the */ 764 /* stack pointer as necessary */ 765 766 if ( arg_cnt > top - decoder->stack ) 767 goto Stack_Underflow; 768 769 top -= arg_cnt; 770 771 known_othersubr_result_cnt = 0; 772 unknown_othersubr_result_cnt = 0; 773 774 /* XXX TODO: The checks to `arg_count == <whatever>' */ 775 /* might not be correct; an othersubr expects a certain */ 776 /* number of operands on the PostScript stack (as opposed */ 777 /* to the T1 stack) but it doesn't have to put them there */ 778 /* by itself; previous othersubrs might have left the */ 779 /* operands there if they were not followed by an */ 780 /* appropriate number of pops */ 781 /* */ 782 /* On the other hand, Adobe Reader 7.0.8 for Linux doesn't */ 783 /* accept a font that contains charstrings like */ 784 /* */ 1206 case op_hsbw: 1207 FT_TRACE4(( " hsbw" )); 1208 1209 builder->parse_state = T1_Parse_Have_Width; 1210 1211 builder->left_bearing.x = ADD_LONG( builder->left_bearing.x, 1212 top[0] ); 1213 1214 builder->advance.x = top[1]; 1215 builder->advance.y = 0; 1216 1217 orig_x = x = ADD_LONG( builder->pos_x, top[0] ); 1218 orig_y = y = builder->pos_y; 1219 1220 FT_UNUSED( orig_y ); 1221 1222 /* the `metrics_only' indicates that we only want to compute */ 1223 /* the glyph's metrics (lsb + advance width), not load the */ 1224 /* rest of it; so exit immediately */ 1225 if ( builder->metrics_only ) 1226 return FT_Err_Ok; 1227 1228 break; 1229 1230 case op_seac: 1231 return t1operator_seac( decoder, 1232 top[0], 1233 top[1], 1234 top[2], 1235 Fix2Int( top[3] ), 1236 Fix2Int( top[4] ) ); 1237 1238 case op_sbw: 1239 FT_TRACE4(( " sbw" )); 1240 1241 builder->parse_state = T1_Parse_Have_Width; 1242 1243 builder->left_bearing.x = ADD_LONG( builder->left_bearing.x, 1244 top[0] ); 1245 builder->left_bearing.y = ADD_LONG( builder->left_bearing.y, 1246 top[1] ); 1247 1248 builder->advance.x = top[2]; 1249 builder->advance.y = top[3]; 1250 1251 x = ADD_LONG( builder->pos_x, top[0] ); 1252 y = ADD_LONG( builder->pos_y, top[1] ); 1253 1254 /* the `metrics_only' indicates that we only want to compute */ 1255 /* the glyph's metrics (lsb + advance width), not load the */ 1256 /* rest of it; so exit immediately */ 1257 if ( builder->metrics_only ) 1258 return FT_Err_Ok; 1259 1260 break; 1261 1262 case op_closepath: 1263 FT_TRACE4(( " closepath" )); 1264 1265 /* if there is no path, `closepath' is a no-op */ 1266 if ( builder->parse_state == T1_Parse_Have_Path || 1267 builder->parse_state == T1_Parse_Have_Moveto ) 1268 t1_builder_close_contour( builder ); 1269 1270 builder->parse_state = T1_Parse_Have_Width; 1271 break; 1272 1273 case op_hlineto: 1274 FT_TRACE4(( " hlineto" )); 1275 1276 if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ) 1277 goto Fail; 1278 1621 FT_TRACE4(( "\n" )); 1622 bol = TRUE; 1623 #endif 1624 1625 } /* general operator processing */ 1626 1627 } /* while ip < limit */ 1628 1629 FT_TRACE4(( "..end..\n\n" )); 1630 1631 Fail: 1632 return error; 1633 1634 Syntax_Error: 1635 return FT_THROW( Syntax_Error ); 1636 1637 Stack_Underflow: 1638 return FT_THROW( Stack_Underflow ); 1639 } 1640 1641 #else /* T1_CONFIG_OPTION_OLD_ENGINE */ 1642 1643 /*************************************************************************/ 1644 /* */ 1645 /* <Function> */ 1646 /* t1_decoder_parse_metrics */ 1647 /* */ 1648 /* <Description> */ 1649 /* Parses a given Type 1 charstrings program to extract width */ 1650 /* */ 1651 /* <Input> */ 1652 /* decoder :: The current Type 1 decoder. */ 1653 /* */ 1654 /* charstring_base :: The base address of the charstring stream. */ 1655 /* */ 1656 /* charstring_len :: The length in bytes of the charstring stream. */ 1657 /* */ 1658 /* <Return> */ 1659 /* FreeType error code. 0 means success. */ 1660 /* */ 1661 FT_LOCAL_DEF( FT_Error ) 1662 t1_decoder_parse_metrics( T1_Decoder decoder, 1663 FT_Byte* charstring_base, 1664 FT_UInt charstring_len ) 1665 { 1666 T1_Decoder_Zone zone; 1667 FT_Byte* ip; 1668 FT_Byte* limit; 1669 T1_Builder builder = &decoder->builder; 1670 1671 #ifdef FT_DEBUG_LEVEL_TRACE 1672 FT_Bool bol = TRUE; 1673 #endif 1674 1675 1676 /* First of all, initialize the decoder */ 1677 decoder->top = decoder->stack; 1678 decoder->zone = decoder->zones; 1679 zone = decoder->zones; 1680 1681 builder->parse_state = T1_Parse_Start; 1682 1683 FT_TRACE4(( "\n" 1684 "Start charstring: get width\n" )); 1685 1686 zone->base = charstring_base; 1687 limit = zone->limit = charstring_base + charstring_len; 1688 ip = zone->cursor = zone->base; 1689 1690 /* now, execute loop */ 1691 while ( ip < limit ) 1692 { 1693 FT_Long* top = decoder->top; 1694 T1_Operator op = op_none; 1695 FT_Int32 value = 0; 1696 1697 1698 #ifdef FT_DEBUG_LEVEL_TRACE 1699 if ( bol ) 1700 { 1701 FT_TRACE5(( " (%d)", decoder->top - decoder->stack )); 1702 bol = FALSE; 1703 } 1704 #endif 1705 1706 /*********************************************************************/ 1707 /* */ 1708 /* Decode operator or operand */ 1709 /* */ 1710 /* */ 1711 1712 /* first of all, decompress operator or value */ 1713 switch ( *ip++ ) 1714 { 1715 case 1: 1716 case 3: 1717 case 4: 1718 case 5: 1719 case 6: 1720 case 7: 1721 case 8: 1722 case 9: 1723 case 10: 1724 case 11: 1725 case 14: 1726 case 15: 1727 case 21: 1728 case 22: 1729 case 30: 1730 case 31: 1800 " unexpected EOF in integer\n" )); 1801 goto Syntax_Error; 1802 } 1803 1804 if ( ip[-2] < 251 ) 1805 value = ( ( ip[-2] - 247 ) * 256 ) + ip[-1] + 108; 1806 else 1807 value = -( ( ( ip[-2] - 251 ) * 256 ) + ip[-1] + 108 ); 1808 } 1809 1810 value = (FT_Int32)( (FT_UInt32)value << 16 ); 1811 } 1812 else 1813 { 1814 FT_ERROR(( "t1_decoder_parse_metrics:" 1815 " invalid byte (%d)\n", ip[-1] )); 1816 goto Syntax_Error; 1817 } 1818 } 1819 1820 /*********************************************************************/ 1821 /* */ 1822 /* Push value on stack, or process operator */ 1823 /* */ 1824 /* */ 1825 if ( op == op_none ) 1826 { 1827 if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS ) 1828 { 1829 FT_ERROR(( "t1_decoder_parse_metrics: stack overflow\n" )); 1830 goto Syntax_Error; 1831 } 1832 1833 #ifdef FT_DEBUG_LEVEL_TRACE 1834 FT_TRACE4(( " %d", value / 65536 )); 1835 #endif 1836 1837 *top++ = value; 1838 decoder->top = top; 1839 } 1840 else /* general operator */ 1841 { 1842 FT_Int num_args = t1_args_count[op]; 1843 1844 1858 #endif /* FT_DEBUG_LEVEL_TRACE */ 1859 1860 top -= num_args; 1861 1862 switch ( op ) 1863 { 1864 case op_hsbw: 1865 FT_TRACE4(( " hsbw" )); 1866 1867 builder->parse_state = T1_Parse_Have_Width; 1868 1869 builder->left_bearing.x = ADD_LONG( builder->left_bearing.x, 1870 top[0] ); 1871 1872 builder->advance.x = top[1]; 1873 builder->advance.y = 0; 1874 1875 /* we only want to compute the glyph's metrics */ 1876 /* (lsb + advance width), not load the rest of */ 1877 /* it; so exit immediately */ 1878 return FT_Err_Ok; 1879 1880 case op_sbw: 1881 FT_TRACE4(( " sbw" )); 1882 1883 builder->parse_state = T1_Parse_Have_Width; 1884 1885 builder->left_bearing.x = ADD_LONG( builder->left_bearing.x, 1886 top[0] ); 1887 builder->left_bearing.y = ADD_LONG( builder->left_bearing.y, 1888 top[1] ); 1889 1890 builder->advance.x = top[2]; 1891 builder->advance.y = top[3]; 1892 1893 /* we only want to compute the glyph's metrics */ 1894 /* (lsb + advance width), not load the rest of */ 1895 /* it; so exit immediately */ 1896 return FT_Err_Ok; 1897 1898 default: 1899 FT_ERROR(( "t1_decoder_parse_metrics:" 1900 " unhandled opcode %d\n", op )); 1901 goto Syntax_Error; 1902 } 1903 1904 } /* general operator processing */ 1905 1906 } /* while ip < limit */ 1907 1908 FT_TRACE4(( "..end..\n\n" )); 1909 1910 No_Width: 1911 FT_ERROR(( "t1_decoder_parse_metrics:" 1912 " no width, found op %d instead\n", 1913 ip[-1] )); 1914 Syntax_Error: 1915 return FT_THROW( Syntax_Error ); 1916 1917 Stack_Underflow: 1918 return FT_THROW( Stack_Underflow ); 1919 } 1920 #endif /* T1_CONFIG_OPTION_OLD_ENGINE */ 1921 1922 1923 /* initialize T1 decoder */ 1924 FT_LOCAL_DEF( FT_Error ) 1925 t1_decoder_init( T1_Decoder decoder, 1926 FT_Face face, 1927 FT_Size size, 1928 FT_GlyphSlot slot, 1929 FT_Byte** glyph_names, 1930 PS_Blend blend, 1931 FT_Bool hinting, 1932 FT_Render_Mode hint_mode, 1933 T1_Decoder_Callback parse_callback ) 1934 { 1935 FT_ZERO( decoder ); 1936 1937 /* retrieve PSNames interface from list of current modules */ 1938 { 1939 FT_Service_PsCMaps psnames; 1940 1941 1942 FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); 1943 if ( !psnames ) 1944 { 1945 FT_ERROR(( "t1_decoder_init:" 1946 " the `psnames' module is not available\n" )); 1947 return FT_THROW( Unimplemented_Feature ); 1948 } 1949 1950 decoder->psnames = psnames; 1951 } 1952 1953 t1_builder_init( &decoder->builder, face, size, slot, hinting ); 1954 1955 /* decoder->buildchar and decoder->len_buildchar have to be */ 1956 /* initialized by the caller since we cannot know the length */ 1957 /* of the BuildCharArray */ | 1 /**************************************************************************** 2 * 3 * t1decode.c 4 * 5 * PostScript Type 1 decoding routines (body). 6 * 7 * Copyright (C) 2000-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_INTERNAL_CALC_H 21 #include FT_INTERNAL_DEBUG_H 22 #include FT_INTERNAL_POSTSCRIPT_HINTS_H 23 #include FT_INTERNAL_HASH_H 24 #include FT_OUTLINE_H 25 26 #include "t1decode.h" 27 #include "psobjs.h" 28 29 #include "psauxerr.h" 30 31 /* ensure proper sign extension */ 32 #define Fix2Int( f ) ( (FT_Int)(FT_Short)( (f) >> 16 ) ) 33 34 /************************************************************************** 35 * 36 * The macro FT_COMPONENT is used in trace mode. It is an implicit 37 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log 38 * messages during execution. 39 */ 40 #undef FT_COMPONENT 41 #define FT_COMPONENT t1decode 42 43 44 typedef enum T1_Operator_ 45 { 46 op_none = 0, 47 op_endchar, 48 op_hsbw, 49 op_seac, 50 op_sbw, 51 op_closepath, 52 op_hlineto, 53 op_hmoveto, 54 op_hvcurveto, 55 op_rlineto, 56 op_rmoveto, 57 op_rrcurveto, 58 op_vhcurveto, 59 op_vlineto, 60 op_vmoveto, 61 op_dotsection, 92 2, /* rmoveto */ 93 6, /* rrcurveto */ 94 4, /* vhcurveto */ 95 1, /* vlineto */ 96 1, /* vmoveto */ 97 0, /* dotsection */ 98 2, /* hstem */ 99 6, /* hstem3 */ 100 2, /* vstem */ 101 6, /* vstem3 */ 102 2, /* div */ 103 -1, /* callothersubr */ 104 1, /* callsubr */ 105 0, /* pop */ 106 0, /* return */ 107 2, /* setcurrentpoint */ 108 2 /* opcode 15 (undocumented and obsolete) */ 109 }; 110 111 112 /************************************************************************** 113 * 114 * @Function: 115 * t1_lookup_glyph_by_stdcharcode_ps 116 * 117 * @Description: 118 * Looks up a given glyph by its StandardEncoding charcode. Used to 119 * implement the SEAC Type 1 operator in the Adobe engine 120 * 121 * @Input: 122 * face :: 123 * The current face object. 124 * 125 * charcode :: 126 * The character code to look for. 127 * 128 * @Return: 129 * A glyph index in the font face. Returns -1 if the corresponding 130 * glyph wasn't found. 131 */ 132 FT_LOCAL_DEF( FT_Int ) 133 t1_lookup_glyph_by_stdcharcode_ps( PS_Decoder* decoder, 134 FT_Int charcode ) 135 { 136 FT_UInt n; 137 const FT_String* glyph_name; 138 FT_Service_PsCMaps psnames = decoder->psnames; 139 140 141 /* check range of standard char code */ 142 if ( charcode < 0 || charcode > 255 ) 143 return -1; 144 145 glyph_name = psnames->adobe_std_strings( 146 psnames->adobe_std_encoding[charcode]); 147 148 for ( n = 0; n < decoder->num_glyphs; n++ ) 149 { 150 FT_String* name = (FT_String*)decoder->glyph_names[n]; 151 152 153 if ( name && 154 name[0] == glyph_name[0] && 155 ft_strcmp( name, glyph_name ) == 0 ) 156 return (FT_Int)n; 157 } 158 159 return -1; 160 } 161 162 163 #ifdef T1_CONFIG_OPTION_OLD_ENGINE 164 165 /************************************************************************** 166 * 167 * @Function: 168 * t1_lookup_glyph_by_stdcharcode 169 * 170 * @Description: 171 * Looks up a given glyph by its StandardEncoding charcode. Used to 172 * implement the SEAC Type 1 operator. 173 * 174 * @Input: 175 * face :: 176 * The current face object. 177 * 178 * charcode :: 179 * The character code to look for. 180 * 181 * @Return: 182 * A glyph index in the font face. Returns -1 if the corresponding 183 * glyph wasn't found. 184 */ 185 static FT_Int 186 t1_lookup_glyph_by_stdcharcode( T1_Decoder decoder, 187 FT_Int charcode ) 188 { 189 FT_UInt n; 190 const FT_String* glyph_name; 191 FT_Service_PsCMaps psnames = decoder->psnames; 192 193 194 /* check range of standard char code */ 195 if ( charcode < 0 || charcode > 255 ) 196 return -1; 197 198 glyph_name = psnames->adobe_std_strings( 199 psnames->adobe_std_encoding[charcode]); 200 201 for ( n = 0; n < decoder->num_glyphs; n++ ) 202 { 203 FT_String* name = (FT_String*)decoder->glyph_names[n]; 204 205 206 if ( name && 207 name[0] == glyph_name[0] && 208 ft_strcmp( name, glyph_name ) == 0 ) 209 return (FT_Int)n; 210 } 211 212 return -1; 213 } 214 215 216 /* parse a single Type 1 glyph */ 217 FT_LOCAL_DEF( FT_Error ) 218 t1_decoder_parse_glyph( T1_Decoder decoder, 219 FT_UInt glyph ) 220 { 221 return decoder->parse_callback( decoder, glyph ); 222 } 223 224 225 /************************************************************************** 226 * 227 * @Function: 228 * t1operator_seac 229 * 230 * @Description: 231 * Implements the `seac' Type 1 operator for a Type 1 decoder. 232 * 233 * @Input: 234 * decoder :: 235 * The current CID decoder. 236 * 237 * asb :: 238 * The accent's side bearing. 239 * 240 * adx :: 241 * The horizontal offset of the accent. 242 * 243 * ady :: 244 * The vertical offset of the accent. 245 * 246 * bchar :: 247 * The base character's StandardEncoding charcode. 248 * 249 * achar :: 250 * The accent character's StandardEncoding charcode. 251 * 252 * @Return: 253 * FreeType error code. 0 means success. 254 */ 255 static FT_Error 256 t1operator_seac( T1_Decoder decoder, 257 FT_Pos asb, 258 FT_Pos adx, 259 FT_Pos ady, 260 FT_Int bchar, 261 FT_Int achar ) 262 { 263 FT_Error error; 264 FT_Int bchar_index, achar_index; 265 #if 0 266 FT_Int n_base_points; 267 FT_Outline* base = decoder->builder.base; 268 #endif 269 FT_Vector left_bearing, advance; 270 271 #ifdef FT_CONFIG_OPTION_INCREMENTAL 272 T1_Face face = (T1_Face)decoder->builder.face; 273 #endif 274 393 decoder->seac = TRUE; 394 error = t1_decoder_parse_glyph( decoder, (FT_UInt)achar_index ); 395 decoder->seac = FALSE; 396 if ( error ) 397 goto Exit; 398 399 /* restore the left side bearing and */ 400 /* advance width of the base character */ 401 402 decoder->builder.left_bearing = left_bearing; 403 decoder->builder.advance = advance; 404 405 decoder->builder.pos_x = 0; 406 decoder->builder.pos_y = 0; 407 408 Exit: 409 return error; 410 } 411 412 413 /************************************************************************** 414 * 415 * @Function: 416 * t1_decoder_parse_charstrings 417 * 418 * @Description: 419 * Parses a given Type 1 charstrings program. 420 * 421 * @Input: 422 * decoder :: 423 * The current Type 1 decoder. 424 * 425 * charstring_base :: 426 * The base address of the charstring stream. 427 * 428 * charstring_len :: 429 * The length in bytes of the charstring stream. 430 * 431 * @Return: 432 * FreeType error code. 0 means success. 433 */ 434 FT_LOCAL_DEF( FT_Error ) 435 t1_decoder_parse_charstrings( T1_Decoder decoder, 436 FT_Byte* charstring_base, 437 FT_UInt charstring_len ) 438 { 439 FT_Error error; 440 T1_Decoder_Zone zone; 441 FT_Byte* ip; 442 FT_Byte* limit; 443 T1_Builder builder = &decoder->builder; 444 FT_Pos x, y, orig_x, orig_y; 445 FT_Int known_othersubr_result_cnt = 0; 446 FT_Int unknown_othersubr_result_cnt = 0; 447 FT_Bool large_int; 448 FT_Fixed seed; 449 450 T1_Hints_Funcs hinter; 451 452 #ifdef FT_DEBUG_LEVEL_TRACE 453 FT_Bool bol = TRUE; 463 if ( seed == 0 ) 464 seed = 0x7384; 465 466 /* First of all, initialize the decoder */ 467 decoder->top = decoder->stack; 468 decoder->zone = decoder->zones; 469 zone = decoder->zones; 470 471 builder->parse_state = T1_Parse_Start; 472 473 hinter = (T1_Hints_Funcs)builder->hints_funcs; 474 475 /* a font that reads BuildCharArray without setting */ 476 /* its values first is buggy, but ... */ 477 FT_ASSERT( ( decoder->len_buildchar == 0 ) == 478 ( decoder->buildchar == NULL ) ); 479 480 if ( decoder->buildchar && decoder->len_buildchar > 0 ) 481 FT_ARRAY_ZERO( decoder->buildchar, decoder->len_buildchar ); 482 483 zone->base = charstring_base; 484 limit = zone->limit = charstring_base + charstring_len; 485 ip = zone->cursor = zone->base; 486 487 error = FT_Err_Ok; 488 489 x = orig_x = builder->pos_x; 490 y = orig_y = builder->pos_y; 491 492 /* begin hints recording session, if any */ 493 if ( hinter ) 494 hinter->open( hinter->hints ); 495 496 large_int = FALSE; 497 498 /* now, execute loop */ 499 while ( ip < limit ) 500 { 501 FT_Long* top = decoder->top; 502 T1_Operator op = op_none; 503 FT_Int32 value = 0; 504 505 506 FT_ASSERT( known_othersubr_result_cnt == 0 || 507 unknown_othersubr_result_cnt == 0 ); 508 509 #ifdef FT_DEBUG_LEVEL_TRACE 510 if ( bol ) 511 { 512 FT_TRACE5(( " (%d)", decoder->top - decoder->stack )); 513 bol = FALSE; 514 } 515 #endif 516 517 /********************************************************************** 518 * 519 * Decode operator or operand 520 * 521 */ 522 523 /* first of all, decompress operator or value */ 524 switch ( *ip++ ) 525 { 526 case 1: 527 op = op_hstem; 528 break; 529 530 case 3: 531 op = op_vstem; 532 break; 533 case 4: 534 op = op_vmoveto; 535 break; 536 case 5: 537 op = op_rlineto; 538 break; 539 case 6: 540 op = op_hlineto; 541 break; 704 case op_return: 705 case op_none: 706 case op_pop: 707 break; 708 709 default: 710 /* all operands have been transferred by previous pops */ 711 unknown_othersubr_result_cnt = 0; 712 break; 713 } 714 } 715 716 if ( large_int && !( op == op_none || op == op_div ) ) 717 { 718 FT_ERROR(( "t1_decoder_parse_charstrings:" 719 " no `div' after large integer\n" )); 720 721 large_int = FALSE; 722 } 723 724 /********************************************************************** 725 * 726 * Push value on stack, or process operator 727 * 728 */ 729 if ( op == op_none ) 730 { 731 if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS ) 732 { 733 FT_ERROR(( "t1_decoder_parse_charstrings: stack overflow\n" )); 734 goto Syntax_Error; 735 } 736 737 #ifdef FT_DEBUG_LEVEL_TRACE 738 if ( large_int ) 739 FT_TRACE4(( " %d", value )); 740 else 741 FT_TRACE4(( " %d", value / 65536 )); 742 #endif 743 744 *top++ = value; 745 decoder->top = top; 746 } 747 else if ( op == op_callothersubr ) /* callothersubr */ 748 { 749 FT_Int subr_no; 750 FT_Int arg_cnt; 751 752 753 #ifdef FT_DEBUG_LEVEL_TRACE 754 FT_TRACE4(( " callothersubr\n" )); 755 bol = TRUE; 756 #endif 757 758 if ( top - decoder->stack < 2 ) 759 goto Stack_Underflow; 760 761 top -= 2; 762 763 subr_no = Fix2Int( top[1] ); 764 arg_cnt = Fix2Int( top[0] ); 765 766 /************************************************************ 767 * 768 * remove all operands to callothersubr from the stack 769 * 770 * for handled othersubrs, where we know the number of 771 * arguments, we increase the stack by the value of 772 * known_othersubr_result_cnt 773 * 774 * for unhandled othersubrs the following pops adjust the 775 * stack pointer as necessary 776 */ 777 778 if ( arg_cnt > top - decoder->stack ) 779 goto Stack_Underflow; 780 781 top -= arg_cnt; 782 783 known_othersubr_result_cnt = 0; 784 unknown_othersubr_result_cnt = 0; 785 786 /* XXX TODO: The checks to `arg_count == <whatever>' */ 787 /* might not be correct; an othersubr expects a certain */ 788 /* number of operands on the PostScript stack (as opposed */ 789 /* to the T1 stack) but it doesn't have to put them there */ 790 /* by itself; previous othersubrs might have left the */ 791 /* operands there if they were not followed by an */ 792 /* appropriate number of pops */ 793 /* */ 794 /* On the other hand, Adobe Reader 7.0.8 for Linux doesn't */ 795 /* accept a font that contains charstrings like */ 796 /* */ 1218 case op_hsbw: 1219 FT_TRACE4(( " hsbw" )); 1220 1221 builder->parse_state = T1_Parse_Have_Width; 1222 1223 builder->left_bearing.x = ADD_LONG( builder->left_bearing.x, 1224 top[0] ); 1225 1226 builder->advance.x = top[1]; 1227 builder->advance.y = 0; 1228 1229 orig_x = x = ADD_LONG( builder->pos_x, top[0] ); 1230 orig_y = y = builder->pos_y; 1231 1232 FT_UNUSED( orig_y ); 1233 1234 /* the `metrics_only' indicates that we only want to compute */ 1235 /* the glyph's metrics (lsb + advance width), not load the */ 1236 /* rest of it; so exit immediately */ 1237 if ( builder->metrics_only ) 1238 { 1239 FT_TRACE4(( "\n" )); 1240 return FT_Err_Ok; 1241 } 1242 1243 break; 1244 1245 case op_seac: 1246 return t1operator_seac( decoder, 1247 top[0], 1248 top[1], 1249 top[2], 1250 Fix2Int( top[3] ), 1251 Fix2Int( top[4] ) ); 1252 1253 case op_sbw: 1254 FT_TRACE4(( " sbw" )); 1255 1256 builder->parse_state = T1_Parse_Have_Width; 1257 1258 builder->left_bearing.x = ADD_LONG( builder->left_bearing.x, 1259 top[0] ); 1260 builder->left_bearing.y = ADD_LONG( builder->left_bearing.y, 1261 top[1] ); 1262 1263 builder->advance.x = top[2]; 1264 builder->advance.y = top[3]; 1265 1266 x = ADD_LONG( builder->pos_x, top[0] ); 1267 y = ADD_LONG( builder->pos_y, top[1] ); 1268 1269 /* the `metrics_only' indicates that we only want to compute */ 1270 /* the glyph's metrics (lsb + advance width), not load the */ 1271 /* rest of it; so exit immediately */ 1272 if ( builder->metrics_only ) 1273 { 1274 FT_TRACE4(( "\n" )); 1275 return FT_Err_Ok; 1276 } 1277 1278 break; 1279 1280 case op_closepath: 1281 FT_TRACE4(( " closepath" )); 1282 1283 /* if there is no path, `closepath' is a no-op */ 1284 if ( builder->parse_state == T1_Parse_Have_Path || 1285 builder->parse_state == T1_Parse_Have_Moveto ) 1286 t1_builder_close_contour( builder ); 1287 1288 builder->parse_state = T1_Parse_Have_Width; 1289 break; 1290 1291 case op_hlineto: 1292 FT_TRACE4(( " hlineto" )); 1293 1294 if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ) 1295 goto Fail; 1296 1639 FT_TRACE4(( "\n" )); 1640 bol = TRUE; 1641 #endif 1642 1643 } /* general operator processing */ 1644 1645 } /* while ip < limit */ 1646 1647 FT_TRACE4(( "..end..\n\n" )); 1648 1649 Fail: 1650 return error; 1651 1652 Syntax_Error: 1653 return FT_THROW( Syntax_Error ); 1654 1655 Stack_Underflow: 1656 return FT_THROW( Stack_Underflow ); 1657 } 1658 1659 1660 #else /* !T1_CONFIG_OPTION_OLD_ENGINE */ 1661 1662 1663 /************************************************************************** 1664 * 1665 * @Function: 1666 * t1_decoder_parse_metrics 1667 * 1668 * @Description: 1669 * Parses a given Type 1 charstrings program to extract width 1670 * 1671 * @Input: 1672 * decoder :: 1673 * The current Type 1 decoder. 1674 * 1675 * charstring_base :: 1676 * The base address of the charstring stream. 1677 * 1678 * charstring_len :: 1679 * The length in bytes of the charstring stream. 1680 * 1681 * @Return: 1682 * FreeType error code. 0 means success. 1683 */ 1684 FT_LOCAL_DEF( FT_Error ) 1685 t1_decoder_parse_metrics( T1_Decoder decoder, 1686 FT_Byte* charstring_base, 1687 FT_UInt charstring_len ) 1688 { 1689 T1_Decoder_Zone zone; 1690 FT_Byte* ip; 1691 FT_Byte* limit; 1692 T1_Builder builder = &decoder->builder; 1693 1694 #ifdef FT_DEBUG_LEVEL_TRACE 1695 FT_Bool bol = TRUE; 1696 #endif 1697 1698 1699 /* First of all, initialize the decoder */ 1700 decoder->top = decoder->stack; 1701 decoder->zone = decoder->zones; 1702 zone = decoder->zones; 1703 1704 builder->parse_state = T1_Parse_Start; 1705 1706 zone->base = charstring_base; 1707 limit = zone->limit = charstring_base + charstring_len; 1708 ip = zone->cursor = zone->base; 1709 1710 /* now, execute loop */ 1711 while ( ip < limit ) 1712 { 1713 FT_Long* top = decoder->top; 1714 T1_Operator op = op_none; 1715 FT_Int32 value = 0; 1716 1717 1718 #ifdef FT_DEBUG_LEVEL_TRACE 1719 if ( bol ) 1720 { 1721 FT_TRACE5(( " (%d)", decoder->top - decoder->stack )); 1722 bol = FALSE; 1723 } 1724 #endif 1725 1726 /********************************************************************** 1727 * 1728 * Decode operator or operand 1729 * 1730 */ 1731 1732 /* first of all, decompress operator or value */ 1733 switch ( *ip++ ) 1734 { 1735 case 1: 1736 case 3: 1737 case 4: 1738 case 5: 1739 case 6: 1740 case 7: 1741 case 8: 1742 case 9: 1743 case 10: 1744 case 11: 1745 case 14: 1746 case 15: 1747 case 21: 1748 case 22: 1749 case 30: 1750 case 31: 1820 " unexpected EOF in integer\n" )); 1821 goto Syntax_Error; 1822 } 1823 1824 if ( ip[-2] < 251 ) 1825 value = ( ( ip[-2] - 247 ) * 256 ) + ip[-1] + 108; 1826 else 1827 value = -( ( ( ip[-2] - 251 ) * 256 ) + ip[-1] + 108 ); 1828 } 1829 1830 value = (FT_Int32)( (FT_UInt32)value << 16 ); 1831 } 1832 else 1833 { 1834 FT_ERROR(( "t1_decoder_parse_metrics:" 1835 " invalid byte (%d)\n", ip[-1] )); 1836 goto Syntax_Error; 1837 } 1838 } 1839 1840 /********************************************************************** 1841 * 1842 * Push value on stack, or process operator 1843 * 1844 */ 1845 if ( op == op_none ) 1846 { 1847 if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS ) 1848 { 1849 FT_ERROR(( "t1_decoder_parse_metrics: stack overflow\n" )); 1850 goto Syntax_Error; 1851 } 1852 1853 #ifdef FT_DEBUG_LEVEL_TRACE 1854 FT_TRACE4(( " %d", value / 65536 )); 1855 #endif 1856 1857 *top++ = value; 1858 decoder->top = top; 1859 } 1860 else /* general operator */ 1861 { 1862 FT_Int num_args = t1_args_count[op]; 1863 1864 1878 #endif /* FT_DEBUG_LEVEL_TRACE */ 1879 1880 top -= num_args; 1881 1882 switch ( op ) 1883 { 1884 case op_hsbw: 1885 FT_TRACE4(( " hsbw" )); 1886 1887 builder->parse_state = T1_Parse_Have_Width; 1888 1889 builder->left_bearing.x = ADD_LONG( builder->left_bearing.x, 1890 top[0] ); 1891 1892 builder->advance.x = top[1]; 1893 builder->advance.y = 0; 1894 1895 /* we only want to compute the glyph's metrics */ 1896 /* (lsb + advance width), not load the rest of */ 1897 /* it; so exit immediately */ 1898 FT_TRACE4(( "\n" )); 1899 return FT_Err_Ok; 1900 1901 case op_sbw: 1902 FT_TRACE4(( " sbw" )); 1903 1904 builder->parse_state = T1_Parse_Have_Width; 1905 1906 builder->left_bearing.x = ADD_LONG( builder->left_bearing.x, 1907 top[0] ); 1908 builder->left_bearing.y = ADD_LONG( builder->left_bearing.y, 1909 top[1] ); 1910 1911 builder->advance.x = top[2]; 1912 builder->advance.y = top[3]; 1913 1914 /* we only want to compute the glyph's metrics */ 1915 /* (lsb + advance width), not load the rest of */ 1916 /* it; so exit immediately */ 1917 FT_TRACE4(( "\n" )); 1918 return FT_Err_Ok; 1919 1920 default: 1921 FT_ERROR(( "t1_decoder_parse_metrics:" 1922 " unhandled opcode %d\n", op )); 1923 goto Syntax_Error; 1924 } 1925 1926 } /* general operator processing */ 1927 1928 } /* while ip < limit */ 1929 1930 FT_TRACE4(( "..end..\n\n" )); 1931 1932 No_Width: 1933 FT_ERROR(( "t1_decoder_parse_metrics:" 1934 " no width, found op %d instead\n", 1935 ip[-1] )); 1936 Syntax_Error: 1937 return FT_THROW( Syntax_Error ); 1938 1939 Stack_Underflow: 1940 return FT_THROW( Stack_Underflow ); 1941 } 1942 1943 #endif /* !T1_CONFIG_OPTION_OLD_ENGINE */ 1944 1945 1946 /* initialize T1 decoder */ 1947 FT_LOCAL_DEF( FT_Error ) 1948 t1_decoder_init( T1_Decoder decoder, 1949 FT_Face face, 1950 FT_Size size, 1951 FT_GlyphSlot slot, 1952 FT_Byte** glyph_names, 1953 PS_Blend blend, 1954 FT_Bool hinting, 1955 FT_Render_Mode hint_mode, 1956 T1_Decoder_Callback parse_callback ) 1957 { 1958 FT_ZERO( decoder ); 1959 1960 /* retrieve `psnames' interface from list of current modules */ 1961 { 1962 FT_Service_PsCMaps psnames; 1963 1964 1965 FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); 1966 if ( !psnames ) 1967 { 1968 FT_ERROR(( "t1_decoder_init:" 1969 " the `psnames' module is not available\n" )); 1970 return FT_THROW( Unimplemented_Feature ); 1971 } 1972 1973 decoder->psnames = psnames; 1974 } 1975 1976 t1_builder_init( &decoder->builder, face, size, slot, hinting ); 1977 1978 /* decoder->buildchar and decoder->len_buildchar have to be */ 1979 /* initialized by the caller since we cannot know the length */ 1980 /* of the BuildCharArray */ |