20#include <glibmm/i18n.h>
22#include <gtkmm/button.h>
44namespace LivePathEffect {
47 {
MT_V, N_(
"Vertical page center"),
"vertical" },
48 {
MT_H, N_(
"Horizontal page center"),
"horizontal" },
49 {
MT_FREE, N_(
"Freely defined mirror line"),
"free" },
50 {
MT_X, N_(
"X coordinate of mirror line midpoint"),
"X" },
51 {
MT_Y, N_(
"Y coordinate of mirror line midpoint"),
"Y" }
60 lpesatellites(_(
"lpesatellites"), _(
"Items satellites"),
"lpesatellites", &wr, this, false),
61 mode(_(
"Mode"), _(
"Set mode of transformation. Either freely defined by mirror line or constrained to certain symmetry points."),
"mode",
MTConverter, &wr, this,
MT_FREE),
62 discard_orig_path(_(
"Discard original path"), _(
"Only keep mirrored part of the path, remove the original."),
"discard_orig_path", &wr, this, false),
63 fuse_paths(_(
"Fuse paths"), _(
"Fuse original path and mirror image into a single path"),
"fuse_paths", &wr, this, false),
64 oposite_fuse(_(
"Fuse opposite sides"), _(
"Picks the part on the other side of the mirror line as the original."),
"oposite_fuse", &wr, this, false),
65 split_items(_(
"Split elements"), _(
"Split original and mirror image into separate paths, so each can have its own style."),
"split_items", &wr, this, false),
66 split_open(_(
"Keep open paths on split"), _(
"Do not automatically close paths along the split line."),
"split_open", &wr, this, false),
67 start_point(_(
"Mirror line start"), _(
"Start point of mirror line"),
"start_point", &wr, this, _(
"Adjust start point of mirror line")),
68 end_point(_(
"Mirror line end"), _(
"End point of mirror line"),
"end_point", &wr, this, _(
"Adjust end point of mirror line")),
69 center_point(_(
"Mirror line mid"), _(
"Center point of mirror line"),
"center_point", &wr, this, _(
"Adjust center point of mirror line")),
70 link_styles(_(
"Link styles"), _(
"Link styles on split mode"),
"link_styles", &wr, this, false)
103 if (version <
"1.2") {
105 Glib::ustring
id = Glib::ustring(
"mirror-");
133 if (lpereference && lpereference->isAttached() && lpereference.get()->getObject() !=
nullptr) {
157 auto const vbox = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL, 2);
160 std::vector<Parameter *>::iterator it =
param_vector.begin();
162 if ((*it)->widget_is_visible) {
166 if (widg && param->
param_key !=
"split_open") {
170 widg->set_tooltip_markup(*tip);
172 widg->set_tooltip_text(
"");
173 widg->set_has_tooltip(
false);
180 auto const hbox = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL, 0);
181 auto const center_vert_button = Gtk::make_managed<Gtk::Button>(Glib::ustring(_(
"Vertical center")));
183 center_vert_button->set_size_request(110,20);
184 auto const center_horiz_button = Gtk::make_managed<Gtk::Button>(Glib::ustring(_(
"Horizontal center")));
186 center_horiz_button->set_size_request(110,20);
210 using namespace Geom;
302 if (
page ==
nullptr) {
305 pageRect =
page->getDocumentRect();
310 sp =
Geom::Point(pageRect->midpoint().x(), pageRect->top());
313 sp =
Geom::Point(pageRect->left(), pageRect->midpoint().y());
333 for (
auto iter :
orig->style->properties()) {
335 auto key = iter->id();
337 const gchar *attr =
orig->getAttribute(iter->name().c_str());
352 if ( is<SPGroup>(
orig) && is<SPGroup>(dest) && cast<SPGroup>(
orig)->getItemCount() == cast<SPGroup>(dest)->getItemCount() ) {
356 std::vector< SPObject * > childs =
orig->childList(
true);
358 for (
auto &
child : childs) {
364 }
else if( is<SPGroup>(
orig) && is<SPGroup>(dest) && cast<SPGroup>(
orig)->getItemCount() != cast<SPGroup>(dest)->getItemCount()) {
369 if (is<SPText>(
orig) && is<SPText>(dest) && cast<SPText>(
orig)->children.size() == cast<SPText>(dest)->children.size()) {
374 for (
auto &
child : cast<SPText>(
orig)->children) {
381 auto shape = cast<SPShape>(
orig);
382 auto path = cast<SPPath>(dest);
387 if (shape && !path) {
394 dest->
updateRepr(xml_doc, dest_node, SP_OBJECT_WRITE_ALL);
395 path = cast<SPPath>(dest);
397 path->setAttribute(
"d", str);
399 path->removeAttribute(
"d");
415 auto group = cast<SPGroup>(elemref);
422 std::vector<SPItem*>
const item_list = group->item_list();
424 for (
auto sub_item : item_list) {
427 previous = resultnode;
456 bool creation =
false;
520 using namespace Geom;
554 for (
const auto & path_it : original_pathv)
556 if (path_it.empty()) {
560 double time_start = 0.0;
562 bool end_open =
false;
563 if (path_it.closed()) {
564 const Geom::Curve &closingline = path_it.back_closed();
570 if (end_open && path_it.closed()) {
577 double dir = line_separation.
angle();
581 s = Geom::Point::polar(dir,size_divider) +
center_point;
582 e = Geom::Point::polar(dir + Geom::rad_from_deg(180),size_divider) +
center_point;
586 std::vector<double> crossed;
588 crossed.push_back(
c.ta);
590 std::sort(crossed.begin(), crossed.end());
591 for (
unsigned int i = 0; i < crossed.size(); i++) {
592 double time_end = crossed[i];
593 if (time_start != time_end && time_end - time_start >
Geom::EPSILON) {
616 time_start = time_end;
622 if (cs.size()!=0 && (position == 1)) {
636 if (cs.size() > 1 && tmp_pathvector.
size() > 0 && tmp_pathvector[0].
size() > 0 ) {
638 portion.setFinal(tmp_pathvector[0].initialPoint());
639 portion.setInitial(tmp_pathvector[0].finalPoint());
641 tmp_pathvector[0] = tmp_pathvector[0].
reversed();
643 portion.setInitial(tmp_pathvector[0].finalPoint());
645 tmp_pathvector[0].append(
portion);
650 tmp_pathvector[0].close();
658 for (
auto &path : tmp_pathvector) {
659 if (!path.closed()) {
665 if (cs.size() == 0 && position == 1) {
672 tmp_pathvector.
clear();
675 for (
const auto & i : original_pathv) {
685 using namespace Geom;
694 hp_vec.push_back(helper);
3x3 affine transformation matrix.
3x3 matrix representing an affine transformation.
Affine inverse() const
Compute the inverse matrix.
friend Bezier portion(const Bezier &a, Coord from, Coord to)
Abstract continuous curve on a plane defined on [0,1].
virtual Point initialPoint() const =0
Retrieve the start of the curve.
virtual Point finalPoint() const =0
Retrieve the end of the curve.
constexpr C middle() const
Infinite line on a plane.
Point vector() const
Get the line's raw direction vector.
Coord angle() const
Angle the line makes with the X axis, in mathematical convention.
Axis-aligned rectangle that can be empty.
size_type size() const
Get the number of paths in the vector.
void push_back(Path const &path)
Append a path at the end.
void clear()
Remove all paths from the vector.
iterator insert(iterator pos, Path const &p)
PathVector reversed(bool reverse_paths=true) const
Get a new vector with reversed direction of paths.
Sequence of contiguous curves, aka spline.
void close(bool closed=true)
Set whether the path is closed.
void setInitial(Point const &p)
void appendNew(Args &&... args)
Append a new curve to the path.
void start(Point const &p)
Two-dimensional point that doubles as a vector.
constexpr Coord y() const noexcept
constexpr Coord x() const noexcept
Axis aligned, non-empty rectangle.
std::vector< StorageType > const & data() const
void param_setValue(bool newvalue)
std::vector< Parameter * > param_vector
void registerParameter(Parameter *param)
bool apply_to_clippath_and_mask
virtual void processObjects(LPEAction lpe_action)
void makeUndoDone(Glib::ustring message)
LivePathEffectObject * getLPEObj()
bool satellitestoclipboard
void original_bbox(SPLPEItem const *lpeitem, bool absolute=false, bool clip_mask=false, Geom::Affine base_transform=Geom::identity())
Geom::Interval boundingbox_Y
Geom::Interval boundingbox_X
void param_setValue(Glib::ustring newvalue, bool write=false)
Glib::ustring param_getSVGValue() const override
Inkscape::XML::Node * createPathBase(SPObject *elemref)
void doBeforeEffect(SPLPEItem const *lpeitem) override
Is performed each time before the effect is updated.
Geom::PathVector doEffect_path(Geom::PathVector const &path_in) override
void cloneD(SPObject *orig, SPObject *dest)
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...
void toMirror(Geom::Affine transform)
void doOnApply(SPLPEItem const *lpeitem) override
Is performed a single time when the effect is freshly applied to a path.
EnumParam< ModeType > mode
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 cloneStyle(SPObject *orig, SPObject *dest)
bool doOnOpen(SPLPEItem const *) override
Is performed on load document or revert If the item is fixed legacy return true.
void doOnRemove(SPLPEItem const *) override
~LPEMirrorSymmetry() override
bool prev_discard_orig_path
BoolParam discard_orig_path
SatelliteArrayParam lpesatellites
Geom::Point previous_center
void doOnVisibilityToggled(SPLPEItem const *) override
LPEMirrorSymmetry(LivePathEffectObject *lpeobject)
Gtk::Widget * newWidget() override
This creates a managed widget.
Glib::ustring const * param_getTooltip() const
virtual void param_widget_is_visible(bool is_visible)
void connect_selection_changed()
virtual Gtk::Widget * param_newWidget()=0
void param_update_default(Geom::Point default_point)
void param_setValue(Geom::Point newpoint, bool write=false)
void link(SPObject *to, size_t pos=Glib::ustring::npos)
Simplified management of enumerations of svg items with UI labels.
Interface for refcounted XML nodes.
void setAttributeOrRemoveIfEmpty(Inkscape::Util::const_char_ptr key, Inkscape::Util::const_char_ptr value)
Change an attribute 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.
Typed SVG document implementation.
SPObject * getObjectById(std::string const &id) const
Geom::OptRect preferredBounds() const
Inkscape::PageManager & getPageManager()
Inkscape::XML::Document * getReprDoc()
Our Inkscape::XML::Document.
SPObject is an abstract base class of all of the document nodes at the SVG document level.
void setAttribute(Inkscape::Util::const_char_ptr key, Inkscape::Util::const_char_ptr value)
char const * getId() const
Returns the objects current ID string.
Inkscape::XML::Node * updateRepr(unsigned int flags=SP_OBJECT_WRITE_EXT)
Updates the object's repr based on the object's state.
Inkscape::XML::Node * getRepr()
Returns the XML representation of tree.
char const * getAttribute(char const *name) const
SPObject * appendChildRepr(Inkscape::XML::Node *repr)
Append repr as child of this object.
SPObject * nthChild(unsigned index)
void addChild(Inkscape::XML::Node *child, Inkscape::XML::Node *prev=nullptr)
constexpr Coord EPSILON
Default "acceptably small" value.
Geom::PathVector pathv_to_linear_and_cubic_beziers(Geom::PathVector const &pathv)
Specific geometry functions for Inkscape, not provided my lib2geom.
LPE <mirror_symmetry> implementation: mirrors a path with respect to a given line.
Various utility functions.
int sgn(const T &x)
Sign function - indicates the sign of a numeric type.
Angle distance(Angle const &a, Angle const &b)
std::vector< Crossing > Crossings
Crossings crossings(Curve const &a, Curve const &b)
Bezier portion(const Bezier &a, double from, double to)
Piecewise< SBasis > cross(Piecewise< D2< SBasis > > const &a, Piecewise< D2< SBasis > > const &b)
bool are_near(Affine const &a1, Affine const &a2, Coord eps=EPSILON)
Point middle_point(LineSegment const &_segment)
static R & release(R &r)
Decrements the reference count of a anchored object.
static const Util::EnumDataConverter< ModeType > MTConverter(ModeTypeData, MT_END)
static const Util::EnumData< ModeType > ModeTypeData[]
void pack_start(Gtk::Box &box, Gtk::Widget &child, bool const expand, bool const fill, unsigned const padding)
Adds child to box, packed with reference to the start of box.
Helper class to stream background task notifications as a series of messages.
static cairo_user_data_key_t key
Helpers for using Gtk::Boxes, encapsulating large changes between GTK3 & GTK4.
void flatten(Geom::PathVector &pathv, FillRule fill_rule)
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.
Base class for live path effect items.
Simplified management of enumerations of svg items with UI labels.
Interface for XML documents.
virtual Node * createElement(char const *name)=0
SPStyle - a style object for SPItem objects.
std::string sp_svg_transform_write(Geom::Affine const &transform)
static void sp_svg_write_path(Inkscape::SVG::PathString &str, Geom::Path const &p, bool normalize=false)