freetype-commit
[Top][All Lists]
Advanced

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

[freetype2] anuj-distance-field c57119b 75/95: [sdf -> bsdf] Added first


From: Anuj Verma
Subject: [freetype2] anuj-distance-field c57119b 75/95: [sdf -> bsdf] Added first pass of the '8SED' algorithm.
Date: Sun, 2 Aug 2020 01:10:39 -0400 (EDT)

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

    [sdf -> bsdf] Added first pass of the '8SED' algorithm.
    
    Added the first pass of the 8SED algorithm. The first pass
    transverse the bitmap from top to bottom and for each row
    it sweeps forward and backward assigning distances to the
    grid points.
    
    * src/sdf/ftbsdf.c (ED): Added additional parameter `sign'.
    
    * src/sdf/ftbsdf.c (edt8): Added function to convert bitmap
      to SDF using the 8SED algorithm.
    
    * src/sdf/ftbsdf.c (first_pass): Added function to do the
      first pass of the 8SED algorithm on the bitmap.
    
    * src/sdf/ftbsdf.c (finalize_sdf): Added function to assign
      the final SDF data to the target bitmap.
    
    * src/sdf/ftbsdf.c (*): Various minor or experimental changes.
    
    * src/sdf/ftsdfrend.c (ft_bsdf_render): Fix spacing.
---
 [GSoC]ChangeLog     |  24 +++++
 src/sdf/ftbsdf.c    | 266 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 src/sdf/ftsdfrend.c |   8 +-
 3 files changed, 284 insertions(+), 14 deletions(-)

diff --git a/[GSoC]ChangeLog b/[GSoC]ChangeLog
index ba15dc4..28a7efb 100644
--- a/[GSoC]ChangeLog
+++ b/[GSoC]ChangeLog
@@ -1,3 +1,27 @@
+2020-07-26  Anuj Verma  <anujv@iitbhilai.ac.in>
+
+       [sdf -> bsdf] Added first pass of the '8SED' algorithm.
+
+       Added the first pass of the 8SED algorithm. The first pass
+       transverse the bitmap from top to bottom and for each row
+       it sweeps forward and backward assigning distances to the
+       grid points.
+
+       * src/sdf/ftbsdf.c (ED): Added additional parameter `sign'.
+
+       * src/sdf/ftbsdf.c (edt8): Added function to convert bitmap
+         to SDF using the 8SED algorithm.
+
+       * src/sdf/ftbsdf.c (first_pass): Added function to do the
+         first pass of the 8SED algorithm on the bitmap.
+
+       * src/sdf/ftbsdf.c (finalize_sdf): Added function to assign
+         the final SDF data to the target bitmap.
+
+       * src/sdf/ftbsdf.c (*): Various minor or experimental changes.
+
+       * src/sdf/ftsdfrend.c (ft_bsdf_render): Fix spacing.
+
 2020-07-25  Anuj Verma  <anujv@iitbhilai.ac.in>
 
        * src/sdf/ftbsdf.c (*): Rename `SDF_TRaster' => `BSDF_TRaster'.
diff --git a/src/sdf/ftbsdf.c b/src/sdf/ftbsdf.c
index 6514cf7..46461f5 100644
--- a/src/sdf/ftbsdf.c
+++ b/src/sdf/ftbsdf.c
@@ -21,6 +21,8 @@
                            goto Exit;              \
                        } while ( 0 )
 
+  #define ONE 65536 /* 1 in 16.16 */
+
   /**************************************************************************
    *
    * typedefs
@@ -48,7 +50,8 @@
   typedef struct  ED_
   {
     FT_16D16      dist; /* distance at `near' */
-    FT_16D16_Vec  near; /* nearest point */
+    FT_16D16_Vec  near; /* nearest point      */
+    FT_Char       sign; /* outside or inside  */
 
   } ED;
 
@@ -65,6 +68,15 @@
 
   /**************************************************************************
    *
+   * initializer
+   *
+   */
+
+  static
+  const ED  zero_ed = { 0, { 0, 0 }, 0 };
+
+  /**************************************************************************
+   *
    * rasterizer functions
    *
    */
