mirror of
https://gitlab.freedesktop.org/freetype/freetype.git
synced 2026-05-07 04:08:47 +02:00
Merge branch 'heap_rast' into 'master'
[smooth] Dynamic pool allocation. See merge request freetype/freetype!429
This commit is contained in:
commit
c236e360e2
1 changed files with 84 additions and 70 deletions
|
|
@ -492,9 +492,10 @@ typedef ptrdiff_t FT_PtrDist;
|
|||
TCoord count_ey; /* same as (max_ey - min_ey) */
|
||||
|
||||
int error; /* pool overflow exception */
|
||||
PCell buffer; /* buffer */
|
||||
PCell cell_null; /* last cell, used as dumpster and limit */
|
||||
PCell cell; /* current cell */
|
||||
PCell cell_free; /* call allocation next free slot */
|
||||
PCell cell_null; /* last cell, used as dumpster and limit */
|
||||
|
||||
PCell* ycells; /* array of cell linked-lists; one per */
|
||||
/* vertical coordinate in the current band */
|
||||
|
|
@ -1861,10 +1862,6 @@ typedef ptrdiff_t FT_PtrDist;
|
|||
static int
|
||||
gray_convert_glyph( RAS_ARG )
|
||||
{
|
||||
TCell buffer[FT_MAX_GRAY_POOL];
|
||||
size_t height = (size_t)( ras.cbox.yMax - ras.cbox.yMin );
|
||||
size_t n = FT_MAX_GRAY_POOL / 8;
|
||||
TCoord y;
|
||||
TCoord bands[32]; /* enough to accommodate bisections */
|
||||
TCoord* band;
|
||||
|
||||
|
|
@ -1873,89 +1870,74 @@ typedef ptrdiff_t FT_PtrDist;
|
|||
|
||||
|
||||
/* Initialize the null cell at the end of the poll. */
|
||||
ras.cell_null = buffer + FT_MAX_GRAY_POOL - 1;
|
||||
ras.cell_null->x = CELL_MAX_X_VALUE;
|
||||
ras.cell_null->area = 0;
|
||||
ras.cell_null->cover = 0;
|
||||
ras.cell_null->next = NULL;
|
||||
|
||||
/* set up vertical bands */
|
||||
ras.ycells = (PCell*)buffer;
|
||||
ras.ycells = (PCell*)ras.buffer;
|
||||
|
||||
if ( height > n )
|
||||
ras.min_ex = ras.cbox.xMin;
|
||||
ras.max_ex = ras.cbox.xMax;
|
||||
|
||||
band = bands;
|
||||
band[1] = ras.cbox.yMin;
|
||||
band[0] = ras.cbox.yMax;
|
||||
|
||||
do
|
||||
{
|
||||
/* two divisions rounded up */
|
||||
n = ( height + n - 1 ) / n;
|
||||
height = ( height + n - 1 ) / n;
|
||||
}
|
||||
size_t n;
|
||||
TCoord i;
|
||||
|
||||
for ( y = ras.cbox.yMin; y < ras.cbox.yMax; )
|
||||
{
|
||||
ras.min_ey = y;
|
||||
y += height;
|
||||
ras.max_ey = FT_MIN( y, ras.cbox.yMax );
|
||||
|
||||
ras.min_ey = band[1];
|
||||
ras.max_ey = band[0];
|
||||
ras.count_ey = ras.max_ey - ras.min_ey;
|
||||
|
||||
band = bands;
|
||||
band[1] = ras.cbox.xMin;
|
||||
band[0] = ras.cbox.xMax;
|
||||
/* memory management: zero out and skip ycells */
|
||||
for ( i = 0; i < ras.count_ey; ++i )
|
||||
ras.ycells[i] = ras.cell_null;
|
||||
|
||||
do
|
||||
n = ( (size_t)ras.count_ey * sizeof ( PCell ) + sizeof ( TCell ) - 1 )
|
||||
/ sizeof ( TCell );
|
||||
|
||||
ras.cell_free = ras.buffer + n;
|
||||
ras.cell = ras.cell_null;
|
||||
ras.error = Smooth_Err_Ok;
|
||||
|
||||
error = gray_convert_glyph_inner( RAS_VAR_ continued );
|
||||
continued = 1;
|
||||
|
||||
if ( !error )
|
||||
{
|
||||
TCoord i;
|
||||
if ( ras.render_span ) /* for FT_RASTER_FLAG_DIRECT only */
|
||||
gray_sweep_direct( RAS_VAR );
|
||||
else
|
||||
gray_sweep( RAS_VAR );
|
||||
band--;
|
||||
continue;
|
||||
}
|
||||
else if ( error != Smooth_Err_Raster_Overflow )
|
||||
goto Exit;
|
||||
|
||||
/* render pool overflow; we will reduce the render band by half */
|
||||
i = ( band[0] - band[1] ) >> 1;
|
||||
|
||||
ras.min_ex = band[1];
|
||||
ras.max_ex = band[0];
|
||||
/* this should never happen even with tiny rendering pool */
|
||||
if ( i == 0 )
|
||||
{
|
||||
FT_TRACE7(( "gray_convert_glyph: rotten glyph\n" ));
|
||||
error = FT_THROW( Raster_Overflow );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* memory management: zero out and skip ycells */
|
||||
for ( i = 0; i < ras.count_ey; ++i )
|
||||
ras.ycells[i] = ras.cell_null;
|
||||
|
||||
n = ( (size_t)ras.count_ey * sizeof ( PCell ) + sizeof ( TCell ) - 1 )
|
||||
/ sizeof ( TCell );
|
||||
|
||||
ras.cell_free = buffer + n;
|
||||
ras.cell = ras.cell_null;
|
||||
ras.error = Smooth_Err_Ok;
|
||||
|
||||
error = gray_convert_glyph_inner( RAS_VAR_ continued );
|
||||
continued = 1;
|
||||
|
||||
if ( !error )
|
||||
{
|
||||
if ( ras.render_span ) /* for FT_RASTER_FLAG_DIRECT only */
|
||||
gray_sweep_direct( RAS_VAR );
|
||||
else
|
||||
gray_sweep( RAS_VAR );
|
||||
band--;
|
||||
continue;
|
||||
}
|
||||
else if ( error != Smooth_Err_Raster_Overflow )
|
||||
goto Exit;
|
||||
|
||||
/* render pool overflow; we will reduce the render band by half */
|
||||
i = ( band[0] - band[1] ) >> 1;
|
||||
|
||||
/* this should never happen even with tiny rendering pool */
|
||||
if ( i == 0 )
|
||||
{
|
||||
FT_TRACE7(( "gray_convert_glyph: rotten glyph\n" ));
|
||||
error = FT_THROW( Raster_Overflow );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
band++;
|
||||
band[1] = band[0];
|
||||
band[0] += i;
|
||||
} while ( band >= bands );
|
||||
}
|
||||
band++;
|
||||
band[1] = band[0];
|
||||
band[0] += i;
|
||||
} while ( band >= bands );
|
||||
|
||||
Exit:
|
||||
ras.cell = ras.cell_free = ras.cell_null = NULL;
|
||||
ras.ycells = NULL;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
@ -1964,6 +1946,9 @@ typedef ptrdiff_t FT_PtrDist;
|
|||
gray_raster_render( FT_Raster raster,
|
||||
const FT_Raster_Params* params )
|
||||
{
|
||||
FT_Long estimate;
|
||||
int ret;
|
||||
|
||||
const FT_Outline* outline = (const FT_Outline*)params->source;
|
||||
const FT_Bitmap* target_map = params->target;
|
||||
|
||||
|
|
@ -2039,7 +2024,36 @@ typedef ptrdiff_t FT_PtrDist;
|
|||
if ( ras.cbox.xMin >= ras.cbox.xMax || ras.cbox.yMin >= ras.cbox.yMax )
|
||||
return Smooth_Err_Ok;
|
||||
|
||||
return gray_convert_glyph( RAS_VAR );
|
||||
/* allocate memory based on empirical estimate from CJK fonts */
|
||||
estimate = ( ras.cbox.xMax - ras.cbox.xMin +
|
||||
ras.cbox.yMax - ras.cbox.yMin ) * 10;
|
||||
if ( estimate > FT_MAX_GRAY_POOL )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Memory memory = (FT_Memory)((gray_PRaster)raster)->memory;
|
||||
|
||||
|
||||
if ( FT_QNEW_ARRAY( ras.buffer, estimate ) )
|
||||
ret = error;
|
||||
else
|
||||
{
|
||||
ras.cell_null = ras.buffer + estimate - 1;
|
||||
ret = gray_convert_glyph( RAS_VAR );
|
||||
FT_FREE( ras.buffer );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TCell buffer[FT_MAX_GRAY_POOL]; /* stack allocation */
|
||||
|
||||
|
||||
ras.buffer = buffer;
|
||||
ras.cell_null = ras.buffer + FT_MAX_GRAY_POOL - 1;
|
||||
|
||||
ret = gray_convert_glyph( RAS_VAR );
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue