freetype-commit
[Top][All Lists]
Advanced

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

[freetype2] anuj-distance-field 145c3c6 4/4: [sdf] Make squared distance


From: Anuj Verma
Subject: [freetype2] anuj-distance-field 145c3c6 4/4: [sdf] Make squared distances toggleable.
Date: Wed, 1 Jul 2020 07:25:24 -0400 (EDT)

branch: anuj-distance-field
commit 145c3c67f872b085c92dfbf03528bc8f325e39ca
Author: Anuj Verma <anujv@iitbhilai.ac.in>
Commit: Anuj Verma <anujv@iitbhilai.ac.in>

    [sdf] Make squared distances toggleable.
---
 [GSoC]ChangeLog | 16 ++++++++++
 src/sdf/ftsdf.c | 92 +++++++++++++++++++++++++++++++++++++++++----------------
 2 files changed, 82 insertions(+), 26 deletions(-)

diff --git a/[GSoC]ChangeLog b/[GSoC]ChangeLog
index 64775cc..780e912 100644
--- a/[GSoC]ChangeLog
+++ b/[GSoC]ChangeLog
@@ -1,5 +1,21 @@
 2020-07-01     Anuj Verma  <anujv@iitbhilai.ac.in>
 
+       [sdf] Make squared distances toggleable.
+
+       * src/sdf/ftsdf.c (SDF_Signed_Distance): Renamed 
+         squared_distance to distance. It can now represent
+         both squared as well as actual distances.
+
+       * src/sdf/ftsdf.c (USE_SQUARED_DISTANCES): Added macro
+         which control weather to do computation is squared
+         distances or actual distances. This can be used to
+         avoid overflow when generating large SDF bitmaps.
+
+       * src/sdf/ftsdf.c: Make sure not to exceed line length
+         of 78.
+
+2020-07-01     Anuj Verma  <anujv@iitbhilai.ac.in>
+
        * src/sdf/ftsdf.c (get_min_distance_conic): In case
          the cubic equation returns zero root, use endpoints
          for calculating the shortest distance.
diff --git a/src/sdf/ftsdf.c b/src/sdf/ftsdf.c
index 5826979..efbc119 100644
--- a/src/sdf/ftsdf.c
+++ b/src/sdf/ftsdf.c
@@ -9,13 +9,32 @@
 
   /**************************************************************************
    *
+   * definitions
+   *
+   */
+
+  /* If it is defined to 1 then the rasterizer will use squared distances */
+  /* for computation. It can greatly improve the performance but there is */
+  /* a chance of overflow and artifacts. You can safely use is upto a     */
+  /* pixel size of 128.                                                   */
+  #ifndef USE_SQUARED_DISTANCES
+    #define USE_SQUARED_DISTANCES 0
+  #endif
+
+  /**************************************************************************
+   *
    * macros
    *
    */
 
-  #define FT_INT_26D6( x )   ( x * 64 )     /* convert int to 26.6 fixed point 
  */
-  #define FT_INT_16D16( x )  ( x * 65536 )  /* convert int to 16.16 fixed 
point  */
-  #define FT_26D6_16D16( x ) ( x * 1024 )   /* convert 26.6 to 16.16 fixed 
point */
+  /* convert int to 26.6 fixed point   */
+  #define FT_INT_26D6( x )   ( x * 64 )
+
+  /* convert int to 16.16 fixed point  */
+  #define FT_INT_16D16( x )  ( x * 65536 )
+
+  /* convert 26.6 to 16.16 fixed point */
+  #define FT_26D6_16D16( x ) ( x * 1024 )
 
 
   /* Convenient macro which calls the function */
@@ -31,6 +50,19 @@
   #define VEC_26D6_DOT( p, q ) ( MUL_26D6( p.x, q.x ) +   \
                                  MUL_26D6( p.y, q.y ) )
 
+  /* [IMPORTANT]: The macro `VECTOR_LENGTH_16D16' is not always the same */
+  /* and must not be used anywhere except a few places. This macro is    */
+  /* controlled by the `USE_SQUARED_DISTANCES' macro. It compute squared */
+  /* distance or actual distance based on `USE_SQUARED_DISTANCES' value. */
+  /* By using squared distances the performance can be greatly improved  */
+  /* but there is a risk of overflow. Use it wisely.                     */
+  #if USE_SQUARED_DISTANCES
+    #define VECTOR_LENGTH_16D16( v ) ( FT_MulFix( v.x, v.x ) + \
+                                       FT_MulFix( v.y, v.y ) )
+  #else
+    #define VECTOR_LENGTH_16D16( v ) FT_Vector_Length( &v )
+  #endif
+
   /**************************************************************************
    *
    * typedefs
@@ -107,9 +139,12 @@
     /* [note]: This is a *direction* vector.          */
     FT_16D16_Vec  direction;
 
-    /* Unsigned shortest squared distance from the    */
-    /* point to the above `nearest_point'.            */
-    FT_16D16      squared_distance;
+    /* Unsigned shortest distance from the point to   */
+    /* the above `nearest_point'.                     */
+    /* [NOTE]: This can represent both squared as or  */
+    /* actual distance. This is controlled by the     */
+    /* `USE_SQUARED_DISTANCES' macro.                 */
+    FT_16D16      distance;
 
     /* Represent weather the `nearest_point' is outside */
     /* or inside the contour corresponding to the edge. */
