freetype-commit
[Top][All Lists]
Advanced

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

[freetype2] anuj-distance-field 29c92db 05/93: [sdf] Implemented a few f


From: Anuj Verma
Subject: [freetype2] anuj-distance-field 29c92db 05/93: [sdf] Implemented a few functions required by a renderer module.
Date: Sun, 2 Aug 2020 07:04:09 -0400 (EDT)

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

    [sdf] Implemented a few functions required by a renderer module.
---
 [GSoC]ChangeLog     |  19 ++++++-
 src/sdf/ftsdf.c     |  36 +++++++++++--
 src/sdf/ftsdfrend.c | 148 ++++++++++++++++++++++++++++++++++++++++++++--------
 3 files changed, 175 insertions(+), 28 deletions(-)

diff --git a/[GSoC]ChangeLog b/[GSoC]ChangeLog
index f3c597c..cc028a8 100644
--- a/[GSoC]ChangeLog
+++ b/[GSoC]ChangeLog
@@ -1,3 +1,20 @@
+2020-06-20  Anuj Verma  <anujv@iitbhilai.ac.in>
+
+       [sdf] Implemented a few functions required by a renderer
+       module.
+
+       * src/sdf/ftsdf.c (sdf_TRaster_): Added new structure to hold
+         the memory allocator `FT_Memory'.
+
+       * src/sdf/ftsdf.c (ft_sdf_raster): Implemented a few essential
+         functions required by `FT_Raster'.
+
+       * src/sdf/ftsdfrend.c (ft_sdf_renderer_class): Implemented a few
+         essential functions required by `FT_Renderer'.
+
+       * src/sdf/ftsdfrend.c (ft_sdf_render): Added functionality to
+         compute shift and padding before rendering the outline.
+
 2020-06-19  Anuj Verma  <anujv@iitbhilai.ac.in>
 
        * include/freetype/ftimage.h (FT_Render_Mode_): Added new
@@ -27,7 +44,7 @@
        * src/sdf/rules.mk, src/sdf/module.mk: Added files required to
          build the `sdf' module using the default build system.
 
