From ab950e18f4f9bf0ea2b4ba6bb9eb3379be3b1a2d Mon Sep 17 00:00:00 2001 From: Anuj Verma Date: Fri, 4 Mar 2022 16:58:50 +0530 Subject: [PATCH] [sdf] Fixed corner checks and improved performance. * src/sdf/ftsdf.c (sdf_generate_bounding_box): Always check for corner if two distance (for different curves) are very close. * src/sdf/ftsdf.c (sdf_conic_to): Added check to figure out if the conic can be treated as a line (which happens if the control point coincide with any end-point). --- src/sdf/ftsdf.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/sdf/ftsdf.c b/src/sdf/ftsdf.c index e6ab61fe6..de6684436 100644 --- a/src/sdf/ftsdf.c +++ b/src/sdf/ftsdf.c @@ -738,6 +738,18 @@ contour = shape->contours; + /* If the control point coincide with any of the end point */ + /* then it's a line and should be treated as one to avoid */ + /* unnecessary complexity later in the algorithm. */ + if ( ( contour->last_pos.x == control_1->x && + contour->last_pos.y == control_1->y ) || + ( control_1->x == to->x && + control_1->y == to->y ) ) + { + sdf_line_to( to, user ); + goto Exit; + } + FT_CALL( sdf_edge_new( memory, &edge ) ); edge->edge_type = SDF_EDGE_CONIC; @@ -3318,6 +3330,7 @@ FT_26D6_Vec grid_point = zero_vector; SDF_Signed_Distance dist = max_sdf; FT_UInt index = 0; + FT_16D16 diff = 0; if ( x < 0 || x >= width ) @@ -3345,7 +3358,7 @@ if ( dist.distance > sp_sq ) continue; - /* square_root the values and fit in a 6.10 fixed-point */ + /* square_root the values if required */ if ( USE_SQUARED_DISTANCES ) dist.distance = square_root( dist.distance ); @@ -3357,11 +3370,15 @@ /* check whether the pixel is set or not */ 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 ) - dists[index] = resolve_corner( dists[index], dist ); + else + { + diff = FT_ABS( dists[index].distance - dist.distance ); + + if ( diff <= CORNER_CHECK_EPSILON ) + dists[index] = resolve_corner( dists[index], dist ); + else if ( dists[index].distance > dist.distance ) + dists[index] = dist; + } } }