@@ -493,7 +528,9 @@
       goto Exit;
     }
 
-    error = FT_Outline_Decompose( outline, &sdf_decompose_funcs, (void*)shape 
);
+    error = FT_Outline_Decompose( outline, 
+                                  &sdf_decompose_funcs,
+                                  (void*)shape );
 
   Exit:
     return error;
@@ -588,7 +625,8 @@
     }
 
     FT_TRACE5(( "\n" ));
-    FT_TRACE5(( "*note: the above values are in 26.6 fixed point format*\n" ));
+    FT_TRACE5(( "*note: the above values are "
+                "in 26.6 fixed point format*\n" ));
     FT_TRACE5(( "total number of contours = %d\n", num_contours ));
     FT_TRACE5(( "total number of edges    = %d\n", total_edges ));
     FT_TRACE5(( "[sdf] sdf_shape_dump complete\n" ));
@@ -925,8 +963,8 @@
     FT_16D16      ortho2;
 
     /* if they are not equal return the shorter */
-    if ( sdf1.squared_distance != sdf2.squared_distance )
-      return sdf1.squared_distance < sdf2.squared_distance ?
+    if ( sdf1.distance != sdf2.distance )
+      return sdf1.distance < sdf2.distance ?
              sdf1 : sdf2;
 
     /* if there is not ambiguity in the sign return any */
@@ -1091,8 +1129,7 @@
     /* assign the output */
     out->nearest_point = nearest_point;
     out->sign = cross < 0 ? 1 : -1;
-    out->squared_distance = FT_MulFix( nearest_vector.x, nearest_vector.x ) +
-                            FT_MulFix( nearest_vector.y, nearest_vector.y );
+    out->distance = VECTOR_LENGTH_16D16( nearest_vector );
     out->direction = line_segment;
 
   Exit:
@@ -1272,8 +1309,7 @@
       dist_vector.x = curve_point.x - p.x;
       dist_vector.y = curve_point.y - p.y;
 
-      dist = FT_MulFix( dist_vector.x, dist_vector.x ) +
-             FT_MulFix( dist_vector.y, dist_vector.y );
+      dist = VECTOR_LENGTH_16D16( dist_vector );
 
       if ( dist < min )
       {
@@ -1292,7 +1328,7 @@
             FT_MulFix( nearest_point.y - p.y, direction.x );
 
     /* assign the values */
-    out->squared_distance = min;
+    out->distance = min;
     out->nearest_point = nearest_point;
     out->sign = cross < 0 ? 1 : -1;
 
@@ -1393,11 +1429,11 @@
                (SDF_Edge*)edge_list.head->data,
                point, &current_dist ) );
 
-      if ( current_dist.squared_distance >= 0 && 
-           current_dist.squared_distance < min_dist.squared_distance )
+      if ( current_dist.distance >= 0 && 
+           current_dist.distance < min_dist.distance )
         min_dist = current_dist;
-      else if ( current_dist.squared_distance ==
-                min_dist.squared_distance )
+      else if ( current_dist.distance ==
+                min_dist.distance )
         min_dist = resolve_corner( min_dist, current_dist, point );
     
       edge_list.head = edge_list.head->next;
@@ -1458,7 +1494,10 @@
     rows   = bitmap->rows;
     buffer = (FT_Short*)bitmap->buffer;
 
-    sp_sq = FT_INT_16D16( spread * spread );
+    if ( USE_SQUARED_DISTANCES )
+      sp_sq = FT_INT_16D16( spread * spread );
+    else
+      sp_sq = FT_INT_16D16( spread );
 
     if ( width == 0 || rows == 0 )
     {
@@ -1506,7 +1545,7 @@
                    (SDF_Contour*)contour_list.head->data,
                    grid_point, &current_dist ) );
 
-          if ( current_dist.squared_distance < min_dist.squared_distance )
+          if ( current_dist.distance < min_dist.distance )
             min_dist = current_dist;
 
           contour_list.head = contour_list.head->next;
@@ -1516,14 +1555,15 @@
         /*                 the value to spread to avoid square_root */
 
         /* clamp the values to spread */
-        if ( min_dist.squared_distance > sp_sq )
-          min_dist.squared_distance = sp_sq;
+        if ( min_dist.distance > sp_sq )
+          min_dist.distance = sp_sq;
 
         /* square_root the values and fit in a 6.10 fixed point */
-        min_dist.squared_distance = square_root( min_dist.squared_distance );
+        if ( USE_SQUARED_DISTANCES )
+          min_dist.distance = square_root( min_dist.distance );
 
-        min_dist.squared_distance /= 64; /* convert from 16.16 to 22.10 */
-        value = min_dist.squared_distance & 0x0000FFFF; /* truncate to 6.10 */
+        min_dist.distance /= 64; /* convert from 16.16 to 22.10 */
+        value = min_dist.distance & 0x0000FFFF; /* truncate to 6.10 */
         value *= min_dist.sign;
 
         buffer[index] = value;



reply via email to

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