-       * CMakeLists.txt (`BASE_SRCS'): Add `src/sdf/sdf.c' to the variable.
+       * CMakeLists.txt (BASE_SRCS): Add `src/sdf/sdf.c' to the variable.
 
        * include/freetype/config/ftmodule.h: Added `sdf' module 
          declaration so that the module can be compiled when not compiling
diff --git a/src/sdf/ftsdf.c b/src/sdf/ftsdf.c
index b4b5c48..30eb184 100644
--- a/src/sdf/ftsdf.c
+++ b/src/sdf/ftsdf.c
@@ -5,15 +5,37 @@
 
 #include "ftsdferrs.h"
 
+  /**************************************************************************
+   *
+   * structures and enums
+   *
+   */
+
+  typedef struct  sdf_TRaster_
+  {
+    FT_Memory  memory; /* used internally to allocate memory */
+  } sdf_TRaster;
+
+  /**************************************************************************
+   *
+   * interface functions
+   *
+   */
+
   static int
   sdf_raster_new( FT_Memory   memory,
                   FT_Raster*  araster)
   {
-    FT_Error  error = FT_THROW( Unimplemented_Feature );
+    FT_Error      error  = FT_Err_Ok;
+    sdf_TRaster*  raster = NULL;
 
 
-    FT_UNUSED( memory );
-    FT_UNUSED( araster );
+    *araster = 0;
+    if ( !FT_ALLOC( raster, sizeof( sdf_TRaster ) ) )
+    {
+      raster->memory = memory;
+      *araster = (FT_Raster)raster;
+    }
 
     return error;
   }
@@ -23,6 +45,7 @@
                     unsigned char*  pool_base,
                     unsigned long   pool_size )
   {
+    /* no use of this function */
     FT_UNUSED( raster );
     FT_UNUSED( pool_base );
     FT_UNUSED( pool_size );
@@ -33,6 +56,8 @@
                        unsigned long  mode,
                        void*          args )
   {
+    /* Currently there is no use for this function but later */
+    /* it will be used to modify the `spread' parameter.     */
     FT_UNUSED( raster );
     FT_UNUSED( mode );
     FT_UNUSED( args );
@@ -55,7 +80,10 @@
   static void
   sdf_raster_done( FT_Raster  raster )
   {
-    FT_UNUSED( raster );
+    FT_Memory  memory = (FT_Memory)((sdf_TRaster*)raster)->memory;
+
+
+    FT_FREE( raster );
   }
 
   FT_DEFINE_RASTER_FUNCS(
diff --git a/src/sdf/ftsdfrend.c b/src/sdf/ftsdfrend.c
index 6264169..62268df 100644
--- a/src/sdf/ftsdfrend.c
+++ b/src/sdf/ftsdfrend.c
@@ -1,69 +1,171 @@
 
 #include <freetype/internal/ftdebug.h>
 #include <freetype/internal/ftobjs.h>
+#include <freetype/ftoutln.h>
 #include "ftsdfrend.h"
 #include "ftsdf.h"
 
 #include "ftsdferrs.h"
 
 
+  /* generate signed distance field from a glyph's slot image */
   static FT_Error
   ft_sdf_render( FT_Renderer       render,
                  FT_GlyphSlot      slot,
                  FT_Render_Mode    mode,
                  const FT_Vector*  origin )
   {
-    FT_Error  error = FT_THROW( Unimplemented_Feature );
-
-
-    FT_UNUSED( render );
-    FT_UNUSED( slot );
-    FT_UNUSED( mode );
-    FT_UNUSED( origin );
+    FT_Error     error   = FT_Err_Ok;
+    FT_Outline*  outline = &slot->outline;
+    FT_Bitmap*   bitmap  = &slot->bitmap;
+    FT_Memory    memory  = render->root.memory;
+    FT_Pos       x_shift = 0;
+    FT_Pos       y_shift = 0;
+    
+    /* use hardcoded padding for now */
+    FT_UInt      x_pad   = 10;
+    FT_UInt      y_pad   = 10;
+
+    FT_Raster_Params  params;
+
+    /* check if slot format is correct before rendering */
+    if ( slot->format != render->glyph_format )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    /* check if render mode is correct */
+    if ( mode != FT_RENDER_MODE_SDF )
+    {
+      FT_ERROR(( "ft_sdf_render: sdf module only"
+                 "render when using `FT_RENDER_MODE_SDF'" ));
+      error = FT_THROW( Cannot_Render_Glyph );
+      goto Exit;
+    }
+
+    /* deallocate the previously allocated bitmap */
+    if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
+    {
+      FT_FREE( bitmap->buffer );
+      slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
+    }
+
+    /* preset the bitmap using the glyph's outline;        */
+    /* the sdf bitmap is similar to a antialiased bitmap   */
+    /* with a slighty bigger size and different pixel mode */
+    if ( ft_glyphslot_preset_bitmap( slot, FT_RENDER_MODE_NORMAL, origin ) )
+    {
+      error = FT_THROW( Raster_Overflow );
+      goto Exit;
+    }
+
+    if ( !bitmap->rows || !bitmap->pitch )
+      goto Exit;
+
+    /* apply the padding */
+    bitmap->rows  += y_pad;
+    bitmap->width += x_pad;
+
+    /* ignore the pitch, pixel mode and set custom */
+    bitmap->pixel_mode = FT_PIXEL_MODE_GRAY16;
+    bitmap->pitch = bitmap->width * 2;
+    bitmap->num_grays = 65536;
+
+    /* allocate new buffer */
+    if ( FT_ALLOC_MULT( bitmap->buffer, bitmap->rows, bitmap->pitch ) )
+      goto Exit;
+
+    slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
+
+    x_shift  = 64 * -( slot->bitmap_left + x_pad );
+    y_shift  = 64 * -( slot->bitmap_top + y_pad );
+    y_shift += 64 * (FT_Int)bitmap->rows;
+
+    if ( origin )
+    {
+      x_shift += origin->x;
+      y_shift += origin->y;
+    }
+
+    /* translate outline to render it into the bitmap */
+    if ( x_shift || y_shift )
+      FT_Outline_Translate( outline, x_shift, y_shift );
+
+    /* set up parameters */
+    params.target = bitmap;
+    params.source = outline;
+    params.flags  = 0;
+
+    /* render the outline */
+    error = render->raster_render( render->raster, &params );
+
+  Exit:
+    if ( !error )
+    {
+      /* the glyph is successfully rendered to a bitmap */
+      slot->format = FT_GLYPH_FORMAT_BITMAP;
+    }
+    else if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
+    {
+      FT_FREE( bitmap->buffer );
+      slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
+    }
+
+    if ( x_shift || y_shift )
+      FT_Outline_Translate( outline, -x_shift, -y_shift );
 
     return error;
   }
 
+  /* transform the glyph using matrix and/or delta */
   static FT_Error
   ft_sdf_transform( FT_Renderer       render,
                     FT_GlyphSlot      slot,
                     const FT_Matrix*  matrix,
                     const FT_Vector*  delta )
   {
-    FT_Error  error = FT_THROW( Unimplemented_Feature );
+    FT_Error  error = FT_Err_Ok;
+
 
+    if ( slot->format != render->glyph_format )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
 
-    FT_UNUSED( render );
-    FT_UNUSED( slot );
-    FT_UNUSED( matrix );
-    FT_UNUSED( delta );
+    if ( matrix )
+      FT_Outline_Transform( &slot->outline, matrix );
 
+    if ( delta )
+      FT_Outline_Translate( &slot->outline, delta->x, delta->y );
+
+  Exit:
     return error;
   }
 
+  /* returns the control box of glyph's outline */
   static void
   ft_sdf_get_cbox( FT_Renderer   render,
                    FT_GlyphSlot  slot,
                    FT_BBox*      cbox )
   {
-    FT_UNUSED( render );
-    FT_UNUSED( slot );
-    FT_UNUSED( cbox );
+    FT_ZERO( cbox );
+
+    if ( slot->format == render->glyph_format )
+      FT_Outline_Get_CBox( &slot->outline, cbox );
   }
 
+  /* set render specific modes or attributes */
   static FT_Error
   ft_sdf_set_mode( FT_Renderer  render,
                    FT_ULong     mode_tag,
                    FT_Pointer   data )
   {
-    FT_Error  error = FT_THROW( Unimplemented_Feature );
-
-
-    FT_UNUSED( render );
-    FT_UNUSED( mode_tag );
-    FT_UNUSED( data );
-
-    return error;
+    /* pass it to the rasterizer */
+    return render->clazz->raster_class->raster_set_mode( render->raster,
+                                                         mode_tag,
+                                                         data );
   }
 
   FT_DEFINE_RENDERER(



reply via email to

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