@@ -180,17 +192,22 @@
         {
           FT_Int    t_index = t_j * t_width + t_i;
           FT_Int    s_index;
-          FT_Short  pixel_value;
+          FT_Byte   pixel_value;
+
 
+          t[t_index] = zero_ed;
 
           s_i = t_i - x_diff;
           s_j = t_j - y_diff;
 
-          /* assign INT_MAX to the padding */
+          /* Assign 0 to padding similar to */
+          /* the source bitmap.             */
           if ( s_i < 0 || s_i >= s_width ||
                s_j < 0 || s_j >= s_rows )
           {
-            t[t_index].dist = FT_INT_MAX;
+            t[t_index].near.x = 100000;
+            t[t_index].near.y = 100000;
+            t[t_index].dist   = 100000;
             continue;
           }
 
@@ -199,7 +216,9 @@
           else
             s_index = s_j * s_width + s_i;
 
-          pixel_value = (FT_Short)s[s_index];
+          pixel_value = s[s_index];
+
+  #if 0
 
           /* to make the fractional value 1 */
           /* for completely filled pixels   */
@@ -211,7 +230,17 @@
           /* shift the value by 8.                     */
           pixel_value <<= 8;
 
-          t[t_index].dist = pixel_value;
+  #else
+          if ( pixel_value )
+            t[t_index].dist = 0;
+          else
+          {
+            t[t_index].near.x = 100000;
+            t[t_index].near.y = 100000;
+            t[t_index].dist   = 100000;
+          }
+
+  #endif
         }
       }
 
@@ -227,7 +256,222 @@
   Exit:
     return error;
   }
-  
+
+  /**************************************************************************
+   *
+   * @Function:
+   *   first_pass
+   *
+   * @Description:
+   *   [TODO]
+   *
+   * @Input:
+   *   [TODO]
+   *
+   * @Return:
+   *   [TODO]
+   */
+  static void
+  first_pass( BSDF_Worker*  worker )
+  {
+    FT_Int    i, j; /* iterators    */
+    FT_Int    w, r; /* width, rows  */
+    ED*       dm;   /* distance map */
+
+
+    dm = worker->distance_map;
+    w  = worker->width;
+    r  = worker->rows;
+
+    /* Start scanning from top to bottom and sweep each   */
+    /* row back and forth comparing the distances of the  */
+    /* neighborhood. Leave the first row as it has no top */
+    /* neighbor, it will be covered in the 2nd scan of    */
+    /* the image, that is from bottom to top.             */
+    for ( j = 1; j < r; j++ )
+    {
+      FT_Int        index;
+      FT_16D16      dist;
+      FT_16D16_Vec  dist_vec;
+      ED*           to_check;
+      ED*           current;
+
+
+      /* Forward pass of rows (left -> right), leave, the */
+      /* first column, will be covered in backward pass.  */
+      for ( i = 1; i < w; i++ )
+      {
+        index = j * w + i;
+        current = dm + index;
+
+        /* left-up */
+        to_check = current - w - 1;
+        dist_vec = to_check->near;
+        dist_vec.x -= ONE;
+        dist_vec.y -= ONE;
+        dist = FT_Vector_Length( &dist_vec );
+        if ( dist < current->dist )
+        {
+          current->dist = dist;
+          current->near = dist_vec;
+        }
+
+        /* up */
+        to_check = current - w;
+        dist_vec = to_check->near;
+        dist_vec.y -= ONE;
+        dist = FT_Vector_Length( &dist_vec );
+        if ( dist < current->dist )
+        {
+          current->dist = dist;
+          current->near = dist_vec;
+        }
+
+        /* up-right */
+        to_check = current - w + 1;
+        dist_vec = to_check->near;
+        dist_vec.x += ONE;
+        dist_vec.y -= ONE;
+        dist = FT_Vector_Length( &dist_vec );
+        if ( dist < current->dist )
+        {
+          current->dist = dist;
+          current->near = dist_vec;
+        }
+
+        /* left */
+        to_check = current - 1;
+        dist_vec = to_check->near;
+        dist_vec.x -= ONE;
+        dist = FT_Vector_Length( &dist_vec );
+        if ( dist < current->dist )
+        {
+          current->dist = dist;
+          current->near = dist_vec;
+        }
+      }
+
+      /* Backward pass of rows (right -> left), leave, the */
+      /* last column, already covered in the forward pass. */
+      for ( i = w - 2; i >= 0; i-- )
+      {
+        index = j * w + i;
+        current = dm + index;
+
+        /* right */
+        to_check = current + 1;
+        dist_vec = to_check->near;
+        dist_vec.x += ONE;
+        dist = FT_Vector_Length( &dist_vec );
+        if ( dist < current->dist )
+        {
+          current->dist = dist;
+          current->near = dist_vec;
+        }
+      }
+    }
+  }
+
+  /**************************************************************************
+   *
+   * @Function:
+   *   edt8
+   *
+   * @Description:
+   *   [TODO]
+   *
+   * @Input:
+   *   [TODO]
+   *
+   * @Return:
+   *   [TODO]
+   */
+  static FT_Error
+  edt8( BSDF_Worker*  worker )
+  {
+    FT_Error  error = FT_Err_Ok;
+
+
+    if ( !worker || !worker->distance_map )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    /* first scan of the image */
+    first_pass( worker );
+
+    /* second scan of the image */
+    /* [TODO] */
+
+  Exit:
+    return error;
+  }
+
+  /**************************************************************************
+   *
+   * @Function:
+   *   finalize_sdf
+   *
+   * @Description:
+   *   [TODO]
+   *
+   * @Input:
+   *   [TODO]
+   *
+   * @Return:
+   *   [TODO]
+   */
+  static FT_Error
+  finalize_sdf( BSDF_Worker*  worker,
+                FT_Bitmap*    target )
+  {
+    FT_Error   error = FT_Err_Ok;
+    FT_Int     w, r;
+    FT_Int     i, j;
+    FT_6D10*   t_buffer;
+
+    if ( !worker || !target )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    w = target->width;
+    r = target->rows;
+    t_buffer = (FT_6D10*)target->buffer;
+
+    if ( w != worker->width ||
+         r != worker->rows )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;      
+    }
+
+    for ( j = 0; j < r; j++ )
+    {
+      for ( i = 0; i < w; i++ )
+      {
+        FT_Int    index;
+        FT_16D16  dist;
+        FT_6D10   final_dist;
+
+
+        index = j * w + i;
+        dist = worker->distance_map[index].dist;
+        /* convert from 16.16 to 6.10 */
+        dist /= 64;
+        final_dist = (FT_6D10)(dist & 0x0000FFFF);
+
+        /* [TODO]: Assing the sign properly. */
+
+        t_buffer[index] = final_dist;
+      }
+    }
+
+  Exit:
+    return error;
+  }
 
   /**************************************************************************
    *
@@ -338,7 +582,7 @@
         "       Also, you must pass `SDF_Raster_Params' instead of the\n"
         "       default `FT_Raster_Params' while calling this function\n"
         "       and set the fields properly.\n"
-        , MIN_SPREAD, MAX_SPREAD) );
+        , MIN_SPREAD, MAX_SPREAD ));
       error = FT_THROW( Invalid_Argument );
       goto Exit;
     }
@@ -346,8 +590,8 @@
     /* setup the worker */
 
     /* allocate the distance map */
