freetype-commit
[Top][All Lists]
Advanced

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

[freetype2] anuj-distance-field 1c6459a 08/95: [sdf] Decompose outline a


From: Anuj Verma
Subject: [freetype2] anuj-distance-field 1c6459a 08/95: [sdf] Decompose outline and store it in a `SDF_Shape'.
Date: Sun, 2 Aug 2020 01:10:25 -0400 (EDT)

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

    [sdf] Decompose outline and store it in a `SDF_Shape'.
---
 [GSoC]ChangeLog |  10 +++
 src/sdf/ftsdf.c | 254 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 251 insertions(+), 13 deletions(-)

diff --git a/[GSoC]ChangeLog b/[GSoC]ChangeLog
index df74a85..32edb69 100644
--- a/[GSoC]ChangeLog
+++ b/[GSoC]ChangeLog
@@ -1,5 +1,15 @@
 2020-06-25  Anuj Verma  <anujv@iitbhilai.ac.in>
 
+       [sdf] Decompose outline and store it in a temporary
+       `SDF_Shape' object for easy iteration and pre-computing
+       some variables.
+
+       * src/sdf/ftsdf.c (sdf_outline_decompose): Added function
+         to decompost outline and store it in a `SDF_Shape' object.
+         This allows us to pre-compute some variable.
+
+2020-06-25  Anuj Verma  <anujv@iitbhilai.ac.in>
+
        [sdf] Added essential enums and structs required.
 
        * src/freetype/internal/fttrace.h: Remove tabs.
diff --git a/src/sdf/ftsdf.c b/src/sdf/ftsdf.c
index 8f4d550..3b6e57f 100644
--- a/src/sdf/ftsdf.c
+++ b/src/sdf/ftsdf.c
@@ -1,6 +1,7 @@
 
 #include <freetype/internal/ftobjs.h>
 #include <freetype/internal/ftdebug.h>
+#include <freetype/ftlist.h>
 #include "ftsdf.h"
 
 #include "ftsdferrs.h"
@@ -53,7 +54,7 @@
   typedef struct  SDF_Contour_
   {
     FT_26D6_Vec  last_pos;  /* end position of the last edge    */
-    FT_List      edges      /* list of all edges in the contour */
+    FT_List      edges;     /* list of all edges in the contour */
 
   } SDF_Contour;
 
@@ -86,6 +87,12 @@
   static
   const SDF_Shape    null_shape   = { NULL, NULL };
 
+  static
+  const FT_ListRec   empty_list   = { NULL, NULL };
+
+
+  /* Creates a new `SDF_Edge' on the heap and assigns the `edge' */
+  /* pointer to the newly allocated memory.                      */
   static FT_Error
   sdf_edge_new( FT_Memory   memory,
                 SDF_Edge**  edge )
@@ -101,9 +108,7 @@
     }
 
     FT_QNEW( ptr );
-    if ( error != FT_Err_Ok )
-      *edge = NULL;
-    else
+    if ( error == FT_Err_Ok )
     {
       *ptr = null_edge;
       *edge = ptr;
@@ -113,6 +118,9 @@
     return error;
   }
 
+  /* Creates a new `SDF_Contour' on the heap and assigns the `contour'  */
+  /* pointer to the newly allocated memory. Note that the function also */
+  /* allocate the `contour.edges' list variable and sets to empty list. */
   static FT_Error
   sdf_contour_new( FT_Memory      memory,
                    SDF_Contour**  contour )
@@ -128,19 +136,24 @@
     }
 
     FT_QNEW( ptr );
-    if ( error != FT_Err_Ok )
-      *contour = NULL;
-    else
+    if ( error == FT_Err_Ok )
     {
       *ptr = null_contour;
       FT_QNEW( ptr->edges );
-      *contour = ptr;
+      if ( error == FT_Err_Ok )
+      {
+        *ptr->edges = empty_list;
+        *contour = ptr;
+      }
     }
 
   Exit:
     return error;
   }
 
+  /* Creates a new `SDF_Shape' on the heap and assigns the `shape'       */
+  /* pointer to the newly allocated memory. Note that the function also  */
+  /* allocate the `shape.contours' list variable and sets to empty list. */
   static void
   sdf_shape_new( FT_Memory    memory,
                  SDF_Shape**  shape )
@@ -156,19 +169,235 @@
     }
 
     FT_QNEW( ptr );
-    if ( error != FT_Err_Ok )
-      *shape = NULL;
-    else
+    if ( error == FT_Err_Ok )
     {
       *ptr = null_shape;
       FT_QNEW( ptr->contours );
-      *shape = ptr;
+      if ( error == FT_Err_Ok )
+      {
+        *ptr->contours = empty_list;
+        ptr->memory = memory;
+        *shape = ptr;
+      }
     }
 
   Exit:
     return error;
   }
 
