< prev index next >
src/java.desktop/share/native/libfreetype/src/psaux/t1decode.c
Print this page
*** 2,12 ****
*
* t1decode.c
*
* PostScript Type 1 decoding routines (body).
*
! * Copyright (C) 2000-2019 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
--- 2,12 ----
*
* t1decode.c
*
* PostScript Type 1 decoding routines (body).
*
! * Copyright (C) 2000-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
*** 365,386 ****
/* First load `bchar' in builder */
/* now load the unscaled outline */
FT_GlyphLoader_Prepare( decoder->builder.loader ); /* prepare loader */
/* the seac operator must not be nested */
decoder->seac = TRUE;
error = t1_decoder_parse_glyph( decoder, (FT_UInt)bchar_index );
decoder->seac = FALSE;
if ( error )
goto Exit;
! /* save the left bearing and width of the base character */
! /* as they will be erased by the next load. */
left_bearing = decoder->builder.left_bearing;
advance = decoder->builder.advance;
decoder->builder.left_bearing.x = 0;
decoder->builder.left_bearing.y = 0;
decoder->builder.pos_x = adx - asb;
--- 365,395 ----
/* First load `bchar' in builder */
/* now load the unscaled outline */
FT_GlyphLoader_Prepare( decoder->builder.loader ); /* prepare loader */
+ /* save the left bearing and width of the SEAC */
+ /* glyph as they will be erased by the next load */
+
+ left_bearing = decoder->builder.left_bearing;
+ advance = decoder->builder.advance;
+
/* the seac operator must not be nested */
decoder->seac = TRUE;
error = t1_decoder_parse_glyph( decoder, (FT_UInt)bchar_index );
decoder->seac = FALSE;
if ( error )
goto Exit;
! /* If the SEAC glyph doesn't have a (H)SBW of its */
! /* own use the values from the base glyph. */
+ if ( decoder->builder.parse_state != T1_Parse_Have_Width )
+ {
left_bearing = decoder->builder.left_bearing;
advance = decoder->builder.advance;
+ }
decoder->builder.left_bearing.x = 0;
decoder->builder.left_bearing.y = 0;
decoder->builder.pos_x = adx - asb;
*** 394,405 ****
error = t1_decoder_parse_glyph( decoder, (FT_UInt)achar_index );
decoder->seac = FALSE;
if ( error )
goto Exit;
! /* restore the left side bearing and */
! /* advance width of the base character */
decoder->builder.left_bearing = left_bearing;
decoder->builder.advance = advance;
decoder->builder.pos_x = 0;
--- 403,414 ----
error = t1_decoder_parse_glyph( decoder, (FT_UInt)achar_index );
decoder->seac = FALSE;
if ( error )
goto Exit;
! /* restore the left side bearing and advance width */
! /* of the SEAC glyph or base character (saved above) */
decoder->builder.left_bearing = left_bearing;
decoder->builder.advance = advance;
decoder->builder.pos_x = 0;
*** 648,661 ****
/* <large1> <large2> <num> div div'. This is probably not allowed */
/* anyway. */
if ( value > 32000 || value < -32000 )
{
if ( large_int )
- {
FT_ERROR(( "t1_decoder_parse_charstrings:"
" no `div' after large integer\n" ));
- }
else
large_int = TRUE;
}
else
{
--- 657,668 ----
*** 1688,1697 ****
--- 1695,1705 ----
{
T1_Decoder_Zone zone;
FT_Byte* ip;
FT_Byte* limit;
T1_Builder builder = &decoder->builder;
+ FT_Bool large_int;
#ifdef FT_DEBUG_LEVEL_TRACE
FT_Bool bol = TRUE;
#endif
*** 1705,1714 ****
--- 1713,1724 ----
zone->base = charstring_base;
limit = zone->limit = charstring_base + charstring_len;
ip = zone->cursor = zone->base;
+ large_int = FALSE;
+
/* now, execute loop */
while ( ip < limit )
{
FT_Long* top = decoder->top;
T1_Operator op = op_none;
*** 1765,1774 ****
--- 1775,1787 ----
switch ( *ip++ )
{
case 7:
op = op_sbw;
break;
+ case 12:
+ op = op_div;
+ break;
default:
goto No_Width;
}
break;
*** 1794,1809 ****
/* stuff like `<large1> <large2> <num> div <num> div' or */
/* <large1> <large2> <num> div div'. This is probably not allowed */
/* anyway. */
if ( value > 32000 || value < -32000 )
{
FT_ERROR(( "t1_decoder_parse_metrics:"
! " large integer found for width\n" ));
goto Syntax_Error;
}
else
{
value = (FT_Int32)( (FT_UInt32)value << 16 );
}
break;
--- 1807,1828 ----
/* stuff like `<large1> <large2> <num> div <num> div' or */
/* <large1> <large2> <num> div div'. This is probably not allowed */
/* anyway. */
if ( value > 32000 || value < -32000 )
{
+ if ( large_int )
+ {
FT_ERROR(( "t1_decoder_parse_metrics:"
! " no `div' after large integer\n" ));
goto Syntax_Error;
}
else
+ large_int = TRUE;
+ }
+ else
{
+ if ( !large_int )
value = (FT_Int32)( (FT_UInt32)value << 16 );
}
break;
*** 1825,1844 ****
--- 1844,1871 ----
value = ( ( ip[-2] - 247 ) * 256 ) + ip[-1] + 108;
else
value = -( ( ( ip[-2] - 251 ) * 256 ) + ip[-1] + 108 );
}
+ if ( !large_int )
value = (FT_Int32)( (FT_UInt32)value << 16 );
}
else
{
FT_ERROR(( "t1_decoder_parse_metrics:"
" invalid byte (%d)\n", ip[-1] ));
goto Syntax_Error;
}
}
+ if ( large_int && !( op == op_none || op == op_div ) )
+ {
+ FT_ERROR(( "t1_decoder_parse_metrics:"
+ " no `div' after large integer\n" ));
+ goto Syntax_Error;
+ }
+
/**********************************************************************
*
* Push value on stack, or process operator
*
*/
*** 1849,1858 ****
--- 1876,1888 ----
FT_ERROR(( "t1_decoder_parse_metrics: stack overflow\n" ));
goto Syntax_Error;
}
#ifdef FT_DEBUG_LEVEL_TRACE
+ if ( large_int )
+ FT_TRACE4(( " %d", value ));
+ else
FT_TRACE4(( " %d", value / 65536 ));
#endif
*top++ = value;
decoder->top = top;
*** 1867,1881 ****
--- 1897,1914 ----
if ( top - decoder->stack < num_args )
goto Stack_Underflow;
#ifdef FT_DEBUG_LEVEL_TRACE
+ if ( op != op_div )
+ {
if ( top - decoder->stack != num_args )
FT_TRACE0(( "t1_decoder_parse_metrics:"
" too much operands on the stack"
" (seen %d, expected %d)\n",
top - decoder->stack, num_args ));
+ }
#endif /* FT_DEBUG_LEVEL_TRACE */
top -= num_args;
*** 1915,1930 ****
--- 1948,1977 ----
/* (lsb + advance width), not load the rest of */
/* it; so exit immediately */
FT_TRACE4(( "\n" ));
return FT_Err_Ok;
+ case op_div:
+ FT_TRACE4(( " div" ));
+
+ /* if `large_int' is set, we divide unscaled numbers; */
+ /* otherwise, we divide numbers in 16.16 format -- */
+ /* in both cases, it is the same operation */
+ *top = FT_DivFix( top[0], top[1] );
+ top++;
+
+ large_int = FALSE;
+ break;
+
default:
FT_ERROR(( "t1_decoder_parse_metrics:"
" unhandled opcode %d\n", op ));
goto Syntax_Error;
}
+ decoder->top = top;
+
} /* general operator processing */
} /* while ip < limit */
FT_TRACE4(( "..end..\n\n" ));
< prev index next >