-    if ( !FT_QALLOC_MULT( worker.distance_map, target->rows,
-                          target->width * sizeof( *worker.distance_map ) ) )
+    if ( FT_QALLOC_MULT( worker.distance_map, target->rows,
+                         target->width * sizeof( *worker.distance_map ) ) )
       goto Exit;
 
     worker.width  = target->width;
@@ -355,6 +599,8 @@
     worker.params = *sdf_params;
 
     FT_CALL( bsdf_init_distance_map( source, &worker ) );
+    FT_CALL( edt8( &worker ) );
+    FT_CALL( finalize_sdf( &worker, target ) );
 
   Exit:
     return error;
diff --git a/src/sdf/ftsdfrend.c b/src/sdf/ftsdfrend.c
index bc7bcab..f2a34b1 100644
--- a/src/sdf/ftsdfrend.c
+++ b/src/sdf/ftsdfrend.c
@@ -404,10 +404,10 @@
 
   /* generate signed distance field from glyph's bitmap */
   static FT_Error
-  ft_bsdf_render( FT_Renderer      module,
-                 FT_GlyphSlot      slot,
-                 FT_Render_Mode    mode,
-                 const FT_Vector*  origin )
+  ft_bsdf_render( FT_Renderer       module,
+                  FT_GlyphSlot      slot,
+                  FT_Render_Mode    mode,
+                  const FT_Vector*  origin )
   {
     FT_Error     error   = FT_Err_Ok;
     FT_Bitmap*   bitmap  = &slot->bitmap;



reply via email to

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