📄 psobjs.c
字号:
FT_LOCAL_DEF( void ) ps_parser_skip_PS_token( PS_Parser parser ) { /* Note: PostScript allows any non-delimiting, non-whitespace */ /* character in a name (PS Ref Manual, 3rd ed, p31). */ /* PostScript delimiters are (, ), <, >, [, ], {, }, /, and %. */ FT_Byte* cur = parser->cursor; FT_Byte* limit = parser->limit; skip_spaces( &cur, limit ); /* this also skips comments */ if ( cur >= limit ) goto Exit; /* self-delimiting, single-character tokens */ if ( *cur == '[' || *cur == ']' || *cur == '{' || *cur == '}' ) { cur++; goto Exit; } if ( *cur == '(' ) /* (...) */ { skip_literal_string( &cur, limit ); goto Exit; } if ( *cur == '<' ) /* <...> */ { if ( cur + 1 < limit && *(cur + 1) == '<' ) /* << */ { cur++; cur++; goto Exit; } parser->cursor = cur; skip_string( parser ); return; } if ( *cur == '>' ) { cur++; if ( cur >= limit || *cur != '>' ) /* >> */ { FT_ERROR(( "ps_parser_skip_PS_token: " "unexpected closing delimiter `>'\n" )); parser->error = PSaux_Err_Invalid_File_Format; goto Exit; } cur++; goto Exit; } if ( *cur == '/' ) cur++; /* anything else */ while ( cur < limit ) { if ( IS_T1_SPACE( *cur ) || *cur == '(' || *cur == '/' || *cur == '%' || *cur == '[' || *cur == ']' || *cur == '{' || *cur == '}' || *cur == '<' || *cur == '>' ) break; if ( *cur == ')' ) { FT_ERROR(( "ps_parser_skip_PS_token: " "unexpected closing delimiter `)'\n" )); parser->error = PSaux_Err_Invalid_File_Format; goto Exit; } cur++; } Exit: parser->cursor = cur; } FT_LOCAL_DEF( void ) ps_parser_skip_spaces( PS_Parser parser ) { skip_spaces( &parser->cursor, parser->limit ); } /* `token' here means either something between balanced delimiters */ /* or the next token; the delimiters are not removed. */ FT_LOCAL_DEF( void ) ps_parser_to_token( PS_Parser parser, T1_Token token ) { FT_Byte* cur; FT_Byte* limit; FT_Byte starter, ender; FT_Int embed; token->type = T1_TOKEN_TYPE_NONE; token->start = 0; token->limit = 0; /* first of all, skip leading whitespace */ ps_parser_skip_spaces( parser ); cur = parser->cursor; limit = parser->limit; if ( cur >= limit ) return; switch ( *cur ) { /************* check for literal string *****************/ case '(': token->type = T1_TOKEN_TYPE_STRING; token->start = cur; skip_literal_string( &cur, limit ); if ( cur < limit ) token->limit = cur; break; /************* check for programs/array *****************/ case '{': token->type = T1_TOKEN_TYPE_ARRAY; ender = '}'; goto Lookup_Ender; /************* check for table/array ********************/ case '[': token->type = T1_TOKEN_TYPE_ARRAY; ender = ']'; /* fall through */ Lookup_Ender: embed = 1; starter = *cur; token->start = cur++; /* we need this to catch `[ ]' */ parser->cursor = cur; ps_parser_skip_spaces( parser ); cur = parser->cursor; while ( cur < limit && !parser->error ) { if ( *cur == starter ) embed++; else if ( *cur == ender ) { embed--; if ( embed <= 0 ) { token->limit = ++cur; break; } } parser->cursor = cur; ps_parser_skip_PS_token( parser ); /* we need this to catch `[XXX ]' */ ps_parser_skip_spaces ( parser ); cur = parser->cursor; } break; /* ************ otherwise, it is any token **************/ default: token->start = cur; token->type = T1_TOKEN_TYPE_ANY; ps_parser_skip_PS_token( parser ); cur = parser->cursor; if ( !parser->error ) token->limit = cur; } if ( !token->limit ) { token->start = 0; token->type = T1_TOKEN_TYPE_NONE; } parser->cursor = cur; } FT_LOCAL_DEF( void ) ps_parser_to_token_array( PS_Parser parser, T1_Token tokens, FT_UInt max_tokens, FT_Int* pnum_tokens ) { T1_TokenRec master; *pnum_tokens = -1; /* this also handles leading whitespace */ ps_parser_to_token( parser, &master ); if ( master.type == T1_TOKEN_TYPE_ARRAY ) { FT_Byte* old_cursor = parser->cursor; FT_Byte* old_limit = parser->limit; T1_Token cur = tokens; T1_Token limit = cur + max_tokens; /* don't include outermost delimiters */ parser->cursor = master.start + 1; parser->limit = master.limit - 1; while ( parser->cursor < parser->limit ) { T1_TokenRec token; ps_parser_to_token( parser, &token ); if ( !token.type ) break; if ( cur < limit ) *cur = token; cur++; } *pnum_tokens = (FT_Int)( cur - tokens ); parser->cursor = old_cursor; parser->limit = old_limit; } } /* first character must be already part of the number */ static FT_Long ps_radix( FT_Long radixBase, FT_Byte* *acur, FT_Byte* limit ) { FT_Long result = 0; FT_Byte* cur = *acur; if ( radixBase < 2 || radixBase > 36 ) return 0; while ( cur < limit ) { int d; if ( *cur OP 0x80 ) break; d = ft_char_table[*cur & 0x7F]; if ( d < 0 || d >= radixBase ) break; result = result * radixBase + d; cur++; } *acur = cur; return result; } /* first character must be already part of the number */ static FT_Long ps_toint( FT_Byte* *acur, FT_Byte* limit ) { FT_Long result = 0; FT_Byte* cur = *acur; FT_Byte c; if ( cur >= limit ) goto Exit; c = *cur; if ( c == '-' ) cur++; while ( cur < limit ) { int d; if ( *cur == '#' ) { cur++; result = ps_radix( result, &cur, limit ); break; } if ( *cur OP 0x80 ) break; d = ft_char_table[*cur & 0x7F]; if ( d < 0 || d >= 10 ) break; result = result * 10 + d; cur++; }; if ( c == '-' ) result = -result; Exit: *acur = cur; return result; } /* first character must be `<' if `delimiters' is non-zero */ static FT_Error ps_tobytes( FT_Byte* *acur, FT_Byte* limit, FT_Long max_bytes, FT_Byte* bytes, FT_Long* pnum_bytes, FT_Bool delimiters ) { FT_Error error = PSaux_Err_Ok; FT_Byte* cur = *acur; FT_Long n = 0; if ( cur >= limit ) goto Exit; if ( delimiters ) { if ( *cur != '<' ) { FT_ERROR(( "ps_tobytes: Missing starting delimiter `<'\n" )); error = PSaux_Err_Invalid_File_Format; goto Exit; } cur++; } max_bytes = max_bytes * 2; for ( n = 0; cur < limit; n++, cur++ ) { int d; if ( n >= max_bytes ) /* buffer is full */ goto Exit; /* All whitespace characters are ignored. */ skip_spaces( &cur, limit ); if ( cur >= limit ) break; if ( *cur OP 0x80 ) break; d = ft_char_table[*cur & 0x7F]; if ( d < 0 || d >= 16 ) break; /* <f> == <f0> != <0f> */ bytes[n / 2] = (FT_Byte)( ( n % 2 ) ? bytes[n / 2] + d : d * 16 ); } if ( delimiters ) { if ( cur < limit && *cur != '>' ) { FT_ERROR(( "ps_tobytes: Missing closing delimiter `>'\n" )); error = PSaux_Err_Invalid_File_Format; goto Exit; } cur++; } *acur = cur; Exit: *pnum_bytes = ( n + 1 ) / 2; return error; } /* first character must be already part of the number */ static FT_Long ps_tofixed( FT_Byte* *acur, FT_Byte* limit, FT_Long power_ten ) { FT_Byte* cur = *acur; FT_Long num, divider, result; FT_Int sign = 0; if ( cur >= limit ) return 0; /* first of all, check the sign */ if ( *cur == '-' && cur + 1 < limit ) { sign = 1; cur++; } /* then, read the integer part, if any */ if ( *cur != '.' ) result = ps_toint( &cur, limit ) << 16; else result = 0; num = 0; divider = 1; if ( cur >= limit ) goto Exit; /* read decimal part, if any */ if ( *cur == '.' && cur + 1 < limit ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -