diff options
author | Anuj Verma <anuj@womp.xyz> | 2022-03-04 16:58:50 +0530 |
---|---|---|
committer | Werner Lemberg <wl@gnu.org> | 2022-03-05 17:00:10 +0100 |
commit | 360e2507a38588e19fa6d2fc30706db74db0d958 (patch) | |
tree | f228b986d4acb6ee8d75b96602dcc8ce5f00e3c1 | |
parent | 2600ef637ef29bcfceb533e554463b4a1ee96f49 (diff) | |
download | freetype2-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.c | 29 |
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; + } } } |