path: Implement path ops

Implement boolean operations on paths.
This commit is contained in:
Matthias Clasen
2022-03-20 22:01:05 -04:00
parent 98c40daa5f
commit 4e24f88482
5 changed files with 1573 additions and 0 deletions

View File

@@ -1432,4 +1432,95 @@ gsk_path_offset (GskPath *self,
return gsk_path_builder_free_to_path (builder);
}
/**
* gsk_path_simplify:
* @self: a `GskPath`
* @fill_rule: a `GskFillRule`
*
* Create a new path that describes the same area as @self,
* without overlapping contours.
*
* Returns: a new `GskPath`
*/
GskPath *
gsk_path_simplify (GskPath *self,
GskFillRule fill_rule)
{
return gsk_path_op (GSK_PATH_OP_SIMPLIFY, fill_rule, self, NULL);
}
/**
* gsk_path_union:
* @first: a `GskPath`
* @second: a `GskPath`
* @fill_rule: a `GskFillRule`
*
* Create a new path that describes the union of the areas
* of the given paths.
*
* Returns: a new `GskPath`
*/
GskPath *
gsk_path_union (GskPath *first,
GskPath *second,
GskFillRule fill_rule)
{
return gsk_path_op (GSK_PATH_OP_UNION, fill_rule, first, second);
}
/**
* gsk_path_intersection:
* @first: a `GskPath`
* @second: a `GskPath`
* @fill_rule: a `GskFillRule`
*
* Create a new path that describes the intersection of the areas
* of the given paths.
*
* Returns: a new `GskPath`
*/
GskPath *
gsk_path_intersection (GskPath *first,
GskPath *second,
GskFillRule fill_rule)
{
return gsk_path_op (GSK_PATH_OP_INTERSECTION, fill_rule, first, second);
}
/**
* gsk_path_difference:
* @first: a `GskPath`
* @second: a `GskPath`
* @fill_rule: a `GskFillRule`
*
* Create a new path that describes the difference of the areas
* of the given paths.
*
* Returns: a new `GskPath`
*/
GskPath *
gsk_path_difference (GskPath *first,
GskPath *second,
GskFillRule fill_rule)
{
return gsk_path_op (GSK_PATH_OP_DIFFERENCE, fill_rule, first, second);
}
/**
* gsk_path_symmetric_difference:
* @first: a `GskPath`
* @second: a `GskPath`
* @fill_rule: a `GskFillRule`
*
* Create a new path that describes the symmetric difference
* of the areas of the given paths.
*
* Returns: a new `GskPath`
*/
GskPath *
gsk_path_symmetric_difference (GskPath *first,
GskPath *second,
GskFillRule fill_rule)
{
return gsk_path_op (GSK_PATH_OP_XOR, fill_rule, first, second);
}

View File

@@ -129,6 +129,30 @@ GskPath * gsk_path_offset (GskPath
GskLineJoin line_join,
float miter_limit);
GDK_AVAILABLE_IN_ALL
GskPath * gsk_path_union (GskPath *first,
GskPath *second,
GskFillRule fill_rule);
GDK_AVAILABLE_IN_ALL
GskPath * gsk_path_intersection (GskPath *first,
GskPath *second,
GskFillRule fill_rule);
GDK_AVAILABLE_IN_ALL
GskPath * gsk_path_difference (GskPath *first,
GskPath *second,
GskFillRule fill_rule);
GDK_AVAILABLE_IN_ALL
GskPath * gsk_path_symmetric_difference (GskPath *first,
GskPath *second,
GskFillRule fill_rule);
GDK_AVAILABLE_IN_ALL
GskPath * gsk_path_simplify (GskPath *self,
GskFillRule fill_rule);
G_END_DECLS

1442
gsk/gskpathops.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -58,6 +58,21 @@ void gsk_path_builder_svg_arc_to (GskPathBuilder
float x,
float y);
typedef enum
{
GSK_PATH_OP_SIMPLIFY,
GSK_PATH_OP_UNION,
GSK_PATH_OP_INTERSECTION,
GSK_PATH_OP_DIFFERENCE,
GSK_PATH_OP_XOR
} GskPathOp;
GskPath * gsk_path_op (GskPathOp operation,
GskFillRule fill_rule,
GskPath *first,
GskPath *second);
G_END_DECLS
#endif /* __GSK_PATH_PRIVATE_H__ */

View File

@@ -29,6 +29,7 @@ gsk_public_sources = files([
'gskpathbuilder.c',
'gskpathdash.c',
'gskpathmeasure.c',
'gskpathops.c',
'gskpathstroke.c',
'gskrenderer.c',
'gskrendernode.c',