15#include <glibmm/i18n.h>
46namespace LivePathEffect {
80 , operand_item(_(
"Operand path:"), _(
"Operand for the boolean operation"),
"operand-path", &wr, this)
81 , bool_operation(_(
"Operation:"), _(
"Boolean Operation"),
"operation",
BoolOpConverter, &wr, this, bool_op_ex_union)
82 , swap_operands(_(
"Swap operands"), _(
"Swap operands (useful e.g. for difference)"),
"swap-operands", &wr, this)
85 _(
"For cut operations: remove inner (non-contour) lines of cutting path to avoid invisible extra points"),
86 "rmv-inner", &wr, this)
87 , fill_type_this(_(
"Fill type this:"), _(
"Fill type (winding mode) for this path"),
"filltype-this",
89 , fill_type_operand(_(
"Fill type operand:"), _(
"Fill type (winding mode) for operand path"),
"filltype-operand",
91 , filter(
"Filter",
"Previous filter",
"filter", &wr, this,
"", true)
117 if (version <
"1.2") {
172 area_path->ConvertWithBackData(1.0);
173 area_path->Fill(combined_shape, 1);
179 contour_path->ConvertWithBackData(1.0);
180 contour_path->Fill(combined_shape, 0,
true,
false,
false);
187 result_path->SetBackData(
false);
190 std::vector<Path::cut_position> toCut;
205 while (cb >= 0 && cb < combined_inters->numberOfEdges()) {
206 if (combined_inters->
ebData[cb].pathID == 0) {
208 piece = combined_inters->
ebData[cb].pieceID;
209 if (combined_inters->
getEdge(cb).
st == i) {
210 t = combined_inters->
ebData[cb].tSt;
212 t = combined_inters->
ebData[cb].tEn;
216 if (combined_inters->
ebData[cb].pathID == 1) {
219 cb = combined_inters->
NextAt(i, cb);
221 if (nbOrig > 0 && nbOther > 0) {
226 cutpos.
piece = piece;
228 toCut.push_back(cutpos);
236 for (; i >= 0; i--) {
237 if (combined_inters->
ebData[i].pathID == 1) {
254 std::vector<Path::cut_position> inside_pieces(combined_inters->
numberOfEdges());
256 inside_pieces[i].piece = combined_inters->
ebData[i].pieceID;
258 inside_pieces[i].t = 0.5 * (combined_inters->
ebData[i].tSt + combined_inters->
ebData[i].tEn);
268 std::vector<Path::cut_position>::iterator itPiece = inside_pieces.begin();
269 std::vector<Path::cut_position>::iterator itCut = toCut.begin();
270 while (itPiece != inside_pieces.end()) {
275 itPiece->piece += idIncr;
281 result_path->Copy(contour_path.get());
282 result_path->ConvertPositionsToMoveTo(toCut.size(), toCut.data());
285 std::vector<bool> inside_flags(result_path->descr_cmd.
size(),
false);
286 for (
auto & inside_piece : inside_pieces) {
287 inside_flags[ inside_piece.piece ] =
true;
289 if (inside_piece.piece >= 1) {
290 inside_flags[ inside_piece.piece - 1 ] =
true;
298 Path **parts = result_path->SubPaths(nParts,
false);
302 for (
int iPart = 0; iPart < nParts; iPart++) {
305 for (
int iCmd = 0; iCmd < parts[iPart]->descr_cmd.
size(); iCmd++, iPiece++) {
306 andsum = andsum && inside_flags[ iPiece ];
307 orsum = andsum || inside_flags[ iPiece ];
310 if (andsum != orsum) {
311 g_warning(
"Inconsistent inside/outside verdict for part=%d", iPart);
319 for (
int iSrc = 0; iSrc < result_path->descr_cmd.
size(); iSrc++) {
320 if (inside_flags[iSrc] == inside) {
321 result_path->descr_cmd[iDest++] = result_path->descr_cmd[iSrc];
323 delete result_path->descr_cmd[iSrc];
326 result_path->descr_cmd.resize(iDest);
328 delete combined_inters;
329 delete combined_shape;
332 auto outres = result_path->MakePathVector();
348 resultp->SetBackData(
false);
350 patha->ConvertWithBackData(0.1);
351 patha->Fill(shape, 0);
359 auto resultpv = resultp->MakePathVector();
369 if (val && strcmp(val,
"nonzero") == 0) {
371 }
else if (val && strcmp(val,
"evenodd") == 0) {
387 if (filt && filt->
getId() && strcmp(filt->
getId(),
"selectable_hidder_filter") != 0) {
390 if (!filt || (filt->
getId() && strcmp(filt->
getId(),
"selectable_hidder_filter") != 0)) {
407 if (filt && (filt->
getId() && strcmp(filt->
getId(),
"selectable_hidder_filter") == 0)) {
411 Glib::ustring url =
"url(#";
455 if (!(elemref = document->
getObjectById(
"selectable_hidder_filter"))) {
457 boolfilter->
setAttribute(
"id",
"selectable_hidder_filter");
462 boolfilter->
setAttribute(
"style",
"color-interpolation-filters:sRGB;");
463 boolfilter->
setAttribute(
"inkscape:label",
"LPE boolean visibility");
466 primitive->
setAttribute(
"id",
"boolops_hidder_primitive");
472 defs->
addChild(boolfilter,
nullptr);
474 boolfilter->
addChild(primitive,
nullptr);
477 for (
auto obj : elemref->
childList(
false)) {
478 if (obj && strcmp(obj->getId(),
"boolops_hidder_primitive") != 0) {
479 obj->deleteObject(
true);
499 if (!current_operand && !
operand) {
502 if (!current_operand) {
505 if (current_operand && !
operand ) {
516 if (current_operand) {
521 current_operand =
nullptr;
536 if (!current_operand) {
544 if (current_operand &&
operand != current_operand) {
554 if (current_operand) {
580 if (
auto objitem = cast<SPItem>(
object)) {
581 SPObject *clip_path = objitem->getClipObject();
583 std::vector<SPObject *> clip_path_list = clip_path->
childList(
true);
584 if (clip_path_list.size()) {
585 for (
auto clip : clip_path_list) {
586 if (
auto clipshape = cast<SPShape>(
clip)) {
587 auto curve = _from_original_d
588 ? clipshape->curveForEdit()
589 : clipshape->curve();
591 clippv =
curve->get_pathvector();
598 if (
auto group = cast<SPGroup>(
object)) {
599 std::vector<SPItem *> item_list = group->item_list();
600 for (
auto iter : item_list) {
603 res = std::move(tmp);
609 if (
auto shape = cast<SPShape>(
object)) {
611 auto curve = _from_original_d
612 ? shape->curveForEdit()
617 res = std::move(tmp);
624 if (
auto text = cast<SPText>(
object)) {
625 auto curve = text->getNormalizedBpath();
629 res = std::move(tmp);
634 if (!clippv.
empty()) {
645 g_warning(
"operand and current shape are the same");
652 if (current_operand) {
661 if (operand_pv.
empty()) {
664 path_in *= current_affine;
676 FillRule fill_a = swap ? fill_this : fill_operand;
677 FillRule fill_b = swap ? fill_operand : fill_this;
708 path_out.
insert(path_out.
end(),tmp.begin(),tmp.end());
715 curve->set_pathvector(path_out * current_affine.
inverse());
721 hp_vec.push_back(
_hp);
736 for (
auto iter :
origin->style->properties()) {
738 auto key = iter->id();
740 const gchar *attr =
origin->getAttribute(iter->name().c_str());
753 auto operandit_item = cast<SPItem>(operandit);
754 auto operandit_g = cast<SPGroup>(operandit);
755 auto operandit_shape = cast<SPShape>(operandit);
781 for (
auto&
child: operandit_g->children) {
788 if (operandit_shape) {
789 if (
auto c = operandit_shape->curve()) {
823 auto operand_a_item = cast<SPItem>(operand_a);
824 auto operand_b_item = cast<SPItem>(operand_b);
825 auto operand_b_g = cast<SPGroup>(operand_b);
826 auto operand_b_shape = cast<SPShape>(operand_b);
840 for (
auto&
child: operand_b_g->children) {
847 if (operand_b_shape) {
851 if (
auto c = operand_b_shape->curveForEdit()) {
Path - a sequence of contiguous curves.
TODO: insert short description here.
TODO: insert short description here.
3x3 affine transformation matrix.
3x3 matrix representing an affine transformation.
Affine inverse() const
Compute the inverse matrix.
void clear()
Remove all paths from the vector.
bool empty() const
Check whether the vector contains any paths.
iterator insert(iterator pos, Path const &p)
Sequence of contiguous curves, aka spline.
size_type size() const
Natural size of the path.
Two-dimensional point that doubles as a vector.
constexpr Coord x() const noexcept
void registerParameter(Parameter *param)
virtual void processObjects(LPEAction lpe_action)
bool isOnClipboard()
The lpe is on clipboard.
bool helperLineSatellites
bool satellitestoclipboard
void param_setValue(Glib::ustring newvalue, bool write=false)
Glib::ustring param_getSVGValue() const override
void doOnVisibilityToggled(SPLPEItem const *) override
EnumParam< FillRule > fill_type_this
Glib::ustring division_id
EnumParam< FillRule > fill_type_operand
Inkscape::XML::Node * dupleNode(SPObject *origin, Glib::ustring element_type)
friend BooleanOp to_bool_op(bool_op_ex val)
Geom::PathVector get_union(SPObject *root, SPObject *object, bool prefear_original=false)
void divisionit(SPObject *operand_a, SPObject *operand_b, Geom::PathVector unionpv)
void fractureit(SPObject *operandit, Geom::PathVector unionpv)
void doAfterEffect(SPLPEItem const *lpeitem, SPCurve *curve) override
Is performed at the end of the LPE only one time per "lpeitem" in paths/shapes is called in middle of...
void doBeforeEffect(SPLPEItem const *lpeitem) override
Is performed each time before the effect is updated.
EnumParam< bool_op_ex > bool_operation
Glib::ustring division_other_id
void doEffect(SPCurve *curve) override
void remove_filter(SPObject *object)
OriginalSatelliteParam operand_item
void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector< Geom::PathVector > &hp_vec) override
Add possible canvas indicators (i.e., helperpaths other than the original path) to hp_vec This functi...
LPEBool(LivePathEffectObject *lpeobject)
void transform_multiply(Geom::Affine const &postmul, bool set) override
Overridden function to apply transforms for example to powerstroke, jointtype or tapperstroke.
void doOnRemove(SPLPEItem const *) override
bool doOnOpen(SPLPEItem const *lpeitem) override
Is performed on load document or revert If the item is fixed legacy return true.
void connect_selection_changed()
std::shared_ptr< SatelliteReference > lperef
void param_set_default() override
void start_listening(SPObject *to)
SPObject * getObject() const
The set of selected SPObjects for a given document and layer model.
bool includes(XML::Node *repr, bool anyAncestor=false)
Returns true if the given item is selected.
Simplified management of enumerations of svg items with UI labels.
Interface for refcounted XML nodes.
virtual void addChild(Node *child, Node *after)=0
Insert another node as a child of this node.
void setAttribute(Util::const_char_ptr key, Util::const_char_ptr value)
Change an attribute of this node.
virtual char const * attribute(char const *key) const =0
Get the string representation of a node's attribute.
Wrapper around a Geom::PathVector object.
To do: update description of desktop.
Inkscape::Selection * getSelection() const
Typed SVG document implementation.
SPObject * getObjectById(std::string const &id) const
SPDefs * getDefs()
Return the main defs object for the document.
Inkscape::XML::Document * getReprDoc()
Our Inkscape::XML::Document.
Base class for visual SVG elements.
unsigned int pos_in_parent() const
void doWriteTransform(Geom::Affine const &transform, Geom::Affine const *adv=nullptr, bool compensate=true)
Set a new transform on an object.
bool pathEffectsEnabled() const
SPObject is an abstract base class of all of the document nodes at the SVG document level.
std::vector< SPObject * > childList(bool add_ref, Action action=ActionGeneral)
Retrieves the children as a std vector object, optionally ref'ing the children in the process,...
char const * getId() const
Returns the objects current ID string.
SPStyle * style
Represents the style properties, whether from presentation attributes, the style attribute,...
void reorder(SPObject *obj, SPObject *prev)
In list of object's children, move object behind prev.
Inkscape::XML::Node * getRepr()
Returns the XML representation of tree.
SPObject * appendChildRepr(Inkscape::XML::Node *repr)
Append repr as child of this object.
A class to store/manipulate directed graphs.
void ConvertToForme(Path *dest)
Extract contours from a directed graph.
int PtWinding(const Geom::Point px) const
std::vector< back_data > ebData
int numberOfEdges() const
Returns number of edges.
int NextAt(int p, int b) const
int numberOfPoints() const
Returns number of points.
dg_arete const & getEdge(int n) const
Get an edge.
int ConvertToShape(Shape *a, FillRule directed=fill_nonZero, bool invert=false)
Using a given fill rule, find all intersections in the shape given, create a new intersection free sh...
dg_point const & getPoint(int n) const
Get a point.
bool hasBackData() const
Do we have back data?
std::shared_ptr< Css const > css
Geom::PathVector pathv_to_linear_and_cubic_beziers(Geom::PathVector const &pathv)
Specific geometry functions for Inkscape, not provided my lib2geom.
vector< vector< Point > > paths
Affine identity()
Create an identity matrix.
bool clip(std::vector< RatQuad > &rq, const xAx &cs, const Rect &R)
static R & release(R &r)
Decrements the reference count of a anchored object.
static const Util::EnumDataConverter< LPEBool::bool_op_ex > BoolOpConverter(BoolOpData, sizeof(BoolOpData)/sizeof(*BoolOpData))
Geom::PathVector sp_pathvector_boolop_slice_intersect(Geom::PathVector const &pathva, Geom::PathVector const &pathvb, bool inside, FillRule fra, FillRule frb)
static const Util::EnumData< LPEBool::bool_op_ex > BoolOpData[LPEBool::bool_op_ex_count]
bool cmp_cut_position(const Path::cut_position &a, const Path::cut_position &b)
static const Util::EnumDataConverter< FillRule > FillTypeConverter(FillTypeData, sizeof(FillTypeData)/sizeof(*FillTypeData))
Geom::PathVector sp_pathvector_boolop_remove_inner(Geom::PathVector const &pathva, FillRule fra)
static FillRule GetFillTyp(SPItem *item)
static const Util::EnumData< FillRule > FillTypeData[]
Helper class to stream background task notifications as a series of messages.
static cairo_user_data_key_t key
Geom::PathVector sp_pathvector_boolop(Geom::PathVector const &pathva, Geom::PathVector const &pathvb, BooleanOp bop, FillRule fra, FillRule frb)
Perform a boolean operation on two pathvectors.
TODO: insert short description here.
callback interface for SVG path data
std::unique_ptr< Path > Path_for_pathvector(Geom::PathVector const &pathv)
Creates a Livarot Path object from the Geom::PathVector.
SPCSSAttr * sp_repr_css_attr_new()
Creates an empty SPCSSAttr (a class for manipulating CSS style properties).
void sp_repr_css_change(Node *repr, SPCSSAttr *css, gchar const *attr)
Creates a new SPCSAttr with the values filled from a repr, merges in properties from the given SPCSAt...
void sp_repr_css_attr_unref(SPCSSAttr *css)
Unreferences an SPCSSAttr (will be garbage collected if no references remain).
SPCSSAttr * sp_repr_css_attr(Node const *repr, gchar const *attr)
Creates a new SPCSSAttr with one attribute (i.e.
char const * sp_repr_css_property(SPCSSAttr *css, gchar const *name, gchar const *defval)
Returns a character string of the value of a given style property or a default value if the attribute...
void sp_repr_css_unset_property(SPCSSAttr *css, gchar const *name)
Set a style property to "inkscape:unset".
void sp_repr_css_set_property(SPCSSAttr *css, gchar const *name, gchar const *value)
Set a style property to a new value (e.g.
Geom::Affine sp_item_transform_repr(SPItem *item)
Find out the inverse of previous transform of an item (from its repr)
Geom::Affine i2anc_affine(SPObject const *object, SPObject const *ancestor)
void sp_lpe_item_update_patheffect(SPLPEItem *lpeitem, bool wholetree, bool write, bool with_satellites)
Calls any registered handlers for the update_patheffect action.
SPRoot: SVG <svg> implementation.
Simplified management of enumerations of svg items with UI labels.
Interface for XML documents.
virtual Node * createElement(char const *name)=0
An edge in the directed graph.
A point or vertex in the directed graph.
SPStyle - a style object for SPItem objects.
parse SVG path specifications
static void sp_svg_write_path(Inkscape::SVG::PathString &str, Geom::Path const &p, bool normalize=false)