summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnuj Verma <anujv@iitbhilai.ac.in>2020-08-17 16:36:30 +0530
committerAnuj Verma <anujv@iitbhilai.ac.in>2020-08-17 16:36:30 +0530
commite4e81c0168a39440882ecacdc6d1510609bc2892 (patch)
tree990701ed9a4bf2051dce28cd5ae866884878be74
parent286fc7e42c5b3660bd498b296be778af679222ec (diff)
downloadfreetype2-e4e81c0168a39440882ecacdc6d1510609bc2892.tar.gz
[sdf] Added functions to decompose `FT_Outline'.
* src/sdf/ftsdf.c (sdf_outline_decompose): Added a function which decompose a `FT_Outline' using `FT_Outline_Decompose' and adds the outline data to a `SDF_Shape' for easier handling later on.
-rw-r--r--src/sdf/ftsdf.c195
1 files changed, 195 insertions, 0 deletions
diff --git a/src/sdf/ftsdf.c b/src/sdf/ftsdf.c
index 88308fa0f..9aba0f5cd 100644
--- a/src/sdf/ftsdf.c
+++ b/src/sdf/ftsdf.c
@@ -602,4 +602,199 @@
SDF_FREE( *shape );
}
+ /**************************************************************************
+ *
+ * shape decomposition functions
+ *
+ */
+
+ /* This function is called when walking along a new contour */
+ /* so add a new contour to the shape's list. */
+ static FT_Error
+ sdf_move_to( const FT_26D6_Vec* to,
+ void* user )
+ {
+ SDF_Shape* shape = ( SDF_Shape* )user;
+ SDF_Contour* contour = NULL;
+
+ FT_Error error = FT_Err_Ok;
+ FT_Memory memory = shape->memory;
+
+
+ if ( !to || !user )
+ {
+ error = FT_THROW( Invalid_Argument );
+ goto Exit;
+ }
+
+ FT_CALL( sdf_contour_new( memory, &contour ) );
+
+ contour->last_pos = *to;
+ contour->next = shape->contours;
+ shape->contours = contour;
+
+ Exit:
+ return error;
+ }
+
+ /* This function is called when there is a line in the */
+ /* contour. The line is from the previous edge point to */
+ /* the parameter `to'. */
+ 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_Error error = FT_Err_Ok;
+ FT_Memory memory = shape->memory;
+
+
+ if ( !to || !user )
+ {
+ error = FT_THROW( Invalid_Argument );
+ goto Exit;
+ }
+
+ contour = shape->contours;
+
+ if ( contour->last_pos.x == to->x &&
+ contour->last_pos.y == to->y )
+ goto Exit;
+
+ FT_CALL( sdf_edge_new( memory, &edge ) );
+
+ edge->edge_type = SDF_EDGE_LINE;
+ edge->start_pos = contour->last_pos;
+ edge->end_pos = *to;
+
+ edge->next = contour->edges;
+ contour->edges = edge;
+ contour->last_pos = *to;
+
+ Exit:
+ return error;
+ }
+
+ /* This function is called when there is a conic bezier */
+ /* curve in the contour. The bezier is from the previous */
+ /* edge point to the parameter `to' with the control */
+ /* point being `control_1'. */
+ 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_Error error = FT_Err_Ok;
+ FT_Memory memory = shape->memory;
+
+
+ if ( !control_1 || !to || !user )
+ {
+ error = FT_THROW( Invalid_Argument );
+ goto Exit;
+ }
+
+ contour = shape->contours;
+
+ FT_CALL( sdf_edge_new( memory, &edge ) );
+
+ edge->edge_type = SDF_EDGE_CONIC;
+ edge->start_pos = contour->last_pos;
+ edge->control_a = *control_1;
+ edge->end_pos = *to;
+
+ edge->next = contour->edges;
+ contour->edges = edge;
+ contour->last_pos = *to;
+
+ Exit:
+ return error;
+ }
+
+ /* This function is called when there is a cubic bezier */
+ /* curve in the contour. The bezier is from the previous */
+ /* edge point to the parameter `to' with one control */
+ /* point being `control_1' and another `control_2'. */
+ 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_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 = shape->contours;
+
+ FT_CALL( sdf_edge_new( memory, &edge ) );
+
+ 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;
+
+ edge->next = contour->edges;
+ contour->edges = edge;
+ contour->last_pos = *to;
+
+ Exit:
+ return error;
+ }
+
+ /* Construct the struct to hold all four outline */
+ /* decomposition functions. */
+ 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 */
+ )
+
+ /* The function decomposes the outline and puts it */
+ /* into the `shape' struct. */
+ 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;
+ }
+
/* END */