freetype-commit
[Top][All Lists]
Advanced

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

[freetype2] GSoC-2020-anuj 461d693 1/6: [bsdf] Added function to copy so


From: Anuj Verma
Subject: [freetype2] GSoC-2020-anuj 461d693 1/6: [bsdf] Added function to copy source bitmap to the distance map.
Date: Fri, 21 Aug 2020 00:58:18 -0400 (EDT)

branch: GSoC-2020-anuj
commit 461d693c29400e322d206474d247b1c2f2692301
Author: Anuj Verma <anujv@iitbhilai.ac.in>
Commit: Anuj Verma <anujv@iitbhilai.ac.in>

    [bsdf] Added function to copy source bitmap to the distance map.
    
    * src/sdf/ftbsdf.c (bsdf_init_distance_map): The function copies the source 
bitmap to
      the intermediate distance map which is present within the `worker'.
---
 src/sdf/ftbsdf.c | 190 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 190 insertions(+)

diff --git a/src/sdf/ftbsdf.c b/src/sdf/ftbsdf.c
index ef932f6..0cc5b94 100644
--- a/src/sdf/ftbsdf.c
+++ b/src/sdf/ftbsdf.c
@@ -480,4 +480,194 @@
     return error;
   }
 
+  /**************************************************************************
+   *
+   * @Function:
+   *   bsdf_init_distance_map
+   *
+   * @Description:
+   *   This function initialize the distance map according to
+   *   algorithm `8-point sequential Euclidean distance mapping' (8SED).
+   *   Basically it copy the `source' bitmap alpha values to the
+   *   `distance_map->alpha' parameter of the `worker'.
+   *
+   * @Input:
+   *   source ::
+   *     Source bitmap to copy the data from.
+   *
+   * @Return:
+   *   worker ::
+   *     Target distance map to copy the data to.
+   *
+   *   FT_Error ::
+   *     FreeType error, 0 means success.
+   *
+   */
+  static FT_Error
+  bsdf_init_distance_map( const FT_Bitmap*  source,
+                          BSDF_Worker*      worker )
+  {
+    FT_Error  error         = FT_Err_Ok;
+
+    FT_Int    x_diff, y_diff;
+    FT_Int    t_i, t_j, s_i, s_j;
+    FT_Byte*  s;
+    ED*       t;
+
+    /* again check the parameters (probably unnecessary) */
+    if ( !source || !worker )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    /* Because of the way we convert bitmap to SDF     */
+    /* i.e. aligning the source to the center of the   */
+    /* target, the target's width/rows must be checked */
+    /* before copying.                                 */
+    if ( worker->width < source->width ||
+         worker->rows  < source->rows )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    /* check pixel mode */
+    if ( source->pixel_mode == FT_PIXEL_MODE_NONE )
+    {
+      FT_ERROR(( "[bsdf] bsdf_copy_source_to_target: "
+                 "Invalid pixel mode of source bitmap" ));
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+  #ifdef FT_DEBUG_LEVEL_TRACE
+    if ( source->pixel_mode == FT_PIXEL_MODE_MONO )
+    {
+      FT_TRACE0(( "[bsdf] bsdf_copy_source_to_target:\n"
+                  "The `bsdf' renderer can convert monochrome bitmap\n"
+                  "to SDF, but the results are not perfect because there\n"
+                  "is no way to approximate actual outline from monochrome\n"
+                  "bitmap. Consider using anti-aliased bitmap instead.\n" ));
+    }
+  #endif
+
+    /* Calculate the difference in width and rows */
+    /* of the target and source.                  */
+    x_diff = worker->width - source->width;
+    y_diff = worker->rows - source->rows;
+
+    x_diff /= 2;
+    y_diff /= 2;
+
+    t = (ED*)worker->distance_map;
+    s = source->buffer;
+
+    /* For now we only support pixel mode `FT_PIXEL_MODE_MONO'  */
+    /* and `FT_PIXEL_MODE_GRAY'. More will be added later.      */
+    /* [NOTE]: We can also use `FT_Bitmap_Convert' to convert   */
+    /*         bitmap to 8bpp. To avoid extra allocation and    */
+    /*         since the target bitmap can be 16bpp we manually */
+    /*         convert the source bitmap to desired bpp.        */
+    switch ( source->pixel_mode ) {
+    case FT_PIXEL_MODE_MONO:
+    {
+      FT_Int  t_width = worker->width;
+      FT_Int  t_rows  = worker->rows;
+      FT_Int  s_width = source->width;
+      FT_Int  s_rows  = source->rows;
+
+
+      for ( t_j = 0; t_j < t_rows; t_j++ )
+      {
+        for ( t_i = 0; t_i < t_width; t_i++ )
+        {
+          FT_Int   t_index = t_j * t_width + t_i;
+          FT_Int   s_index;
+          FT_Int   div, mod;
+          FT_Byte  pixel, byte;
+
+
+          t[t_index] = zero_ed;
+
+          s_i = t_i - x_diff;
+          s_j = t_j - y_diff;
+
+          /* Assign 0 to padding similar to */
+          /* the source bitmap.             */
+          if ( s_i < 0 || s_i >= s_width ||
+               s_j < 0 || s_j >= s_rows )
+            continue;
+
+          if ( worker->params.flip_y )
+            s_index = ( s_rows - s_j - 1 ) * source->pitch;
+          else
+            s_index = s_j * source->pitch;
+
+          div = s_index + s_i / 8;
+          mod = 7 - s_i % 8;
+
+          pixel = s[div];
+          byte = 1 << mod;
+
+          t[t_index].alpha = pixel & byte ? 255 : 0;
+
+          pixel = 0;
+        }
+      }
+      break;
+    }
+    case FT_PIXEL_MODE_GRAY:
+    {
+      FT_Int  t_width = worker->width;
+      FT_Int  t_rows  = worker->rows;
+      FT_Int  s_width = source->width;
+      FT_Int  s_rows  = source->rows;
+
+
+      /* loop through all the pixels and */
+      /* assign pixel values from source */
+      for ( t_j = 0; t_j < t_rows; t_j++ )
+      {
+        for ( t_i = 0; t_i < t_width; t_i++ )
+        {
+          FT_Int    t_index = t_j * t_width + t_i;
+          FT_Int    s_index;
+
+
+          t[t_index] = zero_ed;
+
+          s_i = t_i - x_diff;
+          s_j = t_j - y_diff;
+
+          /* Assign 0 to padding similar to */
+          /* the source bitmap.             */
+          if ( s_i < 0 || s_i >= s_width ||
+               s_j < 0 || s_j >= s_rows )
+            continue;
+
+          if ( worker->params.flip_y )
+            s_index = ( s_rows - s_j - 1 ) * s_width + s_i;
+          else
+            s_index = s_j * s_width + s_i;
+
+          /* simply copy the alpha values */
+          t[t_index].alpha = s[s_index];
+        }
+      }
+
+      break;
+    }
+    default:
+      FT_ERROR(( "[bsdf] bsdf_copy_source_to_target: "
+                 "unsopported pixel mode of source bitmap\n" ));
+      error = FT_THROW( Unimplemented_Feature );
+      break;
+    }
+
+  Exit:
+    return error;
+  }
+
+
 /* END */



reply via email to

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