+  
+
+  /**************************************************************************
+   *
+   * shape decomposition functions
+   *
+   */
+
+  static FT_Error
+  sdf_move_to( const FT_26D6_Vec* to,
+               void*              user )
+  {
+    /* This function is called when walking along a new contour */
+    /* so add a new contour to the shape's list.                */
+    SDF_Shape*    shape    = ( SDF_Shape* )user;
+    SDF_Contour*  contour  = NULL;
+    FT_ListNode   node     = NULL;
+
+    FT_Error      error    = FT_Err_Ok;
+    FT_Memory     memory   = shape->memory;
+
+
+    if ( !to || !user )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    error = sdf_contour_new( memory, &contour );
+    if ( error != FT_Err_Ok )
+      goto Exit;
+
+    FT_QNEW( node );
+    if ( error != FT_Err_Ok )
+      goto Exit;
+
+    contour->last_pos = *to;
+
+    node->data = contour;
+    FT_List_Add( shape->contours, node );
+
+  Exit:
+    return error;
+  }
+
+  static FT_Error
+  sdf_line_to( const FT_26D6_Vec*  to,
+               void*               user )
+  {
+    SDF_Shape*    shape    = ( SDF_Shape* )user;
+    SDF_Edge*     edge     = NULL;
+    SDF_Contour*  contour  = NULL;
+    FT_ListNode   node     = NULL;
+
+    FT_Error      error    = FT_Err_Ok;
+    FT_Memory     memory   = shape->memory;
+
+
+    if ( !to || !user )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    contour = ( SDF_Contour* )shape->contours->tail->data;
+
+    if ( contour->last_pos.x == to->x && 
+         contour->last_pos.y == to->y )
+      goto Exit;
+
+    error = sdf_edge_new( memory, &edge );
+    if ( error != FT_Err_Ok )
+      goto Exit;
+
+    FT_QNEW( node );
+    if ( error != FT_Err_Ok )
+      goto Exit;
+
+    edge->edge_type = SDF_EDGE_LINE;
+    edge->start_pos = contour->last_pos;
+    edge->end_pos   = *to;
+
+    contour->last_pos = *to;
+
+    node->data = edge;
+    FT_List_Add( contour->edges, node );
+
+  Exit:
+    return error;
+  }
+
+  static FT_Error
+  sdf_conic_to( const FT_26D6_Vec*  control_1,
+                const FT_26D6_Vec*  to,
+                void*               user )
+  {
+    SDF_Shape*    shape    = ( SDF_Shape* )user;
+    SDF_Edge*     edge     = NULL;
+    SDF_Contour*  contour  = NULL;
+    FT_ListNode   node     = NULL;
+
+    FT_Error      error    = FT_Err_Ok;
+    FT_Memory     memory   = shape->memory;
+
+
+    if ( !control_1 || !to || !user )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    contour = ( SDF_Contour* )shape->contours->tail->data;
+
+    error = sdf_edge_new( memory, &edge );
+    if ( error != FT_Err_Ok )
+      goto Exit;
+
+    FT_QNEW( node );
+    if ( error != FT_Err_Ok )
+      goto Exit;
+
+    edge->edge_type = SDF_EDGE_CONIC;
+    edge->start_pos = contour->last_pos;
+    edge->control_a = *control_1;
+    edge->end_pos   = *to;
+
+    contour->last_pos = *to;
+
+    node->data = edge;
+    FT_List_Add( contour->edges, node );
+
+  Exit:
+    return error;
+  }
+
+  static FT_Error
+  sdf_cubic_to( const FT_26D6_Vec*  control_1,
+                const FT_26D6_Vec*  control_2,
+                const FT_26D6_Vec*  to,
+                void*               user )
+  {
+    SDF_Shape*    shape    = ( SDF_Shape* )user;
+    SDF_Edge*     edge     = NULL;
+    SDF_Contour*  contour  = NULL;
+    FT_ListNode   node     = NULL;
+
+    FT_Error      error    = FT_Err_Ok;
+    FT_Memory     memory   = shape->memory;
+
+
+    if ( !control_2 || !control_1 || !to || !user )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    contour = ( SDF_Contour* )shape->contours->tail->data;
+
+    error = sdf_edge_new( memory, &edge );
+    if ( error != FT_Err_Ok )
+      goto Exit;
+
+    FT_QNEW( node );
+    if ( error != FT_Err_Ok )
+      goto Exit;
+
+    edge->edge_type = SDF_EDGE_CUBIC;
+    edge->start_pos = contour->last_pos;
+    edge->control_a = *control_1;
+    edge->control_b = *control_2;
+    edge->end_pos   = *to;
+
+    contour->last_pos = *to;
+
+    node->data = edge;
+    FT_List_Add( contour->edges, node );
+
+  Exit:
+    return error;
+  }
+
+  FT_DEFINE_OUTLINE_FUNCS(
+      sdf_decompose_funcs,
+
+      (FT_Outline_MoveTo_Func)  sdf_move_to,   /* move_to  */
+      (FT_Outline_LineTo_Func)  sdf_line_to,   /* line_to  */
+      (FT_Outline_ConicTo_Func) sdf_conic_to,  /* conic_to */
+      (FT_Outline_CubicTo_Func) sdf_cubic_to,  /* cubic_to */
+
+      0,                                       /* shift    */
+      0                                        /* delta    */
+  )
+
+  /* function decomposes the outline and puts it into the `shape' object */
+  static FT_Error
+  sdf_outline_decompose( FT_Outline*  outline,
+                         SDF_Shape*   shape )
+  {
+    FT_Error  error = FT_Err_Ok;
+
+
+    if ( !outline || !shape )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    error = FT_Outline_Decompose( outline, &sdf_decompose_funcs, (void*)shape 
);
+
+  Exit:
+    return error;
+  }
+
   /**************************************************************************
    *
    * interface functions
@@ -224,7 +453,6 @@
     FT_UNUSED( raster );
     FT_UNUSED( params );
 
-
     return FT_THROW( Unimplemented_Feature );
   }
 



reply via email to

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