freetype-commit
[Top][All Lists]
Advanced

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

[freetype2] anuj-distance-field 995ad4e 1/2: [sdf] Added functions to su


From: Anuj Verma
Subject: [freetype2] anuj-distance-field 995ad4e 1/2: [sdf] Added functions to subdivide a cubic curve.
Date: Thu, 9 Jul 2020 02:59:12 -0400 (EDT)

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

    [sdf] Added functions to subdivide a cubic curve.
    
    * src/sdf/ftsdf.c (split_cubic, split_sdf_cubic):
      These functions can be used to subdivide a
      cubic bezier curve into line segments which can
      then be used to generate the SDF.
    
    * src/sdf/ftsdf.c (split_sdf_shape): Added function
      to split a cubic into a line segments.
    
    * src/sdf/ftsdf.c (sdf_shape_done): No need to pass
      `FT_Memory' as a parameter, it can be accessed
      from the `shape' struct.
---
 [GSoC]ChangeLog |  16 +++++++
 src/sdf/ftsdf.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 147 insertions(+), 5 deletions(-)

diff --git a/[GSoC]ChangeLog b/[GSoC]ChangeLog
index 82c20ac..6daa543 100644
--- a/[GSoC]ChangeLog
+++ b/[GSoC]ChangeLog
@@ -1,5 +1,21 @@
 2020-07-09  Anuj Verma  <anujv@iitbhilai.ac.in>
 
+       [sdf] Added functions to subdivide a cubic curve.
+
+       * src/sdf/ftsdf.c (split_cubic, split_sdf_cubic):
+         These functions can be used to subdivide a
+         cubic bezier curve into line segments which can
+         then be used to generate the SDF.
+
+       * src/sdf/ftsdf.c (split_sdf_shape): Added function
+         to split a cubic into a line segments.
+
+       * src/sdf/ftsdf.c (sdf_shape_done): No need to pass
+         `FT_Memory' as a parameter, it can be accessed
+         from the `shape' struct.
+
+2020-07-09  Anuj Verma  <anujv@iitbhilai.ac.in>
+
        * src/sdf/ftsdf.c (split_sdf_shape): Typo.
 
 2020-07-08  Anuj Verma  <anujv@iitbhilai.ac.in>
diff --git a/src/sdf/ftsdf.c b/src/sdf/ftsdf.c
index 2890a02..18e1699 100644
--- a/src/sdf/ftsdf.c
+++ b/src/sdf/ftsdf.c
@@ -332,10 +332,17 @@
   /* Frees the allocated `shape' variable and also frees */
   /* the list of contours.                               */
   static void
-  sdf_shape_done( FT_Memory    memory,
-                  SDF_Shape**  shape )
+  sdf_shape_done( SDF_Shape**  shape )
   {
-    if ( !memory || !shape || !*shape )
+    FT_Memory  memory;
+
+
+    if ( !shape || !*shape )
+      return;
+
+    memory = (*shape)->memory;
+
+    if ( !memory )
       return;
 
     /* release the list of contours */
@@ -671,6 +678,40 @@
     base[1].y = a / 2;
   }
 
+  /* The function is exactly same as the one    */
+  /* in the smooth renderer. It splits a cubic  */
+  /* into two cubic exactly half way at t = 0.5 */
+  static void
+  split_cubic( FT_26D6_Vec*  base )
+  {
+    FT_26D6  a, b, c;
+
+
+    base[6].x = base[3].x;
+    a = base[0].x + base[1].x;
+    b = base[1].x + base[2].x;
+    c = base[2].x + base[3].x;
+    base[5].x = c / 2;
+    c += b;
+    base[4].x = c / 4;
+    base[1].x = a / 2;
+    a += b;
+    base[2].x = a / 4;
+    base[3].x = ( a + c ) / 8;
+
+    base[6].y = base[3].y;
+    a = base[0].y + base[1].y;
+    b = base[1].y + base[2].y;
+    c = base[2].y + base[3].y;
+    base[5].y = c / 2;
+    c += b;
+    base[4].y = c / 4;
+    base[1].y = a / 2;
+    a += b;
+    base[2].y = a / 4;
+    base[3].y = ( a + c ) / 8;
+  }
+
   /* the function splits a conic bezier curve     */
   /* into a number of lines and adds them to      */
   /* a list `out'. The function uses recursion    */
@@ -746,6 +787,82 @@
     return error;
   }
 
+  /* the function splits a cubic bezier curve     */
+  /* into a number of lines and adds them to      */
+  /* a list `out'. The function uses recursion    */
+  /* that is why a `max_splits' param is required */
+  /* for stopping.                                */
+  static FT_Error
+  split_sdf_cubic( FT_Memory     memory,
+                   FT_26D6_Vec*  control_points,
+                   FT_Int        max_splits,
+                   FT_List       out )
+  {
+    FT_Error     error = FT_Err_Ok;
+    FT_26D6_Vec  cpos[7];
+    SDF_Edge*    left,*  right;
+    FT_ListNode  n1, n2;
+
+
+    if ( !memory || !out  )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    /* split the conic */
+    cpos[0] = control_points[0];
+    cpos[1] = control_points[1];
+    cpos[2] = control_points[2];
+    cpos[3] = control_points[3];
+
+    split_cubic( cpos );
+
+    /* If max number of splits is done */
+    /* then stop and add the lines to  */
+    /* the list.                       */
+    if ( max_splits <= 2 )
+      goto Append;
+
+    /* If not max splits then keep splitting */
+    FT_CALL( split_sdf_cubic( memory, &cpos[0], max_splits / 2, out ) );
+    FT_CALL( split_sdf_cubic( memory, &cpos[3], max_splits / 2, out ) );
+
+    /* [NOTE]: This is not an efficient way of   */
+    /* splitting the curve. Check the deviation  */
+    /* instead and stop if the deviation is less */
+    /* than a pixel.                             */
+
+    goto Exit;
+
+  Append:
+
+    /* Allocation and add the lines to the list. */
+
+    FT_CALL( sdf_edge_new( memory, &left) );
+    FT_CALL( sdf_edge_new( memory, &right) );
+
+    if ( FT_QNEW( n1 ) || FT_QNEW( n2 ) )
+      goto Exit;
+
+    left->start_pos  = cpos[0];
+    left->end_pos    = cpos[3];
+    left->edge_type  = SDF_EDGE_LINE;
+
+    right->start_pos = cpos[3];
+    right->end_pos   = cpos[6];
+    right->edge_type = SDF_EDGE_LINE;
+
+    n1->data = left;
+    n2->data = right;
+
+    FT_List_Add( out, n1 );
+    FT_List_Add( out, n2 );
+
+  Exit:
+    return error;
+  }
+
   /* This function subdivide and entire shape   */
   /* into line segment such that the it doesn't */
   /* look visually different than the original  */
@@ -814,7 +931,16 @@
         }
         case SDF_EDGE_CUBIC:
         {
-          /* [TODO] */
+          /* Subdivide the curve and add to the list. */
+          FT_26D6_Vec  ctrls[4];
+
+
+          ctrls[0] = edge->start_pos;
+          ctrls[1] = edge->control_a;
+          ctrls[2] = edge->control_b;
+          ctrls[3] = edge->end_pos;
+          error = split_sdf_cubic( memory, ctrls, 16, &new_edges );
+          break;
         }
         default:
           error = FT_THROW( Invalid_Argument );
@@ -2721,7 +2847,7 @@
 
   Exit:
     if ( shape )
-      sdf_shape_done( memory, &shape );
+      sdf_shape_done( &shape );
 
     return error;
   }



reply via email to

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