forked from minhngoc25a/freetype2
* src/sdf/ftsdfrend.c (sdf_generate_bounding_box): Add buffer for signs.
This commit is contained in:
parent
e6576cc0e7
commit
c4f64fc0e1
|
@ -1,3 +1,12 @@
|
||||||
|
2020-07-06 Anuj Verma <anujv@iitbhilai.ac.in>
|
||||||
|
|
||||||
|
* src/sdf/ftsdfrend.c (sdf_generate_bounding_box): Due to
|
||||||
|
the way we use the bounding box, we need to keep a track
|
||||||
|
of signed distances of each pixel so later the sign can
|
||||||
|
be determined properly. The method is certainly faster
|
||||||
|
then checking all the pixels agains all the edges,
|
||||||
|
but also require a decent amount of memory to work.
|
||||||
|
|
||||||
2020-07-06 Anuj Verma <anujv@iitbhilai.ac.in>
|
2020-07-06 Anuj Verma <anujv@iitbhilai.ac.in>
|
||||||
|
|
||||||
[sdf] Precompute the orthogonality.
|
[sdf] Precompute the orthogonality.
|
||||||
|
|
|
@ -2250,9 +2250,10 @@
|
||||||
|
|
||||||
/* This buffer has the same size in indices as the */
|
/* This buffer has the same size in indices as the */
|
||||||
/* bitmap buffer. When we check a pixel position for */
|
/* bitmap buffer. When we check a pixel position for */
|
||||||
/* shortest distance we keep the sign in this buffer */
|
/* shortest distance we keep it in this buffer. */
|
||||||
/* This way we check find out which pixel is set. */
|
/* This way we check find out which pixel is set, */
|
||||||
FT_Char* signs;
|
/* and also determine the signs properly. */
|
||||||
|
SDF_Signed_Distance* dists;
|
||||||
|
|
||||||
if ( !shape || !bitmap )
|
if ( !shape || !bitmap )
|
||||||
{
|
{
|
||||||
|
@ -2273,10 +2274,10 @@
|
||||||
rows = bitmap->rows;
|
rows = bitmap->rows;
|
||||||
buffer = (FT_Short*)bitmap->buffer;
|
buffer = (FT_Short*)bitmap->buffer;
|
||||||
|
|
||||||
if ( FT_ALLOC_MULT( signs, width, rows ) )
|
if ( FT_ALLOC_MULT( dists, width, rows * sizeof(*dists) ) )
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
|
||||||
FT_MEM_ZERO( signs, width * rows );
|
FT_MEM_ZERO( dists, width * rows * sizeof(*dists) );
|
||||||
|
|
||||||
if ( USE_SQUARED_DISTANCES )
|
if ( USE_SQUARED_DISTANCES )
|
||||||
sp_sq = FT_INT_16D16( spread * spread );
|
sp_sq = FT_INT_16D16( spread * spread );
|
||||||
|
@ -2307,10 +2308,10 @@
|
||||||
|
|
||||||
/* get the control box and increase by `spread' */
|
/* get the control box and increase by `spread' */
|
||||||
cbox = get_control_box( *current_edge );
|
cbox = get_control_box( *current_edge );
|
||||||
cbox.xMin = ROUND_F26DOT6( cbox.xMin ) / 64 - ( FT_Pos )spread;
|
cbox.xMin = ( cbox.xMin - 63 ) / 64 - ( FT_Pos )spread;
|
||||||
cbox.xMax = ROUND_F26DOT6( cbox.xMax ) / 64 + ( FT_Pos )spread;
|
cbox.xMax = ( cbox.xMax + 63 ) / 64 + ( FT_Pos )spread;
|
||||||
cbox.yMin = ROUND_F26DOT6( cbox.yMin ) / 64 - ( FT_Pos )spread;
|
cbox.yMin = ( cbox.yMin - 63 ) / 64 - ( FT_Pos )spread;
|
||||||
cbox.yMax = ROUND_F26DOT6( cbox.yMax ) / 64 + ( FT_Pos )spread;
|
cbox.yMax = ( cbox.yMax + 63 ) / 64 + ( FT_Pos )spread;
|
||||||
|
|
||||||
/* now loop the pixels in the control box. */
|
/* now loop the pixels in the control box. */
|
||||||
for ( y = cbox.yMin; y < cbox.yMax; y++ )
|
for ( y = cbox.yMin; y < cbox.yMax; y++ )
|
||||||
|
@ -2340,30 +2341,23 @@
|
||||||
grid_point,
|
grid_point,
|
||||||
&dist ) );
|
&dist ) );
|
||||||
|
|
||||||
/* clamp the values to spread */
|
/* ignore if the distance is greater than spread */
|
||||||
if ( dist.distance > sp_sq )
|
/* otherwise it creates artifacts due to wrong sign */
|
||||||
dist.distance = sp_sq;
|
if ( dist.distance > sp_sq ) continue;
|
||||||
|
|
||||||
/* square_root the values and fit in a 6.10 fixed point */
|
/* square_root the values and fit in a 6.10 fixed point */
|
||||||
if ( USE_SQUARED_DISTANCES )
|
if ( USE_SQUARED_DISTANCES )
|
||||||
dist.distance = square_root( dist.distance );
|
dist.distance = square_root( dist.distance );
|
||||||
|
|
||||||
dist.distance /= 64;
|
|
||||||
|
|
||||||
/* [IMPORTANT]: Do corner checking. Unfortunately */
|
|
||||||
/* this will require more memory usage to keep the */
|
|
||||||
/* direction of each pixel. */
|
|
||||||
|
|
||||||
/* check weather the pixel is set or not */
|
/* check weather the pixel is set or not */
|
||||||
if ( signs[index] == 0 )
|
if ( dists[index].sign == 0 )
|
||||||
|
dists[index] = dist;
|
||||||
|
else if ( dists[index].distance > dist.distance )
|
||||||
|
dists[index] = dist;
|
||||||
|
else if ( FT_ABS(dists[index].distance - dist.distance ) < CORNER_CHECK_EPSILON )
|
||||||
{
|
{
|
||||||
buffer[index] = dist.distance;
|
if ( FT_ABS( dists[index].cross ) < FT_ABS( dist.cross ) )
|
||||||
signs[index] = dist.sign;
|
dists[index] = dist;
|
||||||
}
|
|
||||||
else if ( dist.distance < buffer[index] )
|
|
||||||
{
|
|
||||||
buffer[index] = dist.distance;
|
|
||||||
signs[index] = dist.sign;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2386,18 +2380,26 @@
|
||||||
{
|
{
|
||||||
index = j * width + i;
|
index = j * width + i;
|
||||||
|
|
||||||
|
/* if the pixel is not set that means it's */
|
||||||
if ( signs[index] == 0 )
|
/* shortest distance is more than spread */
|
||||||
buffer[index] = (spread * 1024);
|
if ( dists[index].sign == 0 )
|
||||||
|
dists[index].distance = FT_INT_16D16( spread );
|
||||||
else
|
else
|
||||||
current_sign = signs[index];
|
current_sign = dists[index].sign;
|
||||||
|
|
||||||
buffer[index] *= current_sign;
|
/* clamp the values */
|
||||||
|
if ( dists[index].distance > FT_INT_16D16( spread ) )
|
||||||
|
dists[index].distance = FT_INT_16D16( spread );
|
||||||
|
|
||||||
|
/* convert from 16.16 to 6.10 */
|
||||||
|
dists[index].distance /= 64;
|
||||||
|
|
||||||
|
buffer[index] = dists[index].distance * current_sign;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Exit:
|
Exit:
|
||||||
FT_FREE( signs );
|
FT_FREE( dists );
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2519,7 +2521,7 @@
|
||||||
|
|
||||||
FT_CALL( sdf_outline_decompose( outline, shape ) );
|
FT_CALL( sdf_outline_decompose( outline, shape ) );
|
||||||
|
|
||||||
FT_CALL( sdf_generate( shape, sdf_params->spread,
|
FT_CALL( sdf_generate_bounding_box( shape, sdf_params->spread,
|
||||||
sdf_params->root.target ) );
|
sdf_params->root.target ) );
|
||||||
|
|
||||||
Exit:
|
Exit:
|
||||||
|
|
Loading…
Reference in New Issue