Commit d27d107f157345402aefdb29d89d50446d52fded

Anuj Verma 2020-08-20T21:25:46

[sdf] Add interface functions for the 'bsdf' rasterizer. * src/sdf/ftsdf.c (bsdf_raster_new, bsdf_raster_reset, bsdf_raster_set_mode, bsdf_raster_render, bsdf_raster_done): New functions. (ft_bitmap_sdf_raster): New variable. * src/sdf/ftsdf.h: Updated.

diff --git a/ChangeLog b/ChangeLog
index dc34e2b..9e855f1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
 2020-08-20  Anuj Verma  <anujv@iitbhilai.ac.in>
 
+	[sdf] Add interface functions for the 'bsdf' rasterizer.
+
+	* src/sdf/ftsdf.c (bsdf_raster_new, bsdf_raster_reset,
+	bsdf_raster_set_mode, bsdf_raster_render, bsdf_raster_done): New
+	functions.
+
+	(ft_bitmap_sdf_raster): New variable.
+
+	* src/sdf/ftsdf.h: Updated.
+
+2020-08-20  Anuj Verma  <anujv@iitbhilai.ac.in>
+
 	[sdf] Add function to copy SDF data into output bitmap.
 
 	* src/sdf/ftbsdf.c (finalize_sdf): New function.
@@ -42,7 +54,7 @@
 
 	[sdf] Add 'sdf' module to non-gnumake build systems.
 
-	* include/freetype/config/ftmodule.h: Add both the 'sfd' and 'bsfd'
+	* include/freetype/config/ftmodule.h: Add both the 'sdf' and 'bsdf'
 	renderers to the list of modules.
 
 	* CMakeLists.txt (BASE_SRCS): Add 'sdf' single-object module.
@@ -58,7 +70,7 @@
 
 	[sdf] Add build infrastructure.
 
-	* src/sdf/module.mk, src/sfd/rules.mk: New files.
+	* src/sdf/module.mk, src/sdf/rules.mk: New files.
 
 	* src/sdf/ftsdf.h (ft_sdf_raster): New forward declaration.
 
diff --git a/src/sdf/ftbsdf.c b/src/sdf/ftbsdf.c
index 1ae68fc..5102733 100644
--- a/src/sdf/ftbsdf.c
+++ b/src/sdf/ftbsdf.c
@@ -1043,4 +1043,185 @@
     return error;
   }
 
