[sdf] Check for left or right fill.

* src/sdf/ftsdf.c (SDF_Params): Added struct which
  contains some internal data required by the rater-
  izer (such as left/right fill).

* src/sdf/ftsdf.c (sdf_raster_render): Determine the
  fill side and pass it to the `sdf_generate_' funcs.

* src/sdf/ftsdf.c (sdf_generate_): Use the new `SDF_Params'
  to generate SDF accordingly.
This commit is contained in:
Anuj Verma 2020-07-13 10:11:05 +05:30 committed by anujverma
parent 548bd3cf62
commit 6b03b1c57a
2 changed files with 58 additions and 7 deletions

View File

@ -1,3 +1,17 @@
2020-07-13 Anuj Verma <anujv@iitbhilai.ac.in>
[sdf] Check for left or right fill.
* src/sdf/ftsdf.c (SDF_Params): Added struct which
contains some internal data required by the rater-
izer (such as left/right fill).
* src/sdf/ftsdf.c (sdf_raster_render): Determine the
fill side and pass it to the `sdf_generate_' funcs.
* src/sdf/ftsdf.c (sdf_generate_): Use the new `SDF_Params'
to generate SDF accordingly.
2020-07-12 Anuj Verma <anujv@iitbhilai.ac.in> 2020-07-12 Anuj Verma <anujv@iitbhilai.ac.in>
[sdf] Optimize the coarse grid optimization. [sdf] Optimize the coarse grid optimization.

View File

@ -181,6 +181,23 @@
} SDF_Signed_Distance; } SDF_Signed_Distance;
typedef struct SDF_Params_
{
/* Used to properly assign sign to the pixels. In */
/* truetype the right should be inside but in post */
/* script left should be inside. */
FT_Orientation orientation;
/* Simply flip the sign if this is true. */
FT_Bool flip_sign;
/* If set to true the output will be upside down. */
/* Can be useful because OpenGL and DirectX have */
/* different coordinate system for textures. */
FT_Bool flip_y;
} SDF_Params;
/************************************************************************** /**************************************************************************
* *
* constants, initializer and destructor * constants, initializer and destructor
@ -2383,7 +2400,8 @@
* [TODO] * [TODO]
*/ */
static FT_Error static FT_Error
sdf_generate( const SDF_Shape* shape, sdf_generate( const SDF_Params internal_params,
const SDF_Shape* shape,
FT_UInt spread, FT_UInt spread,
const FT_Bitmap* bitmap ) const FT_Bitmap* bitmap )
{ {
@ -2480,6 +2498,9 @@
if ( USE_SQUARED_DISTANCES ) if ( USE_SQUARED_DISTANCES )
min_dist.distance = square_root( min_dist.distance ); min_dist.distance = square_root( min_dist.distance );
if ( internal_params.orientation == FT_ORIENTATION_FILL_LEFT )
min_dist.sign = -min_dist.sign;
min_dist.distance /= 64; /* convert from 16.16 to 22.10 */ min_dist.distance /= 64; /* convert from 16.16 to 22.10 */
value = min_dist.distance & 0x0000FFFF; /* truncate to 6.10 */ value = min_dist.distance & 0x0000FFFF; /* truncate to 6.10 */
value *= min_dist.sign; value *= min_dist.sign;
@ -2519,7 +2540,8 @@
* [TODO] * [TODO]
*/ */
static FT_Error static FT_Error
sdf_generate_bounding_box( const SDF_Shape* shape, sdf_generate_bounding_box( const SDF_Params internal_params,
const SDF_Shape* shape,
FT_UInt spread, FT_UInt spread,
const FT_Bitmap* bitmap ) const FT_Bitmap* bitmap )
{ {
@ -2626,6 +2648,9 @@
grid_point, grid_point,
&dist ) ); &dist ) );
if ( internal_params.orientation == FT_ORIENTATION_FILL_LEFT )
dist.sign = -dist.sign;
/* ignore if the distance is greater than spread */ /* ignore if the distance is greater than spread */
/* otherwise it creates artifacts due to wrong sign */ /* otherwise it creates artifacts due to wrong sign */
if ( dist.distance > sp_sq ) continue; if ( dist.distance > sp_sq ) continue;
@ -2707,14 +2732,16 @@
* [TODO] * [TODO]
*/ */
static FT_Error static FT_Error
sdf_generate_subdivision( SDF_Shape* shape, sdf_generate_subdivision( const SDF_Params internal_params,
SDF_Shape* shape,
FT_UInt spread, FT_UInt spread,
const FT_Bitmap* bitmap ) const FT_Bitmap* bitmap )
{ {
FT_Error error = FT_Err_Ok; FT_Error error = FT_Err_Ok;
FT_CALL( split_sdf_shape( shape ) ); FT_CALL( split_sdf_shape( shape ) );
FT_CALL( sdf_generate_bounding_box( shape, spread, bitmap ) ); FT_CALL( sdf_generate_bounding_box( internal_params,
shape, spread, bitmap ) );
Exit: Exit:
return error; return error;
@ -2742,7 +2769,8 @@
* [TODO] * [TODO]
*/ */
static FT_Error static FT_Error
sdf_generate_coarse_grid( const SDF_Shape* shape, sdf_generate_coarse_grid( const SDF_Params internal_params,
const SDF_Shape* shape,
FT_UInt spread, FT_UInt spread,
const FT_Bitmap* bitmap ) const FT_Bitmap* bitmap )
{ {
@ -2811,7 +2839,7 @@
/* check all pixels against all the edges */ /* check all pixels against all the edges */
if ( c_width <= 1 || c_rows <= 1 ) if ( c_width <= 1 || c_rows <= 1 )
{ {
error = sdf_generate( shape, spread, bitmap ); error = sdf_generate( internal_params, shape, spread, bitmap );
goto Exit; goto Exit;
} }
@ -2934,6 +2962,9 @@
if ( USE_SQUARED_DISTANCES ) if ( USE_SQUARED_DISTANCES )
min_dist.distance = square_root( min_dist.distance ); min_dist.distance = square_root( min_dist.distance );
if ( internal_params.orientation == FT_ORIENTATION_FILL_RIGHT )
min_dist.sign = -min_dist.sign;
min_dist.distance /= 64; min_dist.distance /= 64;
buffer[index] = (FT_Short)min_dist.distance * min_dist.sign; buffer[index] = (FT_Short)min_dist.distance * min_dist.sign;
@ -3015,6 +3046,7 @@
FT_Memory memory = NULL; FT_Memory memory = NULL;
SDF_Shape* shape = NULL; SDF_Shape* shape = NULL;
SDF_Params internal_params;
/* check for valid arguments */ /* check for valid arguments */
@ -3070,11 +3102,16 @@
goto Exit; goto Exit;
} }
/* setup the params */
internal_params.orientation = FT_Outline_Get_Orientation( outline );
internal_params.flip_sign = 0;
internal_params.flip_y = 0;
FT_CALL( sdf_shape_new( memory, &shape ) ); FT_CALL( sdf_shape_new( memory, &shape ) );
FT_CALL( sdf_outline_decompose( outline, shape ) ); FT_CALL( sdf_outline_decompose( outline, shape ) );
FT_CALL( sdf_generate_subdivision( shape, sdf_params->spread, FT_CALL( sdf_generate_subdivision( internal_params, shape, sdf_params->spread,
sdf_params->root.target ) ); sdf_params->root.target ) );
if ( shape ) if ( shape )