[truetype/GX] Consolidate memory allocations.

* src/truetype/ttgxvar.c (tt_face_vary_cvt, TT_Vary_Apply_Glyph_Deltas):
Allocate and split bigger memory blocks, avoid unnecessary zeroing,
do not copy shared tuples, revise error exit paths.
This commit is contained in:
Alexei Podtelezhnikov 2024-05-26 19:40:20 -04:00
parent 3416ac16d0
commit 7ff43d3e9f
1 changed files with 61 additions and 90 deletions

View File

@ -3521,9 +3521,10 @@
FT_ULong here;
FT_UInt i, j;
FT_Fixed* tuple_coords = NULL;
FT_Fixed* im_start_coords = NULL;
FT_Fixed* im_end_coords = NULL;
FT_Fixed* peak_coords = NULL;
FT_Fixed* tuple_coords;
FT_Fixed* im_start_coords;
FT_Fixed* im_end_coords;
GX_Blend blend = face->blend;
@ -3544,16 +3545,16 @@
{
FT_TRACE2(( "\n" ));
FT_TRACE2(( "tt_face_vary_cvt: no blend specified\n" ));
error = FT_Err_Ok;
goto Exit;
return FT_Err_Ok;
}
if ( !face->cvt )
{
FT_TRACE2(( "\n" ));
FT_TRACE2(( "tt_face_vary_cvt: no `cvt ' table\n" ));
error = FT_Err_Ok;
goto Exit;
return FT_Err_Ok;
}
error = face->goto_table( face, TTAG_cvar, stream, &table_len );
@ -3561,15 +3562,11 @@
{
FT_TRACE2(( "is missing\n" ));
error = FT_Err_Ok;
goto Exit;
return FT_Err_Ok;
}
if ( FT_FRAME_ENTER( table_len ) )
{
error = FT_Err_Ok;
goto Exit;
}
return FT_Err_Ok;
table_start = FT_Stream_FTell( stream );
if ( FT_GET_LONG() != 0x00010000L )
@ -3582,11 +3579,6 @@
FT_TRACE2(( "loaded\n" ));
if ( FT_NEW_ARRAY( tuple_coords, blend->num_axis ) ||
FT_NEW_ARRAY( im_start_coords, blend->num_axis ) ||
FT_NEW_ARRAY( im_end_coords, blend->num_axis ) )
goto FExit;
tupleCount = FT_GET_USHORT();
offsetToData = FT_GET_USHORT();
@ -3622,8 +3614,12 @@
tupleCount & GX_TC_TUPLE_COUNT_MASK,
( tupleCount & GX_TC_TUPLE_COUNT_MASK ) == 1 ? "" : "s" ));
if ( FT_NEW_ARRAY( cvt_deltas, face->cvt_size ) )
goto FExit;
if ( FT_QNEW_ARRAY( peak_coords, 3 * blend->num_axis ) ||
FT_NEW_ARRAY( cvt_deltas, face->cvt_size ) )
goto Exit;
im_start_coords = peak_coords + blend->num_axis;
im_end_coords = im_start_coords + blend->num_axis;
for ( i = 0; i < ( tupleCount & GX_TC_TUPLE_COUNT_MASK ); i++ )
{
@ -3640,32 +3636,19 @@
if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD )
{
for ( j = 0; j < blend->num_axis; j++ )
tuple_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() );
peak_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() );
tuple_coords = peak_coords;
}
else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount )
else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) < blend->tuplecount )
tuple_coords = blend->tuplecoords +
( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) * blend->num_axis;
else
{
FT_TRACE2(( "tt_face_vary_cvt:"
" invalid tuple index\n" ));
error = FT_THROW( Invalid_Table );
goto FExit;
}
else
{
if ( !blend->tuplecoords )
{
FT_TRACE2(( "tt_face_vary_cvt:"
" no valid tuple coordinates available\n" ));
error = FT_THROW( Invalid_Table );
goto FExit;
}
FT_MEM_COPY(
tuple_coords,
blend->tuplecoords +
( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) * blend->num_axis,
blend->num_axis * sizeof ( FT_Fixed ) );
goto Exit;
}
if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE )
@ -3808,23 +3791,21 @@
for ( i = 0; i < face->cvt_size; i++ )
face->cvt[i] += FT_fixedToFdot6( cvt_deltas[i] );
FExit:
FT_FRAME_EXIT();
Exit:
if ( sharedpoints != ALL_POINTS )
FT_FREE( sharedpoints );
FT_FREE( tuple_coords );
FT_FREE( im_start_coords );
FT_FREE( im_end_coords );
FT_FREE( cvt_deltas );
/* iterate over all FT_Size objects and set `cvt_ready' to -1 */
/* to trigger rescaling of all CVT values */
FT_List_Iterate( &root->sizes_list,
tt_cvt_ready_iterator,
NULL );
Exit:
if ( sharedpoints != ALL_POINTS )
FT_FREE( sharedpoints );
FT_FREE( cvt_deltas );
FT_FREE( peak_coords );
FExit:
FT_FRAME_EXIT();
return error;
#else /* !TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
@ -4087,9 +4068,10 @@
FT_ULong here;
FT_UInt i, j;
FT_Fixed* tuple_coords = NULL;
FT_Fixed* im_start_coords = NULL;
FT_Fixed* im_end_coords = NULL;
FT_Fixed* peak_coords = NULL;
FT_Fixed* tuple_coords;
FT_Fixed* im_start_coords;
FT_Fixed* im_end_coords;
GX_Blend blend = face->blend;
@ -4124,27 +4106,17 @@
return FT_Err_Ok;
}
if ( FT_NEW_ARRAY( points_org, n_points ) ||
FT_NEW_ARRAY( points_out, n_points ) ||
FT_NEW_ARRAY( has_delta, n_points ) )
goto Fail1;
dataSize = blend->glyphoffsets[glyph_index + 1] -
blend->glyphoffsets[glyph_index];
if ( FT_STREAM_SEEK( blend->glyphoffsets[glyph_index] ) ||
FT_FRAME_ENTER( dataSize ) )
goto Fail1;
return error;
glyph_start = FT_Stream_FTell( stream );
/* each set of glyph variation data is formatted similarly to `cvar' */
if ( FT_NEW_ARRAY( tuple_coords, blend->num_axis ) ||
FT_NEW_ARRAY( im_start_coords, blend->num_axis ) ||
FT_NEW_ARRAY( im_end_coords, blend->num_axis ) )
goto Fail2;
tupleCount = FT_GET_USHORT();
offsetToData = FT_GET_USHORT();
@ -4156,7 +4128,7 @@
" invalid glyph variation array header\n" ));
error = FT_THROW( Invalid_Table );
goto Fail2;
goto FExit;
}
offsetToData += glyph_start;
@ -4180,9 +4152,16 @@
tupleCount & GX_TC_TUPLE_COUNT_MASK,
( tupleCount & GX_TC_TUPLE_COUNT_MASK ) == 1 ? "" : "s" ));
if ( FT_NEW_ARRAY( point_deltas_x, n_points ) ||
FT_NEW_ARRAY( point_deltas_y, n_points ) )
goto Fail3;
if ( FT_QNEW_ARRAY( peak_coords, 3 * blend->num_axis ) ||
FT_NEW_ARRAY( point_deltas_x, 2 * n_points ) ||
FT_QNEW_ARRAY( points_org, n_points ) ||
FT_QNEW_ARRAY( points_out, n_points ) ||
FT_QNEW_ARRAY( has_delta, n_points ) )
goto Exit;
im_start_coords = peak_coords + blend->num_axis;
im_end_coords = im_start_coords + blend->num_axis;
point_deltas_y = point_deltas_x + n_points;
for ( j = 0; j < n_points; j++ )
{
@ -4205,22 +4184,20 @@
if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD )
{
for ( j = 0; j < blend->num_axis; j++ )
tuple_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() );
peak_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() );
tuple_coords = peak_coords;
}
else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount )
else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) < blend->tuplecount )
tuple_coords = blend->tuplecoords +
( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) * blend->num_axis;
else
{
FT_TRACE2(( "TT_Vary_Apply_Glyph_Deltas:"
" invalid tuple index\n" ));
error = FT_THROW( Invalid_Table );
goto Fail3;
goto Exit;
}
else
FT_MEM_COPY(
tuple_coords,
blend->tuplecoords +
( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) * blend->num_axis,
blend->num_axis * sizeof ( FT_Fixed ) );
if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE )
{
@ -4448,23 +4425,17 @@
unrounded[n_points - 2].y ) / 64;
}
Fail3:
FT_FREE( point_deltas_x );
FT_FREE( point_deltas_y );
Fail2:
Exit:
if ( sharedpoints != ALL_POINTS )
FT_FREE( sharedpoints );
FT_FREE( tuple_coords );
FT_FREE( im_start_coords );
FT_FREE( im_end_coords );
FT_FRAME_EXIT();
Fail1:
FT_FREE( points_org );
FT_FREE( points_out );
FT_FREE( has_delta );
FT_FREE( peak_coords );
FT_FREE( point_deltas_x );
FExit:
FT_FRAME_EXIT();
return error;
}