freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[freetype2] 1100-sdf-precision-improvement 31c0a83: [sdf] Fixed corner c


From: Werner Lemberg
Subject: [freetype2] 1100-sdf-precision-improvement 31c0a83: [sdf] Fixed corner checks and improved performance.
Date: Sat, 16 Oct 2021 00:43:42 -0400 (EDT)

branch: 1100-sdf-precision-improvement
commit 31c0a833d670da95733109267d0a2a69a9a27bc4
Author: Anuj Verma <anujv@iitbhilai.ac.in>
Commit: Anuj Verma <anujv@iitbhilai.ac.in>

    [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).
    
      Also, replace tabs `\t` with spaces.
---
 src/sdf/ftsdf.c | 65 ++++++++++++++++++++++++++++++++++++---------------------
 1 file changed, 41 insertions(+), 24 deletions(-)

diff --git a/src/sdf/ftsdf.c b/src/sdf/ftsdf.c
index 0f9dffe..8f58a2a 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;
@@ -1160,9 +1172,9 @@
     /* we check the deviation of the bezier and stop if it is     */
     /* lower than a pre-defined `threhold` value.                 */
     if ( FT_ABS( 2 * cpos[0].x - 3 * cpos[1].x + cpos[3].x ) < threshold &&
-        FT_ABS( 2 * cpos[0].y - 3 * cpos[1].y + cpos[3].y ) < threshold &&
+         FT_ABS( 2 * cpos[0].y - 3 * cpos[1].y + cpos[3].y ) < threshold &&
          FT_ABS( cpos[0].x - 3 * cpos[2].x + 2 * cpos[3].x ) < threshold &&
-        FT_ABS( cpos[0].y - 3 * cpos[2].y + 2 * cpos[3].y ) < threshold )
+         FT_ABS( cpos[0].y - 3 * cpos[2].y + 2 * cpos[3].y ) < threshold )
     {
       split_cubic( cpos );
       goto Append;
@@ -1264,29 +1276,29 @@
           /* Subdivide the curve and add it to the list. */
           {
             FT_26D6_Vec  ctrls[3];
-           FT_26D6      dx, dy;
-           FT_UInt      num_splits;
+            FT_26D6      dx, dy;
+            FT_UInt      num_splits;
 
 
             ctrls[0] = edge->start_pos;
             ctrls[1] = edge->control_a;
             ctrls[2] = edge->end_pos;
 
-           dx = FT_ABS( ctrls[2].x + ctrls[0].x - 2 * ctrls[1].x );
-           dy = FT_ABS( ctrls[2].y + ctrls[0].y - 2 * ctrls[1].y );
+            dx = FT_ABS( ctrls[2].x + ctrls[0].x - 2 * ctrls[1].x );
+            dy = FT_ABS( ctrls[2].y + ctrls[0].y - 2 * ctrls[1].y );
             if ( dx < dy )
-             dx = dy;
-
-           /* Here we calculate the number of necessary bisections. Each */
-           /* bisection reduces the deviation by exactly 4-fold, hence   */
-           /* we bisect the bezier until the deviation becomes less than */
-           /* 1/8th of a pixel. For more details check `ftgrays.c`.      */
-           num_splits = 1;
-           while ( dx > ONE_PIXEL / 8 )
-           {
-             dx >>= 2;
-             num_splits <<= 1;
-           }
+              dx = dy;
+
+            /* Here we calculate the number of necessary bisections. Each */
+            /* bisection reduces the deviation by exactly 4-fold, hence   */
+            /* we bisect the bezier until the deviation becomes less than */
+            /* 1/8th of a pixel. For more details check `ftgrays.c`.      */
+            num_splits = 1;
+            while ( dx > ONE_PIXEL / 8 )
+            {
+              dx >>= 2;
+              num_splits <<= 1;
+            }
 
             error = split_sdf_conic( memory, ctrls, num_splits, &new_edges );
           }
@@ -3316,6 +3328,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 )
@@ -3343,7 +3356,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 );
 
@@ -3355,11 +3368,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;
+            }
           }
         }
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]