Fix Type 1 hinting.
Type 1 hinting breaks sometimes when mid-charstring hints should have been in the initial hintmap. This fix adds a preprocessing pass that reads all hints and builds the correct initial hintmap first, before proceeding to build the glyph outline. * src/psaux/psintrp.c (cf2_interpT2CharString): New `initial_map_ready' boolean flag. Ignore outline commands and hint changes on first pass. <cf2_cmdENDCHAR>: Add section to build hintmap and rewind.
This commit is contained in:
parent
2f0e114068
commit
d52dd7f31d
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
||||||
|
2017-09-25 Ewald Hew <ewaldhew@gmail.com>
|
||||||
|
|
||||||
|
[psaux] Fix Type 1 hinting.
|
||||||
|
|
||||||
|
Type 1 hinting breaks sometimes when mid-charstring hints should
|
||||||
|
have been in the initial hintmap. This fix adds a preprocessing
|
||||||
|
pass that reads all hints and builds the correct initial hintmap
|
||||||
|
first, before proceeding to build the glyph outline.
|
||||||
|
|
||||||
|
* src/psaux/psintrp.c (cf2_interpT2CharString): New
|
||||||
|
`initial_map_ready' boolean flag.
|
||||||
|
Ignore outline commands and hint changes on first pass.
|
||||||
|
<cf2_cmdENDCHAR>: Add section to build hintmap and rewind.
|
||||||
|
|
||||||
2017-09-25 Ewald Hew <ewaldhew@gmail.com>
|
2017-09-25 Ewald Hew <ewaldhew@gmail.com>
|
||||||
|
|
||||||
[psaux] Add tracing for hints.
|
[psaux] Add tracing for hints.
|
||||||
|
|
|
@ -492,6 +492,7 @@
|
||||||
/* Stuff for Type 1 */
|
/* Stuff for Type 1 */
|
||||||
FT_Int known_othersubr_result_cnt = 0;
|
FT_Int known_othersubr_result_cnt = 0;
|
||||||
FT_Bool large_int = FALSE;
|
FT_Bool large_int = FALSE;
|
||||||
|
FT_Bool initial_map_ready = FALSE;
|
||||||
#define PS_STORAGE_SIZE 3
|
#define PS_STORAGE_SIZE 3
|
||||||
CF2_F16Dot16 results[PS_STORAGE_SIZE]; /* for othersubr results */
|
CF2_F16Dot16 results[PS_STORAGE_SIZE]; /* for othersubr results */
|
||||||
FT_Int result_cnt = 0;
|
FT_Int result_cnt = 0;
|
||||||
|
@ -650,6 +651,20 @@
|
||||||
|
|
||||||
if ( font->isT1 )
|
if ( font->isT1 )
|
||||||
{
|
{
|
||||||
|
if ( !initial_map_ready &&
|
||||||
|
!( op1 == cf2_cmdHSTEM ||
|
||||||
|
op1 == cf2_cmdVSTEM ||
|
||||||
|
op1 == cf2_cmdHSBW ||
|
||||||
|
op1 == cf2_cmdCALLSUBR ||
|
||||||
|
op1 == cf2_cmdRETURN ||
|
||||||
|
op1 == cf2_cmdESC ||
|
||||||
|
op1 == cf2_cmdENDCHAR ||
|
||||||
|
op1 >= 32 /* Numbers */ ) )
|
||||||
|
{
|
||||||
|
cf2_stack_clear( opStack );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if ( result_cnt > 0 &&
|
if ( result_cnt > 0 &&
|
||||||
!( op1 == cf2_cmdCALLSUBR ||
|
!( op1 == cf2_cmdCALLSUBR ||
|
||||||
op1 == cf2_cmdRETURN ||
|
op1 == cf2_cmdRETURN ||
|
||||||
|
@ -1478,8 +1493,11 @@
|
||||||
if ( builder->metrics_only )
|
if ( builder->metrics_only )
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
curX = ADD_INT32( curX, lsb_x );
|
if ( initial_map_ready )
|
||||||
curY = ADD_INT32( curY, lsb_y );
|
{
|
||||||
|
curX = ADD_INT32( curX, lsb_x );
|
||||||
|
curY = ADD_INT32( curY, lsb_y );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1647,8 +1665,9 @@
|
||||||
if ( arg_cnt != 3 )
|
if ( arg_cnt != 3 )
|
||||||
goto Unexpected_OtherSubr;
|
goto Unexpected_OtherSubr;
|
||||||
|
|
||||||
if ( !decoder->flex_state ||
|
if ( initial_map_ready &&
|
||||||
decoder->num_flex_vectors != 7 )
|
( !decoder->flex_state ||
|
||||||
|
decoder->num_flex_vectors != 7 ) )
|
||||||
{
|
{
|
||||||
FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):"
|
FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):"
|
||||||
" unexpected flex end\n" ));
|
" unexpected flex end\n" ));
|
||||||
|
@ -1666,6 +1685,9 @@
|
||||||
if ( arg_cnt != 0 )
|
if ( arg_cnt != 0 )
|
||||||
goto Unexpected_OtherSubr;
|
goto Unexpected_OtherSubr;
|
||||||
|
|
||||||
|
if ( !initial_map_ready )
|
||||||
|
break;
|
||||||
|
|
||||||
if ( ps_builder_check_points( &decoder->builder, 6 ) )
|
if ( ps_builder_check_points( &decoder->builder, 6 ) )
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
|
@ -1682,6 +1704,9 @@
|
||||||
if ( arg_cnt != 0 )
|
if ( arg_cnt != 0 )
|
||||||
goto Unexpected_OtherSubr;
|
goto Unexpected_OtherSubr;
|
||||||
|
|
||||||
|
if ( !initial_map_ready )
|
||||||
|
break;
|
||||||
|
|
||||||
if ( !decoder->flex_state )
|
if ( !decoder->flex_state )
|
||||||
{
|
{
|
||||||
FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):"
|
FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):"
|
||||||
|
@ -1728,12 +1753,15 @@
|
||||||
if ( arg_cnt != 1 )
|
if ( arg_cnt != 1 )
|
||||||
goto Unexpected_OtherSubr;
|
goto Unexpected_OtherSubr;
|
||||||
|
|
||||||
cf2_arrstack_clear( &vStemHintArray );
|
if ( initial_map_ready )
|
||||||
cf2_arrstack_clear( &hStemHintArray );
|
{
|
||||||
|
cf2_arrstack_clear( &vStemHintArray );
|
||||||
|
cf2_arrstack_clear( &hStemHintArray );
|
||||||
|
|
||||||
cf2_hintmask_init( &hintMask, error );
|
cf2_hintmask_init( &hintMask, error );
|
||||||
hintMask.isValid = FALSE;
|
hintMask.isValid = FALSE;
|
||||||
hintMask.isNew = TRUE;
|
hintMask.isNew = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
known_othersubr_result_cnt = 1;
|
known_othersubr_result_cnt = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -2281,6 +2309,9 @@
|
||||||
{
|
{
|
||||||
FT_TRACE4(( " setcurrentpoint" ));
|
FT_TRACE4(( " setcurrentpoint" ));
|
||||||
|
|
||||||
|
if ( !initial_map_ready )
|
||||||
|
break;
|
||||||
|
|
||||||
/* From the T1 specification, section 6.4: */
|
/* From the T1 specification, section 6.4: */
|
||||||
/* */
|
/* */
|
||||||
/* The setcurrentpoint command is used only in */
|
/* The setcurrentpoint command is used only in */
|
||||||
|
@ -2351,13 +2382,38 @@
|
||||||
if ( builder->metrics_only )
|
if ( builder->metrics_only )
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
curX = ADD_INT32( curX, lsb_x );
|
if ( initial_map_ready )
|
||||||
|
curX = ADD_INT32( curX, lsb_x );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cf2_cmdENDCHAR:
|
case cf2_cmdENDCHAR:
|
||||||
FT_TRACE4(( " endchar\n" ));
|
FT_TRACE4(( " endchar\n" ));
|
||||||
|
|
||||||
|
if ( font->isT1 && !initial_map_ready )
|
||||||
|
{
|
||||||
|
FT_TRACE5(( "cf2_interpT2CharString (Type 1 mode): "
|
||||||
|
"Build initial hintmap, rewinding...\n" ));
|
||||||
|
|
||||||
|
/* Trigger initial hintmap build */
|
||||||
|
cf2_glyphpath_moveTo( &glyphPath, curX, curY );
|
||||||
|
|
||||||
|
initial_map_ready = TRUE;
|
||||||
|
|
||||||
|
/* Change hints routine - clear for rewind */
|
||||||
|
cf2_arrstack_clear( &vStemHintArray );
|
||||||
|
cf2_arrstack_clear( &hStemHintArray );
|
||||||
|
|
||||||
|
cf2_hintmask_init( &hintMask, error );
|
||||||
|
hintMask.isValid = FALSE;
|
||||||
|
hintMask.isNew = TRUE;
|
||||||
|
|
||||||
|
/* Rewind charstring */
|
||||||
|
charstring->ptr = charstring->start;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if ( cf2_stack_count( opStack ) == 1 ||
|
if ( cf2_stack_count( opStack ) == 1 ||
|
||||||
cf2_stack_count( opStack ) == 5 )
|
cf2_stack_count( opStack ) == 5 )
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue