summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnuj Verma <anuj@womp.xyz>2022-03-04 16:58:50 +0530
committerWerner Lemberg <wl@gnu.org>2022-03-05 17:00:10 +0100
commit360e2507a38588e19fa6d2fc30706db74db0d958 (patch)
treef228b986d4acb6ee8d75b96602dcc8ce5f00e3c1
parent2600ef637ef29bcfceb533e554463b4a1ee96f49 (diff)
downloadfreetype2-360e2507a38588e19fa6d2fc30706db74db0d958.tar.gz
[sdf] Fix corner checks and improve performance.
* src/sdf/ftsdf.c (sdf_generate_bounding_box): Always check for a corner if two distances (for different curves) are very close. (sdf_conic_to): Check whether the conic curve can be treated as a line (which happens if the control point coincides with any end point).
-rw-r--r--src/sdf/ftsdf.c29
1 files changed, 23 insertions, 6 deletions
diff --git a/src/sdf/ftsdf.c b/src/sdf/ftsdf.c
index fa551ea6e..891ef187e 100644
--- a/src/sdf/ftsdf.c
+++ b/src/sdf/ftsdf.c
@@ -738,6 +738,18 @@
contour = shape->contours;
+ /* If the control point coincides with any of the end points */
+ /* then it is 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;
@@ -3320,6 +3332,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 )
@@ -3347,7 +3360,7 @@
if ( dist.distance > sp_sq )
continue;
- /* square_root the values and fit in a 6.10 fixed-point */
+ /* take the square root of the distance if required */
if ( USE_SQUARED_DISTANCES )
dist.distance = square_root( dist.distance );
@@ -3359,11 +3372,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;
+ }
}
}