+
+  /**************************************************************************
+   *
+   * interface functions
+   *
+   */
+
+  /* called when adding a new module through @FT_Add_Module */
+  static FT_Error
+  bsdf_raster_new( FT_Memory   memory,
+                   FT_Raster*  araster )
+  {
+    FT_Error       error  = FT_Err_Ok;
+    BSDF_TRaster*  raster = NULL;
+
+
+    *araster = 0;
+    if ( !FT_ALLOC( raster, sizeof ( BSDF_TRaster ) ) )
+    {
+      raster->memory = memory;
+      *araster       = (FT_Raster)raster;
+    }
+
+    return error;
+  }
+
+
+  /* unused */
+  static void
+  bsdf_raster_reset( FT_Raster       raster,
+                     unsigned char*  pool_base,
+                     unsigned long   pool_size )
+  {
+    FT_UNUSED( raster );
+    FT_UNUSED( pool_base );
+    FT_UNUSED( pool_size );
+  }
+
+
+  /* unused */
+  static FT_Error
+  bsdf_raster_set_mode( FT_Raster      raster,
+                        unsigned long  mode,
+                        void*          args )
+  {
+    FT_UNUSED( raster );
+    FT_UNUSED( mode );
+    FT_UNUSED( args );
+
+    return FT_Err_Ok;
+  }
+
+
+  /* called while rendering through @FT_Render_Glyph */
+  static FT_Error
+  bsdf_raster_render( FT_Raster                raster,
+                      const FT_Raster_Params*  params )
+  {
+    FT_Error   error  = FT_Err_Ok;
+    FT_Memory  memory = NULL;
+
+    const FT_Bitmap*  source      = NULL;
+    const FT_Bitmap*  target      = NULL;
+
+    BSDF_TRaster*  bsdf_raster = (BSDF_TRaster*)raster;
+    BSDF_Worker    worker;
+
+    const SDF_Raster_Params*  sdf_params = (const SDF_Raster_Params*)params;
+
+
+    worker.distance_map = NULL;
+
+    /* check for valid parameters */
+    if ( !raster || !params )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    /* check whether the flag is set */
+    if ( sdf_params->root.flags != FT_RASTER_FLAG_SDF )
+    {
+      error = FT_THROW( Raster_Corrupted );
+      goto Exit;
+    }
+
+    source = sdf_params->root.source;
+    target = sdf_params->root.target;
+
+    /* check source and target bitmap */
+    if ( !source || !target )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    memory = bsdf_raster->memory;
+    if ( !memory )
+    {
+      FT_TRACE0(( "bsdf_raster_render: Raster not set up properly,\n" ));
+      FT_TRACE0(( "                    unable to find memory handle.\n" ));
+
+      error = FT_THROW( Invalid_Handle );
+      goto Exit;
+    }
+
+    /* check whether spread is set properly */
+    if ( sdf_params->spread > MAX_SPREAD ||
+         sdf_params->spread < MIN_SPREAD )
+    {
+      FT_TRACE0(( "bsdf_raster_render:"
+                  " The `spread' field of `SDF_Raster_Params'\n" ));
+      FT_TRACE0(( "                   "
+                  " is invalid; the value of this field must be\n" ));
+      FT_TRACE0(( "                   "
+                  " within [%d, %d].\n",
+                  MIN_SPREAD, MAX_SPREAD ));
+      FT_TRACE0(( "                   "
+                  " Also, you must pass `SDF_Raster_Params'\n" ));
+      FT_TRACE0(( "                   "
+                  " instead of the default `FT_Raster_Params'\n" ));
+      FT_TRACE0(( "                   "
+                  " while calling this function and set the fields\n" ));
+      FT_TRACE0(( "                   "
+                  " accordingly.\n" ));
+
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    /* set up the worker */
+
+    /* allocate the distance map */
+    if ( FT_QALLOC_MULT( worker.distance_map, target->rows,
+                         target->width * sizeof ( *worker.distance_map ) ) )
+      goto Exit;
+
+    worker.width  = target->width;
+    worker.rows   = target->rows;
+    worker.params = *sdf_params;
+
+    FT_CALL( bsdf_init_distance_map( source, &worker ) );
+    FT_CALL( bsdf_approximate_edge( &worker ) );
+    FT_CALL( edt8( &worker ) );
+    FT_CALL( finalize_sdf( &worker, target ) );
+
+    FT_TRACE0(( "bsdf_raster_render: Total memory used = %ld\n",
+                worker.width * worker.rows *
+                  sizeof ( *worker.distance_map ) ));
+
+  Exit:
+    if ( worker.distance_map )
+      FT_FREE( worker.distance_map );
+
+    return error;
+  }
+
+
+  /* called while deleting `FT_Library` only if the module is added */
+  static void
+  bsdf_raster_done( FT_Raster  raster )
+  {
+    FT_Memory  memory = (FT_Memory)((BSDF_TRaster*)raster)->memory;
+
+
+    FT_FREE( raster );
+  }
+
+
+  FT_DEFINE_RASTER_FUNCS(
+    ft_bitmap_sdf_raster,
+
+    FT_GLYPH_FORMAT_BITMAP,
+
+    (FT_Raster_New_Func)     bsdf_raster_new,       /* raster_new      */
+    (FT_Raster_Reset_Func)   bsdf_raster_reset,     /* raster_reset    */
+    (FT_Raster_Set_Mode_Func)bsdf_raster_set_mode,  /* raster_set_mode */
+    (FT_Raster_Render_Func)  bsdf_raster_render,    /* raster_render   */
+    (FT_Raster_Done_Func)    bsdf_raster_done       /* raster_done     */
+  )
+
 /* END */
diff --git a/src/sdf/ftsdf.h b/src/sdf/ftsdf.h
index 0275f51..1c68aef 100644
--- a/src/sdf/ftsdf.h
+++ b/src/sdf/ftsdf.h
@@ -67,6 +67,9 @@ FT_BEGIN_HEADER
   /* rasterizer to convert outline to SDF */
   FT_EXPORT_VAR( const FT_Raster_Funcs )  ft_sdf_raster;
 
+  /* rasterizer to convert bitmap to SDF */
+  FT_EXPORT_VAR( const FT_Raster_Funcs )  ft_bitmap_sdf_raster;
+
 FT_END_HEADER
 
 #endif /* FTSDF_H_ */