00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <ft2build.h>
00021 #include FT_INTERNAL_CALC_H
00022 #include FT_INTERNAL_DEBUG_H
00023 #include FT_INTERNAL_POSTSCRIPT_HINTS_H
00024 #include FT_OUTLINE_H
00025
00026 #include "t1decode.h"
00027 #include "psobjs.h"
00028
00029 #include "psauxerr.h"
00030
00031
00032
00033
00034
00035
00036
00037
00038 #undef FT_COMPONENT
00039 #define FT_COMPONENT trace_t1decode
00040
00041
00042 typedef enum T1_Operator_
00043 {
00044 op_none = 0,
00045 op_endchar,
00046 op_hsbw,
00047 op_seac,
00048 op_sbw,
00049 op_closepath,
00050 op_hlineto,
00051 op_hmoveto,
00052 op_hvcurveto,
00053 op_rlineto,
00054 op_rmoveto,
00055 op_rrcurveto,
00056 op_vhcurveto,
00057 op_vlineto,
00058 op_vmoveto,
00059 op_dotsection,
00060 op_hstem,
00061 op_hstem3,
00062 op_vstem,
00063 op_vstem3,
00064 op_div,
00065 op_callothersubr,
00066 op_callsubr,
00067 op_pop,
00068 op_return,
00069 op_setcurrentpoint,
00070 op_unknown15,
00071
00072 op_max
00073
00074 } T1_Operator;
00075
00076
00077 static
00078 const FT_Int t1_args_count[op_max] =
00079 {
00080 0,
00081 0,
00082 2,
00083 5,
00084 4,
00085 0,
00086 1,
00087 1,
00088 4,
00089 2,
00090 2,
00091 6,
00092 4,
00093 1,
00094 1,
00095 0,
00096 2,
00097 6,
00098 2,
00099 6,
00100 2,
00101 -1,
00102 1,
00103 0,
00104 0,
00105 2,
00106 2
00107 };
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128 static FT_Int
00129 t1_lookup_glyph_by_stdcharcode( T1_Decoder decoder,
00130 FT_Int charcode )
00131 {
00132 FT_UInt n;
00133 const FT_String* glyph_name;
00134 FT_Service_PsCMaps psnames = decoder->psnames;
00135
00136
00137
00138 if ( charcode < 0 || charcode > 255 )
00139 return -1;
00140
00141 glyph_name = psnames->adobe_std_strings(
00142 psnames->adobe_std_encoding[charcode]);
00143
00144 for ( n = 0; n < decoder->num_glyphs; n++ )
00145 {
00146 FT_String* name = (FT_String*)decoder->glyph_names[n];
00147
00148
00149 if ( name &&
00150 name[0] == glyph_name[0] &&
00151 ft_strcmp( name, glyph_name ) == 0 )
00152 return n;
00153 }
00154
00155 return -1;
00156 }
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 static FT_Error
00184 t1operator_seac( T1_Decoder decoder,
00185 FT_Pos asb,
00186 FT_Pos adx,
00187 FT_Pos ady,
00188 FT_Int bchar,
00189 FT_Int achar )
00190 {
00191 FT_Error error;
00192 FT_Int bchar_index, achar_index;
00193 #if 0
00194 FT_Int n_base_points;
00195 FT_Outline* base = decoder->builder.base;
00196 #endif
00197 FT_Vector left_bearing, advance;
00198
00199 #ifdef FT_CONFIG_OPTION_INCREMENTAL
00200 T1_Face face = (T1_Face)decoder->builder.face;
00201 #endif
00202
00203
00204 if ( decoder->seac )
00205 {
00206 FT_ERROR(( "t1operator_seac: invalid nested seac\n" ));
00207 return PSaux_Err_Syntax_Error;
00208 }
00209
00210
00211 adx += decoder->builder.left_bearing.x;
00212
00213
00214
00215 #ifdef FT_CONFIG_OPTION_INCREMENTAL
00216 if ( decoder->glyph_names == 0 &&
00217 !face->root.internal->incremental_interface )
00218 #else
00219 if ( decoder->glyph_names == 0 )
00220 #endif
00221 {
00222 FT_ERROR(( "t1operator_seac:"
00223 " glyph names table not available in this font\n" ));
00224 return PSaux_Err_Syntax_Error;
00225 }
00226
00227 #ifdef FT_CONFIG_OPTION_INCREMENTAL
00228 if ( face->root.internal->incremental_interface )
00229 {
00230
00231 bchar_index = bchar;
00232 achar_index = achar;
00233 }
00234 else
00235 #endif
00236 {
00237 bchar_index = t1_lookup_glyph_by_stdcharcode( decoder, bchar );
00238 achar_index = t1_lookup_glyph_by_stdcharcode( decoder, achar );
00239 }
00240
00241 if ( bchar_index < 0 || achar_index < 0 )
00242 {
00243 FT_ERROR(( "t1operator_seac:"
00244 " invalid seac character code arguments\n" ));
00245 return PSaux_Err_Syntax_Error;
00246 }
00247
00248
00249
00250 if ( decoder->builder.no_recurse )
00251 {
00252 FT_GlyphSlot glyph = (FT_GlyphSlot)decoder->builder.glyph;
00253 FT_GlyphLoader loader = glyph->internal->loader;
00254 FT_SubGlyph subg;
00255
00256
00257
00258 error = FT_GlyphLoader_CheckSubGlyphs( loader, 2 );
00259 if ( error )
00260 goto Exit;
00261
00262 subg = loader->current.subglyphs;
00263
00264
00265 subg->index = bchar_index;
00266 subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES |
00267 FT_SUBGLYPH_FLAG_USE_MY_METRICS;
00268 subg->arg1 = 0;
00269 subg->arg2 = 0;
00270 subg++;
00271
00272
00273 subg->index = achar_index;
00274 subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES;
00275 subg->arg1 = (FT_Int)FIXED_TO_INT( adx - asb );
00276 subg->arg2 = (FT_Int)FIXED_TO_INT( ady );
00277
00278
00279 glyph->num_subglyphs = 2;
00280 glyph->subglyphs = loader->base.subglyphs;
00281 glyph->format = FT_GLYPH_FORMAT_COMPOSITE;
00282
00283 loader->current.num_subglyphs = 2;
00284 goto Exit;
00285 }
00286
00287
00288
00289
00290 FT_GlyphLoader_Prepare( decoder->builder.loader );
00291
00292
00293 decoder->seac = TRUE;
00294 error = t1_decoder_parse_glyph( decoder, bchar_index );
00295 decoder->seac = FALSE;
00296 if ( error )
00297 goto Exit;
00298
00299
00300
00301
00302 left_bearing = decoder->builder.left_bearing;
00303 advance = decoder->builder.advance;
00304
00305 decoder->builder.left_bearing.x = 0;
00306 decoder->builder.left_bearing.y = 0;
00307
00308 decoder->builder.pos_x = adx - asb;
00309 decoder->builder.pos_y = ady;
00310
00311
00312
00313
00314
00315 decoder->seac = TRUE;
00316 error = t1_decoder_parse_glyph( decoder, achar_index );
00317 decoder->seac = FALSE;
00318 if ( error )
00319 goto Exit;
00320
00321
00322
00323
00324 decoder->builder.left_bearing = left_bearing;
00325 decoder->builder.advance = advance;
00326
00327 decoder->builder.pos_x = 0;
00328 decoder->builder.pos_y = 0;
00329
00330 Exit:
00331 return error;
00332 }
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353 FT_LOCAL_DEF( FT_Error )
00354 t1_decoder_parse_charstrings( T1_Decoder decoder,
00355 FT_Byte* charstring_base,
00356 FT_UInt charstring_len )
00357 {
00358 FT_Error error;
00359 T1_Decoder_Zone zone;
00360 FT_Byte* ip;
00361 FT_Byte* limit;
00362 T1_Builder builder = &decoder->builder;
00363 FT_Pos x, y, orig_x, orig_y;
00364 FT_Int known_othersubr_result_cnt = 0;
00365 FT_Int unknown_othersubr_result_cnt = 0;
00366 FT_Bool large_int;
00367 FT_Fixed seed;
00368
00369 T1_Hints_Funcs hinter;
00370
00371 #ifdef FT_DEBUG_LEVEL_TRACE
00372 FT_Bool bol = TRUE;
00373 #endif
00374
00375
00376
00377 #define start_point t1_builder_start_point
00378 #define check_points t1_builder_check_points
00379 #define add_point t1_builder_add_point
00380 #define add_point1 t1_builder_add_point1
00381 #define add_contour t1_builder_add_contour
00382 #define close_contour t1_builder_close_contour
00383
00384
00385
00386 seed = (FT_Fixed)( ( (FT_PtrDist)(char*)&seed ^
00387 (FT_PtrDist)(char*)&decoder ^
00388 (FT_PtrDist)(char*)&charstring_base ) &
00389 FT_ULONG_MAX ) ;
00390 seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL;
00391 if ( seed == 0 )
00392 seed = 0x7384;
00393
00394
00395 decoder->top = decoder->stack;
00396 decoder->zone = decoder->zones;
00397 zone = decoder->zones;
00398
00399 builder->parse_state = T1_Parse_Start;
00400
00401 hinter = (T1_Hints_Funcs)builder->hints_funcs;
00402
00403
00404
00405 FT_ASSERT( ( decoder->len_buildchar == 0 ) ==
00406 ( decoder->buildchar == NULL ) );
00407
00408 if ( decoder->len_buildchar > 0 )
00409 ft_memset( &decoder->buildchar[0],
00410 0,
00411 sizeof( decoder->buildchar[0] ) * decoder->len_buildchar );
00412
00413 FT_TRACE4(( "\n"
00414 "Start charstring\n" ));
00415
00416 zone->base = charstring_base;
00417 limit = zone->limit = charstring_base + charstring_len;
00418 ip = zone->cursor = zone->base;
00419
00420 error = PSaux_Err_Ok;
00421
00422 x = orig_x = builder->pos_x;
00423 y = orig_y = builder->pos_y;
00424
00425
00426 if ( hinter )
00427 hinter->open( hinter->hints );
00428
00429 large_int = FALSE;
00430
00431
00432 while ( ip < limit )
00433 {
00434 FT_Long* top = decoder->top;
00435 T1_Operator op = op_none;
00436 FT_Int32 value = 0;
00437
00438
00439 FT_ASSERT( known_othersubr_result_cnt == 0 ||
00440 unknown_othersubr_result_cnt == 0 );
00441
00442 #ifdef FT_DEBUG_LEVEL_TRACE
00443 if ( bol )
00444 {
00445 FT_TRACE5(( " (%d)", decoder->top - decoder->stack ));
00446 bol = FALSE;
00447 }
00448 #endif
00449
00450
00451
00452
00453
00454
00455
00456
00457 switch ( *ip++ )
00458 {
00459 case 1:
00460 op = op_hstem;
00461 break;
00462
00463 case 3:
00464 op = op_vstem;
00465 break;
00466 case 4:
00467 op = op_vmoveto;
00468 break;
00469 case 5:
00470 op = op_rlineto;
00471 break;
00472 case 6:
00473 op = op_hlineto;
00474 break;
00475 case 7:
00476 op = op_vlineto;
00477 break;
00478 case 8:
00479 op = op_rrcurveto;
00480 break;
00481 case 9:
00482 op = op_closepath;
00483 break;
00484 case 10:
00485 op = op_callsubr;
00486 break;
00487 case 11:
00488 op = op_return;
00489 break;
00490
00491 case 13:
00492 op = op_hsbw;
00493 break;
00494 case 14:
00495 op = op_endchar;
00496 break;
00497
00498 case 15:
00499 op = op_unknown15;
00500 break;
00501
00502 case 21:
00503 op = op_rmoveto;
00504 break;
00505 case 22:
00506 op = op_hmoveto;
00507 break;
00508
00509 case 30:
00510 op = op_vhcurveto;
00511 break;
00512 case 31:
00513 op = op_hvcurveto;
00514 break;
00515
00516 case 12:
00517 if ( ip > limit )
00518 {
00519 FT_ERROR(( "t1_decoder_parse_charstrings:"
00520 " invalid escape (12+EOF)\n" ));
00521 goto Syntax_Error;
00522 }
00523
00524 switch ( *ip++ )
00525 {
00526 case 0:
00527 op = op_dotsection;
00528 break;
00529 case 1:
00530 op = op_vstem3;
00531 break;
00532 case 2:
00533 op = op_hstem3;
00534 break;
00535 case 6:
00536 op = op_seac;
00537 break;
00538 case 7:
00539 op = op_sbw;
00540 break;
00541 case 12:
00542 op = op_div;
00543 break;
00544 case 16:
00545 op = op_callothersubr;
00546 break;
00547 case 17:
00548 op = op_pop;
00549 break;
00550 case 33:
00551 op = op_setcurrentpoint;
00552 break;
00553
00554 default:
00555 FT_ERROR(( "t1_decoder_parse_charstrings:"
00556 " invalid escape (12+%d)\n",
00557 ip[-1] ));
00558 goto Syntax_Error;
00559 }
00560 break;
00561
00562 case 255:
00563 if ( ip + 4 > limit )
00564 {
00565 FT_ERROR(( "t1_decoder_parse_charstrings:"
00566 " unexpected EOF in integer\n" ));
00567 goto Syntax_Error;
00568 }
00569
00570 value = (FT_Int32)( ( (FT_Long)ip[0] << 24 ) |
00571 ( (FT_Long)ip[1] << 16 ) |
00572 ( (FT_Long)ip[2] << 8 ) |
00573 ip[3] );
00574 ip += 4;
00575
00576
00577
00578
00579
00580
00581
00582
00583 if ( value > 32000 || value < -32000 )
00584 {
00585 if ( large_int )
00586 {
00587 FT_ERROR(( "t1_decoder_parse_charstrings:"
00588 " no `div' after large integer\n" ));
00589 }
00590 else
00591 large_int = TRUE;
00592 }
00593 else
00594 {
00595 if ( !large_int )
00596 value <<= 16;
00597 }
00598
00599 break;
00600
00601 default:
00602 if ( ip[-1] >= 32 )
00603 {
00604 if ( ip[-1] < 247 )
00605 value = (FT_Int32)ip[-1] - 139;
00606 else
00607 {
00608 if ( ++ip > limit )
00609 {
00610 FT_ERROR(( "t1_decoder_parse_charstrings:"
00611 " unexpected EOF in integer\n" ));
00612 goto Syntax_Error;
00613 }
00614
00615 if ( ip[-2] < 251 )
00616 value = ( ( (FT_Int32)ip[-2] - 247 ) << 8 ) + ip[-1] + 108;
00617 else
00618 value = -( ( ( (FT_Int32)ip[-2] - 251 ) << 8 ) + ip[-1] + 108 );
00619 }
00620
00621 if ( !large_int )
00622 value <<= 16;
00623 }
00624 else
00625 {
00626 FT_ERROR(( "t1_decoder_parse_charstrings:"
00627 " invalid byte (%d)\n", ip[-1] ));
00628 goto Syntax_Error;
00629 }
00630 }
00631
00632 if ( unknown_othersubr_result_cnt > 0 )
00633 {
00634 switch ( op )
00635 {
00636 case op_callsubr:
00637 case op_return:
00638 case op_none:
00639 case op_pop:
00640 break;
00641
00642 default:
00643
00644 unknown_othersubr_result_cnt = 0;
00645 break;
00646 }
00647 }
00648
00649 if ( large_int && !( op == op_none || op == op_div ) )
00650 {
00651 FT_ERROR(( "t1_decoder_parse_charstrings:"
00652 " no `div' after large integer\n" ));
00653
00654 large_int = FALSE;
00655 }
00656
00657
00658
00659
00660
00661
00662 if ( op == op_none )
00663 {
00664 if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS )
00665 {
00666 FT_ERROR(( "t1_decoder_parse_charstrings: stack overflow\n" ));
00667 goto Syntax_Error;
00668 }
00669
00670 #ifdef FT_DEBUG_LEVEL_TRACE
00671 if ( large_int )
00672 FT_TRACE4(( " %ld", value ));
00673 else
00674 FT_TRACE4(( " %ld", (FT_Int32)( value >> 16 ) ));
00675 #endif
00676
00677 *top++ = value;
00678 decoder->top = top;
00679 }
00680 else if ( op == op_callothersubr )
00681 {
00682 FT_Int subr_no;
00683 FT_Int arg_cnt;
00684
00685
00686 #ifdef FT_DEBUG_LEVEL_TRACE
00687 FT_TRACE4(( " callothersubr\n" ));
00688 bol = TRUE;
00689 #endif
00690
00691 if ( top - decoder->stack < 2 )
00692 goto Stack_Underflow;
00693
00694 top -= 2;
00695
00696 subr_no = (FT_Int)( top[1] >> 16 );
00697 arg_cnt = (FT_Int)( top[0] >> 16 );
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710 if ( arg_cnt > top - decoder->stack )
00711 goto Stack_Underflow;
00712
00713 top -= arg_cnt;
00714
00715 known_othersubr_result_cnt = 0;
00716 unknown_othersubr_result_cnt = 0;
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734 switch ( subr_no )
00735 {
00736 case 1:
00737 if ( arg_cnt != 0 )
00738 goto Unexpected_OtherSubr;
00739
00740 decoder->flex_state = 1;
00741 decoder->num_flex_vectors = 0;
00742 if ( start_point( builder, x, y ) ||
00743 check_points( builder, 6 ) )
00744 goto Fail;
00745 break;
00746
00747 case 2:
00748 {
00749 FT_Int idx;
00750
00751
00752 if ( arg_cnt != 0 )
00753 goto Unexpected_OtherSubr;
00754
00755
00756
00757
00758 idx = decoder->num_flex_vectors++;
00759 if ( idx > 0 && idx < 7 )
00760 add_point( builder,
00761 x,
00762 y,
00763 (FT_Byte)( idx == 3 || idx == 6 ) );
00764 }
00765 break;
00766
00767 case 0:
00768 if ( arg_cnt != 3 )
00769 goto Unexpected_OtherSubr;
00770
00771 if ( decoder->flex_state == 0 ||
00772 decoder->num_flex_vectors != 7 )
00773 {
00774 FT_ERROR(( "t1_decoder_parse_charstrings:"
00775 " unexpected flex end\n" ));
00776 goto Syntax_Error;
00777 }
00778
00779
00780 known_othersubr_result_cnt = 2;
00781 break;
00782
00783 case 3:
00784 if ( arg_cnt != 1 )
00785 goto Unexpected_OtherSubr;
00786
00787 known_othersubr_result_cnt = 1;
00788
00789 if ( hinter )
00790 hinter->reset( hinter->hints, builder->current->n_points );
00791 break;
00792
00793 case 12:
00794 case 13:
00795
00796 top = decoder->stack;
00797 break;
00798
00799 case 14:
00800 case 15:
00801 case 16:
00802 case 17:
00803 case 18:
00804 {
00805 PS_Blend blend = decoder->blend;
00806 FT_UInt num_points, nn, mm;
00807 FT_Long* delta;
00808 FT_Long* values;
00809
00810
00811 if ( !blend )
00812 {
00813 FT_ERROR(( "t1_decoder_parse_charstrings:"
00814 " unexpected multiple masters operator\n" ));
00815 goto Syntax_Error;
00816 }
00817
00818 num_points = (FT_UInt)subr_no - 13 + ( subr_no == 18 );
00819 if ( arg_cnt != (FT_Int)( num_points * blend->num_designs ) )
00820 {
00821 FT_ERROR(( "t1_decoder_parse_charstrings:"
00822 " incorrect number of multiple masters arguments\n" ));
00823 goto Syntax_Error;
00824 }
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841 delta = top + num_points;
00842 values = top;
00843 for ( nn = 0; nn < num_points; nn++ )
00844 {
00845 FT_Long tmp = values[0];
00846
00847
00848 for ( mm = 1; mm < blend->num_designs; mm++ )
00849 tmp += FT_MulFix( *delta++, blend->weight_vector[mm] );
00850
00851 *values++ = tmp;
00852 }
00853
00854 known_othersubr_result_cnt = num_points;
00855 break;
00856 }
00857
00858 case 19:
00859
00860
00861
00862 {
00863 FT_Int idx;
00864 PS_Blend blend = decoder->blend;
00865
00866
00867 if ( arg_cnt != 1 || blend == NULL )
00868 goto Unexpected_OtherSubr;
00869
00870 idx = (FT_Int)( top[0] >> 16 );
00871
00872 if ( idx < 0 ||
00873 idx + blend->num_designs > decoder->len_buildchar )
00874 goto Unexpected_OtherSubr;
00875
00876 ft_memcpy( &decoder->buildchar[idx],
00877 blend->weight_vector,
00878 blend->num_designs *
00879 sizeof( blend->weight_vector[0] ) );
00880 }
00881 break;
00882
00883 case 20:
00884
00885
00886 if ( arg_cnt != 2 )
00887 goto Unexpected_OtherSubr;
00888
00889 top[0] += top[1];
00890
00891 known_othersubr_result_cnt = 1;
00892 break;
00893
00894 case 21:
00895
00896
00897 if ( arg_cnt != 2 )
00898 goto Unexpected_OtherSubr;
00899
00900 top[0] -= top[1];
00901
00902 known_othersubr_result_cnt = 1;
00903 break;
00904
00905 case 22:
00906
00907
00908 if ( arg_cnt != 2 )
00909 goto Unexpected_OtherSubr;
00910
00911 top[0] = FT_MulFix( top[0], top[1] );
00912
00913 known_othersubr_result_cnt = 1;
00914 break;
00915
00916 case 23:
00917
00918
00919 if ( arg_cnt != 2 || top[1] == 0 )
00920 goto Unexpected_OtherSubr;
00921
00922 top[0] = FT_DivFix( top[0], top[1] );
00923
00924 known_othersubr_result_cnt = 1;
00925 break;
00926
00927 case 24:
00928
00929
00930 {
00931 FT_Int idx;
00932 PS_Blend blend = decoder->blend;
00933
00934
00935 if ( arg_cnt != 2 || blend == NULL )
00936 goto Unexpected_OtherSubr;
00937
00938 idx = (FT_Int)( top[1] >> 16 );
00939
00940 if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar )
00941 goto Unexpected_OtherSubr;
00942
00943 decoder->buildchar[idx] = top[0];
00944 }
00945 break;
00946
00947 case 25:
00948
00949
00950
00951 {
00952 FT_Int idx;
00953 PS_Blend blend = decoder->blend;
00954
00955
00956 if ( arg_cnt != 1 || blend == NULL )
00957 goto Unexpected_OtherSubr;
00958
00959 idx = (FT_Int)( top[0] >> 16 );
00960
00961 if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar )
00962 goto Unexpected_OtherSubr;
00963
00964 top[0] = decoder->buildchar[idx];
00965 }
00966
00967 known_othersubr_result_cnt = 1;
00968 break;
00969
00970 #if 0
00971 case 26:
00972
00973
00974
00975 XXX which routine has left its mark on the (PostScript) stack?;
00976 break;
00977 #endif
00978
00979 case 27:
00980
00981
00982
00983 if ( arg_cnt != 4 )
00984 goto Unexpected_OtherSubr;
00985
00986 if ( top[2] > top[3] )
00987 top[0] = top[1];
00988
00989 known_othersubr_result_cnt = 1;
00990 break;
00991
00992 case 28:
00993
00994
00995 if ( arg_cnt != 0 )
00996 goto Unexpected_OtherSubr;
00997
00998 {
00999 FT_Fixed Rand;
01000
01001
01002 Rand = seed;
01003 if ( Rand >= 0x8000L )
01004 Rand++;
01005
01006 top[0] = Rand;
01007
01008 seed = FT_MulFix( seed, 0x10000L - seed );
01009 if ( seed == 0 )
01010 seed += 0x2873;
01011 }
01012
01013 known_othersubr_result_cnt = 1;
01014 break;
01015
01016 default:
01017 FT_ERROR(( "t1_decoder_parse_charstrings:"
01018 " unknown othersubr [%d %d], wish me luck\n",
01019 arg_cnt, subr_no ));
01020 unknown_othersubr_result_cnt = arg_cnt;
01021 break;
01022
01023 Unexpected_OtherSubr:
01024 FT_ERROR(( "t1_decoder_parse_charstrings:"
01025 " invalid othersubr [%d %d]\n", arg_cnt, subr_no ));
01026 goto Syntax_Error;
01027 }
01028
01029 top += known_othersubr_result_cnt;
01030
01031 decoder->top = top;
01032 }
01033 else
01034 {
01035 FT_Int num_args = t1_args_count[op];
01036
01037
01038 FT_ASSERT( num_args >= 0 );
01039
01040 if ( top - decoder->stack < num_args )
01041 goto Stack_Underflow;
01042
01043
01044
01045
01046
01047
01048
01049 #ifdef FT_DEBUG_LEVEL_TRACE
01050
01051 switch ( op )
01052 {
01053 case op_callsubr:
01054 case op_div:
01055 case op_callothersubr:
01056 case op_pop:
01057 case op_return:
01058 break;
01059
01060 default:
01061 if ( top - decoder->stack != num_args )
01062 FT_TRACE0(( "t1_decoder_parse_charstrings:"
01063 " too much operands on the stack"
01064 " (seen %d, expected %d)\n",
01065 top - decoder->stack, num_args ));
01066 break;
01067 }
01068
01069 #endif
01070
01071 top -= num_args;
01072
01073 switch ( op )
01074 {
01075 case op_endchar:
01076 FT_TRACE4(( " endchar\n" ));
01077
01078 close_contour( builder );
01079
01080
01081 if ( hinter )
01082 {
01083 if ( hinter->close( hinter->hints, builder->current->n_points ) )
01084 goto Syntax_Error;
01085
01086
01087 hinter->apply( hinter->hints,
01088 builder->current,
01089 (PSH_Globals)builder->hints_globals,
01090 decoder->hint_mode );
01091 }
01092
01093
01094 FT_GlyphLoader_Add( builder->loader );
01095
01096
01097
01098 #ifdef FT_DEBUG_LEVEL_TRACE
01099
01100 if ( decoder->len_buildchar > 0 )
01101 {
01102 FT_UInt i;
01103
01104
01105 FT_TRACE4(( "BuildCharArray = [ " ));
01106
01107 for ( i = 0; i < decoder->len_buildchar; ++i )
01108 FT_TRACE4(( "%d ", decoder->buildchar[ i ] ));
01109
01110 FT_TRACE4(( "]\n" ));
01111 }
01112
01113 #endif
01114
01115 FT_TRACE4(( "\n" ));
01116
01117
01118 return PSaux_Err_Ok;
01119
01120 case op_hsbw:
01121 FT_TRACE4(( " hsbw" ));
01122
01123 builder->parse_state = T1_Parse_Have_Width;
01124
01125 builder->left_bearing.x += top[0];
01126 builder->advance.x = top[1];
01127 builder->advance.y = 0;
01128
01129 orig_x = x = builder->pos_x + top[0];
01130 orig_y = y = builder->pos_y;
01131
01132 FT_UNUSED( orig_y );
01133
01134
01135
01136
01137 if ( builder->metrics_only )
01138 return PSaux_Err_Ok;
01139
01140 break;
01141
01142 case op_seac:
01143 return t1operator_seac( decoder,
01144 top[0],
01145 top[1],
01146 top[2],
01147 (FT_Int)( top[3] >> 16 ),
01148 (FT_Int)( top[4] >> 16 ) );
01149
01150 case op_sbw:
01151 FT_TRACE4(( " sbw" ));
01152
01153 builder->parse_state = T1_Parse_Have_Width;
01154
01155 builder->left_bearing.x += top[0];
01156 builder->left_bearing.y += top[1];
01157 builder->advance.x = top[2];
01158 builder->advance.y = top[3];
01159
01160 x = builder->pos_x + top[0];
01161 y = builder->pos_y + top[1];
01162
01163
01164
01165
01166 if ( builder->metrics_only )
01167 return PSaux_Err_Ok;
01168
01169 break;
01170
01171 case op_closepath:
01172 FT_TRACE4(( " closepath" ));
01173
01174
01175 if ( builder->parse_state == T1_Parse_Have_Path ||
01176 builder->parse_state == T1_Parse_Have_Moveto )
01177 close_contour( builder );
01178
01179 builder->parse_state = T1_Parse_Have_Width;
01180 break;
01181
01182 case op_hlineto:
01183 FT_TRACE4(( " hlineto" ));
01184
01185 if ( start_point( builder, x, y ) )
01186 goto Fail;
01187
01188 x += top[0];
01189 goto Add_Line;
01190
01191 case op_hmoveto:
01192 FT_TRACE4(( " hmoveto" ));
01193
01194 x += top[0];
01195 if ( !decoder->flex_state )
01196 {
01197 if ( builder->parse_state == T1_Parse_Start )
01198 goto Syntax_Error;
01199 builder->parse_state = T1_Parse_Have_Moveto;
01200 }
01201 break;
01202
01203 case op_hvcurveto:
01204 FT_TRACE4(( " hvcurveto" ));
01205
01206 if ( start_point( builder, x, y ) ||
01207 check_points( builder, 3 ) )
01208 goto Fail;
01209
01210 x += top[0];
01211 add_point( builder, x, y, 0 );
01212 x += top[1];
01213 y += top[2];
01214 add_point( builder, x, y, 0 );
01215 y += top[3];
01216 add_point( builder, x, y, 1 );
01217 break;
01218
01219 case op_rlineto:
01220 FT_TRACE4(( " rlineto" ));
01221
01222 if ( start_point( builder, x, y ) )
01223 goto Fail;
01224
01225 x += top[0];
01226 y += top[1];
01227
01228 Add_Line:
01229 if ( add_point1( builder, x, y ) )
01230 goto Fail;
01231 break;
01232
01233 case op_rmoveto:
01234 FT_TRACE4(( " rmoveto" ));
01235
01236 x += top[0];
01237 y += top[1];
01238 if ( !decoder->flex_state )
01239 {
01240 if ( builder->parse_state == T1_Parse_Start )
01241 goto Syntax_Error;
01242 builder->parse_state = T1_Parse_Have_Moveto;
01243 }
01244 break;
01245
01246 case op_rrcurveto:
01247 FT_TRACE4(( " rrcurveto" ));
01248
01249 if ( start_point( builder, x, y ) ||
01250 check_points( builder, 3 ) )
01251 goto Fail;
01252
01253 x += top[0];
01254 y += top[1];
01255 add_point( builder, x, y, 0 );
01256
01257 x += top[2];
01258 y += top[3];
01259 add_point( builder, x, y, 0 );
01260
01261 x += top[4];
01262 y += top[5];
01263 add_point( builder, x, y, 1 );
01264 break;
01265
01266 case op_vhcurveto:
01267 FT_TRACE4(( " vhcurveto" ));
01268
01269 if ( start_point( builder, x, y ) ||
01270 check_points( builder, 3 ) )
01271 goto Fail;
01272
01273 y += top[0];
01274 add_point( builder, x, y, 0 );
01275 x += top[1];
01276 y += top[2];
01277 add_point( builder, x, y, 0 );
01278 x += top[3];
01279 add_point( builder, x, y, 1 );
01280 break;
01281
01282 case op_vlineto:
01283 FT_TRACE4(( " vlineto" ));
01284
01285 if ( start_point( builder, x, y ) )
01286 goto Fail;
01287
01288 y += top[0];
01289 goto Add_Line;
01290
01291 case op_vmoveto:
01292 FT_TRACE4(( " vmoveto" ));
01293
01294 y += top[0];
01295 if ( !decoder->flex_state )
01296 {
01297 if ( builder->parse_state == T1_Parse_Start )
01298 goto Syntax_Error;
01299 builder->parse_state = T1_Parse_Have_Moveto;
01300 }
01301 break;
01302
01303 case op_div:
01304 FT_TRACE4(( " div" ));
01305
01306
01307
01308
01309 *top = FT_DivFix( top[0], top[1] );
01310 ++top;
01311
01312 large_int = FALSE;
01313 break;
01314
01315 case op_callsubr:
01316 {
01317 FT_Int idx;
01318
01319
01320 FT_TRACE4(( " callsubr" ));
01321
01322 idx = (FT_Int)( top[0] >> 16 );
01323 if ( idx < 0 || idx >= (FT_Int)decoder->num_subrs )
01324 {
01325 FT_ERROR(( "t1_decoder_parse_charstrings:"
01326 " invalid subrs index\n" ));
01327 goto Syntax_Error;
01328 }
01329
01330 if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS )
01331 {
01332 FT_ERROR(( "t1_decoder_parse_charstrings:"
01333 " too many nested subrs\n" ));
01334 goto Syntax_Error;
01335 }
01336
01337 zone->cursor = ip;
01338
01339 zone++;
01340
01341
01342
01343
01344 zone->base = decoder->subrs[idx];
01345
01346 if ( decoder->subrs_len )
01347 zone->limit = zone->base + decoder->subrs_len[idx];
01348 else
01349 {
01350
01351
01352 zone->base += ( decoder->lenIV >= 0 ? decoder->lenIV : 0 );
01353 zone->limit = decoder->subrs[idx + 1];
01354 }
01355
01356 zone->cursor = zone->base;
01357
01358 if ( !zone->base )
01359 {
01360 FT_ERROR(( "t1_decoder_parse_charstrings:"
01361 " invoking empty subrs\n" ));
01362 goto Syntax_Error;
01363 }
01364
01365 decoder->zone = zone;
01366 ip = zone->base;
01367 limit = zone->limit;
01368 break;
01369 }
01370
01371 case op_pop:
01372 FT_TRACE4(( " pop" ));
01373
01374 if ( known_othersubr_result_cnt > 0 )
01375 {
01376 known_othersubr_result_cnt--;
01377
01378 break;
01379 }
01380
01381 if ( unknown_othersubr_result_cnt == 0 )
01382 {
01383 FT_ERROR(( "t1_decoder_parse_charstrings:"
01384 " no more operands for othersubr\n" ));
01385 goto Syntax_Error;
01386 }
01387
01388 unknown_othersubr_result_cnt--;
01389 top++;
01390 break;
01391
01392 case op_return:
01393 FT_TRACE4(( " return" ));
01394
01395 if ( zone <= decoder->zones )
01396 {
01397 FT_ERROR(( "t1_decoder_parse_charstrings:"
01398 " unexpected return\n" ));
01399 goto Syntax_Error;
01400 }
01401
01402 zone--;
01403 ip = zone->cursor;
01404 limit = zone->limit;
01405 decoder->zone = zone;
01406 break;
01407
01408 case op_dotsection:
01409 FT_TRACE4(( " dotsection" ));
01410
01411 break;
01412
01413 case op_hstem:
01414 FT_TRACE4(( " hstem" ));
01415
01416
01417 if ( hinter )
01418 {
01419
01420 hinter->stem( hinter->hints, 1, top );
01421 }
01422 break;
01423
01424 case op_hstem3:
01425 FT_TRACE4(( " hstem3" ));
01426
01427
01428 if ( hinter )
01429 hinter->stem3( hinter->hints, 1, top );
01430 break;
01431
01432 case op_vstem:
01433 FT_TRACE4(( " vstem" ));
01434
01435
01436 if ( hinter )
01437 {
01438 top[0] += orig_x;
01439 hinter->stem( hinter->hints, 0, top );
01440 }
01441 break;
01442
01443 case op_vstem3:
01444 FT_TRACE4(( " vstem3" ));
01445
01446
01447 if ( hinter )
01448 {
01449 FT_Pos dx = orig_x;
01450
01451
01452 top[0] += dx;
01453 top[2] += dx;
01454 top[4] += dx;
01455 hinter->stem3( hinter->hints, 0, top );
01456 }
01457 break;
01458
01459 case op_setcurrentpoint:
01460 FT_TRACE4(( " setcurrentpoint" ));
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474 #if 0
01475
01476 if ( decoder->flex_state != 1 )
01477 {
01478 FT_ERROR(( "t1_decoder_parse_charstrings:"
01479 " unexpected `setcurrentpoint'\n" ));
01480 goto Syntax_Error;
01481 }
01482 else
01483 #endif
01484 decoder->flex_state = 0;
01485 break;
01486
01487 case op_unknown15:
01488 FT_TRACE4(( " opcode_15" ));
01489
01490 break;
01491
01492 default:
01493 FT_ERROR(( "t1_decoder_parse_charstrings:"
01494 " unhandled opcode %d\n", op ));
01495 goto Syntax_Error;
01496 }
01497
01498
01499
01500
01501
01502
01503 decoder->top = top;
01504
01505 #ifdef FT_DEBUG_LEVEL_TRACE
01506 FT_TRACE4(( "\n" ));
01507 bol = TRUE;
01508 #endif
01509
01510 }
01511
01512 }
01513
01514 FT_TRACE4(( "..end..\n\n" ));
01515
01516 Fail:
01517 return error;
01518
01519 Syntax_Error:
01520 return PSaux_Err_Syntax_Error;
01521
01522 Stack_Underflow:
01523 return PSaux_Err_Stack_Underflow;
01524 }
01525
01526
01527
01528 FT_LOCAL_DEF( FT_Error )
01529 t1_decoder_parse_glyph( T1_Decoder decoder,
01530 FT_UInt glyph )
01531 {
01532 return decoder->parse_callback( decoder, glyph );
01533 }
01534
01535
01536
01537 FT_LOCAL_DEF( FT_Error )
01538 t1_decoder_init( T1_Decoder decoder,
01539 FT_Face face,
01540 FT_Size size,
01541 FT_GlyphSlot slot,
01542 FT_Byte** glyph_names,
01543 PS_Blend blend,
01544 FT_Bool hinting,
01545 FT_Render_Mode hint_mode,
01546 T1_Decoder_Callback parse_callback )
01547 {
01548 FT_MEM_ZERO( decoder, sizeof ( *decoder ) );
01549
01550
01551 {
01552 FT_Service_PsCMaps psnames = 0;
01553
01554
01555 FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
01556 if ( !psnames )
01557 {
01558 FT_ERROR(( "t1_decoder_init:"
01559 " the `psnames' module is not available\n" ));
01560 return PSaux_Err_Unimplemented_Feature;
01561 }
01562
01563 decoder->psnames = psnames;
01564 }
01565
01566 t1_builder_init( &decoder->builder, face, size, slot, hinting );
01567
01568
01569
01570
01571
01572 decoder->num_glyphs = (FT_UInt)face->num_glyphs;
01573 decoder->glyph_names = glyph_names;
01574 decoder->hint_mode = hint_mode;
01575 decoder->blend = blend;
01576 decoder->parse_callback = parse_callback;
01577
01578 decoder->funcs = t1_decoder_funcs;
01579
01580 return PSaux_Err_Ok;
01581 }
01582
01583
01584
01585 FT_LOCAL_DEF( void )
01586 t1_decoder_done( T1_Decoder decoder )
01587 {
01588 t1_builder_done( &decoder->builder );
01589 }
01590
01591
01592