mirror of
https://gitlab.freedesktop.org/freetype/freetype.git
synced 2025-12-27 06:20:06 +01:00
[smooth] Remove usage of setjmp and longjmp.
To support WASM targets with slow or unsupported setjmp and longjmp, we eliminate these calls in favor of an error propagation model. When gray_set_cell is out of cells, it raises an exception which is later handled in gray_convert_glyph_inner. This is a less invasive alternative to !385. * src/smooth/ftgrays.c (gray_set_cell): Raise the overflow exception and redirect all work to `cell_null`. (gray_move,line,conic,cubic_to): Return the exception. (gray_convert_glyph, gray_convert_glyph_inner): Handle the exception.
This commit is contained in:
parent
b04db3872c
commit
d6022b6d6e
1 changed files with 31 additions and 34 deletions
|
|
@ -157,10 +157,6 @@
|
|||
|
||||
#define ft_memset memset
|
||||
|
||||
#define ft_setjmp setjmp
|
||||
#define ft_longjmp longjmp
|
||||
#define ft_jmp_buf jmp_buf
|
||||
|
||||
typedef ptrdiff_t FT_PtrDist;
|
||||
|
||||
|
||||
|
|
@ -495,6 +491,7 @@ typedef ptrdiff_t FT_PtrDist;
|
|||
TCoord min_ey, max_ey;
|
||||
TCoord count_ey; /* same as (max_ey - min_ey) */
|
||||
|
||||
int error; /* pool overflow exception */
|
||||
PCell cell; /* current cell */
|
||||
PCell cell_free; /* call allocation next free slot */
|
||||
PCell cell_null; /* last cell, used as dumpster and limit */
|
||||
|
|
@ -510,8 +507,6 @@ typedef ptrdiff_t FT_PtrDist;
|
|||
FT_Raster_Span_Func render_span;
|
||||
void* render_span_data;
|
||||
|
||||
ft_jmp_buf jump_buffer;
|
||||
|
||||
} gray_TWorker, *gray_PWorker;
|
||||
|
||||
#if defined( _MSC_VER )
|
||||
|
|
@ -613,9 +608,14 @@ typedef ptrdiff_t FT_PtrDist;
|
|||
}
|
||||
|
||||
/* insert new cell */
|
||||
cell = ras.cell_free++;
|
||||
if ( cell >= ras.cell_null )
|
||||
ft_longjmp( ras.jump_buffer, 1 );
|
||||
cell = ras.cell_free;
|
||||
if ( cell == ras.cell_null )
|
||||
{
|
||||
ras.error = FT_THROW( Raster_Overflow );
|
||||
goto Found;
|
||||
}
|
||||
|
||||
ras.cell_free = cell + 1;
|
||||
|
||||
cell->x = ex;
|
||||
cell->area = 0;
|
||||
|
|
@ -1353,7 +1353,8 @@ typedef ptrdiff_t FT_PtrDist;
|
|||
|
||||
ras.x = x;
|
||||
ras.y = y;
|
||||
return 0;
|
||||
|
||||
return ras.error;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1365,7 +1366,8 @@ typedef ptrdiff_t FT_PtrDist;
|
|||
|
||||
|
||||
gray_render_line( RAS_VAR_ UPSCALE( to->x ), UPSCALE( to->y ) );
|
||||
return 0;
|
||||
|
||||
return ras.error;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1378,7 +1380,8 @@ typedef ptrdiff_t FT_PtrDist;
|
|||
|
||||
|
||||
gray_render_conic( RAS_VAR_ control, to );
|
||||
return 0;
|
||||
|
||||
return ras.error;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1392,7 +1395,8 @@ typedef ptrdiff_t FT_PtrDist;
|
|||
|
||||
|
||||
gray_render_cubic( RAS_VAR_ control1, control2, to );
|
||||
return 0;
|
||||
|
||||
return ras.error;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1700,30 +1704,22 @@ typedef ptrdiff_t FT_PtrDist;
|
|||
gray_convert_glyph_inner( RAS_ARG_
|
||||
int continued )
|
||||
{
|
||||
volatile int error;
|
||||
int error;
|
||||
|
||||
|
||||
if ( ft_setjmp( ras.jump_buffer ) == 0 )
|
||||
{
|
||||
if ( continued )
|
||||
FT_Trace_Disable();
|
||||
error = FT_Outline_Decompose( &ras.outline, &func_interface, &ras );
|
||||
if ( continued )
|
||||
FT_Trace_Enable();
|
||||
if ( continued )
|
||||
FT_Trace_Disable();
|
||||
error = FT_Outline_Decompose( &ras.outline, &func_interface, &ras );
|
||||
if ( continued )
|
||||
FT_Trace_Enable();
|
||||
|
||||
FT_TRACE7(( "band [%d..%d]: %td cell%s remaining\n",
|
||||
ras.min_ey,
|
||||
ras.max_ey,
|
||||
ras.cell_null - ras.cell_free,
|
||||
ras.cell_null - ras.cell_free == 1 ? "" : "s" ));
|
||||
}
|
||||
else
|
||||
{
|
||||
error = FT_THROW( Raster_Overflow );
|
||||
|
||||
FT_TRACE7(( "band [%d..%d]: to be bisected\n",
|
||||
ras.min_ey, ras.max_ey ));
|
||||
}
|
||||
FT_TRACE7(( error == Smooth_Err_Raster_Overflow
|
||||
? "band [%d..%d]: to be bisected\n"
|
||||
: "band [%d..%d]: %td cell%s remaining\n",
|
||||
ras.min_ey,
|
||||
ras.max_ey,
|
||||
ras.cell_null - ras.cell_free,
|
||||
ras.cell_null - ras.cell_free == 1 ? "" : "s" ));
|
||||
|
||||
return error;
|
||||
}
|
||||
|
|
@ -1922,6 +1918,7 @@ typedef ptrdiff_t FT_PtrDist;
|
|||
|
||||
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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue