psobjs.c
来自「一个类似windows」· C语言 代码 · 共 1,794 行 · 第 1/4 页
C
1,794 行
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 + =
减小字号Ctrl + -
显示快捷键?