summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnuj Verma <anujv@iitbhilai.ac.in>2020-08-19 12:22:34 +0530
committerWerner Lemberg <wl@gnu.org>2020-12-22 09:03:26 +0100
commit43ea02796c2010a9f5b508137c99b53da20a486a (patch)
treea79286717e1b933b7977279a71a09f1b710f490e
parent8ccc273c2e1c3c94ad0e855dc39c084b5dae6f57 (diff)
downloadfreetype2-43ea02796c2010a9f5b508137c99b53da20a486a.tar.gz
[sdf] Add functions to get shortest distance from any edge/contour.
* src/sdf/ftsdf.c (sdf_edge_get_min_distance): New function. (sdf_contour_get_min_distance): New function, currently disabled.
-rw-r--r--ChangeLog7
-rw-r--r--src/sdf/ftsdf.c149
2 files changed, 156 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 5d2a01b9f..6dabc350f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2020-08-19 Anuj Verma <anujv@iitbhilai.ac.in>
+
+ [sdf] Add functions to get shortest distance from any edge/contour.
+
+ * src/sdf/ftsdf.c (sdf_edge_get_min_distance): New function.
+ (sdf_contour_get_min_distance): New function, currently disabled.
+
2020-08-18 Anuj Verma <anujv@iitbhilai.ac.in>
[sdf] Add shortest distance finding functions.
diff --git a/src/sdf/ftsdf.c b/src/sdf/ftsdf.c
index 9f7f57d82..5a83d8fef 100644
--- a/src/sdf/ftsdf.c
+++ b/src/sdf/ftsdf.c
@@ -2735,9 +2735,158 @@
out->cross = FT_MulFix( direction.x, nearest_point.y ) -
FT_MulFix( direction.y, nearest_point.x );
}
+
+ Exit:
+ return error;
+ }
+
+
+ /**************************************************************************
+ *
+ * @Function:
+ * sdf_edge_get_min_distance
+ *
+ * @Description:
+ * Find shortest distance from `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.
+ *
+ * @Output:
+ * out ::
+ * Signed distance from `point` to `edge`.
+ *
+ * @Return:
+ * 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:
+ * Iterate over all edges that make up the contour, find the shortest
+ * distance from a point to this contour, and assigns result 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.
+ *
+ * @Output:
+ * out ::
+ * Signed distance from the `point' to the `contour'.
+ *
+ * @Return:
+ * FreeType error, 0 means success.
+ *
+ * @Note:
+ * The function does not return a signed distance for each edge which
+ * makes 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 over 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: Overflow.\n" ));
+
+ edge_list = edge_list->next;
+ }
+
+ *out = min_dist;
+
+ Exit:
+ return error;
+ }
+
+#endif
+
/* END */