[sdf] Added functions to get shortest distance from any edge/contour.

* src/sdf/ftsdf,c (sdf_edge_get_min_distance): Added function to get shortest distance
  from any arbitary edge.

* src/sdf/ftsdf.c (sdf_contour_get_min_distance): Added function to get shortest
  distance from a contour. It basically returns the shortest distance from the nearest
  edge.
This commit is contained in:
Anuj Verma 2020-08-19 12:22:34 +05:30
parent c39b5dd849
commit 75182d8ad1
1 changed files with 143 additions and 0 deletions

View File

@ -2505,5 +2505,148 @@
return error;
}
/**************************************************************************
*
* @Function:
* sdf_edge_get_min_distance
*
* @Description:
* This is a handy function which can be used to find shortest distance
* from a `point' to any type of `edge'. It checks the edge type and
* then calls the relevant `get_min_distance_' function.
*
* @Input:
* edge ::
* An edge to which the shortest distance is to be computed.
*
* point ::
* Point from which the shortest distance is to be computed.
*
* @Return:
* out ::
* Signed distance from the `point' to the `edge'.
*
* FT_Error ::
* FreeType error, 0 means success.
*
*/
static FT_Error
sdf_edge_get_min_distance( SDF_Edge* edge,
FT_26D6_Vec point,
SDF_Signed_Distance* out)
{
FT_Error error = FT_Err_Ok;
if ( !edge || !out )
{
error = FT_THROW( Invalid_Argument );
goto Exit;
}
/* edge specific distance calculation */
switch ( edge->edge_type ) {
case SDF_EDGE_LINE:
get_min_distance_line( edge, point, out );
break;
case SDF_EDGE_CONIC:
get_min_distance_conic( edge, point, out );
break;
case SDF_EDGE_CUBIC:
get_min_distance_cubic( edge, point, out );
break;
default:
error = FT_THROW( Invalid_Argument );
}
Exit:
return error;
}
/* `sdf_generate' is not used at the moment */
#if 0
/**************************************************************************
*
* @Function:
* sdf_contour_get_min_distance
*
* @Description:
* This function iterate through all the edges that make up
* the contour and find the shortest distance from a point to
* this contour and assigns it to `out'.
*
* @Input:
* contour ::
* A contour to which the shortest distance is to be computed.
*
* point ::
* Point from which the shortest distance is to be computed.
*
* @Return:
* out ::
* Signed distance from the `point' to the `contour'.
*
* FT_Error ::
* FreeType error, 0 means success.
*
* @Note:
* The function does not return signed distance for each edge
* which make up the contour, it simply returns the shortest
* of all the edges.
*
*/
static FT_Error
sdf_contour_get_min_distance( SDF_Contour* contour,
FT_26D6_Vec point,
SDF_Signed_Distance* out)
{
FT_Error error = FT_Err_Ok;
SDF_Signed_Distance min_dist = max_sdf;
SDF_Edge* edge_list;
if ( !contour || !out )
{
error = FT_THROW( Invalid_Argument );
goto Exit;
}
edge_list = contour->edges;
/* iterate through all the edges manually */
while ( edge_list ) {
SDF_Signed_Distance current_dist = max_sdf;
FT_16D16 diff;
FT_CALL( sdf_edge_get_min_distance(
edge_list,
point, &current_dist ) );
if ( current_dist.distance >= 0 )
{
diff = current_dist.distance - min_dist.distance;
if ( FT_ABS(diff ) < CORNER_CHECK_EPSILON )
min_dist = resolve_corner( min_dist, current_dist );
else if ( diff < 0 )
min_dist = current_dist;
}
else
{
FT_TRACE0(( "sdf_contour_get_min_distance: Overflowed.\n" ));
}
edge_list = edge_list->next;
}
*out = min_dist;
Exit:
return error;
}
#endif
/* END */